Contributing¶
Running the tests¶
nexum uses only the Python standard library, so there are no dependencies to install. Run the test suite from the repo root:
python3 -m pytest tests/ -q
Or with the stdlib test runner (what CI uses):
python -m unittest discover -s tests -v
Both work. CI runs the unittest variant on Python 3.9, 3.11, and 3.13.
Code rules¶
Stdlib only. Allowed imports are: json, sqlite3, hashlib, os, sys, re, subprocess, pathlib, time, fnmatch, argparse, dataclasses, typing. No third-party packages, no pip installs. This constraint is permanent — the plugin must work in a fresh Claude Code environment with no setup.
Fail-open. Every hook script wraps its logic in try/except. On any internal error it prints {} to stdout and exits 0. A bug in nexum must never crash or block a user's Claude Code session.
Deterministic JSON. Any JSON emitted by a hook uses json.dumps(obj, sort_keys=True). Non-deterministic output invalidates the prompt cache and costs more than it saves.
No timestamps in model-visible content. Timestamps and UUIDs must not appear in any content that feeds a model prefix — they make every message unique and break caching.
Adding a feature¶
- Add or edit the relevant script under
scripts/. - Add or update tests under
tests/test_<module>.py. - Make sure
python -m unittest discover -s testspasses. - If the feature is user-visible, add or update the relevant docs page.
Releasing¶
nexum uses semantic versioning (MAJOR.MINOR.PATCH):
- PATCH — bug fixes, no user-visible behavior change.
- MINOR — new commands, hooks, or options, backward compatible.
- MAJOR — breaking changes to commands, hooks, config, or data layout.
To cut a release:
- Move items from
## [Unreleased]inCHANGELOG.mdinto a new## [X.Y.Z] - YYYY-MM-DDsection. - Bump both manifests in lockstep:
python tools/bump_version.py X.Y.Z - Verify locally:
python tools/check_version.pyandpython -m unittest discover -s tests - Commit:
git commit -am "Release vX.Y.Z" - Tag and push:
git tag vX.Y.Z && git push origin main --tags
Pushing the tag triggers the Release workflow, which runs the test suite, verifies the tag matches the manifest versions, and publishes a GitHub Release with the matching changelog section as the release notes.
Users pull the new version from within Claude Code:
/plugin marketplace update nexum