c76a0f09b2
Two related fixes to the raw-mode controller, mirroring Ink's split (App.tsx:212-224,357): - Sync input-state clear (P6): on the last useInput release (refs→0), reset the input parser, clear the pending escape-flush timer, and detach the stdin listeners SYNCHRONOUSLY — only the terminal raw-mode toggle stays deferred. Previously everything was deferred in one microtask, so a same-tick useInput SWAP (old unmounts → refs 0 → queued; new mounts → refs 0→1; the queued reset then short-circuits on refs>0) left the parser un-reset and a partial escape buffered before the swap leaked into the replacement handler. Ink's clearInputState runs synchronously and unconditionally so this can't happen. - Force raw-off (P7): the final disable now unconditionally setRawMode(false), matching Ink's disableRawMode. The previous prevRaw-restore re-captured stdin.isRaw at acquire while raw was still active on a sync false→true→false swap, snapshotting `true` and leaving the terminal in RAW mode after exit. No test locked the prevRaw-restore (an undocumented vue invention), so the field is removed entirely — eliminating the corruption and aligning with Ink. The swap-keeps-raw-on behavior (deferred toggle short-circuits on refs>0) is preserved. Tests lock the partial-escape no-leak on swap and the terminal being restored (final setRawMode is false) via an isRaw-tracking stdin. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>