Declarative hook framework for Claude Code. Write hooks as data, test them inline, and ship them to CI in the same shape they run in production.
No install needed — run everything through uvx:
uvx capt-hook inituvx fetches captain-hook into a throwaway environment and runs it, so you never add it to pyproject.toml. Every command below works the same way: prefix it with uvx.
Scaffold a project and drop a hook into .claude/hooks/:
uvx capt-hook init# .claude/hooks/my_first.py
from captain_hook import Allow, Block, Input, block_command
block_command(
["git", "stash"],
reason="Use the team's VCS workflow for shelving changes",
hint="Commit a WIP change instead of stashing",
tests={
Input(command="git stash"): Block(),
Input(command="git stash pop"): Block(),
Input(command="git status"): Allow(),
},
)Run the inline tests (from your project root, --hooks defaults to .claude/hooks):
capt-hook testWire the hook into Claude Code's settings:
capt-hook generate-settings > .claude/settings.local.jsonThe next time Claude tries git stash, captain-hook returns a deny with your reason and hint.
Don't want to write hooks by hand? capt-hook ships two Agent Skills — bootstrapping-hooks mines your repo's docs, CI, and git history into proposed gates and nudges; translating-styleguides turns a STYLEGUIDE.md into enforced rules. uvx capt-hook init installs them into .claude/skills/, or get them as a plugin:
/plugin marketplace add yasyf/captain-hook
/plugin install captain-hook@captain-hook
- Block dangerous tool calls before they execute (
PreToolUse) — force-push, package-manager footguns, rawrm -rf. - Drive the agent with feedback that fires on patterns it actually emits — repeated failures, weakened tests, missed conventions.
- Enforce multi-step workflows with stop-gates and artifact validation, so the agent can't declare "done" without running tests / writing a report / completing a checklist.
- Keep all of the above testable — every hook ships with inline
tests = {...}thatcapt-hook testruns in CI, so you catch broken hooks the same way you catch broken code.
Read the docs for the full guide: conditions, primitives, LLM hooks, workflows, state, and real-world patterns.
Working on captain-hook itself? See the development guide.