You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR implements two new hook events for the Qwen Code hooks system:
StopFailure: Triggered when an API error ends a turn (replaces Stop event for error scenarios). Uses fire-and-forget mode where all outputs and exit codes are ignored.
PostCompact: Triggered after conversation compaction completes successfully, allowing users to perform post-compression actions
Screenshots / Video Demo
StopFailure:
Config:
Trigger:
Verify:
PostCompact:
Config:
Trigger:
Verify:
Dive Deeper
StopFailure Event
Purpose: Handle API errors gracefully without blocking the main flow
Fire-and-forget: All hook outputs and exit codes are ignored
This PR implements two new hook events (StopFailure and PostCompact) for the Qwen Code hooks system, with comprehensive test coverage and documentation. The implementation is well-structured, follows existing patterns, and all tests pass successfully. The code quality is high with proper error handling and type safety.
🔍 General Feedback
Strong test coverage: Both new features have extensive unit tests covering edge cases, error scenarios, and all enum variants
Consistent patterns: The implementation follows established hook system patterns (event types, input/output interfaces, fire-and-forget handling)
Good documentation: The hooks.md documentation is thorough with clear examples, use cases, and configuration samples
Type safety: Proper TypeScript types are defined for all new events, inputs, and outputs
Fire-and-forget design: StopFailure correctly implements the fire-and-forget pattern where all outputs and errors are ignored
Build verification: All TypeScript type checks, linting, and builds pass without errors
🎯 Specific Feedback
🟢 Medium
File: packages/cli/src/ui/hooks/useGeminiStream.ts:82-115 - The classifyApiError function uses case-insensitive matching via toLowerCase(), but the error type strings returned are lowercase. Consider adding a comment or using a more explicit matching strategy to clarify that the returned types must match StopFailureErrorType exactly.
File: packages/core/src/hooks/hookAggregator.ts:43-56 - The StopFailure special handling returns success: true and ignores all errors, which is correct for fire-and-forget. However, consider adding a debug log when errors are suppressed to help with troubleshooting hook failures in development mode.
File: packages/core/src/services/chatCompressionService.ts:362-372 - The PostCompact hook is fired after successful compression, but the summary passed to the hook should be validated to ensure it's not empty before firing. Currently, the test at line 1184 checks for empty summary handling, but the hook could still be called with an empty string in some edge cases.
🔵 Low
File: packages/cli/src/ui/hooks/useGeminiStream.ts:86 - The @internal JSDoc comment mentions "Exported for testing purposes" - consider using the project's standard pattern for test-only exports (if one exists) or add a @visibleForTesting annotation for consistency.
File: packages/core/src/hooks/types.ts:706-709 - The PostCompactOutput interface has a comment noting that control fields don't produce effects. Consider adding a similar comment to StopFailureOutput to clarify the fire-and-forget nature for future maintainers.
File: packages/core/src/hooks/hookPlanner.ts:241-245 - The HookEventContext interface adds error?: string for StopFailure. Consider adding a similar optional field documentation comment to explain when this field is populated.
File: packages/cli/src/ui/hooks/useGeminiStream.ts:830-860 - The handleErrorEvent callback fires the StopFailure hook but catches errors with .catch(). Consider extracting the error type classification and hook firing into a separate helper function for better testability and readability.
File: docs/users/features/hooks.md:323 - The StopFailure documentation mentions "fire-and-forget" but the exit code handling table shows "Any | Ignored". Consider explicitly stating "All exit codes are ignored" for clarity.
✅ Highlights
Excellent test coverage: The classifyApiError function has 17 test cases covering all error types, edge cases, and case-insensitive matching
Comprehensive documentation: The hooks.md documentation includes detailed examples, configuration samples, and use cases for both new events
Proper error isolation: Both StopFailure and PostCompact hooks are wrapped in try-catch blocks to prevent hook failures from affecting core functionality
Clean separation of concerns: The StopFailure event correctly replaces Stop only for API error scenarios (guaranteed by code path separation)
Well-structured types: The StopFailureErrorType union type provides clear, type-safe error classification with all expected error scenarios
Thoughtful trigger types: PostCompactTrigger enum (Manual/Auto) enables flexible hook configurations based on compression trigger source
For detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run.
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
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.
TLDR
This PR implements two new hook events for the Qwen Code hooks system:
StopFailure: Triggered when an API error ends a turn (replaces Stop event for error scenarios). Uses fire-and-forget mode where all outputs and exit codes are ignored.PostCompact: Triggered after conversation compaction completes successfully, allowing users to perform post-compression actionsScreenshots / Video Demo
StopFailure:



Config:
Trigger:
Verify:
PostCompact:



Config:
Trigger:
Verify:
Dive Deeper
StopFailureEventPostCompactEventReviewer Test Plan
StopFailurehook in settingsPostCompacthook in settings/compresscommandTesting Matrix
Linked issues / bugs