## What changed
- Show draft attachment thumbnails in reference order in inline and fullscreen views on supported terminals with local workspaces. Display a `+N` count for attachments that do not fit, and preserve editable image references when previews are unavailable or space is limited.
- Refresh previews when attached files change, apply image orientation metadata, and clear frame graphics before terminal handoffs, screen switches, and shutdown.
- Finish CLI subcommand dispatch before polling interactive TUI events.
## Testing
Add a regression test and snapshot covering thumbnail order, overflow, resizing, attachment deletion, file replacement, and fallback behavior in both inline and fullscreen views.
GitOrigin-RevId: 1ea7c89e089cecc390e145c1790b6ede8bad8d5e
## Why
Switching model providers can hide saved chats from resume lookup or prevent them from opening. Keep their history readable when the server rejects resuming because of a provider mismatch, missing configuration, or policy conflict.
## What changed
- Include all providers in the resume picker, named resume lookup, and `resume --last`, while retaining provider filtering for fork lookup.
- Open chats with provider errors as read-only history and show an explanation with recovery shortcuts: `c` to continue in a new chat, `n` to start fresh, and `Esc` to choose another chat.
- Continuing in a new chat prepares an editable, unsent prompt referencing the saved conversation.
- Preserve drafts and rejected prompts or steers, suppress automatic submission, and retry provider admission when reopening the chat.
## Testing
Add coverage for cross-provider discovery, read-only history, configuration recovery, continuation drafts, rejected input recovery, error rendering, and Escape handling during transcript browsing.
GitOrigin-RevId: 5aaa7a404b9a6231101599adef18d2f1e4a8020a
## What changed
- Add the disabled-by-default `tui_extensions_statusline` feature to render configured status items and their picker preview through a shared UI tree renderer.
- Support text, HTTP(S) links, rows, spacers, dividers, and gaps with rendering budgets, text sanitization, and width-aware truncation that keeps the ellipsis outside hyperlinks.
- Use plain text for the extension status line and hide the picker's theme color toggle while preserving the saved color preference.
## Testing
Add coverage for tree serialization and URL validation, Unicode widths, hyperlink clipping, picker previews, color preference preservation, and token usage updates across renderer switches.
GitOrigin-RevId: a6b87c2b1096765d61296d73e142834fcd53ceee
## What changed
- Handle `TurnModerationMetadata` for the active turn, showing a temporary block notice while an explanation is pending.
- Validate safety recourse metadata and render topic-specific explanations with safer ways to continue for biological and cybersecurity policy blocks. Apply the explanation only when the terminal policy error matches its domain; otherwise retain the existing error handling.
- Queue input while recourse is pending and preserve prepared images when queued messages are submitted.
## Testing
Add an integration test covering biological and cybersecurity blocks, the loading notice, and fallback for a mismatched policy error, plus a snapshot of the cybersecurity explanation. Extend queued-image coverage to verify submission succeeds after the original image file is removed.
GitOrigin-RevId: dd9ca57cf3b2d842e3deb8aff5d7c3c73a92e14d
## 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
## What changed
- Add nullable `startedAtMs` and `completedAtMs` fields to `ThreadItem` in live notifications and turn history. Values are Unix milliseconds when recorded.
- Preserve recorded item times through history reconstruction, pagination, and resume, including command start times recorded during approval.
- Separate the Rust item payload into `ThreadItemPayload` while keeping the JSON payload flat, and update consumers, schemas, and generated TypeScript and Python types.
## Testing
Extend coverage for timestamp serialization, history reconstruction, paginated reads and resume, and persisted Python SDK items.
GitOrigin-RevId: ecbcee95af52db7c807b46a6e9deb30e5fba1f80
## Why
Queued prompts can resume before a pending permissions menu opens, and local
`/permissions` commands can bypass guards for outstanding permission changes.
Attaching to a different project can also retain model access information from
the launch directory.
## What changed
- Route `/permissions` through app permission guards and hold queued prompts
while the menu is pending. Settle the hold when opening is rejected, discovery
is invalidated, or a covering request is resolved.
- Apply the custom permission profile selection check beyond embedded servers.
- Refresh API-key model access when the first attached session changes the
working directory, including with an embedded server. Propagate the widget's
model catalog to the app and server even when the model response matches the
widget's already-updated catalog.
- Skip sessions reported as `thread not loaded` during name lookup for all
server types instead of falling back to unverified list metadata.
## Testing
Add regression coverage for permission guards, queued prompts across successive
permission menus, invalidated and covered menus, model catalog propagation,
project changes on initial attachment, and name lookup across server pages with
unreadable entries.
GitOrigin-RevId: eb49cb5268ce0ce1e40009b73a0180f23e61ed72
## What changed
Stop showing title-generation spinners in the footer, status line, and terminal title. Remove the associated UI pending state and animation refresh logic while retaining background title generation.
## Testing
Add a snapshot covering the footer and terminal title while automatic naming is pending. Update status-surface snapshots to cover thread names and ID fallbacks without progress indicators.
GitOrigin-RevId: 061456929149c216f0a98d7214179ec69cdaeee4
## What changed
Allow inline item selection, such as `/title model reasoning` and `/statusline current-dir --no-colors`, without changing saved defaults. Support `--clear` for both commands and `--colors` or `--no-colors` for `/statusline`, including color-only updates that preserve the current items.
Carry overrides with per-thread input state across navigation and reconnects, and allow these local commands in parent-owned subagent threads. Reject invalid or conflicting arguments before applying changes. Saved editor selections supersede the corresponding overrides.
## Testing
Add coverage for argument parsing, atomic updates, rate-limit item aliases and ambiguity, thread-state restoration, saved-setting interactions, and local command submission in parent-owned threads.
GitOrigin-RevId: 909cc2ede026fbf5c7f9cd52c8cf2ae835084f14
## Why
Creating a preset from current settings only offered the model. Permission presets need to preserve the profile, approval policy, and reviewer to restore the same settings.
## What changed
- Add a “Current permissions” option alongside “Current model” when creating a preset from settings.
- Extend `/permissions` with `--approval-policy` and `--reviewer`, including granular policies and quoted profile names.
- Share argument parsing between `/model` and `/permissions`, supporting quoted arguments and both `--setting=value` and `--setting value` forms.
- Keep full-access confirmation for every reviewer and reject automatic review when unavailable.
## Testing
Add parser tests, preset picker snapshots, and permission-selection tests covering complete settings restoration, invalid arguments, unavailable automatic review, and full-access confirmation.
GitOrigin-RevId: f4c9c3f6e264ee8ea4c5244c79f39f2deb15b771
## What changed
Allow `/permissions <profile-id>` to select a built-in or custom permission profile, for example `/permissions :read-only`. Support `:ask-for-approval` and `:approve-for-me` aliases while preserving feature gates, profile requirements, full-access confirmation, and Windows sandbox setup.
Hold queued input until the selection is confirmed, and retain it on cancellation or failure. Reload custom profile definitions on re-selection without leaving unchanged requests pending.
## Testing
Add coverage for unknown and disabled profiles, approval aliases, confirmation and cancellation, discovery retries, Windows sandbox setup, and queued prompts waiting for server confirmation.
GitOrigin-RevId: ada38d3cfc6d6ac4e84ce5645fe33432c55d63cc
## What changed
Replace the `/presets` recall picker with a responsive menu above the composer. Press `0`–`9` to run a saved preset or create one in an empty slot; use `n`, `s`, `e`, and `d` to create, start from current settings, edit, and delete presets.
Add `tui.keymap.chat.open_presets` with an implicit `leader p` shortcut that yields to existing bindings and explicit configuration. Show the action in `/keymap` and add a shortcut tooltip.
Preserve the composer draft, respect popup ownership, and consume held-key repeats after menu actions.
## Testing
Add snapshots for empty, populated, and narrow preset menus, plus coverage for draft preservation, cancellation, held-key handling, transcript search precedence, and default shortcut conflicts.
GitOrigin-RevId: f438c7015dbd416c90cdeb479d2a15d9d6d24954
## What changed
- Add a TUI picker with ten numbered preset slots, an editor, and confirmation before replacement or deletion.
- Create presets from composer text or current model, reasoning effort, and speed settings. Run saved inputs through the normal queued submission path while preserving the composer draft.
- Persist presets under `tui.presets` in the active user configuration, respecting configuration layer ownership and leaving in-memory settings unchanged when writes fail.
- Preserve permissions when changing effort or speed for the effective model, keep default collaboration settings intact in Plan mode, and allow standard-speed selection with older app servers.
## Testing
Add persistence tests for save, replace, delete, configuration ownership, and write failures; picker and confirmation snapshots; and regression coverage for model permissions and standard-speed fallback.
GitOrigin-RevId: 5f11699112cd404cc8e954872d53495c6edd0c0a
## What changed
Allow `/model [model] --reasoning <level> --speed <tier>` to update the current session without changing saved defaults. Both space-separated and `=` flag values are supported; omitting the model applies settings to the current model. Bare `/model` still opens the picker.
Validate model availability, supported reasoning levels, and speed tiers before applying changes. Reject unknown flags, duplicate settings, and missing values. Apply model, reasoning, and speed together after server acceptance.
Restore each thread's speed when switching threads, and use destination configuration defaults for new sessions instead of carrying over the active session's speed.
## Testing
Extend regression coverage for inline commands, invalid arguments, unchanged saved defaults, settings-only updates to hidden current models, destination speed defaults, and speed restoration on the next turn after switching threads.
GitOrigin-RevId: ad9cecbdb3554e34a6518367364978a37fb68439
## What changed
- Add `terminal_columns` and `terminal_rows` buckets to `codex.tui.start`.
- Record `codex.tui.terminal_size` for new turns in the active thread and for resize bucket changes after the terminal size settles for 15 seconds. Reuse launch context and suppress duplicate turn notifications.
- Respect analytics consent for the built-in metrics exporter while allowing explicitly configured OTLP collectors. Apply consent checks to the active exporter across provider replacements.
## Testing
Add coverage for exporter replacement and consent after config reloads. Extend the PTY integration test to verify startup size buckets, turn-start observations, and delayed resize observations with analytics disabled and an explicit OTLP collector.
GitOrigin-RevId: e01a900cd3f04a36731078f725c75374596cb01b
## What changed
- Group preferences into Appearance, Notifications, Input, Sessions, and Text selection tabs, with search and links to existing theme, status line, terminal title, and keyboard editors.
- Persist preference changes to the selected local configuration file, apply supported changes immediately, and show save errors, configuration overrides, and restart requirements in the panel.
- Add a delayed notification test and controls for notification timing while preserving custom event filters.
- Add `tui.copy_on_select_clear_selection`, disabled by default, to clear transcript selection highlights only after confirmed automatic clipboard delivery.
- Keep local configuration editors usable while disconnected and prevent held activation keys or buffered input from triggering actions across editor and reconnect transitions.
## Testing
Add regression tests and rendering snapshots for panel navigation, search, dependency states, editor handoffs, offline persistence, notification timers, custom filter preservation, and confirmed-copy deselection.
GitOrigin-RevId: a16d218046060fcb6e61705a803fcd9297266e6e
## Why
Voice failure metrics lacked cause and lifecycle phase, and session durations were recorded before the final outcome was known. A failed control send could also overwrite a more specific WebRTC error.
## What changed
- Tag `codex.voice.session.failure` with bounded `cause` and `phase` values, recording at most one failure per session.
- Capture duration when stopping and emit `codex.voice.session.duration` at cleanup with a `success` or `failure` outcome.
- Carry typed WebRTC errors into the TUI, preserve existing errors when control sends fail, and avoid duplicate errors after startup failure.
- Record app-server disconnect failures for background voice sessions as well as the visible session.
## Testing
Add coverage for terminal outcome and failure metric attributes, preservation of specific startup and audio-session errors, and startup failures without duplicate control-channel errors.
GitOrigin-RevId: 5aeda6e766093e3fce7206560aa83b6f7770dddb
## Why
Lifecycle status reporting was limited to direct iTerm2 sessions. OSC 7501 lets other terminals receive Codex's program state.
## What changed
- Emit OSC 7501 with `app=codex` and states `idle`, `working`, or `blocked` whenever stdout is a terminal, including multiplexed sessions. Report `blocked` when user action is required.
- Continue emitting iTerm2's OSC 21337 status and bounded activity details in direct iTerm2 sessions.
- Clear status before handing the terminal to an external program, as well as on suspension and exit, and re-emit the current state after returning.
## Testing
Add coverage for OSC 7501 encoding, combined iTerm2 output, clearing both protocols, and protocol selection across terminal and multiplexer environments. Update lifecycle tests and status snapshots for the new protocol.
GitOrigin-RevId: 6d2a6885687b0e7af825e954fab72db0765c9a07
## What changed
Allow mouse selection and plain-text copying of rendered status and footer text, honoring `tui.copy_on_select` and existing selection keyboard controls. Keep the selected region stable while other content updates, preserve Unicode and terminal hyperlinks, and clear selections when their region becomes invalid.
Defer warning clicks until a stationary mouse release so dragging selects text without opening the warning viewer. Preserve the composer draft and cursor while selecting footer text.
## Testing
Add unit and snapshot coverage for visible-text copying, Unicode and hyperlinks, selection invalidation, keyboard ownership, and stationary clicks versus drags. Add a fullscreen integration test for warning selection and draft preservation.
GitOrigin-RevId: dd14d7ede52e97e507be24c4d6ac0299f7388a9b
## Why
The iTerm2 session status reports `Working` without describing the current activity.
## What changed
Populate the OSC 21337 `detail` field from the TUI status header during foreground work, for example `Reading source`. Leave it empty for idle, waiting, background-only work, and the generic `Working` header.
Reuse terminal-title text filtering and the 240-character limit, then escape semicolons and backslashes for the status payload. Include detail in the emission cache so activity changes update the terminal even when the lifecycle state stays the same.
## Testing
Add coverage for foreground-only details, payload encoding, text filtering and truncation, and cache updates when the detail changes.
GitOrigin-RevId: b27a287b80e0db52be6cd9d5d246f03897e2996b
## What changed
Emit `Idle`, `Working`, or `Waiting` with colored indicators through iTerm2's `OSC 21337` session status protocol. Pending user action takes precedence over running tasks and background processes.
Limit emission to direct iTerm2 TTY sessions without a terminal multiplexer. Deduplicate successful writes, refresh status after terminal handoffs and resume, and clear status on suspension and exit.
## Testing
Add coverage for lifecycle transitions, protocol encoding, terminal detection, write retries, deduplication, and re-emission after terminal handoffs.
GitOrigin-RevId: 750e9ec92aeefc57651886a08ef6aea07675d175
## Why
Skill selection and disabled-path matching need to recognize equivalent Windows paths across case and separator differences while preserving literal spaces, `%`, and `#` in native filenames.
## What changed
- Carry `PathUri` through skill metadata, discovery mappings, filesystem lookups, disabled-path sets, and invocation analytics.
- Match linked skill mentions and TUI selections by parsed path identity.
- Use `LegacyAppPathString` for app-server skill paths and regenerate schemas and SDK types, preserving native path strings on the wire.
- Preserve native catalog display paths and ordering. Keep host filesystem probes and configuration writes restricted to host-compatible paths.
## Testing
Add regression tests for Windows path identity and disabled-skill matching, literal filename characters, catalog resource reads, native path ordering, and foreign-path analytics normalization.
GitOrigin-RevId: c212916dc9fef0e7616542726e107f0d6a313267
## Why
Legacy terminals report key auto-repeat as new presses, which can trigger repeated image pastes when presses accumulate during a slow paste.
## What changed
Suppress repeated `Ctrl+V` and `Alt+V` image paste presses within a sliding 250 ms window, refreshed after each suppressed press and after a paste completes. Clear suppression on other ordinary key presses or key release events so a fresh paste can proceed immediately.
## Testing
Add regression coverage for repeated presses, window expiry, and resetting suppression on another key press or a key release. Update the shortcut remapping test to release the key between image pastes.
GitOrigin-RevId: 45abc056e5bda47d1c9704702e369e63dcce29db
## What changed
Render confirmation dialogs as centered overlays while preserving the composer or parent picker behind them. Share dialog sizing and cursor placement across stacked views and full transcript rendering, with input still routed exclusively to the active dialog.
Use the shared confirmation preset for prompts including full access, session archive/delete, goal changes, and log upload consent.
## Testing
Add coverage for backdrop retention and cursor routing at multiple terminal sizes, and for preserving the compact viewport and composer draft after dismissing a confirmation without replaying history. Update confirmation snapshots to show the retained backdrop.
GitOrigin-RevId: 026af89904ec345e2b330317b8cc844512125d0e
## What changed
Replace the rename field with a single-line `TextArea` that honors configured editor bindings and the composer's Vim setting. Start renaming in insert mode and support Vim Escape recovery on legacy terminals.
Strip carriage returns and newlines from titles and pasted text, keep Vim linewise pastes inline, and scroll horizontally at grapheme boundaries to keep the cursor visible.
## Testing
Add single-line editor coverage for newline filtering, Vim commands, repeat edits, and inline yanks. Extend command-center tests to cover Vim renaming across status-filter changes and cursor placement in narrow layouts.
GitOrigin-RevId: 8d320d6b6de9f77e18292169418383929ca6ceda
## Why
Permission shortcuts checked local configuration while the picker used the connected server's catalog and requirements. Shortcuts should respect the same server restrictions, including model-specific auto-review requirements.
## What changed
- Share a cached server catalog between the permission picker and shortcuts. Show the loading picker when no catalog is available and reuse an outstanding fetch.
- Clear the cache on session, account, working-directory, or connection changes.
- Give discovery RPCs distinct request IDs for each fetch and profile page so repeated requests after timeouts do not collide.
## Testing
Add coverage for loading and catalog reuse, managed permission restrictions, and refetching after disconnect. Update timeout coverage to verify that repeated discovery attempts use distinct IDs and each reports a timeout.
GitOrigin-RevId: 7d79874294136bfe3a654bb306eb7caf36d4df1e
## What changed
- Add `/daybreak` with account-aware help and availability messages for broader access for cybersecurity work.
- Save the selection in thread metadata and the `daybreak` default for new threads, restore it on resume, and confirm that it applies to new turns.
- Select `cyberAccessProgram` from the connected server's model catalog. Require a signed-in ChatGPT account, the OpenAI provider, and confirmed model support when Daybreak is enabled, including for faster-model retries. Keep Daybreak disabled for side conversations.
## Testing
Add tests for toggle persistence, turn access-program selection, unsupported-model rejection, side-conversation behavior, command help, and the resumed-thread banner.
GitOrigin-RevId: e3c028b0a6a8e0a862c16fdc766f374aae618ef1
## What changed
Select cyber refusal notices from the current model's `available_access_programs` for ChatGPT accounts using the OpenAI provider. Show Astra-specific guidance only when an Astra model offers standard cyber access without Daybreak access, and use the limited notice when Daybreak access is available. Otherwise, show application guidance.
Remove the separate account eligibility request, background prefetching, and notice cache.
## Testing
Update tests to cover catalog-based notice selection, missing model metadata, isolation from other models' access programs, and rendering the application notice for a cyber policy error.
GitOrigin-RevId: 88e9522bd6ece2d2b9caa6cff01a4178768babb7
## What changed
Fetch optional security setup notices asynchronously for local ChatGPT sessions using the OpenAI provider. Verify that saved credentials match the connected app server, ignore stale account responses, and validate notice text and HTTPS actions on `chatgpt.com`.
Show notices as dismissible inline banners with a browser action, while giving applicable usage banners priority. Preserve notice state and dismissal across thread changes, reconnects, and banner replacement for the same account and user.
## Testing
Add authenticated HTTP fixture tests, notice validation tests, and TUI tests covering stale responses, dismissal persistence, usage banner priority, browser actions, and wrapping in narrow terminals.
GitOrigin-RevId: b8635fcf6a26b42b6a06640601c8517d8d5e47e8
## Why
Reconnecting paused all recovered input, including queued messages that had never been sent. Those messages can resume automatically once any uncertain submissions are resolved.
## What changed
- Track unsent and unconfirmed messages separately. Reconcile submitted prompts and steers using exact client message IDs from restored history, buffered events, and later receipts.
- Remove confirmed submissions from the recovered queue and resume unsent input after replay. Keep uncertain submissions paused without resending them, and show a notice identifying the message whose delivery could not be confirmed.
- Preserve pauses for unavailable conversations, pending compact/review requests, and existing input recovery failures.
- Simplify reconnect status text and remove blanket disconnect/reconnect transcript notices.
## Testing
Update reconnect integration tests and snapshots for automatic queue resumption. Add coverage for matching and unrelated receipts, missing history, late confirmations across navigation, pending compaction, and preservation of image-failure recovery pauses.
GitOrigin-RevId: d0b9aa43c4019d472985d12bbce8ba9bbfb9253b
## What changed
Remove automatic next-message generation after successful turns, suggestion rendering in the composer, and the associated Tab acceptance and Escape dismissal handling. Remove the `tui.prompt_suggestions` configuration option and its schema entry, along with suggestion-specific tests and snapshots.
GitOrigin-RevId: 63bf6f2ca85da6ece502c86e2a805d000bf34210
## What changed
- Use the compact title, version, and directory layout for all session headers, including resume, fork, and clear-screen flows. Remove the boxed model row and retain the optional greeting and YOLO permissions indicator.
- Share title styling with the status card and honor the active render mode and wrapping policy when inserting a fresh header after clearing the screen.
## Testing
Update header and startup snapshots for the borderless layout, narrow widths, and halfwidth directory characters. Add assertions that clearing history preserves the raw header in raw output mode.
GitOrigin-RevId: 0b91c1ce6646f9d9d1954b1442936abe93bdcd3c
## Why
Closing the warnings viewer left reviewed diagnostics in the warning badge and subsequent visits, with no way to dismiss them.
## What changed
- Dismiss only warning pages actually rendered when closing with `Esc`, `F2`, or `Ctrl+C`, and update the footer hint to “dismiss & close”. Unviewed warnings remain available.
- Hide dismissed diagnostics from the badge and viewer while their details are unchanged. Updated details make a warning visible again.
- Reset dismissals when clearing the transcript and ignore queued dismissals from an earlier transcript.
- Cache warning counts until transcript cell identities or dismissal decisions change.
## Testing
Add regression coverage for partial dismissal, navigation that skips rendering a page, changed warning details, and transcript resets with queued dismissals. Update snapshots for the close hint and remaining warning count.
GitOrigin-RevId: 3ce88c62a7f0ff9de34062165051e22168d3db25
## What changed
Connect the existing composer suggestion UI to generation when `tui.prompt_suggestions` is enabled. Request suggestions after successful live turns with known reasoning-summary settings, skipping replayed or duplicate completions and turns with queued follow-ups.
Generate suggestions in hidden, ephemeral forks of the completed turn, preserving conversation context and exposed live settings. Keep fork events out of the visible conversation and reject requests for user interaction. Cancel generation after 30 seconds, interrupt unsuccessful requests, and unsubscribe temporary threads.
Clear suggestions on new submissions, thread changes, reconnects, and feature disablement. Let Escape dismiss suggestions before entering backtrack mode.
## Testing
Add tests for live-turn eligibility and deduplication, preserved request prefixes and settings, hidden fork behavior, startup cancellation, and timeout cleanup.
GitOrigin-RevId: 92ddf3b06448adcc6f4330914cbd8102bff98046
## Why
TUI test helpers used `TempDir::keep()`, leaving temporary Codex homes on disk after fixtures were dropped.
## What changed
Retain `TempDir` ownership in widget and app fixtures so their homes are removed on drop. Transfer ownership to app fixtures to keep the home alive across widget replacement, and retain directory guards in tests that use configs directly.
## Testing
Add regression tests for recursive cleanup, isolation between widget homes, and app home survival across widget replacement followed by cleanup on app drop.
GitOrigin-RevId: fe80f982cc467ede4c3e1edbac8012ec3066dfb3
## Why
Native clipboard setup and writes can block, preventing the TUI from processing input or closing overlays while a copy is in progress.
## What changed
- Route clipboard copies through one session worker that retains native clipboard ownership. Keep terminal escape output on the UI thread.
- Show pending and busy status messages, reject additional copies without queuing them, and ask users to retry image paste after an active copy finishes.
- Abandon setup after five seconds and prevent late delivery. Keep the worker busy until the blocked call returns, and bound shutdown waiting for clipboard handoff.
- Match completions to their originating requests so stale results cannot clear newer selections or unexpectedly resume transcript following. Retain selections on automatic copies, failures, and unconfirmed delivery.
## Testing
Add regression tests for blocked backends, overlay exit, copy and paste ordering, setup expiry, bounded shutdown, completion status messages, and preservation of replaced or moved selections.
GitOrigin-RevId: 4ba1f8da258b9d0700b0edec9ac0ba699f536785
## Why
Queued-message edit hints could vary by terminal instead of showing the first configured shortcut. Use the keymap consistently for queued messages and async question navigation.
## What changed
- Make `Shift+Left` the primary shortcut for advancing through questions and editing the last queued message, and `Shift+Right` for navigating back toward the composer. Keep `Alt+Up` and `Alt+Down` as alternatives.
- Remove terminal-specific hint selection and derive hints from the configured keymap, including custom chords and unbound actions.
- Update question footers, queued-input previews, and keymap picker snapshots to reflect the preferred shortcuts.
## Testing
Extend tests to cover both default shortcut pairs, configured shortcut ordering, custom chord hints, and hiding the queued-message edit hint when the action is unbound.
GitOrigin-RevId: e0f60860ef1e81c71ca0fc32369b8cbd12582b47
## What changed
Remove trailing periods from concise built-in option descriptions and disabled-option explanations, and simplify wording across TUI menus. Share the built-in permission preset descriptions between permission pickers.
Document the convention in `codex-rs/tui/styles.md`, including normal punctuation for descriptions with multiple sentences and preservation of externally supplied descriptions.
## Testing
Update menu assertions and rendering snapshots for the revised copy and line wrapping.
GitOrigin-RevId: 3231d25484178452ab001af5ddc982460d14f94a
## Why
Several TUI views hard-code 24-hour timestamps even when the detected system preference is 12-hour time.
## What changed
Use the existing `ClockFormat` preference for rate-limit and spend-control reset times, usage notices, backend banners, reset-credit expiration times, analytics timestamps, and expanded session details in the resume picker. Capture the preference when constructing views and preserve existing timezone handling, including analytics' UTC labels.
## Testing
Add coverage for midnight, noon, and next-day reset labels in both clock formats, plus 12-hour analytics rendering with UTC labels. Update snapshots for status, banners, usage notices, reset-credit details, and expanded sessions, including narrow-width layouts. Pin test fixtures to explicit clock formats for deterministic output.
GitOrigin-RevId: 73c36d603ddc4eb7800614650a14c6f2961f8b70
## Why
Conversations open in another app disable the composer. Let users continue in an editable fork while the original conversation remains owned by that app.
## What changed
- Add an `f`/`F` shortcut and footer hint to the locked conversation view, preserving local drafts and queued prompts in the fork.
- Show “Forking conversation…” while a fork is pending, block additional key input, and discard buffered input after forking from the locked view.
- Replace the previous session summary after a fork with “Fork created. You can continue here.”
- Keep the locked view and draft intact if the fork request fails.
## Testing
Add tests for shortcut ownership and modifiers, repeated input, editable forks that preserve drafts and queued prompts without taking the source lease, and failure recovery. Add snapshots for fork progress, completion, and the updated footer.
GitOrigin-RevId: 2ecdb0b7fc7e82d8295097faa567995d7a2f7d92
## Why
Quota warnings were hidden from normal transcript rendering, leaving no persistent reminder of remaining usage near the composer.
## What changed
- Show the most constrained quota window in the existing composer hint row, using the existing plan-specific warning thresholds. Include remaining usage, reset time, and `/status` when space permits.
- Keep the notice visible while typing or running a turn, even with tooltips disabled. Yield to interaction controls and blocking banners, and suppress the notice when usable credits are available.
- Preserve quota metadata across sparse updates and thread switches. Require a fresh account usage read to confirm recovery, ignore reads made stale by newer rolling updates, and clear notice state on account changes.
- Render quota warning history cells in both transcript modes while retaining warning counts and replay deduplication.
## Testing
Add unit, integration, and snapshot coverage for warning thresholds, narrow layouts, unchanged composer geometry, suppression, recovery, overlapping reads, account changes, and native transcript replay.
GitOrigin-RevId: e45dc94a6e7a9dad50307840b9fdb15978d053dc
## What changed
Add a picker for Scrollback and Fullscreen modes that requires explicit
confirmation and saves `tui.fullscreen_transcript` to the selected user config
file. Keep the running renderer unchanged and explain that a restart is required
and launch overrides still apply. Report save failures without changing the
stored preference in memory.
## Testing
Add picker snapshots and tests for confirmation, cancellation, selected-config
persistence, and failed saves. Add a PTY test covering mode changes in both
directions across restarts while verifying that the current session stays in
its original mode.
GitOrigin-RevId: 7f231ab37c89e2168133fcfd6aaee54775aa7972
## What changed
Replace `tui.whimsy` with `[tui.effects]` preferences for `starfield`, `shimmer`, `welcome`, `effort`, `progress`, and `title`. Each defaults to `true` and remains subordinate to the `tui.animations` master switch.
Wire the preferences into composer effects, welcome artwork, status and loading text, progress indicators, and terminal-title animations. For example, disable shimmering text while keeping progress animations:
```toml
[tui.effects]
shimmer = false
```
Keep retired `tui.whimsy` entries loadable but ignore their value. Update the configuration schema to expose the new preferences.
## Testing
Add and extend coverage for independent shimmer and progress effects, master-switch precedence, welcome and starfield controls, terminal-title blinking, and strict configuration loading with the retired setting.
GitOrigin-RevId: 28b37ba52872133b8954543cabe9ff424147f1c5
## What changed
- Render a rotating Codex logo in unused space above the composer on fresh conversations, without moving content or the cursor.
- Fade and pause the logo while drafting or unfocused, hide it on alternate views, and dismiss it after submission or conversation activity. Respect disabled animations and stop after three rotations with a fade out.
- Replace the onboarding ASCII frame variants with the shared logo renderer, retaining a faded logo after the animation ends and allowing the existing shortcut to replay it.
## Testing
Add rendering and integration tests for logo placement, visibility, pause/resume timing, completion, and preservation of the draft, cursor, header, and footer. Add snapshots for fresh conversations and the onboarding welcome layout.
GitOrigin-RevId: b98c7dd10acea3ef25d6c1495ed22c24202d6280
## Why
Keep diagnostics accessible without adding warning rows to the live conversation or changing the composer layout.
## What changed
- Show a deduplicated warning count in the passive footer, yielding to interactive hints.
- Open warning details with `F2`, `/warnings`, or a click on the warning notice. Support navigation, scrolling, and copying individual diagnostics while preserving the draft.
- Retain startup, runtime, MCP, and deprecation diagnostics in the full transcript. Group MCP details by server and preserve warnings during replay.
- Respect existing custom bindings and chord prefixes when enabling `F2`.
- Show an immediate explanation when `/pets` is unavailable.
## Testing
Add regression tests and snapshots for warning counts, draft preservation, viewer navigation and copying, narrow layouts, terminal scrollback, and keybinding conflicts.
GitOrigin-RevId: 2bc586430da60347cfbaa5bf128bc48f7f9dc777
## Why
The startup composer accepted edits but ignored submission. Its first frame also preceded configured screen settings, and startup failures could leave typed text unavailable.
## What changed
- Honor configured submit bindings during startup, retaining one confirmation until the session and protected input screens are ready. Repeated submit keys do not duplicate the message; edits, `Esc`, disconnects, or destination changes cancel confirmation while preserving the draft.
- Apply local screen, status-line, keymap, and paste settings before the first editable frame. Anchor the composer at the bottom in owned-screen mode and retain the loading frame until resumed history is ready to render.
- Keep an in-memory recovery copy through submission acknowledgment. On startup failure, restore the terminal before printing unsent text, expanding paste placeholders and escaping terminal control characters.
## Testing
Add regression coverage for deferred single submission, configured key chords, cancellation, protected input, paste handling, draft recovery, initial screen settings, and loading-frame handoff, plus a startup layout snapshot.
GitOrigin-RevId: 1eb4c63027f7d59af5d42d8545cd5cb5c3594306
## Why
Composer suggestions and transient hints should preserve the draft and transcript context. Submitting a local command while reading older history should reveal its output.
## What changed
- Separate persistent status from transient footer hints in the owned transcript, sharing layout calculations for rendering, measurement, and cursor placement.
- Overlay command and mention suggestions on history without moving the composer; hide retained suggestions while transcript interactions own input.
- Show responsive, grouped shortcut help above the composer and let `Esc` dismiss it before interrupting a task or navigating history.
- Resume transcript following for submissions, slash commands, and last-response copy results while preserving the reading position during background updates.
- Reset transcript interaction state after prompt reverts and refresh retained usage information without rewriting terminal history.
## Testing
Add regression tests and snapshots for popup placement, clipped layouts, footer focus, shortcut dismissal, local-command scrolling, prompt reverts, and pagination while browsing prompts.
GitOrigin-RevId: 890147313d53f050503165a57610c381ffb93ef5
## What changed
- Render transcript history and live output above the composer when `features.transcript_v2` is enabled and alternate-screen rendering is available. Handle scrolling, selection, copying, links, and older-history pagination in the main view.
- Add a clickable return-to-latest control with new-activity hints and temporary clipboard status. Let plain Enter return to latest when the composer is empty.
- Reflow retained transcript content during drawing and preserve the launch-selected screen mode across configuration reloads and session transitions, including `--no-alt-screen` restrictions.
- Enter the alternate screen with its first synchronized frame, and box CLI startup futures to reduce stack usage during session transitions.
## Testing
Add regression coverage for transcript layout, input routing, follow controls, clipboard status, and screen-mode persistence. Add a PTY test for the first alternate-screen frame and clean exit, and extend session-transition coverage through the CLI dispatcher.
GitOrigin-RevId: 1daf077826c7744b0f57399d10d159923dc87a97
## Why
The TUI ignored dynamic tool items, and replayed tool activity could differ from live output. Concurrent tool completion also needs to preserve transcript order when writing to terminal scrollback.
## What changed
- Retain dynamic tool rows, update them when calls finish out of order, and mark unfinished calls interrupted when a turn ends.
- Queue terminal output behind unfinished dynamic tools and drain settled rows in bounded batches. Preserve queued output through stream consolidation, resize, and rollback without emitting it twice.
- Align replayed file changes, MCP results, and exploration groups with live rendering. Keep hidden reasoning and terminal interaction details within compatible activity groups, and preserve finalized plan fragments.
- Ignore stale history-page responses, bound turn metadata requests to missing turns, and insert older history after session headers. Keep hidden review prompts as activity-group boundaries.
## Testing
Add regression tests and snapshots for out-of-order tool completion, interruption, ordered scrollback emission, rollback, deferred usage updates, replay consistency, overlapping history, and repeated hidden prompts.
GitOrigin-RevId: a3636cfcf4c9c43a0a5bc52a842b80a7834f1409
## Why
The transcript overlay separately generated cell content for height measurement and rendering. Active cells backed by external state could also leave the live tail stale when their revision key did not change.
## What changed
- Share retained text layouts between measurement and painting, and render only visible rows while preserving wrapping, styles, and hyperlinks.
- Reuse stable layouts across frames, invalidating them when width, animation, syntax theme, or terminal colors change. Bound retention by entry count and text size, allowing a single oversized entry.
- Refresh externally mutable cells each frame and bypass live-tail reuse when any active source is not cacheable.
## Testing
Add coverage for layout reuse, eviction, invalidation, and live-tail refresh without a revision change. Expand the transcript snapshot to cover styled text, wide glyphs, wrapping, and hyperlinks.
GitOrigin-RevId: 7dfb737e762f7f056a38774d956f618090809a62