Skip to main content

harness-hooks

Installs the hooks that a config file lists into Claude Code and Codex, and removes them. Works on macOS and Linux.

Run it with uv:

uvx harness-hooks install path/to/harness-hooks.json
uvx harness-hooks remove path/to/harness-hooks.json

Or install it once, which puts harness-hooks on your PATH:

uv tool install harness-hooks

Config

{
  "name": "notify",
  "files": ["notify.py"],
  "hooks": {
    "Stop": [{"command": "python3 {dir}/notify.py {agent}", "timeout": 5}]
  },
  "claude": {
    "Notification": [{"matcher": "idle_prompt", "command": "python3 {dir}/notify.py claude"}]
  },
  "codex": {
    "PreToolUse": [{"matcher": "^request_user_input", "command": "python3 {dir}/notify.py codex"}]
  }
}
  • hooks go to both agents, claude and codex only to that agent.
  • {dir} becomes the folder with the hooks' files, so hooks can call scripts there. {agent} becomes claude or codex.
  • matcher and command mean what they mean in each agent's own hook files. Other fields, such as timeout, are copied as they are.
  • files, if given, lists the files the hooks need, as paths inside the config's folder.

Copies

With files in the config, install copies those files to ~/.claude/harness-hooks/<name>/ and ~/.codex/harness-hooks/<name>/, and {dir} points there. The hooks keep working when the config's folder moves or is deleted. Run install again to bring in changed files; remove deletes the copies.

Without files, or with --editable, {dir} is the config's folder, so an edit takes effect at once. --editable also deletes copies left by an earlier install. --project never copies.

Where hooks go

By default into ~/.claude/settings.json and ~/.codex/hooks.json, so they run in every project. CLAUDE_CONFIG_DIR and CODEX_HOME move these files, as they do for the agents.

With --project, into .claude/settings.json and .codex/hooks.json of the git repository that holds the config. Commit them, and everyone who clones the repository gets the hooks. {dir} is then found from the repository root, so the hooks work in any clone. Claude reads them only in sessions started at the repository root. Codex reads them only after you trust the project.

--agent claude or --agent codex touches only that agent.

How it finds its hooks

Each installed command ends with # harness-hooks: <name>. install replaces the commands with that mark and remove deletes them, so a hook dropped from the config disappears on the next run. Keep name the same once installed. It is also the copies' folder name, so it can't hold /. Hooks without the mark, such as ones you added by hand, are left alone, and the rest of each file is kept.

Codex asks you to review new or changed hooks at its next start. It remembers approvals by a hook's place in the file, so removing hooks can make it ask again about the hooks after them.

Development

From a clone, uv tool install --editable . runs the code in the clone, so an edit takes effect at once.

python3 -m unittest

Metadata

Release files for harness-hooks 0.1.0

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

Source distribution (sdist)

Source distribution for harness-hooks 0.1.0
File Size Uploaded
harness_hooks-0.1.0.tar.gz 7.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for harness-hooks 0.1.0
File Interpreter ABI Platform
harness_hooks-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 13.3 kB

Release files / harness_hooks-0.1.0.tar.gz

Download URL harness_hooks-0.1.0.tar.gz
Size 7.2 kB
Tags Source
SHA-256 checksum
How to use checksums
43f035ad5215059d23c1d9911b9919367cc3ea24db4dc54174b81e098aaea0bb
BLAKE2b-256 checksum
How to use checksums
64544dc4c51aaf755e8db643b595a71a7bcecb29a8160d34a74cbd68aadd52b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / harness_hooks-0.1.0-py3-none-any.whl

Download URL harness_hooks-0.1.0-py3-none-any.whl
Size 6.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
55ce8c285c8739ba306aeeab8936c883c2a1555493b57d76dea9db265300e319
BLAKE2b-256 checksum
How to use checksums
dd2397f42e9b5382da13a0b75a22204d1487174ea251e0bf7784b7c7c6cc7745
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

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