- Add piSkills option to ai-skills module for pi-only skills - Add ralph-work-loop skill (depends on pi extension) - Update skills.nix registry with nix-review, ralph-work-loop, ui-query - Add intent/approach/work docs for skill organization effort Universal skills deploy to claude/codex/opencode/gemini. Pi-only skills (ralph-work-loop) deploy to ~/.pi/agent/skills/ only.
158 lines
4.3 KiB
Nix
158 lines
4.3 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.services.ai-skills;
|
|
|
|
# Derive repo root from skillsPath (skills/ is a subdirectory)
|
|
repoRoot = dirOf cfg.skillsPath;
|
|
|
|
skillsData = import ../skills.nix;
|
|
|
|
skillsList = ''
|
|
Available skills:
|
|
${concatStringsSep "\n" (map (name: " - ${name}: ${skillsData.${name}}") (attrNames skillsData))}
|
|
'';
|
|
in {
|
|
options.services.ai-skills = {
|
|
enable = mkEnableOption "AI agent skills for Claude Code, OpenCode, and Codex";
|
|
|
|
skillsPath = mkOption {
|
|
type = types.path;
|
|
default = null;
|
|
description = "Path to skills repository (e.g., ~/proj/skills/skills)";
|
|
};
|
|
|
|
# Per-target skill lists
|
|
claudeCodeSkills = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
description = "Skills to deploy to Claude Code (~/.claude/skills/). ${skillsList}";
|
|
example = [ "worklog" "niri-window-capture" ];
|
|
};
|
|
|
|
openCodeSkills = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
description = "Skills to deploy to OpenCode (~/.config/opencode/skills/). ${skillsList}";
|
|
example = [ "worklog" "web-search" ];
|
|
};
|
|
|
|
codexSkills = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
description = "Skills to deploy to Codex (~/.codex/skills/). ${skillsList}";
|
|
example = [ "worklog" "hq" ];
|
|
};
|
|
|
|
geminiSkills = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
description = "Skills to deploy to Gemini CLI (~/.gemini/skills/). ${skillsList}";
|
|
example = [ "worklog" "web-search" ];
|
|
};
|
|
|
|
piSkills = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
description = "Skills to deploy to Pi (~/.pi/agent/skills/). For pi-only skills that depend on extensions. ${skillsList}";
|
|
example = [ "ralph-work-loop" ];
|
|
};
|
|
|
|
# Lenses for orch multi-model review
|
|
enableLenses = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = "Deploy review lenses to ~/.config/lenses/";
|
|
};
|
|
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
home.file = mkMerge [
|
|
# Claude Code skills
|
|
(mkIf (cfg.claudeCodeSkills != []) (
|
|
builtins.listToAttrs (
|
|
map (skillName: {
|
|
name = ".claude/skills/${skillName}";
|
|
value = {
|
|
source = "${cfg.skillsPath}/${skillName}";
|
|
recursive = true;
|
|
};
|
|
}) cfg.claudeCodeSkills
|
|
)
|
|
))
|
|
|
|
# OpenCode skills
|
|
(mkIf (cfg.openCodeSkills != []) (
|
|
builtins.listToAttrs (
|
|
map (skillName: {
|
|
name = ".config/opencode/skills/${skillName}";
|
|
value = {
|
|
source = "${cfg.skillsPath}/${skillName}";
|
|
recursive = true;
|
|
};
|
|
}) cfg.openCodeSkills
|
|
)
|
|
))
|
|
|
|
# Codex skills
|
|
(mkIf (cfg.codexSkills != []) (
|
|
builtins.listToAttrs (
|
|
map (skillName: {
|
|
name = ".codex/skills/${skillName}";
|
|
value = {
|
|
source = "${cfg.skillsPath}/${skillName}";
|
|
recursive = true;
|
|
};
|
|
}) cfg.codexSkills
|
|
)
|
|
))
|
|
|
|
# Gemini skills
|
|
(mkIf (cfg.geminiSkills != []) (
|
|
builtins.listToAttrs (
|
|
map (skillName: {
|
|
name = ".gemini/skills/${skillName}";
|
|
value = {
|
|
source = "${cfg.skillsPath}/${skillName}";
|
|
recursive = true;
|
|
};
|
|
}) cfg.geminiSkills
|
|
)
|
|
))
|
|
|
|
# Pi skills (pi-only, extension-dependent)
|
|
(mkIf (cfg.piSkills != []) (
|
|
builtins.listToAttrs (
|
|
map (skillName: {
|
|
name = ".pi/agent/skills/${skillName}";
|
|
value = {
|
|
source = "${cfg.skillsPath}/${skillName}";
|
|
recursive = true;
|
|
};
|
|
}) cfg.piSkills
|
|
)
|
|
))
|
|
|
|
# Lenses for orch (separate subdirectories per skill)
|
|
(mkIf cfg.enableLenses {
|
|
".config/lenses/code" = {
|
|
source = "${cfg.skillsPath}/code-review/lenses";
|
|
recursive = true;
|
|
};
|
|
".config/lenses/ops" = {
|
|
source = "${cfg.skillsPath}/ops-review/lenses";
|
|
recursive = true;
|
|
};
|
|
".config/lenses/test" = {
|
|
source = "${cfg.skillsPath}/test-review/lenses";
|
|
recursive = true;
|
|
};
|
|
})
|
|
|
|
];
|
|
};
|
|
}
|