Commit Graph
3049 Commits
Author SHA1 Message Date
Eric Traut d64360f628 Support Ctrl+Insert for copying TUI selections (#50215)
## Why

Windows Terminal forwards `Ctrl+Insert` when its Copy action has no native terminal selection. Recognize this shortcut so it can copy text selected within Codex.

## What changed

Add `Ctrl+Insert` to the shared copy-key detection used by transcript and composer selections. Use the same detection for transcript input ownership so the selection consumes the shortcut before other input handlers.

## Testing

Extend transcript tests to verify `Ctrl+Insert` input ownership and copying. Extend composer tests and snapshots to verify that failed or unconfirmed copies preserve the selection, while confirmed copies clear it without changing the draft or cursor.

GitOrigin-RevId: 5a33c72cff4c4395511779a7051fc92f8bd5e5d7
2026-10-02 07:21:07 +00:00
Eric Traut 4dd51f4a5f Make transcript mouse scroll speed configurable (#50209)
## What changed

Add `tui.mouse_scroll_speed` as a finite positive multiplier for transcript mouse wheel scrolling, including transcript overlays and session previews. Change the default from three rows to one row per wheel event; set the multiplier to `3.0` to retain the previous speed.

Fractional values accumulate movement across events and discard the remainder when direction reverses. For example, `0.5` scrolls one row every two events. Following the latest output pauses only when a whole row moves.

## Testing

Add tests for configuration validation, integer and fractional scroll speeds, direction changes, decimal accumulation, and following behavior. Extend local settings coverage to include a command-line override for the new setting.

GitOrigin-RevId: d355e246fd943415f0ce5a6affe849f77f3615e6
2026-10-02 06:50:10 +00:00
Eric Traut e3c2a83937 Release stable Markdown tables into scrollback during streaming (#50207)
## Why

Table holdback kept completed tables and subsequent content mutable until the response finished. Releasing completed tables earlier also requires a final scrollback reflow when late reference-link definitions change previously emitted content.

## What changed

- Release table holdback once the containing top-level Markdown block is stable, rescanning the remaining tail for later tables.
- Track completed-block boundaries across incremental and full renders.
- Request scrollback reflow at answer completion when reference-link definitions are present, including definitions pending without a trailing newline.

## Testing

Add regression assertions and snapshots for completed tables entering scrollback while later tables remain mutable, and for late reference-link definitions resolving correctly at completion. Cover reflow requests with and without a trailing newline and reference handling with inline visualizations enabled.

GitOrigin-RevId: a6b2aac74496281495b53840bbb1daf06bef60d2
2026-10-02 06:40:07 +00:00
Eric Traut 3f97f2b3bd Restore the account email in /status after account updates (#50199)
## Why

Account-update notifications include authentication mode and plan information but
omit the email, causing `/status` to lose the signed-in account's email after an
update.

## What changed

Fetch the ChatGPT account email asynchronously after account updates, with a
30-second timeout, without blocking terminal input. Apply the result only if its
request ID is still current, invalidating pending results on subsequent account
updates and disconnects.

## Testing

Extend the account-update test to verify that the email is restored and a stale
result is ignored. Update the status snapshot to include the account email and
plan alongside credits and limits.

GitOrigin-RevId: 202421f78f3d6a7b373194f9c65d1c22d70a04c1
2026-10-02 06:22:31 +00:00
Benjamin Carlsson e7ea5f4a86 Add managed worktree tools to the TUI (#50148)
## What changed

Expose `create_worktree`, `get_worktree_creation_status`, and `list_worktrees` through MCP when the worktrees feature is enabled for a trusted local project and attachment storage is available. Support both embedded and local daemon sessions.

Create worktrees asynchronously and attach them to the requesting task, with ownership and attachments retained across restarts. Default to the repository's remote default branch unless `ref` is supplied. Keep the task's working directory and execution environment unchanged, and leave uncommitted source changes in place.

Reject creation in ephemeral side conversations and explicitly untrusted source projects, reuse pending operations, and reject configured MCP servers that conflict with the TUI tools namespace.

## Testing

Add integration and model-request snapshot coverage for creation, polling, listing, attachment persistence across restart, task isolation, trust checks, namespace conflicts, and worker failure reporting.

GitOrigin-RevId: b6a57e92cf5f6fc51fd6d4028543d6fabaf5ac49
2026-10-02 02:27:25 +00:00
Eric Traut cb6da58876 Use the server permission catalog for TUI permission shortcuts (#50140)
## 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
2026-10-02 01:34:23 +00:00
Ian MacLeod a0a7a63002 Centralize TUI loading glyphs and frame scheduling (#50112)
## What changed

Move the voice connection spinner into shared helpers in `codex-rs/tui/src/motion.rs`, keeping its 100 ms animation cadence and static reduced-motion glyph. The helpers handle frame scheduling, and `loading_glyph_with_delay` supports hiding the animated spinner until a specified delay expires.

GitOrigin-RevId: c4ebe5e6a33239999aab2f4432c9145432c8f4fd
2026-10-01 22:17:51 +00:00
Ian MacLeod 6ece7bfc21 Keep fullscreen prompts bounded and scrollable (#50109)
## Why

Long drafts need to remain browsable while leaving room for the transcript. Remote image attachments also need to leave an editable prompt row visible.

## What changed

- Cap the fullscreen composer, including padding and hints, at two-thirds of the screen, with a minimum of eight rows when the screen allows.
- Support mouse-wheel browsing without moving the caret or changing transcript selection, search, or activity focus. Show arrows for hidden prompt rows and hide the cursor when the caret is offscreen.
- Resume caret following on editor input, paste, and external edits.
- Keep the selected remote image visible while reserving space for prompt text.

## Testing

Add regression tests and snapshots for fullscreen scrolling, caret restoration after navigation, paste and external edits, remote image navigation and deletion, resizing at scroll boundaries, and disconnected editing.

GitOrigin-RevId: 9a1e4ce14b3b3747e6d136207546327531339258
2026-10-01 22:00:12 +00:00
Ian MacLeod e58b493329 Consolidate chat composer footer logic in footer_state (#50105)
## What changed

Move footer property construction, mode resolution, hint overrides, quit shortcut hints, and custom footer height calculation from `chat_composer.rs` into `chat_composer/footer_state.rs`. Preserve existing behavior and expose the moved helpers to the parent module where needed.

GitOrigin-RevId: 4a23753ac1648352ab19d4bcc3da9f368c48f619
2026-10-01 21:49:01 +00:00
ke-oai e4e33a56b0 Enable dynamic tool inheritance for fresh V2 subagents (#50082)
## Why

Subagents spawned without forked history do not receive their parent's client-defined dynamic tools, preventing them from using those tools for delegated work.

## What changed

Add the disabled-by-default `multi_agent_v2_dynamic_tools` feature flag. When enabled, fresh V2 subagents inherit the parent's dynamic tool definitions and persist them in session metadata.

## Testing

Add coverage for V1 and V2 feature gating, tool persistence, and a fresh V2 subagent calling an inherited tool and receiving its result without inheriting parent history. Update TUI assertions and a snapshot to reflect blank-line separation and question text in recovered answers.

GitOrigin-RevId: a17a16bf5570f54ce922c1521cffb883022354f2
2026-10-01 19:45:28 +00:00
Tamir Duberstein b06b7d2f77 Upgrade Windows bindings to windows-sys 0.61.2 (#50058)
## What changed

- Centralize `windows-sys` at version `0.61.2` in the workspace and migrate dependent crates to it.
- Adapt Windows API calls to the updated handle, boolean, and type definitions. Replace custom handle owners with `OwnedHandle` and use `BorrowedHandle` where ownership stays with the caller.
- Add explicit wrappers for non-owning Windows handles passed between threads.

## Testing

Enable the MCP refresh cleanup test on Windows. Retain process handles to verify that a superseded MCP server stays alive during an in-flight call, exits after cancellation, and leaves the replacement running until shutdown.

GitOrigin-RevId: 86f53d9b300d13edff7154f4a7c32e34dacd2919
2026-10-01 18:05:05 +00:00
Ian MacLeod 57a38c1beb Preserve question context in recovered TUI answer drafts (#50052)
## Why

When a turn ends, unsent question answers are recovered into the main composer. Recovering only the answers loses which question each answer belongs to.

## What changed

Prepend each recovered answer with its question title as a Markdown blockquote. Separate questions, answers, and existing composer text with blank lines.

Sanitize question titles and limit them to 512 bytes at a UTF-8 character boundary, adding an ellipsis when truncated. Keep answer text untruncated.

## Testing

Add coverage for bounded titles, multibyte characters, control characters, and multiline question-and-answer submission. Update recovery assertions and snapshots for turn completion, failure, interruption, large pastes, and Vim undo.

GitOrigin-RevId: 141dacfb64bcad5fcabc5be217d2340ef7de1eb5
2026-10-01 17:52:19 +00:00
Felipe Coury 1cc9917508 Keep transcript Find expansion scoped to the current match (#50045)
## Why

Starting Find expanded the entire transcript into detailed mode. Searching hidden content should preserve the compact view and manually expanded activities.

## What changed

- Search full transcript content, including hidden live output, and temporarily expand only the current matching entry.
- Preserve manual disclosure state and retained text revisions while reading or selecting a match. Allow activity controls while reading results.
- Use `Enter` or `Ctrl+P` for older matches and `Ctrl+N` for newer matches, with matching footer hints.

## Testing

Add regression tests and snapshots for selective expansion, manual disclosures, hidden live matches, retained selections across updates and resizing, and Find in compact transcript overlays.

GitOrigin-RevId: 618ee47ba6c3f3a5138c9e3fe0961e7faa3383da
2026-10-01 17:27:03 +00:00
Felipe Coury a97fb78085 Keep transcript Find results readable after closing the query (#50039)
## Why

Closing Find previously restored the pre-search view, making it difficult to read a match and its surrounding transcript context.

## What changed

- Make `Esc` with a nonempty query close query editing while preserving the query, highlighted match, and expanded output. A second `Esc` returns to the latest output; `Ctrl+C` cancels Find and restores the pre-search presentation.
- Allow paging through surrounding context and loading older history without losing the query. Keep `Ctrl+N` and `Ctrl+P` available for match navigation, and reopen Find to edit the retained query.
- Show context above matches when space permits, preserve match layouts across resizing, and display navigation and history status while reading results.

## Testing

Add regression tests and snapshots for retained results, surrounding context, resizing, paging around live output, older-history loading, and footer status. Update interaction tests for the additional `Esc` transition.

GitOrigin-RevId: d822956d3c6ffab88fc1665ebdf0c86ccf110899
2026-10-01 17:22:19 +00:00
jif 595534314f Use descriptor-safe helpers for executable test fixtures (#50018)
## Why

Concurrent Linux test spawns can inherit writable descriptors for executable fixtures, preventing those fixtures from being executed even after the writing test closes its descriptor.

## What changed

Replace direct executable fixture writes and copies across the Rust tests with `codex_utils_cargo_bin::write_executable` and `copy_executable`. These existing helpers complete writes and copies in separate processes on Linux.

Remove the empty temporary inode before creating fake bubblewrap executables, and stage tampered bubblewrap bytes in a separate data file before copying them into the executable fixture. Add the required test dependencies.

GitOrigin-RevId: c875c83088731a4933ef1574e8d79d8cecc12f54
2026-10-01 15:57:03 +00:00
Eric Traut b527ce4734 Honor server model defaults when starting fresh TUI threads (#50013)
## Why

Fresh TUI threads should use the app server's model settings unless the launch explicitly overrides them. Sending resolved configuration values in `thread/start` turns defaults into explicit overrides.

## What changed

- Track explicit launch choices for `model`, `model_provider`, and `model_reasoning_effort`, and omit unselected settings from the initial `thread/start` request.
- Preserve accepted model migrations as explicit model and reasoning-effort choices.
- Keep explicit profile launches on the existing resolved-configuration path.

## Testing

Update startup request tests to cover omitted defaults, CLI model and provider overrides, repeated model overrides, reasoning-effort overrides, accepted migrations, and explicit profiles.

GitOrigin-RevId: 4e2661ba42322a80e2b769a55c62f61a576762b0
2026-10-01 15:47:07 +00:00
Eric Traut 444da310e1 Respect approval policies in temporary structured threads (#49912)
## Why

Forcing `approval_policy` to `never` on temporary structured threads can trigger configuration warnings when managed requirements allow only `on-request`. These hidden threads also need to reject unexpected interaction requests without prompting the user.

## What changed

Inherit the app server's approval policy when starting temporary structured threads. Reject their server requests before dynamic tool handling or interactive TUI routing.

## Testing

Extend regression tests to verify inherited `on-request` approval without approval-policy warnings, and error responses for recap-thread approval and user-input requests even when the thread is marked active and primary.

GitOrigin-RevId: 2d0a071d3687742c83ba933a7ef1357feea53403
2026-10-01 07:08:19 +00:00
Eric Traut d2b254fd17 Remove personality plumbing from the TUI (#49876)
## What changed

Remove personality from TUI turn commands and cached thread session state, and stop applying personality from thread settings notifications. Send no personality override in `turn/start` requests.

Forward `personality` through session configuration only when explicitly supplied as a CLI override, rather than deriving it from the effective local configuration.

## Testing

Extend configuration override coverage to verify that `personality = "none"` is forwarded only when supplied through CLI overrides.

GitOrigin-RevId: bd3c3bacc90e0561016c0cac557eb1b0e50d32c0
2026-10-01 05:25:31 +00:00
Eric Traut 7b88d09d61 Decouple TUI startup presentation from execution configuration (#49875)
## Why

Startup presentation needs client preferences before thread initialization establishes effective execution permissions. The startup header should not infer permission state from local configuration.

## What changed

- Load `LocalSettings` directly from bootstrap TOML, preserving preference defaults and overrides, accessibility settings, and audio settings that exclude project layers.
- Use those settings for first-frame presentation and pass `LocalSettings` plus the working directory to the startup draft instead of a full `Config`.
- Stop showing the YOLO indicator in the startup header while execution permissions are unknown.

## Testing

Update tests to compare bootstrap settings with resolved configuration, verify first-frame keybindings and paste preferences with an unresolved permission-profile parent, and snapshot the configured startup header. Adapt startup editor tests to the settings-based interface.

GitOrigin-RevId: f33cf8f42c53a9ddcbe0273491b5a849da9e6808
2026-10-01 05:18:04 +00:00
Eric Traut bdfbab9f4f Point usage and credit links to ChatGPT settings (#49874)
## What changed

Replace `https://chatgpt.com/codex/settings/usage` with
`https://chatgpt.com/settings/usage` in usage-limit errors, the `/status`
card, and backend banner actions. Credit purchase actions retain
`?credits_modal=true`.

## Testing

Update error-message assertions, banner action tests, status hyperlink
assertions, and TUI snapshots to expect the new URL.

GitOrigin-RevId: 1e1db971284a25a781120da30a6dea5ff9c3d957
2026-10-01 05:16:40 +00:00
Eric Traut 90d7f2715a Update elevated-launch warning snapshot to use ⌃o for copy (#49867)
GitOrigin-RevId: e9fd778114ba5ae958a1864f99621267e33ef6ba
2026-10-01 04:48:43 +00:00
Eric Traut 8ea2428c38 Add Daybreak state to the status line and terminal title (#49861)
## What changed

Add a selectable `daybreak` item to the status line and terminal title, including setup previews and terminal-title validation. Display `Daybreak on` when enabled for the thread and `Daybreak off` otherwise, including during side conversations.

## Testing

Add coverage for on/off rendering and side conversations, update setup preview snapshots, and verify that terminal-title diagnostics accept `daybreak`.

GitOrigin-RevId: b0b7a6f0ee0a107ba4ee2d56113a5b9b6ebd1d41
2026-10-01 04:25:23 +00:00
Eric Traut cd4a9cbd25 Honor Daybreak settings in TUI continuations and background tasks (#49859)
## Why

Cyber-policy refusal guidance did not distinguish whether Daybreak was on or off, and policy continuations and background task turns omitted `cyberAccessProgram`.

## What changed

- Show refusal guidance for the current Daybreak setting and offer eligible users an “Enable Daybreak” picker for their next request. Persist the selection without automatically retrying the refused request, and suppress the picker during history replay and when viewing parent-owned threads.
- Select and validate the cyber access program for policy continuations and background task turns using account eligibility, model support, and the thread's Daybreak setting.
- Resolve new background threads' Daybreak defaults from effective configuration unless launch flags or a selected profile explicitly override them. Use the target thread's saved setting for follow-up messages.

## Testing

Add unit, snapshot, and request-recording coverage for refusal guidance, picker behavior, continuation access programs, and background tasks retaining Daybreak after configuration changes.

GitOrigin-RevId: 94dee39c067e8eea5791cb31d5fe65fc600e5a18
2026-10-01 04:24:20 +00:00
Eric Traut e1522188e9 Add a persistent /daybreak toggle to the TUI (#49858)
## 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
2026-10-01 04:17:31 +00:00
Eric Traut f58ed54a9d Use the model catalog to select TUI cyber refusal guidance (#49857)
## 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
2026-10-01 04:17:07 +00:00
Eric Traut bc197b77bc Use embedded mode for elevated Windows TUI sessions (#49855)
## Why

The Windows shared daemon rejects elevated launches so shared clients cannot inherit administrator privileges. Local TUI sessions launched as administrator should still be able to start.

## What changed

Select embedded mode before daemon discovery or startup for elevated local Windows sessions. Show a startup warning explaining that the shared background server is disabled and that restarting Codex in a non-elevated terminal enables it. Record `elevated_windows` as the server selection reason.

## Testing

Add Windows integration coverage for elevated normal, `resume`, and `fork` launches without creating daemon directories, and verify that explicit daemon `start` and `restart` still reject elevation. Add a snapshot test for the startup warning in the warning center.

GitOrigin-RevId: 89594e86d6ee19b080dfb11553cee8676395f188
2026-10-01 04:15:13 +00:00
Benjamin Carlsson e53e932dc8 Allow microphone channel selection for voice conversations (#49836)
## Why

Mixing every input on a multichannel audio device can include playback channels in microphone capture. Selecting only microphone inputs keeps those playback channels out of the captured audio.

## What changed

- Add `audio.microphone_channel` with one-based channel numbers, accepting a single value or an array such as `[1, 2]`. Leaving it unset preserves mixing of all inputs.
- Add an input-channel picker for the selected microphone when it has at least three channels. Require a nonempty selection and save it locally for the next voice conversation.
- Average only the selected channels, deduplicate selections, and reject empty or unavailable selections without falling back to other inputs.
- Clear saved channel selections when saving an input device and report configuration overrides that prevent the reset from taking effect.

## Testing

Add regression coverage for excluding playback channels, sample conversion, subset mixing, invalid selections, configuration loading, local persistence and overrides, and picker selection and cancellation. Update UI snapshots and verify channel selections are passed to the voice helper.

GitOrigin-RevId: 99960dcfa7b10cf38270768a90bb84a4be95a406
2026-10-01 02:59:26 +00:00
Eric Traut 08e2b58b07 Clarify service tier default save errors in the TUI (#49835)
## Why

When saving the default service tier fails, users need the underlying configuration error and guidance on how to retry without interrupting their task.

## What changed

Format the error with `format_config_error` and explain that the task can continue. Tell users to resolve the error, then switch to a different tier and back to the desired tier to retry saving the default.

## Testing

Add a snapshot assertion for a rejected service tier save caused by malformed configuration, covering the detailed error and recovery guidance.

GitOrigin-RevId: d666f7915f185d219396d24034412b175c49173e
2026-10-01 02:59:05 +00:00
sayan-oai 799324821d Box the resume future in the agents overview permissions test (#49822)
GitOrigin-RevId: c56597b54aee83d07a05f94258b420e81a859229
2026-10-01 02:16:27 +00:00
Benjamin Carlsson 1182834d13 Remove browser-open success messages from the TUI (#49816)
Stop adding an informational message to chat history when `open_url_in_browser` succeeds. Continue displaying an error when opening the browser fails.

GitOrigin-RevId: 28d33917c1a2e354017470e785e44aa0032c3b46
2026-10-01 02:05:43 +00:00
Benjamin Carlsson cca440697f Flush expired paste bursts before handling Enter (#49810)
## Why

Without a UI flush tick, expired paste detection can cause Enter to be treated as part of a paste instead of submitting buffered input.

## What changed

Flush due characters and paste buffers before classifying Enter during submission, including in Vim insert mode. Preserve the buffered text when submission is blocked for a parent-owned thread.

## Testing

Add regression tests for held characters and buffered bursts with and without Vim mode and parent-owned threads, plus a snapshot test for Enter submitting expired input in Vim insert mode.

GitOrigin-RevId: 1d0d309b57e9d2151e0d9c1774a3401d05413d3c
2026-10-01 01:47:15 +00:00
Eric Traut 2fde968de8 Preserve local launch permissions across TUI sessions and reconnects (#49809)
## Why

Explicit launch permissions such as `--yolo` can be lost during reconnect recovery, causing subsequent input to use different approval and sandbox settings.

## What changed

Remember explicit local launch approval policies, approvals reviewers, and permission profiles at startup and when creating new sessions. Restore the approvals reviewer independently of profile overrides during reconnect recovery. Keep constrained profiles that cannot be expressed through legacy turn parameters under server control.

## Testing

Add regression coverage for `--yolo` across new sessions and reconnects, later permission-picker choices, reviewer-only overrides, and server-owned constrained profiles. Extend the reconnect integration test to submit the preserved draft and verify its approval and sandbox settings.

GitOrigin-RevId: 7a77dc41b2a357ab17fec9ba6cb2361f4a8f4aa5
2026-10-01 01:46:29 +00:00
andrewgu-oai 7d4c7a0767 Enable API-key model discovery by default (#49807)
## What changed

- Mark `api_key_model_discovery` as stable and enable it by default, while preserving explicit user opt-outs and provider catalog requirements.
- Fall back to bundled models when discovery is disabled at runtime, including when a remote catalog has already been loaded.

## Testing

Extend model-list coverage for default enablement, app overrides, and user configuration precedence. Add a regression assertion that runtime opt-outs hide loaded catalogs without additional fetches, and update daemon compatibility tests for the new default.

GitOrigin-RevId: feaf732757792cc58063f21a5327d0e633f079f4
2026-10-01 01:38:27 +00:00
Benjamin Carlsson d2f2c40095 Use platform-specific modifier labels in TUI shortcut hints (#49804)
## What changed

Render Control, Shift, and Alt as `⌃`, `⇧`, and `⌥` on macOS, and Control as `^` on Linux. Keep textual modifier labels on other platforms.

Route hard-coded shortcut hints through the shared key-label formatter so footers, overlays, pickers, and transcript notices use consistent notation.

## Testing

Update modifier-combination and chord label assertions, along with rendering snapshots and narrow-layout expectations for the shorter hints.

GitOrigin-RevId: 0d20fa218e4a11dfe7a81c8de64f8d25e093af03
2026-10-01 01:35:40 +00:00
Benjamin Carlsson ec0cfa5da8 Allow cleanup of replay-only side conversations with missing threads (#49800)
## Why

A saved side conversation transcript can outlive its ephemeral server thread. The resulting `turn/interrupt` error prevented side conversation cleanup and blocked archiving the parent thread.

## What changed

Treat the specific `thread not found` interrupt error as successful interruption for replay-only side conversations, allowing unsubscribe and local cleanup to finish. Continue sending interrupt requests because replay-only conversations may still be running after reconnect.

## Testing

Expand archive lifecycle coverage for local daemon and remote server connections to include live side conversations, replay-only conversations with existing threads, and replay-only conversations whose threads are gone. Assert that interruption, unsubscribe, archiving, and local cleanup occur.

GitOrigin-RevId: 0528c9f5b5278931fd3a7941073071117f2f3612
2026-10-01 01:23:15 +00:00
Eric Traut 606b139565 Preserve server web-search settings in the TUI (#49799)
## Why

The TUI unconditionally forwarded its resolved `web_search` mode, allowing implicit client settings to replace server defaults or saved thread settings.

## What changed

- Forward `web_search` on thread start, resume, and fork only when the winning choice comes from session flags or a selected profile.
- Translate legacy search feature flags into a canonical `web_search` override while preserving precedence, and remove those flags from forwarded feature overrides.
- Honor shared feature requirements for embedded sessions while letting remote servers enforce their own requirements on explicit search choices.

## Testing

Add coverage for configuration origins, canonical and legacy search precedence, and embedded versus remote feature requirements. Extend the Responses integration test to verify that a remote server's live search setting survives thread start and resume when the client's configuration disables search.

GitOrigin-RevId: c714f9cf0321aca9a5fa292a350720af5a2d02d4
2026-10-01 01:22:51 +00:00
Eric Traut 106772e3c6 Preserve background thread requests when forking in the TUI (#49783)
## Why

Switching to a fork can interrupt approval routing for source and child threads that remain on a local daemon or remote app server. Their pending requests and event listeners need to survive the switch.

## What changed

- Retain background request routing and event listeners for tracked threads when switching to a daemon-backed fork, preserving pending approvals without duplicating them.
- Register the source thread before the `fork_thread` tool creates a fork so its requests remain routable during the operation.
- Route requests for the currently viewed thread to the active UI, even when that thread is also tracked in the agents overview.

## Testing

Add regression coverage for local daemon and remote forks retaining source and child threads, replaying pending requests when returning to the source, and displaying active-thread file-change approvals. Verify that embedded forks still discard the source thread state and that `fork_thread` registers its source before issuing the fork request.

GitOrigin-RevId: 63139e2b9a6eff373ab05a31e0140a432ce47389
2026-10-01 00:48:32 +00:00
dennyku 60947e2341 Add account security setup reminders to the TUI (#49715)
## 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
2026-09-30 19:22:34 +00:00
Dmitriy Kovalenko 596ae94fb0 Classify SQLite corruption using typed error codes (#49710)
## What changed

Preserve the underlying error in `LocalStateDbStartupError` and use its error chain to decide whether CLI startup failures qualify for automatic database backup and recovery.

Replace corruption checks against error-message text with SQLite result-code classification, including SQLx extended result codes and directly wrapped `SqliteError` values.

## Testing

Update the embedded startup corruption test to verify that the startup error retains a detectable SQLite corruption cause and the failed database path.

GitOrigin-RevId: 6e8ecd0ee67f3c239183ddea3fc75c4e4cd5744a
2026-09-30 19:00:00 +00:00
Dmitriy Kovalenko 3620b2caf8 Detect SQLite corruption during startup and preserve recovery backups (#49701)
## Why

A database can open successfully while containing corruption that startup previously missed. Detecting it before runtime initialization completes allows recoverable databases to be rebuilt while preserving the damaged files.

## What changed

- Run `PRAGMA quick_check(1)` when opening writable databases, with a 100 ms scan budget. Share attempts across cloned `SqliteConfig` instances by file identity so repeated opens skip validation and replacement files are checked again.
- Back up and rebuild runtime databases that support recovery. Report corruption without rebuilding thread history or other databases without an automatic recovery policy. Treat interrupted or locked checks as incomplete rather than confirmed corruption.
- Collect startup backups across recovery retries and include their locations in the app server warning. Explain that saved conversations can restore the thread list and history, while some database-only metadata may be unavailable.
- Record confirmed corruption in `codex.sqlite.corruption.count`.

## Testing

Add tests for recovery policies, backup preservation, validation caching and concurrency, cancelled and interrupted checks, and locked databases. Add app server coverage for recovery warnings and saved conversation restoration, a TUI warning snapshot, and message board post preservation.

GitOrigin-RevId: 43e26328888e0301def642d69bd324acee867566
2026-09-30 18:29:46 +00:00
Ian MacLeod fcbed044c8 Escape command drafts when recovering question answers (#49678)
## Why

When a turn ends, recovered question answers are appended to the composer draft. If that draft starts with a shell or slash command, submitting the combined text can interpret it as a command instead of a prompt.

## What changed

Escape command prefixes before appending recovered answers so the combined draft stays editable and submits as literal prompt text. Convert shell mode's separate `!` prefix into escaped composer text, and leave slash-prefixed paths such as `/tmp/file` unchanged.

Keep prefix escaping and answer recovery in the same Vim undo edit.

## Testing

Add regression coverage for immediate and queued submission, whitespace around command prefixes, slash-prefixed paths, and already escaped commands. Extend Vim undo coverage to shell and slash command drafts, including shell mode, and add a snapshot of the recovered shell draft.

GitOrigin-RevId: 03c40f72a834a65bf367103cb9170a86dc35ad98
2026-09-30 17:06:14 +00:00
iceweasel-oai 67727e7cf1 Allow managed requirements to disable the Windows MXC sandbox (#49642)
## Why

`windows.allowed_sandbox_implementations` permits MXC regardless of the listed implementations. Managed requirements need a separate way to block both explicit MXC configuration and automatic selection through `prefer_mxc`.

## What changed

Add the optional managed requirement `windows.allow_mxc`. Setting it to `false` disables automatic MXC selection and rejects explicit `windows.sandbox = "mxc"` configuration with an error identifying the requirement. Leaving it unset or setting it to `true` preserves existing behavior.

## Testing

Add coverage for the requirement alongside allowed sandbox implementations, preference resolution, and cloud-managed opt-out behavior for implicit, elevated, and explicit MXC configurations.

GitOrigin-RevId: a458a7b4c92cf17e687dbbad8208884d1c097da5
2026-09-30 14:37:56 +00:00
cooper-oai 7219fd735b Use server authentication for explicit remote session commands (#49624)
## Why

Session commands with `--remote` should use the selected server's authentication and execution environment, even when the caller has workload identity configured and cannot read its identity token.

## What changed

Connect `queue`, `archive`, `unarchive`, and `delete` directly to the explicit remote app server after validating configuration. Skip caller credential and runtime initialization, use remote thread parameters, and preserve the caller's working-directory override.

## Testing

Add end-to-end coverage with an unreadable caller identity token to verify queued turns use the server's API key and remote archive, unarchive, and deletion operate on the selected server. Add configuration-validation coverage for all four commands and `--no-daemon` rejection coverage for remote unarchive and delete.

GitOrigin-RevId: 5da7abbb40506cd754a8863e1a9d8fad9b1f09a9
2026-09-30 13:16:08 +00:00
felixxia-oai de02016798 Persist explicit user goal edits in model history (#49598)
## Why

User goal edits and clears need to reach the model as user instructions, including when a thread is unloaded or history is being compacted. Automatic goal lifecycle updates must not supply user authorization.

## What changed

- Add optional `origin` values of `user` and `automatic` to `thread/goal/set` and `thread/goal/clear`, and mark TUI goal requests as user actions. Omitted origins do not supply user authorization.
- Persist explicit user objective, status, and clear instructions before changing goal state. Recording failures leave goal state unchanged.
- Coordinate goal edits with thread resume, reload stored history under writer ownership, and preserve edits accepted after the compaction input snapshot.
- Update generated protocol schemas and TypeScript and Python bindings.

## Testing

Add coverage for user edits and clears on loaded and unloaded threads, concurrent path-based resume, exclusion of automatic goals from user instructions, preservation of edits during compaction, and recording failures that leave goal state unchanged.

GitOrigin-RevId: d779d7c678a0c32a6ef76975dbe5b1400d1df245
2026-09-30 11:58:03 +00:00
Felipe Coury 0b43721d8d Copy selected file paths as plain text in the TUI (#49564)
## Why

Copying a rendered local file target such as `repo/foo_bar!` should preserve the selected path without adding Markdown escapes.

## What changed

Treat selections contained within rendered file targets as plain text, including partial selections and targets in tables. Coalesce adjacent file targets and inline code into literal ranges while preserving Markdown escaping when the selection includes surrounding content.

## Testing

Add regression coverage for partial paths, adjacent literal spans, styled links, table cells, special characters, and mixed selections at narrow and wide rendering widths.

GitOrigin-RevId: 94bcdacf14b013f9198cb84adfdb237eb644dd48
2026-09-30 10:21:00 +00:00
Eric Traut d42056091a Add a fork shortcut to the TUI command center (#49517)
## What changed

- Fork the selected conversation and open the new session with `f`, configurable through `agents.fork` in the TUI keymap.
- Move the default search shortcuts to `F3` and `/`, preserving unshadowed defaults when custom bindings conflict.
- Keep queued input on the source conversation while attaching and forking, and require closing an open side conversation before forking another task.
- Expose the fork action in command-center help and the keymap picker.

## Testing

Add regression coverage for queued-input preservation, side-conversation protection, configurable fork shortcuts, metadata editing, disconnected actions, and search fallback bindings. Update help and keymap snapshots.

GitOrigin-RevId: b11ae21ef6a2053609b31ce97c646104f18806a3
2026-09-30 07:15:14 +00:00
Keyan Zhang 90abcfac02 Add experimental thread prediction protocol types (#49480)
## What changed

Define `thread/prediction/request` with `threadId` and `sourceTurnId`, and `thread/prediction/updated` with a `completed` result containing optional text or a `failed` result.

Update generated JSON schemas, TypeScript types, and Python notification models. Route prediction notifications to their thread in the TUI and ignore them in the chat widget.

The request remains unimplemented and returns a method-not-found error.

GitOrigin-RevId: 09922f583d5c56f808d018121c651dcd92734515
2026-09-30 04:48:50 +00:00
Eric Traut b588812e8c Use server-authoritative permissions in the TUI (#49472)
## Why

Client permission definitions and constraints can differ from those on the connected app server. Accepted permission changes also need to survive task transitions before their settings notifications arrive.

## What changed

- Discover permission profiles and availability from the connected server and apply selections through `thread/settings/update`, including custom profiles.
- Adopt the server's effective permission settings instead of reapplying local definitions or constraints.
- Retain accepted selections and effective approval settings across new tasks, forks, side conversations, directory changes, reconnects, and safety retries without blocking navigation on a settings notification.
- Recognize the current built-in permission preset when the server supplies an unnamed profile.

## Testing

Add regression coverage for conflicting client/server profile definitions, rejected and unchanged selections, consecutive requests with omitted approval settings, and permission carryover before confirmation. Extend discovery and menu tests to verify server-provided availability and unnamed-profile highlighting.

GitOrigin-RevId: bcd767b58dc92dc4f945189078e51e6e5fce6d24
2026-09-30 03:33:19 +00:00
Benjamin Carlsson fc81a7154b Add local audio device selection to TUI voice settings (#49437)
## Why

Voice conversations previously opened the system-default microphone and speaker. Users need to choose which local devices to use, including when connected to a remote app server.

## What changed

- Add input and output device pickers alongside voice selection, with back navigation and a System default option.
- Persist selections as `audio.microphone` and `audio.speaker` on the TUI's machine, excluding project configuration layers. Apply them to the next voice conversation.
- Enumerate devices without opening audio streams and pass the selected names to the voice helper at startup.
- Disable ambiguous device names in the picker and use the same eligibility filtering for discovery and named-device startup.

## Testing

Add tests for device preference persistence across project and remote transitions, picker navigation and duplicate names, discovery without capture, and forwarding selected devices to the helper.

GitOrigin-RevId: d48fb3a09fa9b982a408f5a7c96bdd81776af21d
2026-09-30 01:58:03 +00:00
Adam Perry @ OpenAI 17a9df60e4 Add an experimental flag for bundled tools in login shells (#49403)
## What changed

Register `login_shell_package_path` as a disabled-by-default experimental feature and add it to the configuration schema. Expose it in `/experimental` as “Bundled tools in login shells,” with a description explaining its intended use when login shell startup resets `PATH`.

## Testing

Extend the experimental feature metadata snapshot test to cover the new feature's label, description, and unchecked default state.

GitOrigin-RevId: dc110486ccd8d2d76ac788ba5a413a1374699ff8
2026-09-29 23:33:58 +00:00