Files
codex/codex-rs/tui2/docs/streaming_wrapping_design.md
Josh McKinney a40bb0af20 docs(tui2): document viewport/history architecture
- Add architecture/roadmap doc + running notes for the TUI2 transcript-owned
  viewport/history work (PR index, module map, gaps, roadmap).
- Add tester-facing guide for validation and triage (scroll, selection/copy,
  streaming reflow, overlays, exit printing, perf).
- Keep earlier design docs intact but add links to the new docs; align tables.

Docs in this change were automatically created by codex (gpt-5.2 xhigh).
2026-01-05 13:33:39 -08:00

88 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Streaming Markdown Wrapping & Animation TUI2 Notes
Note: This doc is historical. For the current architecture/status/roadmap, see
`tui2/docs/tui2_viewport_history_architecture.md`.
This document mirrors the original `tui/streaming_wrapping_design.md` and
captures how the same concerns apply to the new `tui2` crate. It exists so that
future viewport and streaming work in TUI2 can rely on the same context without
having to crossreference the legacy TUI implementation.
At a high level, the design constraints are the same:
- Streaming agent responses are rendered incrementally, with an animation loop
that reveals content over time.
- Nonstreaming history cells are rendered widthagnostically and wrapped only
at display time, so they reflow correctly when the terminal is resized.
- Streaming content should eventually follow the same “wrap on display” model so
the transcript reflows consistently across width changes, without regressing
animation or markdown semantics.
## 1. Where streaming is implemented in TUI2
TUI2 keeps the streaming pipeline conceptually aligned with the legacy TUI but
in a separate crate:
- `tui2/src/markdown_stream.rs` implements the markdown streaming collector and
animation controller for agent deltas.
- `tui2/src/chatwidget.rs` integrates streamed content into the transcript via
`HistoryCell` implementations.
- `tui2/src/history_cell.rs` provides the concrete history cell types used by
the inline transcript and overlays.
- `tui2/src/wrapping.rs` contains the shared text wrapping utilities used by
both streaming and nonstreaming render paths:
- `RtOptions` describes viewportaware wrapping (width, indents, algorithm).
- `word_wrap_line`, `word_wrap_lines`, and `word_wrap_lines_borrowed` provide
spanaware wrapping that preserves markdown styling and emoji width.
As in the original TUI, the key tension is between:
- **Prewrapping streamed content at commit time** (simpler animation, but
bakedin splits that dont reflow), and
- **Deferring wrapping to render time** (better reflow, but requires a more
sophisticated streaming cell model or recomputation on each frame).
## 2. Current behavior and limitations
TUI2 is intentionally conservative for now:
- Streaming responses use the same markdown streaming and wrapping utilities as
the legacy TUI, with width decisions made near the streaming collector.
- The transcript viewport (`App::render_transcript_cells` in
`tui2/src/app.rs`) always uses `word_wrap_lines_borrowed` against the
current `Rect` width, so:
- Nonstreaming cells reflow naturally on resize.
- Streamed cells respect whatever wrapping was applied when their lines were
constructed, and may not fully “unwrap” if that work happened at a fixed
width earlier in the pipeline.
This means TUI2 shares the same fundamental limitation documented in the
original design note: streamed paragraphs can retain historical wrap decisions
made at the time they were streamed, even if the viewport later grows wider.
## 3. Design directions (forwardlooking)
The options outlined in the legacy document apply here as well:
1. **Keep the current behavior but clarify tests and documentation.**
- Ensure tests in `tui2/src/markdown_stream.rs`, `tui2/src/markdown_render.rs`,
`tui2/src/history_cell.rs`, and `tui2/src/wrapping.rs` encode the current
expectations around streaming, wrapping, and emoji / markdown styling.
2. **Move towards widthagnostic streaming cells.**
- Introduce a dedicated streaming history cell that stores the raw markdown
buffer and lets `HistoryCell::display_lines(width)` perform both markdown
rendering and wrapping based on the current viewport width.
- Keep the commit animation logic expressed in terms of “logical” positions
(e.g., number of tokens or lines committed) rather than prewrapped visual
lines at a fixed width.
3. **Hybrid “visual line count” model.**
- Track committed visual lines as a scalar and rerender the streamed prefix
at the current width, revealing only the first `N` visual lines on each
animation tick.
TUI2 does not yet implement these refactors; it intentionally stays close to
the legacy behavior while the viewport work (scrolling, selection, exit
transcripts) is being ported. This document exists to make that tradeoff
explicit for TUI2 and to provide a natural home for any TUI2specific streaming
wrapping notes as the design evolves.