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 devNLP 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 pytestThe example hooks in docs/examples/ carry inline tests too:
uv run capt-hook --hooks docs/examples testDocs
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 previewBuild 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 --helpUsing a local checkout
From a consumer project, point uv run --project at your clone:
uv run --project path/to/captain-hook capt-hook testReleasing
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.1The 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.