Hooklint
Description
Offline linter for the agent config that actually executes: hooks, skills, MCP entries, permission rules. Catches the hook that can never fire and the hook that splices agent-controlled text into a shell command unquoted.
Installation
This entry records only its repository, not the path inside it, so there is no
exact command to give. Open the source below and copy the folder into
~/.claude/skills/, or the file into ~/.claude/agents/.
README
hooklint
You pasted a hook out of a 53,000-star awesome-list into a tool that executes shell on your machine. Two failure modes look identical in the config file: a hook whose matcher can never fire, and a hook that splices tool-output or fetched content into a shell command unquoted. `hooklint` finds both, and six more, anchored to a JSON Pointer into the offending file. It parses; it never executes a hook.
$ hooklint .claude/settings.json
ERROR .claude/settings.json /hooks/PreToolUse/0/matcher [dead_matcher]
PreToolUse hook #0: matcher 'Bahs' matches none of the declared tool names; this hook will never fire
evidence: 'Bahs'
hooklint: scanned 1 file(s), 1 finding(s), 0 parse error(s), unknown_rate=0.0000 (0/9)
That's a typo (`Bahs` for `Bash`) that JSON-validates fine and silently does nothing, forever. Here's the other failure mode, from a generic YAML hook manifest:
$ hooklint agent-hooks.yaml
ERROR agent-hooks.yaml /hooks/pre_tool_use/0/run [unquoted_interpolation]
unquoted/double-quoted shell expansion '$USER_MESSAGE'; if the expanded value is tool output or fetched content this is command injection
evidence: $USER_MESSAGE
hooklint: scanned 1 file(s), 1 finding(s), 0 parse error(s), unknown_rate=0.0000 (0/6)
That one runs. It just runs whatever `$USER_MESSAGE` happens to contain, unquoted, in a shell.
Why this one
| what exists | stars |
|---|---|
hesreallyhim/awesome-claude-code |
53.4k |
PatrickJS/awesome-cursorrules |
40.7k |
wshobson/agents |
39.4k |
| any linter for these configs | 63 |
The ecosystem produced collections, not verification.
Install
pipx run hooklint /path/to/repo
No account, no API key, no network, no client installed. Or:
pip install hooklint
hooklint . # scan the current directory
hooklint --json . # machine-readable
python -m hooklint . # also works
What it checks
Hook commands are parsed as **s
Related Skills
Auto Update
Pull the latest ECC repo changes and reinstall the current managed targets.
Development Ecc Guide
Navigate ECC's current agents, skills, commands, hooks, install profiles, and docs from the live repository su
Development Epic Claim
Claim an epic issue, stamp coordination state, and sync local ownership.
Development Epic Publish
Publish a validated epic update back to the issue and local cache.
Development Epic Review
Mark epic review requested, approved, or changes requested.
Development Epic Unblock
Sweep blocked epic issues and reopen anything whose dependencies are closed.
Development Related Agents
Django Build Resolver
Django/Python build, migration, and dependency error resolution specialist. Fixes pip/Poetry errors, migration
Openai Codex CLI
(55.8k ⭐) - Lightweight coding agent that runs in your terminal.
src/agents/ — 11 Agent Definitions
**Generated:** 2026-04-11