Audit your Claude Code config: dead hooks, duplicate levers, boot-token cost.
Project description
bridle-audit
Your Claude Code config grows in silence. Hooks pile up in settings.json —
some fire on every single turn — and keep firing long after the script
they point at was deleted. The same linter gets wired twice by two different
sessions. Skill descriptions are loaded into context at every session
start, and nobody counts what that boot costs. Configs only ever grow;
nothing prunes them.
bridle-audit is the pruner: one command, zero dependencies, reads your
real config and tells you exactly what is dead, doubled, or dormant.
- Dead hooks — commands wired to scripts that no longer exist (fired every turn, for nothing).
- Duplicate levers — the same script wired several times inside one event.
- Dormant cost — how many characters of skill descriptions you pay at every boot.
Install
pipx install bridle-audit
or
pip install bridle-audit
or straight from source:
pipx install git+https://github.com/trinity-organism/bridle-audit
Python >= 3.9. Zero dependencies — standard library only.
Usage
bridle-audit # audit $CLAUDE_CONFIG_DIR, falling back to ~/.claude
bridle-audit --config DIR # audit a specific config directory
bridle-audit --json # machine-readable output
Exit codes: 0 clean (or no config found), 1 at least one dead hook or
duplication, 2 config unreadable — so it drops straight into CI or a shell
prompt.
Before / after
Real output (username anonymized). Before — a config that grew for six months:
$ bridle-audit
bridle-audit — installed levers vs the ladder (context < skill < tool < hook < daemon)
hooks source: /Users/you/.claude/settings.json
[per session] SessionStart (1 hook)
ok session-banner.sh — /Users/you/.claude/hooks/session-banner.sh
[per turn] PreToolUse (2 hooks)
ok format-check.sh — /Users/you/.claude/hooks/format-check.sh
ok format-check.sh — /Users/you/.claude/hooks/format-check.sh
DUP format-check.sh x2 — same script, 2 voices in one event (one behavior, one lever, one place)
[per turn] Stop (1 hook)
DEAD notify.sh — /Users/you/.claude/hooks/notify.sh
dormant cost — 3 skills, ~414 chars of descriptions loaded at every session start
verdict — dead hooks: 1 · duplicate levers: 1 · skills: 3 (~414 chars/boot)
$ echo $?
1
After pruning the dead Stop hook and merging the duplicate into one matcher:
$ bridle-audit
bridle-audit — installed levers vs the ladder (context < skill < tool < hook < daemon)
hooks source: /Users/you/.claude/settings.json
[per session] SessionStart (1 hook)
ok session-banner.sh — /Users/you/.claude/hooks/session-banner.sh
[per turn] PreToolUse (1 hook)
ok format-check.sh — /Users/you/.claude/hooks/format-check.sh
dormant cost — 3 skills, ~414 chars of descriptions loaded at every session start
verdict — dead hooks: 0 · duplicate levers: 0 · skills: 3 (~414 chars/boot)
$ echo $?
0
And when there is nothing to audit:
$ bridle-audit --config /some/empty/dir
bridle-audit: no settings.json found in /some/empty/dir
Nothing to audit. If your Claude Code config lives elsewhere, point at it with --config DIR or $CLAUDE_CONFIG_DIR.
Hook commands are resolved the way a shell would: quoting (paths with
spaces), wrappers (nohup, bash -c, python3, ...), VAR=val prefixes
and $HOME/~ are all handled before the target is checked.
Philosophy
A bridle, not a harness rack: one behavior, one lever, one place — and always the cheapest lever that actually steers. A line of context beats a skill, a skill beats a tool, a tool beats a hook, a hook beats a daemon. This tool shows you where your config climbed that ladder without need.
Development
pip install -e ".[dev]"
pytest
The test suite fabricates synthetic configs in temp directories — it never
reads your real ~/.claude.
License
MIT
Project details
Release history Release notifications | RSS feed
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 bridle_audit-0.1.0.tar.gz.
File metadata
- Download URL: bridle_audit-0.1.0.tar.gz
- Upload date:
- Size: 9.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61e7e7670c5f72865f4c802f2ee018c348beddc2b3c36e7ee48d058f18745ffe
|
|
| MD5 |
abb2edd6f98811474460b875a787d67d
|
|
| BLAKE2b-256 |
be3da9643ad47ae5c3c29362171540f3ee23880d6c2e910db49d4c91cb313afb
|
File details
Details for the file bridle_audit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: bridle_audit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4e5432ae7a8aedfd2e662578d8ebab1d2a95b82f2749117b6221e10f14403e9
|
|
| MD5 |
6b8d7245cb72e130110fd1c0705f9d23
|
|
| BLAKE2b-256 |
5c604d140c438b7026ffbec7a2a4d38974707e915f10c0da5e3304927b83af6b
|