What would you like to be added?
Improve the hook system's lifecycle coverage and matcher semantics so hooks can observe more Qwen Code events with precise, event-specific filtering.
Proposed scope:
- Add hook events for lifecycle points that already exist in the product:
PostToolBatch: once after a batch of tool calls resolves.
UserPromptExpansion: when a slash command expands into prompt content.
WorktreeCreate / WorktreeRemove: when managed worktree operations happen.
ConfigChange: when settings or extension configuration is reloaded.
InstructionsLoaded or ContextFileLoaded: when QWEN.md or related instruction/context files are loaded.
FileChanged: when tracked files are added, changed, or removed.
- Use payload field names that are easy to consume from hook scripts, for example:
InstructionsLoaded: { file_path, memory_type, load_reason, globs?, trigger_file_path?, parent_file_path? }
ConfigChange: { source, file_path }
WorktreeRemove: { worktree_path }
FileChanged: { file_path, event }
- Add event-specific matcher targets instead of matching every session hook against a tool name.
- Tool lifecycle hooks should still match
tool_name.
SessionStart should match its source.
StopFailure should match its error code.
Notification should match notification type.
- Instruction/context-file events should match the loaded file path or scope.
- Keep the existing matcher pattern syntax (
*, pipe alternatives, regex, exact match). This request is about choosing the right target per event, not reducing matcher expressiveness.
Why is this needed?
Qwen Code already has a strong hook foundation, but many useful lifecycle transitions are currently invisible to hook authors or cannot be filtered ergonomically.
Concrete benefits:
- Better debugging: users can answer "which instruction file was loaded, and why?" without guessing from model behavior.
- Better automation: teams can run setup, indexing, formatting, or audit hooks after worktree, config, file, or tool-batch changes.
- Less brittle hook scripts: users can filter
StopFailure on rate_limit or SessionStart on resume directly instead of parsing every payload inside the hook command.
- Better extension support: a richer event surface gives extensions and session-scoped hooks the same lifecycle vocabulary.
Additional context
The current code already has several pieces that would make this relatively incremental:
packages/core/src/hooks/types.ts defines the event enum and hook payload types.
packages/core/src/hooks/hookSystem.ts and hookEventHandler.ts provide the existing fire path.
packages/core/src/hooks/sessionHooksManager.ts already supports rich matcher syntax.
packages/core/src/hooks/hookRegistry.ts tracks hook source information across user, project, extension, and session sources.
A staged implementation would be reasonable:
- Add
PostToolBatch, UserPromptExpansion, and event-specific matcher targets.
- Add context/instruction-load and config-change events where the current loaders already have the required metadata.
- Add worktree and file-change events at the existing worktree/file-history service boundaries.
What would you like to be added?
Improve the hook system's lifecycle coverage and matcher semantics so hooks can observe more Qwen Code events with precise, event-specific filtering.
Proposed scope:
PostToolBatch: once after a batch of tool calls resolves.UserPromptExpansion: when a slash command expands into prompt content.WorktreeCreate/WorktreeRemove: when managed worktree operations happen.ConfigChange: when settings or extension configuration is reloaded.InstructionsLoadedorContextFileLoaded: when QWEN.md or related instruction/context files are loaded.FileChanged: when tracked files are added, changed, or removed.InstructionsLoaded:{ file_path, memory_type, load_reason, globs?, trigger_file_path?, parent_file_path? }ConfigChange:{ source, file_path }WorktreeRemove:{ worktree_path }FileChanged:{ file_path, event }tool_name.SessionStartshould match itssource.StopFailureshould match its error code.Notificationshould match notification type.*, pipe alternatives, regex, exact match). This request is about choosing the right target per event, not reducing matcher expressiveness.Why is this needed?
Qwen Code already has a strong hook foundation, but many useful lifecycle transitions are currently invisible to hook authors or cannot be filtered ergonomically.
Concrete benefits:
StopFailureonrate_limitorSessionStartonresumedirectly instead of parsing every payload inside the hook command.Additional context
The current code already has several pieces that would make this relatively incremental:
packages/core/src/hooks/types.tsdefines the event enum and hook payload types.packages/core/src/hooks/hookSystem.tsandhookEventHandler.tsprovide the existing fire path.packages/core/src/hooks/sessionHooksManager.tsalready supports rich matcher syntax.packages/core/src/hooks/hookRegistry.tstracks hook source information across user, project, extension, and session sources.A staged implementation would be reasonable:
PostToolBatch,UserPromptExpansion, and event-specific matcher targets.