114 lines
3.5 KiB
Nix
114 lines
3.5 KiB
Nix
|
|
{
|
||
|
|
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";
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|