Long write/edit streams made the TUI stutter or freeze for seconds at a
time (ui.loop-blocked warnings, keystrokes starving while the single JS
thread rebuilt previews). Two compounding quadratic paths:
1. parseStreamingJsonThrottled re-parsed the entire accumulated args
buffer on a FIXED 256-byte cadence. The comment claimed this bounded
mid-stream work to O(N), but a constant growth gate still parses an
N-byte buffer N/256 times at O(N) each: O(N^2) with a smaller
constant. The gate now scales geometrically (max(256, len/32)), so
parse points form a geometric progression: O(log N) parses, O(N log N)
total, with mid-stream snapshots staying within ~3% of the stream.
Small buffers keep the exact fixed cadence as before.
2. write.ts formatStreamingContent normalized + split('\n') the WHOLE
accumulated content on every 30Hz reveal tick (renderCall also ran a
full-payload normalize first): O(N) per tick, O(N^2) per stream, per
concurrent writer. The collapsed tail-window path now tracks the
newline count incrementally (append-only resume keyed on the
component's persistent render-state object via WeakMap) and extracts
only the tail window with a backward scan: O(delta + preview lines)
per tick, byte-identical output to the split-based reference. The
expanded (Ctrl+O) path is unchanged in output and skips its
split+join round-trip.
Tests: geometric-gate bounds + freshness + small-buffer cadence in
parse-streaming-json-throttled.test.ts; append-growth/reference-
window/CRLF/trailing-newline/restart battery in
write-streaming-incremental.test.ts. Full write/tool-render battery
(56 tests) and ai streaming-args tests (117 tests) pass.
- Implemented classifyJsonPrefix to categorize buffers as complete, valid prefix, or invalid based on RFC 8259 strictness.
- Added utility to support disambiguation of identifierless streaming tool-call deltas during model response processing.
- Validated classifier logic with comprehensive suite covering nested structures, escape sequences, and strict formatting rules.
- Added support for parsing unquoted bareword strings in object and array value positions.
- Implemented safety checks to prevent bareword recovery from masking structure, consuming non-finite atoms, or swallowing valid JSON delimiters.
- Included logic to preserve URL-style and Windows-style paths containing colons while rejecting invalid or ambiguous syntax.
- Centralized JSON parsing and stream processing logic by moving utilities from `packages/ai` to the shared `@oh-my-pi/pi-utils` package.
- Standardized import paths for JSON parsing and streaming across the agent, ai, and coding-agent packages.
- Refactored SSE stream handling to use consolidated `parseStreamingJson` logic and introduced robust error recovery for malformed container-shaped tail events.
- Cleaned up legacy bundled registry references and updated related module exports and tests to reflect the new utility structure.