- use-skills.sh: symlink to $CODEX_HOME/skills when CODEX_HOME is set - docs: update PER-REPO-SKILLS.md and RFC-SKILLS-MANIFEST.md with Codex flow - hq: add model configuration section (sonnet-4.5, Claude Max) - hq: update launch commands with explicit --model flag Closes skills-legi Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
151 lines
4 KiB
Markdown
151 lines
4 KiB
Markdown
# Per-Repo Skill Deployment
|
|
|
|
Deploy selected skills to individual projects using direnv + Nix.
|
|
|
|
## Overview
|
|
|
|
Each project can declare which skills it needs. When team members enter the directory (via direnv), skills are symlinked from the Nix store into `.claude/skills/` and `.opencode/skills/` (and `$CODEX_HOME/skills` if set).
|
|
|
|
```
|
|
teammate clones repo
|
|
↓
|
|
direnv allow
|
|
↓
|
|
nix builds skills (cached)
|
|
↓
|
|
symlinks created in .claude/skills/
|
|
↓
|
|
Claude Code sees project-local skills
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### 1. Add to `.envrc`
|
|
|
|
**Option A: Source the helper** (if skills repo is accessible)
|
|
```bash
|
|
source ~/proj/skills/bin/use-skills.sh
|
|
export CODEX_HOME="$PWD/.codex" # Optional: per-repo Codex skills
|
|
use_skills worklog web-search
|
|
```
|
|
|
|
**Option B: Self-contained** (copy-paste, no external dependency)
|
|
```bash
|
|
# AI Agent Skills
|
|
SKILLS_REPO="git+file://$HOME/proj/skills" # or git+http://... for remote
|
|
|
|
use_skill() {
|
|
local skill="$1"
|
|
local out
|
|
out=$(nix build --print-out-paths --no-link "${SKILLS_REPO}#${skill}" 2>/dev/null)
|
|
if [[ -n "$out" ]]; then
|
|
mkdir -p .claude/skills .opencode/skills
|
|
ln -sfn "$out" ".claude/skills/${skill}"
|
|
ln -sfn "$out" ".opencode/skills/${skill}"
|
|
if [[ -n "${CODEX_HOME:-}" ]]; then
|
|
mkdir -p "${CODEX_HOME}/skills"
|
|
ln -sfn "$out" "${CODEX_HOME}/skills/${skill}"
|
|
fi
|
|
echo "use_skill: ${skill}"
|
|
fi
|
|
}
|
|
|
|
use_skill worklog
|
|
use_skill web-search
|
|
```
|
|
|
|
### 2. Add to `.gitignore`
|
|
|
|
```
|
|
.claude/skills/
|
|
.opencode/skills/
|
|
.codex/skills/
|
|
```
|
|
|
|
### 3. Done
|
|
|
|
Team members clone and run `direnv allow`. Skills appear.
|
|
|
|
## Available Skills
|
|
|
|
Run `nix flake show git+ssh://git@forgejo.delmore.io/dan/skills.git` to see all available skills.
|
|
|
|
Current list:
|
|
- `worklog` - Create org-mode worklogs
|
|
- `web-search` - Search the web via Claude
|
|
- `web-research` - Deep research with multiple backends
|
|
- `update-opencode` - Update OpenCode via Nix
|
|
- `update-spec-kit` - Update spec-kit ecosystem
|
|
- `niri-window-capture` - Capture window screenshots
|
|
- `screenshot-latest` - Find latest screenshots
|
|
- `tufte-press` - Generate study card JSON
|
|
|
|
## How It Works
|
|
|
|
1. **direnv** triggers on directory entry
|
|
2. **nix build** fetches/builds the skill package (cached locally)
|
|
3. **symlink** points `.claude/skills/<name>` to `/nix/store/xxx-ai-skill-<name>` (and `$CODEX_HOME/skills/<name>` if set)
|
|
4. **Claude Code** reads skills from `.claude/skills/` when in that directory
|
|
|
|
Skills are always fetched from the latest commit on the skills repo. Nix caches builds locally, so subsequent loads are fast.
|
|
|
|
## Customization
|
|
|
|
### Different skills per project
|
|
|
|
```bash
|
|
# Project A - .envrc
|
|
use_skill worklog
|
|
use_skill web-search
|
|
|
|
# Project B - .envrc
|
|
use_skill worklog
|
|
use_skill tufte-press
|
|
```
|
|
|
|
### Claude Code only (no OpenCode)
|
|
|
|
```bash
|
|
SKILLS_REPO="git+file://$HOME/proj/skills"
|
|
mkdir -p .claude/skills
|
|
for skill in worklog web-search; do
|
|
ln -sfn $(nix build --print-out-paths --no-link "${SKILLS_REPO}#${skill}") ".claude/skills/${skill}"
|
|
done
|
|
```
|
|
|
|
### Pin to specific version
|
|
|
|
```bash
|
|
SKILLS_REPO="git+file://$HOME/proj/skills?rev=abc123def" # pin to commit
|
|
use_skill worklog # uses pinned revision
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Skills not appearing
|
|
|
|
1. Check `direnv allow` was run
|
|
2. Check `.claude/skills/` exists and has symlinks
|
|
3. Restart Claude Code (it loads skills at startup)
|
|
|
|
### nix build fails
|
|
|
|
1. Check network access to skills repo
|
|
2. Check `nix flake show $SKILLS_REPO` works
|
|
3. Check skill name is correct
|
|
|
|
### Symlinks broken after nix-collect-garbage
|
|
|
|
Re-run `direnv reload` to rebuild and re-link.
|
|
|
|
## Comparison with Global Skills
|
|
|
|
| Aspect | Global (~/.claude/skills/) | Per-Repo (.claude/skills/) |
|
|
|--------|---------------------------|---------------------------|
|
|
| Scope | All projects | Single project |
|
|
| Deployment | Nix Home Manager | direnv + nix build |
|
|
| Team sharing | Via dotfiles | Via project .envrc |
|
|
| Selection | User-wide | Per-project |
|
|
|
|
Use global for personal defaults. Use per-repo for project-specific or team-shared skills.
|