# Opencode rules management utilities # # This module provides functions to configure Opencode agent rules across # multiple projects. Rules are defined in the AGENTS repository and can be # selectively included based on language, framework, and concerns. # # Usage in your configuration: # # # In your flake or configuration: # let # m3taLib = inputs.m3ta-nixpkgs.lib.${system}; # # rules = m3taLib.opencode-rules.mkOpencodeRules { # agents = inputs.agents; # languages = [ "python" "typescript" ]; # concerns = [ "coding-style" "naming" "documentation" ]; # frameworks = [ "react" "fastapi" ]; # }; # in { # # Use in your devShell: # devShells.default = pkgs.mkShell { # shellHook = rules.shellHook; # inherit (rules) instructions; # }; # } # # The shellHook creates: # - A `.opencode-rules/` symlink pointing to the AGENTS repository rules directory # - An `opencode.json` file with a $schema reference and instructions list # # The instructions list contains paths relative to the project root, all prefixed # with `.opencode-rules/`, making them portable across different project locations. {lib}: { # Create Opencode rules configuration from AGENTS repository # # Args: # agents: Path to the AGENTS repository (non-flake input) # languages: Optional list of language-specific rules to include # (e.g., [ "python" "typescript" "rust" ]) # concerns: Optional list of concern rules to include # Default: [ "coding-style" "naming" "documentation" "testing" "git-workflow" "project-structure" ] # frameworks: Optional list of framework-specific rules to include # (e.g., [ "react" "fastapi" "django" ]) # extraInstructions: Optional list of additional instruction paths # (for custom rules outside standard locations) # # Returns: # An attribute set containing: # - shellHook: Bash code to create symlink and opencode.json # - instructions: List of rule file paths (relative to project root) # # Example: # mkOpencodeRules { # agents = inputs.agents; # languages = [ "python" ]; # frameworks = [ "fastapi" ]; # } # # Returns: # # { # # shellHook = "..."; # # instructions = [ # # ".opencode-rules/concerns/coding-style.md" # # ".opencode-rules/concerns/naming.md" # # ".opencode-rules/concerns/documentation.md" # # ".opencode-rules/concerns/testing.md" # # ".opencode-rules/concerns/git-workflow.md" # # ".opencode-rules/concerns/project-structure.md" # # ".opencode-rules/languages/python.md" # # ".opencode-rules/frameworks/fastapi.md" # # ]; # # } mkOpencodeRules = { agents, languages ? [], concerns ? [ "coding-style" "naming" "documentation" "testing" "git-workflow" "project-structure" ], frameworks ? [], extraInstructions ? [], }: let rulesDir = ".opencode-rules"; # Build instructions list by mapping concerns, languages, frameworks to their file paths # All paths are relative to project root via the rulesDir symlink instructions = (map (c: "${rulesDir}/concerns/${c}.md") concerns) ++ (map (l: "${rulesDir}/languages/${l}.md") languages) ++ (map (f: "${rulesDir}/frameworks/${f}.md") frameworks) ++ extraInstructions; # Generate JSON configuration for Opencode opencodeConfig = { "$schema" = "https://opencode.ai/config.json"; inherit instructions; }; in { inherit instructions; # Shell hook to set up rules in the project # Creates a symlink to the AGENTS rules directory and generates opencode.json shellHook = '' # Create/update symlink to AGENTS rules directory ln -sfn ${agents}/rules ${rulesDir} # Generate opencode.json configuration file cat > opencode.json <<'OPENCODE_EOF' ${builtins.toJSON opencodeConfig} OPENCODE_EOF ''; }; }