mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
41e171fcf2c4664136ee3bee9e6c3a2aeca4e140
1728 Commits
-
Enforce
animations = falsefor screen readers (#20564)## Why Issue #20489 calls out that animated TUI affordances can be noisy for screen-reader users. Codex already has `tui.animations = false` as a reduced-motion setting, but some live activity rows render spinner-style prefixes in that mode. These were relatively recent regressions. We have also regressed this pattern more than once by adding new spinner/shimmer callsites that do not think through the reduced-motion path, so this PR adds a small guardrail while fixing the current surfaces. ## What changed - Omit the live status-row spinner when animations are disabled, so the row starts with stable text like `Working (...)`. - Render running hook headers without the spinner prefix when animations are disabled, while preserving shimmer/spinner behavior when animations are enabled. - Centralize TUI activity indicators in `tui/src/motion.rs`, with explicit reduced-motion choices for hidden prefixes, static bullets, and plain shimmer-text fallbacks. - Route existing spinner/shimmer callsites through the central motion helper, including exec rows, MCP/web-search/loading rows, hook rows, plugin loading, and onboarding loading text. - Add a source-scan regression test that rejects direct `spinner(...)` or `shimmer_spans(...)` usage outside the central module and primitive definition. - Add focused coverage that reduced-motion active exec rows are stable, status rows start without a spinner, running hooks omit the spinner, and MCP inventory loading stays stable. - Update the one affected status-indicator snapshot; the existing detail tree prefix remains unchanged. ## Verification - `cargo test -p codex-tui`
Eric Traut ·
2026-05-01 09:07:56 -07:00 -
feat: export and replay effective config locks (#20405)
## Why For reproducibility. A hand-written `config.toml` is not enough to recreate what a Codex session actually ran with because layered config, CLI overrides, defaults, feature aliases, resolved feature config, prompt setup, and model-catalog/session values can all affect the final runtime behavior. This PR adds an effective config lockfile path: one run can export the resolved session config, and a later run can replay that lockfile and fail early if the regenerated effective config drifts. ## What Changed - Add a dedicated `ConfigLockfileToml` wrapper with top-level lockfile metadata plus the replayable config: ```toml version = 1 codex_version = "..." [config] # effective ConfigToml fields ``` - Keep lockfile metadata out of regular `ConfigToml`; replay loads `ConfigLockfileToml` and then uses its nested `config` as the authoritative config layer. - Add `debug.config_lockfile.export_dir` to write `<thread_id>.config.lock.toml` when a root session starts. - Add `debug.config_lockfile.load_path` to replay a saved lockfile and validate the regenerated session lockfile against it. - Add `debug.config_lockfile.allow_codex_version_mismatch` to optionally tolerate Codex binary version drift while still comparing the rest of the lockfile. - Add `debug.config_lockfile.save_fields_resolved_from_model_catalog` so lock creation can either save model-catalog/session-resolved fields or intentionally leave those fields dynamic. - Build lockfiles from the effective config plus resolved runtime values such as model selection, reasoning settings, prompts, service tier, web search mode, feature states/config, memories config, skill instructions, and agent limits. - Materialize feature aliases and custom feature config into the lockfile so replay compares canonical resolved behavior instead of user-authored alias shape. - Strip profile/debug/file-include/environment-specific inputs from generated lockfiles so they contain replayable values rather than the inputs that produced those values. - Surface JSON-RPC server error code/data in app-server client and TUI bootstrap errors so config-lock replay failures include the actual TOML diff. - Regenerate the config schema for the new debug config keys. ## Review Notes The main flow is split across these files: - `config/src/config_toml.rs`: lockfile/debug TOML shapes. - `core/src/config/mod.rs`: loading `debug.config_lockfile.*`, replaying a lockfile as a config layer, and preserving the expected lockfile for validation. - `core/src/session/config_lock.rs`: exporting the current session lockfile and materializing resolved session/config values. - `core/src/config_lock.rs`: lockfile parsing, metadata/version checks, replay comparison, and diff formatting. ## Usage Export a lockfile from a normal session: ```sh codex -c 'debug.config_lockfile.export_dir="/tmp/codex-locks"' ``` Export a lockfile without saving model-catalog/session-resolved fields: ```sh codex -c 'debug.config_lockfile.export_dir="/tmp/codex-locks"' \ -c 'debug.config_lockfile.save_fields_resolved_from_model_catalog=false' ``` Replay a saved lockfile in a later session: ```sh codex -c 'debug.config_lockfile.load_path="/tmp/codex-locks/<thread_id>.config.lock.toml"' ``` If replay resolves to a different effective config, startup fails with a TOML diff. To tolerate Codex binary version drift during replay: ```sh codex -c 'debug.config_lockfile.load_path="/tmp/codex-locks/<thread_id>.config.lock.toml"' \ -c 'debug.config_lockfile.allow_codex_version_mismatch=true' ``` ## Limitations This does not support custom rules/network policies. ## Verification - `cargo test -p codex-core config_lock` - `cargo test -p codex-config` - `cargo test -p codex-thread-manager-sample`
jif-oai ·
2026-05-01 17:46:02 +02:00 -
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" />
Eric Traut ·
2026-04-30 22:42:48 -07:00 -
Format multi-day goal durations in the TUI (#20558)
## Why Goal mode shows elapsed time in compact hour/minute form. That is easy to scan for shorter runs, but once a goal runs past 24 hours, large hour counts become harder to read at a glance. ## What changed Updated `codex-rs/tui/src/goal_display.rs` so unbudgeted goal elapsed time keeps the existing compact format below one day, then switches to a day-aware format once the elapsed time reaches 24 hours: - `23h 59m` - `1d 0h 0m` - `2d 23h 42m` The formatter now covers the 24-hour boundary in unit tests, and the TUI status-line snapshot for a completed elapsed goal now exercises the multi-day display. ## Verification - `cargo test -p codex-tui` Here's my longest-running test task: <img width="186" height="23" alt="image" src="https://github.com/user-attachments/assets/cedfcdab-7f6e-44e6-8495-8a39f63973fb" />
Eric Traut ·
2026-04-30 22:42:07 -07:00 -
Make thread store process-scoped (#19474)
- Build one app-server process ThreadStore from startup config and share it with ThreadManager and CodexMessageProcessor. - Remove per-thread/fork store reconstruction so effective thread config cannot switch the persistence backend. - Add params to ThreadStore create/resume for specifying thread metadata, since otherwise the metadata from store creation would be used (incorrectly).
Tom ·
2026-04-30 21:24:59 -07:00 -
[codex] Remove unused event messages (#20511)
## Why Several legacy `EventMsg` variants were still emitted or mapped even though clients either ignored them or had moved to item/lifecycle events. `Op::Undo` had also degraded to an unavailable shim, so this removes that dead task path instead of preserving a command that cannot do useful work. `McpStartupComplete`, `WebSearchBegin`, and `ImageGenerationBegin` are intentionally kept because useful consumers still depend on them: MCP startup completion drives readiness behavior, and the begin events let app-server/core consumers surface in-progress web-search and image-generation items before the final payload arrives. ## What Changed - Removed weak legacy event variants and payloads from `codex-protocol`, including legacy agent deltas, background events, and undo lifecycle events. - Kept/restored `EventMsg::McpStartupComplete`, `EventMsg::WebSearchBegin`, and `EventMsg::ImageGenerationBegin` with serializer and emission coverage. - Updated core, rollout, MCP server, app-server thread history, review/delegate filtering, and tests to rely on the useful replacement events that remain. - Removed `Op::Undo`, `UndoTask`, the undo test module, and stale TUI slash-command comments. - Stopped agent job/background progress and compaction retry notices from emitting `BackgroundEvent` payloads. ## Verification - `cargo check -p codex-protocol -p codex-app-server-protocol -p codex-core -p codex-rollout -p codex-rollout-trace -p codex-mcp-server` - `cargo test -p codex-protocol -p codex-app-server-protocol -p codex-rollout -p codex-rollout-trace -p codex-mcp-server` - `cargo test -p codex-core --test all suite::items` - `just fix -p codex-protocol -p codex-app-server-protocol -p codex-core -p codex-rollout -p codex-rollout-trace -p codex-mcp-server` - Earlier coverage on this PR also included `codex-mcp`, `codex-tui`, core library tests, MCP/plugin/delegate/review/agent job tests, and MCP startup TUI tests.
pakrym-oai ·
2026-04-30 20:03:26 -07:00 -
Surface admin-disabled remote plugin status (#20298)
## Summary Remote plugin-service returns plugin availability separately from a user's installed/enabled state. This adds `PluginAvailabilityStatus` to the app-server protocol, propagates remote catalog `status` into `PluginSummary`, and rejects install attempts for remote plugins marked `DISABLED_BY_ADMIN` before downloading or caching the bundle. This is the `openai/codex` half of the change. The companion `openai/openai` webview PR is https://github.com/openai/openai/pull/873269. ## Validation - `cargo run -p codex-app-server-protocol --bin write_schema_fixtures` - `cargo test -p codex-app-server --test all plugin_list_marks_remote_plugin_disabled_by_admin` - `cargo test -p codex-app-server --test all plugin_list_includes_remote_marketplaces_when_remote_plugin_enabled` - `cargo test -p codex-app-server --test all plugin_install_rejects_remote_plugin_disabled_by_admin_before_download` - `cargo test -p codex-app-server-protocol schema_fixtures`
xli-oai ·
2026-04-30 20:00:07 -07:00 -
feat(tui): add vim composer mode (#18595)
## Why Codex now has configurable TUI keymaps, but the composer still behaves like a plain text field. Users who prefer modal editing need a way to keep Vim muscle memory while drafting prompts, and the keymap picker needs to expose Vim-specific actions if those bindings are configurable instead of hardcoded. ## What Changed - Adds composer Vim mode with insert/normal state, common normal-mode movement and editing commands, `d`/`y` operator-pending flows, and mode-aware footer and cursor indicators. - Adds `/vim`, an optional global `toggle_vim_mode` binding, and `tui.vim_mode_default` so Vim mode can be toggled per session or enabled as the default composer state. - Extends runtime and config keymaps with `vim_normal` and `vim_operator` contexts, exposes those contexts in `/keymap`, refreshes the config schema, and validates Vim bindings separately. - Integrates Vim normal mode with existing composer behavior: `/` opens slash command entry, `!` enters shell mode, `j`/`k` navigate history at history boundaries, successful submissions reset back to normal mode, and paste burst handling remains insert-mode only. - Teaches the TUI render path to apply and restore cursor style so Vim insert mode can use a bar cursor without leaving the terminal in that state after exit. ## Validation - `cargo test -p codex-tui keymap -- --nocapture` on the keymap/Vim coverage - `cargo insta pending-snapshots` ## Docs This introduces user-facing `/vim`, `tui.vim_mode_default`, and Vim keymap contexts under `tui.keymap`, so the public CLI configuration and slash-command docs should be updated before the feature ships.
Felipe Coury ·
2026-04-30 17:20:51 -07:00 -
fix(tui): set persist_extended_history: false (#20502)
Large rollouts are no good. This updates the TUI to behave the same as the Codex App, which is also turning it off.
Owen Lin ·
2026-04-30 23:31:31 +00:00 -
xl-openai ·
2026-04-30 14:26:14 -07:00 -
fix: show correct Bedrock runtime endpoint in /status (#20275)
## Why `/status` was showing the configured `ModelProviderInfo.base_url` for Amazon Bedrock, which can be stale or misleading because the actual Bedrock Mantle endpoint is derived at runtime from the resolved AWS region. This made sessions report the wrong provider endpoint even though requests used the correct runtime URL. ## What changed - Added `ModelProvider::runtime_base_url()` so provider implementations can expose the request-time base URL through the shared runtime provider abstraction. - Moved Bedrock region-to-Mantle URL resolution into `amazon_bedrock::mantle::runtime_base_url()`, keeping region resolution private to the Mantle module. - Overrode `runtime_base_url()` for Amazon Bedrock so it returns the resolved Mantle endpoint instead of the configured default. - Resolved and cached the runtime provider base URL during TUI startup, then used that cached value when rendering `/status`. - Added status coverage that verifies Bedrock displays the runtime URL and ignores the configured Bedrock `base_url` when they differ. ## Verification model provider is resolved correctly in local build: <img width="696" height="245" alt="Screenshot 2026-04-29 at 5 01 36 PM" src="https://github.com/user-attachments/assets/a13c10a5-3720-41ab-8ace-3c4bc573f971" />
Celia Chen ·
2026-04-30 19:02:34 +00:00 -
Add /hooks browser for lifecycle hooks (#19882)
## Why `hooks/list` and `hooks/config/write` give us read/write access to hooks and their state. This hooks up the TUI as a client so users can inspect and manage that state directly. ## What - add a two-page `/hooks` browser in the TUI: an event overview with installed/active counts, followed by a per-event handler page with toggle controls and detail rendering - thread managed-state metadata through hook discovery and `hooks/list` so the UI can label admin-managed hooks and suppress toggles for them - persist hook toggles through the existing config-write path and add snapshot coverage for the event list, handler list, managed-hook, and empty states ## Stack 1. openai/codex#19705 2. openai/codex#19778 3. openai/codex#19840 4. This PR - openai/codex#19882 ## Reviewer Notes - Main UI logic is in `codex-rs/tui/src/bottom_pane/hooks_browser_view.rs`; most of the diff is the new view plus its snapshot coverage - Request / write plumbing for opening the browser and persisting toggles is in `codex-rs/tui/src/app/background_requests.rs` and `codex-rs/tui/src/chatwidget/hooks.rs` - Outside the TUI, the only behavioral change in this PR is threading `is_managed` through hook discovery and `hooks/list` so managed hooks render as non-toggleable - The `codex-rs/tui/src/status/snapshots/` churn is unrelated merge fallout from the stacked base branch's newer permission-label rendering --------- Co-authored-by: Codex <noreply@openai.com>
Abhinav ·
2026-04-30 11:58:27 -07:00 -
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`
Eric Traut ·
2026-04-30 11:34:34 -07:00 -
Remove core protocol dependency [1/2] (#20324)
## Why This stack moves `codex-tui` away from the core protocol event surface and toward app-server API shapes plus TUI-owned local models. This first PR sets up the lower-risk foundation: it introduces the local model surface and extracts app-server event routing into focused TUI modules while preserving the existing behavior for the larger migration in PR2. This PR is part 1 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 - Added TUI-owned approval, diff, session state, session resume, token usage, and user-message models. - Added `app/app_server_event_targets.rs` and `app/app_server_events.rs` to hold app-server event targeting and dispatch logic outside `app.rs`. - Updated app/status tests to use the local model layer and added focused routing coverage. - Boxed a few large async TUI test futures so this base layer remains checkable without overflowing the default test stack. ## Verification - `cargo check -p codex-tui --tests`
Eric Traut ·
2026-04-30 10:52:19 -07:00 -
/plugins: remove marketplace (#19843)
This PR adds marketplace removal to the /plugins menu, giving users a way to remove user-configured plugin marketplaces. It adds a `Ctrl+R` shortcut to remove selected marketplace tabs, a confirmation prompt, loading and error states, and the app-server request flow needed to perform marketplace/remove. After a successful removal, the TUI refreshes config, plugin mentions, user config, and plugin data so the removed marketplace disappears from the menu and other surfaces in the TUI. - Add `Ctrl+R` removal option for user-configured marketplace tabs - Show marketplace removal confirmation, loading, and error states - Route `marketplace/remove` through the TUI background request flow - Refresh config, plugin mentions, and plugin data after successful removal - Adds reusable per-tab footer hints so removal guidance only appears on applicable tabs - Add test coverage for `Ctrl+R` behavior while plugin search is active Steps to test: - Add a marketplace using the TUI /plugins menu - Use Ctrl+R to remove the marketplace - Accept the confirmation prompt - Confirm the marketplace is removed when the process completes.
canvrno-oai ·
2026-04-30 10:25:07 -07:00 -
realtime: rename provider session ids (#20361)
## Summary Codex is repurposing `session` to mean a thread group, so the realtime provider session id should no longer use `session_id` / `sessionId` in Codex-facing protocol payloads. This PR renames that provider-specific field to `realtime_session_id` / `realtimeSessionId` and intentionally breaks clients that still send the old field names. ## What Changed - Renamed realtime provider session fields in `ConversationStartParams`, `RealtimeConversationStartedEvent`, and `RealtimeEvent::SessionUpdated`. - Renamed app-server v2 realtime request and notification fields to `realtimeSessionId`. - Removed legacy serde aliases for `session_id` / `sessionId`; clients must send the new names. - Propagated the rename through core realtime startup, app-server adapters, codex-api websocket handling, and TUI realtime state. - Regenerated app-server protocol schema/TypeScript outputs and updated app-server README examples. - Kept upstream Realtime API concepts unchanged: provider `session.id` parsing and `x-session-id` headers still use the upstream wire names. ## Testing - CI is running on the latest pushed commit. - Earlier local verification on this PR: - `cargo test -p codex-protocol` - `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-core realtime_conversation` - `cargo test -p codex-app-server-protocol` - `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-app-server realtime_conversation` - attempted `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-tui` (local linker bus error while linking the test binary) --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-30 13:39:48 +03:00 -
Michael Bolin ·
2026-04-29 20:54:59 -07:00 -
tui: return from side chat on Ctrl-D (#20282)
## Why Fixes #20264. Side conversations are an ephemeral layer on top of the main chat. Pressing `Ctrl+D` from an empty side-chat composer should unwind back to the parent thread, matching the existing side-return behavior, instead of falling through to the global quit shortcut and exiting Codex. ## What changed The side-return shortcut matcher now treats `Ctrl+D` the same way it already treats `Esc` and `Ctrl+C`. Because app-level side-return handling runs before the chat widget's global quit handling, this returns from `/side` while preserving normal `Ctrl+D` quit behavior outside side conversations. The existing shortcut coverage was updated to include lowercase and uppercase `Ctrl+D` key events. ## Verification - `cargo test -p codex-tui side_return_shortcuts_match_esc_ctrl_c_and_ctrl_d` - `cargo test -p codex-tui` starts successfully and the new shortcut test passes, but the broader suite later aborts in the unrelated existing test `app::tests::attach_live_thread_for_selection_rejects_unmaterialized_fallback_threads` with a stack overflow.
Eric Traut ·
2026-04-29 17:26:11 -07:00 -
Reduce the surface of collaboration modes (#20149)
Collaboration modes were slightly invasive both into ThreadManager construction and ModelProvider
pakrym-oai ·
2026-04-29 17:22:41 -07:00 -
Update Codex login success page UX (#20136)
## Summary update the local login success page to match the Codex desktop auth UX use theme-aware colors and an inline 20px Codex mark keep the actual localhost success page aligned with the browser auth UX PR ## Tests <img width="1728" height="1117" alt="Screenshot 2026-04-29 at 12 00 34 PM" src="https://github.com/user-attachments/assets/76a40c3f-07c3-452c-97da-e7c43717cd2c" />
rafael-jac ·
2026-04-29 19:14:53 -04:00 -
[mcp] Fix plugin MCP approval policy. (#19537)
Plugin MCP servers are loaded from plugin manifests rather than top-level `[mcp_servers]`, so their tool approval preferences need to be stored and applied through the owning plugin config. Without this, choosing "Always allow" for a plugin MCP tool could write a preference that was not reliably used on later tool calls. ## Summary - Add plugin-scoped MCP policy config under `plugins.<plugin>.mcp_servers`, including server enablement, tool allow/deny lists, server defaults, and per-tool approval modes. - Overlay plugin MCP policy onto manifest-provided server configs when plugins are loaded. - Route persistent "Always allow" writes for plugin MCP tools back to the owning `plugins.<plugin>.mcp_servers.<server>.tools.<tool>` config entry. - Reload user config after persisting an approval and make the plugin load cache config-aware so stale plugin MCP policy is not reused after `config.toml` changes. - Regenerate the config schema and add coverage for plugin MCP policy loading, approval lookup, persistence, and stale-cache prevention. ## Testing - `cargo test -p codex-config` - `cargo test -p codex-core-plugins` - `cargo test -p codex-core --lib plugin_mcp`
Matthew Zeng ·
2026-04-29 15:40:03 -07:00 -
Include auto-review rollout in feedback uploads (#20064)
## Summary - include the live auto-review trunk rollout when `/feedback` uploads logs - upload that attachment as `auto-review-rollout-<parent-thread-id>.jsonl` so it is distinguishable from the parent rollout - show the same auto-review attachment name in the TUI consent popup ## Scope - this only covers the live cached auto-review trunk for the current parent thread - it does not add durable historical parent->auto-review lookup - it does not add persisted rollout support for ephemeral parallel review forks ## UI <img width="599" height="185" alt="Screenshot 2026-04-28 at 1 17 18 PM" src="https://github.com/user-attachments/assets/6a0e79c2-5d21-4702-8a89-f765778bc9e9" /> ## Validation - `cargo test -p codex-core cached_guardian_subagent_exposes_its_rollout_path` - `cargo test -p codex-feedback` - `cargo test -p codex-app-server` - `cargo test -p codex-tui feedback_upload_consent_popup_snapshot` - `cargo test -p codex-tui feedback_good_result_consent_popup_includes_connectivity_diagnostics_filename` ## Known unrelated local failures - `cargo test -p codex-core` currently fails in the pre-existing proxy env snapshot test `tools::runtimes::tests::maybe_wrap_shell_lc_with_snapshot_keeps_user_proxy_env_when_proxy_inactive` - `cargo test -p codex-tui` currently hits pre-existing `status::*` snapshot drift unrelated to this change ## Follow-Up - persist parallel auto-review fork sessions so /feedback can include their rollout history too - attach each persisted fork as its own clearly named file, for example auto-review-rollout-<parent-thread-id>-fork <n>.jsonl, instead of merging multiple Guardian sessions into one attachment - keep the same live-session-only scope initially; durable historical parent -> auto-review lookup can remain a separate decision if we later need feedback from resumed sessions
Won Park ·
2026-04-29 11:44:55 -07:00 -
TUI: Remove core protocol dependency [3/7] (#20174)
## Why This is part 3 of a 7-PR stack to remove direct `codex_protocol::protocol` usage from `codex-tui` while keeping each layer reviewable and shippable. With `AppCommand` now explicit, the internal app event bus can carry TUI commands directly instead of bouncing through core `Op` values. ## What changed - Changed `AppEvent::CodexOp` and `AppEvent::SubmitThreadOp` to carry `AppCommand`. - Updated app-event senders and direct emitters to submit `AppCommand` values. - Adjusted tests to match `AppCommand` or convert back through `into_core()` where they intentionally assert legacy payload equality. ## Verification - `cargo test -p codex-tui --no-run`
Eric Traut ·
2026-04-29 10:52:10 -07:00 -
TUI: Remove core protocol dependency [2/7] (#20173)
## Why This is part 2 of a 7-PR stack to remove direct `codex_protocol::protocol` usage from `codex-tui` while keeping each layer reviewable and shippable. Before the TUI event bus can stop carrying core `Op` values, `AppCommand` needs to be an owned TUI command shape rather than a thin wrapper around `Op`. ## What changed - Replaced the opaque `AppCommand(Op)` wrapper with explicit owned variants for the commands the TUI submits. - Preserved `into_core()` so this layer does not yet change the app/thread submission boundary. - Kept existing core leaf types for now so this remains a mechanical command-shape refactor. ## Verification - `cargo check -p codex-tui`
Eric Traut ·
2026-04-29 10:28:04 -07:00 -
TUI: Remove core protocol dependency [1/7] (#20172)
## Why This is part 1 of a 7-PR stack to remove direct `codex_protocol::protocol` usage from `codex-tui` while keeping each layer reviewable and shippable. This first layer reduces the size of the later `chatwidget` diff by mechanically moving MCP startup bookkeeping out of the central widget file without changing the event shapes or behavior. ## What changed - Extracted MCP startup status handling into `tui/src/chatwidget/mcp_startup.rs`. - Kept the existing core event types in place for this purely mechanical move. - Updated the MCP startup tests to import the moved test-only event types directly. ## Verification - `cargo test -p codex-tui chatwidget::tests::mcp_startup`
Eric Traut ·
2026-04-29 09:10:22 -07:00 -
Use /goal resume for paused goals (#20082)
## Why The paused goal statusline currently points users at `/goal` to unpause a goal, but bare `/goal` is the summary command and does not change the goal state. Instead of making `/goal` mutate state only when a goal is paused, this gives the action an explicit command that reads naturally in the UI. ## What Changed - Replace `/goal unpause` with `/goal resume` for reactivating a paused goal. - Update the paused goal statusline and `/goal` summary copy to point at `/goal resume`.
Eric Traut ·
2026-04-29 08:56:02 -07:00 -
chore(cli) deprecate --full-auto (#20133)
## Summary Starts the process of getting rid of `--full-auto`, with some concessions: 1. Fully removes the command from the tui, since it just resolves to the default permissions there, and encourages users to use the one-time trust flow if they're not in a trusted repo. 2. Marks the command as deprecated in `codex exec`, in case users are actively relying on this. We'll remove in an upcoming n+X release. 3. Cleans up some of the `codex sandbox` cli logic, to keep supporting legacy sandbox policies for now. This isn't the cleanest setup, but I think it is worthwhile to warn users for one release before hard-removing it. ## Testing - [x] Updated unit tests
Dylan Hurd ·
2026-04-29 04:41:30 +00:00 -
Add environment provider snapshot (#20058)
## Summary - Change `EnvironmentProvider` to return concrete `Environment` instances instead of `EnvironmentConfigurations`. - Make `DefaultEnvironmentProvider` provide the provider-visible `local` environment plus optional `remote` environment from `CODEX_EXEC_SERVER_URL`. - Keep `EnvironmentManager` as the concrete cache while exposing its own explicit local environment for `local_environment()` fallback paths. ## Validation - `just fmt` - `git diff --check` --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-04-28 20:05:18 -07:00 -
Soften skill description budget warnings (#20112)
Updates skill description budget messaging to be less alarming
xl-openai ·
2026-04-28 19:56:25 -07:00 -
Restore TUI working status after steer message is set (#19939)
Fix for #19925 Restore the `Working` indicator after a streamed final answer finishes when a user steer message is sent. Add regression coverage for long output plus a mid-stream steer: `cargo test -p codex-tui final_answer_completion_restores_status_indicator_for_pending_steer` Duplication/testing steps: 1. Start a new thread and ask for a long response. 2. While the response is streaming, submit a steer message. 3. When the first response finishes, observe whether `Working...` is shown while waiting for the steer message response.
canvrno-oai ·
2026-04-28 18:10:40 -07:00 -
Support detect and import MCP, Subagents, hooks, commands from external (#19949)
## Why This PR expands the migration path so Codex can detect and import MCP server config, hooks, commands, and subagents configs in a Codex-native shape. ## What changed - Added a `codex-external-agent-migration` crate that owns conversion logic for external-agent MCP servers, hooks, commands, and subagents. - Extended the app-server external-agent config detection/import API with migration item types for MCP server config, hooks, commands, and subagents. ## Migration strategy The migration is intentionally conservative: Codex only imports external-agent config that can be represented safely in Codex today. Unsupported or ambiguous config is skipped instead of being partially translated into behavior that may not match the source system. - **MCP servers**: import supported stdio and HTTP MCP server definitions into `mcp_servers`. Disabled servers and servers filtered out by source `enabledMcpjsonServers` / `disabledMcpjsonServers` are skipped. Project-scoped MCP entries from `.claude.json` are included when they match the repo path. - **Hooks**: import only supported command hooks into `.codex/hooks.json`. Unsupported hook features such as conditional groups, async handlers, prompt/http hooks, or unknown fields are skipped. Referenced hook scripts are copied into `.codex/hooks/`, preserving any existing target scripts. - **Commands**: import supported external commands as Codex skills under `.agents/skills/source-command-*`. Commands that rely on source runtime expansion such as `$ARGUMENTS`, `$1`, `@file` references, shell interpolation, or colliding generated names are skipped. - **Subagents**: import valid subagent Markdown files into `.codex/agents/*.toml` when they have the minimum Codex agent fields. Source model names are not migrated, so imported agents keep the user’s Codex default model; compatible reasoning effort and sandbox mode are migrated when present. - **Skills and project guidance**: copy missing skill directories into `.agents/skills` and migrate `CLAUDE.md` guidance into `AGENTS.md`, rewriting source-agent terminology to Codex terminology where appropriate. - **Detection details**: detected migration items include lightweight details for UI preview, such as MCP server names, hook event names, generated command skill names, and subagent names. Import still recomputes from disk instead of trusting details as the source of truth. - Adds focused coverage for the new migration behavior and app-server import flow. ## Verification - `cargo test -p codex-external-agent-migration` - `cargo test -p codex-hooks` - `cargo test -p codex-app-server external_agent_config` - `just bazel-lock-check`
alexsong-oai ·
2026-04-29 00:45:24 +00:00 -
app-server: notify clients of remote-control status changes (#19919)
## Why Remote-control app-server enrollments have both an internal server id and the environment id exposed to remote-control clients. App-server clients need one current status snapshot that says whether remote control is usable and which environment id, if any, is exposed. A temporary websocket disconnect is not itself an identity change. Account changes, stale enrollment invalidation, successful re-enrollment, and missing ChatGPT auth are meaningful status changes. Disabled remote control remains `disabled` regardless of auth or SQLite state. SQLite startup failure disablement and enrollment persistence failures are handled in #20068; this PR reports the resulting effective status to clients. ## What changed - Adds v2 `remoteControl/status/changed` carrying `state` and `environmentId`. - Adds `RemoteControlConnectionState` values: `disabled`, `connecting`, `connected`, and `errored`. - Exposes remote-control status updates through `RemoteControlHandle` using a Tokio watch channel. - Always sends the current remote-control status snapshot to newly initialized app-server clients. - Broadcasts status changes to initialized app-server clients when state or environment id changes. - Treats missing ChatGPT auth as an `errored` status while leaving it retryable because auth can change at runtime. - Clears `environmentId` when enrollment is cleared for account changes, auth loss, stale backend invalidation, or disabled remote control. - Updates app-server protocol schema fixtures, generated TypeScript, app-server README, remote-control tests, and TUI exhaustive notification matches. ## Stack - Builds on #20068. ## Verification - `just write-app-server-schema` - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-app-server transport::remote_control --lib` - `cargo check -p codex-tui` - `just fix -p codex-app-server-protocol` - `just fix -p codex-app-server` - `just fix -p codex-tui`
Ruslan Nigmatullin ·
2026-04-28 23:52:14 +00:00 -
core tests: submit turns with permission profiles (#20010)
## Summary - Add `PermissionProfile`-based turn submission helpers to `core_test_support`, while keeping the legacy `SandboxPolicy` helper for tests that intentionally exercise legacy fallback behavior. - Switch the default `TestCodex::submit_turn()` path to send a real `PermissionProfile` plus the required legacy compatibility projection in `Op::UserTurn`. - Migrate straightforward app/search/shell/truncation tests from `SandboxPolicy::{DangerFullAccess, ReadOnly}` to `PermissionProfile::{Disabled, read_only}`. - Add a TUI compatibility projection helper for legacy app-server fields so non-legacy writable roots are preserved instead of being downgraded to read-only. - Fix remote start/resume/fork sandbox-mode projection to classify any managed profile with writable roots as workspace-write, not only profiles that can write `cwd`. - Reduce `SandboxPolicy` references in `codex-rs/core/tests` from 47 files to 41 files without changing production behavior. ## Testing - `cargo check -p codex-core --tests` - `cargo test -p codex-tui compatibility_profile_preserves_unbridgeable_write_roots` - `cargo test -p codex-tui sandbox_mode_preserves_non_cwd_write_roots_for_remote_sessions` - `just fmt` - `just fix -p core_test_support` - `just fix -p codex-core`Michael Bolin ·
2026-04-28 23:01:40 +00:00 -
/plugins: add marketplace install flow (#18704)
This PR adds a new feature to the `/plugins` menu that gives users the ability to add new plugin marketplaces. It introduces an Add Marketplace tab to the right of installed marketplaces, a source prompt, loading and error states, and the app-server request flow needed to perform the install. After a successful `marketplace/add`, the popup refreshes back into the newly added marketplace tab so the new plugins are immediately visible. - Add an Add Marketplace tab to the `/plugins` menu - Prompt for marketplace source input from git repo, URL, or local path - Show loading and error states during `marketplace/add` - Refresh plugin data after success and switch into the newly added marketplace tab - Add tests and snapshot updates
canvrno-oai ·
2026-04-28 14:22:39 -07:00 -
tui: use permission profiles for sandbox state (#20008)
## Summary - Move TUI permission state from legacy `SandboxPolicy` values to canonical `PermissionProfile` values across presets, app events, chat widget state, app commands, thread routing, and cached thread session state. - Keep app-server compatibility boundaries explicit: embedded sessions send `permissionProfile`, while remote sessions send only a legacy `sandbox` projection and fall back to read-only when a custom profile cannot be projected. - Update status/add-dir UI summaries and snapshots to render the active permission profile, including workspace profiles selected by the new built-in defaults. ## Verification - `rg '\bSandboxPolicy\b' codex-rs/tui -n` returns no matches. - `cargo test -p codex-tui` - `cargo check -p codex-tui --tests` - `cargo test -p codex-tui additional_dirs` - `just fmt` - `just fix -p codex-tui` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/20008). * #20041 * #20040 * #20037 * #20035 * #20034 * #20033 * #20032 * #20030 * #20028 * #20027 * #20026 * #20024 * #20021 * #20018 * #20016 * #20015 * #20013 * #20011 * #20010 * __->__ #20008
Michael Bolin ·
2026-04-28 20:36:48 +00:00 -
Fix plan mode nudge test after task completion signature change (#20045)
Updates the plan mode nudge test to pass the new `duration_ms` argument to task completion. Co-authored-by: Codex <noreply@openai.com>
canvrno-oai ·
2026-04-28 11:24:22 -07:00 -
External agent session support (#19895)
## Summary This extends external agent detection/import beyond config artifacts so Codex can detect recent sessions files from the external agent home and import them into Codex rollout history. ## What changed - Added a focused `external_agent_sessions` module for: - session discovery - source-record parsing - rollout construction - import ledger tracking - Wired session detection/import into the app-server external agent config API. - Added compaction handling so large imported sessions can be resumed safely before the first follow-up turn. ## Testing Added coverage for: - recent-session detection - custom-title handling - recency filtering - dedupe and re-detect-after-source-change behavior - visible imported turn construction - backward-compatible import payload deserialization - end-to-end RPC import flow - rejection of undetected session paths - repeat-import behavior - large-session compaction before first follow-up Ran: - `cargo test -p codex-app-server external_agent_config_import_ --test all`
stefanstokic-oai ·
2026-04-28 17:42:36 +00:00 -
fix(tui): let esc exit empty shell mode (#19986)
## Summary - exit shell mode when `Esc` is pressed while the absorbed `!` is the only input - add direct regression coverage plus a composer snapshot for the restored normal prompt state ## Root cause Shell mode stores the leading `!` outside the editable textarea. After typing only `!`, the textarea is empty but the composer is still in bash mode, so the existing empty-composer `Esc` handling never runs. ## Validation - `just fmt` - `cargo test -p codex-tui bottom_pane::chat_composer::tests::esc_exits_empty_shell_mode` - `cargo test -p codex-tui bottom_pane::chat_composer::tests::footer_mode_snapshots` - `cargo insta pending-snapshots` `cargo test -p codex-tui` still reports unrelated existing `/status` snapshot drift in this local environment because the rendered permissions text is `workspace-write with network access` instead of the older `read-only` fixture text.
Felipe Coury ·
2026-04-28 14:35:24 -03:00 -
Move local /resume cwd filtering into thread/list (#19931)
Move local resume and fork cwd filtering to `thread/list` instead of filtering in the TUI. This makes the `/resume` menu feel slightly faster to load when working in repos with many historical threads, and centralizes the cwd filtering in app-server. **Affected:** - /resume from inside the TUI. - codex resume with no session ID and without --last - codex resume --all - codex fork with no session ID and without --last - codex fork --all **Not affected:** - codex resume <id> - codex fork <id> - codex resume --last - codex fork --last Steps to test performance improvement in a real Codex environment: - Launch `codex resume` using compiled binary in a directory that has seen many threads. - Launch `codex resume` using release binary in same directory. - Observe difference in time-to-full-page as threads load.
canvrno-oai ·
2026-04-28 10:35:10 -07:00 -
feat(tui): suggest plan mode from composer drafts (#19901)
## Summary - suggest Plan mode when the current composer draft contains the standalone word `plan` - shares the Codex App heuristics for detection - excludes things line `/plan` and the word plan in shell mode - reuse the existing `Shift+Tab` mode cycle and add thread-scoped dismissal with `Esc` - replace the normal footer hint while the reminder is visible so the statusline stays anchored https://github.com/user-attachments/assets/01123ae8-cee6-4e95-b563-44655c071cde ## Why The desktop app already nudges users toward Plan mode when their draft clearly signals planning intent. The TUI had the underlying `/plan` and `Shift+Tab` flows, but no equivalent reminder at the moment the user was most likely to benefit from them. ## Details The reminder is shown only when Plan mode is available, the draft contains standalone `plan`, the user is not already in Plan mode, the composer is actionable, and the current thread has not dismissed the reminder. Slash-command and shell-command drafts are excluded. The first implementation used an extra composer row, but that moved the statusline whenever the heuristic fired. This version keeps the layout stable by rendering the reminder in the existing footer row instead. ## Validation - `INSTA_UPDATE=always cargo test -p codex-tui chatwidget::tests::plan_mode::plan_mode_nudge -- --nocapture` - `just fmt` - `just fix -p codex-tui` - `./tools/argument-comment-lint/run.py -p codex-tui` - `cargo insta pending-snapshots` - `git diff --check`
Felipe Coury ·
2026-04-28 14:34:10 -03:00 -
efrazer-oai ·
2026-04-28 09:56:20 -07:00 -
TUI: use cumulative turn duration for worked-for separator (#19929)
## Why Fixes #19814. The TUI's current `Worked for ...` timing behavior is a leftover from #9599. At that point, models could emit multiple assistant messages in one turn for preambles/commentary, but the TUI did not yet have a reliable signal that an assistant message was the final answer when it started streaming. To avoid showing an ever-growing elapsed time on each preamble separator, #9599 made the separator timer incremental by tracking elapsed time since the previous separator. That workaround is no longer the right model for the final completed-turn display. Since then, #16638 added protocol-native turn timing, including `duration_ms` on turn completion. With that cumulative duration available at the point where the TUI renders the completed-turn separator, the UI can show the actual turn duration directly instead of carrying per-separator timing state. ## What Changed - Thread `duration_ms` into `ChatWidget::on_task_complete` from both legacy `TurnCompleteEvent` handling and app-server `TurnCompleted` notifications. - Use `duration_ms` for the final `Worked for ...` separator, falling back to the status indicator timer only when the protocol duration is unavailable. - Keep mid-turn separators before later assistant text as plain visual dividers instead of clocked `Worked for ...` separators. - Remove the old incremental separator timer state and helper (`last_separator_elapsed_secs` / `worked_elapsed_from`). - Add a snapshot regression test for a turn that runs a command and then completes with a final answer, verifying the final separator uses the cumulative turn duration. ## Verification - `cargo test -p codex-tui final_worked_for_uses_cumulative_turn_duration_snapshot` - `just fix -p codex-tui` Manual repro prompt: ```text Manual timing repro. First send a short preamble/commentary sentence before using tools. Then run exactly this shell command: sleep 75; echo MANUAL_TIMING_DONE. After the command finishes, give a final answer that says "done". Do not skip the preamble. ``` After this change, the mid-turn break before the final answer should be a plain divider, and the final completed-turn separator should show `Worked for ...` using the cumulative turn duration. Before: <img width="414" height="102" alt="Screenshot 2026-04-27 at 10 09 01 PM" src="https://github.com/user-attachments/assets/b9e2ce01-2460-40e4-a5c4-c9ba8add2557" /> After: <img width="485" height="149" alt="Screenshot 2026-04-27 at 10 09 07 PM" src="https://github.com/user-attachments/assets/d24089ae-d4e2-41b6-b966-07c98706ead4" />
Eric Traut ·
2026-04-28 09:24:29 -07:00 -
feat(tui): add configurable keymap support (#18593)
## Why The TUI currently handles keyboard shortcuts as hard-coded event matches spread across app, composer, pager, list, approval, and navigation code. That makes shortcuts hard to customize, makes displayed hints easy to drift from actual behavior, and makes future keymap work riskier because there is no central action inventory. This PR adds the foundation for configurable, action-based keymaps without adding the interactive remapping UI yet. Onboarding intentionally stays on fixed startup shortcuts because users cannot reasonably configure keymaps before completing onboarding. This is PR1 in the keymap stack: - PR1: #18593: configurable keymap foundation - PR2: #18594: `/keymap` picker and guided remapping UI - PR3: #18595: Vim composer mode and the remap option ## Design Notes The new model resolves named actions into concrete runtime bindings once from config, then passes those bindings to the UI surfaces that handle input or render shortcut hints. The main concepts are: - **Context**: a scope where an action is active, such as `global`, `chat`, `composer`, `editor`, `pager`, `list`, or `approval`. - **Action**: a named operation inside a context, such as `global.open_transcript`, `composer.submit`, or `pager.close`. - **Binding**: one or more single-key shortcuts assigned to an action, written as config strings such as `ctrl-t`, `alt-backspace`, or `page-down`. Multi-step sequences such as `ctrl-x ctrl-s`, `g g`, or leader-key flows are not part of this PR. - **Resolution order**: context-specific config wins first, supported global fallbacks come next, and built-in defaults fill in anything unset. - **Explicit unbinding**: an empty array removes an action binding in that scope and does not fall through to a fallback binding. - **Conflict validation**: a resolved keymap rejects duplicate active bindings inside the same scope so one keypress cannot dispatch two actions. ## What Changed - Added `TuiKeymap` config support under `[tui.keymap]`, including typed contexts/actions, key alias normalization, generated schema coverage, and user-facing config errors. - Added `RuntimeKeymap` resolution in `codex-rs/tui/src/keymap.rs`, including fallback precedence, built-in defaults, explicit unbinding, and per-context conflict validation. - Rewired existing TUI handlers to consume resolved keymap actions instead of directly matching hard-coded keys in each component. - Updated key hint rendering and footer/pager/list surfaces so displayed shortcuts follow the resolved keymap. - Kept onboarding shortcuts fixed in `codex-rs/tui/src/onboarding/keys.rs` instead of exposing them through `[tui.keymap]`. ## Validation The branch includes focused coverage for config parsing, key normalization, runtime fallback resolution, explicit unbinding, duplicate-key conflict validation, default keymap consistency, onboarding startup key behavior, and UI hint snapshots affected by resolved key bindings.
Felipe Coury ·
2026-04-28 12:52:25 -03:00 -
Reset TUI keyboard reporting on exit (#19625)
## Why Codex enables enhanced keyboard reporting while the TUI owns the terminal. In iTerm2, exiting the TUI with Ctrl+C can intermittently leave the parent shell receiving raw CSI-u / `modifyOtherKeys` fragments instead of normal key input. Final terminal cleanup should put the parent shell back into normal keyboard reporting even if the terminal misses the usual stack pop. Fixes #19553. ## What Changed - Move TUI keyboard enhancement setup and detection into `tui/src/tui/keyboard_modes.rs`. - Add an exit-only `restore_after_exit()` path that performs the normal keyboard enhancement pop plus unconditional keyboard enhancement and `modifyOtherKeys` resets. - Keep temporary restore paths, such as external-editor handoff, using the balanced stack pop behavior. ## Confidence Medium. This is a speculative fix: I was not able to reproduce the reported iTerm2 behavior manually, but the symptoms line up with terminal keyboard reporting state surviving Codex exit. The added reset sequences are scoped to final TUI shutdown and should be harmless when the terminal is already clean.
Eric Traut ·
2026-04-28 08:51:44 -07:00 -
Add
codex updatecommand (#19933)## Why Addresses #9274 Running `codex update` currently starts an interactive Codex session with `update` as the prompt. That is a rough edge for users who expect a direct self-update command after seeing the existing update notice, and it forces them to copy the suggested package-manager command manually. ## What changed - Added a top-level `codex update` subcommand. - Reused the existing install-channel detection and update command runner that the TUI already uses for update prompts. - Exposed the update-action lookup from `codex-tui` so the CLI can invoke the same behavior. - Added CLI coverage to ensure `codex update` is parsed as a subcommand instead of becoming an interactive prompt. ## Verification - `cargo test -p codex-cli` - `cargo test -p codex-tui update_action::tests`
Eric Traut ·
2026-04-27 23:33:59 -07:00 -
permissions: store thread sessions as profiles (#19776)
## Why After thread sessions have a required `PermissionProfile`, the TUI no longer needs to cache a separate legacy `SandboxPolicy` in `ThreadSessionState`. Keeping the legacy field would reintroduce two permission authorities in the session cache and make later replay/switching logic easier to get wrong. This PR keeps legacy app-server compatibility at the ingestion boundary: old `sandbox` response values are still accepted, but they are immediately converted to a cwd-anchored profile. ## What Changed - Removes `ThreadSessionState.sandbox_policy`. - Updates active-session permission syncing to write only the current `PermissionProfile`. - Updates thread-read/replay/test fixtures to use profiles as the cached session permission source. - Leaves legacy `sandbox` fields in app-server request/response protocol paths unchanged; those are compatibility boundaries and are converted before entering cached TUI state. ## Verification - `cargo test -p codex-tui thread_session_state::tests --lib` - `cargo test -p codex-tui inactive_thread_started_notification_initializes_replay_session --lib` - `cargo test -p codex-tui thread_events --lib` - `just fix -p codex-tui` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19776). * #19900 * #19899 * __->__ #19776
Michael Bolin ·
2026-04-28 05:49:58 +00:00 -
permissions: make SessionConfigured profile-only (#19774)
## Why `SessionConfiguredEvent` is the internal event that tells clients what permissions are active for a session. Emitting both `sandbox_policy` and `permission_profile` leaves two possible authorities and forces every consumer to decide which one to honor. At this point in the migration, the profile is expressive enough to represent managed, disabled, and external sandbox enforcement, so the internal event can be profile-only. The wire compatibility concern is older serialized events or rollout data that only contain `sandbox_policy`; those still need to deserialize. ## What Changed - Removes `sandbox_policy` from `SessionConfiguredEvent` and makes `permission_profile` required. - Adds custom deserialization so old payloads with only `sandbox_policy` are upgraded to a cwd-anchored `PermissionProfile`. - Updates core event emission and TUI session handling to sync permissions from the profile directly. - Updates app-server response construction to derive the legacy `sandbox` response field from the active thread snapshot instead of from `SessionConfiguredEvent`. - Updates yolo-mode display logic to treat both `PermissionProfile::Disabled` and managed unrestricted filesystem plus enabled network as full-access, while still preserving the distinction between no sandbox and external sandboxing. ## Verification - `cargo test -p codex-protocol session_configured_event --lib` - `cargo test -p codex-protocol serialize_event --lib` - `cargo test -p codex-exec session_configured --lib` - `cargo test -p codex-app-server thread_response_permission_profile_preserves_enforcement --lib` - `cargo test -p codex-core session_configured_reports_permission_profile_for_external_sandbox --lib` - `cargo test -p codex-tui session_configured --lib` - `cargo test -p codex-tui yolo_mode_includes_managed_full_access_profiles --lib` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19774). * #19900 * #19899 * #19776 * #19775 * __->__ #19774
Michael Bolin ·
2026-04-27 22:06:47 -07:00 -
Allow /statusline and /title slash commands during active turns (#19917)
- Marks `/title` and `/statusline` as available during active tasks. - Extends the existing slash-command availability test coverage to include these commands alongside `/goal`.
canvrno-oai ·
2026-04-27 20:57:20 -07:00 -
permissions: require profiles in TUI thread state (#19773)
## Why `ThreadSessionState` is the TUI's cached view of an app-server session. To make `PermissionProfile` the canonical runtime permissions model, cached thread sessions need to always have a profile instead of treating the profile as an optional supplement to a legacy `sandbox` response field. The main compatibility concern is older app-server v2 lifecycle responses that only include `sandbox` and omit `permissionProfile`: - `thread/start` -> `ThreadStartResponse.sandbox` - `thread/resume` -> `ThreadResumeResponse.sandbox` - `thread/fork` -> `ThreadForkResponse.sandbox` Those responses must still hydrate correctly when the TUI is pointed at an older app-server. This PR converts the legacy `sandbox` value into a `PermissionProfile` immediately at response ingestion time, using the response `cwd`, so cached sessions do not carry an optional profile that can later reinterpret cwd-bound grants against a different thread cwd. This fallback is intentionally boundary compatibility. The follow-up PRs in this stack continue the cleanup by making `SessionConfiguredEvent` profile-only, deriving sandbox projections from snapshots only when an API still needs them, and then removing `sandbox_policy` from `ThreadSessionState`. ## What Changed - Makes `ThreadSessionState.permission_profile` required. - Converts legacy app-server response `sandbox` values into a `PermissionProfile` at ingestion time using the response cwd. - Ensures `thread/read` hydration does not reuse a primary session profile that may be anchored to a different cwd; it uses the active widget permission settings for the read thread fallback instead of reusing cached primary-session permissions. - Keeps the app-server request path unchanged: embedded sessions send profiles, while remote sessions continue using legacy sandbox overrides for compatibility. ## Verification - `cargo test -p codex-tui thread_read --lib` - `cargo test -p codex-tui permission_settings_sync_preserves_active_profile_only_rules --lib` - `cargo test -p codex-tui resume_response_restores_turns_from_thread_items --lib` - `cargo test -p codex-tui thread_session_state::tests --lib` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19773). * #19900 * #19899 * #19776 * #19775 * #19774 * __->__ #19773
Michael Bolin ·
2026-04-27 20:39:06 -07:00 -
Remove ghost snapshots (#19481)
## Summary - Remove `ghost_snapshot` / `GhostCommit` from the Responses API surface and generated SDK/schema artifacts. - Keep legacy config loading compatible, but make undo a no-op that reports the feature is unavailable. - Clean up core history, compaction, telemetry, rollout, and tests to stop carrying ghost snapshot items. ## Testing - Unit tests passed for `codex-protocol`, `codex-core` targeted undo and compaction flows, `codex-rollout`, and `codex-app-server-protocol`. - Regenerated config and app-server schemas plus Python SDK artifacts and verified they match the checked-in outputs.
pakrym-oai ·
2026-04-27 18:48:57 -07:00