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"}]
}
}
hooksgo to both agents,claudeandcodexonly to that agent.{dir}becomes the folder with the hooks' files, so hooks can call scripts there.{agent}becomesclaudeorcodex.matcherandcommandmean what they mean in each agent's own hook files. Other fields, such astimeout, 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)
| File | Size | Uploaded | |
|---|---|---|---|
| harness_hooks-0.1.0.tar.gz | 7.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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}
|