Metadata
| Status | abandoned ‖ paused |
|---|---|
| Created | 2026-04-29T13:53:43.000770807+00:00 |
| Tags | priority-high,refactor,tui,pty,architecture |
Description
Description
We've shipped 3+ targeted fixes for PTY scrollback corruption in the last 24 hours and the symptom keeps coming back in different code paths or different triggers. Pattern observed:
- fix-tui-pty (commit e0f5d029b) — resize-trigger duplication
- fix-pty-scrollback (commit e18de347c) — initial-render duplication
- And now: still corrupting on what user reports as 'every resize, but resize happens all the time'
User quote: 'why is this so hard?'
The honest answer: terminal emulation is genuinely hard. Custom code is fighting xterm's state machine (cursor save/restore, scroll regions, alt-screen, SGR/SGR-mouse, line-wrap continuation, OSC sequences, mode bits). Every fix surfaces the next bug. Time to stop.
Goal
Replace the home-rolled PTY parsing + scrollback buffer with a maintained terminal emulator crate. After this lands, future terminal-rendering bugs become 'submit a patch upstream' instead of 'another fix-pty-X task.'
Crate options to evaluate
- alacritty_terminal — used by Alacritty + several other Rust TUIs; full xterm-compatible state machine; widely battle-tested; most thorough but largest dep surface
- vt100 — focused, smaller; parses VT100/xterm escape sequences into a grid; simpler integration; good enough for our chat-tab use case
- wezterm-term — used by WezTerm; rich feature set; bigger dep surface
- termwiz — also from WezTerm project; lower-level building blocks
Recommend: alacritty_terminal if we need full fidelity (e.g. to render codex's complex output), vt100 if we want minimum dep surface and our use case is mostly chat-tab text + occasional alt-screen.
Scope
- Identify the boundary in src/tui/ where bytes-from-PTY become rendered-cells. Replace the parser + grid + scrollback buffer with the chosen crate's equivalents.
- Keep the chat-tab outer chrome (tab bar, status line, etc.) — we're only swapping the terminal-emulation core.
- Migrate the existing scrollback persistence (chat history JSONL) — the new emulator's cell buffer should be hydrated from that JSONL on tab activation.
- The rendering path: emulator's cell grid → ratatui buffer → screen. Should be a clean adapter.
- Resize handling becomes the emulator's responsibility (which is exactly what these crates are tested for).
Validation
- Failing tests written first (TDD): a series of recorded byte sequences (resize, codex output, claude output, ANSI color stress test) that the new renderer must handle without duplication or corruption
- Live smoke: open the TUI, fill scrollback, resize many times in many directions, switch tabs, alt-screen apps (vim, less) — no corruption visible. Recording in task log.
-
Live smoke: codex chat tab renders identically to native
codexCLI (same colors, same layout, no scrollback dup) - Live smoke: claude chat tab renders correctly (no regression from current state)
- All previously-filed PTY tasks (fix-tui-pty, fix-pty-scrollback, the symptoms in fix-codex-agent) — verify their repros are gone after this refactor
- cargo build + cargo test pass with no regressions
- Permanent smoke scenarios for the resize / scrollback / alt-screen paths added to manifest with this task id in owners
- cargo install --path . was run before claiming done
Process note
This task supersedes targeted PTY-bug fixes. After this lands, close any remaining PTY-rendering bugs as 'fixed by architectural reset' and verify their original repros are gone. If they're not, file follow-ups against the chosen crate (upstream bug or wrong adapter usage), NOT against our home-rolled code.
Depends on
- (none)
Required by
- (none)
Log
- 2026-04-29T13:53:42.991998336+00:00 Task paused
- 2026-04-29T13:54:49.182113605+00:00 Task abandoned