All checks were successful
CI / check (push) Successful in 3m16s
Correct terminology mismatch: - Rename skills/ to commands/ (these are user-invokable commands) - Create new skills/ for reference materials - Move bd_workflow.md to skills/ (it's reference material) - Add micro-skills and formulas directories - Update default.nix to install both commands and skills Commands → ~/.claude/commands/ (invokable as /command-name) Skills → ~/.claude/commands/skills/ (reference materials) Formulas → ~/.beads/formulas/ (workflow templates) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
152 lines
5.6 KiB
Nix
152 lines
5.6 KiB
Nix
{ config, lib, pkgs, globalInputs, system, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.home.roles.development;
|
|
|
|
# FIXME: Temporary override for upstream beads vendorHash mismatch
|
|
# Remove after upstream fix: https://github.com/steveyegge/beads/issues/XXX
|
|
beadsPackage = globalInputs.beads.packages.${system}.default.overrideAttrs (old: {
|
|
vendorHash = "sha256-YU+bRLVlWtHzJ1QPzcKJ70f+ynp8lMoIeFlm+29BNPE=";
|
|
});
|
|
|
|
# Fetch the claude-plugins repository (for humanlayer commands/agents)
|
|
# Update the rev to get newer versions of the commands
|
|
claudePluginsRepo = builtins.fetchGit {
|
|
url = "https://github.com/jeffh/claude-plugins.git";
|
|
# To update: change this to the latest commit hash
|
|
# You can find the latest commit at: https://github.com/jeffh/claude-plugins/commits/main
|
|
rev = "5e3e4d937162185b6d78c62022cbfd1c8ad42c4c";
|
|
ref = "main";
|
|
};
|
|
|
|
in
|
|
{
|
|
options.home.roles.development = {
|
|
enable = mkEnableOption "Enable development tools and utilities";
|
|
|
|
allowArbitraryClaudeCodeModelSelection = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Whether to preserve model specifications in Claude Code humanlayer commands and agents.
|
|
|
|
When false (default), the model: line is stripped from frontmatter, allowing Claude Code
|
|
to use its default model selection.
|
|
|
|
When true, the model: specifications from the source files are preserved, allowing
|
|
commands to specify opus/sonnet/haiku explicitly.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
home.packages = [
|
|
beadsPackage
|
|
pkgs.unstable.claude-code
|
|
pkgs.unstable.claude-code-router
|
|
pkgs.unstable.codex
|
|
|
|
# Custom packages
|
|
pkgs.custom.tea-rbw
|
|
];
|
|
|
|
# Install Claude Code humanlayer command and agent plugins
|
|
home.activation.claudeCodeCommands = lib.hm.dag.entryAfter ["writeBoundary"] ''
|
|
# Clean up old plugin-installed commands and agents to avoid duplicates
|
|
rm -f ~/.claude/commands/humanlayer:* 2>/dev/null || true
|
|
rm -f ~/.claude/agents/humanlayer:* 2>/dev/null || true
|
|
|
|
# Create directories if they don't exist
|
|
mkdir -p ~/.claude/commands
|
|
mkdir -p ~/.claude/agents
|
|
|
|
# Copy all humanlayer command files and remove model specifications
|
|
for file in ${claudePluginsRepo}/humanlayer/commands/*.md; do
|
|
if [ -f "$file" ]; then
|
|
filename=$(basename "$file" .md)
|
|
dest="$HOME/.claude/commands/humanlayer:''${filename}.md"
|
|
|
|
# Copy file and conditionally remove the "model:" line from frontmatter
|
|
${if cfg.allowArbitraryClaudeCodeModelSelection
|
|
then "cp \"$file\" \"$dest\""
|
|
else "${pkgs.gnused}/bin/sed '/^model:/d' \"$file\" > \"$dest\""
|
|
}
|
|
fi
|
|
done
|
|
|
|
# Copy all humanlayer agent files and remove model specifications
|
|
for file in ${claudePluginsRepo}/humanlayer/agents/*.md; do
|
|
if [ -f "$file" ]; then
|
|
filename=$(basename "$file" .md)
|
|
dest="$HOME/.claude/agents/humanlayer:''${filename}.md"
|
|
|
|
# Copy file and conditionally remove the "model:" line from frontmatter
|
|
${if cfg.allowArbitraryClaudeCodeModelSelection
|
|
then "cp \"$file\" \"$dest\""
|
|
else "${pkgs.gnused}/bin/sed '/^model:/d' \"$file\" > \"$dest\""
|
|
}
|
|
fi
|
|
done
|
|
|
|
# Copy local commands from this repo (with retry for race conditions with running Claude)
|
|
for file in ${./commands}/*.md; do
|
|
if [ -f "$file" ]; then
|
|
filename=$(basename "$file" .md)
|
|
dest="$HOME/.claude/commands/''${filename}.md"
|
|
# Remove existing file first, then copy with retry on failure
|
|
rm -f "$dest" 2>/dev/null || true
|
|
if ! cp "$file" "$dest" 2>/dev/null; then
|
|
sleep 0.5
|
|
cp "$file" "$dest" || echo "Warning: Failed to copy $filename.md to commands"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Copy local skills (reference materials) to skills subdirectory
|
|
mkdir -p ~/.claude/commands/skills
|
|
for file in ${./skills}/*.md; do
|
|
if [ -f "$file" ]; then
|
|
filename=$(basename "$file" .md)
|
|
dest="$HOME/.claude/commands/skills/''${filename}.md"
|
|
rm -f "$dest" 2>/dev/null || true
|
|
if ! cp "$file" "$dest" 2>/dev/null; then
|
|
sleep 0.5
|
|
cp "$file" "$dest" || echo "Warning: Failed to copy $filename.md to skills"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Copy micro-skills (compact reusable knowledge referenced by formulas)
|
|
for file in ${./skills/micro}/*.md; do
|
|
if [ -f "$file" ]; then
|
|
cp "$file" "$HOME/.claude/commands/skills/$(basename "$file")"
|
|
fi
|
|
done
|
|
|
|
# Install beads formulas to user-level formula directory
|
|
mkdir -p ~/.beads/formulas
|
|
for file in ${./formulas}/*.formula.toml; do
|
|
if [ -f "$file" ]; then
|
|
cp "$file" "$HOME/.beads/formulas/$(basename "$file")"
|
|
fi
|
|
done
|
|
|
|
$DRY_RUN_CMD echo "Claude Code plugins installed: humanlayer commands/agents + local commands + local skills + formulas"
|
|
'';
|
|
|
|
# Set up beads Claude Code integration (hooks for SessionStart/PreCompact)
|
|
# This uses the CLI + hooks approach which is recommended over MCP for Claude Code
|
|
home.activation.claudeCodeBeadsSetup = lib.hm.dag.entryAfter ["writeBoundary" "claudeCodeCommands"] ''
|
|
# Run bd setup claude to install hooks into ~/.claude/settings.json
|
|
# This is idempotent - safe to run multiple times
|
|
${beadsPackage}/bin/bd setup claude 2>/dev/null || true
|
|
|
|
$DRY_RUN_CMD echo "Claude Code beads integration configured (hooks installed)"
|
|
'';
|
|
|
|
# Note: modules must be imported at top-level home config
|
|
};
|
|
}
|