Skip to content

Improve hook lifecycle coverage and matcher targets #4343

@qqqys

Description

@qqqys

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:

  1. Add PostToolBatch, UserPromptExpansion, and event-specific matcher targets.
  2. Add context/instruction-load and config-change events where the current loaders already have the required metadata.
  3. Add worktree and file-change events at the existing worktree/file-history service boundaries.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions