fix(tui): harden Terminal.app render behavior

Avoid Terminal.app paint corruption by disabling fast-echo in that terminal, sanitizing non-SGR control sequences before ANSI rendering, and defaulting Apple Terminal back to the safer 256-color path unless truecolor is explicitly requested.
This commit is contained in:
Brooklyn Nicholson 2026-05-16 22:51:51 -05:00
parent 3b39096904
commit 290bf93104
9 changed files with 214 additions and 10 deletions

View file

@ -9,12 +9,27 @@ import { VERBS } from '../content/verbs.js'
import type { ThinkingMode } from '../types.js'
const ESC = String.fromCharCode(27)
const ANSI_RE = new RegExp(`${ESC}\\[[0-9;]*m`, 'g')
const BEL = String.fromCharCode(7)
const ANSI_CSI_RE = new RegExp(`${ESC}\\[[0-?]*[ -/]*[@-~]`, 'g')
const ANSI_CSI_WITH_CMD_RE = new RegExp(`${ESC}\\[[0-?]*[ -/]*([@-~])`, 'g')
const ANSI_OSC_RE = new RegExp(`${ESC}\\][\\s\\S]*?(?:${BEL}|${ESC}\\\\)`, 'g')
const ANSI_STRING_RE = new RegExp(`${ESC}[PX^_][\\s\\S]*?(?:${BEL}|${ESC}\\\\)`, 'g')
const ANSI_STRAY_ESC_RE = new RegExp(`${ESC}(?!\\[)[\\s\\S]?`, 'g')
const CONTROL_RE = /[\x00-\x08\x0B\x0C\x0E-\x1A\x1C-\x1F\x7F]/g
const WS_RE = /\s+/g
export const stripAnsi = (s: string) => s.replace(ANSI_RE, '')
export const stripAnsi = (s: string) =>
s.replace(ANSI_OSC_RE, '').replace(ANSI_STRING_RE, '').replace(ANSI_CSI_RE, '').replace(ANSI_STRAY_ESC_RE, '').replace(CONTROL_RE, '')
export const hasAnsi = (s: string) => s.includes(`${ESC}[`) || s.includes(`${ESC}]`)
export const sanitizeAnsiForRender = (s: string) =>
s
.replace(ANSI_OSC_RE, '')
.replace(ANSI_STRING_RE, '')
.replace(ANSI_CSI_WITH_CMD_RE, (seq, cmd: string) => (cmd === 'm' ? seq : ''))
.replace(ANSI_STRAY_ESC_RE, '')
.replace(CONTROL_RE, '')
export const hasAnsi = (s: string) => s.includes(ESC)
const renderEstimateLine = (line: string) => {
const trimmed = line.trim()