Hook Matchers: Precision Targeting

Day 36 · Week 8 · Hooks — Guardrails

Slack Message — copy & paste

🤖 Tip #36 — Hook matchers give you precision targeting — match only `git push --force`, not every Bash call. Glob-style wildcards, no regex.

#36 Claude Code

Matcher Syntax

  • Tool name plus optional argument pattern in parentheses
    • `"Bash"` — matches ALL Bash tool calls (too broad for most uses)
    • `"Bash(git commit*)"` — matches Bash calls starting with "git commit" (perfect for branch protection)
    • `"Bash(git push --force*)"` — matches only force pushes (precise, no false positives)
  • MCP and other tool matchers
    • `"mcp__*figma*"` — matches any MCP tool with "figma" in the name
    • `"Edit"` — matches all Edit tool calls (good for file validation)
    • `"Write(*.env*)"` — catches secret file creation
  • Wildcard rules
    • `*` matches anything (including nothing)
    • Pattern matches tool name and optionally arguments in parentheses
    • No regex — just glob-style wildcards
  • The `if` fieldfine-grained filtering inside a hook
    • `matcher` selects which tool events to listen for; `if` adds a second filter using permission rule syntax
    • Evaluated BEFORE spawning the hook process — avoids unnecessary shell invocations
    • Example: `"matcher": "Bash"` + `"if": "Bash(git commit*)"` — the hook entry fires on all Bash events, but only spawns the script for git commits
    • Example: `"matcher": "Edit"` + `"if": "Edit(**/.claude-plugin/**)"` — only validate plugin file edits, skip all other edits
    • Use `if` when your matcher is broad but your script only applies to a subset
Matchers Wildcards Patterns
#36 Hooks — Guardrails

Matchers for Every Risk

  1. 1 A matcher for every risk level
    • `Bash(rm -rf*)` — catch destructive deletions
    • `Bash(git reset --hard*)` — catch history destruction
    • `Write(*.env*)` — catch secret file creation
    • `Bash(curl*|*wget*)` — catch network calls
  2. 2 List the 3 most dangerous commands for your projectwrite a matcher for each and you have a safety net
  3. 3 Start specific, not broad`Bash(git commit*)` is better than `Bash` because it avoids false positives on harmless commands
  4. 4 Test matchers by asking the AI to run the matched commandverify the hook fires and the error message is clear
Matchers Wildcards Patterns
Your screenshot here Optional — add a screenshot from your own workflow
KAI by Dragan Filipovic