Skip to main content

Declarative hook framework for Claude Code

Project description

captain-hook

PyPI Python Docs License: PolyForm Noncommercial

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.

Install

There's no install step. Run everything through uvx.

uvx capt-hook init

uvx 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 once you prefix it with uvx.

First hook

uvx capt-hook init scaffolds .claude/hooks/, wires Claude Code's settings, and installs the skills. One command and you're live.

uvx capt-hook init

A hook is declarative Python with an event, some conditions, and an action. This one stops the agent from finishing a UI change it never looked at.

# .claude/hooks/visual_review.py
from captain_hook import gate, TouchedFile, UsedSkill

# A Stop gate: before the agent finishes, block if it edited UI files without doing a visual review.
gate(
    # the one-line reason shown to the agent when the gate fires
    "You edited UI files. Open them with agent-browser and verify they render before finishing.",
    # fires only if UI files changed
    only_if=[TouchedFile("**/src/routes/**", "**/src/components/**")],
    # already reviewed -> don't block
    skip_if=[UsedSkill("agent-browser")],
)

Conditions match tools, files, commands, and even which skills the agent used.

Test your hooks

Every deterministic hook carries inline tests, so a broken hook fails like broken code. Run them from your project root, where --hooks defaults to .claude/hooks.

# .claude/hooks/safety.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 status"): Allow(),
    },
)
uvx capt-hook test

init already wired Claude Code's settings. Each event runs uvx capt-hook run <Event>, with the event JSON arriving on stdin and the verdict written to stdout. Re-run uvx capt-hook generate-settings only after you add hooks on a new event.

Agent skills & plugin

capt-hook ships two Agent Skills so you don't have to write hooks by hand. 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 both into .claude/skills/, or you can add them as a plugin.

/plugin marketplace add yasyf/captain-hook
/plugin install captain-hook@captain-hook

What problems does this solve?

captain-hook covers four jobs:

  • Block dangerous tool calls before they execute on PreToolUse, like force-push, package-manager footguns, and raw rm -rf.
  • Drive the agent with feedback that fires on the patterns it actually emits, such as repeated failures, weakened tests, and 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, or completing a checklist.
  • Keep all of the above testable. Every hook ships with inline tests = {...} that uvx capt-hook test runs in CI, so you catch broken hooks the way you catch broken code.

Docs

Read the docs for the full guide to conditions, primitives, LLM hooks, workflows, state, and real-world patterns.

For working on captain-hook itself, see the development guide.

Project details


Release history Release notifications | RSS feed

This version

0.7.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

capt_hook-0.7.0.tar.gz (93.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

capt_hook-0.7.0-py3-none-any.whl (124.6 kB view details)

Uploaded Python 3

File details

Details for the file capt_hook-0.7.0.tar.gz.

File metadata

  • Download URL: capt_hook-0.7.0.tar.gz
  • Upload date:
  • Size: 93.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for capt_hook-0.7.0.tar.gz
Algorithm Hash digest
SHA256 78d5a3f51c50f9fb49ee0725708f0d7a04721fdf5fea37331d0eee88d3f137d6
MD5 3c3bc5d4d01b3dd05da0af3e3a483fd8
BLAKE2b-256 dfcac2403b8fc7a9f74169d83863894b766bdbdfd3cbb3f16259d96679707f3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for capt_hook-0.7.0.tar.gz:

Publisher: release-pypi.yml on yasyf/captain-hook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file capt_hook-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: capt_hook-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 124.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for capt_hook-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9ba252d1d234f3a89c5405f6dfb7cb5d91fb7c7adea484c9a046afed7727790c
MD5 c3c5f2e44b5b1c51650c95ebfd314025
BLAKE2b-256 e8591c164b24bc91861ec67f1a77df5f5685aba63d70fd588e7865090df3229a

See more details on using hashes here.

Provenance

The following attestation bundles were made for capt_hook-0.7.0-py3-none-any.whl:

Publisher: release-pypi.yml on yasyf/captain-hook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page