Skip to content

branding: paint banner hex as truecolor SGR - #727

Merged
soydachi merged 1 commit into
mainfrom
fix/banner-truecolor
Sep 17, 2026
Merged

soydachi merged 1 commit into
mainfrom
fix/banner-truecolor

Conversation

@soydachi

Copy link
Copy Markdown
Member

Cause

styleText (node:util) validates its format argument at runtime and accepts only named formats — but its TypeScript type advertises hex. src/theme.ts emits BANNER_GREEN = '#00ED64' (generated from brand/tokens.jsonaccent), so:

  • Bun 1.3.x (validating runtime): ERR_INVALID_ARG_VALUE at the first render — ai-eng crashed on startup. Reported on a fresh macOS install.
  • Bun 1.4 / Node ≥ 24.1 (lenient): silent drop — banner shipped without its brand colour.

Fix

src/branding.ts paints the declared hex as a raw truecolor SGR sequence (ESC[38;2;r;g;b) itself, degrading to plain text under NO_COLOR or a non-TTY stdout — the same rule the rest of the frame follows. Named formats still route through styleText. The generator is untouched: it emitted the hex correctly; the consumer defined the wrong contract.

Check

New test in tests/cli-ux.test.ts: forces TTY, runs showLogo, asserts the exact escape \x1b[38;2;0;237;100m. Fails deterministically pre-fix on every runtime (strict: crash; lenient: no escape), passes post-fix. Env hygiene: the fixture restores isTTY (incl. the inherited-getter case via Reflect.deleteProperty) and NO_COLOR — verified that a leaked isTTY: true was flipping later doctor/uninstall specs.

Verification

  • bun test: 698 pass / 0 fail (clean-tree baseline 697; +1 is the new check)
  • PTY smoke under Bun 1.3.14 and 1.4.2: truecolor emitted, no crash; piped/NO_COLOR: plain text
  • tsc --noEmit: 0 errors in src/tests · oxlint src tests: clean on touched files
  • PTY smoke renders the banner in green on both runtimes

styleText (node:util) validates its format argument at runtime and accepts
only named formats, but the type advertises hex — a token file whose
banner-green resolves to #00ED64 crashed the first render on runtimes that
validate (Bun 1.3.x, ERR_INVALID_ARG_VALUE) and dropped the colour on the
lenient ones. The banner now emits the truecolor sequence itself, degrading
to plain text under NO_COLOR or a non-TTY stdout, the same rule the frame
already follows. The failing check pins the exact escape sequence.

Receipt-Id: 1fcddb8b
@trailhq-graft

trailhq-graft Bot commented Sep 17, 2026

Copy link
Copy Markdown

🌱 graft blast radius

1 area changed → 1 area can be affected. 1 dependent symbol, depth 2.
Tests: 1 area updated its tests.

flowchart TB
  A0(("Command Line Interface<br/>1 symbol"))
  classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
  class A0 reached;
Loading
Can be affected Symbols Nearest hop Reached from
Command Line Interface 1 src/cli.ts:L1-L129 cli.ts — calls, depth 1 Branding Elements
All 1 dependent symbol, grouped by area

Command Line Interface — 1 symbol in 1 file

  • src/cli.ts:L1-L129 — cli.ts (calls, depth 1)
Test signal per changed area — 1 ✓

Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.

  • Branding Elements — 1 of 4 reached · 1 test file changed here: tests/cli-ux.test.ts
    • not reached: paint, sgr, line

⚠️ 1 changed file not in the graph (.changeset/banner-truecolor.md) — no parser claims the extension, or the index predates the file.

graft blast · refs/graft/base...HEAD · depth 2 · 3 changed files

Open the interactive graph → — click an area to see the code that changed, and the line that reaches it.

@sonarqubecloud

Copy link
Copy Markdown

@soydachi
soydachi merged commit 7504041 into main Sep 17, 2026
23 checks passed
@soydachi
soydachi deleted the fix/banner-truecolor branch September 17, 2026 09:20
@github-project-automation github-project-automation Bot moved this from Backlog to Done in ai-engineering Sep 17, 2026
@github-actions github-actions Bot mentioned this pull request Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant