feat(cli): add OSC notification support for iTerm2, Kitty, and Ghostty#3562
Merged
Merged
Conversation
Replace the basic terminal bell with protocol-specific OSC notifications that display rich system notifications with title and message content. - Add terminal detection (TERM → TERM_PROGRAM → KITTY_WINDOW_ID fallback) - Add OSC 9 (iTerm2), OSC 99 (Kitty 3-step), OSC 777 (Ghostty/cmux) - Add tmux/screen DCS passthrough with ESC byte doubling - Add notification routing service with auto terminal detection - Add dynamic tool name in approval notifications - Refactor useTerminalProgress to use shared osc.ts module - 42 unit tests covering all detection paths and protocols Closes QwenLM#2528
yiliang114
reviewed
Apr 23, 2026
yiliang114
reviewed
Apr 23, 2026
yiliang114
left a comment
Collaborator
There was a problem hiding this comment.
Overall: nice feature direction — bell-only is barely noticeable in modern terminals. Architecture is clean, test coverage is solid. Inline comments below.
wenshao
requested changes
Apr 24, 2026
- Reorder terminal detection: TERM_PROGRAM first, TERM fallback, KITTY_WINDOW_ID last - Add TTY guard in sendNotification to skip OSC when stdout is piped - Add sanitizeOscPayload to prevent control character injection in OSC payloads - Replace hand-rolled PendingToolCall with imported TrackedToolCall type - Extract awaiting tool name via useMemo to avoid useEffect re-fires - Unify brand name to "Qwen Code" in all notification messages - Remove unused TerminalWriteContext/Provider/Hook exports - Fix docstring: OSC_PREFIX 9;4 → OSC 9;4
wenshao
requested changes
Apr 24, 2026
- Add encodeKittyPayload() to base64-encode UTF-8 text for Kitty OSC 99 - oscKittyNotify() now uses e=1 flag with base64-encoded title/body - osc() falls back to BEL terminator for Kitty inside GNU screen to avoid ST conflicting with the DCS passthrough wrapper's own ST
wenshao
approved these changes
Apr 27, 2026
wenshao
left a comment
Collaborator
There was a problem hiding this comment.
No issues found. LGTM! ✅ — gpt-5.5 via Qwen Code /review
wenshao
approved these changes
Apr 27, 2026
wenshao
left a comment
Collaborator
There was a problem hiding this comment.
No blocking issues found. LGTM! ✅ — gpt-5.5 via Qwen Code /review
yiliang114
approved these changes
Apr 27, 2026
yiliang114
left a comment
Collaborator
There was a problem hiding this comment.
Nice work — clean protocol abstraction and good test coverage across the detection paths. LGTM!
xaelistic
pushed a commit
to xaelistic/qwen-code
that referenced
this pull request
Jun 7, 2026
QwenLM#3562) * feat(cli): add OSC notification support for iTerm2, Kitty, and Ghostty Replace the basic terminal bell with protocol-specific OSC notifications that display rich system notifications with title and message content. - Add terminal detection (TERM → TERM_PROGRAM → KITTY_WINDOW_ID fallback) - Add OSC 9 (iTerm2), OSC 99 (Kitty 3-step), OSC 777 (Ghostty/cmux) - Add tmux/screen DCS passthrough with ESC byte doubling - Add notification routing service with auto terminal detection - Add dynamic tool name in approval notifications - Refactor useTerminalProgress to use shared osc.ts module - 42 unit tests covering all detection paths and protocols Closes QwenLM#2528 * fix(cli): address PR review feedback for OSC notification system - Reorder terminal detection: TERM_PROGRAM first, TERM fallback, KITTY_WINDOW_ID last - Add TTY guard in sendNotification to skip OSC when stdout is piped - Add sanitizeOscPayload to prevent control character injection in OSC payloads - Replace hand-rolled PendingToolCall with imported TrackedToolCall type - Extract awaiting tool name via useMemo to avoid useEffect re-fires - Unify brand name to "Qwen Code" in all notification messages - Remove unused TerminalWriteContext/Provider/Hook exports - Fix docstring: OSC_PREFIX 9;4 → OSC 9;4 * fix(cli): base64-encode Kitty OSC 99 payloads and fix screen ST conflict - Add encodeKittyPayload() to base64-encode UTF-8 text for Kitty OSC 99 - oscKittyNotify() now uses e=1 flag with base64-encoded title/body - osc() falls back to BEL terminator for Kitty inside GNU screen to avoid ST conflicting with the DCS passthrough wrapper's own ST
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.
TLDR
This PR adds OSC (Operating System Command) notification support to replace the basic terminal bell with rich, protocol-specific system notifications.
What changed:
useTerminalProgressto use sharedosc.tsmoduleWhy:
The original terminal bell (
\x07) is barely noticeable in modern workflows. This PR enables rich system notifications that work seamlessly with terminal multiplexers like cmux, improving developer experience when Qwen Code runs in the background or requires attention.Closes #2528
Screenshots / Video Demo
Tool approval notification:
Long task completion notification:
Both notifications require terminalBell: true in settings (enabled by default). The notification method is automatically selected based on your
terminal: OSC 9 for iTerm2, OSC 99 for Kitty, OSC 777 for Ghostty/cmux, and terminal bell as fallback for other terminals.
cmux


iTerm2


Dive Deeper
Terminal Detection Strategy
The implementation uses a fallback chain to detect the terminal type:
TERM_PROGRAMenvironment variable (most reliable for iTerm2, Apple_Terminal, WezTerm)KITTY_WINDOW_IDfor Kitty terminalProtocol Support
Architecture
osc.ts: Core OSC protocol implementationsnotificationService.ts: Routing service that auto-detects terminal and dispatchesuseTerminalNotificationanduseAttentionNotificationsfor UI integrationReviewer Test Plan
Test on different terminals:
Test scenarios:
Run unit tests:
Testing Matrix
Linked issues / bugs
Closes #2528
🤖 Generated with Qwen Code