Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3.1 KiB
Hooks
Hook scripts are deterministic enforcement — unlike rules (advisory), hooks guarantee behavior by blocking or modifying tool calls before/after they execute.
Hooks are wired in settings.json under the "hooks" key. Each hook specifies an event, a matcher, and a command to run.
Available Hooks
protect-files.sh
Event: PreToolUse (Edit|Write)
Blocks edits to sensitive and generated files. Fails closed (blocks if jq is missing).
.env,.env.*— secrets (by basename and path)*.pem,*.key,*.crt,*.p12,*.pfx— certificates and keysid_rsa,id_ed25519,credentials.json,.npmrc,.pypirc— credentialspackage-lock.json,yarn.lock,pnpm-lock.yaml— lock files*.gen.ts,*.generated.*— generated code*.min.js,*.min.css— minified bundles- Anything inside
.git/,secrets/, or.claude/hooks/ - Self-protecting: blocks edits to hook scripts and
settings.json
warn-large-files.sh
Event: PreToolUse (Edit|Write)
Blocks writes to build artifacts, dependency directories, and binary files. Fails closed.
node_modules/,vendor/,dist/,build/,.next/,__pycache__/,.venv/*.wasm,*.so,*.dylib,*.dll,*.exe,*.zip,*.tar.**.mp4,*.mov,*.mp3,*.pyc,*.class
block-dangerous-commands.sh
Event: PreToolUse (Bash)
Blocks dangerous shell commands. Detects patterns even in chained commands (&&, ;). Fails closed.
- Git:
git push origin main/master,git push --force(allows--force-with-lease), baregit pushon main - Filesystem:
rm -rf /,rm -rf ~, recursive delete on root/home paths - Database:
DROP TABLE/DATABASE,DELETE FROMwithout WHERE,TRUNCATE TABLE - System:
chmod 777, pipingcurl/wgettobash/sh,mkfs,dd if=, writes to/dev/
format-on-save.sh
Event: PostToolUse (Edit|Write)
Auto-formats files after Claude edits them. Auto-detects formatters by checking for both the binary and a config file:
- Biome:
biome.json+node_modules/.bin/biome - Prettier:
.prettierrc*orpackage.jsonprettier key +node_modules/.bin/prettier - Ruff:
ruff.tomlorpyproject.toml [tool.ruff]+ruffbinary - Black:
pyproject.toml [tool.black]+blackbinary - rustfmt: standard for Rust (no config needed)
- gofmt: standard for Go (no config needed)
session-start.sh
Event: SessionStart
Injects dynamic project context at session start: current branch (or detached HEAD warning), last commit, uncommitted changes count, staged changes indicator, and stash count.
Adding Your Own
- Create a
.shscript in this directory - Make it executable:
chmod +x your-hook.sh - Wire it in
settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/your-hook.sh"
}
]
}
]
}
}
- Exit 0 = allow, Exit 2 = block
- Scripts receive JSON on stdin with
tool_input - Requires
jqfor JSON parsing
See Claude Code docs for all hook events.