Metadata-Version: 2.4
Name: capt-hook
Version: 0.2.0
Summary: Declarative hook framework for Claude Code
Keywords: claude,claude-code,hooks,llm,agents,guardrails,cli
Author: Yasyf Mohamedali
Author-email: Yasyf Mohamedali <yasyfm@gmail.com>
License-Expression: PolyForm-Noncommercial-1.0.0
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Classifier: Typing :: Typed
Requires-Dist: pydantic>=2.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: tree-sitter>=0.24
Requires-Dist: tree-sitter-bash>=0.23
Requires-Dist: funcy>=2.0
Requires-Dist: spacy>=3.7
Requires-Dist: click>=8
Requires-Dist: orjsonl>=1.0
Requires-Dist: wn>=1.1.0
Requires-Dist: lazy-object-proxy>=1.12.0
Requires-Dist: filelock>=3
Requires-Dist: loguru>=0.7.3
Requires-Dist: pytest>=8.0 ; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24 ; extra == 'dev'
Requires-Dist: pyright>=1.1 ; extra == 'dev'
Requires-Dist: ruff>=0.8 ; extra == 'dev'
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/yasyf/captain-hook
Project-URL: Documentation, https://captain-hook.readthedocs.io
Project-URL: Repository, https://github.com/yasyf/captain-hook
Project-URL: Issues, https://github.com/yasyf/captain-hook/issues
Project-URL: Changelog, https://github.com/yasyf/captain-hook/blob/main/CHANGELOG.md
Provides-Extra: dev
Description-Content-Type: text/markdown

# captain-hook

[![PyPI](https://img.shields.io/pypi/v/capt-hook.svg)](https://pypi.org/project/capt-hook/)
[![Python](https://img.shields.io/pypi/pyversions/capt-hook.svg)](https://pypi.org/project/capt-hook/)
[![Docs](https://readthedocs.org/projects/captain-hook/badge/?version=latest)](https://captain-hook.readthedocs.io)
[![License: PolyForm Noncommercial](https://img.shields.io/badge/License-PolyForm_Noncommercial_1.0.0-blue.svg)](https://github.com/yasyf/captain-hook/blob/main/LICENSE)

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

No install needed — run everything through [uvx](https://docs.astral.sh/uv/):

```bash
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: prefix it with `uvx`.

## First hook

Scaffold a project and drop a hook into `.claude/hooks/`:

```bash
uvx capt-hook init
```

```python
# .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`):

```bash
capt-hook test
```

Wire the hook into Claude Code's settings:

```bash
capt-hook generate-settings > .claude/settings.local.json
```

The next time Claude tries `git stash`, captain-hook returns a deny with your reason and hint.

## What problems does this solve?

- **Block dangerous tool calls** before they execute (`PreToolUse`) — force-push, package-manager footguns, raw `rm -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 = {...}` that `capt-hook test` runs in CI, so you catch broken hooks the same way you catch broken code.

## Docs

[Read the docs](https://captain-hook.readthedocs.io) for the full guide: conditions, primitives, LLM hooks, workflows, state, and real-world patterns.

Working on captain-hook itself? See the [development guide](https://captain-hook.readthedocs.io/en/latest/development/).
