8091154785
Ink squashes every ink-text via squashTextNodes, which always returns sanitizeAnsi(text) (squash-text-nodes.ts:45) — stripping cursor/erase CSI while keeping SGR + OSC. vue's SR squash concatenated raw text-leaf values with no sanitize, so an embedded control sequence (e.g. \x1b[2J) leaked into screen-reader output. Wrap the squashed SR text in sanitizeAnsi at squashTextContent and the standalone <Transform> branch — the SR twin of text-measure.ts:54. The double pass on nested/transform text is idempotent (sanitizeAnsi is a fixed point), matching Ink's recursive squashTextNodes. Tests assert erase stripping in Text/Box/Transform AND that SGR is KEPT (so a strip-everything regression is caught). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>