Capture formatter-only import ordering updates in two TUI files to keep the
working tree clean after recent core changes.
No behavior changes are included in this commit.
Pin `syntect` to `=5.3.0` and add explicit review dates to the
existing `RUSTSEC-2024-0320` and `RUSTSEC-2025-0141` exceptions in
`deny.toml` so dependency risk review stays deliberate.
Fix grammar in `core/src/agent/builtins/monitor.toml` developer
instructions and add a realtime conversation test that returns `None`
when a message item is missing `content`.
Ignore empty or whitespace-only realtime transcript input so we do not
create no-op user turns from blank transcriptions.
Move realtime text mirroring off the `send_event` hot path and add
bounded truncation for mirrored patch output and file lists, while
adding a serde alias for `background_terminal_timeout` compatibility.
Adjust table column classification in `markdown_render.rs` so token-heavy,
low-word-density columns are treated as Structured instead of Narrative.
This keeps URL-heavy link columns from being first in the shrink order,
reducing rare but severe narrow-column wrapping in rendered tables.
Disable table holdback for `PlanStreamController` by adding a
per-stream `TableHoldbackMode` in `StreamCore`. Agent streams keep
holdback enabled, while plan streams now enqueue table lines
incrementally.
Also treat plan live tail as active in `stream_controllers_idle()` and
add regression coverage in `codex-rs/tui/src/streaming/controller.rs`
and `codex-rs/tui/src/chatwidget/tests.rs` to prevent premature
`StopCommitAnimation` and preserve streaming behavior.
Improve resize reflow scheduling so due reflows request an immediate frame
instead of waiting for unrelated redraws, and clear queued stream output on
`Op::Interrupt` so stale lines stop rendering immediately.
Harden markdown/table parsing by treating tab indentation as 4-column
whitespace in `strip_line_indent` and ignoring escaped-only pipes in
`parse_table_segments` unless explicit outer pipes are present.
Replace clone with mem::take in finalize(), return Cow from
unwrap_markdown_fences for zero-copy on fence-free messages, use
index-based iteration in reflow loop, add #[inline] on ~20 hot-path
functions, add with_capacity hints on hot Vecs/Strings, box large
ActiveFence variant, and eliminate minor allocations (into_iter,
Span::from for literals, write!-based plain_text, redundant .max(1)).
Remove accumulated duplication and dead code across the md-table
branch: extract shared helpers (trailing_run_start<T>, strip_line_indent,
compute_target_stable_len, reset_history_emission_state,
maybe_finish_stream_reflow, is_blockquote_active, active_cell_is_stream_tail),
collapse redundant conditionals (normalize_row, FenceTracker Option state,
merged match arms), delete duplicate methods and tests, and fix stale
doc comments. No behavioral changes; -86 net lines.
Strip blockquote prefixes during table detection only when the fence
itself is inside a blockquote, preventing false unwrapping of fences
that contain blockquoted table examples as illustration content.
- tick_batch(0) now returns empty instead of silently draining one line
- has_live_tail avoids Vec allocation via field comparison
- Convert 15 sync-only controller tests from tokio::test to #[test]
Address reviewer concerns about self-referential test coverage:
- Column-metrics: 6 tests for TableColumnKind classification,
preferred_column_floor caps, and next_column_to_shrink priority.
- Spillover detection: 6 tests for is_spillover_row covering each
heuristic branch and negative cases.
Add module-level, type-level, and function-level documentation across
the table rendering pipeline: table_detect, width, markdown,
markdown_render, and streaming/controller. Separate spillover lines
from table grid output via RenderedTableLines so spillover prose
routes through normal word wrapping instead of bypassing it.
Add module, type, and function-level doc comments across the table
rendering change. Fix typos ("taht", "mirros", "stabe", "durin").
Expand streaming controller module docs to cover holdback and resize
handling. Document width allocation, spillover detection, consolidation,
and prewrapped line rendering contracts. No runtime behavior changes
in documentation edits; also includes extracted draw helpers in app.rs
and a fence-detection fix in markdown.rs.
Wire the Unicode box-drawing table renderer into the live streaming
path with holdback-aware commit logic, post-stream cell consolidation,
and debounced resize reflow.
Key additions:
- StreamCore: shared bookkeeping deduplicating Stream/PlanStreamController
- Table holdback: fence-aware state machine keeps buffer mutable during table detection
- AgentMarkdownCell: stores raw markdown source, re-renders at any width on demand
- ConsolidateAgentMessage: backward-walk replaces streamed cells with single consolidated cell
- Resize reflow: debounced (75ms) re-render of all transcript cells after terminal resize
Add proper table rendering to the markdown renderer using Unicode
box-drawing characters (┌─┬┐│├─┼┤└─┴┘) instead of raw pipe syntax.
Supports column alignment, cell wrapping at narrow widths, tables
inside blockquotes, escaped pipes, and styled inline content.
Addresses #16622
Problem: bare local file links in TUI markdown render percent-encoded
path bytes literally, unlike file:// links.
Solution: decode bare path targets before local-path expansion and add
regression coverage for spaces and Unicode.
Problem: The resume picker used awkward "Created at" and "Updated at"
headers, and its relative timestamps changed while navigating because
they were recomputed on each redraw.
Solution: Rename the headers to "Created" and "Updated", and anchor
relative timestamp formatting to the picker load time so the displayed
ages stay stable while browsing.
Addresses #16781
Problem: `codex exec --ephemeral` backfilled empty `turn/completed`
items with `thread/read(includeTurns=true)`, which app-server rejects
for ephemeral threads.
This is a regression introduced in the recent conversion of "exec" to
use app server rather than call the core directly.
Solution: Skip turn-item backfill for ephemeral exec threads while
preserving the existing recovery path for non-ephemeral sessions.
Addresses #16832
Problem: After `/fast on`, the TUI omitted an explicit service-tier
clear on later turns, so `/fast off` left app-server sessions stuck on
`priority` until restart.
Solution: Always submit the current service tier with user turns,
including an explicit clear when Fast mode is off, and add a regression
test for the `/fast on` -> `/fast off` flow.
Addresses #16584
Problem: TUI word-wise cursor movement treated entire CJK runs as a
single word, so Option/Alt+Left and Right skipped too far when editing
East Asian text.
Solution: Use Unicode word-boundary segments within each non-whitespace
run so CJK text advances one segment at a time while preserving
separator and delete-word behavior, and add regression coverage for CJK
and mixed-script navigation.
Testing: Manually tested solution by pasting text that includes CJK
characters into the composer and confirmed that keyboard navigation
worked correctly (after confirming it didn't prior to the change).
This adds end-to-end coverage for `responses-api-proxy` request dumps
when Codex spawns a subagent and validates that the `x-codex-window-id`
and `x-openai-subagent` are properly set.