{ config, lib, pkgs, ... }: with lib; let cfg = config.services.ai-skills; in { options.services.ai-skills = { enable = mkEnableOption "AI agent skills for Claude Code and OpenCode"; skills = mkOption { type = types.listOf types.str; default = []; description = '' List of skills to deploy. Available skills: - niri-window-capture: Invisibly capture window screenshots - screenshot-latest: Find latest screenshots - tufte-press: Generate study card JSON - worklog: Create org-mode worklogs - update-spec-kit: Update spec-kit ecosystem - update-opencode: Update OpenCode via Nix - web-search: Search the web via Claude - web-research: Deep web research with multiple backends ''; example = [ "worklog" "web-search" ]; }; skillsPath = mkOption { type = types.path; default = null; description = "Path to skills repository (e.g., ~/proj/skills/skills)"; }; enableClaudeCode = mkOption { type = types.bool; default = true; description = "Deploy skills to Claude Code (~/.claude/skills/)"; }; enableOpenCode = mkOption { type = types.bool; default = true; description = "Deploy skills to OpenCode (~/.config/opencode/skills/)"; }; }; config = mkIf cfg.enable { # Deploy skills to Claude Code home.file = mkMerge [ # Claude Code skills (mkIf cfg.enableClaudeCode ( builtins.listToAttrs ( map (skillName: { name = ".claude/skills/${skillName}"; value = { source = "${cfg.skillsPath}/${skillName}"; recursive = true; }; }) cfg.skills ) )) # OpenCode skills (mkIf cfg.enableOpenCode ( builtins.listToAttrs ( map (skillName: { name = ".config/opencode/skills/${skillName}"; value = { source = "${cfg.skillsPath}/${skillName}"; recursive = true; }; }) cfg.skills ) )) ]; }; }