mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat(tui): retire the tui2 experiment (#9640)
## Summary - Retire the experimental TUI2 implementation and its feature flag. - Remove TUI2-only config/schema/docs so the CLI stays on the terminal-native path. - Keep docs aligned with the legacy TUI while we focus on redraw-based improvements. ## Customer impact - Retires the TUI2 experiment and keeps Codex on the proven terminal-native UI while we invest in redraw-based improvements to the existing experience. ## Migration / compatibility - If you previously set tui2-related options in config.toml, they are now ignored and Codex continues using the existing terminal-native TUI (no action required). ## Context - What worked: a transcript-owned viewport delivered excellent resize rewrap and high-fidelity copy (especially for code). - Why stop: making that experience feel fully native across the environment matrix (terminal emulator, OS, input modality, multiplexer, font/theme, alt-screen behavior) creates a combinatorial explosion of edge cases. - What next: we are focusing on redraw-based improvements to the existing terminal-native TUI so scrolling, selection, and copy remain native while resize/redraw correctness improves. ## Testing - just write-config-schema - just fmt - cargo clippy --fix --all-features --tests --allow-dirty --allow-no-vcs -p codex-core - cargo clippy --fix --all-features --tests --allow-dirty --allow-no-vcs -p codex-cli - cargo check - cargo test -p codex-core - cargo test -p codex-cli
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Exit and shutdown flow (tui + tui2)
|
||||
# Exit and shutdown flow (tui)
|
||||
|
||||
This document describes how exit, shutdown, and interruption work in the Rust TUIs (`codex-rs/tui`
|
||||
and `codex-rs/tui2`). It is intended for Codex developers and Codex itself when reasoning about
|
||||
future exit/shutdown changes.
|
||||
This document describes how exit, shutdown, and interruption work in the Rust TUI (`codex-rs/tui`).
|
||||
It is intended for Codex developers and Codex itself when reasoning about future exit/shutdown
|
||||
changes.
|
||||
|
||||
This doc replaces earlier separate history and design notes. High-level history is summarized
|
||||
below; full details are captured in PR #8936.
|
||||
|
||||
@@ -6,12 +6,10 @@ for Windows terminals.
|
||||
Primary implementations:
|
||||
|
||||
- `codex-rs/tui/src/bottom_pane/chat_composer.rs`
|
||||
- `codex-rs/tui2/src/bottom_pane/chat_composer.rs`
|
||||
|
||||
Paste-burst detector:
|
||||
|
||||
- `codex-rs/tui/src/bottom_pane/paste_burst.rs`
|
||||
- `codex-rs/tui2/src/bottom_pane/paste_burst.rs`
|
||||
|
||||
## What problem is being solved?
|
||||
|
||||
@@ -222,12 +220,6 @@ The `PasteBurst` logic is currently exercised through `ChatComposer` integration
|
||||
- `question_mark_does_not_toggle_during_paste_burst`
|
||||
- `burst_paste_fast_small_buffers_and_flushes_on_stop`
|
||||
- `burst_paste_fast_large_inserts_placeholder_on_flush`
|
||||
- `codex-rs/tui2/src/bottom_pane/chat_composer.rs`
|
||||
- `non_ascii_burst_handles_newline`
|
||||
- `ascii_burst_treats_enter_as_newline`
|
||||
- `question_mark_does_not_toggle_during_paste_burst`
|
||||
- `burst_paste_fast_small_buffers_and_flushes_on_stop`
|
||||
- `burst_paste_fast_large_inserts_placeholder_on_flush`
|
||||
|
||||
This document calls out some additional contracts (like “flush before clearing”) that are not yet
|
||||
fully pinned by dedicated `PasteBurst` unit tests.
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
# Performance testing (`codex-tui2`)
|
||||
|
||||
This doc captures a repeatable workflow for investigating `codex-tui2` performance issues
|
||||
(especially high idle CPU and high CPU while streaming) and validating optimizations to the draw
|
||||
hot path.
|
||||
|
||||
## Scope (this round)
|
||||
|
||||
The current focus is the transcript draw hot path, specifically the cost of repeatedly rendering
|
||||
the same visible transcript lines via Ratatui’s `Line::render_ref` (notably grapheme segmentation
|
||||
and span layout).
|
||||
|
||||
The intended mitigation is a **rasterization cache**: render a wrapped transcript `Line` into a
|
||||
row of `Cell`s once, cache it, and on subsequent redraws copy cached cells into the frame buffer.
|
||||
|
||||
Key invariants:
|
||||
|
||||
- The cache is width-scoped (invalidate on terminal width changes).
|
||||
- The cache stores **base content** only; selection highlight and copy affordances are applied
|
||||
after rendering, so they don’t pollute cached rows.
|
||||
|
||||
## Roles
|
||||
|
||||
- Human: runs `codex-tui2` in an interactive terminal (e.g. Ghostty), triggers “idle” and
|
||||
“streaming” scenarios, and captures profiles.
|
||||
- Assistant (or a script): reads profile output and extracts hotspots and deltas.
|
||||
|
||||
## Baseline setup
|
||||
|
||||
Build from a clean checkout:
|
||||
|
||||
```sh
|
||||
cd codex-rs
|
||||
cargo build -p codex-tui2
|
||||
```
|
||||
|
||||
Run `codex-tui2` in a terminal and get a PID (macOS):
|
||||
|
||||
```sh
|
||||
pgrep -n codex-tui2
|
||||
```
|
||||
|
||||
Track CPU quickly while reproducing:
|
||||
|
||||
```sh
|
||||
top -pid "$(pgrep -n codex-tui2)"
|
||||
```
|
||||
|
||||
## Capture profiles (macOS)
|
||||
|
||||
Capture both an “idle” and a “streaming” profile so hotspots are not conflated:
|
||||
|
||||
```sh
|
||||
sample "$(pgrep -n codex-tui2)" 1 -file /tmp/tui2.idle.sample.txt
|
||||
sample "$(pgrep -n codex-tui2)" 1 -file /tmp/tui2.streaming.sample.txt
|
||||
```
|
||||
|
||||
For the streaming sample, trigger a response that emits many deltas (e.g. “Tell me a story”) so
|
||||
the stream runs long enough to sample.
|
||||
|
||||
## Quick hotspot extraction
|
||||
|
||||
These `rg` patterns keep the investigation grounded in the data:
|
||||
|
||||
```sh
|
||||
# Buffer diff hot path (idle)
|
||||
rg -n "custom_terminal::diff_buffers|diff_buffers" /tmp/tui2.*.sample.txt | head -n 80
|
||||
|
||||
# Transcript rendering hot path (streaming)
|
||||
rg -n "App::render_transcript_cells|Line::render|render_spans|styled_graphemes|GraphemeCursor::next_boundary" /tmp/tui2.*.sample.txt | head -n 120
|
||||
```
|
||||
|
||||
## Rasterization-cache validation checklist
|
||||
|
||||
After implementing a transcript rasterization cache, re-run the same scenarios and confirm:
|
||||
|
||||
- Streaming sample shifts away from `unicode_segmentation::grapheme::GraphemeCursor::next_boundary`
|
||||
stacks dominating the main thread.
|
||||
- CPU during streaming drops materially vs baseline for the same streaming load.
|
||||
- Idle CPU does not regress (redraw gating changes can mask rendering improvements; always measure
|
||||
both idle and streaming).
|
||||
|
||||
## Notes to record per run
|
||||
|
||||
- Terminal size: width × height
|
||||
- Scenario: idle vs streaming (prompt + approximate response length)
|
||||
- CPU snapshot: `top` (directional)
|
||||
- Profile excerpt: 20–50 relevant lines for the dominant stacks
|
||||
|
||||
## Code pointers
|
||||
|
||||
- `codex-rs/tui2/src/transcript_view_cache.rs`: wrapped transcript memoization + per-line
|
||||
rasterization cache (cached `Cell` rows).
|
||||
- `codex-rs/tui2/src/transcript_render.rs`: incremental helper used by the wrapped-line cache
|
||||
(`append_wrapped_transcript_cell`).
|
||||
- `codex-rs/tui2/src/app.rs`: wiring in `App::render_transcript_cells` (uses cached rows instead of
|
||||
calling `Line::render_ref` every frame).
|
||||
Reference in New Issue
Block a user