- Add bin/use-skills.sh helper with use_skill and load_skills_from_manifest - Add .skills manifest pattern for declarative skill configuration - Fix ai-skills.nix: remove broken npm plugin code, update skill list - Add update-opencode, web-search, web-research to flake.nix availableSkills - Add RFC and documentation for team adoption 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
145 lines
3.7 KiB
Markdown
145 lines
3.7 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/`.
|
|
|
|
```
|
|
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
|
|
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}"
|
|
echo "use_skill: ${skill}"
|
|
fi
|
|
}
|
|
|
|
use_skill worklog
|
|
use_skill web-search
|
|
```
|
|
|
|
### 2. Add to `.gitignore`
|
|
|
|
```
|
|
.claude/skills/
|
|
.opencode/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>`
|
|
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.
|