Skip to content

extend: hooklint — lint Claude Code settings.json hooks (the unlinted config surface)#5

Open
deemwario wants to merge 1 commit into
mainfrom
extend/hooklint-cycle11
Open

extend: hooklint — lint Claude Code settings.json hooks (the unlinted config surface)#5
deemwario wants to merge 1 commit into
mainfrom
extend/hooklint-cycle11

Conversation

@deemwario

Copy link
Copy Markdown

Extend: hooklint — lint Claude Code settings.json hooks

#ossengine cycle 11extend the family, additive (new tool dir), no owner gate. Independent of the open PRs.

Why

The fleet lints permissions (perm-audit), .mcp.json (mcp-audit), CLAUDE.md (context-lint), and skills (skill-lint) — but nothing checked hooks, the one config that runs shell on your agent's tool events. A misconfigured hook fails silently: a typo'd event name (PreTooluse) never fires; an empty command never runs. hooklint catches those before they bite.

What it does

Reads settings.json and flags, with honest severity + heuristic labels:

  • UNKNOWN_EVENT — event name not in the valid 9-event set (silent no-op)
  • HOOK_BAD_COMMAND — missing type:command / empty command
  • MATCHER_IGNORED — a matcher on an event that ignores it (only PreToolUse/PostToolUse use it)
  • BAD_MATCHER_REGEX — matcher that won't compile
  • CMD_RELATIVE (heuristic) — relative command path that may not resolve
  • CMD_RISKY (heuristic) — rm -rf / curl … | sh / eval
  • empty event/group lists, plus structural-robustness codes (never tracebacks)

Exit 0 clean / 1 findings / 2 bad input; --json for CI. Honest by construction — it checks structure + known pitfalls, not whether a hook's logic is correct.

Verification (independently re-run)

  • test_hooklint.sh18/18 green (≥1 case per check + clean/missing-file/invalid-JSON/stdin/wrong-type).
  • Exit codes confirmed directly: bad→1, clean→0, missing→2, invalid-JSON→2. --json emits {findings, summary}.
  • Single-file python3, no deps. README house-style with the deemwar.com/contact CTA. MIT.

Self-discovering CI (PR #2) will pick up test_hooklint.sh automatically on merge.

🤖 Generated with Claude Code

New tool in the family. The fleet lints permissions (perm-audit), .mcp.json
(mcp-audit), CLAUDE.md (context-lint) and skills (skill-lint) — but nothing
checked hooks, which run shell on your agent's tool events and fail SILENTLY
when misconfigured (a typo'd event name never fires; an empty command never
runs).

hooklint reads settings.json and flags: unknown/typo'd event names, hook
entries missing type:command or an empty command, a matcher on an event that
ignores it, invalid matcher regex, and (heuristic, labelled) relative command
paths + risky command patterns. Exit 0 clean / 1 findings / 2 bad input;
--json for CI. Honest by construction — checks structure + known pitfalls,
not whether a hook's logic is correct.

- single-file python3, no deps; test_hooklint.sh 18/18 green (self-locating,
  one case per check + clean/missing/invalid/stdin/wrong-type robustness).
- house-style README with the deemwar.com/contact CTA. MIT.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant