Claude Code Hooks
A battle-tested guide to writing, testing, registering and debugging Claude Code PreToolUse/PostToolUse/SessionStart/Stop hooks.
Dev & CodingAdvanced★ 1,323⑂ 212AI score 9/10Last updated: Aug 8, 2026
What it does
Turns a rule Claude keeps talking itself past into a structural wall — a hook — instead of another line of prose in CLAUDE.md.
- Clear map of every hook type, when it fires, and what each exit code means (0 = allow, 2 = block)
- Ready-to-copy PreToolUse Bash guard skeleton plus runnable patterns (references/hook_patterns.md)
- Token-level matching with
shlex.shlex(punctuation_chars=True)so healthy commands aren't false-blocked (no awk splitting) - A hard pre-registration gate:
bash -nplus real JSON event end-to-end tests, with a bundled test harness script - SSOT + symlink layout so a
~/.claudereinstall can't silently disarm a guard - Multi-profile convergence and human-only release valves (osascript dialog, typed YES on /dev/tty)
- Termination proofs (loop variant V) so a Stop hook can't spin forever
Who it's for
- Developers who want to hard-block irreversible actions: force pushes, file deletion, secrets leaving the machine
- Team leads tired of repeating a rule that keeps getting violated anyway
- Anyone whose existing hook misfires, silently misses, or "poisons the session"
- Operators rolling guardrails out consistently across profiles and machines
Examples
- "Block
git push --forcefor good" → generates a PreToolUse guard that checks command position and still letsgrep, comments and commit-message mentions through. - "My new hook blocks perfectly fine commands" → diagnoses raw-string/awk splitting and replaces it with the shlex command-position walker.
- "Stop Claude from believing it committed when it didn't" → designs a PostToolUse hook that re-reads real git HEAD and injects authoritative context.
· · · Install guide · · ·
Install in the Claude app (no terminal)
- Download the ZIP with the button below.
- In Claude, open Settings → Capabilities and turn on 'Code execution and file creation'. (one time)
- Go to Customize → Skills → + → 'Upload a skill' and upload the ZIP.
Install in Claude Code
Let Claude do it — paste this into Claude Code
Install the skill I found on Claude Skill Mart. Copy the daymade-claude-code/claude-code-hooks folder from the GitHub repo daymade/claude-code-skills into my ~/.claude/skills/claude-code-hooks/. When it's done, tell me in one line what this skill can do.
Install with a command instead
git clone https://github.com/daymade/claude-code-skills.git /tmp/daymade-skills && mkdir -p ~/.claude/skills && cp -r /tmp/daymade-skills/daymade-claude-code/claude-code-hooks ~/.claude/skills/⚠ This is a third-party skill. Check the source repository before installing.
- Open a terminal.
- Make sure the skills folder exists:
mkdir -p ~/.claude/skills - Clone the repo to a temp dir:
git clone https://github.com/daymade/claude-code-skills.git /tmp/daymade-skills - Copy just this skill:
cp -r /tmp/daymade-skills/daymade-claude-code/claude-code-hooks ~/.claude/skills/ - Verify:
ls ~/.claude/skills/claude-code-hooks— you should see SKILL.md, references/ and scripts/. - Restart Claude Code and try a prompt like "write a hook that blocks rm -rf"; the skill triggers automatically.
- Important: before registering any generated hook, run
bash -n hook.shandscripts/test_hook.sh. A broken PreToolUse hook can break every Bash call in the session. - To roll back, delete the hook entry from
~/.claude/settings.json(and remove the symlink in~/.claude/hooks/).
View source on GitHub ↗License: MIT