100 Commits
Author SHA1 Message Date
Benjamin Carlsson e4568a3538 Reject TUI events from a different backend (#55304)
## Why

Events from another backend must not mutate the current backend's thread or connection state, even when native thread IDs collide.

## What changed

Attach the session's `BackendId` to incoming app-server events and check it before dispatching to thread caches or UI handlers. Apply the same check when waiting for a thread revert notification.

## Testing

Add regression tests covering ignored foreign notifications, approval requests, lag and disconnect events, accepted events from the current backend, and preservation of backend identity on transport events.

GitOrigin-RevId: 2577ab78e0592726f5f05e3426772899e6cb7c7e
2026-10-19 15:20:42 +00:00
Benjamin Carlsson d13db678cb Stop applying macOS background priority to managed daemons (#54763)
## What changed

Launch managed app-server and updater processes directly through the shared background command helper, removing the macOS `taskpolicy -b` wrapper and its availability probe. Remove the associated launch-policy tests and macOS daemon-startup test serialization.

Retain the 30-second macOS readiness timeout because older updaters can pass background policy to replacement daemons during upgrades.

GitOrigin-RevId: d8620a49139bd2a5c226c624cf7908e06ba7ba38
2026-10-17 02:19:20 +00:00
Benjamin Carlsson 5009a99dfc Render slash command prefixes as composer prompt markers (#54742)
## What changed

- Display the leading `/` in the prompt marker instead of the editable text, sharing prefix state with shell mode's `!`.
- Preserve command prefixes and text element offsets across submission, queuing, history, and external editing. Keep prefixes literal in plain-text composers.
- Track composer-owned slash command elements separately, omit them from exported draft elements, and refresh them when command availability changes.
- Let backward deletion at the start of the text remove the prompt prefix while preserving selected-text deletion and Vim Replace recovery.

## Testing

Add regression coverage for slash prompt cursor placement, prefix deletion, history search highlighting, dynamic command availability, and Vim Replace restoration, including Unicode text. Update rendering snapshots for the slash prompt marker.

GitOrigin-RevId: 0da42da8e98bf7885f9b0ba2c8d5ad4f44d6847e
2026-10-17 00:03:04 +00:00
Benjamin Carlsson 440312f113 Keep TUI session selections bound to their backend (#54681)
## Why

A thread ID alone does not identify the backend that owns a session. Resume and fork selections must retain that ownership across connection replacement so they cannot operate on another backend, even when thread IDs match.

## What changed

- Add a process-local `BackendId` to app-server sessions and session targets, preserving it across reconnects and auxiliary picker connections.
- Reject selections from a different backend before changing session state or sending resume, fork, or unarchive requests.
- Disable local-daemon fallback to an embedded server for auxiliary pickers and after selecting a session, while retaining fallback for fresh startup.

## Testing

Add regression coverage for foreign selections with matching thread IDs, startup resume and fork rejection before requests, shared ownership across picker connections, and fallback eligibility.

GitOrigin-RevId: 05a3ca0a901a8dc24337d130548aa2c048b4d586
2026-10-16 19:13:40 +00:00
Benjamin Carlsson 98fd26206d Use neutral labels for nonzero exits in compact TUI output (#54433)
## What changed

- Show `Exited (status N)` instead of `Failed (exit N)` for compact command output, and remove the red bullet styling.
- Label compact exploration counts as `nonzero exit` or `nonzero exits` instead of `failed`, and remove the red styling from the count.

## Testing

Update snapshots for compact command output and exploration summaries to reflect the new labels and styling.

GitOrigin-RevId: 043593720cc3837ca530d1c008565695abcd5af1
2026-10-15 22:31:50 +00:00
Benjamin Carlsson 97ebf2d94d Run managed daemon processes at background priority on macOS (#54401)
## What changed

- Launch managed processes through `taskpolicy -b` on macOS when a five-second probe succeeds, preserving the managed process PID. Fall back to direct launch if the probe fails or times out.
- Increase the macOS startup timeout from 10 to 30 seconds to accommodate background CPU and I/O scheduling, and serialize daemon startup test fixtures on macOS.
- Use the shared background command helper and retain `CREATE_NO_WINDOW` alongside Windows detachment flags.

## Testing

Add macOS tests for PID preservation, background priority when available, and direct-launch fallback after a probe timeout.

GitOrigin-RevId: ab3328e2e8f62218ac9602e4172563c00056875b
2026-10-15 20:00:15 +00:00
Benjamin Carlsson bb64b894fd Retire worktree and voice feature flags (#54175)
## What changed

- Remove feature-flag checks from managed worktree creation and repository-aware session discovery, while retaining local workspace and trust checks.
- Make TUI voice availability follow platform support instead of `features.realtime_conversation`.
- Ignore `features.worktrees` and `features.realtime_conversation` configuration overrides, warn when managed requirements reference them, and hide both flags from `/experimental`, including catalogs from older servers.

## Testing

Add coverage for ignored configuration overrides and managed requirements, and update session filtering, worktree grouping, and experimental feature discovery tests for the retired flags.

GitOrigin-RevId: 1d64e890e6e2f8a78926a9ea163126c0890b068e
2026-10-15 03:48:33 +00:00
Benjamin Carlsson ac9db7d8b5 Generate keymap descriptors and binding accessors from one catalog (#54151)
## Why

The `/keymap` action catalog and root-config binding lookup duplicated the same action inventory, requiring both to be maintained together.

## What changed

Use `define_keymap_actions!` to generate `KEYMAP_ACTIONS` and `binding_slot` from a single declaration grouped by context. Preserve the existing action order, descriptions, feature gates, and binding mappings.

GitOrigin-RevId: 182e937d9642a8b5a4aa787691da793712f29010
2026-10-15 01:37:36 +00:00
Benjamin Carlsson 01ff831ce9 Centralize vertical navigation in TUI list views (#54081)
## What changed

Add `ListKeymap::vertical_action_for` and `ScrollState::apply_vertical_action` to share key resolution, selection movement, and visibility handling across the experimental features, hooks, memories, skills, and multi-select views. Preserve navigation priority, search input handling, and item reordering precedence.

## Testing

Update scroll-state tests to exercise the shared action handler and picker tests to navigate through key events. Cover overlapping page-down and move-left bindings when item reordering is disabled.

GitOrigin-RevId: 29927b0a4de0fbeb4c0dd19c418b8f60fffb8a7d
2026-10-14 20:05:29 +00:00
Benjamin Carlsson 57b5e89be8 Extract TUI user-turn submission into a dedicated module (#54080)
## What changed

Move `AppCommand::UserTurn` handling from `thread_routing.rs` into
`user_turn_submission.rs`. Keep turn creation, permission resolution, and
active-turn steering behavior together, preserving retry and queueing behavior.

GitOrigin-RevId: b4f798cf20a4609d959f4d9b19447ba3c4baba0a
2026-10-14 20:01:55 +00:00
Benjamin Carlsson 7eed30ad1b Preserve running turn recovery across thread settings updates (#53879)
## Why

Standalone thread settings updates cleared the running turn's continuation lineage, preventing recovery after a daemon restart.

## What changed

Preserve continuation lineage while a task is registered. Continue invalidating pending continuations for idle, reserved, and finishing turns, and record started-turn lineage atomically with task registration.

## Testing

Extend settings invalidation coverage to idle, reserved, and finishing turns. Exercise an in-flight reasoning effort update before compaction, then verify cold resume preserves the turn's frozen settings and allows continuation. Wait for thread idle before testing idle continuation.

GitOrigin-RevId: d7c316af6a4c871790bb57f0af9892bb30871ac8
2026-10-14 06:03:02 +00:00
Benjamin Carlsson 72ad8747e9 Render Markdown web links as labels in Rex (#53725)
## What changed

Select label-only web link rendering when `TERM_PROGRAM` is `rex`, matched case-insensitively. Preserve the existing visible-destination fallback for multiplexers and `dumb`, `screen`, or `tmux` terminal modes.

## Testing

Add a regression test verifying that Rex renders `[label](https://example.com)` with the label-only policy.

GitOrigin-RevId: 615ca6186d84fc17cef9286e75848877b542b6ab
2026-10-13 17:30:45 +00:00
Benjamin Carlsson f82e365922 Deduplicate TUI modifier handling and terminal color caching (#53556)
## What changed

- Reuse `custom_terminal::ModifierDiff` when writing history spans.
- Share the terminal default-color probe and cache implementation between Unix and Windows.

Both changes remove duplicate implementations while preserving existing behavior.

GitOrigin-RevId: 35f8d77ade972b791c6beac0678d2fe2be3aa763
2026-10-13 04:42:04 +00:00
Benjamin Carlsson 6f47fcb0be Route TUI request replies to their originating connection and thread (#53436)
## Why

Pending requests can outlive a session switch, and different threads or connections can reuse request IDs. Replies and resolution notifications must stay associated with the request that prompted them.

## What changed

- Retain the original app-server reply handle for pending and buffered requests, including requests replayed after thread attachment or session reset.
- Scope user input, MCP elicitation, and user verification bookkeeping by thread, and send user input answers to the requesting thread.
- Keep background resolution notifications from dismissing foreground prompts.
- Consume failed replies to closed connections and clear pending replay state without falling through to another request route.

## Testing

Add WebSocket regression tests for direct and buffered approvals with colliding request IDs and replies to closed connections. Extend coverage for foreground prompt preservation and thread-scoped user verification cancellation.

GitOrigin-RevId: 541acb9910e92f6f2e83c27d2a2384185d4f8fec
2026-10-12 17:39:17 +00:00
Benjamin Carlsson 72f999edc7 Simplify the custom terminal drawing API (#53156)
## What changed

Remove `Terminal::autoresize` and the fallible `try_draw` helpers. Render directly in `draw_with_size`, retaining automatic size updates and the existing buffer flush and cursor handling.

Update the cursor-ordering test to use `draw`, preserving its assertion that the cursor moves before it is shown.

GitOrigin-RevId: 5889e9603d772945660e7ae35690d2b7326b10ae
2026-10-11 16:03:20 +00:00
Benjamin Carlsson 8c0f701167 Add connection-bound reply handles for app-server requests (#53049)
## Why

Server request IDs can be reused across connections. Retained replies need to target the connection that emitted the request, even if the UI selection later changes.

## What changed

- Expose `AppServerReplyHandle` through `AppServerRequestHandle::server_request_reply_handle`, capturing the originating client and request ID for explicit `resolve` or `reject` calls.
- Share single-use completion state across clones so only the first reply is submitted. Dropping a handle sends nothing; stale connections return I/O errors without retrying or switching connections.
- Route existing client reply methods through request handles and use the new API in the managed worktree model test.

## Testing

Add in-process and WebSocket tests for replies on separate connections with identical request IDs, rejection routing, duplicate completion, and stale handles after worker shutdown. Also check that debug output redacts handle details.

GitOrigin-RevId: 940d0951ab67529b05919ca8ec7adb5813834b8c
2026-10-11 06:08:41 +00:00
Benjamin Carlsson 322bbf4d84 Classify voice session failures and record terminal outcomes (#52756)
## 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
2026-10-10 02:54:59 +00:00
Benjamin Carlsson 2351d9e1b6 Avoid an extra blank quote line when pasting text with a trailing newline (#52418)
## Why

Pasting text ending in a newline into a composer line beginning with `> ` adds an unnecessary empty quoted line before the next Markdown block.

## What changed

Remove one trailing newline from nonempty blockquote paste content before adding quote prefixes. Preserve interior blank lines and the two unquoted newlines that move the cursor to the next block.

## Testing

Add a trailing-newline regression case, update the CRLF/CR expectations, and exercise trailing-newline input in the existing rendering snapshot test.

GitOrigin-RevId: 2367efa8253dd0512de8ba6333b39eba6381fba8
2026-10-09 05:12:54 +00:00
Benjamin Carlsson 22ebb0fb17 Clamp wrapped source ranges before remapping terminal hyperlinks (#52330)
## Why

Wrapping can retain a cursor sentinel one byte past the end of the input. Using that range to slice source text during hyperlink remapping can panic.

## What changed

Clamp wrapped range boundaries to the input length before calculating hyperlink columns and recording logical source ranges, keeping both aligned with the visible text.

## Testing

Add a regression test that extends a wrapped range past the input boundary and verifies that the line, hyperlinks, and logical source are preserved.

GitOrigin-RevId: c83c817df8d3ea790f7d126768092ae317ff9217
2026-10-09 00:04:15 +00:00
Benjamin Carlsson b8dceb0d4f Open slash commands from empty drafts in Vim Normal mode (#50788)
## Why

Pressing `/` in Vim Normal mode starts a composer search, even when the draft is empty. Allow this key to open slash commands directly on an empty draft.

## What changed

When slash commands are enabled, a standalone `/` on an empty draft switches to Insert mode, inserts `/`, and opens command completion. Preserve Vim search behavior for nonempty drafts, `?`, and pending operators.

## Testing

Add a snapshot test for the Insert mode transition and command picker. Exercise Vim slash-command entry in the transcript overlay test across terminal sizes, and extend command sparkle coverage to Vim mode.

GitOrigin-RevId: 806c2f6b841190ccdc1a258f88dfa590773ba33a
2026-10-04 04:33:42 +00:00
Benjamin Carlsson acf9818fae Remember Command Center grouping across launches (#50786)
## Why

Command Center previously reset to project grouping on startup, losing the user's selected grouping.

## What changed

Save grouping changes to `tui.agents_overview_grouping` in the client’s user configuration and restore the saved choice at startup. Support `project`, `status`, and `model`, with `project` as the default. Report save failures in Command Center while keeping the selected grouping active.

## Testing

Add tests for cycling through and persisting all grouping modes, preserving unrelated settings in a custom configuration file, displaying save errors, and restoring saved grouping during startup.

GitOrigin-RevId: fd56dfecb4b79cfa8439f54420ce58cc0ed66ec7
2026-10-04 04:25:31 +00:00
Benjamin Carlsson dde5f8c5ae Allow /archive while a turn is running (#50764)
## Why

`/archive` was disabled during a running turn, preventing users from archiving the current session until the turn ended.

## What changed

Enable `/archive` during a running turn and warn in the confirmation dialog that archiving will stop the current turn. Cancelling the dialog leaves the turn running.

## Testing

Extend confirmation tests to cover both idle and running sessions, add a snapshot of the running-turn warning, and verify that cancellation leaves the task running without emitting archive events or operations.

GitOrigin-RevId: c7c530aa671b5f04e5dc2a637e3d27a81d98d8bf
2026-10-04 02:32:39 +00:00
Benjamin Carlsson cd7d9e128c Show unavailable slash commands when searched in side conversations (#50756)
## Why

Side conversations hide unavailable slash commands, leaving users without an explanation when searching for a known command.

## What changed

- Show matching unavailable commands as disabled rows with the reason `not available in a side conversation`. For example, `/arch` now shows a disabled `/archive` entry. Keep these commands hidden from the unfiltered `/` menu.
- Rank available matches first and skip disabled rows during keyboard selection and completion.
- Prevent `Tab` from queuing input when only disabled matches are visible, and insert `/` normally when no selectable command is present.

## Testing

Add a rendering snapshot and regression tests for unavailable command discovery, navigation, available command completion and queuing, blocked queuing of unavailable matches, and slash insertion.

GitOrigin-RevId: 7160b308ca57a24a5dcb6e2686b5248a8eb4b6a7
2026-10-04 01:36:25 +00:00
Benjamin Carlsson 447eac3b81 Decode Windows Terminal's mapped Shift+Enter sequence (#50720)
## Why

Windows Terminal's `sendInput` mapping delivers `ESC[13;2u` as individual console key events. Decode it as `Shift+Enter` so the mapping inserts a newline in the composer.

## What changed

- Wrap the Windows event stream with a decoder for the complete Escape-prefixed sequence, including interleaved key releases.
- Use a fixed 50 ms deadline for partial sequences and replay incomplete or mismatched input unchanged. Preserve literal text, paste events, and native key events.
- Update the `crossterm` revision and dependency lockfiles.

## Testing

Add tests for repeated and fragmented mappings, deadline handling, unchanged input, error and end-of-stream replay, and composer newline rendering with a snapshot.

GitOrigin-RevId: 95ab39960510d71322824c63817710633a2fda23
2026-10-03 21:20:56 +00:00
Benjamin Carlsson 3a69ec3ef8 Preserve local Markdown link labels in the TUI (#50695)
## Why

Path-like link labels were collapsed into their destinations, discarding the author's label text and formatting.

## What changed

Preserve nonblank local link labels alongside the formatted destination as `label (target)`, including in tables. Empty or whitespace-only labels show only the destination. Keep destination formatting and fall back to the original destination when a local file URL cannot be parsed.

Render file citations without a label so they continue to display only the formatted destination.

## Testing

Update rendering and transcript-copy tests and snapshots to cover preserved path labels, styled labels, empty labels, malformed file URLs, tables, and Markdown escaping.

GitOrigin-RevId: 2810b70f1ecdc59d7f90fa1b254b1e9069c8fc29
2026-10-03 18:44:14 +00:00
Benjamin Carlsson 47379efd52 Keep Command Center selection adjacent after task removal (#50505)
## Why

Archiving or deleting the selected task could make Command Center selection jump to the current task instead of a neighboring task in the displayed list.

## What changed

Choose the next surviving task in displayed order before removing tasks, falling back to the previous task when needed. Apply this selection behavior to archive, delete, and hide actions, respecting filtering and grouping.

Preserve the pending selection across view rebuilds, batched removals, and duplicate server notifications. Allow selection to fall back when a rename target disappears while retaining the existing notice about its unsubmitted title.

## Testing

Add regression tests and snapshots for archive/delete selection across project, status, and model grouping, with and without filtering. Cover removal of the attached task, external removal notifications, removal of a pending successor, repeated repaints, and an empty task list. Update the disappeared-rename-target snapshot to verify that the remaining selection is preserved.

GitOrigin-RevId: ca93d664fadbc602993fbdae316c7a375b449345
2026-10-03 03:06:40 +00:00
Benjamin Carlsson d42aecc56b Center TUI confirmations over their retained backdrop (#50504)
## 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
2026-10-03 03:00:46 +00:00
Benjamin Carlsson 09bced5ad9 Populate thread previews from delegated task inputs (#50462)
## Why

Delegated turns can begin without a user message, leaving threads without a task preview. Populate the preview from delegated input so these threads are discoverable before a user follow-up.

## What changed

- Extract previews from completed `create_thread` and `send_message_to_thread` outputs in the `codex_app` and `codex_tui` namespaces.
- Unwrap recognized `<codex_delegation>` inputs and decode their escaped task text for display, preserving model content. Keep plain or unrecognized wrappers as text and ignore blank inputs.
- Fill missing previews in state metadata extraction and live thread metadata updates without replacing existing previews or setting the title or `first_user_message`.

## Testing

Add tests for delegation decoding and tool filtering, preview-only metadata updates, preservation of later user-message metadata, and database listing before a user follow-up in both legacy and paginated history modes.

GitOrigin-RevId: f7b3c60ef75e08c76b4084d043e3967bf2bade22
2026-10-02 23:34:11 +00:00
Benjamin Carlsson c536ffcb18 Add keyboard copy selection to the owned transcript (#50434)
## What changed

- Make `/copy` select the latest completed response directly in the owned transcript. Navigate user messages, code blocks, and blockquotes with arrow keys or `j`/`k`, use `g`/`G` to jump to the ends, and press Enter to copy or Escape to close.
- Highlight selected blocks and keep surrounding context visible during navigation and resizing. Preserve source payloads for code and quotes, including rendered Mermaid diagrams and fenced Markdown tables.
- Pause queued submissions until copy mode closes, and report clipboard results in the transcript footer.

## Testing

Add tests for copy routing, keyboard navigation, highlighting and resize behavior, source whitespace and line endings, clipboard completion, and queued-input resumption.

GitOrigin-RevId: bd4f58ec17568f95d0e91014e5ddba33ca8bd57c
2026-10-02 21:42:23 +00:00
Benjamin Carlsson b6903c0669 Preserve terminal hyperlinks in agents overview previews (#50431)
## What changed

Keep Markdown link destinations attached to prompt and last-message previews in the agents overview details pane as text wraps and is clipped. Render visible links as terminal hyperlinks, while keeping truncation ellipses unlinked.

## Testing

Add a regression test and snapshot covering links that span multiple rows, prompt links, and clipped previews with unlinked ellipses.

GitOrigin-RevId: d121e062b197790ce45a70d6d64aadcb181e4dde
2026-10-02 21:28:40 +00:00
Benjamin Carlsson dff5270b29 Clarify Git worktree choices for new and forked conversations (#50416)
## What changed

Label the `/new` and `/fork` picker options “Use current Git worktree” and “Create new Git worktree”. Explain that creating a worktree makes a separate checkout of the repository in another directory.

## Testing

Update picker assertions and snapshots for both commands to cover the revised labels and description.

GitOrigin-RevId: b7fb1aac3107e39c324707f9ae69c210a97346d7
2026-10-02 20:04:57 +00:00
Benjamin Carlsson d61c7a824f Honor pager bindings for transcript page keys (#50396)
## Why

Transcript scrolling hardcoded `PageUp` and `PageDown` to full-page movement, ignoring customized pager bindings.

## What changed

Resolve unmodified `PageUp` and `PageDown` through the pager's scroll bindings so they can scroll by a full page, half a page, or one row, or remain unbound. Preserve the one-row overlap for full-page scrolling and leave pager typing shortcuts unhandled by the transcript.

## Testing

Add a regression test and snapshot covering default, half-page, single-row, and unbound configurations. Verify that `PageDown` reverses `PageUp` scrolling and that `j` and `Ctrl+u` remain unhandled.

GitOrigin-RevId: 945e99d7370f84f326ab71037be2924dddada32c
2026-10-02 18:29:19 +00:00
Benjamin Carlsson 37f53199a6 Use the shared text editor for command-center task renaming (#50216)
## 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
2026-10-02 07:22:28 +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
Benjamin Carlsson b707714ae4 Add a native gRPC client for cloud thread resume and attach (#50113)
## What changed

Add `codex-cloud-client`, a reusable Rust client for `ThreadService.Resume` and live `ThreadService.Attach` over HTTP/2. Callers supply the native gRPC origin, bearer token, account ID, and `HttpClientFactory`.

- Reuse shared proxy, custom CA, and network policy handling for HTTPS. Reject redirects and allow plaintext HTTP only on direct loopback with unrestricted, unmanaged policy.
- Preserve notification and server-request protobuf payloads as opaque bytes and expose native gRPC status details while redacting credentials, payloads, and error details from diagnostics.
- Bound resume and attach setup to 150 seconds without retrying requests or imposing an idle deadline on live streams. Attach ends on its first error and provides no history or automatic reconnect.
- Select Rustls in `HttpClientBuilder::http2_prior_knowledge()` so HTTPS advertises `h2` through ALPN.

Include a standalone attach example and documentation of admission semantics and stream behavior.

## Testing

Add HTTP/2 fixture tests for protobuf framing, authentication metadata, status trailers, event preservation, malformed responses, stream cancellation, redirect rejection, and diagnostic redaction. Add checks for unsafe origins, network policy restrictions, and TLS `h2` advertisement.

GitOrigin-RevId: 55db70438bb5e59272c6995c67a46ced5fa28ff4
2026-10-01 22:32:29 +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
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
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
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
Benjamin Carlsson 2cc65cdd4c Enable analytics by default for daemon-launched app servers (#49426)
## Why

Daemon-launched app servers should use the same analytics default as first-party clients while honoring explicit user opt-outs.

## What changed

Pass `--analytics-default-enabled` when the PID backend launches an app server, with or without remote control. Users can still disable analytics with `analytics.enabled = false` in `config.toml`.

## Testing

Update argument assertions for both remote-control modes and the daemon start/restart test to expect the analytics flag alongside launch feature overrides.

GitOrigin-RevId: 8a222a00fc56737f5fe2b0385abf59466d1a6671
2026-09-30 01:35:21 +00:00
Benjamin Carlsson 1983c48fd1 Continue Markdown blockquotes when pasting multiline text (#49357)
## Why

Pasting multiple lines into a blockquote previously left subsequent lines unquoted.

## What changed

- Continue the current line's `> ` prefix across pasted lines, including blank and trailing lines, in the TUI composer and embedded answer fields.
- Append two unquoted newlines so typing resumes in the next Markdown block. Preserve quoting when large paste placeholders expand on submission.
- Use a shared edit target for paste context and insertion so selection replacement uses the prefix at the replacement start.
- Keep shell input and provisional startup pastes literal.

## Testing

Add unit tests and rendering snapshots for blockquote pastes, embedded answers, cursor placement, selection replacement, and large-paste expansion. Add textarea tests for forward and backward selections, adjacent elements, and Vim Replace backspace recovery.

GitOrigin-RevId: 525a7951aa16a25d49cc3be98822d0dd0709de97
2026-09-29 20:22:34 +00:00
Benjamin Carlsson c6c7c8d270 Omit blockquote markers when copying quoted selections in the TUI (#49153)
## Why

Copying text selected within a blockquote adds Markdown quote markers that are not part of the selected content.

## What changed

Return plain text for selections containing only quoted content, preserving literal `>` characters and selected whitespace. For quoted tables and task lists, remove quote prefixes while retaining table reconstruction and checkbox states. Selections spanning quoted and unquoted content continue to preserve Markdown structure.

Preserve the existing logical source when marking list separator lines as omitted from Markdown copying.

## Testing

Add coverage for partial and nested blockquote selections, quoted tables and task lists at narrow and wide widths and after rewrapping, and copying a mouse-selected blockquote.

GitOrigin-RevId: 5ac0c8c47a77937e5a35c376d8908065217ad2dc
2026-09-29 03:49:47 +00:00
Benjamin Carlsson d7f7fa4106 Remove the plus separator after Option symbols in TUI key hints (#49136)
## What changed

Render macOS Option shortcuts as `⌥t` and `ctrl+⌥t` instead of `⌥+t` and `ctrl+⌥+t`. Keep `+` separators after text modifier labels such as `ctrl`, `shift`, and `alt`.

## Testing

Update key-label and chord assertions and UI snapshots to expect the compact labels across shortcut help, navigation hints, and tooltips.

GitOrigin-RevId: 7d52088ebce3dfa3f8bdad65eb159ca0fead8a31
2026-09-29 02:37:23 +00:00
Benjamin Carlsson 8f6517772b Add history pagination to the agent command center (#49106)
## Why

The command center seeded only ten recent sessions, with no way to browse older history from the task list.

## What changed

- Add a keyboard-selectable “Show more” row that discovers up to ten more tasks, with loading and retry states that remain accessible during search.
- Retain per-source cursors and buffered rows across requests, merging interactive and non-interactive history by recency without discarding existing tasks on failure.
- Refill vacancies after tasks are archived or deleted, and prevent stale refreshes from restoring removed tasks.
- Limit routine detail refreshes to recent and loaded tasks, plus explicitly targeted threads, as retained history grows.

## Testing

Add regression coverage for pagination across mixed sources, cursor retries without row loss, automatic refill, queued pagination, and “Show more” navigation, loading, search, and retry rendering.

GitOrigin-RevId: 0bfcc970c9adf0c8d509b275a92ecf01c29595ad
2026-09-29 00:18:20 +00:00
Benjamin Carlsson c2d2f422e6 Preserve SQLite vacuum modes and surface pool initialization errors (#49102)
## Why

Changing an existing database from `FULL` to `INCREMENTAL` auto-vacuum requires a writer lock and can block pool initialization. SQLx also retries connection initialization failures, masking the original error as `PoolTimedOut`.

## What changed

Preserve existing auto-vacuum modes when opening writable pools, while continuing to initialize empty databases with incremental auto-vacuum. Return the first connection initialization error directly to the caller, retaining SQLx's normal error handling for later lazy connections.

## Testing

Add regression tests for fresh database settings, opening an existing `FULL` auto-vacuum database under a write lock, and preserving the WAL conversion lock error while allowing a subsequent open to succeed after the lock is released.

GitOrigin-RevId: b586c68e43a5a0d3b47268378716919d01b749cf
2026-09-28 23:44:39 +00:00
Benjamin Carlsson d8fc718809 Clarify ChatGPT sign-in success copy (#49031)
Describe permissions and approvals explicitly in the Codex docs link text,
and clarify that the user's ChatGPT plan rate limits and training data
preferences apply. Remove the “Before you start” preamble to shorten the
success screen.

Update the rendering snapshot and hyperlink styling assertions for the
revised copy and layout.

GitOrigin-RevId: 5166ddade6a433191fa86c960899c4da5092b9f5
2026-09-28 16:52:39 +00:00
Benjamin Carlsson 81d5405882 Allow archiving threads before their first turn (#48828)
## Why

Fresh threads have no rollout until their first turn, so archiving them previously failed with a missing-rollout error.

## What changed

Persist loaded, non-ephemeral threads before looking them up for archival. This lets a newly started thread be archived without creating a user turn.

## Testing

Update the archive regression test to cover threads with no turns in both legacy and paginated history modes. Verify the archive notification, empty turn history, `NotLoaded` status, and archived rollout path.

GitOrigin-RevId: 507351c6238ad96f5e3ffbd2ed7f432058e3d52c
2026-09-28 00:58:56 +00:00
Benjamin Carlsson 6af89155d0 Show a hand pointer over transcript links in Ghostty and Kitty (#48827)
## What changed

- Show a hand pointer over actionable transcript links while Codex captures mouse input in Ghostty and Kitty, excluding sessions inside terminal multiplexers.
- Share link hit testing between hover and click activation, and refresh hover after rendering so scrolling and live output cannot leave a stale hand pointer.
- Suppress link hover during mouse presses and drags, overlays, and popups, and clear remembered mouse coordinates on focus loss, resize, and resume.
- Restore the terminal's pointer policy when releasing mouse capture, releasing Kitty's override and using a text pointer in Ghostty. Deduplicate pointer updates and preserve cleanup after write failures.

## Testing

Add tests for wrapped links containing wide characters, hover/click target agreement, scrolling, pointer transitions and restoration, write-failure retries, and hover invalidation.

GitOrigin-RevId: 1cf52e039a229e12260fa334879784c9bc1c8c87
2026-09-28 00:53:05 +00:00
Benjamin Carlsson 84cc4b3fb5 Keep voice RTP timestamps aligned to 20 ms packets (#48824)
## Why

Capture jitter and mute transitions can shift RTP timestamps off the 20 ms source grid, causing receivers that assemble fixed-duration frames to reject subsequent audio.

## What changed

Advance elapsed gaps in whole 20 ms packets and keep the track clock on that grid. Bias empty gap durations by 1 ns to avoid losing an RTP tick to floating-point truncation.

## Testing

Update jitter and mute tests to assert exact clock advancement, including a 580 ms gap, and verify that resumed RTP timestamps stay aligned to 960-sample packets.

GitOrigin-RevId: 1511c739b77ee5871f72723fd34cb67aa9a48c95
2026-09-28 00:43:04 +00:00
Benjamin Carlsson 944d6fd1ba Keep voice captions visible across speaker updates and history handoff (#44952)
## Why

Completed voice captions could disappear before their queued history insertion ran. Interleaved user and assistant updates could also hide the other speaker's caption and restart its animation.

## What changed

- Preserve separate live caption cells for both speakers, rendering the user above the assistant without restarting settled text.
- Render completed captions while history insertion is pending, then move them into history in one app event. Keep them visible when agent streaming delays insertion.
- Invalidate the transcript overlay when an interleaved caption is cleared.

## Testing

Add regression tests for caption visibility through deferred history insertion, settled animations with either speaker arriving first, and empty caption completion during active and stopping sessions. Update replay coverage to exercise the app's history handoff.

GitOrigin-RevId: 31de6fc74b6dc7ff148c554e3176bf3ee92dced9
2026-09-12 01:21:25 +00:00
Benjamin Carlsson d43f1e7eb2 Clarify the Windows Visual C++ runtime notice for voice packages (#44942)
Identify the bundled runtime as `bin/vcruntime140.dll`, relative to the
notice in release packages. Add a dedicated section with links to Microsoft's
license terms, redistributable downloads and support, and Visual Studio 2026
redistribution information.

GitOrigin-RevId: 9ef14ebd9b2d5b2ff0b449d50717f40e7823c727
2026-09-12 00:06:16 +00:00
Benjamin Carlsson 16491f7f70 Preserve voice meter history through quiet samples (#44928)
## Why

A quiet sample cleared all earlier activity from that channel's voice meter, making recent speech disappear immediately.

## What changed

Let quiet samples scroll into the microphone and speaker meter history so earlier activity remains visible until it ages out.

## Testing

Update history assertions and the meter snapshot to cover quiet samples on each channel and the eventual return to silence after a full history window.

GitOrigin-RevId: 834157df28c9d2cfbe9fa17bbfaf32b81313a295
2026-09-11 22:17:40 +00:00
Benjamin Carlsson 1b5e27c7f0 Accept voice response audio before captions on quiet turns (#44925)
## Why

Starting a voice turn while the speaker is idle suppresses response audio until assistant captions arrive, preventing audio that arrives first from being accepted.

## What changed

Make speaker suppression conditional when user transcripts start a new turn. Keep idle output ready for audio while preserving interruption of active assistant output and older, uncaptioned speech that is queued or accepted.

## Testing

Add regression coverage for quiet turns with incremental or final-only user transcripts and for interruption of older pending speech across queue and caption states.

GitOrigin-RevId: 288d2071766a1d0c1b8c7a10c0ab434dc4d7cee1
2026-09-11 22:09:26 +00:00
Benjamin Carlsson 7ef70f95d5 Refresh the speaker format when restarting voice output (#44924)
## Why

Opening a Bluetooth microphone can change the speaker format, leaving the previously cached sample rate unsupported when the speaker stream restarts.

## What changed

Requery and validate the speaker configuration after stopping the old stream. Update playback and render resampling to the current sample rate, and revalidate callback timing. Discard stale echo references while preserving capture history and audio processing state.

## Testing

Extend the speaker reset test to cover 48, 24, and 44.1 kHz output rates, checking that render output matches a fresh converter while capture history and pending samples are preserved.

GitOrigin-RevId: 3a4fba577288a83a7509fc78be86171ac85a3c0a
2026-09-11 22:09:02 +00:00
Benjamin Carlsson ce7fbb373b Bundle native voice runtimes in Windows releases (#44922)
## Why

Windows release packages need the voice helper and native audio libraries. Realtime TLS connections on fresh Windows installations also need platform certificate validation so Windows can retrieve missing trusted roots on demand.

## What changed

- Build and sign the voice helper and audio DLLs for Windows x64 and ARM64, bundle a pinned Microsoft CRT DLL, and verify signatures and runtime receipts before packaging.
- Add verified, pinned Cygwin and native build tools plus MSVC linker, compiler, and path handling fixes for the Windows Bazel builds.
- Include voice resources in primary release archives and WinGet packages. Preserve WinGet executable names, update manifest hashes, and recognize the package root through matching entrypoint metadata. Keep Python runtime wheels voice-free to preserve their existing Windows support floor.
- Use Windows platform TLS validation for realtime WebSockets when no custom CA bundle is configured, preserving custom CA behavior.

## Testing

Add coverage for build-input integrity and unsafe paths, signed Windows runtime assembly, WinGet file and hash preservation, package discovery, and TLS trust selection, untrusted certificate rejection, and hostname validation.

GitOrigin-RevId: 423da35872fa5549d69fd4ca97d922bb49599386
2026-09-11 21:59:24 +00:00
Benjamin Carlsson 3f59eb965a Enable TUI voice conversations by default (#44921)
## What changed

Promote `realtime_conversation` to stable and enable it by default, removing its experimental announcement. Update popup and tooltip tests to use explicit experimental voice fixtures now that the feature is stable.

GitOrigin-RevId: 4e947189f41de465d1f343e95100b26d6200db24
2026-09-11 21:59:01 +00:00
Benjamin Carlsson 68bc5369ba Enable worktrees by default and clarify local daemon errors (#44870)
## What changed

- Mark `worktrees` stable and enable it by default, removing it from `/experimental`. Point users who explicitly disable it to their Codex configuration.
- When a local daemon lacks `thread/backgroundTerminals/list`, block worktree creation and `/cd` with guidance to run `codex app-server daemon update` and restart Codex.

## Testing

Add regression coverage for unsupported local daemon methods, unrelated errors, embedded servers, and empty background terminal lists. Update feature-gating tests to disable worktrees explicitly and remove worktrees from the experimental menu snapshot.

GitOrigin-RevId: 3f21d0ebaa02da11a6aaa2e1ac615b4518fc98d8
2026-09-11 17:08:59 +00:00
Benjamin Carlsson ab95cd4dd9 Preserve voice caption order when replaying TUI history (#44749)
## Why

Retained voice captions were appended after replayed history, placing earlier speech after later typed turns when switching back to a thread.

## What changed

Anchor completed captions to the next live turn and restore them before that turn during replay. Handle buffered item, delta, and completion events even when the turn-start event has been evicted. Restore remaining captions at the end of replay.

## Testing

Extend regression coverage to verify caption order and avoid duplicates across repeated thread switches. Add coverage for inactive-thread captions replayed before a later buffered turn without its start event, with and without a message delta.

GitOrigin-RevId: 6860a649bdcdda4937afb3ab4bbd75cf4ea5b4e6
2026-09-11 06:56:37 +00:00
Benjamin Carlsson eabb7c91d1 Preserve editor yanks across new sessions and thread switches (#44742)
## Why

Starting a new session with `/new` or switching threads replaces the chat composer, losing the last editor kill or Vim yank.

## What changed

Transfer the kill buffer to the replacement composer, preserving both its text and whether it is characterwise or linewise. Yanked text remains available to paste within the same TUI session.

## Testing

Add regression tests for new sessions and root thread switches that delete a line with Vim `dd`, then paste it with `p` in the replacement composer and verify the text and rendered output.

GitOrigin-RevId: edb4790d4de7b7425de6ef6af4e2786f6a4771c1
2026-09-11 06:27:28 +00:00
Benjamin Carlsson da20788df9 Bundle Linux voice runtimes and improve audio reliability (#44714)
## Why

Linux voice needs system ALSA plugins and enough buffering to accommodate PipeWire graph cycles without losing capture samples. Voice startup failures also need actionable diagnostics without exposing native error details.

## What changed

- Build and bundle GNU voice helpers and runtimes with primary Linux musl release archives, and sign the archives. Keep Python wheels free of these libraries to preserve `manylinux_2_17` compatibility.
- Discover ALSA plugins in fixed system directories and increase Linux capture and playback buffering to support larger PipeWire graph cycles.
- Report voice failures by stage, preserve negotiation timeout classification, and discard native error sources. Suppress the misleading `requested` closure message after failure cleanup.
- Add explicit Windows MSVC, pkgconf, and CMake toolchain configuration and preserve host architecture in native build environments.

## Testing

Add coverage for Linux release assembly, ALSA plugin discovery, PipeWire capture and playback, classified startup failures, failure cleanup rendering, and Windows build environment handling.

GitOrigin-RevId: d805eace96a669ce3a4489f12e2db6f68f9f7f53
2026-09-11 03:16:01 +00:00
Benjamin Carlsson 28f43b0417 Keep voice sessions alive through mute and audio backlog (#44671)
## Why

Audio queue saturation and processing delays could terminate voice sessions. Muted sessions also need outgoing audio to keep the peer alive.

## What changed

- Drop stale or excess incoming, capture, render-reference, and playback audio so fresh audio can resume. Reset affected processing state while preserving queue bounds and mute generations.
- Send paced, generated Opus silence while muted, without using device or processing buffers.
- Add fixed helper exit stages and session failure categories to default TUI logs without logging raw native errors, SDP, or device error text. Preserve observed helper exit status for shutdown.

## Testing

Extend tests to cover decoded mute silence and RTP sequence continuity, recovery after stale audio and queue saturation, and shutdown after observing helper output closure. Verify the helper's exit stage when the parent pipe closes during blocked startup.

GitOrigin-RevId: 17d580a72acd4423fb0b4f5107d9b541b964d069
2026-09-10 23:25:10 +00:00
Benjamin Carlsson 9c9451131f Add /voice settings to choose a voice for future conversations (#44622)
## Why

The TUI has no voice picker, and realtime start requests omit the voice preference. Voice selection also needs to reflect the active project's effective server settings, which can differ from cached local settings.

## What changed

- Add `/voice settings` with the server's voice catalog and current effective selection, falling back to the built-in catalog when unavailable.
- Save `realtime.voice` through the app server and reread effective settings before confirming the selection. Report save failures and overrides.
- Resolve the effective voice for each realtime start. Apply selections to the next voice conversation without interrupting live audio, and retain compatibility with servers that lack `config/read` or return unknown voice names.

## Testing

Add picker and confirmation snapshots, plus request tests covering persistence, server defaults, catalog fallback, unknown voices, config read failures, overrides, and project settings after thread switches.

GitOrigin-RevId: d47e3da6c1164053c5be9d1da0f5932f2a09261f
2026-09-10 19:14:57 +00:00
Benjamin Carlsson e722303e38 Expose voice conversations in experimental features (#44331)
## What changed

- Mark `realtime_conversation` as experimental, keeping it disabled by default, and label it “Voice conversations” in `/experimental`.
- Add an announcement directing users to enable the feature, restart Codex, and run `/voice`.
- Hide server-discovered voice entries and the announcement when the client lacks native voice runtime support.

## Testing

Add tests and snapshots for voice discovery and announcement visibility with and without runtime support, and update the experimental features popup snapshot.

GitOrigin-RevId: 709655f3733cb88191eb78b40ac1f67e27c9816e
2026-09-09 23:16:06 +00:00
Benjamin Carlsson ccf470c060 Preserve voice indicator styles during composer sparkle effects (#44198)
## Why

Rendering the voice strip over sparkle stars can leave voice indicators with a star's color even when their glyphs are unchanged.

## What changed

Render the voice strip after effort ignition and before sparkle effects so stars skip its text and preserve its styles.

## Testing

Add a regression test comparing all nonblank composer cells, including their styles, across 80 sparkle frames while confirming stars still appear. Add a snapshot of the active voice composer.

GitOrigin-RevId: 48774408646c1281df3a6f7b1e12ab9d03a1babd
2026-09-09 16:43:50 +00:00
Benjamin Carlsson 9e868bd9dc Handle empty voice arguments in macOS release packaging (#44101)
Guard the `voice_args` array expansion to avoid unbound-variable errors
under `set -u` when packaging bundles without voice arguments. Preserve
quoted arguments for the `primary` bundle.

GitOrigin-RevId: 677a565d1678dc1e218cd9a98298aa6a26873643
2026-09-09 08:16:54 +00:00
Benjamin Carlsson 7b9e7d99bd Make staged macOS voice runtimes writable before packaging (#44080)
## Why

GNU tar extraction and signing require writable copies of Bazel outputs.

## What changed

Recursively add owner write permission to the staged macOS voice runtime before creating the unsigned release archive.

GitOrigin-RevId: 1d415251b26303ac17cf886f35ae18277e9e6032
2026-09-09 06:33:16 +00:00
Benjamin Carlsson 85c2d4d921 Fix voice runtime release builds and packaging (#44062)
## What changed

- Build the voice host and native runtime with Bazel's `-c opt` configuration.
- Resolve runtime paths before validating their contents in the release workflow.
- Make `runtime.json` owner-writable before sealing the post-signing release receipt.
- Use `scripts` in `PYTHONPATH` so archive creation can import `codex_package.archive`.

GitOrigin-RevId: 02f960573a4151f52cde486e17e1d45b73435306
2026-09-09 05:21:27 +00:00
Benjamin Carlsson 7aba218851 Refresh workspace lockfile before building macOS voice releases (#44025)
## Why

Release tags bump `Cargo.toml` versions without updating the workspace lockfile, leaving stale versions for Bazel's Cargo dependency graph.

## What changed

Run `cargo update --workspace` in `codex-rs` before the macOS voice release job builds the voice host and native runtime with Bazel.

GitOrigin-RevId: ed923530ff5bc9982968cac4f1def4dde379f422
2026-09-09 03:02:35 +00:00
Benjamin Carlsson 721f46a07a Bundle signed voice resources in macOS releases (#43983)
## What changed

- Build, sign, and notarize `codex-voice-host` and its native runtime for Apple Silicon and Intel macOS release packages, granting the helper audio-input access.
- Include voice resources in primary package archives and DMGs, with a root-level `codex` symlink to `bin/codex` so the runtime can be located.
- Seal runtime receipts with post-signing hashes, require matching release versions and source builds, and bundle dependency notices, licenses, and source metadata.
- Keep voice resources out of Python wheels to preserve their older macOS compatibility; the native voice build targets macOS 14.

## Testing

Add packaging tests for alpha, beta, and stable versions, signed-byte preservation, license hashes, receipt validation, tamper detection, and exclusion of unlisted files. Extend release verification to check voice architectures, signatures, build identity, package hashes, and DMG contents.

GitOrigin-RevId: 9f9415a8b2532d655a9a8740bcdf64066ddb7472
2026-09-09 02:20:06 +00:00
Benjamin Carlsson 973dcd80fc Show worktree owner details and add confirmed deletion (#43942)
## What changed

- Display owner thread titles, relative update times, and archived or unavailable status in the managed worktree browser. Offer resume only for resumable owners, including those with compressed thread history.
- Add a delete action with a confirmation dialog that defaults to Cancel and preserves thread history.
- Restrict removal to managed worktrees in the current repository. Refuse the current checkout, including path aliases, and checkouts containing local changes, untracked files, or ignored files.

## Testing

Add browser snapshots and tests for owner states, deletion confirmation, and compressed thread history. Add worktree removal coverage for unrelated checkouts, current-directory aliases, untracked and ignored files, and successful removal of a clean checkout.

GitOrigin-RevId: e5867f1540d5d5bc8130acc76875e51e3d8b3b6a
2026-09-08 23:37:26 +00:00
Benjamin Carlsson fba22e9a2a Track voice session lifecycle metrics in the TUI (#43934)
## What changed

- Record voice session starts, connections, failures, endings, and active duration under `codex.voice.session.*`.
- Deduplicate failure accounting and distinguish errors during startup retry cleanup from errors during a requested stop.
- Record failures on rejected voice operations and disconnects, and clear the owned session when a stop request is rejected.

## Testing

Add regression tests for failure accounting during retry cleanup and session cleanup after rejected stop requests, including replay-only threads.

GitOrigin-RevId: d67cab5ff1e8fc85ce7a3d61a1763d38a5d537f0
2026-09-08 22:21:01 +00:00
Benjamin Carlsson 095da4b7e8 Fix transcript viewer restoration and half-page scrolling (#43889)
## Why

Repeated alternate-screen entry can overwrite the saved inline viewport, and half-page scrolling can use a different height from the rendered transcript.

## What changed

- Make alternate-screen entry idempotent to preserve the inline viewport for restoration.
- Defer transcript reflow after raw output mode changes while an overlay is open, preserving queued history until the overlay closes.
- Use the last rendered content height for half-page scrolling, matching full-page scrolling.

## Testing

Add regression coverage for restoring the inline viewport and draft after closing the transcript with pending history and a raw output mode change, plus half-page scrolling when the rendered height differs from the terminal viewport.

GitOrigin-RevId: 30847df4b6383db26791ebda20470c9b169f9680
2026-09-08 19:06:42 +00:00
Benjamin Carlsson dd9512c000 Include completed commentary in the /copy picker (#43846)
## Why

During an active turn, `/copy` could still offer the previous final response even after a new commentary message had completed.

## What changed

Record every completed agent message with non-empty visible Markdown for copying, including commentary. The picker can then offer the latest completed commentary as a whole response and expose its code blocks.

## Testing

Add a regression test and picker snapshot covering completed commentary during an active turn after a previous final response. Verify that selecting “Whole response” copies the commentary and that the picker lists its shell code block.

GitOrigin-RevId: 0ea1d5e3952ccac21f2ee951d482619de82f28e0
2026-09-08 16:15:24 +00:00
Benjamin Carlsson ef6c058202 Disable clock synchronization in the voice audio sink (#43704)
Set the GStreamer audio sink's `slave-method` to `none` instead of
`resample`, and disable sink synchronization with `set_sync(false)`.

GitOrigin-RevId: a74f3e6d70e0d817c75bd963b31f16c69c2732ab
2026-09-08 04:55:29 +00:00
Benjamin Carlsson 6b6fdc3572 Preserve split-flap animation state when voice transcripts scroll (#43699)
## Why

Trimming the live voice transcript to its 1,024-byte window could restart
animations for retained words or skip animations for new text that repeats
existing text.

## What changed

Track discarded prefix bytes and render the retained text to identify which
tiles survive. Preserve their arrival times and animation phase so only new
tiles begin animating. Start fresh when the speaker changes or the retained
text no longer matches.

## Testing

Add regression coverage for repeated text, retained-word visibility, Unicode
and Markdown rendering, reduced motion, and replaced or changed-speaker windows.

GitOrigin-RevId: dd33f76441baa4d7787d0a9a1e72b281476acb4c
2026-09-08 04:39:31 +00:00
Benjamin Carlsson 9a3af22d01 Stabilize realtime voice meter sampling across redraws (#43695)
## Why

Footer updates and transcript animation can trigger redraws before more audio arrives, consuming peaks too early and adding spurious quiet samples. Old peaks also linger in the meter after a channel becomes quiet.

## What changed

- Sample microphone and speaker peaks at most once every 100 ms, preserving accumulated peaks on early redraws and scheduling the next sampling frame.
- Clear each channel's meter history on its first quiet sample without clearing the other channel.

## Testing

Add regression tests for early redraw scheduling, peak preservation, independent channel silence, delayed sampling, and sampling after a conversation reset. Snapshot the meters at wide and narrow widths and after each channel becomes quiet.

GitOrigin-RevId: d7b116af2c099a2eaeb6db0d66bca93b230db970
2026-09-08 04:21:46 +00:00
Benjamin Carlsson 45305dd229 Make the voice mute shortcut configurable in the TUI (#43690)
## Why

Voice mute used a hard-coded `Ctrl+X` shortcut and footer hint, so keymap customization could not change or disable it.

## What changed

- Wire `tui.keymap.chat.toggle_voice_mute` into runtime keybindings and the keymap picker, supporting custom keys, chords, and unbinding.
- Keep `Ctrl+X` as the default, but let existing configured shortcuts and overlapping chord prefixes take precedence. Validate explicitly configured mute bindings for conflicts.
- Activate voice chords only when the microphone shortcut is available, excluding pagers and overlays.
- Refresh the voice footer when bindings change, showing the configured shortcut or `/voice mute` when unbound.

## Testing

Add regression tests for binding resolution, conflicts, voice chord context, and live keymap updates. Add footer snapshots covering custom keys, chords, and unbinding in muted and listening states at wide and narrow widths.

GitOrigin-RevId: ec9385f3956aa268bba34dcf2cc2b0c92a31bfec
2026-09-08 04:03:42 +00:00
Benjamin Carlsson 98c7c0415b Move voice controls into a dedicated composer strip (#43683)
## Why

Voice controls replaced the normal footer and could be truncated at narrow widths. Give them dedicated space while keeping the status line visible.

## What changed

- Render voice status, `ctrl+x` mute/unmute, and `/voice stop` above the draft, with separate microphone and Codex audio history meters.
- Keep control positions stable across mute states, prioritize stop at narrow widths, and hide the strip when vertical space is needed for the draft and cursor.
- Reflect actual microphone capture in the recording indicator, respect reduced motion, and allow muting during connection once the audio handle is available.
- Preserve speaker history when muting the microphone and clear speaker samples when playback is suppressed.

## Testing

Add layout and snapshot regressions for voice states, narrow and clipped composers, recording colors, independent audio histories, and status-line visibility. Extend coverage for audio intensity scaling and spoken transcript rendering.

GitOrigin-RevId: 9deb432654f4328cc8a577b8896eee088a0a1d5e
2026-09-08 03:39:58 +00:00
Benjamin Carlsson 3caf9f9586 Style spoken prompts and link workspace files in voice transcripts (#43676)
## What changed

- Render spoken user prompts with a bold red chevron, preserving its color during live transcript animation. Trim leading whitespace for display while retaining the raw transcript text.
- Underline and link file references such as `src/lib.rs:42` in spoken assistant transcripts using terminal hyperlinks. Preserve existing links and support Windows-style relative separators.
- Restrict generated file links to existing files with allowed extensions inside the workspace, rejecting hidden paths, traversal, and symlink escapes.

## Testing

Add rendering and transcript tests for the spoken marker, raw text preservation, file links, Unicode column offsets, and Windows-style paths, plus validation tests for rejected file destinations.

GitOrigin-RevId: 5fa180aa606acdc579a916441520602cb2bf3655
2026-09-08 03:15:37 +00:00
Benjamin Carlsson 4e93cf9b4e Animate live voice transcripts with split-flap tiles (#43656)
## What changed

Render live voice transcripts with a split-flap effect, a black background, and brief speaker-colored highlights as characters settle. Preserve settled characters when text is appended and include animation ticks in the active transcript cache key so frames refresh.

Respect `animations = false`, preserve Unicode graphemes and raw transcript text, and keep completed transcripts as ordinary history cells. Stop requesting animation frames once the effect settles.

## Testing

Add frame snapshots and regression coverage for row styling, speaker colors, appended text, reduced motion, Unicode width, frame scheduling, and unchanged final transcript history.

GitOrigin-RevId: 934f577c7279158f9161d6232634087ab32b0ea3
2026-09-08 02:46:14 +00:00
Benjamin Carlsson 4b0d9669cc Add voice mute shortcut and recording activity indicators (#43651)
## What changed

- Add `Ctrl+X` to toggle the microphone for the active voice session on the current thread, with a footer hint and guards for modals, popups, and repeated key events.
- Show a recording dot in the terminal title's activity indicator while the microphone is listening, respecting title settings and clearing it when capture stops.
- Replace the microphone and speaker bars with compact Braille meters showing four recent amplitude samples.
- Briefly show `heard` when voice input interrupts speech, when animations are enabled.

## Testing

Add regression tests for shortcut routing, amplitude glyphs, interruption acknowledgment, and terminal title lifecycle, plus updated voice footer snapshots.

GitOrigin-RevId: e1dc0c1744667e646e0040e247c5a0409b416075
2026-09-08 02:29:17 +00:00
Benjamin Carlsson 6fee98cc85 Expand TUI regression coverage for realtime voice conversations (#43645)
## What changed

- Add app-to-RPC tests for voice startup, shutdown, thread switching, speech delivery, and rejected or stale speech, using a recording app server without audio hardware.
- Cover session retries, typed and voice handoffs, reasoning visibility, and recovery of undelivered answers in focused chat widget test modules.
- Add transcript and buffered replay tests for caption reconciliation, partial transcript preservation, and voice output ownership across thread changes, with rendering snapshots.

GitOrigin-RevId: 8a76523907289f94f257fe97386db7d2e7f33ca5
2026-09-08 02:09:29 +00:00
Benjamin Carlsson 4b0f44d304 Add worktree classification to thread telemetry (#43621)
## What changed

Add `is_worktree` to thread initialization analytics and the `codex.thread.started` metric using validated Git repository metadata. Classify linked worktrees as `true` and primary checkouts as `false`; report an unavailable classification as `null` in analytics and `unknown` in metrics. Subagent initialization analytics leave the field unset (`null`).

## Testing

Add analytics coverage for primary checkouts, linked worktrees, unknown repositories, and event serialization. Extend the account-switch telemetry test to check that the `is_worktree` tag reaches the next account's collector.

GitOrigin-RevId: bc9bcd3c0212c0a123e4bcfed0c7020eef17dda6
2026-09-07 23:38:35 +00:00
Benjamin Carlsson b01c3986fd Add live WebRTC voice conversations to the TUI (#43581)
## What changed

- Add feature-gated `/voice`, `/voice mute`, and `/voice stop` commands with local WebRTC audio and app-server signaling.
- Show live transcripts, conversation status, and microphone and speaker levels. Preserve captions and undelivered answers across thread switches.
- Speak final answers from voice handoffs while keeping delegated reasoning and commentary hidden and typed answers unspoken.
- Retry eligible startup failures once and clean up voice sessions on thread switches and disconnects.
- Stop voice and block late handoffs after a misalignment policy violation. Remove realtime event payloads and spoken text from receipt and debug logs.

## Testing

Add coverage for voice command mapping, rejected starts, disconnect cleanup, delegated final-answer speech, late handoff rejection, and transcript and footer rendering.

GitOrigin-RevId: 11def1f86b0e023b21d0d92072d6636ccad89815
2026-09-07 20:25:30 +00:00
Benjamin Carlsson 5ecb3afd1b Defer resume picker and directory changes to a fresh TUI stack (#43376)
## Why

Session transitions need stack headroom for embedded-server initialization and configuration loading. Running them inside event dispatch risks exhausting the TUI thread's stack.

## What changed

- Queue `/resume` and valid `/cd` requests for processing after event dispatch returns.
- Reject additional `/cd` requests while one is pending, and recheck the source session, working directory, idle state, and remote-environment restrictions before applying it.

## Testing

Add a Unix PTY regression test that exercises `/resume`, worktree conversation forks, `/cd`, and new worktree conversations through the real TUI event loop. Update the directory-change test to verify that dispatch queues the request without immediately changing configuration.

GitOrigin-RevId: 4950921931dfaba9e55e6bb04f98f7ba64b72122
2026-09-07 06:43:23 +00:00
Benjamin Carlsson 52e12e0cb5 Defer managed worktree transitions to fresh TUI loop iterations (#43298)
## Why

Managed worktree transitions run through the event handler into the large synchronous `ChatWidget` constructor. Split this work so each stage runs on a fresh event-loop stack.

## What changed

- Queue worktree setup, checkout completion and configuration loading, session transition, and widget attachment as separate stages with boxed futures.
- Recheck the source session before transitioning and report retained checkout cleanup instructions when the transition cannot proceed.
- Keep the old configuration paired with the old widget until attachment, and protect input during the handoff.

## Testing

Update worktree lifecycle and submission tests to drain the deferred stages explicitly and assert that checkout creation starts before completion.

GitOrigin-RevId: 0435f56d08bf3a6392d35b5c1cfdcc0f1fe02753
2026-09-06 22:34:30 +00:00
Benjamin Carlsson b053ef9e5a Add a managed worktree browser to the TUI (#43286)
## What changed

Add a searchable “Browse worktrees” option to `/worktree` for local repositories with worktrees enabled. List checkouts from the repository's configured pool, show owner metadata, and let users resume an owner thread or copy a worktree's working directory.

Load worktrees asynchronously and discard results after the loading popup is dismissed or the request context changes. Ignore actions from stale requests and offer copying when owner metadata is missing or invalid.

## Testing

Add popup snapshots and tests for search, resume and copy actions, stale results, and disabled local worktree operations. Extend lifecycle coverage to verify discovery from repository subdirectories and handling of missing or invalid owner metadata.

GitOrigin-RevId: 2b7e694a133278da640b6bb275fd5c1202b271c7
2026-09-06 21:36:02 +00:00
Benjamin Carlsson d30f9cc72a Include linked worktrees in TUI session discovery (#43279)
## Why

Directory-scoped session lookup misses conversations in linked worktrees of the same repository. Managed worktree creation also runs synchronous Git work on the TUI event loop.

## What changed

- With `worktrees` enabled for local sessions, include corresponding directories across linked checkouts in resume and fork pickers and `--last` lookup. Group them together in the agents overview and show checkout paths for picker entries from another worktree.
- Validate shared Git metadata and backlinks, preserve relative working directories and logical path aliases, and reject directory symlink escapes. Keep the expanded directory filter stable across pagination until the listing restarts.
- Fall back to the originally requested directory when an older daemon rejects an array-valued `cwd` filter.
- Create managed worktrees on a blocking worker, check transition blockers before allocation, and revalidate the source session before switching. Report retained checkout paths and cleanup instructions if the transition cannot complete.
- Start the in-session picker server in a separate task to avoid exhausting the TUI event future's stack.

## Testing

Add coverage for linked-checkout discovery, feature gating, picker selection and rendering, project grouping, pagination stability, and legacy daemon fallback. Extend worktree lifecycle tests to cover running-agent blockers and recovery after the source session changes during creation.

GitOrigin-RevId: 4a8a36c0dba3d32d72600f2edf8258a29fb4cb07
2026-09-06 20:52:29 +00:00
Benjamin Carlsson a9896da3fe Connect voice-host RTP audio to speaker playback (#43248)
## Why

The voice host drained incoming RTP packets without playing them. Route received audio through decoding and speaker output while preserving speaker suppression boundaries.

## What changed

- Add a GStreamer pipeline with RTP jitter buffering, Opus decoding, conversion, and resampling into the native speaker sink.
- Rebuild playout when the speaker is re-enabled, reject packets received before the new pipeline started, and discard queued audio and echo references on speaker transitions while preserving capture history.
- Limit each receive pass to 64 packets so incoming media cannot indefinitely delay audio controls.
- Prevent retired sink failures from failing a new speaker generation, and retain the last coherent playback delay estimate during callback contention.

## Testing

Add tests for real Opus playback and stale packet rejection, combined microphone mute and speaker suppression, retired sink failures, delay contention, and echo-reference reset without losing capture history.

GitOrigin-RevId: c91c94a2ba2347ac98af4e7fd1dc331ae766cc45
2026-09-06 16:40:33 +00:00
Benjamin Carlsson 9daf7d22ca Add bounded GStreamer playback components to the voice host (#43244)
## What changed

- Add a `GstAudioSink` subclass backed by a bounded mono `F32LE` playback writer, with partial writes, cancellation on speaker epoch changes, and delay accounting for queued samples and pending device output.
- Recreate the CPAL output stream and discard buffered audio when speaker controls change the epoch, preventing stale audio from surviving suppression.
- Add GStreamer dependencies, adjust Windows Bazel native-tool selection, and allow the helper handshake time to load startup-linked libraries.
- Separate installed-client tests from protocol lifecycle tests and supply native startup libraries in test packages.

## Testing

Add unit coverage for partial writes, sample accounting, suppression cancellation, stale writers, device delay, invalid samples, and stalled consumption.

GitOrigin-RevId: c48c48d2fee00659cf6f8a4039a6745385cb77cd
2026-09-06 16:02:27 +00:00
Benjamin Carlsson 1c40ffe427 Add Windows MSVC Bazel targets for native voice libraries (#43144)
## What changed

- Add explicit x64 and ARM64 targets for native builds, runtime preparation, and linking using the existing voice recipes. Each target requires native Windows execution of the matching architecture.
- Declare compiler, SDK, Python, and CMake inputs; require an explicitly supplied Cygwin/pkgconf tool tree and a fixed `SystemRoot`. Validate installed tool selections against the manifest and declared files.
- Pair Windows DLLs with SDK import libraries, preserve plugin and receipt runfiles, and omit Unix runtime-search flags. Use Python for portable payload copying.
- Correct the MSVC ARM64 tool directory casing to `HostArm64` and document provisioning and build commands.

The generic Rust-consumer aliases remain separate; native Windows Bazel execution and consumer validation are still needed to establish complete Windows voice support.

## Testing

Add eight unit tests covering tool selection, path anchoring, invalid inputs, and DLL/import-library copying, plus x64 and ARM64 link smoke targets that reference `gst_version`.

GitOrigin-RevId: fb2b4998e9ffb5b64ca830ebf4bb4633fc959eb9
2026-09-06 02:14:05 +00:00
Benjamin Carlsson 008bbd5884 Expose native Windows build tools through Bazel targets (#43126)
## Why

The MSVC runtime and Windows SDK repositories discard their tool binaries during setup, leaving native build tools unavailable to Bazel consumers.

## What changed

Patch `windows_support` to retain native MSVC tools and support files, plus the selected SDK's versioned tools, for `x64` and `arm64`. Expose them through opt-in `msvc_tools_x64`, `msvc_tools_arm64`, `winsdk_tools_x64`, and `winsdk_tools_arm64` directory targets.

Exclude the retained tool trees from the existing `sysroot_files`, `headers`, and `libs` targets.

GitOrigin-RevId: df7db08fecfb5e389252332842b8d7361d166891
2026-09-05 23:58:01 +00:00
Benjamin Carlsson aa4a870e06 Add explicit Windows tool selection for native voice builds (#43125)
## Why

Windows libffi builds invoke tools by name, and Cygwin provides a different `link.exe` from MSVC. Inherited search paths can select unintended tools or SDK inputs.

## What changed

Add optional `--windows-build-inputs <json>` to `third_party/voice/build_native.py` to select installed tools and SDK directories for Windows MSVC targets. Validate the target, tool paths, architecture-specific assembler, SDK directories, and agreement with CLI tool arguments.

Build the search path from the selection with MSVC ahead of Cygwin, reject shadowed tools, replace inherited `INCLUDE` and `LIB`, and remove `LIBPATH`. Retain the selection in build receipts. Builds without the option continue using the normal Visual Studio environment.

## Testing

Add tests for linker precedence and subprocess selection, invalid or mismatched inputs, shadowed SDK tools, environment replacement, and receipt recording.

GitOrigin-RevId: c80a6d9eb29556157ba1316d62c9b5083f4038b9
2026-09-05 23:49:23 +00:00
Benjamin Carlsson e01f38c388 Require a prepared runtime when assembling voice helper packages (#43121)
## Why

The helper's native bindings require shared libraries before entering `main`, including for lifecycle calls. Helper-only packages cannot satisfy that requirement.

## What changed

Make `--runtime` mandatory in `third_party/voice/assemble_package.py` and require the `runtime` argument in `assemble()`. Always validate and include the prepared runtime, and update the voice host documentation to describe the requirement.

## Testing

Update assembly tests to supply prepared runtimes and verify that package manifests include runtime library hashes and `runtime.json` alongside the helper.

GitOrigin-RevId: ab5abf80ae935b4ace833fa59b74f670ba62c632
2026-09-05 23:09:26 +00:00
Benjamin Carlsson f6976ab036 Add managed worktree creation to TUI session commands (#43120)
## What changed

- Add `/worktree` to start a fresh conversation or fork the current conversation into a new managed checkout.
- Offer current-checkout and new-worktree choices for `/new` and `/fork`, preserving optional conversation names. Enable these choices for local Git repositories when the `worktrees` feature is enabled.
- Load destination configuration, bind the checkout to the replacement thread, and inherit conversation history only when forking.
- Reject creation from explicitly untrusted sources and require an idle primary session without queued input. Refuse forks when developer instructions differ, with guidance for removing the unused checkout.

## Testing

Add picker snapshots and tests for command availability, named selections, fresh versus forked history, destination configuration, worktree ownership, and feature and trust checks.

GitOrigin-RevId: d6c83e00217660aacf2a6d92acad50b506607e0b
2026-09-05 22:53:48 +00:00
Benjamin Carlsson f5a71ff40a Link Unix Bazel bindings against the prepared voice runtime (#43117)
## What changed

- Export `native_sdk` from the same inspected build as `native_runtime`.
- Configure GLib and GStreamer Rust build scripts to use the declared `pkg-config` executable and SDK, preserving upstream version checks while directing linking to prepared libraries.
- Add `native_link` to expose canonical libraries, development aliases, transitive dependencies, plugins, and the runtime manifest through `CcInfo` and runfiles. Replace GStreamer SDK absolute rpaths with relative Bazel runpaths.

## Testing

Extend the macOS archive preparation test to cover absent and empty SDK output directories, verify SDK file hashes, and check that SDK and runtime manifests share the same source commit and target.

GitOrigin-RevId: 3fc33af06225c69e4c293437f1985290f228dc0a
2026-09-05 22:42:31 +00:00
Benjamin Carlsson a947db131b Add Bazel preparation for native voice runtimes (#43114)
## What changed

Add the manual `//third_party/voice:native_runtime` target for macOS and GNU Linux. It consumes the native prefix archive, validates the completed build receipt against the target and source manifest, inspects libraries, and prepares verified copies using the existing platform policies.

Record the build commit through Bazel workspace status and include it in runtime receipts. Reject invalid or ambiguous commit metadata and escaping library aliases. Keep macOS preparation local and allow the system `libc++.1.dylib` dependency.

## Testing

Add tests for receipt validation, inspection ordering and failures, invalid commit metadata, and escaping archive links. Add a macOS integration test for preparing real libraries from a sandbox-linked archive with native aliases and either an absent or empty output directory.

GitOrigin-RevId: 23717ab33d1d3da5fb0042c1cc8e8efcd333c386
2026-09-05 22:27:22 +00:00
Benjamin Carlsson a31c18ab7a Add a Bazel target for native voice dependencies (#43111)
## What changed

Add `//third_party/voice:native_prefix` to run the existing native build recipe with Bazel-declared archives and toolchain inputs on matching macOS and Linux GNU 2.28 targets for x64 and ARM64. The manual target exports `prefix.tar` and a `built.json` receipt through the `receipt` output group.

Keep macOS actions local to access Apple tools, use Apple's linker for libffi partial links, and preserve compiler runtime flags through libtool on Linux. Surface upstream build failure logs in the Bazel action output.

Document the build's host utility requirements and the distinction between the raw prefix and a relocatable SDK or runtime package.

GitOrigin-RevId: b4917943f621dec07bb994392619e8a42e496b8b
2026-09-05 22:07:21 +00:00