Skip to main content

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:

  1. Codex invokes codhc as a command hook.
  2. Codex sends the hook payload to stdin.
  3. codhc runs the external command.
  4. codhc writes a single JSON response to stdout.
  5. If the command fails, codhc forwards the captured command output to stderr.

This separation keeps stdout clean for hook JSON while preserving useful failure output. Successful runs stay quiet apart from the minimal hook result.

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
}

This keeps successful Stop hooks explicit without producing a systemMessage, which Codex surfaces as a warning.

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 JSON
  • stdout: one JSON response emitted by codhc
  • stderr: 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.

Metadata

Release files for codhc 0.0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for codhc 0.0.5
File Size Uploaded
codhc-0.0.5.tar.gz 4.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for codhc 0.0.5
File Interpreter ABI Platform
codhc-0.0.5-py3-none-any.whl Python 3 none any Details

Total release size: 9.1 kB

Release files / codhc-0.0.5.tar.gz

Download URL codhc-0.0.5.tar.gz
Size 4.2 kB
Tags Source
SHA-256 checksum
How to use checksums
4c9bd6c1fb21f1988e07f5fd0e96d2b040513b3d2d6da4fc2a2dea8af103684c
BLAKE2b-256 checksum
How to use checksums
a3ad8aa0ffa4a4b74182f0d65976cdb94071af72cb635877ba29b5fe4f3d4fd5
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release files / codhc-0.0.5-py3-none-any.whl

Download URL codhc-0.0.5-py3-none-any.whl
Size 4.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aed973604e05be12f8ce6bdc52d908cb59dc900cd5e63930510ab1e81548d202
BLAKE2b-256 checksum
How to use checksums
3706c1e06d28bd096bbbf65cc7e7369699596050e34495650c553139e3d5c3f7
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release history Release notifications | RSS feed

This release

0.0.5 This release

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page