test(routes): regression coverage for stripInkRedrawBloat

The clustering rewrite of stripInkRedrawBloat() shipped silently inside
the v0.6.7 "chore: version packages" commit (dcc814f). The previous
implementation discarded everything after the first VPA escape — silently
dropping 100KB+ of legitimate streamed response text on every long
Claude turn. The fix landed without any test coverage, so a regression
back to the old shape would be invisible until users noticed missing
conversation history.

Export the function (it's a pure (string)=>string helper) and add 12
tests covering:
  - The early-out paths (empty buffer, no VPAs, fewer than 10 VPAs)
  - Small clusters preserved (< MIN_BLOAT_SIZE = 32KB span)
  - Big clusters collapsed to a single trailing VPA
  - The silent-data-loss bug: response text BETWEEN two big clusters
    is preserved (input >280KB so any "keep just the tail" approach
    would push the response text out of its window — verified locally
    that a simulated old impl fails the assertion)
  - FRAME_GAP boundary on both sides (>8KB splits clusters; <=8KB merges)
  - Mixed small + big in the same buffer
  - Big cluster at end-of-buffer keeps the last frame
  - Idempotency: a second pass is a no-op
  - Realistic 200KB+ input shrinks by an order of magnitude

Total runtime ~12ms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
arkon
2026-05-12 10:11:47 +02:00
co-authored by Claude Opus 4.7
parent 56c2c29009
commit e7b95ae579
2 changed files with 226 additions and 1 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ const LEADING_WHITESPACE_PATTERN = /^[\s\r\n]+/;
* Without clustering, a single first-VPA-finds-all approach would discard the entire
* conversation after Claude's first render — losing 100KB+ of legitimate scrollback.
*/
function stripInkRedrawBloat(buffer: string): string {
export function stripInkRedrawBloat(buffer: string): string {
// eslint-disable-next-line no-control-regex
const vpaRe = /\x1b\[\d+d/g;
const positions: number[] = [];