Hook Shipyard
Install the standalone distribution and use its canonical import:
python -m pip install hook-shipyard
hook-shipyard --help
hook-shipyard --version
hook_shipyard is a standard-library-only tool for Claude Code, Codex, Cursor,
Devin CLI and VS Code's Copilot harness. It neither imports nor starts District.
District is one consumer; its adapters live in hook/tools/district/.
events.py normalizes lifecycle payloads. native.py manages registration and
native response formatting for observation integrations. templates.py renders
packaged .tmd resources with strict literal substitution.
Create a non-monitoring command hook in an explicit disposable project:
python -m hook_shipyard install --provider codex --project \
--root /path/to/project --owner formatter --phase after_tool \
--command 'python scripts/format.py' --matcher 'Write|Edit' --timeout 10
python -m hook_shipyard list --provider codex --project \
--root /path/to/project --owner formatter
python -m hook_shipyard uninstall --provider codex --project \
--root /path/to/project --owner formatter
install replaces that owner's complete registration set. The Python API accepts
multiple HookSpec objects in one install. Different owners remain independent.
Use --event for native events or --phase for the shared lifecycle vocabulary:
session_start, session_end, before_tool, after_tool, prompt, stop.
Only supported native equivalents are accepted; payloads, matcher syntax and
tool names still belong to the destination host. Shell commands are trusted
operator code, not values interpolated from hook stdin. They run only when the
host fires the event; installing or listing never executes them.
The included non-monitoring policy blocks exact configured tool names:
python -m hook_shipyard.guard --provider codex --deny-tool Bash
Register that command at before_tool using the same provider. The guard reads
bounded JSON from stdin, emits that host's native denial for a blocked name, and
otherwise emits {} (no permission decision). It writes no telemetry or logs.
Its role is a small deterministic policy example, not a sandbox or protection
against every tool alias. Test the actual native tool names before relying on it.
Configuration roots are explicit. Defaults relative to that root are
.claude/settings.json, .codex/hooks.json, .cursor/hooks.json,
.config/devin/config.json (user) or .devin/config.json (project), and
.copilot/hooks/kairos.json (user) or .github/hooks/kairos.json (project) for
VS Code Copilot. Custom home environment variables and Windows APPDATA layouts
can be represented with an explicit Provider.relative override in the Python
API. Native hook discovery/trust still needs verification in the target host.
The manager preserves foreign fields and mixed matcher groups, creates one
private .hook-shipyard-bak backup, and records versioned per-owner registrations in a
private .hook-shipyard-owners sidecar. Atomic replacements preserve native file modes.
Malformed JSON, unsupported versions, symlinks, duplicate ownership and busy
locks refuse changes. Interrupted transactions retain old/new ownership intent
so a retry can reconcile them. Cooperating managers serialize using an exclusive
.hook-shipyard-lock file; after a crashed process, confirm it has stopped before
removing that stale lock. Non-cooperating editor writes need coordination.
Backups and receipts remain after uninstall for recovery; protect and remove
them according to the operator's retention policy.
fail_closed=True is only accepted for Cursor's native failClosed. Other
providers' failure and timeout semantics differ, so that request is rejected.
Codex end/interrupt deadlines are bounded by its three-second native maximum.
No installation changes trust hashes, enables host features, approves commands,
or bypasses the provider's permissions or enterprise settings.
Files: __init__.py exports the API; __main__.py and cli.py expose the CLI;
models.py defines registrations and provider capabilities; providers.py
selects schemas and lifecycle names; manager.py owns lifecycle; merge.py
preserves foreign commands; storage.py owns atomic local I/O; receipts.py
versions ownership; guard.py supplies the policy example; pyproject.toml
packages the independent hook-shipyard distribution.
Provider contracts checked against primary documentation on 2026-11-01: Claude Code, Codex, Cursor, Devin, and VS Code.
Directory contents
Files
__init__.py— Manage native agent hooks independently of their consumers.__main__.py— Run the standalone hook management CLI.cli.py— Manage native hooks without running commands or enabling monitoring.events.py— Normalize native agent lifecycle payloads for any hook consumer.guard.py— Implement a standalone non-monitoring pre-tool policy for native hosts.manager.py— Manage owner-scoped hooks without importing a monitoring implementation.merge.py— Remove only recorded commands while preserving mixed native groups.migrations.py— Read explicit legacy sidecar names without guessing ownership.models.py— Define consumer-neutral native hook registrations.native.py— Manage native lifecycle registration and wire responses for any consumer.providers.py— Keep provider schema differences outside every consuming tool.pyproject.toml— Provide pyproject toml content.receipts.py— Version private ownership state separately from native host schemas.storage.py— Protect shared JSON configuration with bounded, atomic local writes.templates.py— Render packaged consumer templates without evaluating executable code.
Subdirectories
resources/— No subdirectories.
Metadata
Release files for hook-shipyard 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| hook_shipyard-0.1.0.tar.gz | 18.1 kB | Without provenance | Details for hook_shipyard-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| hook_shipyard-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for hook_shipyard-0.1.0-py3-none-any.whl |
Total release size: 42.1 kB
Release files / hook_shipyard-0.1.0.tar.gz
| Download URL | hook_shipyard-0.1.0.tar.gz |
|---|---|
| Size | 18.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0495a2dd35512bac94bab7da9f886e0c96e4c2d39e6244320e9c25398386b57d
|
|
BLAKE2b-256 checksum How to use checksums |
2d251d0f2084108604680793ef3617a105f9c47cf72128e4a0828f1d5c371fb0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Release files / hook_shipyard-0.1.0-py3-none-any.whl
| Download URL | hook_shipyard-0.1.0-py3-none-any.whl |
|---|---|
| Size | 24.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5ab7685e0440cc07e771934c4df7591fea76598b2d2830ee9f7416ba1f30daaa
|
|
BLAKE2b-256 checksum How to use checksums |
193a6875a3ba9f964435d0de5e6a84f93b3f50bbf9a19b7a7873d6c7cd64d613
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Security for hook-shipyard 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.