Loading...
Loading...
Creates or audits a Claude Code hook. Use when user says 'add a hook', 'create a hook', 'review our hooks', 'audit hooks', 'wire up a format-on-save hook', 'block edits to secrets', or 'our hooks are broken'. Do NOT use for skills (use create-or-audit-skill), agents (use create-or-audit-agent), or settings (edit `settings.json` directly).
npx skill4agent add thommann/skills create-or-audit-hookskills/meta/create-or-audit-hook/templates/hook.shskills/meta/create-or-audit-hook/lib/validate.shPreToolUsePostToolUseStopSessionStart02| You want... | Event | Matcher |
|---|---|---|
| Block a write to protected files | | |
| Refuse a dangerous shell command | | |
| Format a file after editing | | |
| Run typecheck before "done" | | — |
| Warm caches at session start | | — |
cp .claude/skills/meta/create-or-audit-hook/templates/hook.sh .claude/hooks/{hook-name}.sh
chmod +x .claude/hooks/{hook-name}.sh#!/usr/bin/env bashset -euo pipefailinput=$(cat)exit 0exit 2echo "BLOCKED: reason + instead" >&2command -vexit 1settings.json{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": ".claude/hooks/{hook-name}.sh" }]
}
]
}
}bash skills/meta/create-or-audit-hook/lib/validate.sh .claude/hooks/{hook-name}.shecho '{"tool_name":"Write","tool_input":{"file_path":"test.py","content":"x"}}' | \
bash .claude/hooks/{hook-name}.shfor f in .claude/hooks/*.sh; do
echo "=== $f ==="
bash skills/meta/create-or-audit-hook/lib/validate.sh "$f" | tail -5
donesettings.jsonjq -r '.hooks | to_entries[] | .value[] | .hooks[]?.command' .claude/settings.json \
| grep -oE '[^/]+\.sh$' | sort -u > /tmp/wired.txt
ls .claude/hooks/*.sh | xargs -n1 basename | sort > /tmp/exists.txt
comm -23 /tmp/exists.txt /tmp/wired.txt # hooks that exist but are not wired
comm -13 /tmp/exists.txt /tmp/wired.txt # wirings that point to missing hooksPostToolUsecommand -v ruff >/dev/null 2>&1 || exit 0exit 2>&2curlwgetfetchSessionStart## Hooks Audit
### Verdict per hook
| Hook | Event | Wired? | Validator | Gates |
|---|---|---|---|---|
| protect-sensitive-files.sh | PreToolUse | yes | PASS | all |
| ... |
### Orphan hooks (remove or wire)
...
### Broken wirings (point to missing files)
...
### Proposed additions (hooks the codebase would benefit from)
...bash skills/meta/create-or-audit-hook/lib/validate.sh .claude/hooks/{name}.sh
# Expected: VERDICT: PASS
# Dry-run with a representative payload
echo '{"tool_name":"Write","tool_input":{"file_path":"x.py"}}' | bash .claude/hooks/{name}.sh| Mistake | Correction |
|---|---|
Hook file exists but isn't in | Wire it. Claude Code only runs what's declared. |
| |
| Add |
Reading | Write's payload is |