Theme-adaptive ANSI color rewrite for terminal readability#644
Merged
Conversation
AI agents emit pale 256-color SGR codes and dim attributes tuned for dark backgrounds. ghostty-web resolves 256-color indexes inside WASM (theme palette cannot remap them) and renders dim as 50% alpha, which washes text out on white. Add a light-mode stream filter that drops SGR dim and darkens pale indexed/truecolor foregrounds by luminance before term.write(), and darken the light theme ANSI palette (white, brightBlack, yellows).
Claude Code's light-ansi theme paints message bars with ansi:white as a background (SGR 47) plus dark 30/90 foregrounds. Our light palette maps white to a dark gray so 37 stays legible as text, which turned those bars dark-on-dark. Split the roles: 37/97 text stays dark, 47/107 and 48;5;7 / 48;5;15 backgrounds become light gray truecolor.
Codex emits GitHub-light ink truecolors (#333333, #183691, ...) regardless of the terminal background, making its output unreadable on the dark theme. Extend the PTY stream filter (renamed ansi-light-adapt -> ansi-theme-adapt) with a dark mode that blends foregrounds below 0.25 luminance toward white. Foreground adjustment in both modes is now skipped while an explicit SGR background or reverse video is active, preserving intentional contrast in vim themes and highlight bars; the gate state persists across chunks.
Claude Code paints message bars and the history-select highlight with ansi:white/whiteBright (SGR 47/107); the dark palette resolves those to pale lavender, leaving default-fg text unreadable. Rewrite them to Claude Code's own dark theme bar colors (55/70 gray) and flip explicit dark ANSI fg (30/90) on those bars to light grays, tracking the last dark fg across sequences since Claude emits fg before bg. Remapped white bars no longer gate fg adjustment — they sit near the theme background after remapping.
Pure black brightened to the flat 0.38 luminance target lands on a chroma-less #616161 gray that still reads as nearly invisible on a dark background (e.g. Codex paints its model name with #000000). Ramp the blend target up as input luminance approaches zero (0.38 at the threshold, 0.50 for pure black), so near-black ink gets a stronger lift while already-colored dark foregrounds barely shift.
The 0.50 target still rendered pure black as a gray too dark to read comfortably on the dark background (Codex model name in its status bar). Pure black now maps to #999999; colors near the threshold barely shift.
A binary gate skipped fg fixes under any explicit background, so Codex's pure-black model name on its own dark truecolor bg (48;2;30;30;46) was never brightened. Explicit truecolor/indexed backgrounds are now classified by luminance: same-polarity bgs keep fg adjustment on, opposite-polarity and unknown (named ANSI, reverse video) still gate.
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.
Summary
src/mainview/utils/ansi-theme-adapt.ts) applied in theTerminalViewwrite batcher.See
decisions/066-light-theme-ansi-stream-rewrite.mdfor the full investigation.