chore(release): merge upstream rust-v0.140.0#74
Open
richardgetz wants to merge 195 commits into
Open
Conversation
Codex forces `core.fsmonitor=false` on internal Git commands so a repository cannot select an executable fsmonitor helper. This also disables Git's built-in daemon for `status`, `diff`, and `ls-files`, turning those worktree reads into full scans in large repositories. Read the raw effective `core.fsmonitor` value and preserve it only when Git interprets it as true and advertises built-in daemon support through `git version --build-options`. Query uncommon boolean spellings back through Git using the exact effective value. Unset, false, helper paths, malformed values, probe failures, and unsupported Git builds continue to force `core.fsmonitor=false`. Centralize this policy in `git-utils` while keeping process execution in the existing local and workspace-command adapters. Probe once per worktree workflow and reuse the result for its Git commands, including the TUI `/diff` path. Metadata-only commands and repository discovery remain disabled without probing. Each probe and requested Git process keeps its own existing timeout, and the decision is not cached because layered and conditional Git configuration can change while Codex runs. --------- Co-authored-by: Chris Bookholt <bookholt@openai.com>
) ## Summary - request `includeAppsNeedingAuth=true` when installing remote plugins - return backend-provided `app_ids_needing_auth` from the remote install client - use those app IDs to populate `appsNeedingAuth` without refetching accessible apps, with fallback for older responses ## Testing - `just fmt` - `just test -p codex-app-server` - `just test -p codex-core-plugins` - real app-server install/uninstall check with Notion remote plugin - subagent review found no blocking issues
## Summary - return installed `workspace-directory` remote plugins by default in `plugin/installed` - keep shared-with-me installed plugins gated behind `plugin_sharing` - filter remote installed plugin marketplaces by canonical marketplace name instead of coarse workspace scope ## Validation - `just fmt` - `just test -p codex-core-plugins` - `just test -p codex-app-server` - `just fix -p codex-core-plugins` - `just fix -p codex-app-server` - `$xin-build` targeted verification: - `just test -p codex-core-plugins build_remote_installed_plugin_marketplaces_from_cache_filters_by_marketplace_name` - `just test -p codex-app-server plugin_installed_includes_workspace_directory_without_plugin_sharing` - `just test -p codex-app-server plugin_installed_includes_remote_shared_with_me_plugins` - `just test -p codex-app-server plugin_list_omits_shared_with_me_kind_when_plugin_sharing_disabled`
## Why Multi-agent v2 identifies agents by canonical paths, but its tool handlers still emitted the larger legacy collaboration begin/end events built around nickname and role metadata. App-server, rollout-trace, analytics, and TUI consumers therefore lacked one compact path-based completion signal that behaved consistently across live events and replay. The TUI also needs a bounded `/agent` status surface for v2 agents. It should use recent local activity for previews, refresh liveness without loading full histories, and keep the legacy picker available when no path-backed v2 agent is known. ## What changed - Replace the v2 `spawn_agent`, `send_message`, `followup_task`, and `interrupt_agent` legacy lifecycle emissions with a success-only `SubAgentActivity` event. The event records the tool call ID, occurrence time, affected thread, canonical agent path, and `started`, `interacted`, or `interrupted` kind. - Expose the activity as a completion-only app-server v2 `subAgentActivity` thread item in live notifications and reconstructed history, regenerate the protocol schemas, and count it in sub-agent tool analytics. - Track canonical paths from live activity and loaded-thread metadata in the TUI, and render the activity in live and replayed transcripts. - Make `/agent` list running path-backed agents with summaries from bounded local event buffers. Each summary is capped at 240 graphemes, the scan is capped at six recent items, only the last three wrapped lines are shown, and command output is omitted. Liveness falls back to metadata-only `thread/read` when local turn state is unavailable. - Persist the activity as a terminal rollout-trace runtime payload and reduce it to the corresponding spawn, send, follow-up, or close interaction edge. `interrupt_agent` is classified as a close-edge operation. - Preserve the legacy picker when no path-backed v2 agent is known. ## Compatibility App-server v2 clients that consumed `collabAgentToolCall` begin/end pairs for these tools must handle the new completion-only `subAgentActivity` item. Legacy v1 collaboration behavior is unchanged. ## Screenshot <img width="684" height="288" alt="Screenshot 2026-06-08 at 15 40 47" src="https://github.com/user-attachments/assets/194b3cd0-619d-45fb-b587-cf3e2b1b8a1d" /> ## Testing - `just test -p codex-app-server-protocol` - `just test -p codex-rollout-trace` - Added focused coverage for activity analytics, terminal trace serialization, spawn-edge reduction, `interrupt_agent` classification, TUI status rendering without aggregated command output, and clearing stale running state after a completed turn.
…penai#27166) ## Why PR openai#27007 moved MultiAgentV2 interruption reporting from the legacy collaboration close event to `SubAgentActivity::Interrupted`. App-server's missing-thread cleanup still ran only for the legacy event, so an interrupted child that had already been unloaded could remain marked as loaded and running in `ThreadWatchManager`. That leaves thread status and running-turn accounting stale, including the count used during graceful shutdown. ## What changed - Handle `SubAgentActivity::Interrupted` separately in app-server event processing. - Remove the child's thread watch when `ThreadManager` no longer has that thread. - Continue forwarding the same completed sub-agent activity notification to clients. ## Testing - Added a regression test that starts with a running watch for an unloaded child, applies the interrupted activity event, and verifies the watch is removed, the running count returns to zero, and the client notification is still emitted.
## Why The PR babysitter could surface inline comments from a GitHub review that was still in the `PENDING` state. That allowed Codex to start acting on feedback before the reviewer submitted it. ## What changed - Correlate inline comments with their parent review and ignore pending reviews and their comments. - Remove pending review IDs from saved watcher state so the feedback surfaces normally after publication. - Update the skill instructions and add regression coverage for the draft-to-published transition. ## Validation - `python3 -m pytest .codex/skills/babysit-pr/scripts/test_gh_pr_watch.py` - Skill package validation with `quick_validate.py` - Live verification on openai#26835: the draft comment stayed hidden and surfaced after the review was submitted.
## Summary - avoid acquiring SQLite's writer slot when the singleton backfill row already exists - preserve race-safe repair when the row is missing - add regressions for writer contention and missing-row repair ## Why State runtime initialization and backfill-state reads previously executed `INSERT ... ON CONFLICT DO NOTHING` even in the steady state. SQLite still enters the writer path for that statement, so TUI and app-server startup could wait behind another writer for up to the configured five-second busy timeout. ## Validation - `just test -p codex-state` (134 tests passed) - `just fix -p codex-state` - `just fmt`
## Summary - reuse the history-bearing `StoredThread` loaded while probing for a running thread - avoid rereading and reparsing the rollout when that probe finds no active process - reload after shutting down a loaded thread because shutdown may flush newer rollout items - add a regression test that verifies cold resume performs one history-bearing store read ## Problem `thread/resume` first reads the persisted thread with history while checking whether the thread is already running. When no running process exists, cold resume currently falls through to `resume_thread_from_rollout`, which reads and parses the same history again. That duplicate work grows with rollout size and remains on the synchronous resume path even when the caller requests `excludeTurns`. ## Background The duplicate read was introduced by openai#24528, which fixed resume overrides for idle cached threads. To support resumes specified by rollout path, `resume_running_thread` began loading the stored thread with history so it could resolve the canonical thread ID and determine whether a cached `CodexThread` was already loaded. That history is needed when the loaded-thread path handles the request. On a cold miss, however, the function's boolean result could only report that no loaded thread handled the request. It discarded the history-bearing `StoredThread`, and the normal cold-resume path immediately loaded and parsed the same rollout again. This change preserves the idle cached-thread behavior from openai#24528 while allowing the cold-resume path to reuse the probe result. ## Performance I benchmarked real retained rollouts using isolated `CODEX_HOME` directories, explicit rollout paths, debug builds of the commit and its exact parent, and alternating parent/patch order. The table below uses `thread/resume` with `excludeTurns: true`; response payload sizes were identical. | Rollout size | Records | Parent median | Patch median | Median paired saving | | ---: | ---: | ---: | ---: | ---: | | 6 MB | 3,574 | 541 ms | 441 ms | 132 ms | | 30 MB | 15,220 | 1.505 s | 1.041 s | 701 ms | | 60 MB | 31,453 | 2.644 s | 1.742 s | 970 ms | | 149 MB | 100,874 | 10.506 s | 7.156 s | 3.350 s | | 559 MB | 259,734 | 27.759 s | 16.725 s | 9.836 s | The absolute saving increases with thread size, as expected when removing one complete JSONL history read and parse. Total resume time is also content-dependent, so the relationship is not perfectly linear. I also tested full-history resume with `excludeTurns: false`. The response payload was byte-identical between variants, and the same size-dependent improvement remained visible: | Rollout size | Parent median | Patch median | Median paired saving | | ---: | ---: | ---: | ---: | | 6 MB | 1.052 s | 904 ms | 270 ms | | 30 MB | 2.667 s | 1.762 s | 924 ms | | 60 MB | 8.464 s | 6.272 s | 3.680 s | | 149 MB | 26.719 s | 12.118 s | 14.601 s | | 559 MB | 40.359 s | 25.475 s | 16.590 s | ## Validation - `just test -p codex-app-server cold_thread_resume_reuses_non_local_history_probe` - `just fix -p codex-app-server -p codex-thread-store` - `just fmt`
…#22879) This changes the `/review` escape path so `Esc` no longer behaves like the normal queued-follow-up interrupt flow while a review is running. Steering is not currently supported in `/review` mode, without this change users are able to attempt a steer but it leads to a crash (see openai#22815). If the user has already tried to send additional guidance during `/review`, the TUI now keeps the review running and shows a warning that steer messages are not supported in that mode, while still pointing users to `Ctrl+C` if they actually want to cancel. It also adds regression coverage for the review-specific warning behavior. When users do cancel with Ctrl+C during /review, the TUI now tolerates the active-turn race that can happen during review handoff, and any queued steer messages are restored to the composer instead of being discarded. - Special-case `Esc` during an active `/review` when follow-up steer input is pending or has already been deferred. - Show a clear warning instead of interrupting the running review. - Make the Ctrl+C cancel path during /review resilient to active-turn races, while preserving any queued steer text by restoring it to the composer. - Add review-mode test coverage for the warning path. ## Testing 1. Start a `/review` with a diff large enough that the review stays active for more than a few seconds. 2. While the review is still running, type a follow-up / steer message, submit it, and then press `Esc`. Before: `Esc` causes the TUI to close abruptly. After: the review keeps running and the transcript shows a warning that steer messages are not supported during `/review`, with guidance to use `Ctrl+C` if you want to cancel. 3. Press `Ctrl+C` if you actually want to stop the review. Before: (after restarting the test since Pt. 2 crashed) this is the intentional cancellation path. After: this remains the intentional cancellation path, and any queued follow-up steer text is restored to the composer instead of being lost. ## Note: `/review` mode explicitly does not support steering at this time (as noted in `turn_processer.rs`, if we want to explore that in the future this code will need to be modified). This change keeps unsupported steer attempts from crashing the TUI and preserves queued follow-up text if the user cancels with Ctrl+C.
…27173) ## Why Multi-agent v2 sub-agents are owned and coordinated by their parent agent. Allowing an app-server client to start or steer turns on a spawned child bypasses the multi-agent messaging path and creates a second, conflicting source of work for that sub-agent. ## What changed - Reject direct `turn/start` and `turn/steer` requests targeting multi-agent v2 thread-spawn sub-agents. - Identify these targets using both the thread's resolved multi-agent version and its `SubAgentSource::ThreadSpawn` session source, leaving root threads, v1 agents, and other sub-agent types unchanged. - Return a consistent invalid-request error before validating or applying the submitted input. ## Testing - Added an app-server integration test that spawns a real multi-agent v2 child and verifies that direct `turn/start` and `turn/steer` requests are rejected.
## Why
CCA is moving toward a split runtime where the orchestrator may not have
a filesystem, while executors can expose preinstalled plugins and
skills. A thread therefore needs to select capabilities without asking
app-server or core to interpret executor-owned paths through the
orchestrator's filesystem.
The longer-term model is broader than executor skills:
- A plugin is a bundle of skills, MCP servers, connectors/apps, and
hooks.
- A plugin root can be local, executor-owned, or hosted by a backend.
- Components inside one plugin can use different access and execution
mechanisms. A skill may be read from a filesystem or through backend
tools; an HTTP MCP server can run without an executor; a stdio MCP
server or hook needs an execution environment.
- Core should carry generic extension initialization data. The extension
that owns a component should discover it, expose it to the model, and
invoke it through the appropriate runtime.
This PR establishes that architecture through one complete vertical:
selecting a root on an executor, discovering the skills beneath it,
exposing those skills to the model, and reading an explicitly invoked
`SKILL.md` through the same executor.
## Contract
`thread/start` gains an experimental `selectedCapabilityRoots` field:
```json
{
"selectedCapabilityRoots": [
{
"id": "deploy-plugin@1",
"location": {
"type": "environment",
"environmentId": "workspace",
"path": "/opt/codex/plugins/deploy"
}
}
]
}
```
The root is intentionally not classified as a "plugin" or "skill" in the
API. It can point at a standalone skill, a directory containing several
skills, or a plugin containing skills and other components. This PR only
teaches the skills extension how to consume it; later extensions can
resolve MCP, connector, and hook components from the same selection.
The platform-supplied `id` is stable selection identity. The location
says which runtime owns the root and gives that runtime an opaque path.
App-server does not inspect or canonicalize the path.
## What changed
### Generic thread extension initialization
App-server converts selected roots into `ExtensionDataInit`. Core
carries that generic initialization value until the final thread ID is
known, then creates thread-scoped `ExtensionData` before lifecycle
contributors run.
This keeps `Session` and core independent of the capability-selection
contract. The initialization value is consumed during construction; it
is not retained as another long-lived `Session` field.
### Executor-backed skills
The skills extension now owns an `ExecutorSkillProvider` that:
- resolves the selected environment through `EnvironmentManager`
- discovers, canonicalizes, and reads skills through that environment's
`ExecutorFileSystem`
- contributes the bounded selected-skill catalog as stable developer
context
- reads an explicitly invoked skill body through the authority that
listed it
- warns when an environment or root is unavailable
- never falls back to the orchestrator filesystem for an executor-owned
root
Skill catalog and instruction fragments have hard byte bounds, which
also bound them below the 10K-token per-item context limit. If a
selected executor skill has the same name as a legacy local skill, the
executor selection owns that invocation and the local body is not
injected a second time.
Existing local and bundled skill loading remains in place. Omitting
`selectedCapabilityRoots` therefore preserves current local-only
behavior.
## Current semantics
- Only environment-owned locations are represented in this first
contract.
- Roots are resolved by the destination extension, not by app-server or
core.
- An unavailable executor or invalid root produces a warning and no
capabilities from that root; it does not trigger a local-filesystem
fallback.
- Selection applies to a newly started active thread.
- MCP servers, connectors, and hooks beneath a selected plugin root are
not activated yet.
- Selection is not yet persisted or inherited across resume, fork, or
subagent creation. Existing local capabilities continue to behave as
they do today in those flows.
## Planned vertical follow-ups
1. **Hosted HTTP MCP:** add an extension-backed HTTP MCP source that
works without an executor, then replace the special-purpose MCP plugins
loader with that implementation.
2. **Executor MCP:** register and execute stdio MCP servers through the
environment that owns the selected plugin root.
3. **Backend skills:** add a hosted skill source whose catalog and
bodies are accessed through extension tools rather than a filesystem.
4. **Connectors and hooks:** activate those components through their
owning extensions, using the same selected-root boundary and
component-specific runtime.
5. **Durable selection:** define the desired-selection lifecycle,
persist it, and make resume, fork, and subagent inheritance explicit
rather than accidental.
6. **Local convergence:** incrementally route existing local plugin,
skill, and MCP loading through the same extension model while preserving
current local behavior.
Each follow-up remains reviewable as an end-to-end capability. The
platform selects roots, generic thread extension data carries the
selection, and the owning extension resolves and operates its component.
## Verification
Coverage added for:
- app-server end-to-end discovery and explicit invocation of a skill
inside an executor-selected plugin root
- exclusive invocation when a selected executor skill collides with a
local skill name
- executor filesystem authority for discovery, canonicalization, and
reads
- thread extension initialization before lifecycle contributors run
- stable executor catalog context, explicit invocation, context
rebuilding, hidden skills, and preserved host/remote catalog behavior
Targeted protocol, core-skills, skills-extension, core lifecycle, and
app-server executor-skill tests were run during development.
## Why `codex-extension-api` defines contracts shared by extension crates and their hosts, but it had no direct test suite. Host and feature tests cover downstream behavior, while regressions in the API crate's own typed state, registry ordering, and capability adapters could go unnoticed. ## What - Add public-surface integration tests for `ExtensionData`, including concurrent initialization and poison recovery. - Cover contributor registration order, approval short-circuiting, event sink retention, no-op response injection, and closure-based agent spawning. - Add the test-only dependencies used by the suite. ## Validation - `just test -p codex-extension-api` - `just argument-comment-lint -p codex-extension-api` - `just bazel-lock-check`
## Why - `ThreadSource` currently defines a closed set of core-owned values - Product features also create threads for background or scheduled work - Adding every product-specific value to the core enum would require repeated `codex-rs` protocol changes - Feature-backed values let product callers provide precise attribution while preserving the existing core classifications ## What Changed - Adds `ThreadSource::Feature(String)` for app-owned thread source values - Represents all app-server v2 thread sources as scalar strings, so a feature source is supplied as `"automation"` - Persists and emits the feature's plain string label, so `"automation"` produces `thread_source="automation"` in analytics - Keeps `user`, `subagent`, and `memory_consolidation` as explicit core-owned values and regenerates the app-server schemas and TypeScript bindings ## Verification - `just write-app-server-schema` - `cargo check --workspace` - `just test -p codex-protocol feature_thread_source_serializes_as_its_app_owned_label` - `just test -p codex-app-server-protocol thread_sources_round_trip_as_scalar_labels` - `cargo test -p codex-analytics thread_initialized_event_serializes_expected_shape` - `just fmt`
## Why `just test` currently uses the CI-oriented nextest profile, which serializes app-server integration tests even on developer machines that can run several safely. Bounded local parallelism substantially shortens this common iteration loop without changing CI behavior. Eight-worker experiments were faster, but keeping them reliable required relaxing several test deadlines. Four workers for integration tests is a solid tradeoff that speeds up local testing without needing to change test logic. ## What changed - Add a `local` nextest profile that inherits the existing defaults. - Allow up to four app-server integration tests to run concurrently under that profile. - Make `just test` select the local profile on Unix and Windows. - Keep the default CI profile serialized and leave all test deadlines unchanged. The tests use separate processes, randomized temporary `CODEX_HOME` directories, and ephemeral ports. The remaining shared constraints are system resources; each app-server also uses a multi-thread Tokio runtime, and fuzzy-search tests can create additional worker threads, so the local cap remains intentionally conservative. ## Performance and validation All measurements below are warm, execution-only app-server runs with nextest retries disabled. On the current rebased branch, an AMD EPYC 7763 machine with 16 logical CPUs and 62 GiB RAM completed three consecutive runs: | Run | Nextest time | Wall time | Result | | --- | ---: | ---: | --- | | 1 | 142.941s | 145.17s | 836/836 passed | | 2 | 143.402s | 145.59s | 836/836 passed | | 3 | 142.870s | 145.08s | 836/836 passed | The mean wall time was 145.28s. The slow-inventory, approval replay, and zsh-fork tests all passed with their original deadlines. Earlier measurements on the same Linux machine, before the suite grew, showed the scaling that motivated the change: | App-server concurrency | Nextest time | Result | | --- | ---: | --- | | 1 | 369.5s | 572/572 passed | | 2 | 194.5s | 572/572 passed | | 4 | 111.0s mean over 3 runs | 3/3 clean | Four workers reduced that execution time by about 70%, a roughly 3.3x speedup over serialization.
## Summary - reuse the MITM HTTPS serving path for raw SOCKS5 TCP streams - route limited-mode and hooked SOCKS5 TCP requests through MITM before dialing upstream - keep SOCKS5 UDP limited-mode behavior unchanged ## Validation - `just fmt` - `just test -p codex-network-proxy` - `just fix -p codex-network-proxy` - `git diff --check`
## Why Users have indicated that they want an agent to be able to create a new goal for itself after completing the previous goal. Currently, that's not possible because agents cannot overwrite an existing goal even if it's complete. This PR removes this limitation and allows `create_goal` to overwrite an existing goal if it is in the `complete` state. ## What changed `create_goal` now replaces the existing goal only when its status is `complete`. The replacement is performed atomically in the goal store, creates a fresh active goal with reset usage, and continues to reject creation while any unfinished goal exists. App server clients see a single `thread/goal/updated` event when the previous goal is replaced with the new one. The tool description and error message now reflect these semantics. ## What didn't change Agents are not allowed to create a new goal (overwrite their existing goal) if an existing goal is still active, blocked, paused, or in any other state other than "completed".
## Why The TUI still reached through `app-server-client::legacy_core` for thread-name normalization and project-instruction filename details. In particular, checking the TUI's local filesystem for `/init` is incorrect for remote app-server sessions, where the server owns the working directory and instruction discovery. ## What changed - use the instruction source paths supplied by the app server to decide whether `/init` should avoid overwriting project instructions - keep the small thread-name normalization helper local to the TUI - remove the now-unused instruction filename constants, utility module, and other unused `legacy_core` re-exports - make status helper tests independent of concrete instruction filenames ## Verification - `just test -p codex-app-server-client` - `just test -p codex-tui slash_init_skips_when_project_instructions_are_loaded` - `just test -p codex-tui` ran 2,799 tests; 2,797 passed and two unrelated guardian feature-flag tests failed reproducibly in untouched code ### Manual test Started an app server over WebSocket with a remote workspace containing `AGENTS.md`, then connected the TUI using `--remote`. After confirming `thread/start` returned the file in `instructionSources`, deleted `AGENTS.md` and ran `/init` in the existing session. The TUI still reported that project instructions already existed and skipped `/init`. The trace contained no `turn/start` request, confirming the decision came from app-server session state rather than a new client-local filesystem check.
## Why Goal continuation turns are emitted by the existing runtime as separate physical turns. The Python SDK needs private thread-scoped routing before it can present those notifications as one logical operation, without changing ordinary turn routing or the app-server protocol. ## What - add private goal operation state and thread-scoped notification routing - add internal wrappers for the existing `thread/goal/clear` and `thread/goal/set` RPCs - include existing goal notifications in the SDK notification union - preserve ordinary turn-ID routing unchanged - add focused routing coverage This PR does not expose a public goal API. It is the first PR in the Python goal operations stack. ## Test plan - online CI, including the Python SDK suite - focused typed-notification routing coverage
## Stack - Base: openai#27184 - This PR is the second vertical and should be reviewed against `jif/external-plugins-1`, not `main`. ## Why CCA is moving toward a split runtime where the orchestrator may have no filesystem or executor, but it still needs to activate remotely hosted plugin components. HTTP MCP servers are the simplest complete example: they need configuration and host authentication, but they do not need an executor process. The Apps MCP endpoint is currently synthesized by a special-purpose loader inside the MCP runtime. That works locally, but it leaves hosted MCP activation outside the extension model being established in openai#27184. It also makes the Apps path a poor foundation for plugins whose skills, MCP servers, connectors, and hooks may come from different sources or execute in different places. This PR moves that one behavior behind an extension-owned contribution while preserving the existing local fallback. It deliberately does not introduce a generic plugin activation framework. ## What changed ### MCP extension contribution `codex-extension-api` gains an ordered `McpServerContributor` contract. A contributor returns typed `Set` or `Remove` overlays for MCP server configuration; later contributors win for the names they own. The contract stays at the existing MCP configuration boundary. Extensions do not create a second connection manager or transport abstraction. ### Hosted Apps MCP extension A new `codex-mcp-extension` contributes the reserved `codex_apps` server from the existing Apps feature, ChatGPT base URL, path override, and product SKU configuration. When `apps_mcp_path_override` is enabled for `https://chatgpt.com`, the resulting streamable HTTP endpoint is `https://chatgpt.com/backend-api/ps/mcp`. The existing ChatGPT-auth gate remains authoritative, so this server can run in an orchestrator-only process without being exposed for API-key sessions. ### One resolved runtime view `McpManager` now distinguishes three views: - **configured:** config- and plugin-backed servers before extension overlays; - **runtime:** configured servers plus host-installed extension contributions; - **effective:** runtime servers after auth gating and compatibility built-ins. App-server installs the hosted MCP extension and uses the runtime view for thread startup, refresh, status, threadless resource reads, connector discovery, and MCP OAuth lookup. This keeps `mcpServer/oauth/login` consistent with the servers exposed by the other MCP APIs. The hosted Apps server itself continues to use existing ChatGPT host authentication rather than MCP OAuth. ## Compatibility Hosts that do not install the MCP extension retain the existing Apps MCP synthesis path. This preserves current local-only, CLI, and standalone-host behavior while app-server exercises the extension path. Disabling Apps removes the reserved `codex_apps` entry, and losing ChatGPT auth removes it from the effective runtime view. Executor availability is not consulted for this HTTP transport. ## Follow-ups The next vertical will resolve a manifest-declared stdio MCP server from an executor-selected plugin root and execute it in the environment that owns that root. Later verticals can add backend-owned skills, connector metadata, hooks, durable selection semantics, and incremental local convergence without changing the component-specific runtime boundaries introduced here. ## Verification Focused coverage was added for: - contributing the hosted Apps MCP at `/backend-api/ps/mcp` without an executor; - requiring ChatGPT auth in the effective runtime view; - removing a reserved configured Apps server when the Apps feature is disabled. `cargo check -p codex-app-server -p codex-mcp-extension -p codex-extension-api -p codex-mcp` passed. Tests and Clippy were not run locally under the current development instruction; CI provides the full validation pass.
## Why Global instruction behavior spans thread creation, resume, forks, subagents, and compaction. Characterization coverage is needed before changing those semantics so preserved history can be distinguished from newly loaded configuration. ## What changed - Extends the existing `agents_md` suite with fresh-thread, warning, resume, fork, and subagent lifecycle coverage. - Extends the existing `compact` suite with manual, mid-turn, and remote-v2 compaction coverage. - Asserts rendered instruction fragments, reported source paths, and structured request history before and after instruction-file mutations.
…6713) ## Why Persisted MCP OAuth credentials were reported as authenticated whenever a credential record existed. An expired token without a usable refresh token could therefore appear as `OAuth` even though startup could not authenticate with it, leaving users with a misleading status instead of a login prompt. ## What changed - Classify stored OAuth credentials as missing, usable, or requiring authorization. - Reuse the existing refresh window so near-expiry credentials without a refresh path are also treated as logged out. - Validate required credential fields before reporting OAuth authentication. - Add unit coverage for credential usability and integration coverage for expired, unexpired, and refreshable persisted credentials. ## Validation - `just test -p codex-rmcp-client`
## Why A long-running unified exec process started with `tty: false` could not be interrupted via `write_stdin`: ordinary non-TTY stdin writes are rejected once stdin is closed, but an exact U+0003 payload should still map to a process interrupt. The interrupt should flow through the same process lifecycle path as a real signal so Codex preserves process-reported output and exit metadata instead of fabricating a Ctrl-C exit code or tearing down the session early. ## What Changed - Add `process/signal` to exec-server with `ProcessSignal::Interrupt` and an empty response. - Add a non-consuming `ProcessHandle::signal` path for spawned processes; on Unix it sends SIGINT to the process group and leaves terminate/hard-kill unchanged. - Route non-TTY U+0003 `write_stdin` through `process.signal(...)` instead of `terminate`, then let the normal post-write collection path drain output and observe exit. - Add exec-server coverage where a shell `trap INT` handler prints the signal and exits with its own code. - Add unified exec coverage where a `tty: false` process traps SIGINT, emits output, and exits with its own code. ## Validation - `just test -p codex-exec-server exec_process_signal_interrupts_process` - `just test -p codex-exec-server` - `just test -p codex-core write_stdin_ctrl_c_interrupts_non_tty_session`
## Why The realtime frontend model and the backing Codex thread should present one coherent assistant. Raw typed messages, steers, and worker reports belong to the orchestrator; the frontend model should receive the orchestrator's user-facing result rather than a second copy of those inputs. Today normal `turn/start` input is automatically inserted into the realtime conversation, while `turn/steer` is not. Besides creating inconsistent context, this can make the frontend model react independently before Codex has produced the response it should speak. ## What changed - Remove automatic accepted-user-input mirroring into realtime - Remove the mirror-only echo-suppression flag and dead V2 prefix helper - Preserve explicit app-to-realtime text injection and FEM-to-Codex delegation - Replace the positive mirror tests and obsolete snapshots with a negative routing regression test ## Test plan - `cargo test -p codex-core conversation_user_text_turn_is_not_sent_to_realtime` - `cargo test -p codex-core conversation_startup_context_is_truncated_and_sent_once_per_start` - `cargo test -p codex-core inbound_handoff_request_starts_turn`
## Why The Python SDK must treat the runtime's initial goal turn and its continuations as one logical operation. That requires a private lifecycle engine before the public API can return the existing turn handle and result types. ## What - start goals by composing the existing clear/set goal RPCs - enforce persisted, idle threads and a bounded startup handshake - coalesce continuation notifications under a stable logical turn ID - aggregate items, usage, timing, and terminal status - support rollover-aware steering, interruption, cancellation, and cleanup - provide equivalent sync and async internals This is the second PR in the stack and intentionally adds no public API. ## Test plan - online CI, including the Python SDK suite - behavioral coverage is added in the following two stack PRs
## Summary - Retry transient streamable HTTP failures during RMCP startup when the failure happens while sending the initialize request. - Retry transient streamable HTTP failures for tools/list, which is read-only and safe to replay. - Cover both retryable HTTP statuses and request-layer failures where no HTTP status is returned. - Surface retryable HTTP statuses from the streamable HTTP adapter as typed client errors. - Add integration coverage for initialize retry, tools/list retry, no-status request failure retry, and non-retryable initialize status. ## Root cause The observed codex_apps failures can happen before normal tool execution: RMCP startup fails while sending initialize, or the first read-only tools/list fails after startup. Retrying hosted_apps_bridge tools/call would not cover initialize and would risk replaying side-effecting tool calls. This change retries the streamable HTTP handshake itself, recreates the transport between initialize attempts, and retries only tools/list among post-initialize service operations. ## Validation - cargo fmt --package codex-rmcp-client - cargo test -p codex-rmcp-client --test streamable_http_recovery
…ai#27257) ## Summary - order `McpConnectionManager` methods by visibility, with the primary constructor and public API first - restrict `list_available_server_infos` to `codex-mcp` - make `new_uninitialized` a private test-only helper ## Why The manager exposed methods that are only used inside `codex-mcp` or its unit tests. Tightening those methods keeps the exported API intentional, while the new ordering makes the supported surface easier to scan. ## Validation - `just fmt` - `git diff --check` - local tests not run; relying on CI
## Why Memory startup used hardcoded OpenAI model slugs for extraction and consolidation. That works for the default OpenAI-compatible path, but provider-specific backends can require different model identifiers. In particular, Amazon Bedrock should use its Bedrock model ID for these background memory requests instead of the OpenAI `gpt-5.4-mini` / `gpt-5.4` slugs. ## What Changed - Added provider-owned preferred memory model methods alongside `approval_review_preferred_model`. - Updated memory extraction and consolidation to resolve their default model through the active `ModelProvider`. - Added Amazon Bedrock overrides so both memory stages use `openai.gpt-5.4` through Bedrock’s provider-specific model ID. - Kept explicit `memories.extract_model` and `memories.consolidation_model` config overrides taking precedence. - Added startup coverage for default OpenAI and Bedrock memory model selection. #closes openai#26288
## Why - Local profiling shows `append_tool_search_executor` averages ~113ms per call. Adding a span lets us track this cost as we optimize in follow-up PRs, either by reducing the work or avoiding repeated rebuilds when inputs have not changed. - While we're here, we can add spans to `build_tool_router` and other sub-calls which code analysis shows may have additional opportunities for improvement. ## What changed Add function-level trace spans around `build_tool_router`, `build_tool_specs_and_registry`, `add_tool_sources`, `append_tool_search_executor`, and `build_model_visible_specs_and_registry` ## Verification Trigger Codex rollout and observe new spans are included
## Summary Removes Plugin descriptions from the dev message, since descriptions of skills and MCPs cover the capabilities offered by the plugin. ## Testing - [x] Updates unit tests
## Why Multi-agent v2 `send_message` deliveries already reach the receiving model as typed `agent_message` items with encrypted content. Child-completion notifications are generated by Codex itself, so their content is plaintext and previously fell back to a serialized JSON envelope inside an assistant message. With plaintext `input_text` supported for `agent_message`, both delivery paths can use the same model-visible type while preserving explicit author and recipient metadata. ## What changed - add plaintext `input_text` support to `AgentMessageInputContent` and regenerate the affected app-server schemas - preserve `InterAgentCommunication` as structured mailbox input instead of converting it to assistant text - record delivered communications as typed `agent_message` history items - persist a dedicated rollout item so local delivery metadata such as `trigger_turn` remains available without leaking into the Responses request - reconstruct typed agent messages on resume and preserve fork-turn truncation behavior - remove request-time assistant-content parsing - preserve plaintext and encrypted inter-agent deliveries in stage-one memory inputs - normalize and link plaintext and encrypted agent messages in rollout traces without treating inbound messages as child results - cover the real MultiAgent V2 child-completion path end to end with deterministic mailbox synchronization ## Verification - `just test -p codex-core plaintext_multi_agent_v2_completion_sends_agent_message` - `just test -p codex-core input_queue_drains_mailbox_in_delivery_order record_initial_history_reconstructs_typed_inter_agent_message fork_turn_positions_use_inter_agent_delivery_metadata` - `just test -p codex-memories-write serializes_inter_agent_communications_for_memory` - `just test -p codex-rollout-trace agent_messages_preserve_routing_and_content sub_agent_started_activity_creates_spawn_edge` - `just test -p codex-rollout-trace agent_result_edge_falls_back_to_child_thread_without_result_message` - `just test -p codex-protocol -p codex-rollout -p codex-app-server-protocol`
## Why Removes the realtime audio support from TUI. ## What Changed - Removed the TUI `/realtime` and realtime `/settings` command paths. - Deleted TUI voice capture/playback, WebRTC session handling, audio-device selection UI, and recording-meter code. - Removed TUI realtime tests and snapshots that covered the deleted surfaces. - Dropped the TUI-only `cpal` and `codex-realtime-webrtc` dependencies and refreshed the Rust/Bazel locks.
## Why Windows Credential Manager limits generic credential blobs to 2,560 bytes. Large serialized ChatGPT auth payloads can exceed that limit, so keyring-mode CLI auth needs a backend that keeps only the encryption key in the OS keyring and stores the payload in Codex's encrypted local-secrets file. This is the third PR in the encrypted-auth stack: 1. openai#27504 — feature and config selection 2. openai#27535 — auth-specific local-secrets namespaces 3. This PR — CLI auth implementation and activation 4. MCP OAuth implementation and activation ## What Changed - Added encrypted CLI-auth storage using the `CliAuth` secrets namespace. - Preserved direct keyring storage for platforms/configurations where it remains selected. - Selected the backend consistently for login, logout, refresh, device-code login, auth loading, and login restrictions. - Threaded resolved bootstrap/full config through CLI, exec, TUI, app-server account handling, cloud config, and cloud tasks. - Removed stale `auth.json` fallback data after successful encrypted saves and removed encrypted, direct-keyring, and fallback data during logout. - Added storage and integration coverage for both direct and encrypted keyring modes. MCP OAuth persistence is intentionally left to the next PR. ## Validation - `just test -p codex-login` — 131 passed - `just test -p codex-cli` — 280 passed - `just test -p codex-app-server v2::account` — 25 passed - `just test -p codex-cloud-config service` — 21 passed, 7 skipped - `just fix -p codex-login` - `just fix -p codex-cli` - `just fmt`
## Summary
Startup warnings for under-development features only recognized bare
boolean toggles like `features.foo = true`. An upcoming feature will use
table-format config, so `features.foo = { enabled = true, ... }` needs
to count as an explicit opt-in too.
This updates the warning predicate to recognize structured tables with
`enabled = true`, while leaving tables without that field unwarned.
## Testing
- `just fmt`
- `just test -p codex-features
unstable_warning_event_mentions_enabled_structured_under_development_feature`
## Summary - store MCP OAuth credentials in the configured auth credential backend - support encrypted-local OAuth storage, including legacy keyring migration - propagate the credential backend through MCP refresh, session, CLI, and app-server paths ## Stack 1. openai#27504 — config and feature flag 2. openai#27535 — auth-specific secret namespaces 3. openai#27539 — encrypted CLI auth storage 4. this PR — encrypted MCP OAuth storage This is a parallel review stack; the original openai#17931 remains unchanged. ## Tests - `just test -p codex-rmcp-client` (the transport round-trip test passed after building the required `codex` binary and retrying) - `just test -p codex-mcp` - `just test -p codex-app-server refresh_config_uses_latest_auth_keyring_backend` - `just test -p codex-core refresh_mcp_servers_is_deferred_until_next_turn` - `just test -p codex-cli mcp` - `just fix -p codex-rmcp-client -p codex-mcp -p codex-core -p codex-cli -p codex-app-server -p codex-protocol` - `just bazel-lock-check`
## Summary Add an explicit `user` or `developer` role to `thread/realtime/appendText` and propagate it through the realtime input queue into `conversation.item.create`. Older JSON clients that omit the field continue to default to `user`. This lets app-provided context such as memory retain developer authority without bypassing app-server through a renderer-owned data channel. The app-server schemas, API documentation, and focused protocol and websocket coverage are updated with the new contract. The Codex Apps consumer is tracked in [openai/openai#1025261](openai/openai#1025261).
## Stack 1. [1 of 3] Support long raw TUI goal objectives - openai#27508 2. **[2 of 3] Support long pasted text in TUI goals** - this PR 3. [3 of 3] Support images in TUI goals - openai#27510 ## Why Large text pasted into the TUI composer is represented as a paste placeholder plus pending paste metadata. For `/goal`, preserving only the visible placeholder is not enough: the agent would see a short placeholder string instead of the actual pasted text, and the long-text support from the first PR would never see the payload. The TUI also needs to avoid writing stale sidecar files when a user pastes a large block and then deletes its placeholder before submitting the goal. ## What Changed - Introduces a TUI `GoalDraft` for goal submissions so `/goal`, `/goal edit`, and queued goal commands can carry objective text plus text elements and pending paste payloads. - Materializes active pasted-text placeholders to `pasted-text-N.txt` files through the app-server filesystem path introduced in openai#27508. - Rewrites active paste placeholders in the persisted objective to file references, while leaving literal placeholder-looking text alone. - Filters out deleted paste placeholders so otherwise-small goals do not require `$CODEX_HOME` or remote filesystem writes. - Preserves pending paste metadata when a `/goal` command is queued before a thread exists. ## Verification - Added goal materialization tests for active paste placeholders, deleted paste placeholders, and whitespace-only paste payloads. - Added/updated TUI slash-command tests for large pasted text, queued `/goal` commands before thread start, and queued oversized goal behavior. ## Manual Testing - Used real terminal bracketed-paste sequences through a remote TUI session. A 1,228-byte multiline paste became `pasted-text-1.txt`; its first/last lines and byte count matched exactly, and the persisted objective referenced the server-host path. - Pasted a large block, deleted its placeholder, and submitted a small replacement objective. No new directory or sidecar file was created. - Added two same-length large pastes to one goal. The composer disambiguated their visible placeholders, and materialization preserved order and contents in `pasted-text-1.txt` and `pasted-text-2.txt`. - Submitted a whitespace-only large paste and verified the goal was rejected as empty without writing a file. - Submitted a pasted-text replacement while another goal was active, verified no file was written before confirmation, then canceled and confirmed the original goal remained unchanged. - Combined a large paste with enough raw text to exceed 4,000 characters after placeholder rewriting. The paste sidecar and `goal-objective.md` were created in the same remote attachment directory, and `/goal edit` restored the rewritten objective with its sidecar reference.
## Why We need request-level evidence for Guardian cases where `codex-auto-review` is missing from the client-side model catalog and the review falls back to the parent model. ## What changed - Add `guardian_catalog_contains_auto_review` to Guardian Responses API client metadata. - Add `guardian_model_provider_id` to Guardian Responses API client metadata. - Keep review-session metadata optional so callers without metadata preserve the existing `None` path. - Add tests for override, normal preferred-model, and missing-auto-review-catalog behavior. ## Validation - `just test -p codex-core guardian_review_records_missing_auto_review_model_in_request_metadata` - `just test -p codex-core guardian_review_uses_model_catalog_override_when_preferred_review_model_exists` - `just test -p codex-core guardian_review_uses_preferred_review_model_without_model_catalog_override` - `git diff --check origin/main`
Codex seems to do interesting things with `cfg`'s sometimes and it seems it would be good to give it guidance about how broadly our Rust needs to work. This adds a very brief section to AGENTS.md explaining that we target the major desktop OSes and that we want the vast majority of our logic to be portable across them.
Each Windows packaging job creates three compressed forms of five binaries in sequence. This takes roughly two minutes and is on the release critical path. Use two xargs workers to compress independent binaries concurrently. The workers only read the raw executables and write per-binary archive names. The Codex zip can safely read the helper executables while their own archives are generated. On a 16-vCPU AMD EPYC 9V74 Windows x64 release runner, alternating trials against artifacts from release run 27391514823 measured: serial: 121 s, 123 s, 121 s parallel: 73 s, 73 s, 74 s This saves 47 to 50 seconds in the x64 packaging lane, reducing the observed release critical path by about 48 seconds when x64 remains the limiting lane. https://github.com/openai/codex/actions/runs/27401905938
…penai#27499) ## Summary This PR promotes Mentions 2.0 (unified TUI mention popup) to stable and enables it by default. - Keep `mentions_v2` as a temporary rollback path to the legacy split popups (`--disable mentions_v2`). - Add feature-default and snapshot coverage for the default experience. ## Prior work - [openai#19068 — Unified mentions in TUI](openai#19068) - [openai#22375 — Use plugin/list to get plugins for mentions](openai#22375) - [openai#23363 — Unified mentions tweaks and rendering polish](openai#23363) ## Test plan - Launch Codex without any feature overrides. - Type `@` in the TUI composer. - Confirm the unified mentions menu opens and displays filesystem, plugin, and skill results.
## Why The paired thread-environment migration changed several generic test turn helpers from supplying a fallback cwd to explicitly selecting the local environment. That changes their meaning under `build_with_remote_env()`: remote-only fixtures cannot resolve the forced local selection, so the tests fail before exercising apply-patch, RMCP, unified-exec, or view-image behavior. Generic helpers should inherit the environment selected by their fixture. Tests that intentionally exercise local routing continue to select the local environment explicitly. ## What changed - Remove forced `local_selections(...)` overrides from the generic apply-patch, RMCP, unified-exec, and view-image turn helpers. - Remove the imports made unused by those deletions. ## Testing - Not run locally; this is a test-fixture-only change and the `full-ci` branch will exercise the affected remote shards.
In the x64 packaging job from https://github.com/openai/codex/actions/runs/27391514823 archiving and uploading PDBs took 65 seconds after signing. Release packaging could not start until that work completed. Windows code signing changes executables but not their PDBs. Package the PDBs in a sibling Ubuntu job as soon as all binary artifacts are available. Signing and release packaging can then proceed without waiting for the symbols archive, reducing the critical path by about one minute.
## Why `PathUri::from_abs_path` can fail for absolute paths that do not have a normal `file:` URI representation, forcing filesystem call sites to handle a conversion error even though the original path can be preserved losslessly. ## What Make `from_abs_path` infallible and migrate its callers. Unrepresentable paths use `file:///%00/bad/path/<base64>`, encoding Unix bytes or Windows UTF-16LE; `to_abs_path` validates and decodes that fallback. The leading encoded null reserves a namespace that cannot collide with a real Unix or Windows path, and fallback URIs remain opaque to lexical path operations. ## Validation Added path-URI coverage for Unix null and non-UTF-8 paths, Windows device/verbatim and non-Unicode paths, serialization, malformed fallbacks, opaque lexical operations, invalid native payloads, and literal `/bad/path` collision resistance.
In the Windows x64 packaging job from https://github.com/openai/codex/actions/runs/27391514823 building the primary and app-server package archives serially took 116 seconds. Both archives read the same signed-binary directory but write separate package trees and output files. Run them concurrently with xargs -P2. The package helper rewrites DotSlash executables under the process temp directory. A naive concurrent run failed when one process tried to replace an executable used by the other. Give each bundle separate TMP and TEMP roots to keep those caches independent. On Windows x64 in https://github.com/openai/codex/actions/runs/27397197944 three serial trials took 127, 128, and 126 seconds. Concurrent trials took 76, 74, and 74 seconds, saving 52 to 54 seconds. This removes about 50 seconds from the release critical path without changing the packaging commands or output set.
In the release job from https://github.com/openai/codex/actions/runs/27391514823 staging the nine npm release tarballs serially took 104 seconds. Each package build writes to a separate staging directory, output path, and npm cache. Run them through the script's existing thread pool, bounded by the available CPU count. Delete each staging tree as its build finishes so concurrency does not retain all copies until the end. On ubuntu-24.04 in https://github.com/openai/codex/actions/runs/27397232050 two serial trials took 103 and 101 seconds, while concurrent trials both took 41 seconds. Comparing every extracted file from the first serial and concurrent sets found no differences. This removes about one minute from every release.
## Why We have some large gaps in our thread start, resume, and pre-sampling traces that make it hard to tell where latency is coming from. ## What Changed - Added coarse spans around thread start/resume, turn context construction, rollout reconstruction, skill/plugin loading, and tool preparation. - Added a breakdown of discoverable-tool preparation across connector loading, plugin discovery, and local plugin details. ## Testing - `cargo check -p codex-app-server -p codex-core -p codex-core-skills -p codex-core-plugins` - Built the app-server locally and exercised thread start, first turn, follow-up turn, server restart, thread resume, and a resumed turn.
## Stack 1. [1 of 3] Support long raw TUI goal objectives - openai#27508 2. [2 of 3] Support long pasted text in TUI goals - openai#27509 3. **[3 of 3] Support images in TUI goals** - this PR ## Why The first two PRs make goal definitions resilient to long text, but `/goal` still dropped image inputs from the composer. That meant a user could attach images while defining a goal and the resulting goal continuation would not have any useful reference to those images. Goal state still persists only objective text, so image inputs need to become paths or URLs that the agent can read later. ## What Changed - Extends TUI `GoalDraft` with local image attachments and remote image URLs. - Copies local goal images through the app-server filesystem layer into the managed goal attachment directory, then rewrites active image placeholders to file references. - Appends unplaced local images and remote image URLs to the objective as referenced image files or URLs. - Preserves goal image metadata through live `/goal` submission and queued `/goal` dispatch. ## Verification - Added goal materialization coverage for local image files and remote image URLs. - Added/updated TUI slash-command coverage showing `/goal` drafts include attached images instead of dropping them. ## Manual Testing - Attached an image by bracketed-pasting its local path into a live `/goal` composer. The `[Image #1]` placeholder became a server-host `image-1.png` reference, copied bytes matched exactly, and no attachment was written under the TUI's local home. - Deleted an image placeholder before submitting a small goal and verified no image was copied. - Attached PNG and JPEG files to the same goal. Placeholder order was preserved as `image-1.png` and `image-2.jpg`, and both remote copies matched their source bytes. - Tried extensionless, malformed-extension, and extension/content-mismatched paths; the composer rejected them as image attachments before goal dispatch rather than creating misleading managed image files. - Combined a local image, a large pasted block, and enough raw text to exceed 4,000 characters. The remote attachment directory contained the image, paste sidecar, and `goal-objective.md`; all embedded references used server-host paths and both payloads matched their sources. - Submitted an image replacement while a goal was active, verified no image was copied before confirmation, then canceled and confirmed the attachment count was unchanged.
## Why [openai#25345](openai#25345) was approved, green, and squash-merged into its stacked base branch, `fcoury/tokenmaxxing-api`. Four minutes later, that base branch was force-pushed back to an API-only rebased head while preparing [openai#25344](openai#25344) for `main`. As a result, the squash commit from openai#25345 was orphaned and the TUI command never reached `main` or a release. This PR relands the orphaned TUI change from [`411410b8`](openai@411410b) on current `main`. ## What changed - Add `/usage`, `/usage daily`, `/usage weekly`, and `/usage cumulative` for account token activity. - Fetch account usage asynchronously through the existing `account/usage/read` app-server RPC. - Render daily, weekly, and cumulative activity with theme-aware terminal palettes and bounded transient cards. - Preserve transcript ordering while assistant streams, history consolidations, active cells, and hooks complete. - Hide `/usage` from completion when backend auth is unavailable while keeping typed-command guidance. - Carry current-main behavior forward for cwd-aware Markdown parsing, Windows Terminal color detection, and personal access token auth. - Clear pending usage cards on thread rollback and delay completed cards until live hook output is committed. - Add focused regression and snapshot coverage for loading, auth errors, invalid views, rollback, hook ordering, layout, and charts. ## Prior review The original implementation was approved by Eric Traut in openai#25345 after testing multiple themes and light/dark terminals. This PR preserves that reviewed implementation while adapting it to current `main` and adding regression coverage for newer rollback and hook lifecycle behavior. ## Validation - `just test -p codex-tui token_activity palette renderable usage_command` — 37 passed. - Focused rollback, hook-ordering, and error snapshot tests — 4 passed. - `just fix -p codex-tui` — passed. - `UV_CACHE_DIR=/private/tmp/codex-uv-cache just fmt` — passed. - `cargo insta pending-snapshots` — no pending snapshots. - `just test -p codex-tui` — 2,870 passed; two unrelated guardian feature-flag tests failed because their expected `OverrideTurnContext` event was absent: - `update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history` - `update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default` - `just argument-comment-lint` could not complete because the local Bazel LLVM `compiler-rt` repository is missing `include/sanitizer/*.h`. The touched Rust diff was manually inspected and no missing opaque-literal argument comments were found.
…#27988) ## Summary - Keep local plugin suggestions bounded to fallback and explicitly configured plugins. - Preserve app-overlap recommendations for remote plugins using cached catalog metadata. - Remove the WSL-specific local discovery exception and move manager-owned discovery tests into `codex-core-plugins`. ## Why Local curated marketplaces were allowlisted before plugin detail loading, so every uninstalled candidate could be deep-read before its app IDs were checked. That caused per-turn reads of candidate plugin manifests, skills, app configs, hooks, and MCP configs, which is especially expensive on slow disks. Remote discovery does not need those local candidate reads because app IDs are already available in the cached remote catalog. Installed local plugins are still loaded when needed to determine the user's installed app IDs. ## Validation - `just fmt` - `just test -p codex-core-plugins discoverable::tests` (13 passed) - `just test -p codex-core plugins::discoverable::tests` (4 passed) - `just bazel-lock-update` - `just bazel-lock-check` - `git diff --check`
## Context Plugins can expose more than one way for Codex to use them: App connectors for ChatGPT/SIWC-backed sessions and MCP servers for API key login sessions. The broader goal is to make `PluginsManager` the place that understands which plugin surfaces should be visible for the current auth route, so callers do not each have to make that decision themselves. This PR is the small setup step for that work. It lets the plugin manager be created with the current `AuthMode`, which gives the followup auth routing PRs the information they need without relying on setter injection. ## Stack - PR1: openai#27652 seed plugin manager auth at construction. - PR2: openai#27459 route plugin surfaces by auth mode. - PR3: openai#27607 dedupe plugin MCP servers by App declaration name. - PR4: openai#27602 preserve plugin Apps in connector listings. - PR5: openai#27461 skip install-time plugin MCP OAuth for matching App routes. ## Summary - Let `PluginsManager::new_with_restriction_product` accept an initial `AuthMode`. - Keep `PluginsManager::new` behavior unchanged for ordinary callers. ## Validation ```bash cargo test -p codex-core-plugins plugins_manager_tracks_auth_mode cargo test -p codex-core list_tool_suggest_discoverable_plugins git diff --check ``` --------- Co-authored-by: Xin Lin <xl@openai.com>
## Why We want to make it possible for an app-server orchestrator on one OS to control an exec-server on another host running a different OS. In practice this kinda already works if you get lucky and the two hosts have the same path format, but we mangle quite a lot of operations if either end is Windows. We should be able to test the cross-platform interactions for exec-server, but we want to do this fairly soon and need a lightweight option for testing. Using Wine to run the Windows side is far from perfect, but it should give us a decent measure of how well we're handling the basics of paths, process spawning, shell interaction, etc. Future changes will add actual exec-server tests and possibly extensions to the Wine testing environment. ## What To make the cross-target-triple build easy, these tests are added only to the Bazel build. This change adds an x86_64 Wine prebuilt managed by Bazel and some build rules that can set up the needed toolchain transition. The support library for running Wine in a test environment created by the Bazel rules comes with its own basic unit and integration tests. Their primary priority is to make sure we don't leak child processes on developer machines and that we can build and launch a basic hello world binary. ## Validation Confirmed these new tests are running on the [x86_64 bazel ubuntu jobs](https://github.com/openai/codex/actions/runs/27446432302/job/81132356855?pr=27937): ``` //bazel/rules/testing/wine:wine-smoke-test (cached) PASSED in 3.7s //bazel/rules/testing/wine:wine-test-support-unit-tests (cached) PASSED in 15.8s ```
## Context Some plugins expose both Apps and MCP servers. This PR moves auth-aware surface projection into `core-plugins::PluginsManager`, so callers get a consistent effective plugin view. Later PRs narrow the conflict rule and update listing/install paths. The high level goal of this PR is to set up the plumbing to conditionally filter App/MCP in the plugin manager layer. We start by removing MCP servers when using SIWC/Codex-backend auth, and removing Apps when using API-key-style auth. This PR is now stacked on openai#27652, which contains only the constructor plumbing for seeding `PluginsManager` with the current auth mode. ## Stack - PR1: openai#27652 seed plugin manager auth at construction. - PR2: openai#27459 route plugin surfaces by auth mode. - PR3: openai#27607 dedupe plugin MCP servers by App declaration name. - PR4: openai#27602 preserve plugin Apps in connector listings. - PR5: openai#27461 skip install-time plugin MCP OAuth for matching App routes. ## Summary - API-key/non-ChatGPT routes hide plugin Apps and keep plugin MCPs. - ChatGPT/SIWC with Apps enabled keeps plugin Apps and suppresses MCPs for dual-surface plugins. - MCP-only plugins stay available for ChatGPT/SIWC sessions. - Cached plugin load outcomes are re-projected when auth mode changes. ## Validation ```bash cargo test -p codex-core-plugins plugin_auth_projection cargo test -p codex-core list_tool_suggest_discoverable_plugins git diff --check ```
## Why Managed deployments need a reliable deny gate for remote control. Persisted enablement and explicit startup requests currently remain able to start the transport, while the removed `features.remote_control` key is intentionally only a compatibility no-op. This adds a dedicated requirement that administrators can use to force remote control off without deleting the user's persisted preference. Removing the requirement and restarting restores the prior choice. ## What Changed - Added top-level `allow_remote_control` requirements parsing, sourced layer precedence, debug output, and `configRequirements/read` exposure as `allowRemoteControl`. - Added a typed transport policy captured from the startup requirements snapshot. Managed disable forces the initial state to disabled and prevents enrollment, refresh, connection, and persisted-preference mutation. - Rejected every `remoteControl/*` RPC before parameter deserialization with JSON-RPC `-32600` and `remote control is disabled by managed requirements`. - Preserved the existing disabled status notification and the previous behavior when the requirement is `true` or omitted. - Regenerated app-server protocol schemas and documented the new requirement. ## Verification - Confirmed all remote-control RPCs, including a malformed request, return the managed-policy error while the initial status notification remains `disabled`. - Confirmed explicit ephemeral startup and persisted enablement make no backend connection and leave the SQLite preference unchanged. - Confirmed `allow_remote_control = true` does not enable or block remote control and `configRequirements/read` returns `allowRemoteControl: false` for the deny policy. Related issue: N/A (managed-policy hardening).
## Why We want to make it possible for an app-server orchestrator on one OS to control an exec-server on another host running a different OS. In practice this kinda already works if you get lucky and the two hosts have the same path format, but we mangle quite a lot of operations if either end is Windows. This test starts exercising that interaction, although right now the initial bootstrap fails. Future changes will expand the test's assertions to match improved support. ## What Stacked on openai#27964. This adds a small Windows exec-server fixture and a Linux protocol smoke test using the reusable Wine harness, covering Windows environment discovery, non-TTY `cmd.exe` execution, output, exit status, and working directory. Once we've got the full codex binary cross-building under Bazel we could consider moving to the real binary instead of the stripped down exec-server-only binary used here.
## Context Turn state is scoped to one logical turn, but the WebSocket path currently exchanges it through upgrade headers, which are scoped to the physical connection. A connection may be reused across turns, so its handshake cannot represent the turn lifecycle reliably. ## Change Exchange turn state on each WebSocket response request instead: - send an established value in `response.create.client_metadata` - read the returned value from the existing `response.metadata` event - retain the first value in the turn-scoped `ModelClientSession` `OnceLock` - start the next logical turn without state, even when it reuses the same WebSocket connection This gives WebSocket requests the same first-value-wins contract as the existing HTTP path. ## Test plan Integration coverage verifies that: - WebSocket replays returned state on same-turn follow-ups - later response metadata does not replace the first value - state resets at the logical turn boundary without requiring a reconnect CI validates the full change. ## Stack This is 1/2. openai#28002 builds on this request-scoped transport to carry established state through compact requests.
## Context Inline compaction is part of the active logical turn. Compact requests and the sampling requests around them should use the same turn state, including when compaction is the first request to establish it. ## Change Pass the turn-scoped `OnceLock` directly to inline v1 compaction so `/responses/compact` includes an established value in the existing HTTP header. Capture `x-codex-turn-state` from the compact response into that same lock, allowing pre-turn compact to establish the value that subsequent sampling reuses. V2 compact already uses the normal Responses HTTP/WebSocket path and continues to share the same `OnceLock` without separate plumbing. The first returned value wins for the logical turn. ## Test plan Integration coverage verifies that: - pre-turn v1 compact can establish state for the first sampling request - inline v1 compact receives established state over HTTP - inline v2 compact reuses established state over HTTP - inline v2 compact reuses established state over WebSocket CI validates the full change.
- Added `/usage` views for daily, weekly, and cumulative account token activity. (openai#27925) - `/goal` now preserves oversized text, large pasted blocks, and image attachments, including in remote app-server sessions. (openai#27508, openai#27509, openai#27510) - Added permanent session deletion through `codex delete`, `/delete`, and app-server `thread/delete`, with confirmation safeguards and subagent cleanup. (openai#25018, openai#27476) - Added `/import` for selectively importing setup, project configuration, and recent chats from Claude Code. (openai#27070, openai#27071, openai#27703) - Typing `@` now opens the unified mentions menu for files, plugins, and skills by default. (openai#27499) - Added managed Amazon Bedrock API-key authentication and encrypted local storage for CLI and MCP OAuth credentials. (openai#27443, openai#27689, openai#27504, openai#27535, openai#27539, openai#27541) ## Bug Fixes - Corrupted SQLite state databases are now backed up and rebuilt automatically from rollout data, including malformed database-directory cases. (openai#26859, openai#27719) - Prevented `/review` from crashing when `Esc` is pressed with queued guidance, while preserving that guidance when the review is canceled. (openai#22879) - Improved MCP reliability by retrying transient startup failures, reporting unusable OAuth credentials as logged out, and preserving explicitly disabled servers. (openai#25147, openai#26713, openai#27414) - Fixed remote plugin uninstall requests and correctly surfaced apps requiring authentication during installation. (openai#27085, openai#27223) - Persisted “Don’t remind me” update dismissals reliably and cleared stale running-hook indicators after completed turns. (openai#27619, openai#27783) - Non-TTY background commands can now be interrupted with Ctrl-C while preserving their final output and exit status. (openai#26734) ## Documentation - Clarified contributor guidance around keeping crate APIs narrow and supporting Linux, macOS, and Windows. (openai#27939, openai#27966) ## Chores - Improved responsiveness for large repositories and long sessions by preserving Git’s built-in filesystem monitor, avoiding duplicate history reads, accelerating archive lookup, and caching turn-diff rendering. (openai#26880, openai#27031, openai#27276, openai#27489) - Removed the experimental `/realtime` voice controls and related audio dependencies from the TUI. (openai#27801) ## Changelog Full Changelog: openai/codex@rust-v0.139.0...rust-v0.140.0 - openai#26880 [codex] preserve fsmonitor for worktree Git reads @tamird - openai#27085 Use server app auth requirements for remote plugin install @xl-openai - openai#27098 [codex] Return workspace directory installed plugins @xl-openai - openai#27007 multi-agent: add path-based v2 activity tracking @jif-oai - openai#27166 app-server: clear stale thread watches after v2 agent interruption @jif-oai - openai#27080 [codex] Ignore pending PR review comments @anp-oai - openai#26420 Avoid no-op backfill state writes @zanie-oai - openai#27031 Avoid rereading rollout history during cold resume @zanie-oai - openai#22879 fix: Prevent /review crash when entering Esc on steer message @canvrno-oai - openai#27173 app-server: reject direct input to multi-agent v2 sub-agents @jif-oai - openai#27184 Load selected executor skills through extensions @jif-oai - openai#26835 [codex] Test extension API contracts @anp-oai - openai#27063 [codex-analytics] add extensible feature thread sources @marksteinbrick-oai - openai#26479 [codex] Speed up local nextest runs @anp-oai - openai#27223 fix: use plugin service route for remote uninstall @ericning-o - openai#22685 Add SOCKS5 TCP MITM coverage @winston-openai - openai#26681 Allow creating a new goal after completion @etraut-openai - openai#26711 Reduce TUI legacy core dependencies @etraut-openai - openai#27110 [1/6] Add Python goal routing foundation @aibrahim-oai - openai#27191 Route hosted Apps MCP through extensions @jif-oai - openai#26830 [codex] Characterize global instruction lifecycle @anp-oai - openai#26713 [codex] Report unusable MCP OAuth credentials as logged out @anp-oai - openai#26734 [codex] Handle Ctrl-C for non-TTY unified exec @pakrym-oai - openai#27116 Stop mirroring Codex user input into realtime @guinness-oai - openai#27111 [2/6] Add private Python goal operations @aibrahim-oai - openai#25147 [codex] Retry streamable HTTP initialize failures @ssetty-oai - openai#27257 [codex] Tighten MCP connection manager API visibility and order @aibrahim-oai - openai#26701 TUI Plugin Sharing 1 - add remote plugin identity @canvrno-oai - openai#27129 feat: use provider defaults for memory models @celia-oai - openai#27094 Add spans to build_tool_router @mchen-oai - openai#24999 Add per-session realtime model and version overrides @guinness-oai - openai#27078 [codex-analytics] emit goal lifecycle analytics @marksteinbrick-oai - openai#27285 [codex] Fix post-merge analytics integration failures @anp-oai - openai#27107 Add spans to run_turn @mchen-oai - openai#27261 [codex] Make MCP connection startup fallible @aibrahim-oai - openai#27174 feat: keep child MCP warnings out of parent transcript @jif-oai - openai#27198 Use plugin-service MCP as the hosted plugin runtime @jif-oai - openai#27375 [codex] Tag multi-agent spawn metrics with version @jif-oai - openai#27383 Remove async-trait from extension contributors @jif-oai - openai#27259 Use latest-wins MCP manager replacement @charliemarsh-oai - openai#27264 [codex] Store compact window id in rollout @pakrym-oai - openai#27280 [codex] add io PathUri native conversion APIs @anp-oai - openai#27315 [codex] link Windows releases with LLD @tamird - openai#27276 Reduce archive rollout lookup CPU @etraut-openai - openai#27299 [codex] Outline ToolExecutor handler bodies @anp-oai - openai#27391 Index visible thread list ordering @zanie-oai - openai#27407 Fix compressed rollout search path matching @jif-oai - openai#27304 [codex] Remove async_trait from ToolExecutor @anp-oai - openai#26041 Add app-server background terminal process APIs @etraut-openai - openai#25018 Add app-server `thread/delete` API @etraut-openai - openai#26859 fix: Auto-recover from corrupted sqlite databases @ddr-oai - openai#27064 [codex] remove blocking external agent migration flow @stefanstokic-oai - openai#27421 [codex] Raise app-server recursion limit @anp-oai - openai#27062 [codex] Retry transient Guardian review failures @kbazzi - openai#27065 [codex] extract external agent import picker renderer @stefanstokic-oai - openai#26409 [plugins] Inject remote_plugin_id into install elicitations @adaley-openai - openai#27439 feat: make ThreadStore available on ThreadExtensionDependencies @bolinfest - openai#27343 Guard core test subprocess cleanup @etraut-openai - openai#27070 [codex] add external agent import picker UX @stefanstokic-oai - openai#27321 [codex] Move release platform rules into bazel package @anp-oai - openai#27071 [codex] add /import for external agents @stefanstokic-oai - openai#27311 [codex] Skip local curated discovery for remote plugins @xl-openai - openai#27414 [codex] Preserve disabled MCP servers across runtime overlays @e-provencher - openai#27312 [codex] reuse release artifacts for npm staging @tamird - openai#27319 Forward standalone assistant output to realtime @guinness-oai - openai#27057 [codex] Add reusable OTEL gauge instruments @richardopenai - openai#27245 image: add shared data URL preparation utilities @fjord-oai - openai#27392 [codex-analytics] emit internally started turn events @marksteinbrick-oai - openai#27322 [codex] Preserve build-script dependencies in rules_rs annotations @anp-oai - openai#27489 core: cache turn diff rendering @nornagon-openai - openai#27465 [codex] Remove redundant plugin app auth state @xl-openai - openai#27484 Remove TUI legacy core test_support dependencies @etraut-openai - openai#27476 Add session delete commands in CLI and TUI @etraut-openai - openai#27247 core: resize all history images behind a feature flag @fjord-oai - openai#27487 Trim TUI legacy telemetry and migration dependencies @etraut-openai - openai#27438 [codex] Add token budget context feature @pakrym-oai - openai#27501 [codex] Expand hosted web search citation guidance @yuning-oai - openai#27526 tools: simplify default tool search text @sayan-oai - openai#27488 [codex] Add new context window tool @pakrym-oai - openai#27443 feat: add Bedrock API key as a managed auth mode @celia-oai - openai#27532 [codex] Add comp_hash to model metadata @aibrahim-oai - openai#27246 core: strip image detail from Responses Lite requests @fjord-oai - openai#27517 [codex] Pass auth mode to plugin manager @xl-openai - openai#27520 [codex] Compact when comp_hash changes @aibrahim-oai - openai#27518 [codex] Add context remaining tool @pakrym-oai - openai#27266 image: preserve metadata when resizing prompt images @fjord-oai - openai#27103 [codex-analytics] report cached input tokens for v2 compaction @rhan-oai - openai#27356 Use generic search metadata for dynamic tools @sayan-oai - openai#27082 [codex-analytics] Emit structured compaction codex errors @rhan-oai - openai#26513 [codex] Tune cloud config cache intervals @alexsong-oai - openai#27387 skills: make backend plugin skills invocable without an executor @jif-oai - openai#27403 skills: cache remote catalog failures per thread @jif-oai - openai#27573 core: enable remote compaction v2 by default @jif-oai - openai#27388 skills: expose remote skill resource tools @jif-oai - openai#27569 multi-agent: move concurrency guidance into v2 usage hints @jif-oai - openai#27585 nit: cap error @jif-oai - openai#27404 test: cover referenced backend skill reads without an executor @jif-oai - openai#27591 skills: render catalog locators by authority @jif-oai - openai#27413 skills: decouple the skills extension from core @jif-oai - openai#27527 [codex] publish npm packages concurrently @tamird - openai#27528 [codex] publish DotSlash alongside npm @tamird - openai#27529 [codex] download only release artifacts @tamird - openai#27490 Remove TUI legacy Windows sandbox dependency @etraut-openai - openai#27483 Emit plugin ID on MCP tool call analytics events @chrisdong-oai - openai#27417 Print TUI session info on fatal exits @etraut-openai - openai#27507 lint: allow self-documenting builder arguments @anp-oai - openai#27420 [codex] Propagate plugin app categories @charlesgong-openai - openai#27454 [codex] add cross-platform filesystem adapter coverage @anp-oai - openai#27415 [codex] Surface runtime warnings in codex exec @anp-oai - openai#27639 [codex] revert concurrent npm publishing @tamird - openai#27646 feat: disable orchestrator skills for now @jif-oai - openai#27323 [codex] Provide ARM64 MinGW powl compatibility support @anp-oai - openai#27433 [codex] remove EnvironmentPathRef @anp-oai - openai#27424 [codex] migrate ExecutorFileSystem paths to PathUri @anp-oai - openai#27101 [codex] Load user instructions through an injected provider @anp-oai - openai#27634 Resolve MCP server registrations through a catalog @jif-oai - openai#27122 core: Consolidate Responses API Codex metadata @owenlin0 - openai#27450 [codex-rs] enforce PAT workspace restrictions @cooper-oai - openai#27653 [codex] migrate exec-server filesystem protocol to PathUri @anp-oai - openai#27663 Include thread id in token budget context @pakrym-oai - openai#26418 [codex] Avoid duplicate hooks.json discovery with profiles @abhinav-oai - openai#27689 feat: prefer managed Bedrock auth in model provider @celia-oai - openai#27700 Remove fs/join and fs/parent from exec-server protocol @anp-oai - openai#26426 Warn when hooks.json has unsupported top-level fields @abhinav-oai - openai#27318 [codex] Move persistence policy application into ThreadStore @wiltzius-openai - openai#27498 Route image extension reads through turn environments v2 @won-openai - openai#27623 Add spans to turn lifecycle gaps @mchen-oai - openai#27619 tui: clear stale hook row after turn completion @kotakem-openai - openai#27711 Fix image extension PathUri conversion @anp-oai - openai#27475 [codex] Remove async_trait from first-party code @anp-oai - openai#27719 fix: Recover from sqlite directory being a file @ddr-oai - openai#27715 ci(v8): gate Windows source builds on relevant changes @cconger - openai#27702 [codex] parallelize release code generation @tamird - openai#27709 [codex] resolve environment shell metadata eagerly @pakrym-oai - openai#27445 feat(app-server): persist remote-control desired state @apanasenko-oai - openai#27508 [1 of 3] Support long raw TUI goal objectives @etraut-openai - openai#27256 Add request_user_input auto-resolution window contract @shijie-oai - openai#27724 code-mode standalone: extract protocol and add host crate @cconger - openai#27778 Translate non-English issues @etraut-openai - openai#27316 Keep request_user_input direct-model only @shijie-oai - openai#27696 [codex] Load AGENTS.md from all bound environments @anp-oai - openai#27670 Make MCP server contributions thread-scoped @jif-oai - openai#27732 [code-mode] Reject remote image URLs from output helpers @rka-oai - openai#27692 Add executor-owned plugin resolution @jif-oai - openai#27863 Extract shared plugin MCP config parsing @jif-oai - openai#27703 [codex] restore source-specific import copy @stefanstokic-oai - openai#27879 fix: serialize auth environment tests @jif-oai - openai#27791 Reject transcript backtrack in side conversations @etraut-openai - openai#27075 [ez][codex-rs] Support approvals reviewer in app defaults @zamoshchin-openai - openai#27538 Use dependency groups for Python SDK tooling @charliemarsh-oai - openai#27783 Persist update dismissal without cache @etraut-openai - openai#27814 tui: Allow extra o's in /goal command @btraut-openai - openai#27901 Use uv as Python SDK build backend @charliemarsh-oai - openai#27720 realtime: add AVAS architecture override @bakks - openai#27919 chore: prompt MAv2 @jif-oai - openai#27816 sandboxing: migrate cwd inputs to PathUri @anp-oai - openai#27890 [codex] expose remote plugin share URL @ericning-o - openai#27913 [codex] unify apply patch parsing @pakrym-oai - openai#27920 Handle standalone image generation failures as terminal items @won-openai - openai#27927 [codex] Add size to internal filesystem metadata @pakrym-oai - openai#27504 feat: add secret auth storage configuration @celia-oai - openai#27674 [login] revoke existing auth before starting login @cooper-oai - openai#27535 feat: add auth-specific encrypted secret namespaces @celia-oai - openai#27939 [codex] Add crate API surface review rule @pakrym-oai - openai#27926 [codex] Align implicit skill reads with parser @alexsong-oai - openai#23254 fix(plugins) rm plugin descriptions @dylan-hurd-oai - openai#27830 Support plaintext agent messages @jif-oai - openai#27801 Remove TUI realtime voice support @etraut-openai - openai#27539 feat: use encrypted local secrets for CLI auth @celia-oai - openai#27076 Warn for structured feature toggles @canvrno-oai - openai#27541 feat: use encrypted local secrets for MCP OAuth @celia-oai - openai#27936 [codex] add roles to realtime append text @agamble-oai - openai#27509 [2 of 3] Support long pasted text in TUI goals @etraut-openai - openai#27109 Add Guardian catalog diagnostics metadata @won-openai - openai#27966 Specify platform support in AGENTS.md @anp-oai - openai#27855 [codex] parallelize Windows compression @tamird - openai#27499 Promote TUI unified mentions in composer to default mentions feature @canvrno-oai - openai#27972 [codex] Let generic test turns inherit their environment @pakrym-oai - openai#27856 [codex] package Windows symbols in parallel @tamird - openai#27976 [codex] make PathUri::from_abs_path infallible @anp-oai - openai#27854 [codex] parallelize Windows package archives @tamird - openai#27853 [codex] stage npm packages concurrently @tamird - openai#27710 [codex] add latency tracing spans @rphilizaire-openai - openai#27510 [3 of 3] Support images in TUI goals @etraut-openai - openai#27925 feat(tui): reland token activity command @fcoury-oai - openai#27988 [codex] Limit app-based plugin suggestions to remote catalogs @xl-openai - openai#27652 [codex] Add auth mode to plugin manager constructor @felixxia-oai - openai#27964 [codex] Add hermetic Wine test support @anp-oai - openai#27459 [codex] Gate plugin MCP servers by auth route @felixxia-oai - openai#27961 feat(app-server): enforce managed remote control disable @apanasenko-oai - openai#27937 [codex] Add hermetic Wine exec-server test @anp-oai - openai#27996 [codex] Send request-scoped turn state over WebSocket @aibrahim-oai - openai#28002 [codex] Send turn state through compact requests @aibrahim-oai
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
rust-v0.140.0into the forkstablebranch.Fork-contract conflict notes
Local verification
just write-app-server-schemajust write-config-schemajust bazel-lock-updatejust bazel-lock-checkjust fmtjust test -p codex-app-server-protocolpassed 243/243just test -p codex-core-skillspassed 102/102just test -p codex-skills-extensionpassed 8/8just test -p codex-mcppassed 83/83just test -p codex-loginpassed 140/140just test -p codex-statepassed 148/148just test -p codex-toolspassed 86/86just test -p codex-tuipassed 2930/2930, with 1 leaky and 4 skippedcodex-coremerge-drift tests passed for state migration numbering, thread-spawn lineage metadata, token-count payloads, token-budget context windows, and skill injection.just fix -p codex-toolsjust fix -p codex-core -p codex-app-server -p codex-tui -p codex-mcp -p codex-login -p codex-state -p codex-core-skills -p codex-skills-extensionLocal environment caveats
just test -p codex-corestill has local harness failures dominated by nested Seatbelt (sandbox-exec: sandbox_apply: Operation not permitted), missing localtest_stdio_server, and sandbox/network hook expectations. Focused merge-drift failures were resolved.just test -p codex-app-serverimproved to 875 passed, 3 failed, 1 timed out, 3 skipped. Remaining failures are local nested sandbox/network/image file access issues.just fix/just fmtpass.