Safety Hook: Block Dangerous Commands
The most critical hook is a PreToolUse safety guard that prevents Claude from running destructive commands:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "echo \"$TOOL_INPUT\" | grep -qE \"(rm -rf|git push --force|git reset --hard|DROP TABLE|docker system prune)\" && echo \"BLOCKED: Dangerous command detected\" && exit 1 || exit 0"
}
]
}
}
This hook intercepts every Bash command and checks for destructive patterns. If it finds rm -rf, git push --force, git reset --hard, or similar dangerous operations, it blocks the execution before it happens. This is especially important when using Claude Code in autonomous mode where it makes decisions without asking.
Auto-Commit Hook: Structured Git History
You can hook into commit operations to enforce commit message conventions:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"command": "echo \"$TOOL_INPUT\" | grep -q \"git commit\" && cd $PROJECT_DIR && git log -1 --pretty=%s | grep -qE \"^(feat|fix|refactor|test|docs|chore|perf)\\(\" || echo \"Warning: commit message doesn’t follow conventional format\" || true"
}
]
}
}
Context Injection with UserPromptSubmit
The UserPromptSubmit hook lets you inject context into every conversation. This is powerful for setting project-specific context that Claude should always have:
{
"hooks": {
"UserPromptSubmit": [
{
"command": "echo \"Current branch: $(git branch --show-current). Last commit: $(git log -1 --oneline). Modified files: $(git diff --name-only HEAD | head -5)\""
}
]
}
}
Every time you submit a prompt, Claude receives the current git branch, last commit, and modified files as additional context. This means Claude always knows where you are in the codebase without you having to explain it.
Advanced: Multi-Agent Safety Hooks
If you’re using Claude Code’s agent teams (multi-agent coordination where sub-agents work in parallel), hooks become even more critical. Each agent can be configured with its own hooks to enforce boundaries:
- Read-only agents: PreToolUse hook that blocks Edit/Write/Bash for research-only agents
- Scoped agents: PreToolUse hook that only allows edits to specific directories
- Auditing: PostToolUse hook that logs every agent action for review
WOWHOW sells pre-configured Claude Code agent team packs with safety hooks already built in — 12-agent specialist teams with safety guardrails, auto-lint, and structured workflows ready to deploy.
Environment Variables Available in Hooks
Every hook receives environment variables that let you make smart decisions:
$TOOL_NAME — which tool is being called (Edit, Write, Bash, etc.)
$TOOL_INPUT — the full input to the tool (file path, command, etc.)
$FILE_PATH — the file being edited (for Edit/Write hooks)
$PROJECT_DIR — the project root directory
These variables let you write hooks that are context-aware. For example, you could block edits to production config files while allowing edits to test files, or only run expensive linting on TypeScript files.
Real-World Hook Configuration
Here’s a production-grade hook configuration that we use at WOWHOW for the storefront codebase:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "/path/to/safety-guardian.sh"
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "cd $PROJECT_DIR && npx biome check --fix $FILE_PATH 2>/dev/null; exit 0"
}
],
"UserPromptSubmit": [
{
"command": "echo \"Git: $(git branch --show-current) | $(git diff --stat HEAD | tail -1)\""
}
]
}
}
The safety-guardian.sh script is a comprehensive safety check that blocks destructive operations, validates file paths, and logs all commands for audit. This is the same setup powering our 12-agent team configuration.
Common Mistakes to Avoid
Based on our experience running hooks in production:
- Don’t make hooks too slow. Every PreToolUse hook adds latency to every tool call. Keep them under 100ms. If you need heavy validation, run it in PostToolUse instead.
- Don’t block on non-critical failures. Use
|| true or exit 0 for non-critical PostToolUse hooks. A failing lint hook shouldn’t stop Claude from working.
- Do use project-level settings. Put hooks in
.claude/settings.local.json (gitignored) rather than the shared .claude/settings.json unless the whole team should use them.
- Do test hooks manually first. Run your hook command in the terminal with sample inputs before adding it to the configuration.
Getting Started
The fastest path to useful hooks:
- Create
.claude/settings.local.json in your project
- Add the auto-lint PostToolUse hook (adapt to your linter)
- Add the safety PreToolUse hook (block dangerous commands)
- Run a few Claude Code tasks and verify hooks fire correctly
- Iterate: add more hooks as you discover patterns that need enforcement
Hooks transform Claude Code from an AI assistant into an autonomous engineering system with guardrails. Use our free token counter to estimate the cost of longer Claude Code sessions, and check out the developer tools collection for pre-built agent team configurations with hooks included.
Comments · 0
Beta: comments are stored locally on your device and not visible to other readers.
No comments yet. Be the first to share your thoughts.