# 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.
