## Why
Long built-in status lines were truncated to a single row even when the footer had room for more content.
## What changed
- Wrap status text to the available width and row budget, preserving styles and hyperlink targets across rows.
- Show an unlinked ellipsis when content exceeds the available space.
- Refresh wrapped content when the status text, agent label, or width changes.
- Keep reasoning-effort transitions on one row and restore wrapping after the final animation frame.
## Testing
Add coverage for wrapping and hyperlink boundaries across footer layouts, content and agent-label updates, resizing, and wrapping restoration after an effort transition. Update transcript and startup snapshots for multiline status text.
GitOrigin-RevId: 30e0795c473efd62fc4d0dca4deb6029b625a9e8
## What changed
Use a shared layout traversal to measure prepared UI trees and paint text directly into terminal buffers. Add natural and viewport-constrained size measurement, and use direct rendering for extension footer content.
Preserve wrapping, styles, and terminal hyperlinks while clipping at grapheme boundaries and leaving overflow ellipses unlinked.
## Testing
Add coverage for size measurement in terminal cells, wide characters at clipping boundaries, and zero-width text around overflow ellipses. Update rendering tests to check painted buffer contents and hyperlinks.
GitOrigin-RevId: 828c45d3400f9e3dfce9a7bd812d1cc0ea51642f
## Why
Typed prompts currently display Markdown syntax literally, including emphasis, lists, and code fences.
## What changed
- Render Markdown in typed prompts while retaining the prompt gutter, background, and hyperlinks.
- Preserve literal rendering for spoken prompts, prompts with inline text elements, and text without visible Markdown formatting.
- Keep the original Markdown when copying a whole prompt, and preserve source text for code block and blockquote copy targets.
- Preserve bold styling when leaving the dim prompt marker and track hyperlink columns incrementally across styled spans.
## Testing
Add regression coverage for prompt rendering at multiple widths, hyperlink positions, terminal bold styling, and copying Markdown source, code blocks, and blockquotes, including original code line endings and fenced tables with table rendering disabled.
GitOrigin-RevId: eda62043ca8a9fe012ea7e0683fe05de6ad1b898
## What changed
- Add terminal file hyperlinks to viewed image filenames and transcript paths, including older history loaded through pagination.
- Enable links only for local workspaces outside SSH sessions. Require a local regular file with a recognized image extension on both the original and resolved paths, and reject Windows reparse points.
- Preserve links when summaries are truncated or transcript paths wrap.
## Testing
Add coverage for local versus remote workspace links and for hyperlink destinations and column ranges in compact and expanded image rows.
GitOrigin-RevId: a7dff255c280ad4e609644e6f5ef5e130d9a55fb
## Why
Footer hyperlinks must follow their text when the status line is truncated or animated. Inferring link targets from underlined cells loses that association, and Unicode width differences can shift links onto the wrong cells.
## What changed
- Carry explicit hyperlink ranges with status-line content through footer layout and reasoning-effort transitions.
- Fit content to the space allocated beside right-hand indicators, keeping the truncation ellipsis outside links.
- Measure and truncate rendered graphemes consistently while preserving source columns for transcript tab expansion.
- Box the composer's footer state to reduce its stack footprint during session navigation.
## Testing
Add regression tests for clipped links after halfwidth katakana and Arabic prefixes, hyperlink positions during effort transitions, and narrow status rows beside the Plan mode indicator.
GitOrigin-RevId: ede62690e191daefc85f38e637f9bcc9796268b7
## Why
Async question replies appeared as plain user text, leaving Markdown formatting literal and repeating the full question above each answer.
## What changed
- Accent question titles with a `?` prefix while preserving Markdown in titles and suggestions.
- Render replies with a `↪ Re:` question caption and a Markdown answer. Limit captions to two rows with an ellipsis on overflow, while keeping answers complete.
- Apply the same rendering to live messages and loaded transcripts, preserving inline styles, hyperlinks, and Markdown when copying selections.
## Testing
Add snapshots and assertions for matching live and loaded transcript rendering, plus tests for caption clipping, hyperlink bounds, Markdown copying, partial selections, and whitespace-only or nonprinting answers.
GitOrigin-RevId: 0290d8a2ebfb42bd5d7374c7037cde5ae8a13b5d
## Why
Wrapping can retain a cursor sentinel one byte past the end of the input. Using that range to slice source text during hyperlink remapping can panic.
## What changed
Clamp wrapped range boundaries to the input length before calculating hyperlink columns and recording logical source ranges, keeping both aligned with the visible text.
## Testing
Add a regression test that extends a wrapped range past the input boundary and verifies that the line, hyperlinks, and logical source are preserved.
GitOrigin-RevId: c83c817df8d3ea790f7d126768092ae317ff9217
## What changed
Render web URLs in pending steers, rejected steers, and queued follow-up messages as terminal hyperlinks. Preserve the complete destination when the visible URL is clipped to the preview width.
Add `HyperlinkRows` to render already-wrapped rows without changing their spacing or row count, clipping text and hyperlink ranges to the viewport.
## Testing
Add regression coverage for complete URL destinations across all three preview sections, plus snapshots for oversized URLs and clipping overflow text and the edit hint in a narrow preview.
GitOrigin-RevId: 959df27bba381b1b3895f5a86cc2ecb1419806b1
## What changed
Render command, permission, patch, and MCP elicitation approval headers with `HyperlinkText`, which annotates web URLs and preserves their full destinations across wrapping and clipping.
## Testing
Add a regression test covering wrapped URL destinations in all four header types, plus a snapshot of the wrapped command approval header.
GitOrigin-RevId: 7f6b79484c9297cd03514da2d6805b0d239fee63
## What changed
Render web URLs in TUI asynchronous question titles as terminal hyperlinks, preserving the full destination when a URL wraps across lines or is partially clipped. Exclude trailing question punctuation such as `)?` from detected URLs while preserving balanced parentheses and query strings.
## Testing
Add a rendering regression test and snapshot for a wrapped URL, checking complete hyperlink destinations at full and reduced heights. Extend URL detection tests for trailing question punctuation and balanced parentheses in query strings.
GitOrigin-RevId: 6c9a807466d7b7e3a23bc6e86aae8410ae378161
## What changed
- Add mouse selection, word and line selection, drag autoscrolling, and keyboard selection with `Ctrl+Space`. Support copying selected text and opening links with a modified click.
- Anchor reading positions and selections to source text so resizing, streaming completion, and history pagination preserve the displayed content. Preserve hard line breaks, indentation, tabs, and graphemes when copying, while excluding display gutters and soft wraps.
- Rejoin activity groups split across history pages while retaining the reader's displayed revision.
- Distinguish confirmed clipboard writes from unconfirmed terminal requests, and retain native clipboard ownership after the transcript overlay closes.
- Manage mouse capture and keyboard modes across overlay transitions, editor handoffs, and suspend/resume.
## Testing
Add regression tests for selection during live updates and pagination, source-text copying across resize, clipboard confirmation and lifetime, and terminal mode restoration.
GitOrigin-RevId: 6b2438f576567cbba755b2405915a25acf009b8d
## Why
Loaded transcripts reduce several tool calls and file changes to basic status summaries, losing details available in live history cells.
## What changed
- Reuse rich history cells for completed commands, MCP calls, patches, agent activity, image generation, and notices.
- Add dynamic tool cells with bounded output previews while retaining arguments and full output in detailed and raw views.
- Preserve last-known statuses for incomplete calls, unavailable results, and declined or failed operations. Keep legacy command text and terminal interaction output when rich reconstruction is unavailable.
- Remove redundant move annotations from patch diffs and retain patch activity IDs.
- Filter untrusted control characters before emitting terminal scrollback, while preserving semantic hyperlinks.
## Testing
Add unit and snapshot coverage for compact and detailed tool rendering, status fallbacks, retained output, patch restoration, and control-character filtering with and without hyperlinks.
GitOrigin-RevId: 73d754262768cf6d91f3ea4040116bf93cf87784
## What changed
- Add compact renderers for commands, MCP calls, computer activity, patches, and plans, with bounded previews and retained transcript details.
- Preserve logical source text, styles, and hyperlink metadata across wrapping so transcript copying can exclude display gutters while retaining meaningful labels. Wrap diff text at grapheme boundaries.
- Add activity identities, ordered detail retention, and deduplicated warning metadata to history cells.
- Hide background terminal interaction notices from chat while retaining them in the transcript, and keep local image-only user messages visible without duplicating image placeholders.
## Testing
Add regression and snapshot coverage for compact previews, retained patch diagnostics, wrapped source text and hyperlinks, question-and-answer labels, and local image placeholders.
GitOrigin-RevId: fd82fadd8ed3418eaba2bc74c4327d9c63d7e997
## Why
Display wrapping removes whitespace and adds gutters, so rendered rows alone cannot reliably describe the original logical text. Streaming previews also need to detect source changes that leave visible rows unchanged.
## What changed
- Retain shared logical text, styles, exact byte ranges, and display margins alongside wrapped rows; remap hyperlinks using those ranges.
- Preserve source metadata through prompt, Markdown, and prefixed history rendering, including spoken artifact annotations. Clear it when split-flap animation replaces the text.
- Include source metadata when comparing streaming previews and agent or plan tails.
- Keep compound graphemes intact, preserve explicit span styles, and reuse first-fit wrapping results when safe.
- Use the lighter history prompt background for submitted messages.
## Testing
Add regression coverage for source ranges and styles across widths and gutters, distinct repeated lines, source-only streaming updates, compound graphemes, and equivalence between reused and generic wrapping results. Extend Markdown, spoken artifact, and animation tests to check retained source metadata.
GitOrigin-RevId: 9e60746642fc9a8f91c1abfe7c77eefc1fe421ab
## What changed
- Render spoken user prompts with a bold red chevron, preserving its color during live transcript animation. Trim leading whitespace for display while retaining the raw transcript text.
- Underline and link file references such as `src/lib.rs:42` in spoken assistant transcripts using terminal hyperlinks. Preserve existing links and support Windows-style relative separators.
- Restrict generated file links to existing files with allowed extensions inside the workspace, rejecting hidden paths, traversal, and symlink escapes.
## Testing
Add rendering and transcript tests for the spoken marker, raw text preservation, file links, Unicode column offsets, and Windows-style paths, plus validation tests for rejected file destinations.
GitOrigin-RevId: 5fa180aa606acdc579a916441520602cb2bf3655
## What changed
- Detect visible HTTP(S) URLs in the composer and attach the complete OSC 8 destination to every wrapped fragment, including when part of the URL is scrolled offscreen.
- Cache hyperlink metadata with the textarea wrap state while leaving masked input and destinations larger than 8 KiB unannotated.
- Make shared hyperlink mapping grapheme-aware, recognize Unicode whitespace boundaries, and scan URLs and trailing delimiters incrementally for large inputs.
## Testing
- Add coverage for wrapped and scrolled URLs, joined emoji, Unicode whitespace, preserved highlighting, masked input, cache invalidation, oversized destinations, and drafts containing many URLs.
GitOrigin-RevId: 40facdf2fe79438c91c82bff2d849c342f1ab28a
## What changed
- Render web-link labels in cyan with an underline and hide the repeated destination in recognized terminals with hyperlink support.
- Keep destinations visible for unknown terminals, multiplexers, non-terminal output, and empty labels so the URL remains usable.
- Preserve OSC 8 link targets through prose and table wrapping, streaming updates, transcript clipping, and pager scrolling.
## Testing
- Add coverage for terminal detection, label formatting and fallbacks, wrapped tables and prose, streaming parity, history output, and scrolled transcript rendering.
GitOrigin-RevId: 4a09e41e349ba299022a9c00f0c25892d9aaefe3
## What changed
- Skip hyperlink layout for wrapped rows above the scroll offset and stop once
processing reaches the bottom of the viewport.
- Resolve each rendered link destination once while marking its visible cells.
- Add coverage for hyperlinks that span visible wrapped rows after scrolling.
GitOrigin-RevId: c1506d47fa3f1b895966dc2cde7d5b859c201792
Encode each character into a stack buffer before appending it to the
decorated span, avoiding a temporary `String` allocation for every character.
GitOrigin-RevId: 72ec1ad5363391dffee089f04073d827d8c459bf
## What changed
Return early from `mark_buffer_hyperlinks` when none of the supplied lines
contain hyperlink metadata, avoiding unnecessary paragraph layout work.
GitOrigin-RevId: bdd6727f3dab7cef87646f97ac955e848cfcfee2
## What changed
- Use Ratatui-compatible terminal widths throughout TUI layout, preserving
full-width counters for long lines.
- Wrap and truncate on grapheme boundaries so halfwidth kana sound marks and
emoji sequences stay intact.
- Apply the corrected sizing to text input, selection popups, status and
history cells, Markdown, hyperlinks, and scrollable cloud diffs.
## Testing
- Add focused unit and snapshot coverage for wrapping, truncation, cursor and
mask alignment, popup columns, status output, session headers, Markdown
tables, process output, and scrollable diffs.
GitOrigin-RevId: 294ec0bcff743c6bb16d55ec26308524ce741879
## What changed
- Mark OSC 8 hyperlink cells with their visible width so Ratatui's buffer diff handles wide and halfwidth characters correctly.
- Use Ratatui's diff iterator while explicitly clearing styled trailing cells when a forced-width cell replaces a wider cell.
## Testing
- Add coverage for forced-width hyperlink rendering, always-update cells, and styled trailing-cell cleanup.
GitOrigin-RevId: 041128f43beb1e09d40179a3ac16dca1fbdcbc44
## What changed
- Upgrade `ratatui`, `ratatui-macros`, `crossterm`, and `ansi-to-tui`, and adapt the TUI to their updated rendering, backend, color-conversion, and cell APIs.
- Use Ratatui's cell-width and continuation-cell metadata when mapping OSC 8 hyperlinks so links remain aligned across wrapped wide glyphs and halfwidth characters with dakuten.
- Preserve explicit hyperlinks in the sign-in success screen and empty MCP state without embedding escape sequences in the text passed to Ratatui.
## Testing
- Add regression coverage for hyperlink placement across wide glyphs and halfwidth dakuten, hyperlink preservation in onboarding and MCP output, and display-width handling.
GitOrigin-RevId: 8460873e5a266923acd0417bc46264845eab0134
## What changed
Add a borrowed `Line` conversion and use it when rendering and measuring
hyperlink-aware history and pager content. This preserves line styling and
alignment while avoiding clones of the underlying span strings.
GitOrigin-RevId: c9cd6ff5ec63cd29719ea2ae51acede7364f2bd8
## What changed
- Allocate Markdown table widths in bulk while preserving the existing column
shrink priorities and balancing behavior.
- Reuse flattened styled-line data during adaptive wrapping and detect URLs
across span boundaries.
- Remap wrapped terminal hyperlinks with a single forward scan.
## Testing
- Verify bulk table shrinking matches the previous one-cell-at-a-time results,
including a token-heavy column with a million-character width.
- Cover URLs split across styled spans and multiple links on indented Unicode
lines.
GitOrigin-RevId: 24a6fd6fdace6ca948e613d67c130a3a7f8d1a4e
## Why
Assistant-authored inline visualizations need a terminal fallback that lets users open generated artifacts in a browser.
## What changed
- Recognize `::codex-inline-vis{file="..."}` directives in assistant Markdown and replace them with browser links during streaming, finalized history rendering, and local transcript previews.
- Materialize visualization fragments in sandboxed viewer documents with a content security policy, while restricting artifacts to HTML files within the thread's visualization directory and limiting their size.
- Show an explicit unavailable message for invalid or missing artifacts, hide incomplete streaming directives, and preserve directive text in code blocks and user Markdown.
- Add a trusted file-link path for generated viewers without enabling arbitrary `file:` links in Markdown.
## Testing
Add coverage for directive rewriting, streaming and replay, artifact validation, sandboxed viewer generation, trusted terminal hyperlinks, and literal preservation.
GitOrigin-RevId: a666b4ebc82bb5798ad45bd137fd815d538e1de2
## Why
Wrapped URLs in rich TUI output, especially URLs rendered inside
Markdown tables, are split across terminal rows. In terminals that
support OSC 8 hyperlinks, treating each visible fragment as part of the
complete destination enables reliable open-link and copy-link actions
even after table layout wraps the URL.
This addresses the semantic-link portion of #12200 and the behavior
described in
https://github.com/openai/codex/issues/12200#issuecomment-4535452980. It
does not change ordinary drag-selection across bordered table rows.
## What Changed
- Added shared TUI OSC 8 support that validates `http://` and `https://`
destinations, sanitizes terminal payloads, and applies metadata
separately from visible line width/layout.
- Added semantic web-link annotations to assistant and proposed-plan
Markdown, including explicit web links and bare web URLs in prose and
table cells while excluding code and non-web Markdown destinations.
- Preserved complete URL targets through table wrapping, narrow pipe
fallback, streaming, transcript overlay rendering, history insertion,
and resize replay.
- Routed intentional Codex-owned links in notices,
status/setup/app-link, feedback, onboarding, MCP/plugin help, memories,
and update surfaces through the shared hyperlink handling.
## How to Test
1. Run Codex in a terminal with OSC 8 link support, such as Ghostty, and
request an assistant response containing a Markdown table whose last
column contains a long `https://` URL.
2. Make the terminal narrow enough for the URL to wrap across multiple
bordered table rows.
3. Use the terminal's open-link or copy-link action on more than one
wrapped URL fragment and confirm each fragment resolves to the complete
original URL.
4. Resize the terminal after the table is rendered and repeat the link
action to confirm the destination survives scrollback replay.
5. Open the transcript overlay while rich output is present and confirm
web links remain interactive there.
6. As a regression check, render inline/fenced code containing URL text
and a Markdown link such as
`[https://example.com](mailto:support@example.com)`; confirm these do
not acquire a web OSC 8 destination.
Targeted automated coverage exercised Markdown links and exclusions,
wrapped and pipe-fallback tables, streaming/transcript overlay
propagation, status-link truncation, and rendered word-wrapping cell
alignment. `just test -p codex-tui` was also run; it passed the
hyperlink coverage and reproduced two unrelated existing guardian
feature-flag test failures.