Installation¶
Requirements¶
- Python 3.12 or later
- uv is required. The
uvxrunner ships with uv and is how every captain-hook command is invoked.
Run without installing (default)¶
The fastest way to use captain-hook — no project dependency needed:
uvx fetches capt-hook into a throwaway environment, runs the CLI, and discards it. Every command works the same way — just prefix it with uvx:
Run from your project root and --hooks defaults to .claude/hooks. This is the headline path: you never add captain-hook to pyproject.toml and never manage a venv yourself.
Add as a project dependency¶
Only if you want captain-hook pinned in your project's lockfile (e.g. to vendor it for offline CI):
Then the commands drop the uvx prefix:
Verify installation¶
This runs the inline tests on the scaffolded example hook. If you added captain-hook as a dependency, you can also check the import directly:
Project layout¶
capt-hook init produces:
my-project/
├── .claude/
│ ├── hooks/
│ │ ├── conf.py # Settings (optional)
│ │ └── example.py # Starter hook
│ └── settings.local.json # Captain-hook wires itself in here
You don't need this exact layout — capt-hook --hooks <any-dir> test works on any directory of hooks. The default just lines up with what Claude Code looks for.
Dependencies¶
capt-hook bundles:
- pydantic / pydantic-settings — typed settings and data models
- tree-sitter / tree-sitter-bash — bash command parsing for
CommandLine - spacy — NLP-based signal matching and echo detection
- wn — WordNet synonym expansion for NLP signals
- funcy — functional utilities
- orjsonl — fast JSONL reading for transcripts
The spaCy English model is not auto-downloaded — see Troubleshooting.
CI integration¶
Run inline hook tests in CI so scaffold edits cannot ship broken expectations. capt-hook test --json emits one JSON object per test (id, status, expected, reason) and exits non-zero on the first failure.
# .github/workflows/hooks.yml
name: hooks
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uvx capt-hook test
setup-uv installs uv (which provides Python 3.12+ and uvx), so there's no separate Python or install step. Drop --json in if a downstream reporter consumes the output.