Commit Graph
61 Commits
Author SHA1 Message Date
Benjamin Carlsson b279cfb170 Enable conversation-scoped speed selection for Cloud turns (#61178)
## What changed

- Stage Cloud speed choices for the next new turn in the conversation, alongside pending model and effort selections. Update the displayed conversation speed after admission without changing the local default.
- Offer speed commands supported by the pending model. Clear an incompatible pending speed change with a warning when switching models.
- Carry `service_tier` through Cloud message requests, preserving omission to inherit the thread tier and explicit null to clear it. Translate `default` to null and reject tier overrides on queued requests.

## Testing

Add tests for Cloud speed toggling, model-dependent speed choices, admission-time updates, and preserving the conversation tier when selecting a model. Extend request and wire tests to cover service-tier values, explicit clearing, and queue rejection.

GitOrigin-RevId: b4daa701f1fe29593d90a938e60cc20cb980298a
2026-11-12 20:56:33 +00:00
Benjamin Carlsson 0702ebed4d Lowercase service tier names in the model status line (#60972)
## What changed

Render service tier names in lowercase for the `model-with-reasoning` status line item, while preserving their display casing in terminal titles.

## Testing

Extend footer snapshots to cover Fast and Ultrafast, verify terminal title casing, and check lowercase Flex and multiword tier labels.

GitOrigin-RevId: 16227735d4aae55463df537b91ff7e81c436a66e
2026-11-12 02:15:25 +00:00
Eric Traut 4f9e7171a1 Let terminal status become done while background terminals run (#60418)
## Why

Background terminals kept the terminal program status at `Working` after a turn completed, preventing it from reporting `Done` or returning to `Idle` when acknowledged.

## What changed

Stop treating running background processes as active work when computing terminal program status. Background terminals remain visible in the TUI while the status follows the turn lifecycle.

## Testing

Update the lifecycle regression test to complete a turn with a background terminal still running and assert the `Done` → `Idle` transition on acknowledgment.

GitOrigin-RevId: cb995947e6868d6128736a621f268ebfe3891eec
2026-11-09 16:59:14 +00:00
Joe Savona 66a56b17a1 Keep configured status lines on the native renderer (#60027)
## Why

Enabling `tui_extensions_status_line` routed configured status lines through a plain-text extension renderer and hid the “Use theme colors” option in the status line picker.

## What changed

Always use the native status line renderer for configured items and their live picker previews, preserving theme colors and pull request links regardless of the extensions flag. Always expose the theme color option in the picker, and clarify that the flag enables experimental MCP status line providers.

## Testing

Update coverage to require native status line content across extensions flag changes and exercise the live picker preview with the flag enabled. Retain checks for pull request hyperlinks and color preference preservation.

GitOrigin-RevId: bce7df5696c2bd3583d3ef99c43e7a2014e17294
2026-11-07 01:51:31 +00:00
Joe Savona 797bab4746 Add an experimental UI tree renderer for the status line (#57970)
## What changed

- Add the disabled-by-default `tui_extensions_statusline` feature to render configured status items and their picker preview through a shared UI tree renderer.
- Support text, HTTP(S) links, rows, spacers, dividers, and gaps with rendering budgets, text sanitization, and width-aware truncation that keeps the ellipsis outside hyperlinks.
- Use plain text for the extension status line and hide the picker's theme color toggle while preserving the saved color preference.

## Testing

Add coverage for tree serialization and URL validation, Unicode widths, hyperlink clipping, picker previews, color preference preservation, and token usage updates across renderer switches.

GitOrigin-RevId: a6b87c2b1096765d61296d73e142834fcd53ceee
2026-10-29 03:07:15 +00:00
Joe Savona 6c776cfc8c Preserve status-line hyperlinks through footer layout and animations (#57883)
## Why

Footer hyperlinks must follow their text when the status line is truncated or animated. Inferring link targets from underlined cells loses that association, and Unicode width differences can shift links onto the wrong cells.

## What changed

- Carry explicit hyperlink ranges with status-line content through footer layout and reasoning-effort transitions.
- Fit content to the space allocated beside right-hand indicators, keeping the truncation ellipsis outside links.
- Measure and truncate rendered graphemes consistently while preserving source columns for transcript tab expansion.
- Box the composer's footer state to reduce its stack footprint during session navigation.

## Testing

Add regression tests for clipped links after halfwidth katakana and Arabic prefixes, hyperlink positions during effort transitions, and narrow status rows beside the Plan mode indicator.

GitOrigin-RevId: ede62690e191daefc85f38e637f9bcc9796268b7
2026-10-29 02:10:32 +00:00
Eric Traut 4c54667b40 Add profile and provider status line items (#57516)
## What changed

Add selectable `profile` and `provider` items to the TUI status line, including setup previews and theme colors. Render them as `profile: <name>` and `provider: <id>`, omitting the profile when unset and the provider until a thread is active. Accept `model-provider` as an alias for `provider`.

## Testing

Extend status line tests to cover omitted values, the active thread's provider, provider updates, and a selected profile. Update the setup popup snapshot to include both items.

GitOrigin-RevId: e7cbb7fb1e7017cfbd6ee71e1df7d0ddb1836ed4
2026-10-27 17:08:08 +00:00
Eric Traut c93a54e164 Show effective processing tiers in TUI status surfaces (#57265)
## What changed

- Make the `fast-mode` status line and terminal title items show the current model's processing tier name, falling back to `Standard`, instead of `Fast on` or `Fast off`.
- Share tier label resolution with `model-with-reasoning`, including `Flex` for configured providers other than Amazon Bedrock, and remove the ChatGPT account requirement for displaying tier names.
- Refresh model-dependent surfaces when Fast or Ultrafast mode is enabled or disabled.

## Testing

Update status surface tests and snapshots to cover tier selection, feature toggles, model changes, and provider-specific `Flex` fallback behavior.

GitOrigin-RevId: 7d67ae6177bb1b3c0be4ecf0910106aaaf2bd0be
2026-10-26 21:21:23 +00:00
jif f358635d8e Show native dollar thread usage for ENT26 plans (#57251)
## Why

ENT26 plans are billed directly in dollars, so credit estimates and credit-weighted breakdowns do not describe their thread usage.

## What changed

- Expose optional `nativeUsageUsdMicros` in app-server `ThreadUsage` responses and generated schemas and SDK types. Missing native usage means unknown, not zero.
- Enable ENT26 usage fetching and display native dollar amounts in `/status`, the status line, terminal titles, and the agents overview. Hide credits and omit credit-weighted `/status` breakdowns for these plans.
- Use native dollar amounts when tracking post-turn usage settlement for ENT26 plans.

## Testing

Add coverage for native usage forwarding, ENT26 billing displays, and settlement polling with stale, missing, or zero dollar amounts.

GitOrigin-RevId: ca8ea98141a66bdf0a27feb9f58f67822b821f5f
2026-10-26 20:54:35 +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
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
Felipe Coury 4bad6d78e9 Report terminal program status with OSC 7501 (#52725)
## Why

Lifecycle status reporting was limited to direct iTerm2 sessions. OSC 7501 lets other terminals receive Codex's program state.

## What changed

- Emit OSC 7501 with `app=codex` and states `idle`, `working`, or `blocked` whenever stdout is a terminal, including multiplexed sessions. Report `blocked` when user action is required.
- Continue emitting iTerm2's OSC 21337 status and bounded activity details in direct iTerm2 sessions.
- Clear status before handing the terminal to an external program, as well as on suspension and exit, and re-emit the current state after returning.

## Testing

Add coverage for OSC 7501 encoding, combined iTerm2 output, clearing both protocols, and protocol selection across terminal and multiplexer environments. Update lifecycle tests and status snapshots for the new protocol.

GitOrigin-RevId: 6d2a6885687b0e7af825e954fab72db0765c9a07
2026-10-09 23:43:10 +00:00
Felipe Coury 96d238d0b9 Include foreground activity in iTerm2 session status (#52226)
## Why

The iTerm2 session status reports `Working` without describing the current activity.

## What changed

Populate the OSC 21337 `detail` field from the TUI status header during foreground work, for example `Reading source`. Leave it empty for idle, waiting, background-only work, and the generic `Working` header.

Reuse terminal-title text filtering and the 240-character limit, then escape semicolons and backslashes for the status payload. Include detail in the emission cache so activity changes update the terminal even when the lifecycle state stays the same.

## Testing

Add coverage for foreground-only details, payload encoding, text filtering and truncation, and cache updates when the detail changes.

GitOrigin-RevId: b27a287b80e0db52be6cd9d5d246f03897e2996b
2026-10-08 18:56:04 +00:00
Felipe Coury ade12342e2 Expose Codex lifecycle status in iTerm2 sessions (#52203)
## What changed

Emit `Idle`, `Working`, or `Waiting` with colored indicators through iTerm2's `OSC 21337` session status protocol. Pending user action takes precedence over running tasks and background processes.

Limit emission to direct iTerm2 TTY sessions without a terminal multiplexer. Deduplicate successful writes, refresh status after terminal handoffs and resume, and clear status on suspension and exit.

## Testing

Add coverage for lifecycle transitions, protocol encoding, terminal detection, write retries, deduplication, and re-emission after terminal handoffs.

GitOrigin-RevId: 750e9ec92aeefc57651886a08ef6aea07675d175
2026-10-08 18:07:35 +00:00
Eric Traut 8ea2428c38 Add Daybreak state to the status line and terminal title (#49861)
## What changed

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

## Testing

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

GitOrigin-RevId: b0b7a6f0ee0a107ba4ee2d56113a5b9b6ebd1d41
2026-10-01 04:25:23 +00:00
Eric Traut a837a656ff Keep voice conversations running across TUI thread navigation (#47381)
## Why

Switching threads stopped the active voice conversation. Users should be able to view another task while continuing the call on its original thread.

## What changed

- Retain the voice owner's live widget and subscription in the background, routing voice controls, speech, and connection callbacks to that owner.
- Restore the live call and transcript when returning to its thread, without duplicating captions or letting background UI events affect the visible task.
- Preserve undelivered speech and defer background errors until the owning thread is shown.
- Stop background voice on shutdown, disconnect, or removal of the owning session.

## Testing

Extend regression and end-to-end coverage for thread switching during delegated speech, voice control routing, transcript restoration, caption deduplication, and cleanup on disconnect or archive/delete.

GitOrigin-RevId: ce010dce6fa8cd6fa44949a131f3f16e8cb80c4d
2026-09-22 22:45:08 +00:00
Eric Traut bba48e5ce8 Add independent controls for TUI visual effects (#46832)
## What changed

Replace `tui.whimsy` with `[tui.effects]` preferences for `starfield`, `shimmer`, `welcome`, `effort`, `progress`, and `title`. Each defaults to `true` and remains subordinate to the `tui.animations` master switch.

Wire the preferences into composer effects, welcome artwork, status and loading text, progress indicators, and terminal-title animations. For example, disable shimmering text while keeping progress animations:

```toml
[tui.effects]
shimmer = false
```

Keep retired `tui.whimsy` entries loadable but ignore their value. Update the configuration schema to expose the new preferences.

## Testing

Add and extend coverage for independent shimmer and progress effects, master-switch precedence, welcome and starfield controls, terminal-title blinking, and strict configuration loading with the retired setting.

GitOrigin-RevId: 28b37ba52872133b8954543cabe9ff424147f1c5
2026-09-20 16:16:46 +00:00
Sean Huang 83dc7d11e8 Preserve executor path URIs in permission profile workspace roots (#45863)
## Why

Executor profile roots can use path conventions that are not native to the current host. Converting them to host paths during configuration or turn reconstruction can reject or drop those roots, while case-insensitive comparison can hide Windows path spelling changes.

## What changed

- Store profile roots as URI-backed `ProfileWorkspaceRoot` values throughout permission snapshots and thread settings, preserving spelling in equality and deduplication.
- Keep effective workspace roots as `PathUri` values for permission materialization and status summaries. Convert Windows sandbox root hints to native paths only at native Windows sandbox boundaries, rejecting incompatible roots.
- Omit the legacy rollout `workspace_roots` field when profile roots cannot be represented as host paths, retaining the compiled permission profile.

## Testing

Add regression coverage for Windows and UNC root spelling changes, settings restoration and turn recording with foreign roots, executor-root status display, and backend-specific Windows root conversion.

GitOrigin-RevId: 903c068fd74959bdd10e7cb1141aa42b953a59a4
2026-09-16 04:23:46 +00:00
Sean Huang 7322c5e790 Preserve executor path conventions in permission summaries (#45852)
## Why

Permission summaries must preserve executor paths without interpreting them in the host's filesystem namespace.

## What changed

Accept `PathUri` values and summarize permission profiles directly instead of converting them to a legacy sandbox policy. Render additional workspace roots using their inferred native path convention, and update the exec and TUI callers.

Keep workspace subpath writes and writes outside the working directory classified as `custom permissions` when the working directory itself is not writable.

## Testing

Add coverage for POSIX, Windows drive, and UNC workspace paths, including encoded spaces and case-distinct roots, plus opaque workspace subpath writes.

GitOrigin-RevId: ff2c456e2a720e7216f13e0241b3a935cc925d00
2026-09-16 03:40:53 +00:00
Eric Traut 0818b6550b Add consistent theme-based thread colors across the TUI (#44857)
## What changed

Assign thread colors deterministically from the full thread ID and the active syntax theme's accents. Use the same color for thread names and titles in the status line, status previews, agents overview, and resume/fork pickers, independent of renaming or list order.

Preserve thread colors when picker rows are selected and honor `tui.status_line_use_colors`. Load the configured theme before startup pickers render and refresh the cached palette when the theme changes. Fall back to the terminal's default color when no accents are available.

## Testing

Add unit and snapshot tests for palette extraction and refresh, default accent coverage, selected titles in both picker layouts, color suppression, and preview/footer consistency during automatic naming.

GitOrigin-RevId: 2b83a66bb3e80d4a1daea48ab9a86dbf2b525eef
2026-09-11 16:20:50 +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
Felipe Coury a1294e57f1 Improve automatic thread naming in the TUI (#42749)
## Why

Automatic title generation used a provisional thread name and only applied the
generated result while its thread remained active. Switching threads could
therefore leave the originating thread without its generated name.

## What changed

- Track title-generation requests by thread so results are persisted for the
  originating thread, while preserving any name set before generation finishes.
- Show a `renaming...` spinner instead of a provisional name, including across
  thread switches and failure paths.
- Add `thread-name` items to the status line and terminal title, and include the
  generated thread name in both default layouts.

## Testing

- Cover automatic naming, manual-name precedence, thread switching, failed
  requests, deduplication, and status-surface rendering and animation.

GitOrigin-RevId: a03ae4849bedec9f62f256fadad72c1685ce46e0
2026-09-04 12:20:57 +00:00
dhruvgupta-oai 5037919777 Add Luna Reserve usage fallback to the TUI (#42372)
## Why

When ordinary included usage is exhausted, eligible users need a way to keep working with the backend-provided Luna Reserve quota and return to their previous model once ordinary usage recovers.

## What changed

- Automatically switch eligible TUI tasks to Luna Reserve after an authoritative account usage read, preserving the prior model and reasoning effort per task.
- Restrict model selection while on Reserve to its supported reasoning levels, keep queued turns on the accepted model, and restore the saved model after a fresh read confirms recovery.
- Surface Reserve usage in the composer and `/status`, and expose `normalModelSlug` in app-server rate-limit snapshots so clients can use the associated model's display metadata without changing the request model.
- Poll account limits more frequently near exhaustion and retain compatibility with app servers that only accept the legacy null request parameters.

## Testing

- Added coverage for Reserve entry, queued-turn handling, task reconstruction, recovery authorization, account changes, model selection, usage rendering, and banner dismissal.

GitOrigin-RevId: 46a435e9531051f8cec3f6a46c4b9f7cfa479747
2026-09-02 21:50:51 +00:00
Eric Traut 9d57be71ba Separate TUI preferences from server configuration (#42202)
## Why

TUI preferences and persistence paths belong to the local client, while thread
configuration and account requirements may come from the active app server.
Keeping both in the same resolved `Config` can replace live local preferences
when a thread is resumed, forked, reconnected, or switched.

## What changed

- Add `LocalSettings` as the TUI-owned source for UI, history, notice, and local
  persistence settings, and preserve it across session lifecycle transitions.
- Write preference changes to the selected user config file and reload local
  settings from disk when changing roots.
- Use the app server's account response for authentication-dependent onboarding
  and status UI instead of the local model-provider configuration.
- Retain platform family and OS metadata reported by remote app servers.

## Testing

- Cover local setting defaults, overrides, persistence destinations, reloads,
  and preservation across widget replacement and root switching.
- Cover remote platform metadata and server-controlled authentication UI.

GitOrigin-RevId: dbc2965fb1d6cbecb3f973f6133f3dcd4467b753
2026-09-02 04:20:38 +00:00
Tamir Duberstein 6525b95dae Refresh animated terminal titles without redrawing the TUI (#40618)
## Why

Terminal title animations only need to update the title, but each animation tick
previously requested a full TUI frame.

## What changed

- Track the next terminal title refresh deadline on `ChatWidget`.
- Have the foreground event loop refresh the title when that deadline expires.
- Clear the deadline when title animations are disabled or the configured title is
  empty.

## Testing

- Verify spinner and action-required animations set the expected refresh deadlines.
- Verify refreshing an animated title does not enqueue a TUI draw request.

GitOrigin-RevId: 269347cd48de4ad9ba9a0aef9ed105c25d1a7dae
2026-08-25 14:24:18 +00:00
Benjamin Carlsson 9cdc66904f Hide Fast mode status for unsupported models (#39999)
## Why

The `fast-mode` status item showed `Fast off` even when the selected model did not support Fast mode.

## What changed

- Hide the Fast mode status value when the current model is known not to support Fast mode.
- Continue showing the value for supported and uncatalogued models.

## Testing

- Cover visibility updates when switching among supported, unsupported, and uncatalogued models.
- Update the footer snapshot to verify that an unsupported model omits the Fast mode value.

GitOrigin-RevId: c297655189efc719b2097c2aa415029b01d6873e
2026-08-21 19:47:49 +00:00
Ian MacLeod d9fd91edab Add hostname to the configurable TUI status line (#39795)
## What changed

- Add `hostname` as a selectable status-line item and show it in setup previews.
- Read the normalized operating-system hostname without triggering DNS resolution, and omit the item when no hostname is available.

## Testing

- Cover hostname normalization, status-line rendering, and setup and surface previews.

GitOrigin-RevId: c5e4e0ee1dba6e4bfdf942562a6b037835ff9e69
2026-08-20 20:08:11 +00:00
Felipe Coury 1e71e35df6 Add thread usage to TUI status surfaces (#38282)
## What changed

- Add `thread-credits` and `estimated-thread-cost` items to the configurable
  status line and terminal title for Enterprise workspaces.
- Fetch one shared thread usage estimate only when either item is selected,
  omit unavailable values, and refresh the display after turns complete.
- Preserve the last nonzero estimate while usage settles, with bounded delayed
  refreshes and retries for transient failures.

## Testing

- Add coverage for configuration, rendering, previews, plan availability,
  replay handling, retries, and post-turn settlement.

GitOrigin-RevId: dd69ee621c5bca0e5d9edd32b2bba42487eb1500
2026-08-13 00:34:39 +00:00
Felipe Coury 8bfa49e350 Paginate transcript history in the TUI (#36948)
## Why

Paginated threads should not require the TUI to load and render their entire
history when a session is resumed.

## What changed

- Hydrate a bounded initial history page for paginated resumes and forks,
  respecting the configured terminal reflow row budget.
- Load older transcript items in the background as users navigate upward, while
  preserving the viewport, live output, and backtrack selection.
- Reconcile review-mode prompts across page boundaries and keep restored token
  usage hidden until it can be attributed to a persisted turn.

## Testing

- Added coverage for paginated resume and fork hydration, older-page merging,
  transcript prepending, backtrack behavior, review prompt filtering, and token
  usage restoration.

GitOrigin-RevId: 42160b943a9f6a1ba0cfe4b195c24ddf410b747d
2026-08-04 18:59:32 +00:00
jif 78306a32af Clarify config layer iteration APIs (#36774)
## What changed

- Replace the ordering enum and `include_disabled` boolean with named
  `ConfigLayerStack` iterators for each precedence direction.
- Keep enabled-only iteration separate from `all_layers_*` iteration, which
  includes disabled layers.
- Update config consumers to use the iterator matching their precedence and
  disabled-layer requirements without allocating an intermediate `Vec`.

## Testing

- Add coverage that verifies ordering and disabled-layer filtering for all four
  iterators.

GitOrigin-RevId: d14df3db4a2eae80ba97cdec246bff405e6c5f3d
2026-08-03 17:29:42 +00:00
Adam Perry @ OpenAI 1d65ccabd5 config: own layer provenance types (#29722)
## Why

Config layer provenance describes how effective configuration was
assembled, so it belongs with the config loader rather than in
app-server's serialized API types.

## What changed

- Moved `ConfigLayerSource`, `ConfigLayerMetadata`, and `ConfigLayer`
ownership into `codex-config`.
- Kept app-server's wire payloads unchanged and added explicit
conversions at the app boundary.
- Removed lower-level app-server-protocol dependencies from config
consumers.

## Stack

This is PR 3 of 6, stacked on [PR
#29721](https://github.com/openai/codex/pull/29721). Review only the
delta from `codex/split-auth-domain-types`. Next: [PR
#29723](https://github.com/openai/codex/pull/29723).

## Validation

- `codex-config` coverage passed.
- App-server config-manager and config RPC coverage passed.
2026-06-24 04:03:04 +00:00
xli-oai 21d36296f1 Add workspace messages app-server API (#29001)
## Summary

- Add backend-client types and fetch support for active workspace
messages.
- Add the app-server v2 `account/workspaceMessages/read` method,
generated schemas, and README documentation.
- Delegate workspace-message eligibility to the Codex backend feature
gate; map a backend 404 to `featureEnabled: false`.

## Testing

- `just write-app-server-schema`
- `just test -p codex-backend-client`
- `just test -p codex-app-server-protocol`
- `just test -p codex-app-server workspace_messages`
- `just fix -p codex-backend-client -p codex-app-server-protocol -p
codex-app-server`
- `just fmt`

## Stack

- Base PR for #28232, which adds the TUI status-line integration.
2026-06-22 04:25:07 -07:00
Ahmed Ibrahim 8ac304c299 [codex] Support model-defined reasoning efforts (#26444)
## Summary
- accept non-empty model-defined reasoning effort values while
preserving built-in effort behavior
- propagate the non-Copy effort type through core, app-server, TUI,
telemetry, and persistence call sites
- preserve string wire encoding and expose an open-string schema for
clients
- update model selection and shortcut behavior for model-advertised
effort values

## Root cause
`ReasoningEffort` gained a string-backed custom variant, so it could no
longer implement `Copy` or rely on derived closed-enum serialization.
Existing consumers still moved effort values from shared references and
assumed a fixed built-in value set.

## Validation
- `just fmt`
- Local tests and compilation were not run per request; relying on CI.
2026-06-04 13:36:24 -07:00
Eric Traut f1d029cf75 Add reasoning-only status surface item (#25504)
Closes #24886.

## Why
Users can configure the TUI status line and terminal title with
`model-with-reasoning`, but issue #24886 asks for a compact
reasoning-only item. That lets a setup show just `default`, `low`,
`medium`, `high`, or `xhigh` without repeating the model name.

## What changed
- Added a `reasoning` item for `/statusline` and `/title` setup flows.
- Rendered the item from the effective reasoning effort, including
collaboration-mode overrides.
- Registered `reasoning` with `codex doctor` so Codex-generated
terminal-title config is not reported as invalid.
- Updated TUI setup snapshots so the picker previews include the new
item.
2026-06-01 09:30:20 -07:00
Eric Traut 1333f4a689 Align TUI permissions labels with app (#25017)
## Summary

The desktop app now presents the on-request permissions mode as `Ask for
approval` and the manual-review-backed mode as `Approve for me`. The TUI
still exposed older/internal labels like `Default` and `Auto-review`,
which made the same underlying settings look different across clients.

This updates the TUI UX copy to match the app without changing the
underlying default behavior. Fresh threads continue to use the existing
on-request approval mode, now displayed as `Ask for approval`.

The label changes cover `/permissions`, explicit profile permissions
menus, status surfaces, config persistence history/error text, and the
corresponding TUI snapshots.

### Before
<img width="1181" height="119" alt="Screenshot 2026-05-28 at 10 19
47 PM"
src="https://github.com/user-attachments/assets/0664846b-b6dd-4931-b4dd-d0af0d42058e"
/>
<img width="523" height="19" alt="Screenshot 2026-05-28 at 10 21 29 PM"
src="https://github.com/user-attachments/assets/7899c33e-b35d-4684-8389-97e357803423"
/>

### After
<img width="1216" height="117" alt="Screenshot 2026-05-28 at 10 19
32 PM"
src="https://github.com/user-attachments/assets/015aab43-ac97-411f-8031-75cdd887251b"
/>
<img width="567" height="18" alt="Screenshot 2026-05-28 at 10 20 24 PM"
src="https://github.com/user-attachments/assets/28b6422c-b823-4298-b221-c83d46d09d66"
/>
2026-05-29 11:06:40 -07:00
Arun Eswara d269aa2af9 Harden CLI rate limit window labels (#22929)
## Context

The CLI rate-limit surfaces previously described usage windows as fixed
5-hour and weekly limits. We want the CLI to display whatever supported
rate-limit period the server returns instead of assuming a 5-hour/1-week
pair. This supports generalized Codex rate-limit periods.

## Summary

- Formats CLI rate-limit warning/status labels only for the supported
returned window durations: approximate 5h, daily, weekly, monthly, and
annual.
- Uses generic fallback copy when a primary or secondary window has no
duration, so missing secondary protection data does not produce stale
weekly copy.
- Uses generic fallback copy for unsupported window durations instead of
adding arbitrary hourly, multi-day, multi-week, or multi-year labels.
- Updates status line and terminal title setup descriptions/previews to
talk about primary/secondary usage limits rather than fixed 5h/weekly
limits.
- Adds rendered insta snapshot coverage for the updated rate-limit
status surfaces and `/status` fallback labels.

## Tests
Tested locally:
- one primary window
- one secondary window
- primary and secondary window
2026-05-19 11:22:00 -07:00
Michael Bolin 8adb6032cc tui/exec: show effective workspace roots in summaries (#22612)
## Why

This PR builds on [#22611](https://github.com/openai/codex/pull/22611).

After `runtimeWorkspaceRoots` moved onto thread state, the user-facing
summaries were still inconsistent about which roots they showed. In
particular, `/status` and the exec startup summary could under-report
extra workspace roots from `--add-dir` or from profile-defined
`workspace_roots`, which made the new model look incorrect even when the
permissions themselves were right.

## What Changed

- switched the TUI status surfaces to summarize against
`Config::effective_workspace_roots()`
- updated the exec human-output summary to render from the effective
permission profile instead of the raw constrained profile
- added focused regressions for both the TUI and exec code paths so
extra workspace roots stay visible in user-facing summaries

## Verification

Targeted coverage for this follow-up lives in:
- `codex-rs/tui/src/status/tests.rs`
- `codex-rs/exec/src/event_processor_with_human_output_tests.rs`

The added regressions verify that:
- status output includes profile-defined workspace roots in the
effective permissions summary
- exec startup output includes runtime workspace roots instead of
collapsing back to `cwd` only
2026-05-14 23:10:45 -07:00
Michael Bolin c25d905f61 permissions: support workspace roots in profiles (#22610)
## Why

This is the configuration/model half of the alternative permissions
migration we discussed as a comparison point for
[#22401](https://github.com/openai/codex/pull/22401) and
[#22402](https://github.com/openai/codex/pull/22402).

The old `workspace-write` model mixes three concerns that we want to
keep separate:
- reusable profile rules that should stay immutable once selected
- user/runtime workspace roots from `cwd`, `--add-dir`, and legacy
workspace-write config
- internal Codex writable roots such as memories, which should not be
shown as user workspace roots

This PR gives permission profiles first-class `workspace_roots` so users
can opt multiple repositories into the same `:workspace_roots` rules
without using broad absolute-path write grants. It also starts
separating the raw selected profile from the effective runtime profile
by making `Permissions` expose explicit accessors instead of public
mutable fields.

A representative `config.toml` looks like this:

```toml
default_permissions = "dev"

[permissions.dev.workspace_roots]
"~/code/openai" = true
"~/code/developers-website" = true

[permissions.dev.filesystem.":workspace_roots"]
"." = "write"
".codex" = "read"
".git" = "read"
".vscode" = "read"
```

If Codex starts in `~/code/codex` with that profile selected, the
effective workspace-root set becomes:
- `~/code/codex` from the runtime `cwd`
- `~/code/openai` from the profile
- `~/code/developers-website` from the profile

The `:workspace_roots` rules are materialized across each root, so
`.git`, `.codex`, and `.vscode` stay scoped the same way everywhere.
Runtime additions such as `--add-dir` can still layer on later stack
entries without mutating the selected profile.

## Stack Shape

This PR intentionally stops before the profile-identity cleanup in
[#22683](https://github.com/openai/codex/pull/22683) so the base review
stays focused on config loading, workspace-root materialization, and
compatibility with legacy `workspace-write`.

The representation in this PR is therefore transitional: `Permissions`
carries enough state to distinguish the raw constrained profile from the
effective runtime profile, and there are still call sites that must keep
the active profile identity and constrained profile value in sync. The
follow-up PR replaces that with a single resolved profile state
(`ResolvedPermissionProfile` / `PermissionProfileState`) that keeps the
profile id, immutable `PermissionProfile`, and profile-declared
workspace roots together. That follow-up removes APIs such as
`set_constrained_permission_profile_with_active_profile()` where
separate arguments could drift out of sync.

Downstream PRs then build on this base to switch app-server turn updates
to profile ids plus runtime workspace roots and to finish the
user-visible summary behavior. Reviewers should judge this PR as the
workspace-roots foundation, not as the final in-memory shape of selected
permission profiles.

## Review Guide

Suggested review order:

1. Start with `codex-rs/core/src/config/mod.rs`.
This is the main shape change in the base slice. `Permissions` now
stores a private raw `Constrained<PermissionProfile>` plus runtime
`workspace_roots`. Callers use `permission_profile()` when they need the
raw constrained value and `effective_permission_profile()` when they
need a materialized runtime profile. As noted above,
[#22683](https://github.com/openai/codex/pull/22683) replaces this
transitional shape with a resolved profile state that keeps identity and
profile data together.

2. Review `codex-rs/config/src/permissions_toml.rs` and
`codex-rs/core/src/config/permissions.rs`.
These add `[permissions.<id>.workspace_roots]`, resolve enabled entries
relative to the policy cwd, and keep `:workspace_roots` deny-read glob
patterns symbolic until the actual roots are known.

3. Review `codex-rs/protocol/src/permissions.rs` and
`codex-rs/protocol/src/models.rs`.
These add the policy/profile materialization helpers that expand exact
`:workspace_roots` entries and scoped deny-read globs over every
workspace root. This is also where `ActivePermissionProfileModification`
is removed from the core model.

4. Review the legacy bridge in
`Config::load_from_base_config_with_overrides` and
`Config::set_legacy_sandbox_policy`.
This is where legacy `workspace-write` roots become runtime workspace
roots, while Codex internal writable roots stay internal and do not
appear as user-facing workspace roots.

5. Then skim downstream call sites.
The interesting pattern is raw-vs-effective access: state/proxy/bwrap
paths keep the raw constrained profile, while execution, summaries, and
user-visible status use the effective profile and workspace-root list.

## What Changed

- added `[permissions.<id>.workspace_roots]` to the config model and
schema
- added runtime `workspace_roots` state to `Config`/`Permissions` and
`ConfigOverrides`
- made `Permissions` profile fields private and replaced direct mutation
with accessors/setters
- added `PermissionProfile` and `FileSystemSandboxPolicy` helpers for
materializing `:workspace_roots` exact paths and deny-read globs across
all roots
- moved legacy additional writable roots into runtime workspace-root
state instead of active profile modifications
- removed `ActivePermissionProfileModification` and its app-server
protocol/schema export
- updated sandbox/status summary paths so internal writable roots are
not reported as user workspace roots

## Verification Strategy

The targeted tests cover the behavior at the layers where regressions
are most likely:
- `codex-rs/core/src/config/config_tests.rs` verifies config loading,
legacy workspace-root seeding, effective profile materialization, and
memory-root handling.
- `codex-rs/core/src/config/permissions_tests.rs` verifies profile
`workspace_roots` parsing and `:workspace_roots` scoped/glob
compilation.
- `codex-rs/protocol/src/permissions.rs` unit tests verify exact and
glob materialization over multiple workspace roots.
- `codex-rs/tui/src/status/tests.rs` and
`codex-rs/utils/sandbox-summary/src/sandbox_summary.rs` verify the
user-facing summaries show effective workspace roots and hide internal
writes.

I also ran `cargo check --tests` locally after the latest stack refresh
to catch cross-crate API breakage from the private-field/accessor
changes.







---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22610).
* #22612
* #22611
* #22683
* __->__ #22610
2026-05-14 18:25:23 -07:00
Eric Traut 789b7e39dc Split ChatWidget state into focused modules (#21866)
## Summary

`ChatWidget` has been carrying several independent domains in one large
state bag: transcript bookkeeping, turn lifecycle, queued input, status
surfaces, connectors, review mode, and protocol dispatch. That makes
otherwise-local changes hard to reason about because unrelated fields
and side effects live beside each other in `chatwidget.rs`.

This is the first cleanup PR in a larger decomposition effort. It does
not try to make `chatwidget.rs` small in one sweep; instead, it
establishes focused state boundaries that later handler, popup,
rendering, and effect-synchronization extractions can build on.

This PR keeps `ChatWidget` as the composition layer while moving focused
state into smaller `codex-tui` modules. The widget still owns effects
that touch the bottom pane, app events, command submission, redraw
scheduling, and terminal-title updates.

## Changes

- Add focused state modules under `codex-rs/tui/src/chatwidget/` for
input queues, turn lifecycle, transcript bookkeeping, status state,
connectors, review mode, and app-server protocol dispatch.
- Update `ChatWidget` to hold grouped state structs and route
input/lifecycle/status operations through those focused helpers.
- Move app-server notification dispatch into `chatwidget/protocol.rs`
while leaving feature handlers and side effects on `ChatWidget`.
- Replace the large manual `ChatWidget` test literal with the normal
constructor plus narrow test overrides, so future state moves do not
require every field to be restated in test setup.
- Update existing tests to access the new grouped state or narrower
helpers without changing snapshot behavior.

## Longer-term direction

Follow-up PRs can continue shrinking `chatwidget.rs` by moving behavior,
not just state, into focused modules:

- Extract input/submission flow, turn/stream handling, and tool-cell
lifecycles into domain modules that call the new state reducers.
- Move popup/settings builders and rendering helpers out of the main
widget file so `ChatWidget` stays focused on composition.
- Reduce direct `BottomPane` mutation by applying domain-specific sync
outputs at clearer boundaries.
2026-05-09 15:16:01 -07:00
Ahmed IbrahimandCodex 7c0e54bf59 [codex] Generalize service tier slash commands (#21745)
## Why

`/fast` was wired as a one-off slash command even though model metadata
now exposes service tiers as catalog data. That meant adding another
tier, such as a slower/cheaper tier, would require more hardcoded TUI
plumbing instead of letting the model catalog drive the available
commands.

This change makes service-tier commands data-driven: each advertised
`service_tiers` entry becomes a `/name` command using the catalog
description, while the request path sends the tier `id` only when the
selected model supports it.

## What Changed

- Removed the hardcoded `/fast` slash-command variant and introduced
dynamic service-tier command items in the composer and command popup.
- Added toggle behavior for service-tier commands: invoking `/name`
selects that tier, and invoking it again clears the selection.
- Preserved the existing Fast-mode keybinding/status affordances by
resolving the current model tier whose name is `fast`, while still
sending the tier request value such as `priority`.
- Persisted service-tier selections as raw request strings so non-fast
tiers can round-trip through config.
- Updated the Bedrock catalog entry to advertise fast support through
`service_tiers` with `id: "priority"` and `name: "fast"`.
- Added defensive filtering in core so unsupported selected service
tiers are omitted from `/responses` requests.

## Validation

- Added/updated coverage for dynamic service-tier slash command lookup,
popup descriptions, composer dispatch, TUI fast toggling, and
unsupported-tier omission in core request construction.
- Local tests were not run per request.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-05-08 20:09:51 +03:00
jif-oai 5b87bd2845 chore: thread tui (#21767) 2026-05-08 17:53:23 +02:00
Eric Traut e6312d44f0 Show permissions and approval mode in the TUI status line (#21677)
Fixes #21665.

## Why

The TUI status line is the right place for compact, glanceable session
state. The original request was motivated by the need to see the active
permission posture without opening `/permissions` or `/status`,
especially when switching between safer and more permissive modes during
a session.

This PR intentionally separates `permissions` from `approval-mode`
instead of combining them into one status-line item. They answer related
but different questions: `permissions` describes the active
sandbox/profile shape, while `approval-mode` describes how command
approvals are handled. Keeping them separate makes each item
independently configurable and avoids long combined labels in an already
space-constrained status line.

The tradeoff is that users who want the full permission posture in the
status line need to opt into both items. In exchange, users can show
only the sandbox/profile label, only the approval behavior, or both, and
named user-defined profiles remain concise. Non-standard permission
shapes are rendered as `Custom permissions` rather than trying to
squeeze detailed profile contents into the status line; `/status`
remains the fuller explanatory surface.

## What changed

- Added a configurable `permissions` status-line item.
- Added a separate `approval-mode` status-line item, with `approval` as
an alias.
- Render standard permission states compactly as `Read Only`,
`Workspace`, or `Full Access`.
- Preserve user-defined permission profile names directly in the status
line.
- Render unnamed non-standard permission shapes as `Custom permissions`.
- Refresh status surfaces when `/permissions` updates the permission
profile, approval policy, or approval reviewer.
- Updated status-line preview snapshot coverage for the new items.

## Verification

- `cargo test -p codex-tui
status_permissions_non_default_workspace_write_uses_workspace_label`
- `cargo test -p codex-tui
permissions_selection_emits_history_cell_when_selection_changes`
- `cargo insta pending-snapshots --manifest-path tui/Cargo.toml`
2026-05-08 08:03:11 -07:00
Eric Traut f86d95a242 Display blended token count in status line (#21669)
## Why

The configurable `/statusline` and terminal title can display session
token usage. That display was using the raw total token count, which
includes cached input tokens, so it significantly overstated the token
usage compared with the blended token count shown elsewhere (in
`/status` and tracked in goals). This inconsistency resulted in user
confusion. We don't want to report cached tokens because we don't charge
for them and they are somewhat of an implementation detail that users
shouldn't care about.

## What changed

- Use `TokenUsage::blended_total()` for the `used-tokens` status surface
item so cached input is excluded.
- Add a brief comment to `tokens_in_context_window()` clarifying that it
returns raw `total_tokens`, whose meaning depends on whether the caller
has last-turn or accumulated usage.
2026-05-08 07:56:13 -07:00
Felipe Coury 5e0a4adbe5 feat(tui): add raw scrollback mode (#20819)
## Why

Granular copy is particularly difficult with the current output. Part of
it was solved with the introduction of the `/copy` command but when you
only need to copy parts of a response, you still encounter some issues:

- When you copy a paragraph, the result is a sequence of separate lines
instead of one correctly joined paragraph.
- When a word wraps, part of it stays on the original line and the rest
appears at the start of the next line.
- When you copy a long command, extra line breaks are often inserted,
and command arguments can be split across multiple lines.


https://github.com/user-attachments/assets/0ef85c84-9363-4aad-b43a-15fce062a443

## Solution

Now that we own the scrollback and we re-create it when we resize, we
have the opportunity of toggling between the raw text and the rich text
we see today.

- Add TUI raw scrollback mode with `tui.raw_output_mode`, `/raw
[on|off]`, and the configurable `tui.keymap.global.toggle_raw_output`
action.
- Render transcript cells through rich/raw-aware paths so raw mode
preserves source text and lets the terminal soft-wrap selection-friendly
output.
- Bind raw-mode toggle to `alt-r` by default, with the keybinding path
toggling silently while `/raw` continues to emit confirmation messages.

## Related Issues

Likely addressed by raw mode:

- #12200: clean copy for multiline and soft-wrapped output. Raw mode
removes Codex-inserted wrapping/indentation and lets the terminal
soft-wrap logical lines.
- #9252: command suggestions gain unwanted leading spaces when copied.
Raw mode renders transcript text without the rich-mode left
padding/gutter.
- #8258: prompt output is hard to copy because of leading indentation.
Raw mode renders user/source-backed transcript text without that
decorative indentation.

Partially or conditionally addressed:

- #2880: copy/export message as Markdown. Raw mode exposes raw Markdown
for terminal selection, but this PR does not add a dedicated
export/copy-message command.
- #19820: mouse drag selection + copy in the TUI. Raw mode improves
terminal-native selection of output/history text, but this PR does not
implement in-TUI mouse selection, highlighting, auto-copy, or composer
selection.
- #18979: copied content is divided into two parts. This should improve
cases caused by Codex-inserted wraps/padding in rendered output; if the
report is about pasting into the composer/input path, that remains
outside this PR.

## Validation

- `just write-config-schema`
- `just fmt`
- `cargo test -p codex-config`
- `cargo test -p codex-tui`
- `just fix -p codex-tui`
- `just argument-comment-lint`
- `cargo test -p codex-tui
raw_output_mode_can_change_without_inserting_notice -- --nocapture`
- `cargo test -p codex-tui
raw_slash_command_toggles_and_accepts_on_off_args -- --nocapture`
- `cargo test -p codex-tui raw_output_toggle -- --nocapture`
- `git diff --check`
- `cargo insta pending-snapshots`
2026-05-05 11:17:47 -07:00
Felipe Coury cc16995cc6 feat(tui): add PR summary statusline items (#20892)
## Why?

The Codex App already exposes branch and PR context in its
branch-details UI. This brings the same context into the CLI footer as
opt-in statusline items, so users can choose the extra signal without
making the default footer busier.

## What?

Add optional `pull-request-number` and `branch-changes` items to the
configurable TUI status line.

- `pull-request-number` shows the open PR for the current checkout and
renders as a clickable terminal hyperlink when OSC 8 links are
supported.
- `branch-changes` shows committed additions/deletions against the
repository default branch, or `No changes` when the branch has no
committed diff.

<img width="1257" height="261" alt="CleanShot 2026-05-03 at 20 44 15"
src="https://github.com/user-attachments/assets/10b4380b-c3e9-4729-9ee1-3f742068fa47"
/>

## Architecture

This follows the same client/app-server split as the Codex App: the TUI
owns presentation, caching, and optional rendering, while
workspace-sensitive `git` and `gh` discovery runs through app-server.

The new TUI-local `workspace_command` layer sends bounded,
non-interactive `command/exec` requests to the active app-server. That
makes the implementation remote-friendly: the TUI does not decide
whether commands run in an embedded local workspace or a remote
workspace, and it does not bypass app-server sandbox or permission
policy.

The branch summary logic stays internal to `codex-tui` because this PR
only needs TUI statusline behavior. The command boundary is still
isolated behind `WorkspaceCommandExecutor`, so the lookup code can be
lifted or reused later without changing statusline rendering.

## How?

- Add a TUI `WorkspaceCommandExecutor` abstraction backed by app-server
`command/exec`.
- Add branch summary probes for:
  - current branch name,
  - open PR metadata,
  - committed branch diff stats against the default branch.
- Prefer remote-tracking default branch refs for diff stats, avoiding
stale or absent local `main` branches.
- Resolve PRs with `gh pr view` first, then fall back to
commit-associated PR lookup across parent/fork repos.
- Add `/statusline` picker entries, preview values, rendering, and OSC 8
clickable PR links.
- Keep all probes best-effort so missing `git`, missing `gh`, auth
failures, or non-git directories hide optional items instead of
surfacing footer errors.

## Validation

- `cargo test -p codex-tui branch_summary -- --nocapture`
- Snapshot coverage for the `/statusline` preview/setup rendering paths
- Hyperlink rendering coverage for clickable PR statusline cells
2026-05-04 16:11:15 -03:00
Eric Traut a93c89f497 Color TUI statusline from active theme (#19631)
## Why

Users have shared that the TUI can feel too visually flat because themes
mostly show up in code syntax highlighting. The configurable statusline
is a natural place to make the active theme more visible, while still
letting users keep the existing monotone statusline if they prefer it.

## What Changed

- Added a statusline styling helper that builds the rendered statusline
from `(StatusLineItem, text)` segments, preserving item identity while
keeping the plain text output unchanged.
- Derived foreground accent colors from the active syntax theme by
looking up TextMate scopes through the existing syntax highlighter, with
conservative ANSI fallbacks when a scope does not provide a foreground.
- Tuned theme-derived colors to keep the accents visible without making
the statusline feel overly bright.
- Added `[tui].status_line_use_colors`, defaulting to `true`, plus a
separated `/statusline` toggle so users can enable or disable
theme-derived statusline colors from the setup UI.
- Updated the live statusline and `/statusline` preview to use the same
styled builder, while keeping terminal-title preview text plain.
- Kept statusline separators and active-agent add-ons subdued while
removing blanket dimming from the whole passive statusline.

## Verification

- `cargo test -p codex-tui status_line`
- `cargo test -p codex-tui theme_picker`
- `cargo test -p codex-tui foreground_style_for_scopes`
- `cargo test -p codex-tui`
- `cargo test -p codex-config`
- `cargo test -p codex-core status_line_use_colors`
- `cargo insta pending-snapshots --manifest-path tui/Cargo.toml`

## Visual

<img width="369" height="23" alt="Screenshot 2026-04-30 at 6 16 08 PM"
src="https://github.com/user-attachments/assets/11d03efb-8e4f-4450-8f4d-00a9659ef4cd"
/>

<img width="385" height="23" alt="Screenshot 2026-04-30 at 6 16 02 PM"
src="https://github.com/user-attachments/assets/a3d89f36-bdc1-42e8-8e84-61350e3999e2"
/>
2026-04-30 22:42:48 -07:00
Eric Traut f2bc2f26a9 Remove core protocol dependency [2/2] (#20325)
## Why

With the local model layer and app-server routing in place from PR1,
this PR moves the active TUI runtime onto app-server notifications. The
affected pieces share the same event flow, so the command surface,
session state, bottom-pane prompts, chat rendering, history/status
views, and tests move together to keep the stacked branch buildable.

This PR also removes the obsolete compatibility surface that is no
longer used after the migration. The proposed protocol-boundary verifier
layer was dropped from the stack; enforcing that final boundary will be
simpler once `codex-tui` no longer needs any `codex_protocol`
references.

This PR is part 2 of a 2-PR stack:

1. Add TUI-owned replacement models and extract app-server event
routing.
2. Move the active TUI flow to app-server notifications and delete
obsolete adapter code.

## What changed

- Rewired app command and session handling to use app-server request and
notification shapes.
- Moved approval overlays, request-user-input flows, MCP elicitation,
realtime events, and review commands onto the app-server-facing model
surface.
- Updated chat rendering, history cells, status views, multi-agent UI,
replay state, and TUI tests to use app-server notifications plus the
local models introduced in PR1.
- Deleted `codex-rs/tui/src/app/app_server_adapter.rs` and the
superseded `chatwidget/tests/background_events.rs` fixture path.

## Verification

- `cargo check -p codex-tui --tests`
- Top of stack: `cargo test -p codex-tui`
2026-04-30 11:34:34 -07:00
canvrno-oai e64c765673 Show action required in terminal title (#18372)
Implements #18162

This updates the TUI terminal title to show an explicit action-required
state when Codex is blocked on user approval or input. The terminal
title now uses the activity title item to cover both active work and
blocked-on-user states, while still accepting the legacy spinner config
value.

Changes
- Rename the terminal title item from `spinner` to `activity` while
preserving legacy config compatibility
- Show `[ ! ] Action Required `while approval or input overlays are
active, with a blinking `[ . ]` alternate state
- Suppress the normal working spinner while Codex is blocked on user
action
- Add targeted coverage for action-required title behavior and legacy
title-item parsing

Testing
- Trigger an approval or input modal and confirm the tab title
alternates between `[ ! ] Action Required` and `[ . ] Action Required`
- Disable the activity title item and confirm the action-required title
does not appear
- Resolve the prompt and confirm the title returns to the normal
spinning/idel state


https://github.com/user-attachments/assets/e9ecc530-a6be-4fd7-b9a6-d550a790eb2c
2026-04-27 15:27:11 -07:00
Eric Traut f1c963d77e Add goal TUI UX (5 / 5) (#18077)
Adds the TUI user experience for goals on top of the core runtime from
PR 4.

## Why

Users need a direct TUI control surface for long-running goals. The UI
should make the current goal visible, support common goal actions
without waiting for a model turn, and avoid confusing end-of-turn
notifications while an active goal is immediately continuing.

## What changed

- Added `/goal` summary rendering for the current goal, including
active, paused, budget-limited, and complete states.
- Added `/goal <objective>` creation/replacement through the app-server
goal API rather than a model prompt.
- Added `/goal clear`, `/goal pause`, and `/goal unpause` command
variants.
- Added a confirmation menu when the user enters a new goal while
another goal already exists.
- Updated `/goal` help and summary tip text so it reflects the supported
command variants without advertising slash-command token budgets.
- Added footer/statusline goal indicators, including elapsed time and
token budget display when a budget exists from API/tool-created goals.
- Consumes goal updated/cleared notifications so the TUI stays in sync
with external app-server changes.
- Suppresses end-of-turn desktop notifications only when a goal is still
active and follow-up work is expected.
- Preserves slash-command history behavior and avoids leaking queued
`/goal` state into unrelated submissions.

## Verification

- Added TUI unit and snapshot coverage for goal command availability,
summary rendering, control commands, replacement menu behavior,
status/footer display, notification handling, and command history.
2026-04-24 21:16:45 -07:00
Shijie Rao 02170996e6 Default Fast service tier for eligible ChatGPT plans (#19053)
## Why

Enterprise and business-like ChatGPT plans should get Codex's Fast
service tier by default when the user or caller has not made an explicit
service-tier choice. At the same time, callers need a durable way to
choose standard routing without adding a new persisted `standard`
service tier value. This keeps existing config compatibility while
letting core own the managed default policy.

## What changed

- Resolve the effective service tier in core at session creation:
explicit `fast` or `flex` wins, explicit null/clear or
`[notice].fast_default_opt_out = true` resolves to standard routing, and
otherwise eligible ChatGPT plans resolve to Fast when FastMode is
enabled.
- Add `[notice].fast_default_opt_out` as the persisted opt-out marker
for managed Fast defaults.
- Treat app-server/TUI `service_tier: null` as an explicit
standard/clear choice by preserving that intent through config loading.
- Update TUI rendering to use core's effective service tier for startup
and status surfaces while still keeping `config.service_tier` as the
explicit configured choice.
- Update `/fast off` to clear `service_tier`, persist the opt-out
marker, and send explicit standard for subsequent turns.

## Verification

- Added unit coverage for config override/notice handling, service-tier
resolution, runtime null clearing, and `/fast off` turn propagation.
- `cargo build -p codex-cli`

Full test suite was not run locally per author request.
2026-04-22 21:54:44 -07:00