diff --git a/ui-tui/src/cli.tsx b/ui-tui/src/cli.tsx index f747e1f46..2bf79aedf 100644 --- a/ui-tui/src/cli.tsx +++ b/ui-tui/src/cli.tsx @@ -14,6 +14,7 @@ * clawcodex-tui [--cwd DIR] # spawn + own a backend * clawcodex-tui [--token T] [--cwd DIR] # attach */ +import './forceColor.js' // MUST be first — sets FORCE_COLOR before chalk/Ink load import { render } from 'ink' import React from 'react' import { App } from './App.js' diff --git a/ui-tui/src/components/DiffView.tsx b/ui-tui/src/components/DiffView.tsx index 163aeeb83..633448818 100644 --- a/ui-tui/src/components/DiffView.tsx +++ b/ui-tui/src/components/DiffView.tsx @@ -21,6 +21,7 @@ import { theme } from '../theme.js' import type { DiffLine } from '../diff.js' const MAX_LINES = 80 +const MAX_DIFF_WIDTH = 120 // readable cap so wide terminals don't stretch the tint const RESET = '\x1b[0m' const ADD_BG: [number, number, number] = [34, 92, 43] const DEL_BG: [number, number, number] = [122, 41, 54] @@ -70,9 +71,12 @@ export function DiffView({ lines, filePath }: { lines: DiffLine[]; filePath?: st const cols = process.stdout.columns ?? 80 const indent = 2 // sit under the "⎿" summary const gutterW = indent + numW + 1 // indent + right-aligned number + a space - const contentMax = Math.max(8, cols - gutterW - 1) + // Cap the content column at a readable width so a very wide terminal (or one + // long line) doesn't stretch the tint across the whole screen — a no-op on + // normal terminals, it just bounds the worst case. + const contentMax = Math.max(8, Math.min(cols - gutterW - 1, MAX_DIFF_WIDTH)) // Tint width = the longest line in the hunk (marker + code), capped at the - // terminal — a tight block for short hunks instead of a full-width bar. + // content column — a tight block for short hunks instead of a full-width bar. const longest = Math.max(2, ...shown.map((l) => 1 + (l.text?.length ?? 0))) const blockW = Math.min(contentMax, longest) const segW = Math.max(4, blockW) // wrap target (marker is counted in bgRow) diff --git a/ui-tui/src/forceColor.ts b/ui-tui/src/forceColor.ts new file mode 100644 index 000000000..e31b06613 --- /dev/null +++ b/ui-tui/src/forceColor.ts @@ -0,0 +1,16 @@ +/** + * Force color ON before any color library (chalk via cli-highlight, and Ink) + * loads — this MUST be imported first. + * + * The launcher spawns this process with stdout inherited, but in that spawned + * context cli-highlight's `supports-color` can resolve to "no color" (level 0), + * so syntax highlighting silently drops to plain text — which then sits on the + * diff's hardcoded rgb tint as flat, unreadable text. The TUI always renders to + * a terminal (Ink itself emits truecolor), so advertise truecolor — unless the + * user explicitly opted out via NO_COLOR or their own FORCE_COLOR. + */ +if (process.env['FORCE_COLOR'] === undefined && process.env['NO_COLOR'] === undefined) { + process.env['FORCE_COLOR'] = '3' +} + +export {}