TUI dark-theme diff foregrounds have low contrast on tinted backgrounds
What version of Codex CLI is running?
codex-cli 0.144.4; also reproduced against main at 365d70203da18c2a6f6848df3778e390e794ef17.
What subscription do you have?
ChatGPT authentication; the exact tier does not appear relevant to this local TUI renderer issue.
Which model were you using?
gpt-5.6-sol, but the issue is in local diff rendering and is model-independent.
What platform is your computer?
Darwin 24.5.0 arm64 arm
What terminal emulator and version are you using?
Reproduced in both Apple Terminal 455.1 and iTerm2 3.6.11 on dark terminal profiles. iTerm2 reported TERM=xterm-256color and COLORTERM=truecolor.
What issue are you seeing?
In the TUI's built-in diff cards, foregrounds on dark-theme insert/delete backgrounds can have very low contrast:
- plain insert/delete content uses green/red foregrounds over dark green/red backgrounds;
- syntax-highlighted delete content additionally receives
Modifier::DIM, producing dim gray or muted syntax colors over the dark red background; - the gutter is also dimmed.
The result can be difficult to distinguish even though the terminal correctly supports 256 colors and truecolor. The same terminals render ordinary git diff --color=always foreground colors correctly.
The root cause is in codex-rs/tui/src/diff_render.rs: dark rich-color content uses red/green foregrounds, syntax-highlighted deletions are always dimmed, and dark gutters use style_gutter_dim().
This is distinct from #13012 (overly bright backgrounds, fixed by #13037) and #33422 (tmux rendering the fills as solid yellow).
What steps can reproduce the bug?
- Use a dark terminal profile with 256-color or truecolor support.
- Start Codex CLI 0.144.4.
- Ask Codex to modify a syntax-highlighted source file with both additions and deletions.
- Inspect the built-in
Edited ...diff card, especially deleted syntax-highlighted lines.
What is the expected behavior?
Keep the dark red/green background cues, but render the gutter, sign, and content with a high-contrast foreground. For dark truecolor and ANSI-256 diff lines, white foreground text is substantially more readable. Light themes and ANSI-16 foreground-only behavior should remain unchanged.
Additional information
I prepared and tested a focused implementation against current main:
https://github.com/chouchunming/codex/commit/bf0c12406bd669874542ebcce33da743084e9575
The proposed change:
- uses white foregrounds only for dark truecolor/ANSI-256 insert and delete lines;
- removes
DIMfrom syntax-highlighted deletions in those dark rich-color modes; - clears per-token syntax backgrounds so the line-level diff background remains visible;
- preserves light-theme and ANSI-16 behavior;
- adds coverage for plain and syntax-highlighted insert/delete lines in truecolor and ANSI-256 modes.
Validation completed:
just fmtjust fmt-checkjust fix -p codex-tuicargo test --offline --locked -p codex-tui --lib diff_render::tests::— 52 passed, 0 failed
Per the contribution policy, I am opening the issue first and requesting confirmation of the approach before opening a PR.
2 Comments
I can reproduce this on macOS using Core Shell with the Dracula theme.
Environment:
File edits/diffs in the Codex TUI can become effectively unreadable—for example, yellow text over a yellow/gold background. The terminal itself appears to be rendering the colors it receives correctly.
There seem to be two related contributors:
I prepared a candidate implementation in my fork for discussion:
https://github.com/akblissweb/codex/tree/fix/tui-diff-contrast
I understand external pull requests are invitation-only, so I’m sharing this as reproduction details and a possible direction rather than opening an unsolicited PR.
Thanks for putting together the reproduction and candidate implementation. I tested the same general direction and ended up with a hybrid of the theme-aware approach here and an earlier hardcoded-white experiment.
The behavior that worked best was:
Plain changed content similarly uses the resolved red/green background with no explicit foreground. The
+/-signs remain green/red. The changed-line gutter uses the default foreground, but unchanged context lines retain syntax colors and a dimmed gutter.Trade-offs
Theme-default foreground (
fg = None)Hardcoded white
Whiteis a configurable palette slot rather than a guaranteed high-contrast color.Suppressing syntax foregrounds on changed lines
Two correctness details in the current candidate commit
At
7610f5a61bb4bf8600af1f062eac654c758f60fd:Style::remove_modifierandStyle::add_modifierreturn a newStyle; they do not mutate in place. The returned values need to be assigned, otherwiseDIMis neither removed nor added in those branches.DiffLineType::Context(both in syntax composition and the(DiffTheme::Dark, _, Some(...))gutter arm). That strips syntax styling and gutter dimming from unchanged lines. Restricting the override to Insert/Delete avoids that regression.The proposed snapshot also uses the existing text-oriented
TestBackendhelper, whose golden output contains characters but not foreground/background/modifier state; the commit does not include an accepted.snapfile. A style-structure snapshot (assert_debug_snapshot!on the renderedRtLines) catches this regression directly.Test matrix used for the hybrid
On current
mainat62fd410384:DIMremoved, unrelated modifiers preserved;+remains green and-remains red;DIMbehavior.just test -p codex-tui: 3,254 passed, 4 skipped.just fix -p codex-tui: clean.just fmt: clean.So I think the candidate's default-foreground idea is the right foundation, with the narrower Insert/Delete scope, assigned modifier results, and style-aware snapshot coverage added.