Hooks Patterns
Claude Code hook patterns from production usage. Every entry has a date and context.
2026-03: PreToolUse Auto-Backup Before Every Edit
Problem: Claude Code edits files directly. If an edit breaks something, the original is gone (git can recover, but it’s friction).
Context: Daily editing across 15 repos, protecting against destructive edits.
The Fix:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit",
"command": "mkdir -p ~/.claude/backups/auto-edit-backups/$(date +%Y%m%d) && cp \"$CLAUDE_FILE_PATH\" ~/.claude/backups/auto-edit-backups/$(date +%Y%m%d)/$(basename \"$CLAUDE_FILE_PATH\").$(date +%H%M%S).bak 2>/dev/null || true"
},
{
"matcher": "Write",
"command": "mkdir -p ~/.claude/backups/auto-write-backups/$(date +%Y%m%d) && cp \"$CLAUDE_FILE_PATH\" ~/.claude/backups/auto-write-backups/$(date +%Y%m%d)/$(basename \"$CLAUDE_FILE_PATH\").$(date +%H%M%S).bak 2>/dev/null || true"
}
]
}
}
Rule: PreToolUse hooks fire BEFORE the tool executes. Auto-backup every edit. Organized by date. || true prevents hook failure from blocking edits. Insurance, not friction.
2026-03: PostToolUse Attribute Validation
Problem: AsciiDoc files with undefined {attributes} render broken but don’t cause build errors — silent failures.
Context: domus-* repos, Antora documentation with 200+ attributes.
The Fix:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"command": "~/.claude/hooks/validate-asciidoc-attrs.sh"
},
{
"matcher": "Write",
"command": "~/.claude/hooks/validate-asciidoc-attrs.sh"
}
]
}
}
The validation script (172 lines):
-
Extracts
{attribute}references from the edited.adocfile -
Walks directory tree to find nearest
antora.yml -
Checks if each attribute is defined
-
Skips 100+ built-in AsciiDoc attributes
-
Warns on undefined custom attributes
-
Always exits 0 (warns, never blocks)
Rule: PostToolUse hooks for validation. Always exit 0 to avoid blocking work. Warn loudly, don’t block silently.
2026-03: UserPromptSubmit Security Scanning
Problem: Accidental staging of .env files, credentials, or private keys before commit.
Context: Security-first workflow, secrets protection.
The Fix:
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "*",
"command": "git diff --cached --name-only 2>/dev/null | grep -E '\\.(env|key|pem|credentials)' && echo 'WARNING: Staged files may contain secrets!' || true"
}
]
}
}
Rule: UserPromptSubmit fires on every user message. Use it for ambient security scanning. Check staged files for sensitive patterns before any commit-related work begins.
2026-03: SessionStart Professional Environment Banner
Problem: Need visual confirmation that Claude Code loaded with correct configuration (hooks, backups, etc.).
Context: Multi-machine setup (Razer, P16g), confirming environment consistency.
The Fix:
{
"hooks": {
"SessionStart": [
{
"matcher": "*",
"command": "echo 'Professional Environment Active' && echo \"Output Style: Professional (No AI Attribution)\" && echo \"Config Backups: $(find ~/.claude/backups -name '*.bak' 2>/dev/null | wc -l) files\""
}
]
}
}
Rule: SessionStart hooks run once when Claude Code launches. Use for environment verification, not heavy computation. Fast feedback that your config is loaded.