- Remove dead overlays/default.nix (flake defines overlays inline)
- Remove orphaned overlays/mods/{beads,n8n}.nix (never imported)
- Remove docs/packages/notesmd-cli.md (package doesn't exist)
- Extract externalSkills submodule to shared-options.nix (eliminates
~100 lines of duplication across opencode/claude-code/pi modules)
- Fix lib output: use nixpkgs.lib directly instead of instantiating
a full nixpkgs just to get lib
- Add lib unit tests to flake checks
- Update stale comment in coding-rules.nix
90 lines
3.0 KiB
Nix
90 lines
3.0 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}: let
|
|
shared = import ./shared-options.nix {inherit lib;};
|
|
in
|
|
with lib; let
|
|
cfg = config.coding.agents.claude-code;
|
|
mcpCfg = config.programs.mcp or null;
|
|
in {
|
|
options.coding.agents.claude-code = {
|
|
enable = mkEnableOption "Claude Code agent management via canonical agent.toml definitions";
|
|
|
|
agentsInput = shared.mkAgentsInputOption ''
|
|
The `agents` flake input (your personal AGENTS repo).
|
|
When set, agents are rendered from canonical agent.toml files
|
|
and symlinked to ~/.claude/agents/.
|
|
'';
|
|
|
|
modelOverrides = shared.mkModelOverridesOption;
|
|
|
|
externalSkills = shared.externalSkillsOption;
|
|
|
|
mcpServers = mkOption {
|
|
type = types.attrsOf types.anything;
|
|
default =
|
|
if mcpCfg != null
|
|
then mcpCfg.servers
|
|
else {};
|
|
defaultText = literalExpression "config.programs.mcp.servers";
|
|
description = ''
|
|
MCP server configurations for Claude Code.
|
|
Merged into ~/.claude/settings.json alongside permissions.
|
|
Automatically inherits from config.programs.mcp.servers.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable (let
|
|
agentsLib = (import ../../../../lib {inherit lib;}).agents;
|
|
|
|
# Rendered agents + permissions (only if agentsInput is set)
|
|
rendered = mkIf (cfg.agentsInput != null) (
|
|
agentsLib.renderForClaudeCode {
|
|
inherit pkgs;
|
|
canonical = cfg.agentsInput.lib.loadAgents;
|
|
modelOverrides = cfg.modelOverrides;
|
|
}
|
|
);
|
|
|
|
# Merge MCP servers into the rendered settings.json.
|
|
# The renderer produces { permissions: { allow, deny } }.
|
|
# We add mcpServers on top.
|
|
settingsJson =
|
|
if cfg.agentsInput != null
|
|
then let
|
|
renderedSettings = builtins.fromJSON (builtins.readFile "${rendered}/.claude/settings.json");
|
|
withMcp =
|
|
if cfg.mcpServers != {}
|
|
then renderedSettings // {mcpServers = cfg.mcpServers;}
|
|
else renderedSettings;
|
|
in
|
|
pkgs.writeText "claude-settings.json" (builtins.toJSON withMcp)
|
|
else if cfg.mcpServers != {}
|
|
then pkgs.writeText "claude-settings.json" (builtins.toJSON {mcpServers = cfg.mcpServers;})
|
|
else null;
|
|
in {
|
|
# Rendered agent files symlinked to ~/.claude/agents/
|
|
home.file.".claude/agents" = mkIf (cfg.agentsInput != null) {
|
|
source = "${rendered}/.claude/agents";
|
|
};
|
|
|
|
# Skills (merged from personal AGENTS repo + optional external skills)
|
|
home.file.".claude/skills" = mkIf (cfg.agentsInput != null) {
|
|
source = cfg.agentsInput.lib.mkOpencodeSkills {
|
|
inherit pkgs;
|
|
customSkills = "${cfg.agentsInput}/skills";
|
|
externalSkills = shared.mapExternalSkills cfg.externalSkills;
|
|
};
|
|
};
|
|
|
|
# Rendered settings.json with permissions + MCP servers
|
|
home.file.".claude/settings.json" = mkIf (settingsJson != null) {
|
|
source = "${settingsJson}";
|
|
};
|
|
});
|
|
}
|