skills/modules/ai-skills.nix
dan 5fea49b7c0 feat(tufte-press): evolve skill to complete workflow with JSON generation and build automation
- Transform tufte-press from reference guide to conversation-aware generator
- Add JSON generation from conversation context following strict schema
- Create build automation scripts with Nix environment handling
- Integrate CUPS printing with duplex support
- Add comprehensive workflow documentation

Scripts added:
- skills/tufte-press/scripts/generate-and-build.sh (242 lines)
- skills/tufte-press/scripts/build-card.sh (23 lines)

Documentation:
- Updated SKILL.md with complete workflow instructions (370 lines)
- Updated README.md with usage examples (340 lines)
- Created SKILL-DEVELOPMENT-STRATEGY-tufte-press.md (450 lines)
- Added worklog: 2025-11-10-tufte-press-skill-evolution.org

Features:
- Agent generates valid JSON from conversation
- Schema validation before build (catches errors early)
- Automatic Nix shell entry for dependencies
- PDF build via tufte-press toolchain
- Optional print with duplex support
- Self-contained margin notes enforced
- Complete end-to-end testing

Workflow: Conversation → JSON → Validate → Build → Print

Related: niri-window-capture, screenshot-latest, worklog skills
2025-11-10 15:03:44 -08:00

134 lines
3.9 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.ai-skills;
# Helper to install opencode-skills npm package
opencodeSkillsPlugin = pkgs.buildNpmPackage rec {
pname = "opencode-skills";
version = "0.1.0";
src = pkgs.fetchFromNpm {
name = pname;
version = version;
sha256 = ""; # TODO: Get actual hash
};
# Alternative: install from npm directly at runtime
# This is a placeholder - actual implementation would fetch from npm
};
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
'';
example = [ "worklog" "screenshot-latest" ];
};
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/)";
};
installOpencodePlugin = mkOption {
type = types.bool;
default = true;
description = "Install opencode-skills npm plugin";
};
};
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
)
))
# OpenCode plugin installation
(mkIf (cfg.enableOpenCode && cfg.installOpencodePlugin) {
".config/opencode/package.json" = {
text = builtins.toJSON {
dependencies = {
"@opencode-ai/plugin" = "1.0.44";
"opencode-skills" = "^0.1.0";
};
};
};
})
];
# Ensure opencode-skills plugin is in config
home.activation.opencodeSkillsPlugin = mkIf (cfg.enableOpenCode && cfg.installOpencodePlugin) (
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
# Install npm dependencies for OpenCode
if [ -f "$HOME/.config/opencode/package.json" ]; then
cd "$HOME/.config/opencode"
if command -v bun &> /dev/null; then
${pkgs.bun}/bin/bun install
elif command -v npm &> /dev/null; then
${pkgs.nodejs}/bin/npm install
fi
fi
# Ensure plugin is enabled in config
CONFIG_FILE="$HOME/.config/opencode/config.json"
if [ -f "$CONFIG_FILE" ]; then
# Check if plugin array includes opencode-skills
if ! ${pkgs.jq}/bin/jq -e '.plugin | index("opencode-skills")' "$CONFIG_FILE" &> /dev/null; then
echo "Warning: opencode-skills plugin not in config.json plugin array"
echo "Add it manually: { \"plugin\": [\"opencode-skills\"] }"
fi
fi
''
);
};
}