88916880eb
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1.5 KiB
1.5 KiB
Fix: ANSI color codes no longer leak into tool output
A nested penguin run driven through exec_command and polled with input_command filled Web tool cards with [36m/[0m fragments spliced into words (#102). Three layers each contributed, and each is fixed:
- CLI: the renderer wrote escape codes unconditionally. Color is now decided once per output stream — TTY,
NO_COLORunset,TERMnotdumb, with a non-emptyFORCE_COLORoverriding in either direction, matching Node's own semantics — and every renderer escape routes through that palette, so piped output is plain text. - Command tool environment: the child environment always set
NO_COLOR=1andTERM=dumb, but an inheritedFORCE_COLORsilently won (Node ignoresNO_COLORwhenFORCE_COLORis set).FORCE_COLORandCLICOLOR_FORCEare now stripped — removed, not blanked, since Node reads an emptyFORCE_COLORas "on" — so the hardening finally holds; a vault-provided value still passes through by design. - Web: tool output renders through a defensive ANSI stripper (CSI including multi-parameter SGR, OSC, two-byte escapes, and an incomplete trailing sequence cut mid-stream), applied at render time only — historical Traces display clean without their files being rewritten. The Trace event inspector deliberately keeps raw payloads: it is the raw-data view.
Regression tests cover all three layers, including the reported FORCE_COLOR=3 + NO_COLOR=1 + TERM=dumb combination and sequences split across streaming chunk boundaries.