Answer OSC 10/11/12 color queries so TUIs detect the terminal theme#202
Merged
Conversation
TUIs like Codex query the terminal's fg/bg/cursor colors (OSC 10/11/12) to adapt their UI — e.g. Codex blends its composer "pill" against the background. Dormouse never answered, so on a light theme the pill came out an unreadable near-black. Fix it end to end: - TerminalProtocolParser now answers OSC 10/11/12 `?` queries from the active theme (via an optional color provider), emitting a `kind:'response'` reply and consuming the query — same seam as the iTerm2 CSI>q response. - Standalone adapters supply a provider backed by the live xterm theme (shared `themeColorProvider`). VS Code parses in the extension host (no DOM), so the webview pushes resolved colors up via a new `dormouse:themeColors` message and the router feeds them to its parsers. - Windows: the in-box ConPTY swallows color queries, so spawn with node-pty's bundled OpenConsole (`useConptyDll: true`), which forwards them like Windows Terminal does. Verified end to end. - Advertise 24-bit color with `COLORTERM=truecolor` (xterm.js renders it; we spawn `xterm-256color` with no other depth hint). Specs updated (terminal-escapes, vscode, auto-update) and tests added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parseColor/toHex lived privately in themes/flatten-alpha.ts; the OSC color-query reply added its own hex parser. Promote the primitives to a neutral, DOM-free lib/css-color.ts so both reuse one parser instead of two. formatOscColorResponse now accepts rgb()/rgba() theme colors (not just hex), which more VS Code themes emit, and rounds/clamps channels. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dormouse-bot
approved these changes
Jul 2, 2026
dormouse-bot
left a comment
Collaborator
There was a problem hiding this comment.
Traced the response path end to end and it holds up: the query is consumed and answered on both surfaces (VS Code host writes replies back via ptyManager.write in message-router.ts; standalone reuses the existing kind:'response' seam), the optional colorProvider leaves every existing new TerminalProtocolParser() call site unchanged, and parseColor/toHex moved into css-color.ts byte-for-byte. Nicely tested across both providers.
One trivial cleanup below.
Co-authored-by: dormouse-bot <ned.twigg+dormouse-bot@diffplug.com>
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.
Problem
TUIs like Codex query the terminal's foreground/background/cursor colors via
OSC 10/11/12to adapt their UI — Codex blends its composer "pill" against the detected background. Dormouse never answered these queries, so on a light theme the pill rendered an unreadable near-black (dark text on a dark fill).Fix (end to end)
TerminalProtocolParsernow replies toOSC 10/11/12 ; ?from the active theme, emitting akind:'response'event and consuming the query — the same seam the iTerm2CSI > qreply already uses. Only the?report form is intercepted;setrequests and the no-provider case fall through to xterm.js.themeColorProvider).dormouse:themeColorsmessage; the router caches them and feeds them to its parsers. VS Code now matches standalone.useConptyDll: true), which forwards them like Windows Terminal does. Verified end to end against the real PTY path (the requiredconpty.dll/OpenConsole.exealready ship in both bundles).COLORTERM=truecolor. Advertise 24-bit color (xterm.js renders it; the PTY is spawnedxterm-256colorwith no other depth hint).lib/css-color.ts(parseColor/toHex) so the OSC reply reuses the theme parser instead of a second hex parser; it also acceptsrgb()/rgba()theme colors now.Not covered
Codex on Windows doesn't query OSC at all (it reads env/registry), so its pill there needs a separate env hint (
COLORFGBG/TERM_PROGRAM_BACKGROUND) — scoped but intentionally left as a follow-up. This PR fixes OSC color-query answering generally (Codex on macOS/Linux, vim, and other querying TUIs).Tests / specs
formatOscColorResponseunit tests; VS Code adapter theme-push test;COLORTERMspawn assertions.terminal-escapes.md,vscode.md,auto-update.md.🤖 Generated with Claude Code