Development

Working on captain-hook itself. For using captain-hook in your project, see Installation.

Setup

Clone the repo and sync the dev extra:

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:

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:

uv run pytest

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

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:

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:

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:

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):

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 holds the runnable hooks whose inline tests uv run capt-hook --hooks docs/examples test exercises
  • Reference covers the API and CLI surface the docs build renders