No project description provided
Project description
Codex Hook Command
codhc is a small command wrapper for Codex hooks. It runs an external command, reads the hook payload from stdin, and emits the JSON response that Codex expects.
This project is built for the Codex hook workflow first, especially the Stop hook. It is not a general shell runner and it is not a hook framework. Its job is to stay small, predictable, and easy to wire into hooks.json.
Start Here
If you are using codhc, this is the main integration point:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "uvx codhc ruff check --fix",
"timeout": 30
}
]
}
]
}
}
That configuration tells Codex to run codhc during the Stop hook. codhc then runs the command you give it and converts the result into a Codex-compatible response.
For the broader Codex hook model, including events, matchers, and payload shapes, see docs/HOOKS.md.
What It Does
codhc has a deliberately narrow contract:
- Read the hook payload from
stdin - Run the external command you provide
- Inspect
stop_hook_active - Return a hook response based on command success or failure
That narrow scope is intentional. The tool is designed to be a thin adapter, not a policy engine.
How It Flows
The runtime model is simple:
- Codex invokes
codhcas a command hook. - Codex sends the hook payload to
stdin. codhcruns the external command.codhcwrites a single JSON response tostdout.- If the command fails,
codhcforwards the captured command output tostderr.
This separation keeps stdout clean for hook JSON while preserving useful failure output.
Installation
Install it as a tool:
uv tool install .
codhc uv run ruff check --fix
Or run it with uvx:
uvx codhc uv run ruff check --fix
CLI Usage
codhc <command> [args...]
Examples:
codhc uv run ruff check --fix
codhc uv run pytest -q
codhc python -m compileall src
If no command is provided, codhc exits non-zero, prints a usage message to stderr, and emits no hook JSON.
Command Semantics
codhc executes argv exactly as it receives it.
- It does not parse shell strings.
- It does not provide subcommands.
- It does not re-tokenize your command.
Use this:
codhc uv run ruff check --fix
Not this:
codhc "uv run ruff check --fix"
Stop Hook Behavior
The current implementation is aimed at the Codex Stop hook and only reads one payload field:
{
"stop_hook_active": false
}
If stdin is empty, invalid JSON, or not a JSON object, codhc treats that as missing hook metadata and still runs the command.
Success
If the command exits with 0, codhc emits:
{
"continue": false,
"systemMessage": "`uv run ruff check --fix` passed."
}
First failure
If the command fails and stop_hook_active is not true, codhc emits:
{
"decision": "block",
"reason": "`uv run ruff check --fix` failed. Inspect the command output, fix the issues, then stop again."
}
This uses the documented legacy continuation shape for Stop hooks.
Failure after the continuation pass
If the command fails and stop_hook_active is true, codhc emits:
{
"continue": false,
"systemMessage": "`uv run ruff check --fix` failed after the Stop continuation pass."
}
I/O Contract
stdin: Codex hook payload JSONstdout: one JSON response emitted bycodhcstderr: captured command output, usually only useful on failure
stdout is reserved for hook JSON. External command output is not forwarded there.
Development
Install development dependencies:
uv sync --group dev
Run the standard checks:
just format
just lint
just type
just test
just all
Run the tools directly with uv:
uv run pytest -v -s --cov=src tests
uv run ruff check --fix
uv run ty check
If you are working from this repository and want to run the package from the local checkout without installing it as a tool, use:
uvx --from . codhc uv run ruff check --fix
Design Constraints
This version does not:
- validate the hook event name
- implement timeout handling itself
- inject custom environment variables
- add tool-specific behavior
- parse shell quoting or reconstruct commands
Those boundaries are deliberate. If the tool grows past them, it should do so only for a concrete hook use case.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file codhc-0.0.2.tar.gz.
File metadata
- Download URL: codhc-0.0.2.tar.gz
- Upload date:
- Size: 4.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bd2ef5291b285e0e8f3f59cf848f4f60cebdc8e05e10437f225e61eb0c38ec4
|
|
| MD5 |
fbb162b8d6bdda33becda14c7ede3ab5
|
|
| BLAKE2b-256 |
5ffa9384cecf867f07e9cb06d52609beef78b112c3b13d7af8d88c42c1f5cee4
|
File details
Details for the file codhc-0.0.2-py3-none-any.whl.
File metadata
- Download URL: codhc-0.0.2-py3-none-any.whl
- Upload date:
- Size: 4.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9bec600136b6d465d5338b3cf11907ece01de16e7a78e086f842a5d9e715932
|
|
| MD5 |
e2579c8116cd2250a32c1df16767cb18
|
|
| BLAKE2b-256 |
3f48f00c9bd674f4edc2085c1bc5b0ba1901b6a2b6827605b9ece9bb359335df
|