Commit Graph
3237 Commits
Author SHA1 Message Date
Eric Traut 7389eebf45 Fix TUI permission selection and session state handling (#55682)
## Why

Queued prompts can resume before a pending permissions menu opens, and local
`/permissions` commands can bypass guards for outstanding permission changes.
Attaching to a different project can also retain model access information from
the launch directory.

## What changed

- Route `/permissions` through app permission guards and hold queued prompts
  while the menu is pending. Settle the hold when opening is rejected, discovery
  is invalidated, or a covering request is resolved.
- Apply the custom permission profile selection check beyond embedded servers.
- Refresh API-key model access when the first attached session changes the
  working directory, including with an embedded server. Propagate the widget's
  model catalog to the app and server even when the model response matches the
  widget's already-updated catalog.
- Skip sessions reported as `thread not loaded` during name lookup for all
  server types instead of falling back to unverified list metadata.

## Testing

Add regression coverage for permission guards, queued prompts across successive
permission menus, invalidated and covered menus, model catalog propagation,
project changes on initial attachment, and name lookup across server pages with
unreadable entries.

GitOrigin-RevId: eb49cb5268ce0ce1e40009b73a0180f23e61ed72
2026-10-20 21:40:30 +00:00
Dmitriy Kovalenko ef1604d8f5 Upgrade the Rust toolchain to 1.99.1 (#55677)
## What changed

- Update Cargo and Bazel toolchain pins, CI and release workflows, and Windows setup from Rust `1.95.0` to `1.99.1`.
- Adapt Rust code to updated APIs and lint requirements, including `try_update` and `as_chunks`, and refresh the halfwidth sound marks snapshot.
- Update `webpki-root-certs` from `1.0.5` to `1.0.10` in the Cargo and Bazel lockfiles.

GitOrigin-RevId: e1aaed63b7e72bb8c8bbe25b32c6329c9a37b6c3
2026-10-20 21:28:45 +00:00
cooper-oai f29d55ff06 Propagate authentication header failures before sending requests (#55607)
## Why

Synchronous auth header construction could silently return no credentials when managed authentication became unavailable. Callers need an error to avoid sending requests with missing or partial authentication.

## What changed

- Make `AuthProvider::add_auth_headers`, `to_auth_headers`, and auth header telemetry fallible, and propagate failures through request and WebSocket setup.
- Return a transient error when managed authentication is unavailable, and preserve network policy denials through auth error conversion.
- Retry transient MCP authentication errors while treating build errors and policy denials as terminal.
- Cancel local MCP event streams before resolving authentication so cleanup still works when credentials become unavailable.

## Testing

Add regression coverage for rejected partial authentication, async header resolution, terminal auth errors without sending requests, managed account changes, MCP retry classification, and local stream cancellation after authentication becomes unavailable.

GitOrigin-RevId: 39d981e232cba1e302de502a2fa6239101114ed1
2026-10-20 15:43:19 +00:00
Benjamin Carlsson 78d4c7c7fa Extract shared TUI user prompt helpers from IDE context (#55597)
Move context prefixing and request extraction into `user_prompt`, and update
IDE context injection, thread routing, thread titles, transcript export, and
user message rendering to use the shared helpers. Preserve the request
delimiter, text element byte offsets, and input ordering.

Move the existing last-delimiter extraction test alongside the shared helpers.

GitOrigin-RevId: 3ee350506a536a6dba9575e8311188bc92fed584
2026-10-20 15:15:24 +00:00
Benjamin Carlsson fa71afc8a7 Rank $ mentions by recent selection frequency (#55596)
## What changed

Prefer frequently selected entries in the TUI's `$` picker within exact, prefix, and fuzzy match tiers, keeping stronger match tiers ahead of usage preferences.

Track the last 50 confirmed selections and persist them in `mention_usage.json` under `CODEX_HOME` when history persistence is enabled. Preserve in-memory preferences across compatible chat widget replacements, including when history persistence is disabled. Serialize background writes, merge updates under a bounded file lock, and flush pending writes on shutdown.

## Testing

Add coverage for picker ordering, preference handoff and persistence, history-disabled widget replacement, selection expiry, malformed history, and lock contention.

GitOrigin-RevId: 7efa8c1c365e23000fcda10dbbc2a7e90f4e777c
2026-10-20 15:10:26 +00:00
Eric Traut 8196bcdc18 Check daemon feature overrides and prompt for mismatch recovery (#55442)
## Why

A fixed feature allowlist excluded other boolean feature overrides from daemon use. Feature mismatches could also silently fall back to embedded mode, while automatic startup could persist enabled overrides without confirmation.

## What changed

- Allow boolean feature overrides without a fixed allowlist and compare explicit overrides with the daemon's reported settings. Ignore removed features, treat unreported features as disabled, and include only mismatches in restart settings.
- Preserve saved daemon settings during automatic startup. Prompt on feature mismatches even when embedded fallback is allowed, letting users run without the daemon, confirm a managed-daemon restart, or cancel.
- Detect managed daemons during recovery, mark available restarts as recommended, and limit the displayed feature list to three entries plus a remaining count.

## Testing

Update compatibility tests for mixed overrides, removed and unreported features, unreachable daemons, and required versus optional attachment. Update recovery snapshots and the TUI integration test to exercise explicit embedded-mode selection.

GitOrigin-RevId: 9204620f168ff80aaef312c88e681b754908a431
2026-10-20 03:11:07 +00:00
Benjamin Carlsson 1a35bc4ccb Render async question prompts as Markdown in the TUI (#55411)
## What changed

Render async question titles with the Markdown renderer so emphasis, fenced code blocks, and labeled links display with their intended formatting. Remove blanket bold styling and wrap overwide tokens while preserving hyperlink destinations and accurate row counts.

## Testing

Update rendering snapshots and extend the question rendering test to cover Markdown formatting, link destinations, selective bold styling, and equivalent LF and CRLF rendering at narrow and wide widths.

GitOrigin-RevId: b3e8a94a04433c2d9e5d11e66f83cbd16959d8ed
2026-10-20 00:17:51 +00:00
Felipe Coury a3c643bf8d Retry TUI startup after a server shutdown refusal (#55409)
## Why

A remote server can refuse the initial `thread/start` while shutting down. An explicit refusal establishes that no thread was created, allowing the TUI to retry without risking duplicate startup submissions.

## What changed

- Wait for the draining connection to close, reconnect within a shared two-minute deadline, and retry startup once.
- Preserve the initial prompt, confirmed draft, model, and reasoning effort across recovery. Keep drafts editable and allow cancellation of a pending submission.
- Restore input without submitting if recovery fails or startup is refused again. Continue treating a lost startup reply as uncertain and avoid automatic resubmission.

## Testing

Add regression coverage for successful reconnection with exactly one prompt submission, repeated refusal, disconnect event ordering, and draft cancellation, editing, and paste provenance during recovery.

GitOrigin-RevId: 85b756e14f29c239c4774af2b32215fe251530ac
2026-10-20 00:02:07 +00:00
jif 896604a12d Record OAuth provenance and login identity for account tokens (#55397)
## Why

Token refresh needs the issuer and client ID used at login. Unverified token claims cannot establish that authority, and OAuth error bodies may echo credentials.

## What changed

- Save `oauth_provenance` and a new `login_owner_id` on browser and device-code login. Preserve the login identifier through token rotation.
- Refresh using the recorded issuer and client ID, retaining the existing endpoint override and fallback behavior for legacy records. Clear provenance when an override changes the endpoint or when a response without token rotation encounters a concurrently replaced refresh token.
- Keep both metadata fields optional for older records without inferring provenance from token claims.
- Remove backend token error details from structured logs and refresh error messages.
- Box large futures in token refresh, MCP initialization, and embedded app-server test startup to reduce surrounding async frame sizes.

## Testing

Add coverage for legacy record compatibility and metadata round trips, browser and device-code login persistence, refresh using recorded OAuth settings, metadata preservation through rotation, and provenance clearing for a superseded refresh token.

GitOrigin-RevId: b6b5d2fcbe2a284a171a242c1a17128af55f1024
2026-10-19 22:21:13 +00:00
Eric Traut 36e5861fd9 Mark transcript_v2 as removed (#55388)
## What changed

Mark the no-op `transcript_v2` feature as removed and drop it from the daemon startup override allowlist. Use `tui.fullscreen_transcript` to control the transcript preference.

## Testing

Update local settings coverage to assert that `features.transcript_v2` does not override the fullscreen transcript preference. Use a generic deprecated option in the deprecation notification test and snapshot.

GitOrigin-RevId: 78f832b9603cedc2a6509404a45509e47e845752
2026-10-19 21:44:30 +00:00
Eric Traut fea1d7f7d1 Add support for Academic Researchers plans (#55387)
## What changed

- Recognize `sci` and `sci_plus` in authentication, account responses, rate limits, and generated client schemas.
- Treat both plans as workspace accounts eligible for cloud configuration, and use business analytics routes.
- Display “Academic Researchers” and “Academic Researchers Plus” in the TUI and direct users to their admin when usage limits are reached.

## Testing

Add coverage for plan parsing, workspace classification, account and rate-limit responses, cloud configuration eligibility, analytics routing, TUI labels, and usage-limit guidance. Exercise installed-app refresh and listing with `sci_plus` authentication.

GitOrigin-RevId: b51c5df03029b8bc249d44f11b353a7755e7dd04
2026-10-19 21:43:19 +00:00
Benjamin Carlsson 63ba55817a Manage TUI backend sessions independently (#55381)
## What changed

Add a `BackendSessions` collection to own app-server sessions and poll their events fairly with cancellation-safe receives. Track listening state per backend so pausing or closing one stream leaves the others available, and resume polling after reconnect. Shut down all registered sessions on exit.

Ignore background backend disconnect, lag, account, and rate-limit events that would otherwise update the displayed conversation's UI.

## Testing

Add coverage for polling three sessions, paused and closed stream isolation, cancellation, and session replacement after reconnect. Extend event ownership coverage to verify that background lifecycle and account events leave the displayed connection and rate-limit state untouched.

GitOrigin-RevId: 9ed82abc77aaf4bfeb86eb72161ad90fe20177ad
2026-10-19 21:03:57 +00:00
Joe Savona 0d337e5fe7 Fix recall of command-line initial prompts in the TUI (#55372)
## Why

Command-line initial prompts bypass the composer and were missing from local recall history, so pressing Up could skip them and retrieve cross-session history instead.

## What changed

Record accepted initial prompts in local recall history with their draft metadata. Add image placeholders where needed so recalled local attachments survive resubmission. Leave synchronously rejected prompts out of recall history.

## Testing

Add regression tests for recall order before cross-session history, ordering after transcript replay, queued prompts appearing once, rejected submissions, and image attachment recall and resubmission. Add a snapshot of the recalled initial prompt.

GitOrigin-RevId: 0a12221ae285f01bff4b5860e546c8f7ee3c71e3
2026-10-19 20:21:30 +00:00
Channing Conger 8dd6099e26 Remove thread title generation spinners from the TUI (#55324)
## What changed

Stop showing title-generation spinners in the footer, status line, and terminal title. Remove the associated UI pending state and animation refresh logic while retaining background title generation.

## Testing

Add a snapshot covering the footer and terminal title while automatic naming is pending. Update status-surface snapshots to cover thread names and ID fallbacks without progress indicators.

GitOrigin-RevId: 061456929149c216f0a98d7214179ec69cdaeee4
2026-10-19 17:09:36 +00:00
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
jif d28be12577 Honor per-thread unload delays in app-server (#55270)
## Why

Thread unload timing used the server-wide delay, ignoring per-thread configuration overrides. Clients need to control how long individual idle, unsubscribed threads remain loaded.

## What changed

- Resolve unload timing from each loaded thread's `thread_unload_delay_secs` configuration. Setting it to `0` allows immediate unloading once the thread has no subscribers or activity.
- Allow this runtime retention override in `experimentalPredictionMode` forks while continuing to reject other configuration overrides. Reject negative values and delays too large to schedule.
- Replace the source-specific immediate-unload behavior with explicit configuration.

## Testing

Extend integration coverage for per-thread delays, unloading after active turns finish, fork overrides, and invalid prediction-fork delays. Verify that immediate unloading preserves persistent history and that cold resumes and ordinary nested forks use their default delay instead of retaining the previous runtime's override.

GitOrigin-RevId: fcb82bd73a101260c51e2a8476f94320c23ac929
2026-10-19 12:30:33 +00:00
Vivian Fang 70b3bb6d88 Add observation-only model request lifecycle hooks (#55144)
## What changed

- Add `PreModelRequest` and `PostModelRequest` hooks around model request attempts, including retries. Pass model, session, turn, and optional subagent context; report completion, failure, or cancellation with errors and token usage when available.
- Treat hook output as diagnostic data without allowing it to veto requests or alter model context. Wait for synchronous post-request hooks before dispatching tools, while asynchronous hooks allow streaming tool dispatch to continue.
- Apply memory-consolidation hook filtering and expose the new events through configuration, protocol schemas, generated clients, and the hooks browser.

## Testing

Add integration coverage for failures and retries, ignored control directives, cancellation, synchronous and asynchronous tool ordering, interrupted-turn resume and token accounting, and memory-consolidation filtering. Update hook schema fixtures and hooks browser snapshots.

GitOrigin-RevId: 6ed7b39fc8bb94cf467e350d07d97fcc729c21ce
2026-10-18 22:43:56 +00:00
thorvald-oai 7b44ac1661 Gate app-server WebSocket compression behind a feature flag (#54949)
## What changed

Add `features.app_server_websocket_compression`, disabled by default. TCP WebSocket and Unix-domain socket listeners now negotiate zstd compression only when the feature is enabled and the client offers the supported protocol. Otherwise, connections use plain text messages.

Include the feature in the configuration schema and allow its override during TUI daemon startup.

## Testing

Extend transport tests to cover enabled and disabled compression with supported, unsupported, and absent client offers on both transports. Add an app-server integration test that verifies startup configuration controls negotiation and the message format used for initialization responses.

GitOrigin-RevId: 6001d65f66f9c48f099b85380c2cad8ffee04de7
2026-10-17 23:34:04 +00:00
pakrym-oai ce0323f2f2 Support typed content in contextual prompt fragments (#54776)
## Why

Contextual fragments and extension-owned world-state sections currently return strings, limiting them to text content.

## What changed

- Return `ContentItem` from fragment bodies and rendering, preserving classification and attribution. Apply text markers only to `InputText`; pass other content through unchanged.
- Allow extension prompt and world-state contributions to carry typed content, and preserve media in context-window hints.
- Hash non-text world-state fragments by their serialized content and role while retaining the existing text hashing behavior.
- Add shared content-to-tool-output conversion that preserves image references, image detail, and audio.

## Testing

Add coverage for typed world-state hashing and preservation of image content and attribution. Expand code-mode output tests to cover input text, output text, file-backed and inline images, and audio.

GitOrigin-RevId: 2ed00d466a3f169b151202f3eef71e667ea64be1
2026-10-17 04:02:21 +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
victor-openai 0e67502123 Preserve MCP tool-list metadata in server status (#54686)
## Why

MCP tool discovery discarded response-level `_meta`, leaving server-status clients unable to inspect metadata associated with the tool catalog.

## What changed

- Preserve opaque `_meta` from the first `tools/list` page through catalog refreshes and caches.
- Expose it as `toolListMeta` in `McpServerStatus`, with `null` when unavailable, and update generated schemas and bindings.
- Scope cached Apps catalog metadata to discovery settings, including client capabilities and extensions, while retaining tools from older caches without metadata.
- Restrict server capabilities in status snapshots to the selected servers.

## Testing

Add regression coverage for listing legacy cached Apps tools during failed startup, and update protocol serialization expectations for nullable `toolListMeta`.

GitOrigin-RevId: 62335e2fd8c482067a7a78a7612b58c3eaa9fb55
2026-10-16 19:26:46 +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
vkg-oai a083a1e49e Distinguish MCP approval cancellation reasons (#54679)
## Why

MCP tool calls reported every aborted approval as "user cancelled MCP tool call", including interrupted requests and automatic cancellations in `exec` mode.

## What changed

Carry `user`, `interrupted`, or `non_interactive` cancellation reasons through MCP approval metadata and resolution. Mark explicit TUI cancellations as user actions, interrupted requests as interruptions, and automatic `exec` cancellations as non-interactive.

Use the reason to report when a call was cancelled before approval or because interactive approval is unavailable in `exec` mode. Preserve the existing cancellation message for clients that omit the reason.

## Testing

Update tests to verify that a closed approval response carries the interruption reason and that `exec` cancellation responses include the non-interactive reason.

GitOrigin-RevId: be2a5f7fef539b5db2add53b46aea27e2b8a66fc
2026-10-16 19:08:19 +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
Eric Traut e90f49a269 Treat explicit connections to the verified default daemon as local (#54421)
## Why

Explicitly selecting the default daemon socket previously classified the TUI connection as remote, changing how local configuration and thread parameters were handled. A socket at that path may also be an SSH forward, so the path alone cannot establish that the daemon is local.

## What changed

- Verify the default daemon endpoint before classifying an explicit connection as local. On Unix, check the expected symlink target and the private socket directory's ownership and permissions, then connect to the protected endpoint directly.
- Preserve local workspace behavior and local thread parameters for verified attachments while keeping directly bound Unix sockets classified as remote.
- Report a missing explicitly requested socket, disable embedded fallback for explicit attachments, and restrict daemon auto-start to implicit connections.

## Testing

Extend tests to cover explicit and implicit local target selection, verified socket resolution, and rejection of a directly bound socket as a local daemon endpoint.

GitOrigin-RevId: ac2226ca1c5f60b26aad9571f945e3325d3bebfa
2026-10-15 21:35:40 +00:00
Matt Kaufer 592964c0cb Record local image inputs on completed image-generation items (#54420)
## What changed

Add optional `inputImages` metadata containing each referenced local image's path and SHA-256 hash of the bytes read before normalization. Compute the hash from the same bytes used to prepare the edit request.

Preserve this metadata through completion events, persisted thread history, resume, and legacy rollout migration. Update app-server schemas and generated TypeScript and Python types; older items continue to deserialize without the field.

## Testing

Add coverage for input ordering, changed contents at the same path, unreadable or invalid references, serialization, persisted history and resume, and legacy migration.

GitOrigin-RevId: 522be8ec1e39c9b2bbe5b9ccb37ea67d17f0e21a
2026-10-15 21:30:56 +00:00
Eric Traut 9fcb1f5ed4 Support line breaks in Mermaid flowchart node labels (#54419)
## Why

Flowcharts with `<br>` tags in node labels previously fell back to source instead of rendering as terminal diagrams.

## What changed

Render `<br>`, `<br/>`, and `<br />` as line breaks in quoted and unquoted flowchart node labels. Apply the 40-display-cell label limit per line and keep the decision marker on the first line. Continue rejecting other HTML, break tags in edge labels, and labels containing only breaks or whitespace.

## Testing

Extend rendering snapshots across all four flowchart directions and cover per-line width limits and unsupported markup. Update TUI streaming tests to cover multiline rendering, resizing, source fallback, and preservation of the original source for copying.

GitOrigin-RevId: 61f2a84c8bb161ac4a1c26ddaa0569f52bfea749
2026-10-15 21:29:41 +00:00
Krish Chainani aabf13307a Store generated image items as attachment references (#54398)
## What changed

- Upload generated images to the attachment store and expose `fileId` in image-generation items when available, with inline `result` fallback on upload or decoding failure.
- Preserve file references through legacy events, persisted rollouts, thread history, and task output summaries. Keep model-facing image preparation separate.
- Add attachment request tags and mark generated-image uploads with `usage=image_gen`, preserving the thread's ephemeral setting.
- Update public schemas and SDK types to accept either image representation, retain the Python `ImageGenerationThreadItem` alias, and prefer `fileId` when reading records containing both fields.

## Testing

Add coverage for file-backed generation and rollout persistence, legacy history replay, inline and transitional serialization, task output visibility, and Python SDK alias compatibility.

GitOrigin-RevId: f7a2bb5707e2f277348a547a988bc33c8e96d891
2026-10-15 19:51:22 +00:00
Felipe Coury f847a4bd3c Add quick dial presets for terminal title and status line layouts (#54388)
## What changed

Add current terminal title and status line options to the preset picker. Generate `/title` and `/statusline` commands that preserve item order and duplicates, normalize item aliases, and retain the status line color setting. Use `--clear` for empty layouts and disable options containing unavailable items.

## Testing

Extend picker tests and snapshots to cover the new options, generated commands, empty layouts, and unavailable terminal title items.

GitOrigin-RevId: b836b15e87c03249cf479b1c3baf0bd71931a6be
2026-10-15 19:13:03 +00:00
Felipe Coury 141bf7680d Add session-only arguments to /title and /statusline (#54387)
## What changed

Allow inline item selection, such as `/title model reasoning` and `/statusline current-dir --no-colors`, without changing saved defaults. Support `--clear` for both commands and `--colors` or `--no-colors` for `/statusline`, including color-only updates that preserve the current items.

Carry overrides with per-thread input state across navigation and reconnects, and allow these local commands in parent-owned subagent threads. Reject invalid or conflicting arguments before applying changes. Saved editor selections supersede the corresponding overrides.

## Testing

Add coverage for argument parsing, atomic updates, rate-limit item aliases and ambiguity, thread-state restoration, saved-setting interactions, and local command submission in parent-owned threads.

GitOrigin-RevId: 909cc2ede026fbf5c7f9cd52c8cf2ae835084f14
2026-10-15 19:11:32 +00:00
Felipe Coury 36803b180a Allow saving current permission settings as presets (#54385)
## Why

Creating a preset from current settings only offered the model. Permission presets need to preserve the profile, approval policy, and reviewer to restore the same settings.

## What changed

- Add a “Current permissions” option alongside “Current model” when creating a preset from settings.
- Extend `/permissions` with `--approval-policy` and `--reviewer`, including granular policies and quoted profile names.
- Share argument parsing between `/model` and `/permissions`, supporting quoted arguments and both `--setting=value` and `--setting value` forms.
- Keep full-access confirmation for every reviewer and reject automatic review when unavailable.

## Testing

Add parser tests, preset picker snapshots, and permission-selection tests covering complete settings restoration, invalid arguments, unavailable automatic review, and full-access confirmation.

GitOrigin-RevId: f4c9c3f6e264ee8ea4c5244c79f39f2deb15b771
2026-10-15 19:11:06 +00:00
Felipe Coury b095b2ef23 Support inline permission profile selection with /permissions (#54383)
## What changed

Allow `/permissions <profile-id>` to select a built-in or custom permission profile, for example `/permissions :read-only`. Support `:ask-for-approval` and `:approve-for-me` aliases while preserving feature gates, profile requirements, full-access confirmation, and Windows sandbox setup.

Hold queued input until the selection is confirmed, and retain it on cancellation or failure. Reload custom profile definitions on re-selection without leaving unchanged requests pending.

## Testing

Add coverage for unknown and disabled profiles, approval aliases, confirmation and cancellation, discovery retries, Windows sandbox setup, and queued prompts waiting for server confirmation.

GitOrigin-RevId: ada38d3cfc6d6ac4e84ce5645fe33432c55d63cc
2026-10-15 19:09:34 +00:00
Felipe Coury 111362a6a0 Add a keyboard shortcut menu for presets (#54381)
## What changed

Replace the `/presets` recall picker with a responsive menu above the composer. Press `0`–`9` to run a saved preset or create one in an empty slot; use `n`, `s`, `e`, and `d` to create, start from current settings, edit, and delete presets.

Add `tui.keymap.chat.open_presets` with an implicit `leader p` shortcut that yields to existing bindings and explicit configuration. Show the action in `/keymap` and add a shortcut tooltip.

Preserve the composer draft, respect popup ownership, and consume held-key repeats after menu actions.

## Testing

Add snapshots for empty, populated, and narrow preset menus, plus coverage for draft preservation, cancellation, held-key handling, transcript search precedence, and default shortcut conflicts.

GitOrigin-RevId: f438c7015dbd416c90cdeb479d2a15d9d6d24954
2026-10-15 19:02:34 +00:00
Felipe Coury dcd9e95459 Add /presets for reusable prompts and slash commands (#54380)
## What changed

- Add a TUI picker with ten numbered preset slots, an editor, and confirmation before replacement or deletion.
- Create presets from composer text or current model, reasoning effort, and speed settings. Run saved inputs through the normal queued submission path while preserving the composer draft.
- Persist presets under `tui.presets` in the active user configuration, respecting configuration layer ownership and leaving in-memory settings unchanged when writes fail.
- Preserve permissions when changing effort or speed for the effective model, keep default collaboration settings intact in Plan mode, and allow standard-speed selection with older app servers.

## Testing

Add persistence tests for save, replace, delete, configuration ownership, and write failures; picker and confirmation snapshots; and regression coverage for model permissions and standard-speed fallback.

GitOrigin-RevId: 5f11699112cd404cc8e954872d53495c6edd0c0a
2026-10-15 19:02:09 +00:00
Felipe Coury 1544ffc79d Add configuration support for TUI input presets (#54379)
## What changed

Add `tui.presets` entries keyed by a single digit from `0` to `9`, each with an `input` prompt or slash command and an optional `label`. Expose presets in the configuration schema, load them into runtime configuration, and preserve them in TUI local settings.

Reject invalid slots, blank inputs, shell commands beginning with `!` after leading whitespace, and inputs exceeding 8,000 UTF-8 bytes.

## Testing

Extend the runtime configuration test to verify loading both a slash command with a label and a prompt without one.

GitOrigin-RevId: d2911e540bc50f05b4a5224abf17ce4ef5a18ea3
2026-10-15 19:01:43 +00:00
Felipe Coury 0884c8047a Support inline model, reasoning, and speed selection in /model (#54378)
## What changed

Allow `/model [model] --reasoning <level> --speed <tier>` to update the current session without changing saved defaults. Both space-separated and `=` flag values are supported; omitting the model applies settings to the current model. Bare `/model` still opens the picker.

Validate model availability, supported reasoning levels, and speed tiers before applying changes. Reject unknown flags, duplicate settings, and missing values. Apply model, reasoning, and speed together after server acceptance.

Restore each thread's speed when switching threads, and use destination configuration defaults for new sessions instead of carrying over the active session's speed.

## Testing

Extend regression coverage for inline commands, invalid arguments, unchanged saved defaults, settings-only updates to hidden current models, destination speed defaults, and speed restoration on the next turn after switching threads.

GitOrigin-RevId: ad9cecbdb3554e34a6518367364978a37fb68439
2026-10-15 19:01:10 +00:00
Felipe Coury c313eb75fd Prevent duplicate assistant messages around interleaved commands (#54365)
## Why

When a command starts before an assistant message completes, the TUI can flush the streamed text and then render it again when the completion arrives. This duplicates the preamble in both live output and replay.

## What changed

Track the turn ID, item ID, and source text of the flushed message. Skip rendering its completion again when the identity and text match, allowing for the trailing newline added during stream finalization. Continue rendering completions whose identity or text differs.

## Testing

Add an end-to-end test that delays message completion until a command starts and checks that live and replayed transcripts contain the preamble once. Add regression coverage for completions with different text or item IDs.

GitOrigin-RevId: 59af0198a99f26ba8ba2a47644ba662301c30011
2026-10-15 17:59:14 +00:00
Felipe Coury 86ee40c380 Keep TUI Markdown colors readable against their backgrounds (#54315)
## Why

Syntax theme colors can have insufficient contrast against the terminal background or the shaded proposed-plan surface.

## What changed

- Adapt themed Markdown foreground colors to the terminal background while preserving inline code colors from the syntax theme.
- Adjust proposed-plan foreground colors after applying the plan background, including retained styles used for reflow. Apply the same styling to streamed and completed plans.

## Testing

Expand snapshots across syntax themes and light and dark backgrounds, and cover proposed-plan tables and streamed plans with wrapped hyperlinks. Update streaming assertions to expect contrast-adjusted blockquote colors.

GitOrigin-RevId: 0e358412562c438af17be5bcded9d058b56212b7
2026-10-15 15:08:28 +00:00
Eric Traut e89b7c442c Apply syntax theme colors to Markdown prose in the TUI (#54217)
## What changed

Use the active syntax theme's markup foregrounds for headings, emphasis, strong text, list markers, links, and blockquotes. Preserve existing bold, italic, and underline modifiers, and retain previous styles when a scope provides no foreground.

## Testing

Update rendering snapshots and streaming blockquote assertions for themed colors. Exercise existing fallback expectations with an empty syntax theme.

GitOrigin-RevId: b00aa4af30f73f538ff5f888a0f9b4edbdc15893
2026-10-15 07:05:58 +00:00
Eric Traut dffa0deb69 Show image previews in the fullscreen transcript (#54216)
## What changed

Render local viewed images and generated image artifacts as bounded thumbnails in the rich fullscreen transcript using Kitty or Sixel graphics. Viewed images appear when their activity is expanded or the detailed presentation is active; generated images appear alongside their saved-path entry.

Keep previews clipped to the viewport, retain graphics across unrelated redraws, and remove them when overlays open. Bound image decoding and cache memory, and preserve text-only entries for remote workspaces, unsupported terminals, missing files, and oversized images. Image rows do not enter searchable or selectable text.

## Testing

Add layout and snapshot coverage for disclosure, viewport clipping, rewrapping, raw-mode fallback, deleted files, and oversized rasters. Add terminal coverage for retained Kitty graphics, repainting after a clear, local-file transport, and overlay cleanup.

GitOrigin-RevId: fb2ec146331acfcfc82b2b283616671c9ee93757
2026-10-15 07:00:34 +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
smurching-oai 7943713993 Reload the model catalog after account changes (#54169)
## Why

The app server retained its startup model provider for catalog requests, so signing in or out could leave `model/list` using stale provider settings or requiring a restart after managed provider requirements changed.

## What changed

- Invalidate the catalog after successful login and logout, then reload the effective configuration on the next model list or background refresh. Rebuild the models manager when the provider or catalog changes, while preserving existing threads' routes.
- Retain the original project context and the TUI's `--oss` provider selection across reloads. Retry configuration loading after falling back to defaults so temporary failures do not pin the fallback catalog.
- Keep provider policy checks for cached catalogs and apply runtime `api_key_model_discovery` toggles to the active catalog manager.

## Testing

Add and extend tests for provider selection and definition changes after login, catalog reloads after logout, OAuth gateway transitions, fallback recovery, project context, and runtime model discovery toggles.

GitOrigin-RevId: bce2e23ff567e1a52eac2b6ad736a6e63ff61e2b
2026-10-15 03:06:16 +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
Channing Conger dec54912f9 Report terminal completion states and blocking reasons (#54114)
## Why

Terminal status previously collapsed completed and failed turns into `idle` and reported blocking prompts without a reason. Blocking detection also depended on terminal title settings.

## What changed

- Emit `done` and `error` through OSC 7501 for live turn results, retaining them until deliberate keyboard, paste, or mouse input acknowledges them. Mouse movement does not acknowledge results.
- Classify blocking requests with `kind=permission`, `kind=question`, or `kind=auth`, including requests hidden behind another view or delayed while typing, independently of terminal title settings.
- Keep pending follow-up work and active goals `working`. Treat interrupted turns and replayed results as `idle` rather than new results.
- Preserve the existing iTerm2 OSC 21337 labels and indicators, mapping `done` and `error` to `Idle`.

## Testing

Add lifecycle and input-acknowledgment tests covering approvals, completion, failure, interruption, replay, pending follow-ups, and active goals. Extend blocking-request assertions and terminal protocol snapshots for the new states and reasons.

GitOrigin-RevId: 90bad1d54d8b3b9e3cec66fbd3bf3df0c42b995b
2026-10-14 22:58:37 +00:00
Charlie Marsh f10ec115b7 Show Daybreak notices after the session header (#54097)
## What changed

Emit the Daybreak notice after replacing or removing the placeholder session header so the notice follows the configured header.

## Testing

Extend the resumed-history snapshot test to start with a placeholder header and verify the full transcript order: session header, Daybreak notice, and replayed user and assistant messages.

GitOrigin-RevId: 536f717b2859d2fe319756f52123b4cd0407cb66
2026-10-14 21:05:41 +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
marksteinbrick-oai 2b21129c6b Add Responses API client metadata patches for turn start and steer (#54053)
## Why

Clients need a way to update individual turn metadata entries without replacing the existing client metadata map.

## What changed

Add the experimental `responsesapiClientMetadataPatch` field to `turn/start` and `turn/steer`. Patches add or overwrite entries while retaining other keys and apply after `responsesapiClientMetadata` when both are supplied. The existing field retains replacement semantics, including clearing unprotected entries with an empty map.

Continue protecting reserved metadata keys and preserving targeted `misalignment_override` continuations across updates.

## Testing

Extend the app-server metadata integration test to cover replacement and patch steering, patch precedence at turn start, preservation of unrelated entries during patches, and protection of targeted continuations.

GitOrigin-RevId: 8c4da3ba1b87329da20b5295846bdcf3a88126de
2026-10-14 17:39:43 +00:00
Eric Traut 9671d20fc8 Scope TUI skill refreshes and workspace commands to explicit directories (#54050)
## Why

A queued skill refresh can outlive the workspace it was requested for when the working directory changes.

## What changed

- Refresh skills for the current working directory when the skills management popup closes.
- Ignore queued `ListSkills` commands whose directories do not include the current working directory.
- Require an explicit working directory when constructing `WorkspaceCommand` and always pass it to app-server command execution. Update Git and GitHub metadata probes to use the constructor.

## Testing

Extend regression tests to verify that closing skill management refreshes the configured working directory and that stale skill refreshes after a directory change do not issue a `skills/list` request.

GitOrigin-RevId: 47ad1d95930840b3f6f0e20d7d8fe8d025e789e6
2026-10-14 17:36:18 +00:00
Eric Traut 534c70863c Defer folder trust checks until starting a task from agents overview (#54048)
## Why

The Agent Command Center does not open a workspace, so viewing it should not require consent for the launch directory.

## What changed

Skip startup folder consent when opening the agents overview, while preserving initialization for the embedded fallback. Check folder trust before starting the first task, including through `/new` after dismissing the overview. On Windows, retain the sandbox setup prompt after folder trust is granted.

## Testing

Add CLI tests for starting a task from an untrusted folder through the overview and through `/new` after dismissing it. A terminal snapshot verifies that the overview appears before folder consent.

GitOrigin-RevId: 129be14a354b8abde2e8430c81599e2064ccac87
2026-10-14 17:35:13 +00:00