{ config, lib, pkgs, ... }: with lib; let cfg = config.coding.agents.opencode; in { options.coding.agents.opencode = { enable = mkEnableOption "OpenCode agent management via canonical agent.toml definitions"; agentsInput = mkOption { type = types.nullOr types.anything; default = null; description = '' The `agents` flake input (your personal AGENTS repo). When set, agents are rendered from canonical agent.toml files and symlinked to ~/.config/opencode/agents/. ''; }; modelOverrides = mkOption { type = types.attrsOf types.str; default = {}; description = '' Per-agent model overrides. Maps agent slug to model string. Example: { chiron = "anthropic/claude-sonnet-4"; } ''; example = literalExpression '' { chiron = "anthropic/claude-sonnet-4"; "chiron-forge" = "anthropic/claude-sonnet-4"; } ''; }; externalSkills = mkOption { type = types.listOf (types.submodule { options = { src = mkOption { type = types.anything; description = "Flake input pointing to a skills repository root."; }; skillsDir = mkOption { type = types.str; default = "skills"; description = '' Subdirectory inside src that contains skill folders. ''; }; selectSkills = mkOption { type = types.nullOr (types.listOf types.str); default = null; description = '' List of skill names to cherry-pick from this source. null means include every skill found in skillsDir. ''; }; }; }); default = []; description = '' External skill sources passed to mkOpencodeSkills. Each entry maps directly to an element of the externalSkills list accepted by the AGENTS flake's lib.mkOpencodeSkills. ''; example = literalExpression '' [ { src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; } { src = inputs.skills-vercel; } ] ''; }; }; config = mkIf cfg.enable { # Rendered agent files symlinked to ~/.config/opencode/agents/ xdg.configFile."opencode/agents" = mkIf (cfg.agentsInput != null) { source = (import ../../../../lib {inherit lib;}).agents.renderForOpencode { inherit pkgs; canonical = cfg.agentsInput.lib.loadAgents; modelOverrides = cfg.modelOverrides; }; }; # Skills (merged from personal AGENTS repo + optional external skills) xdg.configFile."opencode/skills" = mkIf (cfg.agentsInput != null) { source = cfg.agentsInput.lib.mkOpencodeSkills { inherit pkgs; customSkills = "${cfg.agentsInput}/skills"; externalSkills = map ( entry: {inherit (entry) src skillsDir;} // optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;} ) cfg.externalSkills; }; }; # Static config dirs from AGENTS repo xdg.configFile."opencode/context" = mkIf (cfg.agentsInput != null) { source = "${cfg.agentsInput}/context"; }; xdg.configFile."opencode/commands" = mkIf (cfg.agentsInput != null) { source = "${cfg.agentsInput}/commands"; }; xdg.configFile."opencode/prompts" = mkIf (cfg.agentsInput != null) { source = "${cfg.agentsInput}/prompts"; }; }; }