mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
b4f0f3eff1303ea445a218afb039e0079df0afce
7792 Commits
-
install WFP filters for Windows sandbox setup (#20101)
## Summary This PR installs a first wave of WFP (Windows Filtering Platform) filters that reduce the surface area of network egress vulnerabilities for the Windows Sandbox. - Add persistent Windows Filtering Platform provider, sublayer, and filters for the Windows sandbox offline account. - Install WFP filters during elevated full setup, log failures non-fatally, and emit setup metrics when analytics are enabled. - Bump the Windows sandbox setup version so existing users rerun full setup and receive the new filters. ## What WFP is Windows Filtering Platform (WFP) is the low-level Windows networking policy engine underneath things like Windows Firewall. It lets privileged code install persistent filtering rules at specific network stack layers, with conditions like "only traffic from this Windows account" or "only this remote port," and an action like block. In this change, we create a Codex-owned persistent WFP provider and sublayer, then install block filters scoped to the Windows sandbox's offline user account via `ALE_USER_ID`. That means the filters are targeted at sandboxed processes running as that account, rather than globally affecting the host. ## Initial filter set We are starting with 12 concrete WFP filters across a few high-value bypass surfaces. The table below describes the filter families rather than one filter per row: | Area | Concrete filters | Purpose | | --- | --- | --- | | ICMP | 4 filters: ICMP v4/v6 on `ALE_AUTH_CONNECT` and `ALE_RESOURCE_ASSIGNMENT` | Block direct ping-style network reachability checks from the offline account. | | DNS | 2 filters: remote port `53` on `ALE_AUTH_CONNECT_V4/V6` | Block direct DNS queries that bypass our intended proxy/offline path. | | DNS-over-TLS | 2 filters: remote port `853` on `ALE_AUTH_CONNECT_V4/V6` | Block encrypted DNS attempts that could bypass ordinary DNS interception. | | SMB / NetBIOS | 4 filters: remote ports `445` and `139` on `ALE_AUTH_CONNECT_V4/V6` | Block Windows file-sharing/network share traffic from sandboxed processes. | For IPv4/IPv6 coverage, the port-based filters are installed on both `ALE_AUTH_CONNECT_V4` and `ALE_AUTH_CONNECT_V6`. ICMP also gets both connect-layer and resource-assignment-layer coverage because ICMP traffic is shaped differently from ordinary TCP/UDP port traffic. ## Validation - `cargo fmt -p codex-windows-sandbox` (completed with existing stable-rustfmt warnings about `imports_granularity = Item`) - `cargo test -p codex-windows-sandbox wfp::tests` - `cargo test -p codex-windows-sandbox` (fails in existing legacy PowerShell sandbox tests because `Microsoft.PowerShell.Utility` could not be loaded; WFP tests passed before that failure)
iceweasel-oai ·
2026-04-30 12:39:01 -07:00 -
feat(rollouts): store EventMsg::ApplyPatchEnd in limited history mode (#20463)
The Codex App treats apply patch tool calls quite load-bearing in the UI (always shown on a completed turn), so we'd like to persist `EventMsg::ApplyPatchEnd` to guarantee that when a client reconnects to app-server mid-turn, we always have the full diff to display at the end of that turn.
Owen Lin ·
2026-04-30 12:11:02 -07:00 -
[codex] Fix elevated Windows sandbox named-pipe access (#20270)
## Summary - add elevated-only token constructors that include the current token user SID in the restricted SID list - switch the elevated Windows command runner to use those constructors - leave the unelevated restricted-token path unchanged ## Why Windows named pipes created by tools like Ninja use the platform's default named-pipe ACL when no explicit security descriptor is provided. In the elevated sandbox, the pipe owner has access, but the write-restricted token can still fail its restricted-SID access check because the sandbox user SID was not in the restricting SID set. That causes child processes to exit successfully while Ninja never receives the expected pipe completion/close behavior and hangs. Including the elevated sandbox user's SID in the restricting SID list lets the restricted check succeed for these owner-scoped pipe objects without broadening the unelevated sandbox to the real signed-in user. ## Impact - fixes the minimal Ninja hang repro in the elevated Windows sandbox - preserves the existing unelevated sandbox behavior and write protections - keeps the change scoped to the elevated runner rather than changing shared token semantics - this does not affect file-writes for the sandbox because the sandbox users themselves do not receive any additional permissions over what the capability SIDs already have. In fact we don't even explicitly grant the sandbox user ACLs anywhere. ## Validation - `cargo build -p codex-windows-sandbox --quiet` - verified the stock `ninja.exe` minimal repro exits normally on host and in the elevated sandbox - verified the same repro still hangs in the unelevated sandbox, which is the intended scope of this change
iceweasel-oai ·
2026-04-30 12:06:11 -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 -
[Codex] Add browser use external feature flag (#20245)
## Summary - Adds a separate feature control for external-browser Browser Use integrations. - Registers `browser_use_external` as a stable, default-enabled requirements-owned feature key. - Updates feature registry tests and regenerates the config schema. Codex validation: - `cargo fmt -- --config imports_granularity=Item` - `cargo run -p codex-core --bin codex-write-config-schema` - `cargo test -p codex-features` ## Addendum This gives enterprise policy a coarse control for Browser Use outside the Codex-managed in-app browser. The existing `browser_use` feature is the Browser Use control, while `browser_use_external` can gate extension/native integrations for external browsers as that surface grows
khoi ·
2026-04-30 11:53:19 -07:00 -
Stop emitting item/fileChange/outputDelta output delta notifications (#20471)
## Why `item/fileChange/outputDelta` text output was only the tool's summary or error text and not used by client surfaces. We keep `item/fileChange/outputDelta` in the app-server protocol as a deprecated compatibility entry, but the server no longer emits it. ## What changed - stop the `apply_patch` runtime from emitting `ExecCommandOutputDelta` events - simplify `item_event_to_server_notification` so command output deltas always map to `item/commandExecution/outputDelta` - remove the app-server bookkeeping that tried to detect whether an output delta belonged to a file change - mark `item/fileChange/outputDelta` as a deprecated legacy protocol entry in the v2 types, schema, and README - simplify the file-change approval tests so they only wait for completion instead of expecting output-delta notifications ## Testing - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-thread-manager-sample` - `cargo test -p codex-app-server-protocol protocol::event_mapping::tests::exec_command_output_delta_maps_to_command_execution_output_delta -- --exact` - `cargo test -p codex-app-server turn_start_file_change_approval_accept_for_session_persists_v2 -- --exact` *(failed before the test assertions because the wiremock `/responses` mock received 0 requests in setup)*
pakrym-oai ·
2026-04-30 11:42:07 -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 -
Move item event mapping into app-server-protocol (#20299)
## Why Follow-up to #20291. The v2 item-event-to-notification translation had been embedded in `app-server/src/bespoke_event_handling.rs`, which made it hard to reuse anywhere else. This PR moves that stateless mapping into shared protocol code so other entry points can produce the same `ServerNotification` payloads without copying app-server logic. That also lets `thread-manager-sample` demonstrate the same notification surface that the app server exposes, instead of only printing the final assistant message. ## What changed - move `item_event_to_server_notification` into `codex-app-server-protocol::protocol::event_mapping` - keep the mapper tests next to the shared implementation in `codex-app-server-protocol` - re-export the mapper from `codex-core-api` so lightweight consumers can use it without reaching into `app-server-protocol` directly - simplify `app-server/src/bespoke_event_handling.rs` so it delegates the stateless event-to-notification projection to the shared helper - update `thread-manager-sample` to: - print mapped notifications as newline-delimited JSON - use the shared mapper through `codex-core-api` - enable the default feature set so the sample exposes the normal tool surface - use a `read_only` permission profile so shell commands can run in the sample without widening permissions ## Testing - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-core-api` - `cargo test -p codex-app-server bespoke_event_handling::tests` - `cargo test -p codex-thread-manager-sample` - `cargo run -p codex-thread-manager-sample -- "briefly explore the repo with pwd and ls, then summarize it"`
pakrym-oai ·
2026-04-30 11:02:13 -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 -
[Extension] Allowlist Chrome Extension in the tool_suggest tool (#20458)
### Summary Allowlist chrome extension in tool_suggest tool ### Screenshot Allowlist chrome extension in tool_suggest tool <img width="808" height="309" alt="chrome_internal" src="https://github.com/user-attachments/assets/ed769d77-b635-4a40-a0c5-fbff05af3036" />
teddywyly-oai ·
2026-04-30 10:29:03 -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 -
Mark goals feature as experimental (#20083)
## Why The `goals` feature flag is ready to move out of the hidden under-development bucket and into the user-facing experimental surface. Marking it experimental lets users discover it through the experimental features UI while still making clear that it is opt-in. ## What changed - Changed `goals` from `Stage::UnderDevelopment` to `Stage::Experimental` in `codex-rs/features/src/lib.rs`. - Added experimental menu metadata for the feature with the description `Set a persistent goal Codex can continue over time`. ## Verification - `cargo test -p codex-features`
Eric Traut ·
2026-04-30 10:06:44 -07:00 -
fix(core): truncate large mcp tool outputs in rollouts (#20260)
## Why Large MCP tool call outputs can make rollout JSONL files enormous. In the session that motivated this change, the biggest JSONL records were: - `event_msg/mcp_tool_call_end` - `response_item/function_call_output` both containing the same unbounded MCP payloads - just 3 MCP tool calls that each were multi-hundred MBs 😱 This PR truncates both of those JSONL records. ## How #### For `response_item/function_call_output` Unified exec already bounds tool output before it is injected into model-facing history, which also keeps the corresponding rollout `response_item/function_call_output` records small. MCP should follow the same pattern: truncate the model-facing tool output at the tool-output boundary, while leaving code-mode/raw hook consumers alone. #### For `event_msg/mcp_tool_call_end` `McpToolCallEnd` also needs its own bounded event copy because it is the app-server/replay/UI event shape that backs `ThreadItem::McpToolCall`. Unfortunately this is _not_ downstream of the `ToolOutput` trait. ## Model behavior Model behavior is actually unchanged as a result of this PR. Before this PR, MCP output was: 1. Converted to `FunctionCallOutput`. 2. Recorded into in-memory history. 3. Truncated by `ContextManager::record_items()` before later model turns saw it. After this branch, MCP output is truncated earlier, in `McpToolOutput::response_payload()`, using the same helper. Then `ContextManager::record_items()` sees an already-truncated output and effectively has little/no additional work to do. So the model should still see the same kind of truncated function-call output. The practical difference is where truncation happens: earlier, before rollout persistence/app-server emission can see the giant payload. ## Verification - `cargo test -p codex-core mcp_tool_output` - `cargo test -p codex-core mcp_tool_call::tests::truncate_mcp_tool_result_for_event` - `cargo test -p codex-core mcp_post_tool_use_payload_uses_model_tool_name_args_and_result` - `just fmt` - `just fix -p codex-core` - `git diff --check`Owen Lin ·
2026-04-30 16:30:43 +00: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 -
Gate multi-agent v2 tools independently of collab (#20246)
## Why `multi_agents_v2` is meant to be independently gated from the older `collab` feature. The tool registry still treated the collaboration-style agent tools as `collab`-only, so enabling `multi_agents_v2` without `collab` omitted the v2 agent tools. Review and guardian sub-sessions also need to keep agent spawning disabled even when the outer session has `multi_agents_v2` enabled. ## What changed - Include the collab-backed agent tools when either `multi_agents_v2` or `collab` is enabled. - Explicitly disable `multi_agents_v2` for review and guardian review sub-sessions, matching the existing `spawn_csv` and `collab` restrictions. - Add a registry test that enables `multi_agents_v2`, disables `collab`, and verifies the v2 agent tools are present while legacy `send_input` and `resume_agent` remain hidden. ## Testing - Added `test_build_specs_multi_agent_v2_does_not_require_collab_feature`.
jif-oai ·
2026-04-30 10:23:31 +02:00 -
Make missing config clears no-ops (#20334)
## Why Fixes #20145. `config/value/write` treats a JSON `null` value as a request to clear the config key. Clearing a key that is already absent should be idempotent, but clearing a nested key such as `features.personality` from an empty `config.toml` returned `configPathNotFound` because `clear_path` treated the missing `features` parent table as an error. That makes app-server reset flows brittle because clients have to read first and avoid sending a clear request unless the parent path already exists. ## What Changed - Updated app-server config clearing so missing intermediate tables, or non-table parents, are treated as an unchanged no-op. - Removed the now-unreachable `MergeError::PathNotFound` path from config write merging. - Added a regression test covering `features.personality = null` against an empty user config. ## Verification - `cargo test -p codex-app-server clear_missing_nested_config_is_noop` - `cargo test -p codex-app-server` was run; the config manager unit suite passed, but one unrelated integration test failed because `turn_start_emits_thread_scoped_warning_notification_for_trimmed_skills` expected `7` trimmed skills and observed `8`. - `just fix -p codex-app-server`
Eric Traut ·
2026-04-30 10:13:33 +02:00 -
feat: Add workspace plugin sharing APIs (#20278)
1. Adds v2 plugin/share/save, plugin/share/list, and plugin/share/delete RPCs. 2. Implements save by archiving a local plugin root, enforcing a size limit, uploading through the workspace upload flow, and supporting updates via remotePluginId. 3. Lists created workspace plugins 4. Deletes a previously uploaded/shared plugin.
xl-openai ·
2026-04-29 23:49:20 -07:00 -
ci: increase Windows release workflow timeouts (#20343)
## Why #20271 increased the `90`-minute timeout in `rust-release.yml`, but it did not update the reusable Windows workflow in `rust-release-windows.yml`. As a result, the Windows release compile jobs were still capped at `60` minutes and the `windows-x64` primary build could continue timing out. We are keeping the existing `90`-minute timeout in `rust-release.yml`. That increase was still directionally correct because the top-level release build benefits from extra headroom; the mistake was assuming it also covered the reusable Windows jobs. ## What Changed - increase the reusable Windows release workflow timeouts in `rust-release-windows.yml` from `60` minutes to `90` minutes - update the comment in `rust-release.yml` so it no longer implies that the top-level timeout covers the Windows reusable jobs
Michael Bolin ·
2026-04-29 23:27:04 -07:00 -
Add persisted hook enablement state (#19840)
## Why After `hooks/list` exposes the hook inventory, clients need a way to persist user hook preferences, make those changes effective in already-open sessions, and distinguish user-controllable hooks from managed requirements without adding another bespoke app-server write API. ## What - Extends `hooks/list` entries with effective `enabled` state. - Persists user-level hook state under `hooks.state.<hook-id>` so the model can grow beyond a single boolean over time. - Uses the existing `config/batchWrite` path for hook state updates instead of introducing a dedicated hook write RPC. - Refreshes live session hook engines after config writes so already-open threads observe updated enablement without a restart. ## Stack 1. openai/codex#19705 2. openai/codex#19778 3. This PR - openai/codex#19840 4. openai/codex#19882 ## Reviewer Notes The generated schema files account for much of the raw diff. The core behavior is in: - `hooks/src/config_rules.rs`, which resolves per-hook user state from the config layer stack. - `hooks/src/engine/discovery.rs`, which projects effective enablement into `hooks/list` from source-derived managedness. - `config/src/hook_config.rs`, which defines the new `hooks.state` representation. - `core/src/session/mod.rs`, which rebuilds live hook state after user config reloads. --------- Co-authored-by: Codex <noreply@openai.com>
Abhinav ·
2026-04-30 04:46:32 +00:00 -
Michael Bolin ·
2026-04-29 20:54:59 -07:00 -
[plugins] Allow MSFT curated plugins in tool_suggest (#20304)
## Summary - [x] Move the allowlist out of core crate - [x] Add Teams, SharePoint, Outlook Email, and Outlook Calendar to the tool_suggest discoverable plugin allowlist - [x] Add focused coverage for Microsoft curated plugin discovery ## Testing - just fmt - cargo test -p codex-core-plugins - cargo test -p codex-core list_tool_suggest_discoverable_plugins_returns_
Matthew Zeng ·
2026-04-29 19:45:52 -07:00 -
app-server: remove dead api version handling from bespoke events (#20291)
Remove ApiVersion::V1
pakrym-oai ·
2026-04-30 01:55:44 +00:00 -
[codex-analytics] prevent stale guardian events from satisfying reused reviews (#20080)
## Why Reused Guardian review trunks can still have older child-turn events queued when a later review starts. The review waiter currently accepts the first terminal event it sees from the shared child session, so a stale `TurnComplete` can be attributed to the new review. That produces impossible analytics combinations such as non-null TTFT with sub-10 ms completion latency and zero token deltas on `trunk_reused` reviews. ## What changed - Preserve the child turn id returned by the Guardian review `Op::UserTurn` submission. - Restrict Guardian review waiting to events correlated with that submitted child turn. - Restrict timeout/abort draining to terminal events for the same child turn. - Add regression coverage for stale prior-turn completions, stale prior-turn errors, and interrupt draining in `codex-rs/core/src/guardian/review_session.rs`. ## Verification - `cargo test -p codex-core guardian::review_session::tests::` - `cargo clippy -p codex-core --tests -- -D warnings`
rhan-oai ·
2026-04-29 18:26:39 -07:00 -
update codex_plugins_beta_setting (from workspace settings) (#20250)
update the name after rename internally see https://github.com/openai/openai/pull/871006
Alex Zamoshchin ·
2026-04-30 00:40:25 +00: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 -
Import external agent sessions in background (#20284)
Summary: - Return from external agent import before session history import finishes - Run session import work in the background and emit the existing completion notification when it is done - Serialize session imports so duplicate requests do not create duplicate imported threads Verification: - cargo test -p codex-app-server external_agent_config_ - cargo test -p codex-external-agent-sessions - just fix -p codex-app-server - just fix -p codex-external-agent-sessions - git diff --check
stefanstokic-oai ·
2026-04-30 00:00:41 +00:00 -
Consume ai-title from external sessions and add end marker (#20261)
## Summary - Support Claude Code `ai-title` / `aiTitle` records when detecting and importing external agent sessions. - Preserve existing `custom-title` / `customTitle` precedence; only fall back to `aiTitle` when no custom title is present. - Add coverage for both detection and import title selection, including the custom-title-over-ai-title case. ## Testing - `cargo test -p codex-external-agent-sessions` - `just fix -p codex-external-agent-sessions`
alexsong-oai ·
2026-04-30 00:00:13 +00:00 -
Add hooks/list app-server RPC (#19778)
## Why We need a way to list the available hooks to expose via the TUI and App so users can view and manage their hooks ## What - Adds `hooks/list` for one or more `cwd` values that returns discovered hook metadata ## Stack 1. openai/codex#19705 2. This PR - openai/codex#19778 3. openai/codex#19840 4. openai/codex#19882 ## Review Notes The generated schema files account for most of the raw diff, these files have the core change: - `hooks/src/engine/discovery.rs` builds the inventory entries during hook discovery while leaving runtime handlers focused on execution. - `app-server/src/codex_message_processor.rs` wires `hooks/list` into the app-server flow for each requested `cwd`. - `app-server-protocol/src/protocol/v2.rs` defines the new v2 request/response payloads exposed on the wire. ### Core Changes `core/src/plugins/manager.rs` adds `plugins_for_layer_stack(...)` so `skills/list` and `hooks/list`can resolve plugin state for each requested `cwd` --------- Co-authored-by: Codex <noreply@openai.com>
Abhinav ·
2026-04-29 23:39:57 +00:00 -
chore: increase release build timeout from 60 min to 90 (#20271)
Build times are creeping up, so increase the timeout as a precaution.
Michael Bolin ·
2026-04-29 16:19:59 -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 -
Enforce workspace metadata protections in Linux sandbox (#19852)
## Summary Enforce FileSystemSandboxPolicy protected metadata names in the Linux bubblewrap adapter so `.git`, `.agents`, and `.codex` remain read only inside writable workspace roots unless the policy grants an explicit write carveout. ## Scope 1. Translate protected metadata names from FileSystemSandboxPolicy into bubblewrap masks for existing metadata paths. 2. Represent missing protected metadata paths as guarded mount targets so agents cannot create `.git`, `.agents`, or `.codex` under writable roots. 3. Preserve normal git discovery for existing repos, worktrees, and parent repos. 4. Keep explicit user write grants working when policy allows a protected metadata path directly. ## Not in scope 1. No shell preflight UX. 2. No TUI runtime profile propagation. 3. No macOS Seatbelt changes in this PR. ## Reviewer focus 1. This should be reviewed as the Linux enforcement adapter for the policy primitive from PR 19846. 2. macOS enforcement already landed in PR 19847. 3. The important invariant is that `FileSystemSandboxPolicy` is the source of truth for `.git`, `.agents`, and `.codex`. ## Validation 1. `git diff` whitespace check passed. 2. `cargo fmt` check passed with the existing stable rustfmt warning about `imports_granularity`. 3. Full Linux sandbox Cargo test suite passed on the devbox. 4. Devbox forty six case suite passed at head `012accb703c13bd28df5b40079a9bf183036336a`. 5. Devbox summary: pass 46, fail 0. 6. The devbox suite was run through `just c sandbox linux`. 7. Focused repo test for Viyat parent repo case passed on the devbox.
evawong-oai ·
2026-04-29 16:14:14 -07:00 -
stop blocking unified_exec on Windows (#19435)
## Summary - remove the Windows-specific unified-exec environment block from tool selection - keep `unified_exec` default-off on Windows unless the feature is explicitly enabled - normalize model-provided `shell_type = unified_exec` to `shell_command` when the feature is disabled - drop obsolete tests tied to the removed environment gate and keep the feature-flag regression coverage ## Why Now that the session/long-lived process backend is implemented for the Windows sandbox, we don't need to hard disable it anymore. We will be rolling out slowly using a feature gate. ## Impact This allows manual Windows opt-in in CLI and app-backed flows while preserving the existing default-off behavior for Windows users. --------- Co-authored-by: canvrno-oai <kbond@openai.com> Co-authored-by: Codex <noreply@openai.com>
iceweasel-oai ·
2026-04-29 16:06:33 -07:00 -
Add codex-core public API listing (#20243)
Summary: - Add a checked-in codex-core public API listing generated by cargo-public-api. - Add scripts/regen-public-api.sh with an embedded crate list, auto-install for cargo-public-api 0.51.0, pinned nightly, and --check mode. - Add Rust CI jobs on the codex Linux x64 runner pool to verify the listing stays up to date. Testing: - bash -n scripts/regen-public-api.sh - just regen-public-api --check - yq '.' .github/workflows/rust-ci.yml .github/workflows/rust-ci-full.yml - git diff --check
pakrym-oai ·
2026-04-29 22:58:08 +00:00 -
Add agent graph store interface (#19229)
## Summary Persisted subagent parent/child topology currently leaks through `StateRuntime`'s SQLite-specific thread-spawn helpers. This PR introduces a narrow `AgentGraphStore` boundary so follow-up work can route graph operations through a local or remote store without coupling orchestration code directly to the state DB graph API. ## Changes - Adds the new `codex-agent-graph-store` crate. - Defines a flat `AgentGraphStore` trait for the v1 graph surface: upsert edge, set edge status, list direct children, and list descendants. - Adds public graph types for `ThreadSpawnEdgeStatus`, `AgentGraphStoreError`, and `AgentGraphStoreResult`. - Implements `LocalAgentGraphStore` on top of an existing `codex_state::StateRuntime`, preserving today's SQLite-backed `thread_spawn_edges` behavior. - Registers the crate in Cargo/Bazel metadata. This PR only adds the local contract and implementation; call-site migration and the remote gRPC store are left to the follow-up PRs in the stack. ## Testing - `cargo test -p codex-agent-graph-store` The new unit tests cover local parity with the existing `StateRuntime` graph methods, `Open`/`Closed` filtering, status updates, and stable breadth-first descendant ordering.
Rasmus Rygaard ·
2026-04-29 22:48:26 +00: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 -
Escape turn metadata headers as ASCII JSON (#19620)
## Why `x-codex-turn-metadata` is sent as an HTTP/WebSocket header, but Codex was serializing the metadata JSON with raw UTF-8 string contents. When a workspace path contains non-ASCII characters, common HTTP stacks can reject or corrupt that header before the request reaches the provider. Fixes #17468. Also addresses the duplicate WebSocket report in #19581. ## What changed - Added `codex_utils_string::to_ascii_json_string`, a shared helper that serializes JSON normally while escaping non-ASCII string content as `\uXXXX`. - Switched turn metadata header serialization, including merged Responses API client metadata, to use the ASCII-safe JSON helper. - Added coverage for non-ASCII workspace paths and non-ASCII client metadata while preserving the same parsed JSON values. ## Verification - `cargo test -p codex-utils-string` - `cargo test -p codex-core turn_metadata` - `just bazel-lock-check`
Eric Traut ·
2026-04-29 15:35:33 -07:00 -
docs: discourage
#[async_trait]and#[allow(async_fn_in_trait)](#20242)## Why We have run into two avoidable problems when introducing async trait APIs in Rust: - `#[async_trait]` has caused materially worse build times in this repository. - `#[allow(async_fn_in_trait)]` makes it too easy to ship a public trait without spelling out whether the returned future is `Send`, which hides an important part of the trait contract. We already have a good example of the preferred alternative in [#16630](https://github.com/openai/codex/pull/16630) / [`3c7f013f9735`](https://github.com/openai/codex/commit/3c7f013f9735), but that guidance currently lives only as prior art in the codebase. This PR documents the rule in `AGENTS.md` so contributors are more likely to follow the native RPITIT pattern before these two shortcuts spread further. ## What Changed - added Rust guidance in `AGENTS.md` discouraging both `#[async_trait]` and `#[allow(async_fn_in_trait)]` - pointed contributors to the native RPITIT pattern with explicit `Send` bounds on the returned future - clarified that implementations may still use `async fn` when they satisfy that trait contract ## Verification - docs-only change; no tests run
Michael Bolin ·
2026-04-29 15:29:29 -07:00 -
[apps] Add apps MCP path override (#20231)
Summary - Add `[features.apps_mcp_path_override]` config with a `path` field for overriding only the built-in apps MCP path. - Keep existing host/base URL derivation unchanged and append the configured path after that base. - Regenerate the config schema with the custom feature-config case. Test Plan - Not run for latest revision; only `just fmt` and `just write-config-schema` were run. - Earlier revision: `cargo test -p codex-features` - Earlier revision: `cargo test -p codex-mcp`
Alex Daley ·
2026-04-29 18:08:06 -04:00 -
Fallback login callback port when default is busy (#19334)
## Summary - Keep the preferred ChatGPT login callback port `1455` first. - Preserve the existing `/cancel` recovery for stale Codex login servers. - Fall back to the registered localhost callback port `1457` when `1455` remains unavailable. ## Why Cursor and Codex Desktop both use the ChatGPT account login callback server. On Windows, Cursor can already be listening on `127.0.0.1:1455` / `[::1]:1455`, causing Codex Desktop sign-in to fail with: `Local callback port 1455 is already in use on this machine.` Codex already attempted to cancel a stale Codex login server on that port, but if the listener does not release the port, the old behavior was to fail. The new behavior falls back to `1457`, which matches the fixed redirect URI being registered server-side in `openai/openai#863817`. This keeps the OAuth `redirect_uri` inside Hydra's exact allow-list instead of choosing an arbitrary ephemeral port. ## Validation - `just fmt` - `cargo test -p codex-login` - `git diff --check HEAD~1..HEAD`
xli-oai ·
2026-04-29 14:45:27 -07:00 -
[app-server] centralize client response analytics (#20059)
## Why The precursor PR keeps successful client responses typed until app-server's outgoing response seam. This follow-up uses that seam to move successful client-response analytics out of individual handlers and into the shared sender path, while keeping filtering decisions inside `codex-analytics`. ## What changed - Emit successful client-response analytics centrally from `OutgoingMessageSender::send_response`. - Remove duplicate handler-local response tracking for the current thread/turn lifecycle responses. - Keep analytics ingestion selective inside `AnalyticsEventsClient`, so unrelated client traffic is ignored before cloning or boxing. - Collapse client-response analytics facts onto one typed path and normalize payloads in the reducer. - Add direct client-filter coverage plus sender-level coverage for the centralized forwarding path. ## Verification - `cargo test -p codex-analytics` - `cargo test -p codex-app-server outgoing_message::tests --lib`
rhan-oai ·
2026-04-29 21:22:39 +00:00 -
Require remote plugin detail before uninstall (#19966)
## Summary - Fetch remote plugin detail before sending the uninstall request. - Use the detail response to derive the marketplace namespace and plugin name for cache cleanup. - Stop the uninstall before the backend POST if detail lookup fails, so backend state and local cache state do not diverge. ## Testing - `just fmt` - `cargo test -p codex-app-server plugin_uninstall` - `cargo test -p codex-core-plugins` - `git diff --check`
xli-oai ·
2026-04-29 14:01:11 -07:00 -
[app-server] type client response payloads (#20050)
## Why `pr17088` adds typed server-originated request/response plumbing, but successful client responses are still erased into bare JSON-RPC `result` values before app-server can make any typed decision about them. This precursor PR keeps successful client responses typed until the outgoing response seam. It is intentionally limited to protocol/app-server plumbing so the analytics behavior change can review separately on top. ## What changed - Add `ClientResponsePayload` as the pre-serialization client response body type. - Route app-server successful response paths through the typed payload seam while preserving existing handler-local analytics behavior. - Keep `InterruptConversation` JSON-RPC-only because it has no `ClientResponse` variant. - Move the new payload conversion tests into a dedicated protocol test module. ## Verification - `cargo check -p codex-app-server` - `cargo test -p codex-app-server-protocol`
rhan-oai ·
2026-04-29 20:50:47 +00:00 -
app-server: fix outgoing sender test setup (#20258)
## Why [#17088](https://github.com/openai/codex/pull/17088) changed `OutgoingMessageSender::new` to require an `AnalyticsEventsClient`, but one `command_exec` test added earlier on `main` still called the old one-argument constructor. That leaves current `main` failing to compile in Bazel and argument-comment-lint jobs. ## What changed - Pass `AnalyticsEventsClient::disabled()` to the missed `OutgoingMessageSender::new` test call site in `command_exec.rs`. ## Verification - `cargo test -p codex-app-server timeout_or_cancellation_reports_cancellation_without_timeout_exit_code`
sayan-oai ·
2026-04-29 20:47:20 +00:00 -
[tool_suggest] Improve tool_suggest triggering conditions. (#20091)
## Summary - Tighten `tool_suggest` guidance so it prefers explicit plugin install requests, while still allowing a connector install when the relevant plugin is already installed and a needed connector from that plugin is missing. - Tell the model not to call `tool_suggest` in parallel with other tools. ## Testing - `cargo test -p codex-tools tool_suggest` - `cargo test -p codex-core tool_suggest`
Matthew Zeng ·
2026-04-29 13:41:12 -07:00 -
[codex-analytics] ingest server requests and responses (#17088)
## Why Codex analytics needs a typed seam for app-server-originated request/response traffic so future tool-approval analytics can consume those facts without adding bespoke callsite tracking each time. Server responses arrive as JSON-RPC `id + result` payloads, so analytics has to reconstruct the matching typed response from the original typed request while that request context still exists in app-server. This also puts analytics on the app-server outbound path, which needs to avoid keeping the runtime alive during shutdown. The final ownership fix keeps the normal strong auth-manager retention in analytics and makes the external-auth refresh bridge hold a weak back-reference to `OutgoingMessageSender`, breaking the runtime cycle at the bridge boundary instead of exposing retention policy through the analytics client API. ## What changed - Adds typed `ServerRequest` and `ServerResponse` analytics facts, plus `AnalyticsEventsClient::track_server_request` and `track_server_response`. - Renames the existing client-side facts to `ClientRequest` and `ClientResponse` so reducers can distinguish client-to-server traffic from server-to-client traffic. - Adds `ServerRequest::response_from_result`, allowing a stored typed request to decode the matching typed server response from a raw JSON-RPC result payload. - Threads `AnalyticsEventsClient` through `OutgoingMessageSender` and records targeted server requests, replayed targeted requests, and matching targeted responses with the responding connection id needed for correlation. - Intentionally leaves broadcast server requests/responses out of analytics for now because the current model is per connection, while broadcasts fan one logical request out across multiple connections. - Breaks the app-server shutdown cycle by storing `Weak<OutgoingMessageSender>` in `ExternalAuthRefreshBridge` and upgrading it only when an external-auth refresh is actually requested. - Keeps reducer ingestion of the new server-side facts as no-ops for now; this PR is plumbing for later tool-approval analytics work. ## Verification - `cargo test -p codex-analytics` - `cargo test -p codex-app-server outgoing_message::tests::` - Covers typed-response reconstruction plus the targeted, replayed, broadcast-exclusion, and response-attribution analytics paths. ## Follow-up This PR intentionally stops at ingestion plumbing, so `ServerRequest` and `ServerResponse` facts are still reducer no-ops. Once a follow-up PR adds real downstream analytics output for those facts: - replace the temporary pre-reducer observation seam with reducer tests for the emitted event shape; - add end-to-end coverage in `app-server/tests/suite/v2/analytics.rs` for the real app-server workflow and captured analytics payload; - remove the temporary sender-level observer tests added here in favor of the real-output coverage above. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/17088). * #18748 * #18747 * #17090 * #17089 * #20241 * #20239 * __->__ #17088
rhan-oai ·
2026-04-29 19:56:41 +00:00 -
expand the set of core shell env vars for Windows. (#20089)
https://github.com/openai/codex/issues/13917 and https://github.com/openai/codex/issues/18248 correctly identify that ``` [shell_environment_policy] inherit = "core" ``` is not functional on Windows because it carries an insufficient set of env vars. This PR expands that to match the more functional set from the MCP client
iceweasel-oai ·
2026-04-29 19:23:46 +00:00 -
fix: handle deferred network proxy denials (#19184)
## Why This bug is exposed by Guardian/auto-review approvals. With the managed network proxy enabled, a blocked network request can be reported back through the network approval service as an approval denial after the command has already started. Before this change, the shell and unified exec runtimes registered those network approval calls, but did not have a way to observe an async proxy denial as a cancellation/failure signal for the running process. The result was confusing: Guardian/auto-review could correctly deny network access, but the command path could keep running or unregister the approval without surfacing the denial as the command failure. ## What Changed - `NetworkApprovalService` now attaches a cancellation token to active and deferred network approvals. - Proxy-denial outcomes are recorded only for active registrations, cancel the owning token, and are consumed when the approval is finalized. - The shell runtime combines the normal command timeout with the network-denial cancellation token. - Unified exec stores the deferred network approval object, terminates tracked processes when the proxy denial arrives, and returns the denial as a process failure while polling or completing the process. - Tool orchestration passes the active network approval cancellation token into the sandbox attempt and preserves deferred approval errors instead of silently unregistering them. - App-server `command/exec` now handles the combined timeout-or-cancellation expiration variant used by the runtime. ## Verification - `cargo test -p codex-core network_approval --lib` - `cargo clippy -p codex-app-server --all-targets -- -D warnings` - `cargo clippy -p codex-core --all-targets -- -D warnings` --------- Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-04-29 19:13:57 +00:00 -
feat: Use remote installed plugin cache for skills and MCP (#20096)
- Fetches and caches remote /installed plugin state - Lets skills/list load skills from remote-installed cached plugins without requiring a local marketplace entry - Routes plugin list/startup/install/uninstall changes through async plugin cache invalidation and MCP refresh
xl-openai ·
2026-04-29 12:09:49 -07:00