Commit Graph
3250 Commits
Author SHA1 Message Date
Felipe Coury 75a714843b Preserve Markdown tables and whitespace when copying TUI responses (#48549)
## Why

Copied table selections became code blocks containing the rendered grid, losing table structure. Stripping trailing whitespace from completed responses also removed Markdown hard breaks and spaces in code.

## What changed

- Reconstruct Markdown tables from selected cells across grid and record layouts, preserving alignment, inline formatting, and list or blockquote nesting.
- Copy a single selected cell as inline content and leave unselected cells empty without adding their text. Escape literal pipes in table code spans and link destinations.
- Preserve trailing whitespace on lines unchanged by assistant directive removal.
- Keep blank rows in copied text without painting newline selection highlights on empty rows.

## Testing

Add regression coverage for wrapped and rewrapped tables, partial selections, empty cells, literal pipes, and separate table and code blocks. Update snapshots for nested tables and selection highlights, and verify completed-response copying preserves hard breaks and code whitespace.

GitOrigin-RevId: 661e4c8331f2737bedff286548f9343bac44e0cb
2026-09-26 21:58:39 +00:00
Felipe Coury 16c21e3f36 Preserve table cell source metadata through TUI rendering (#48548)
## What changed

- Retain table identity, column alignments, cell coordinates, source byte ranges, and inline formatting in copy metadata.
- Carry cell fragments through grid padding, wrapping, key/value layouts, and pipe output, including escaped pipes and empty cells.
- Preserve logical source metadata when remapping wrapped lines, even without hyperlinks.

## Testing

Add coverage for cell fragments across narrow and wide layouts, blank table continuations, and Markdown selection copy structure and visible transformations.

GitOrigin-RevId: 8422f224cffe2e74813394f0623b9167bdd4ac59
2026-09-26 21:58:17 +00:00
Felipe Coury d6f25a54ba Fade blossom replays back to the idle state (#48547)
## Why

Clicking the welcome blossom replays its animation, but completion abruptly switches from full color to the dim idle frame.

## What changed

Fade the blossom back to idle opacity over 400 ms after the replay finishes spinning. Keep scheduling redraws until the fade completes, then clear the replay state.

## Testing

Extend the replay test with color snapshots at the start, midpoint, and end of the fade, and assertions that redraws stop and the original idle frame is restored.

GitOrigin-RevId: ec3fafb6766533d9c221913e8a3be03b8a8036f7
2026-09-26 21:57:55 +00:00
Eric Traut 7ed14a27db Make onboarding login links easier to copy (#48544)
## Why

When browser sign-in does not open automatically, users need to copy the login URL. Onboarding should also allow terminal selection of login URLs and device codes in fullscreen mode.

## What changed

- Add a `c` shortcut to copy the browser sign-in URL, with status messages for pending, successful, unconfirmed, busy, and failed clipboard requests.
- Apply asynchronous clipboard results only to the matching login attempt.
- Disable mouse capture during onboarding so the terminal can select text, and restore the previous input policy afterward.

## Testing

Update the narrow-screen login snapshot to show the copy shortcut and extend mouse-policy coverage to verify onboarding leaves mouse capture disabled.

GitOrigin-RevId: 01676b737efb192d900da306cd2c6b32f791ceb9
2026-09-26 21:44:28 +00:00
Felipe Coury 7f6c0f9387 Refresh the TUI welcome screen for new sessions (#48513)
## What changed

- Show a compact session header with a randomly selected greeting, preserving the greeting and blossom state from startup into the live session.
- Center a settled blossom in unused fullscreen space and replay its animation on click. Hide it while typing or when space is insufficient, and respect `tui.animations` and `tui.effects.welcome`.
- Hide startup tips in the fullscreen transcript while retaining them in terminal scrollback, and prevent hidden entries from shifting the first visible header.
- Keep the composer visible and responsive during daemon startup, routing startup diagnostics through tracing while direct lifecycle commands retain stderr output.

## Testing

Add regression tests and update snapshots for blossom placement and click replay, welcome opt-outs, greeting stability, startup transitions, tip visibility, and transcript spacing.

GitOrigin-RevId: ec7b082fbe25ced1180cad3348f5c76e48c0e92b
2026-09-26 18:59:50 +00:00
Eric Traut 0fbf0bedc2 Fix ChatGPT browser sign-in for local app servers (#48502)
## Why

Local daemons use a remote request handle even though their login callback is local, so the TUI skipped opening the browser. Login completion could also arrive while the browser was opening, before the TUI had recorded the active login.

## What changed

- Use `AppServerTarget` to open the login URL for embedded servers and local daemons, while continuing to skip automatic browser opening for remote workspaces.
- Set the pending login state and schedule a frame before opening the browser so completion notifications can match the active login.

## Testing

Add regression tests for browser opening across embedded, local daemon, and remote targets, and for login completion during browser opening.

GitOrigin-RevId: 3feceb877e6131bfd0671c3556314c6c7fd4a677
2026-09-26 18:15:43 +00:00
Felipe Coury a6bd19261c Fall back to embedded mode under restrictive Windows launchers (#48491)
## Why

Windows launchers such as `cargo run` can prevent background processes from outliving them, causing automatic daemon startup to fail and blocking the CLI from opening.

## What changed

- Classify detached launch restrictions by retrying an access-denied launch probe without the job breakaway flag. Keep both probes suspended and terminate and reap successful probes.
- Use the embedded server with a visible warning when automatic startup encounters this restriction. Preserve errors for other launch failures, including inaccessible executables and elevated startup.
- Keep explicit daemon lifecycle operations failing on the restriction, with guidance to build and run `codex.exe` directly.

## Testing

Add Windows coverage for restriction classification and executable access failures, plus a CLI integration test and warning snapshot for embedded fallback under a restrictive job. The integration test also checks that elevated startup still fails and no daemon PID file is created.

GitOrigin-RevId: fc7c46e0f5f07ca0aba12b535a0e372021bdf46a
2026-09-26 17:31:48 +00:00
Eric Traut 6e1ab4d294 Fix Mermaid shape, relationship, and state description parsing (#48489)
## What changed

- Reject unsupported flowchart shapes and Markdown strings so the terminal renderer preserves the source with an unsupported-feature notice instead of misrendering it. Keep ordinary quoted labels containing shape-like punctuation valid.
- Preserve class relationship targets beginning with `o`, such as `A --orange`, instead of consuming the first letter as an aggregation marker.
- Accumulate state aliases and descriptions in source order: use the first as the title and subsequent entries as body rows, preserving state identity and limiting body rows to 16.

## Testing

Add parser regressions for these cases and description limits, update class and state snapshots, and extend TUI snapshots to verify source preservation for unsupported flowchart syntax.

GitOrigin-RevId: c44d954312c77229a3752a0d9ada14e34a43a376
2026-09-26 17:26:07 +00:00
Felipe Coury b334d5b3f2 Default to copying transcript selections in more terminals (#48469)
## What changed

Make `tui.copy_on_select = "auto"` copy on mouse release unless a direct terminal is known to forward its native copy shortcut: Ghostty with a parsed version at least `1.2.0`, Kitty on macOS, Windows Terminal, or VS Code on Windows.

Unknown terminals and Ghostty with older, missing, or unrecognized versions now default to copying. Keep copying enabled under tmux/Zellij and preserve explicit `always` and `never` overrides. Update the configuration documentation and schema to describe these defaults.

## Testing

Expand the existing configuration test matrix to cover more terminals, Ghostty versions (including `1.2.0-dev`), platform-specific defaults, and multiplexer behavior alongside configuration and launch overrides.

GitOrigin-RevId: 410abfa580156454b0f88e0bf4ed977fb8c81b1e
2026-09-26 15:48:27 +00:00
Felipe Coury ca41ed337f Show turn tips while working and after completion in the TUI (#48352)
## What changed

- Show a random tip beneath the working status after 30 seconds, using the existing tooltip catalog and current key bindings.
- Show completion tips only after successful turns with a final answer, starting with the third turn and spacing displayed tips by at least three turn starts. Limit completion tips to two per app session, and skip them when a working tip was already shown for that turn.
- Respect `tui.show_tooltips`, hide tips during composer or transcript interactions, and omit tips when space is insufficient. Count exposure only when a tip is rendered.
- Anchor completion tips after queued history updates, keep them outside transcript selection and search, and dismiss them on history replay or transcript clearing.

## Testing

Add lifecycle tests for timing, completion cadence, duplicate notifications, failed and interrupted turns, and hidden tips. Add rendering snapshots and assertions for completion ordering, resizing, limited terminal space, and exclusion from transcript selection and search.

GitOrigin-RevId: 9e956f5b0377e3be71f9574639c3c6ef11ad1168
2026-09-26 04:17:41 +00:00
Eric Traut 09a3d2108f Display reconnect commands on a separate line (#48350)
## What changed

Print `To reconnect, run:` followed by the indented resume command on its own line in disconnect exit summaries. Update CLI expectations and TUI snapshots for the new layout, and adjust the remote reconnect test to parse the command from its new line.

GitOrigin-RevId: 46f05084482063cf4f196b3b49471f331bc91384
2026-09-26 04:09:02 +00:00
Eric Traut 25270df261 Keep TUI reconnect attempts running until the shared deadline (#48318)
## Why

The five-attempt limit could stop reconnection before the existing 120-second budget expired, preventing recovery from longer temporary failures.

## What changed

Continue retrying with an eight-second delay after the initial backoff until reconnection succeeds or the shared deadline expires.

## Testing

Update the exhaustion test to require the full 120-second budget. Extend the integration test to recover after five failed `thread/resume` attempts and verify draft preservation and notification delivery.

GitOrigin-RevId: 321d4ad100dbec1254bfe8aafd67ff63fb9a6e93
2026-09-26 00:51:21 +00:00
Eric Traut d5355e95ef Keep Codex visible during external editor handoff (#48211)
## Why

Opening a separate-window editor from the fullscreen TUI leaves the alternate screen, hiding the draft and the instruction to save and close the editor.

## What changed

Preserve and repaint the last Codex frame when handing the terminal to an external editor, while releasing keyboard and mouse input modes. Track whether the alternate screen's keyboard mode is active so cleanup does not pop it twice if the editor switches screens. Restore TUI modes and the alternate screen when the editor returns.

## Testing

Add terminal integration coverage for separate-window editors, terminal editors that switch or reuse screens, and inline mode. Verify the visible draft and handoff hint, disabled mouse reporting, edited draft recovery, and continued typing. Add a unit test for balanced keyboard stacks whether or not the editor leaves the alternate screen.

GitOrigin-RevId: c2ff1046a933f5f9e3168663e2c326999845c578
2026-09-25 20:46:05 +00:00
Felipe Coury 4193f1acfb Add a keep-and-next action to the warnings viewer (#48206)
## Why

Closing the warnings viewer dismisses warnings whose pages were displayed. Allow users to keep a warning available for later review while moving through the remaining warnings.

## What changed

- Press `k` to keep the current warning and advance, closing the viewer after the last warning.
- Preserve kept warnings when applying queued dismissal updates, so a later keep decision takes precedence for the same warning details.
- Reserve `k` in the viewer, update footer hints, and suppress key repeats so holding it does not skip warnings or modify the restored draft.

## Testing

Add coverage for keeping warnings, leaving unvisited warnings undismissed, conflicting key bindings, repeated key events, draft preservation, and queued dismissal updates. Update warning footer snapshots.

GitOrigin-RevId: da267b9142ddda78086418192970db2aec370d3a
2026-09-25 20:26:45 +00:00
Felipe Coury 7703f8b354 Dismiss viewed TUI warnings when closing the viewer (#48205)
## 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
2026-09-25 20:26:19 +00:00
Brent Traut de9e78e3e7 Add item anchors to thread/items/list pagination (#48151)
## What changed

Allow `cursor` to accept an item anchor such as `{"type":"item","itemId":"item-123"}` with a non-empty `turnId`. Ascending pagination returns items after the anchor; descending pagination returns items before it. The anchor itself is excluded, and subsequent pages use the returned opaque string cursor.

Resolve anchors within the requested turn's visible history, including inherited fork history. Reject missing turn IDs and empty, unknown, or out-of-scope item IDs with invalid params (`-32602`). Preserve existing string and null cursor behavior, and update the protocol schemas, TypeScript and Python types, and API documentation.

## Testing

Add protocol round-trip and invalid-shape tests, app-server coverage for anchored pagination and errors, and thread-store coverage for growing turns, reverse pagination, page boundaries, fork visibility, and anchor scope validation.

GitOrigin-RevId: a74cea190d3ff1b44865429f8b0650b793eb688d
2026-09-25 17:57:32 +00:00
Eric Traut d9275a63ed Allow Left to open the command center from read-only conversations (#48132)
## What changed

- Let `Left` return to the command center from a conversation open in another app, including while disconnected, without discarding the retained draft.
- Respect editor and Vim keymaps, conflicting shortcuts, and chord prefixes before enabling this navigation.
- Show `←/esc` in the command center hint when `Left` is available; otherwise keep `esc`.

## Testing

Add regression coverage for connected and disconnected navigation, draft preservation, and remapped `Left` with Vim enabled or disabled. Extend attach-conflict coverage to verify that both `Left` and `Esc` preserve the command center selection, and update footer snapshots.

GitOrigin-RevId: 80ef004b548176443ebee03c2a143e723e54c44a
2026-09-25 16:20:53 +00:00
Eric Traut 66c4e5a20d Keep startup drafts visible during command center session handoff (#48121)
## Why

Starting a new session from the command center could clear the startup composer or replace it with `Loading task` before the attached chat was ready to render.

## What changed

Show the startup draft immediately and skip loading frames while it is present. Reset transcript state without clearing the visible draft, deferring the terminal clear until the next synchronized draw. Preserve this behavior during resize reflow as well.

## Testing

Add a regression test and snapshot covering inline and owned-screen modes. Verify that draft text survives the handoff, queued events leave the startup frame intact, and the attached composer retains the draft.

GitOrigin-RevId: 26a7ba2929a3b46537da960cbb7201b21b5dc61f
2026-09-25 15:34:02 +00:00
Felipe Coury b8a1fe4afc Add configurable right-click paste to the fullscreen TUI (#48118)
## What changed

- Add `tui.right_click_paste` with `auto`, `on`, and `off` modes. The default `auto` enables the fallback on Windows and Linux, including WSL when terminal detection is conclusive. `on` also enables macOS. Both modes skip SSH sessions and recognized VS Code terminals.
- Paste clipboard text through the normal composer input path when no selection, search, or blocking view takes precedence. Discard pending results after intervening input, focus loss, or changes to the target thread, draft, or cursor.
- Read text asynchronously through the shared clipboard worker, with a five-second deadline and the message size limit. Read the Windows clipboard through PowerShell on WSL and reject overlapping clipboard operations.

## Testing

Add coverage for platform and terminal policy, normal paste delivery, stale reads, overlapping clipboard operations, read timeouts, oversized text, and large command output.

GitOrigin-RevId: 0a7b6d445c09928da6c5335841ba2a9a66cc7e4b
2026-09-25 15:15:56 +00:00
Eric Traut bf832f4678 Allow reasoning shortcuts to reach Max (#48116)
## Why

Reasoning shortcuts stopped before Max even when the active model supported it, requiring users to open the advanced-reasoning picker.

## What changed

Allow `Alt+.` and `Shift+Up` to raise reasoning to Max in default and Plan modes. Keep Ultra behind the explicit picker and update the guidance to mention only Ultra.

## Testing

Add coverage for both shortcuts reaching Max in both modes, with footer snapshots. Update the Ultra boundary test to verify that raising from Max shows picker guidance without changing reasoning effort.

GitOrigin-RevId: 4e5ef2866f118a1f59313d494a2383db43293da9
2026-09-25 15:05:54 +00:00
Eric Traut e75b36efde Show multiline command previews in /ps (#48101)
## Why

`/ps` previously showed only the first line of each background command, hiding useful details when a command began with an opening parenthesis.

## What changed

Render LF and CRLF line breaks as `↵` in command previews. Include subsequent lines within the existing 80-grapheme limit, and show the truncation marker only when the command exceeds that limit.

## Testing

Update snapshot coverage for multiline commands, including parenthesized commands and CRLF line endings, and add a snapshot for a multiline command exceeding the preview limit.

GitOrigin-RevId: 92544e5636821fc94bc1ca4af389c3c646127c0e
2026-09-25 14:26:57 +00:00
victor-openai 4b1c0c30da Remove plugin extension metadata from discovery and summaries (#48035)
## What changed

- Stop sending `includeExtensions=true` when fetching installed plugins and remove extension metadata from remote plugin models.
- Remove `PluginSummary.extensions` and the associated extension declaration types from the app-server protocol.
- Update generated JSON schemas, TypeScript and Python bindings, and precomputed protocol exports to match.

GitOrigin-RevId: 56509437b6bdf58d99badff68e86bcf7f09fe036
2026-09-25 08:25:37 +00:00
aionescu-oai d0a64e91ae Validate tool suggestion install URLs before showing the app link (#48015)
## Why

Tool suggestions could pass unchecked `install_url` values to the app link view for opening in a browser.

## What changed

Reuse the external URL validator to require HTTPS URLs with a host and no embedded credentials. Decline suggestions with invalid URLs on the requesting thread without showing a popup.

## Testing

Add a regression test covering malformed URLs, unsupported schemes, embedded credentials, and a valid HTTPS URL. Verify that rejected suggestions leave the popup unchanged and resolve on the requesting thread, while the valid URL opens on confirmation.

GitOrigin-RevId: e47bf09868ec81aeaf1ffed8330039b69c60e093
2026-09-25 06:18:12 +00:00
Eric Traut 1f17a0a04b Prevent stale voice answers from reappearing during speech recovery (#47975)
## Why

Queued voice answers could reappear as text under a newer question when speech failed, the pending queue overflowed, or voice stopped, including answers already spoken as paraphrases.

## What changed

Filter recovered and replayed speech by the current input generation, preserving that generation across conversation resets. Keep text fallbacks for answers still awaiting turn completion so delayed user transcripts do not discard unspoken answers.

## Testing

Add regression coverage for paraphrased answers, queue overflow, stop and replay, failed delivery for current versus superseded input, and delayed transcripts.

GitOrigin-RevId: b7b230910bf4fdb4ae93f7de8ca2222a19c55d7f
2026-09-25 00:36:02 +00:00
Eric Traut b725da3b6d Add Pro Max plan support and update Pro display names (#47971)
## What changed

- Recognize `promax` in authentication, account responses, and backend rate limits; update generated schemas and client types.
- Display `prolite` as “Pro”, `pro` as “Pro (More)”, and `promax` as “Pro (Max)” in account labels, status, and analytics.
- Include Pro Max in experimental context eligibility, paid-plan tooltips, and usage-limit guidance for purchasing credits.

## Testing

Extend coverage for Pro Max plan parsing, account and rate-limit responses, experimental context eligibility, and plan display names. Update the login token test to expect “Pro (More)”.

GitOrigin-RevId: 197e00fa7a99cbce125c8f1d43a451ec1ed5c1fb
2026-09-25 00:20:02 +00:00
Eric Traut 40e13e6281 Move fullscreen startup tips into the transcript (#47954)
## What changed

Show the startup tip beneath the session header in the fullscreen transcript, with wrapping on narrow terminals. Remove rotating tips and startup announcements from above the composer, leaving that area for usage warnings.

## Testing

Add startup transcript snapshots at 80 and 32 columns and assert that compact tooltip rendering preserves styled links. Update usage-warning tests to verify composer geometry and recovery without rotating tips.

GitOrigin-RevId: b5e79a46147d112cd50802b0702537deb9b87001
2026-09-24 22:44:55 +00:00
andrewgu-oai 694d8d45bd Remove GPT-5.4 from bundled catalogs and preserve migration prompts (#47932)
## Why

Saved model selections can outlive their catalog entries. Removing GPT-5.4 needs to preserve a migration path without applying it to other providers that may still support the same model slug.

## What changed

- Remove `gpt-5.4` from the bundled catalog and `openai.gpt-5.4` from the Bedrock catalogs, including GovCloud.
- Add fallback migration prompts to GPT-6 Sol for saved GPT-5.4 selections on OpenAI and Amazon Bedrock. Scope fallback migrations, including the existing GPT-5.4 Mini migration, to their owning providers while honoring catalog metadata.
- Update tests that depend on bundled GPT-5.4 metadata to use GPT-5.5 or explicit model overrides.

## Testing

Extend migration tests to cover catalog metadata precedence, acknowledged targets, missing or hidden replacements, and preserving the provider while saving the replacement model and its default reasoning effort. Update Bedrock catalog assertions and picker snapshots.

GitOrigin-RevId: f739795da423b9622db2a416be6c52b01b8e7a71
2026-09-24 20:28:31 +00:00
Eric Traut e154f7b807 Generate TUI prompt suggestions after successful turns (#47929)
## 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
2026-09-24 20:01:59 +00:00
Eric Traut 6743672ad7 Add TUI composer support for prompt suggestions (#47911)
## What changed

Add `tui.prompt_suggestions`, defaulting to `false`, along with suggestion request state, a generation prompt, and strict parsing of single-line suggestions up to 240 characters. Suggestion generation is not connected yet.

Keep suggestions outside the draft and render them dimly in an empty, focused composer. `Tab` accepts a suggestion for editing, a separate `Enter` submits, and `Escape` cancels pending suggestions. Respect active key bindings, popups, attachments, paste bursts, and interactive transcript footers; ignore stale results and cancel suggestions when a task starts.

## Testing

Add parser tests, composer interaction tests, and snapshots covering acceptance, dismissal, stale results, input precedence, wrapping, and transcript search layout.

GitOrigin-RevId: 868001a0fc3e6fd8c11ef1650aabc477fa36e03d
2026-09-24 18:37:33 +00:00
Ian MacLeod 5c8fc15cc9 Alias tui.whimsy to tui.effects.starfield (#47908)
Normalize the legacy setting so existing `tui.whimsy` values control the
starfield effect. If both keys appear in the same config layer, the explicit
`tui.effects.starfield` value takes precedence.

GitOrigin-RevId: 2884dbd643690d500ed8d1493ce47950d93d6ab3
2026-09-24 18:23:11 +00:00
Owen Lin 12cb14f7b7 Default local threads to paginated history (#47900)
## What changed

- Make `LocalThreadStore` default to paginated history while retaining explicit legacy mode.
- Explicitly use paginated history for Guardian review sessions and allow in-memory stores to create paginated threads.
- Rename full-history resume, fork, and subagent helpers to identify them as legacy APIs, and document the paginated alternatives.
- Reject `thread/revert` for ephemeral threads and prevent the TUI from replaying or attaching to ephemeral agent threads.

## Testing

Add coverage for preserving the default and explicitly selected history modes and conversation context across restart, and for retaining context after rejected ephemeral reverts. Extend Guardian checkpoint coverage across both history modes and verify that saved reviews use paginated history.

GitOrigin-RevId: 870239eb3757018159ee4f230a009c97d38ac5b7
2026-09-24 18:07:37 +00:00
Felipe Coury a33fb9751c Preserve Markdown formatting when copying transcript selections (#47896)
## Why

Transcript selections were copied as plain text, losing the formatting of rendered Markdown when pasted.

## What changed

- Retain semantic Markdown annotations through rendering, wrapping, and streaming, then serialize selected text with balanced markup.
- Preserve inline formatting, web links, headings, lists, blockquotes, and hard breaks in Markdown clipboard payloads.
- Keep code-only and other literal-only selections as plain text. In mixed selections, escape user prose and fence code, tables, and tool output to preserve their literal content.

## Testing

Add unit tests and Markdown/HTML snapshots covering partial selections, nested containers, escaping, links, resize stability, and streaming boundaries.

GitOrigin-RevId: f0476334a6bf8ad0fb57626627bd258443540852
2026-09-24 17:55:29 +00:00
Felipe Coury f6fd7f17ed Clean up temporary Codex homes after TUI tests (#47894)
## 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
2026-09-24 17:43:15 +00:00
Eric Traut b3ea9fa632 Include TUI client logs in diagnostic uploads (#47889)
## Why

Diagnostic uploads through the app server do not include the TUI client's diagnostic buffer. Attach those diagnostics when users consent to uploading logs.

## What changed

- Stage the most recent 1 MiB of client logs as `client-logs.txt` on the app-server host and append it to `extra_log_files`.
- Skip staging without log consent and list the optional attachment in the consent dialog.
- Continue uploading the report if staging fails, noting the omitted logs in the report reason. Attempt to remove the staging directory after both successful and failed uploads.
- Make app-server filesystem helpers usable by background requests.

## Testing

Extend submission tests to cover log truncation, preservation of existing attachments, consent gating, staging failures, cleanup after upload failure, and error display. Update consent dialog snapshots to include the client log attachment.

GitOrigin-RevId: 9790834d52772c08a147ee7c176cbbc2aa029d5f
2026-09-24 17:21:45 +00:00
Dmitriy Kovalenko 3d6428510f Warn users when SQLite diagnostic log writes fail (#47887)
## Why

Failed SQLite writes leave diagnostic logs incomplete. Notify users before they close Codex so they can submit logs or run `codex doctor`.

## What changed

- Add a best-effort warning on the first log write failure in standalone and in-process app servers, while continuing to retain failure diagnostics in memory.
- Handle failures that occurred before the in-process warning reporter was attached.
- Tailor the warning's guidance to whether submitting logs is enabled.

## Testing

Add coverage for warning deduplication, both guidance variants, retained diagnostics after the notification sender is dropped, and SQLite flush failures before and after reporter attachment. Extend log upload integration coverage and add a TUI warnings snapshot.

GitOrigin-RevId: 12a74126d13c3568430e539a180cca47fa931fa9
2026-09-24 17:04:50 +00:00
Dmitriy Kovalenko a285066737 Preserve diagnostic logs when SQLite logging fails (#47886)
## Why

SQLite write failures can leave persisted logs incomplete, while log snapshots taken before collection miss errors raised during that collection.

## What changed

- Report SQLite flush failures directly to the in-memory log buffer without re-entering tracing, using an error category and batch size instead of raw error details.
- Track whether the log writer has lost a batch and make app-server diagnostic uploads use the memory buffer when SQLite logs are incomplete.
- Refresh log bytes after flushing and querying SQLite so the same submission includes collection failures, while preserving captured metadata and thread identity.

## Testing

Add regression tests for failure reporting without recursion, subsequent write recovery, metadata preservation, and healthy and failing SQLite collection. Add an upload integration test that captures attachments locally and checks failure diagnostics, memory-buffer fallback, and omission of raw SQLite error details.

GitOrigin-RevId: 51b0c4b69c977d9f4e74f2f245a9fd90fdb13761
2026-09-24 17:04:24 +00:00
Charlie Marsh 90b67c96ca Use Tokio's clock for TUI paste timing (#47881)
## Why

Paste input classification and asynchronous flush deadlines need to share a clock, including when Tokio time is paused in tests.

## What changed

Use Tokio's clock for chat composer paste timing and startup draft newline tracking, converting to `std::time::Instant` where existing composer helpers require it.

## Testing

Run the existing startup draft multiline paste test with `start_paused = true`. It checks that non-bracketed pastes preserve newlines without submitting the draft.

GitOrigin-RevId: 73bac963204473d85e7395781e0df966ecc92801
2026-09-24 16:48:22 +00:00
jif 3e9d1d2937 Avoid nested read locking when rendering browser sign-in (#47861)
## Why

`render_ref` already holds a read lock on `sign_in_state`. Acquiring another read lock in `render_continue_in_browser` can deadlock when a writer is waiting.

## What changed

Pass the borrowed `ContinueInBrowserState` from `render_ref` into the browser sign-in renderer instead of reading the lock again.

## Testing

Update the existing narrow-width browser sign-in test to exercise `render_ref`, retaining checks for the full OSC 8 authentication link, device-code guidance, and cancellation footer.

GitOrigin-RevId: ba83e212d510627be9dfd068c8d7318da32a1749
2026-09-24 15:21:29 +00:00
Felipe Coury 12fd929f72 Keep the TUI responsive during clipboard copies (#47847)
## 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
2026-09-24 14:15:42 +00:00
Ahmed Ibrahim e0ef5a1a0f Reduce generic code duplication in RPC and Markdown rendering (#47751)
## Why

RPC sending and waiting do not depend on request or response types, and Markdown layout does not depend on the parser iterator. Share these implementations across typed calls and parser variants.

## What changed

- Extract `RpcClient::send_request_and_wait` into a non-generic async method, preserving registration before serialization and disconnected-client error precedence.
- Remove the iterator type parameter from `Writer` and pass iterators to event traversal methods, retaining static dispatch and dropping the parser before rendering state, including on unwind.
- Update streaming rendering and existing rendering tests to use the separate parser.

GitOrigin-RevId: 4cc07223111b7c08211028948d13fe04598f8fc7
2026-09-24 04:48:03 +00:00
Eric Traut 7dae8c53d9 Avoid recursive TUI event dispatch for model picker selections (#47717)
## Why

Confirming an Astra model selection recursively polled the large event dispatcher on the TUI thread's stack.

## What changed

Unwrap `AstraSelectedFromModelPicker` before dispatching its model update, then trigger the sparkle afterward when eligible. Keep the eligibility check and model update in the same event so queued backend updates cannot turn a no-op confirmation into a sparkle.

## Testing

Add a regression test that confirms `gpt-6-astra` with `XHigh` reasoning on a thread with a 4 MiB stack and checks the resulting model and reasoning effort.

GitOrigin-RevId: 89df8b417a9fd0107ebb918edeb2d240b53d42bd
2026-09-24 02:09:52 +00:00
Eric Traut 9477081ccd Support quoted labels and ampersands in Mermaid flowcharts (#47678)
## Why

Flowcharts with labels such as `A["Review & confirm"]` fell back to source display instead of rendering a diagram.

## What changed

Accept double-quoted node and edge labels, strip the surrounding quotes, and allow literal ampersands in flowchart labels. Keep other diagram families' label restrictions and continue rejecting HTML, entity escapes, and malformed quotes.

## Testing

Add parser and renderer regression tests for quoted labels, literal ampersands, statement separators, and unsupported text, plus TUI coverage for rendered labels and entity source fallback.

GitOrigin-RevId: 9e61a04665f0266d369fa3595411c9a72f10cb9d
2026-09-23 22:09:41 +00:00
jackz 5bae5b563e Restrict the default Bedrock GovCloud model catalog (#47657)
## What changed

Use a dedicated default catalog for Bedrock Mantle endpoints whose host starts with `bedrock-mantle.us-gov-` and ends with `.api.aws`. Include only GPT-5.6 Terra, GPT-5.6 Luna, and GPT-5.4, with GPT-5.6 Terra as the default.

## Testing

Add model picker snapshot coverage for `us-gov-west-1` and `us-gov-east-1`. Update the configured-catalog test to use a GovCloud endpoint, verifying that a custom catalog is preserved while service tiers remain normalized.

GitOrigin-RevId: 5f22ba6983bd60be52d8845c9709112a4766839d
2026-09-23 20:29:30 +00:00
Felipe Coury ab021e9f13 Add configurable copy-on-select for transcript selections (#47639)
## What changed

- Add `tui.copy_on_select` with `auto` (default), `always`, and `never` modes, and apply it to the fullscreen transcript, transcript overlay, and resume/fork previews.
- Enable `auto` in tmux and Zellij, and in direct macOS terminals except Ghostty and Kitty. On other platforms, enable it in direct terminals identified as iTerm2 or Terminal.app.
- Copy nonempty mouse selections on release, including word and line selections, while retaining their highlight. Preserve link activation and ignore empty selections.
- Clear composer selections after confirmed keyboard copies, matching right-click copies, while preserving the draft and cursor. Keep selections when copying fails or delivery is unconfirmed.

## Testing

Add coverage for terminal defaults and configuration overrides, copying on release, retained highlights, repeated clicks, link activation, and empty drags. Extend composer coverage to verify selection clearing for `Cmd-C`, `Ctrl-C`, and right-click across clipboard outcomes.

GitOrigin-RevId: 24e6f9e267ef3ab249c5356db736e094127f68b8
2026-09-23 19:37:42 +00:00
Ian MacLeod 591ffb1aae Prefer Shift-arrow hints for queued messages and questions (#47618)
## 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
2026-09-23 18:39:19 +00:00
Eric Traut e0a64cf2bc Keep unfinished link destinations out of rich streaming previews (#47589)
## Why

An unfinished Markdown link can display its destination across multiple preview rows, then collapse when the closing parenthesis arrives.

## What changed

Keep the link label visible while withholding the opening parenthesis and destination until the link closes. Scan incoming text incrementally, accounting for nested parentheses, escapes, angle-bracket destinations, titles, and inline code. Apply this holdback only to rich prose previews; newline commitment and finalization still render the original source.

## Testing

Add regression tests for character-by-character input, long Unicode destinations, resizing, raw-mode switching, and flushing unfinished links on newline or completion, plus a snapshot of the label-only preview.

GitOrigin-RevId: 9cea680a93dfcd0aea21f0fc12006b27400d4dab
2026-09-23 16:39:22 +00:00
Eric Traut cb1eea3e98 Explain Mermaid rendering fallbacks in the TUI (#47572)
## Why

Mermaid diagrams that cannot be rendered currently fall back to source without
explaining why the preview is unavailable.

## What changed

Show a dimmed notice above the preserved source when a completed Mermaid block
uses unsupported syntax, exceeds renderer size limits, or does not fit the
terminal width. Wrap the notice to the available width and preserve indentation
inside lists and blockquotes. Leave unfinished fences and disabled Mermaid
rendering without notices.

## Testing

Add coverage for fallback reasons, dimmed styling, source preservation, nested
indentation, and suppression of notices for unfinished fences and disabled
rendering. Update the streaming resize snapshot to include the width notice.

GitOrigin-RevId: 6ac7914b398c855e7aed3775ee0de70fb4484b78
2026-09-23 15:15:58 +00:00
iceweasel-oai 6f6af0fce4 Record sandbox backends in command execution analytics (#47568)
## Why

Command execution analytics lack the observed sandbox backend. Older execution servers may omit this information, so an unknown backend must remain distinguishable from an explicitly unsandboxed process.

## What changed

- Carry optional `sandbox_type` metadata through command execution items and emit its metric tag as `sandbox_backend` in analytics.
- Propagate the observed backend through unified execution completion and failure events, including asynchronous exits.
- Preserve missing backend information as `None` and mark executed user shell commands as `Some(SandboxType::None)`.
- Exclude the metadata from serialized command items and generated schemas and TypeScript types.

## Testing

Extend tests for missing and explicit executor backends, backend propagation on failed execution, and analytics payloads, including platform-specific backend tags in app-server integration coverage.

GitOrigin-RevId: 178fe46824a6194910802ec02168ed40ee0b2019
2026-09-23 15:05:59 +00:00
Eric Traut 4981037e99 Use secondary text styling for the transcript footer shortcut hint (#47441)
Apply `secondary_text_style()` to the shortcut hint separator and label
so they use a readable foreground color instead of terminal-dependent dimming.

GitOrigin-RevId: 6cd9ced75deca9353c1224d3e5fefc6c4ad6ae8f
2026-09-23 03:57:18 +00:00
Ian MacLeod 408a77dc1a Clear pending async question notifications when turns end (#47424)
## Why

An async question notification can outlive its unanswered question and suppress the lower-priority turn completion notification.

## What changed

Clear pending `AsyncQuestion` notifications when collecting question drafts on completion, interruption, or failure, including the error-handling path. Completed turns can then queue their completion notification.

## Testing

Add regression coverage for all three turn outcomes and assertions for error handling and completion after dropped message deltas.

GitOrigin-RevId: 647b2b37acced431fc98fd4f5334c8973a0be241
2026-09-23 01:41:17 +00:00