Skip to content

perf: add matcher groups to PreToolUse/PostToolUse hooks#176

Merged
notque merged 2 commits intomainfrom
feat/hook-matcher-groups
Mar 27, 2026
Merged

perf: add matcher groups to PreToolUse/PostToolUse hooks#176
notque merged 2 commits intomainfrom
feat/hook-matcher-groups

Conversation

@notque
Copy link
Copy Markdown
Owner

@notque notque commented Mar 27, 2026

Summary

  • Split PreToolUse from 1 hook group (10 hooks, all firing on every tool call) into 7 matcher-filtered groups
  • Split PostToolUse from 1 hook group (13 hooks, all firing on every tool call) into 7 matcher-filtered groups
  • Remove dead tool_name self-filter code from 18 Python hooks (matcher now handles filtering before process spawns)
  • Remove orphaned constants (TARGET_TOOLS, TRACKED_TOOLS)

Performance impact

Tool call Before (processes spawned) After Reduction
Read/Grep/Glob 23 4-5 -78% to -83%
Agent 23 7 -70%
Bash 23 11 -52%
Edit 23 16 -30%

Why matcher not if

The new if field uses glob patterns anchored to command start. Our hard gates use substring matching to catch compound commands (cd dir && git commit). Using if on safety gates would miss edge cases — a correctness regression. The matcher field provides the biggest win without safety tradeoffs.

Test plan

  • Both settings.json files validate as correct JSON
  • All 18 modified hooks compile without syntax errors
  • Functional tests: hooks accept matching input and exit 0
  • Matcher-to-filter correspondence verified for all 23 hooks
  • Code review confirmed no argument-level filtering was removed
  • Unfiltered group (4 hooks) correctly has no matcher

notque added 2 commits March 26, 2026 18:12
Split PreToolUse from 1 group (10 hooks) into 7 matcher-filtered groups
and PostToolUse from 1 group (13 hooks) into 7 groups. This prevents
process spawning for non-matching tools — a Read/Grep/Glob call now
spawns 0 PreToolUse hooks instead of 10.

Matcher groups: Bash, Bash|Edit, Bash|Write|Edit, Write|Edit, Write,
Edit, Agent, Read, Skill|Agent, and an unfiltered group for hooks that
need all tool events.

Remove dead tool_name self-filter code from 18 Python hooks — the
matcher in settings.json now handles filtering before the process
spawns. Dead constants (TARGET_TOOLS, TRACKED_TOOLS) also removed.
Tests that verified tool_name self-filtering now document that filtering
is handled by the matcher field in settings.json. Hooks still exit 0
for any input (non-blocking), so tests verify that contract instead.

Fix ruff I001 import sorting in record-activation.py.
@notque notque merged commit 1097468 into main Mar 27, 2026
4 checks passed
@notque notque deleted the feat/hook-matcher-groups branch March 27, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant