Skip to content

fix(shared): PASS and FAIL badges stay readable in dark command output - #24042

Merged
juliusmarminge merged 4 commits into
pingdotgg:mainfrom
WesleySmits:fix/shared-command-badge-contrast
Nov 14, 2026
Merged

juliusmarminge merged 4 commits into
pingdotgg:mainfrom
WesleySmits:fix/shared-command-badge-contrast

Conversation

@WesleySmits

@WesleySmits WesleySmits commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Problem

#15094 promised: "Text on a coloured background switches to near-black or white when it would be unreadable (e.g. "PASS" badges)." spanStyle does this when the text colour is under 3:1 against the background. It picks near-black only above luminance 0.35, but white already drops below that same 3:1 at 0.30. Five of the dark palette's eight standard backgrounds (red, green, yellow, blue, magenta) fall in that gap, so the usual PASS/FAIL badges render white at about 2.85:1 in the dark theme.

Change

Lower the cutoff to 0.30, where white stops reaching 3:1, so the fallback colour meets its own target on every background. One line in packages/shared/src/terminalOutput.ts.

Dark background Before After
red #f47067 white 2.85:1 #1f2328 5.54:1
green #57ab5a white 2.85:1 #1f2328 5.55:1
yellow #c69026 white 2.83:1 #1f2328 5.58:1
blue #539bf5 white 2.85:1 #1f2328 5.55:1
magenta #b083f0 white 2.86:1 #1f2328 5.53:1

Only backgrounds with luminance between 0.30 and 0.35 change: these five dark palette colours, 18 xterm-256 colours, and the matching true-colour band. In the dark theme those badges visibly switch from white to near-black text. Backgrounds where white already reached 3:1 keep white, and no light-palette colour changes. The fallback now reaches at least 3:1 on every background, checked across all 16.7M truecolor values. This restores the existing 3:1 contract; it does not aim for any broader contrast standard.

Scope and approval

This is a very small fix for an obvious bug: the fallback misses the threshold it was written to enforce. It changes one comparison in the shared function that web, desktop and mobile already use. There are no new options, palette changes or parser changes. Per AGENTS.md, a colour fix is proven with before/after captures, so it adds no test.

Verification

Web, isolated dev server (vp run dev --home-dir <tmp> --no-seed), real CommandOutputPanel.

  • Fixture: a project added with t3 project add. One completed thread holds a command_execution item whose persisted output contains the badge escapes below. It was written as V2 projection rows following test-t3-app/references/sqlite-fixtures.md, and each payload was validated against the contract schemas first.
  • Not a provider repro: this is a fixture fed through the real server and renderer, not a captured provider run.
  • Before and after: same server and fixture; the only difference is the source line, picked up by HMR.

Badges: ESC[42m PASS, ESC[1;37;41m FAIL, Jest-style inverse green ESC[7mESC[1mESC[32m PASS. Controls that must not change: ESC[30;42m PASS (3.67:1, no fallback) and ESC[100m SKIP on #768390 (white 3.87:1).

Dark, before → after

dark before
dark after

Light, before → after (byte-identical)

light before
light after

Computed styles read from the real DOM:

  • Dark, badges: the three badges go from rgb(255,255,255) to rgb(31,35,40).
  • Dark, controls: rgb(59,64,72) and white, unchanged.
  • Light: all five stay white.

Checks on the final commit: vp run check:changed passes (format, lint, knip, typecheck, terminalOutput.test.ts 16/16), and git diff --check is clean.

Not checked:

  • Mobile: agent device access was turned off in my environment, so I could not run the mobile client. Mobile calls the same terminalOutputSpans(text, TERMINAL_PALETTES[theme]), so it gets the same colour choice, but I did not capture it.
  • Desktop: uses the same web CommandOutputPanel; not captured separately.
  • Screenshot tool: T3's built-in browser panel paired and confirmed the white-on-green DOM before the fix, but its screenshot call timed out every time. I took the captures with headless Chromium (the repo's existing Playwright, fresh context) against the same isolated server.

Written by Claude Opus 5.5 via Claude Code in T3 Code, coordinated by Sol 6.1 via Codex.

The readable-text fallback for coloured backgrounds switched to near-black
only above luminance 0.35, but white text drops below its own 3:1 target
at 0.30. Dark-theme green, red, yellow, blue and magenta sit in that gap,
so badges like PASS on green rendered white at about 2.85:1. They now get
the existing near-black (about 5.5:1). Backgrounds that already reached
3:1 with white, and the whole light palette, are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-10-23T09:26:40.885309Z 3b0c29c PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added vouch:unvouched Author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 23, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 3b0c29c

Macroscope's review found this PR approvable — This is a narrowly scoped readability fix that changes one contrast threshold in the existing shared terminal renderer, with no API, configuration, or workflow changes. Its visible impact is limited to correcting fallback text colors for a small luminance range in existing command output.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

spanStyle now uses a 0.3 background-luminance threshold instead of 0.35 to select the dark fallback text color. A test checks foreground colors on dark-palette green and red backgrounds.

Changes: Terminal text color

Layer / File(s) Summary
Fallback color threshold
packages/shared/src/terminalOutput.ts, packages/shared/src/terminalOutput.test.ts
spanStyle now uses a 0.3 luminance threshold to select the fallback text color. A test checks for #1f2328 on dark-palette green and red backgrounds.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix

Suggested reviewers: scratchyone

Merge Risk: Minimal · up to f5621

This change makes PASS and FAIL badge text more readable on dark backgrounds in command output. It only affects backgrounds in a narrow luminance range, and no merge-blocking risk was identified.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the actual change: the fallback text colour for PASS and FAIL badges in dark command output is fixed so the badges stay readable. It matches the raw summary, which shows the luminance …
Description check Passed The description follows the repository template closely. It has a clear Problem section that cites the expected behaviour and the affected palette colours. The Change section explains the one-line fix…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the actual change: the fallback text colour for PASS and FAIL badges in dark command output is fixed so the badges stay readable. It matches the raw summary, which shows the luminance cutoff moved from 0.35 to 0.30 in terminalOutput.ts, and the test added for dark-palette green and red badges. The title is in conventional-commit form and fits the scope of the change.

Full details: Description check

Explanation

The description follows the repository template closely. It has a clear Problem section that cites the expected behaviour and the affected palette colours. The Change section explains the one-line fix and why it is needed. The Scope section states that this is a small fix of an obvious bug and says why no issue link is needed. The Verification section gives specific fixtures, before and after computed styles, screenshots, the tests run, and the items not checked. The description also gives the model and harness, as the template asks. The only gap is that the Scope section does not link an issue; it explains why one is not needed, which the template accepts.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 4915b15 and f562153.

Files selected for processing: 2

  • packages/shared/src/terminalOutput.test.ts
  • packages/shared/src/terminalOutput.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

maria-rcks commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

Verified as-is at 4915b157499ea3842a9d18ba56ed590c00d1c322 on this Linux Boat VM. No code changes or pushes were needed.

  • Reproduced on github/main at fa4e4677c0 in /home/user/main, then stopped its dev server before starting the exact PR head. Ran vp i in both checkouts and used separate, empty development state.
  • Drove /usr/bin/google-chrome with the repository's Playwright. Added /home/user/t3code as a project through the app, selected Codex gpt-6.1-sol, and submitted the same read-only ANSI printf prompt on each version. Both real provider turns completed through the local proxy. No mocked provider, database fixtures, demo data, or injected command-output rows.
  • Expanded the completed turn and command output in the web client. On main, green PASS, white-on-red FAIL, and inverse green PASS render white at about 2.85:1. On the PR they render rgb(31,35,40) at about 5.5:1.
  • Neighbor checks: explicit black-on-green stays rgb(59,64,72); gray SKIP stays white; plain output remains readable. All five light-theme badge foreground/background styles match main. Collapsing, reopening, and reloading command output preserve the real provider output.
  • Blacksmith: vp test run packages/shared/src/terminalOutput.test.ts passed 16/16. vp run check:changed passed format, lint, knip, affected typechecks, and 16/16 tests. The shallow worker needed PR base history fetched before check:changed could compare it. git diff --check passed locally.

Dark, main before:

main dark: white PASS and FAIL badges from a real Codex command

Dark, PR after:

PR dark: near-black PASS and FAIL badges with unchanged controls

Light, main before:

main light: five real command-output badge controls

Light, PR after:

PR light: badge colors remain unchanged

Command output expansion, collapse, and reopening. Inspected the captures, checked uploaded image hashes, and played and sought the uploaded video in Chrome:

real Codex command output opens with readable dark badges

Not verified

Native iOS/Android and the Electron desktop shell were not exercised on this Linux browser pass. Other provider adapters, remote/relay/tunnel connections, custom themes, and every xterm/truecolor background were not exercised. This verifies the shipped web command-output path with real Codex output, not an exhaustive color-space audit.

Evidence rendering limitation: reopening this comment in cafe shows external media as links rather than inline players/images. The uploaded images match the inspected originals byte-for-byte, and the uploaded video played to completion and supported seeking in Chrome. An attempted native cafe attachment upload returned HTTP 409 (Operation changed); its unused reservation was canceled. Inline cafe media playback remains unverified.

@juliusmarminge

Copy link
Copy Markdown
Member

Evidence

Scenario: Command output badges meet the existing 3:1 contrast target

Created fresh synthetic project/thread state, replayed the exact five ANSI badge outputs, opened the thread, expanded Worked for and the command row, and captured dark and light themes. Both sides used Chromium at 1280×800.

Proven: base selected white for the first three dark badges (about 2.85:1); head selected near-black (5.54–5.55:1). The explicit foreground and gray-background controls retained their colors. Light rendering appeared unchanged.

Before After
Commit 1f55acf13b f562153602
Result Failed: measured 2.846:1 against the 3:1 target Passed: all five dark badges meet 3:1
Dark command badges Before: dark command badges After: dark command badges
Light command badges Before: light command badges After: light command badges
Assertion failure capture after light control Base failure capture

Scenario source

Not shown:

  • Desktop and mobile rendering were not exercised; this proof covers the reported web-client reproduction.
  • Yellow, blue, and magenta backgrounds were not captured; the reproduction supplied green/red affected badges and two controls.

@juliusmarminge juliusmarminge added takeover:ready Takeover done; auto-lands when gates pass and removed takeover:in-progress A takeover lead is working on this PR labels Nov 14, 2026
@juliusmarminge
juliusmarminge merged commit f315da3 into pingdotgg:main Nov 14, 2026
49 checks passed
@juliusmarminge juliusmarminge removed the takeover:ready Takeover done; auto-lands when gates pass label Nov 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched Author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants