# Development

Working on captain-hook itself. For using captain-hook in your project, see [Installation](../../docs/getting-started/quickstart.md).


# Setup

Clone the repo and sync the dev extra:

``` bash
git clone https://github.com/yasyf/captain-hook
cd captain-hook
uv sync --extra dev
```


## NLP assets

Tests that exercise NLP signals need the spaCy English model and WordNet data:

``` bash
uv run python -m spacy download en_core_web_sm
uv run python -c "import wn; wn.download('oewn:2025')"
```

This mirrors what CI provisions -- see `.github/workflows/ci.yml`.


# Tests

Run the suite:

``` bash
uv run pytest
```

The example hooks in `docs/examples/` carry inline tests too:

``` bash
uv run capt-hook --hooks docs/examples test
```


# Docs

The docs are Great Docs (Quarto), published to GitHub Pages. The API reference is generated from docstrings at build time; the CLI reference comes from the Click app.

Sync the docs group alongside the dev extra, then preview locally:

``` bash
uv sync --extra dev --group docs
uv run great-docs preview
```


# Build and smoke-test the wheel

Build the wheel, then install and exercise it in a throwaway venv:

``` bash
uv build
uv venv --seed .wheel-smoke
uv pip install --python .wheel-smoke/bin/python dist/*.whl
.wheel-smoke/bin/capt-hook --help
```


# Using a local checkout

From a consumer project, point `uv run --project` at your clone:

``` bash
uv run --project path/to/captain-hook capt-hook test
```


# Releasing

Add the CHANGELOG entry and commit it, together with `uv.lock` when a dependency change moved it. Then tag the new version and push. `.github/workflows/release-pypi.yml` builds the sdist and wheel, publishes to PyPI via trusted publishing, cuts a GitHub release, and commits `captain_hook/.claude-plugin/plugin.json` back to `main` with its `version` synced to the tag -- that bump is what makes consumer plugin caches pick up the release, so no manual plugin.json edit is needed (a hand-bump before tagging is harmless; the sync no-ops):

``` bash
git tag v0.9.1
git push origin v0.9.1
```

The release workflow re-derives the wheel version from the tag via `uv version --frozen` -- the committed `pyproject.toml` version is an inert `0.0.0` sentinel, so there is nothing to bump there either. After the run goes green, `git pull`: the plugin.json sync commit landed on `main`, so your local branch is one commit behind.


# See also

- [Examples](../../docs/examples/index.md) holds the runnable hooks whose inline tests `uv run capt-hook --hooks docs/examples test` exercises
- [Reference](../../docs/reference/index.md) covers the API and CLI surface the docs build renders
