Conversation
…d registration - Replace HookMatcher with Hook base class; HookRegistry.register generates typed subclasses (e.g., PreToolUseHook) and DSL methods by convention - Replace 23 static *Input classes with a single dynamic HookInput - Move Hook responsibilities: dispatch (wraps input/context), to_config (builds CLI payload), matches? (tool name filtering), event_name (derived from class name) - Make HookRegistry Enumerable — it persists as the data structure in Options#hooks instead of compiling to a hash and being discarded - Add HookRegistry.wrap for uniform input normalization - Restructure into hooks/ directory - Update docs, CHANGELOG, SPEC, and architecture guide
b0b8fa7 to
fb32434
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Replaces the rigid per-event hook system with a dynamic, convention-based architecture. Adding a new CLI hook event is now one string in an array instead of changes to three separate files.
Why
Every new hook event required updating
HOOK_EVENTS,EVENT_MAP, and adefine_inputdeclaration — 23 events × 3 locations. The typed input classes (PreToolUseInput, etc.) weren't even used in the dispatch path. This refactor eliminates that maintenance burden and gives each type a clear reason to exist.How
Hook base class — replaces
HookMatcher. Owns matching (matches?), CLI serialization (to_config), and callback dispatch (dispatch).event_nameis derived from the class name by convention (PreToolUseHook→"PreToolUse"). Subclasses are generated per event byHookRegistry.register.HookInput — single dynamic class replacing 23 static
*Inputclasses. Base fields (session_id,cwd, etc.) are first-class readers; event-specific fields usemethod_missing. Frozen at construction.HookRegistry —
Enumerablecollection that persists as the data structure inOptions#hooks(no more compile-to-hash step).register("PreToolUse")generates both aPreToolUseHookclass and abefore_tool_useDSL method.wrapnormalizes any input type.from_hashbuilds from raw hashes.Hook#dispatch — wires
HookInputandHookContextinto the actual callback dispatch path (previously callbacks received raw hashes).Key changes
-648 linesnet (23 files, 780 additions, 1428 deletions)Hook,HookInput,HookContext,HookRegistryinhooks/directoryHook::CallbackEntryreplaces plain hash in callback registrybuild_hooks_configreduced from 20 lines to 7