ad067d9ae3
The layout measure path flattened a Text node to its RAW string while paint applied sanitizeAnsi, so measure and paint used different strings. A control sequence that sanitizeAnsi strips then either mis-measured the width (ESC#8/DECALN: string-width 2 vs the real 3 -> undersized cell -> trailing char clipped) or broke the wrap step (\x1b[2K: wrap-ansi doesn't recognize the CSI -> text un-wrapped, overflowing a too-short cell). Sanitizes the measure-path squash (flattenLeaves + flattenTransformLeaves) so measure and wrap see the same string paint emits, matching Ink's squashTextNodes -> sanitizeAnsi (dom.ts:227, render-node-to-output.ts:141-150). Un-skips the ESC#8 test (corrected to the ESC#8-alone input) and adds a \x1b[2K wrap-drop test (exact-byte, verified against Ink). The non-hyperlink-OSC overflow case is a SEPARATE Output grid-clip gap (sanitize preserves OSC) -- its test stays skipped with a corrected note. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>