Skip to main content

Audit your Claude Code config: dead hooks, duplicate levers, boot-token cost.

Project description

bridle-audit

CI PyPI Python versions License: MIT

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bridle_audit-0.1.0.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bridle_audit-0.1.0-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

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

Hashes for bridle_audit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 61e7e7670c5f72865f4c802f2ee018c348beddc2b3c36e7ee48d058f18745ffe
MD5 abb2edd6f98811474460b875a787d67d
BLAKE2b-256 be3da9643ad47ae5c3c29362171540f3ee23880d6c2e910db49d4c91cb313afb

See more details on using hashes here.

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

Hashes for bridle_audit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d4e5432ae7a8aedfd2e662578d8ebab1d2a95b82f2749117b6221e10f14403e9
MD5 6b8d7245cb72e130110fd1c0705f9d23
BLAKE2b-256 5c604d140c438b7026ffbec7a2a4d38974707e915f10c0da5e3304927b83af6b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page