mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
c4e53d103c102f8d5201247adbc60bbddd47c88d
32 Commits
-
Migrate exec-server remote registration to environments (#23633)
## Summary - migrate exec-server remote registration naming from executor to environment - align CLI, public Rust exports, registry error messages, and relay test fixtures with the environment registry contract - keep the live registration path and response model consistent with `/cloud/environment/{environment_id}/register` ## Verification - `cargo test -p codex-exec-server remote::tests::register_environment_posts_with_auth_provider_headers --manifest-path /Users/richardlee/code/codex/codex-rs/Cargo.toml` - `cargo test -p codex-exec-server --test relay multiplexed_remote_environment_routes_independent_virtual_streams --manifest-path /Users/richardlee/code/codex/codex-rs/Cargo.toml` - `cargo check -p codex-cli --manifest-path /Users/richardlee/code/codex/codex-rs/Cargo.toml` (still running when PR opened; will update after completion if needed)richardopenai ·
2026-05-20 00:25:04 -07:00 -
exec-server: support auth-backed remote executor registration (#22769)
This updates remote `exec-server` registration to use normal Codex auth instead of a registry-issued credential. The registry request is built from the existing auth-provider path, which preserves the biscuit-only registry contract introduced in [openai/openai#924101](https://github.com/openai/openai/pull/924101) while removing the old remote registry bearer env var and its direct transport assumptions. The default remote flow uses persisted ChatGPT auth from the normal Codex config/storage path. This PR also includes the containerized Agent Identity path needed by [openai/openai#924260](https://github.com/openai/openai/pull/924260): remote `exec-server` accepts `--allow-agent-identity-auth`, permits Agent Identity auth loaded from `CODEX_ACCESS_TOKEN` only when that flag is present, and reuses the existing Agent task registration plus derived `AgentAssertion` header generation. API-key auth remains unsupported, and Agent Identity stays opt-in. Validation performed beyond normal presubmit coverage: - `cargo fmt --all --check` - `cargo check -p codex-cli` - `cargo test -p codex-exec-server` - `cargo test -p codex-cli exec_server_agent_identity_auth_flag_` - `cargo test -p codex-cli remote_exec_server_auth_mode_` I also attempted `cargo test -p codex-cli`. The new CLI tests passed inside that run, but the suite ended on an unrelated local marketplace-state failure in `plugin_list_excludes_unconfigured_repo_local_marketplaces`.
Michael Zeng ·
2026-05-16 12:48:28 -07:00 -
feat(exec-server): use protobuf relay frames (#22343)
## Why Remote exec-server now needs one executor websocket to serve multiple harness JSON-RPC sessions. Rendezvous routes by `stream_id`, and the exec-server side needs to use the same stable relay frame contract instead of a hand-rolled JSON shape. The relay protocol also needs to make ownership boundaries clear: harness and executor endpoints own sequencing, acks, retries, duplicate suppression, segmentation, and reassembly; rendezvous only routes frames. ## What Changed - Add the checked-in `codex.exec_server.relay.v1.RelayMessageFrame` proto plus generated prost bindings for `codex-exec-server`. - Encode remote harness/executor relay traffic as binary protobuf websocket frames while keeping local websocket JSON-RPC unchanged. - Demux executor-side relay streams into independent `ConnectionProcessor` sessions keyed by `stream_id`. - Add a programmatic `RemoteExecutorConfig::with_bearer_token(...)` constructor for non-CLI callers and integration tests. - Add an integration test that starts the remote executor against a fake registry/rendezvous websocket and verifies two virtual streams share one executor websocket without cross-talk, including per-stream reset behavior. - Document the remote relay envelope, sequence ranges, `ack`/`ack_bits`, and endpoint responsibilities in `exec-server/README.md`. ## Verification - `cargo test -p codex-exec-server --test relay multiplexed_remote_executor_routes_independent_virtual_streams -- --exact` - `cargo test -p codex-exec-server --test relay` - `cargo test -p codex-exec-server` passed outside the sandbox. The sandboxed run hit macOS `sandbox-exec: sandbox_apply: Operation not permitted` in filesystem sandbox tests.
Anton Panasenko ·
2026-05-12 16:50:45 -07:00 -
Load configured environments from CODEX_HOME (#20667)
## Why The earlier PRs add stdio transport support and the config-backed environment provider, but the feature remains inert until normal Codex entrypoints construct `EnvironmentManager` with enough context to discover `CODEX_HOME/environments.toml`. This final stack PR activates the provider while preserving the legacy `CODEX_EXEC_SERVER_URL` fallback when no environments file exists. **Stack position:** this is PR 5 of 5. It is the product wiring PR that activates the configured environment provider added in PR 4. ## What Changed - Thread `codex_home` into `EnvironmentManagerArgs`. - Change `EnvironmentManager::new(...)` to load the provider from `CODEX_HOME`. - Preserve legacy behavior by falling back to `DefaultEnvironmentProvider::from_env()` when `environments.toml` is absent. - Make `environments.toml`-backed managers start new threads with all configured environments, default first, while keeping the legacy env-var path single-default. - Update the app-server, TUI, exec, MCP server, connector, prompt-debug, and thread-manager-sample callsites to pass `codex_home` and handle provider-loading errors. ## Self-Review Notes - The multi-environment startup path is intentionally tied to the `environments.toml` provider. Using `>1` configured environment as the only signal would also expand the legacy `CODEX_EXEC_SERVER_URL` provider because it keeps `local` addressable alongside `remote`. - The startup environment list is still derived inside `EnvironmentManager`; the provider only says whether its snapshot should start new threads with all configured environments. - The thread-manager sample was updated to pass the current `ThreadManager::new(...)` installation id argument so the stack compiles under Bazel. ## Stack - 1. https://github.com/openai/codex/pull/20663 - Add stdio exec-server listener - 2. https://github.com/openai/codex/pull/20664 - Add stdio exec-server client transport - 3. https://github.com/openai/codex/pull/20665 - Make environment providers own default selection - 4. https://github.com/openai/codex/pull/20666 - Add CODEX_HOME environments TOML provider - **5. This PR:** https://github.com/openai/codex/pull/20667 - Load configured environments from CODEX_HOME Split from original draft: https://github.com/openai/codex/pull/20508 ## Validation - `just fmt` - `git diff --check` - `bazel build --config=remote --strategy=remote --remote_download_toplevel //codex-rs/thread-manager-sample:codex-thread-manager-sample` - `bazel test --config=remote --strategy=remote --remote_download_toplevel //codex-rs/exec-server:exec-server-unit-tests` - `bazel test --config=remote --strategy=remote --remote_download_toplevel --test_sharding_strategy=disabled --test_arg=default_thread_environment_selections_use_manager_default_id //codex-rs/core:core-unit-tests` - `bazel test --config=remote --strategy=remote --remote_download_toplevel --test_sharding_strategy=disabled --test_arg=start_thread_uses_all_default_environments_from_codex_home //codex-rs/core:core-unit-tests` ## Documentation This activates `CODEX_HOME/environments.toml`; user-facing documentation should be added before this stack is treated as a documented public workflow. --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-05-08 11:17:56 -07:00 -
Add CODEX_HOME environments TOML provider (#20666)
## Why After stdio transports and provider-owned defaults exist, Codex needs a config-backed provider that can describe more than the single legacy `CODEX_EXEC_SERVER_URL` remote. This PR adds that provider without activating it in product entrypoints yet, keeping parser/validation review separate from runtime wiring. **Stack position:** this is PR 4 of 5. It builds on PR 3's provider/default model and adds the `environments.toml` provider used by PR 5. ## What Changed - Add `environment_toml.rs` as the TOML-specific home for parsing, validation, and provider construction. - Keep the TOML schema/provider structs private; the public constructor added here is `EnvironmentManager::from_codex_home(...)`. - Add `TomlEnvironmentProvider`, including validation for: - reserved ids such as `local` and `none` - duplicate ids - unknown explicit defaults - empty programs or URLs - exactly one of `url` or `program` per configured environment - Support websocket environments with `url = "ws://..."` / `wss://...`. - Support stdio-command environments with `program = "..."`. - Add helpers to load `environments.toml` from `CODEX_HOME`, but do not wire entrypoints to call them yet. - Add the `toml` dependency for parsing. ## Stack - 1. https://github.com/openai/codex/pull/20663 - Add stdio exec-server listener - 2. https://github.com/openai/codex/pull/20664 - Add stdio exec-server client transport - 3. https://github.com/openai/codex/pull/20665 - Make environment providers own default selection - **4. This PR:** https://github.com/openai/codex/pull/20666 - Add CODEX_HOME environments TOML provider - 5. https://github.com/openai/codex/pull/20667 - Load configured environments from CODEX_HOME Split from original draft: https://github.com/openai/codex/pull/20508 ## Validation Not run locally; this was split out of the original draft stack. ## Documentation This introduces the config shape for `environments.toml`; user-facing documentation should be added before this stack is treated as a documented public workflow. --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-05-08 01:37:47 +00:00 -
Add stdio exec-server client transport (#20664)
## Why Configured environments need to connect to exec-server instances that are not necessarily already listening on a websocket URL. A command-backed stdio transport lets Codex start an exec-server process, speak JSON-RPC over its stdio streams, and clean up that child process with the client lifetime. **Stack position:** this is PR 2 of 5. It builds on the server-side stdio listener from PR 1 and provides the client transport used by later environment/config PRs. ## What Changed - Add `ExecServerTransport` variants for websocket URLs and stdio shell commands. - Add stdio command connection support for `ExecServerClient`. - Move websocket/stdio transport setup into `client_transport.rs` so `client.rs` stays focused on shared JSON-RPC client, session, HTTP, and notification behavior. - Tie stdio child process cleanup to the JSON-RPC connection lifetime with a RAII lifetime guard. - Keep existing websocket environment behavior by adapting URL-backed remotes to `ExecServerTransport::WebSocketUrl`. ## Stack - 1. https://github.com/openai/codex/pull/20663 - Add stdio exec-server listener - **2. This PR:** https://github.com/openai/codex/pull/20664 - Add stdio exec-server client transport - 3. https://github.com/openai/codex/pull/20665 - Make environment providers own default selection - 4. https://github.com/openai/codex/pull/20666 - Add CODEX_HOME environments TOML provider - 5. https://github.com/openai/codex/pull/20667 - Load configured environments from CODEX_HOME Split from original draft: https://github.com/openai/codex/pull/20508 ## Validation Not run locally; this was split out of the original draft stack and then refactored to separate transport setup from the base client. --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-05-07 23:48:50 +00:00 -
Add cloud executor registration to exec-server (#19575)
## Summary This PR adds the first `codex-rs` milestone for remote-exec e2e: a local `codex exec-server` can now register itself with `codex-cloud-environments` and attach to the returned rendezvous websocket. At a high level, `codex exec-server --cloud ...` now: - loads ChatGPT auth from normal Codex config - registers an executor with `codex-cloud-environments` - receives a signed rendezvous websocket URL - serves the existing exec-server JSON-RPC protocol over that websocket ## What Changed - Added `--cloud`, `--cloud-base-url`, `--cloud-environment-id`, and `--cloud-name` to `codex exec-server` - Added a new `exec-server/src/cloud.rs` module that handles: - registration requests - auth/header setup - bounded auth retry on `401/403` - reconnect/backoff after websocket disconnects - Reused the existing `ConnectionProcessor` / `ExecServerHandler` path so cloud mode serves the same exec/filesystem RPC surface as local websocket mode - Added cloud-specific error variants and minimal docs for the new mode ## Testing Manual e2e test that fully goes through exec server flow with our codex cloud agent as orchestrator
Michael Zeng ·
2026-05-05 22:01:48 +00:00 -
Add environment provider snapshot (#20058)
## Summary - Change `EnvironmentProvider` to return concrete `Environment` instances instead of `EnvironmentConfigurations`. - Make `DefaultEnvironmentProvider` provide the provider-visible `local` environment plus optional `remote` environment from `CODEX_EXEC_SERVER_URL`. - Keep `EnvironmentManager` as the concrete cache while exposing its own explicit local environment for `local_environment()` fallback paths. ## Validation - `just fmt` - `git diff --check` --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-04-28 20:05:18 -07:00 -
Refactor exec-server filesystem API into codex-file-system (#19892)
## Summary - Extracted the shared filesystem types and `ExecutorFileSystem` trait into a new `codex-file-system` crate - Switched `codex-config` and `codex-git-utils` to depend on that crate instead of `codex-exec-server` - Kept `codex-exec-server` re-exporting the same API for existing callers ## Testing - Ran `cargo test -p codex-file-system` - Ran `cargo test -p codex-git-utils` - Ran `cargo test -p codex-config` - Ran `cargo test -p codex-exec-server` - Ran `just fix -p codex-file-system`, `just fix -p codex-git-utils`, `just fix -p codex-config`, `just fix -p codex-exec-server` - Ran `just fmt` - Updated and verified the Bazel module lockfile
Michael Zeng ·
2026-04-27 17:43:15 -07:00 -
Add sticky environment API and thread state (#18897)
## Summary - add sticky environment selections to app-server v2 thread/start and turn/start request flow - carry thread-level selections through core session/thread state - add app-server coverage for sticky selections and turn overrides ## Stack 1. This PR: API and thread persistence 2. #18898: config.toml named environment loading 3. #18899: downstream tool/runtime consumers ## Validation - Not run locally; split only. --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-04-23 18:57:13 -07:00 -
[3/4] Add executor-backed RMCP HTTP client (#18583)
### Why The RMCP layer needs a Streamable HTTP client that can talk either directly over `reqwest` or through the executor HTTP runner without duplicating MCP session logic higher in the stack. This PR adds that client-side transport boundary so remote Streamable HTTP MCP can reuse the same RMCP flow as the local path. ### What - Add a shared `rmcp-client/src/streamable_http/` module with: - `transport_client.rs` for the local-or-remote transport enum - `local_client.rs` for the direct `reqwest` implementation - `remote_client.rs` for the executor-backed implementation - `common.rs` for the small shared Streamable HTTP helpers - Teach `RmcpClient` to build Streamable HTTP transports in either local or remote mode while keeping the existing OAuth ownership in RMCP. - Translate remote POST, GET, and DELETE session operations into executor `http/request` calls. - Preserve RMCP session expiry handling and reconnect behavior for the remote transport. - Add remote transport coverage in `rmcp-client/tests/streamable_http_remote.rs` and keep the shared test support in `rmcp-client/tests/streamable_http_test_support.rs`. ### Verification - `cargo check -p codex-rmcp-client` - online CI ### Stack 1. #18581 protocol 2. #18582 runner 3. #18583 RMCP client 4. #18584 manager wiring and local/remote coverage --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-22 17:38:04 -07:00 -
Support multiple managed environments (#18401)
## Summary - refactor EnvironmentManager to own keyed environments with default/local lookup helpers - keep remote exec-server client creation lazy until exec/fs use - preserve disabled agent environment access separately from internal local environment access ## Validation - not run (per Codex worktree instruction to avoid tests/builds unless requested) --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-04-21 15:29:35 -07:00 -
[1/4] Add executor HTTP request protocol (#18581)
### Why Remote streamable HTTP MCP needs a transport-shaped executor primitive before the MCP client can move network I/O to the executor. This layer keeps the executor unaware of MCP and gives later PRs an ordered streaming surface for response bodies. ### What - Add typed `http/request` and `http/request/bodyDelta` protocol payloads. - Add executor client helpers for buffered and streamed HTTP responses. - Route body-delta notifications to request-scoped streams with sequence validation and cleanup when a stream finishes or is dropped. - Document the new protocol constants, transport structs, public client methods, body-stream lifecycle, and request-scoped routing helpers. - Add in-memory JSON-RPC client coverage for streamed HTTP response-body notifications, with comments spelling out what the test proves and each setup/exercise/assert phase. ### Stack 1. #18581 protocol 2. #18582 runner 3. #18583 RMCP client 4. #18584 manager wiring and local/remote coverage ### Verification - `just fmt` - `cargo check -p codex-exec-server -p codex-rmcp-client --tests` - `cargo check -p codex-core --test all` compile-only - `git diff --check` - Online full CI is running from the `full-ci` branch, including the remote Rust test job. Co-authored-by: Codex <noreply@openai.com> --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-21 02:21:08 +00:00 -
[3/6] Add pushed exec process events (#18020)
## Summary - Add a pushed `ExecProcessEvent` stream alongside retained `process/read` output. - Publish local and remote output, exit, close, and failure events. - Cover the event stream with shared local/remote exec process tests. ## Testing - `cargo check -p codex-exec-server` - `cargo check -p codex-rmcp-client` - Not run: `cargo test` per repo instruction; CI will cover. ## Stack ```text o #18027 [6/6] Fail exec client operations after disconnect │ o #18212 [5/6] Wire executor-backed MCP stdio │ o #18087 [4/6] Abstract MCP stdio server launching │ @ #18020 [3/6] Add pushed exec process events │ o #18086 [2/6] Support piped stdin in exec process API │ o #18085 [1/6] Add MCP server environment config │ o main ``` --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-17 19:07:43 +00:00 -
Build remote exec env from exec-server policy (#17216)
## Summary - add an exec-server `envPolicy` field; when present, the server starts from its own process env and applies the shell environment policy there - keep `env` as the exact environment for local/embedded starts, but make it an overlay for remote unified-exec starts - move the shell-environment-policy builder into `codex-config` so Core and exec-server share the inherit/filter/set/include behavior - overlay only runtime/sandbox/network deltas from Core onto the exec-server-derived env ## Why Remote unified exec was materializing the shell env inside Core and forwarding the whole map to exec-server, so remote processes could inherit the orchestrator machine's `HOME`, `PATH`, etc. This keeps the base env on the executor while preserving Core-owned runtime additions like `CODEX_THREAD_ID`, unified-exec defaults, network proxy env, and sandbox marker env. ## Validation - `just fmt` - `git diff --check` - `cargo test -p codex-exec-server --lib` - `cargo test -p codex-core --lib unified_exec::process_manager::tests` - `cargo test -p codex-core --lib exec_env::tests` - `cargo test -p codex-core --lib exec_env_tests` (compile-only; filter matched 0 tests) - `cargo test -p codex-config --lib shell_environment` (compile-only; filter matched 0 tests) - `just bazel-lock-update` ## Known local validation issue - `just bazel-lock-check` is not runnable in this checkout: it invokes `./scripts/check-module-bazel-lock.sh`, which is missing. --------- Co-authored-by: Codex <noreply@openai.com> Co-authored-by: pakrym-oai <pakrym@openai.com>
jif-oai ·
2026-04-13 09:59:08 +01:00 -
Run exec-server fs operations through sandbox helper (#17294)
## Summary - run exec-server filesystem RPCs requiring sandboxing through a `codex-fs` arg0 helper over stdin/stdout - keep direct local filesystem execution for `DangerFullAccess` and external sandbox policies - remove the standalone exec-server binary path in favor of top-level arg0 dispatch/runtime paths - add sandbox escape regression coverage for local and remote filesystem paths ## Validation - `just fmt` - `git diff --check` - remote devbox: `cd codex-rs && bazel test --bes_backend= --bes_results_url= //codex-rs/exec-server:all` (6/6 passed) --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-04-12 18:36:03 -07:00 -
Add sandbox support to filesystem APIs (#16751)
## Summary - add optional `sandboxPolicy` support to the app-server filesystem request surface - thread sandbox-aware filesystem options through app-server and exec-server adapters - enforce sandboxed read/write access in the filesystem abstraction with focused local and remote coverage ## Validation - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-exec-server file_system` - `cargo test -p codex-app-server suite::v2::fs` --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-04-08 12:10:48 -07:00 -
Make AGENTS.md discovery FS-aware (#15826)
## Summary - make AGENTS.md discovery and loading fully FS-aware and remove the non-FS discover helper - migrate remote-aware codex-core tests to use TestEnv workspace setup instead of syncing a local workspace copy - add AGENTS.md corner-case coverage, including directory fallbacks and remote-aware integration coverage ## Testing - cargo test -p codex-core project_doc -- --nocapture - cargo test -p codex-core hierarchical_agents -- --nocapture - cargo test -p codex-core agents_md -- --nocapture - cargo test -p codex-tui status -- --nocapture - cargo test -p codex-tui-app-server status -- --nocapture - just fix - just fmt - just bazel-lock-update - just bazel-lock-check - just argument-comment-lint - remote Linux executor tests in progress via scripts/test-remote-env.sh
pakrym-oai ·
2026-04-06 20:26:21 -07:00 -
Disable env-bound tools when exec server is none (#16349)
## Summary - make `CODEX_EXEC_SERVER_URL=none` map to an explicit disabled environment mode instead of inferring from a missing URL - expose environment capabilities (`exec_enabled`, `filesystem_enabled`) so tool building can gate behavior explicitly and future multi-environment work has a clearer seam - suppress env-backed tools when the relevant capability is unavailable, including exec tools, `js_repl`, `apply_patch`, `list_dir`, and `view_image` - keep handler/runtime backstops so disabled environments still reject execution if a tool path somehow bypasses registration ## Testing - `just fmt` - `cargo test -p codex-exec-server` - `cargo test -p codex-tools disabled_environment_omits_environment_backed_tools` - `cargo test -p codex-tools environment_capabilities_gate_exec_and_filesystem_tools_independently` - remote devbox Bazel build via `codex-applied-devbox`: `//codex-rs/cli:cli`
starr-openai ·
2026-04-06 17:22:06 -07:00 -
feat: use
ProcessIdinexec-server(#15866)Use a full struct for the ProcessId to increase readability and make it easier in the future to make it evolve if needed
jif-oai ·
2026-03-26 16:45:36 +01:00 -
feat: exec-server prep for unified exec (#15691)
This PR partially rebase `unified_exec` on the `exec-server` and adapt the `exec-server` accordingly. ## What changed in `exec-server` 1. Replaced the old "broadcast-driven; process-global" event model with process-scoped session events. The goal is to be able to have dedicated handler for each process. 2. Add to protocol contract to support explicit lifecycle status and stream ordering: - `WriteResponse` now returns `WriteStatus` (Accepted, UnknownProcess, StdinClosed, Starting) instead of a bool. - Added seq fields to output/exited notifications. - Added terminal process/closed notification. 3. Demultiplexed remote notifications into per-process channels. Same as for the event sys 4. Local and remote backends now both implement ExecBackend. 5. Local backend wraps internal process ID/operations into per-process ExecProcess objects. 6. Remote backend registers a session channel before launch and unregisters on failed launch. ## What changed in `unified_exec` 1. Added unified process-state model and backend-neutral process wrapper. This will probably disappear in the future, but it makes it easier to keep the work flowing on both side. - `UnifiedExecProcess` now handles both local PTY sessions and remote exec-server processes through a shared `ProcessHandle`. - Added `ProcessState` to track has_exited, exit_code, and terminal failure message consistently across backends. 2. Routed write and lifecycle handling through process-level methods. ## Some rationals 1. The change centralizes execution transport in exec-server while preserving policy and orchestration ownership in core, avoiding duplicated launch approval logic. This comes from internal discussion. 2. Session-scoped events remove coupling/cross-talk between processes and make stream ordering and terminal state explicit (seq, closed, failed). 3. The failure-path surfacing (remote launch failures, write failures, transport disconnects) makes command tool output and cleanup behavior deterministic ## Follow-ups: * Unify the concept of thread ID behind an obfuscated struct * FD handling * Full zsh-fork compatibility * Full network sandboxing compatibility * Handle ws disconnection
jif-oai ·
2026-03-26 15:22:34 +01:00 -
Add cached environment manager for exec server URL (#15785)
Add environment manager that is a singleton and is created early in app-server (before skill manager, before config loading). Use an environment variable to point to a running exec server.
pakrym-oai ·
2026-03-25 16:14:36 -07:00 -
Split exec process into local and remote implementations (#15233)
## Summary - match the exec-process structure to filesystem PR #15232 - expose `ExecProcess` on `Environment` - make `LocalProcess` the real implementation and `RemoteProcess` a thin network proxy over `ExecServerClient` - make `ProcessHandler` a thin RPC adapter delegating to `LocalProcess` - add a shared local/remote process test ## Validation - `just fmt` - `CARGO_TARGET_DIR=~/.cache/cargo-target/codex cargo test -p codex-exec-server` - `just fix -p codex-exec-server` --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-03-20 03:13:08 +00:00 -
Refactor ExecServer filesystem split between local and remote (#15232)
For each feature we have: 1. Trait exposed on environment 2. **Local Implementation** of the trait 3. Remote implementation that uses the client to proxy via network 4. Handler implementation that handles PRC requests and calls into **Local Implementation**
pakrym-oai ·
2026-03-19 17:08:04 -07:00 -
Add exec-server exec RPC implementation (#15090)
Stacked PR 2/3, based on the stub PR. Adds the exec RPC implementation and process/event flow in exec-server only. --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-03-19 19:00:36 +00:00 -
Move environment abstraction into exec server (#15125)
The idea is that codex-exec exposes an Environment struct with services on it. Each of those is a trait. Depending on construction parameters passed to Environment they are either backed by local or remote server but core doesn't see these differences.
pakrym-oai ·
2026-03-19 08:31:14 -07:00 -
Remove stdio transport from exec server (#15119)
Summary - delete the deprecated stdio transport plumbing from the exec server stack - add a basic `exec_server()` harness plus test utilities to start a server, send requests, and await events - refresh exec-server dependencies, configs, and documentation to reflect the new flow Testing - Not run (not requested) --------- Co-authored-by: starr-openai <starr@openai.com> Co-authored-by: Codex <noreply@openai.com>
pakrym-oai ·
2026-03-19 01:00:35 +00:00 -
Add exec-server stub server and protocol docs (#15089)
Stacked PR 1/3. This is the initialize-only exec-server stub slice: binary/client scaffolding and protocol docs, without exec/filesystem implementation. --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-03-19 00:30:05 +00:00 -
refactor: delete exec-server and move execve wrapper into shell-escalation (#12632)
## Why We already plan to remove the shell-tool MCP path, and doing that cleanup first makes the follow-on `shell-escalation` work much simpler. This change removes the last remaining reason to keep `codex-rs/exec-server` around by moving the `codex-execve-wrapper` binary and shared shell test fixtures to the crates/tests that now own that functionality. ## What Changed ### Delete `codex-rs/exec-server` - Remove the `exec-server` crate, including the MCP server binary, MCP-specific modules, and its test support/test suite - Remove `exec-server` from the `codex-rs` workspace and update `Cargo.lock` ### Move `codex-execve-wrapper` into `codex-rs/shell-escalation` - Move the wrapper implementation into `shell-escalation` (`src/unix/execve_wrapper.rs`) - Add the `codex-execve-wrapper` binary entrypoint under `shell-escalation/src/bin/` - Update `shell-escalation` exports/module layout so the wrapper entrypoint is hosted there - Move the wrapper README content from `exec-server` to `shell-escalation/README.md` ### Move shared shell test fixtures to `app-server` - Move the DotSlash `bash`/`zsh` test fixtures from `exec-server/tests/suite/` to `app-server/tests/suite/` - Update `app-server` zsh-fork tests to reference the new fixture paths ### Keep `shell-tool-mcp` as a shell-assets package - Update `.github/workflows/shell-tool-mcp.yml` packaging so the npm artifact contains only patched Bash/Zsh payloads (no Rust binaries) - Update `shell-tool-mcp/package.json`, `shell-tool-mcp/src/index.ts`, and docs to reflect the shell-assets-only package shape - `shell-tool-mcp-ci.yml` does not need changes because it is already JS-only ## Verification - `cargo shear` - `cargo clippy -p codex-shell-escalation --tests` - `just clippy`
Michael Bolin ·
2026-02-23 20:10:22 -08:00 -
refactor: normalize unix module layout for exec-server and shell-escalation (#12556)
## Why Shell execution refactoring in `exec-server` had become split between duplicated code paths, which blocked a clean introduction of the new reusable shell escalation flow. This commit creates a dedicated foundation crate so later shell tooling changes can share one implementation. ## What changed - Added the `codex-shell-escalation` crate and moved the core escalation pieces (`mcp` protocol/socket/session flow, policy glue) that were previously in `exec-server` into it. - Normalized `exec-server` Unix structure under a dedicated `unix` module layout and kept non-Unix builds narrow. - Wired crate/build metadata so `shell-escalation` is a first-class workspace dependency for follow-on integration work. ## Verification - Built and linted the stack at this commit point with `just clippy`. [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/12556). * #12584 * #12583 * __->__ #12556
Michael Bolin ·
2026-02-23 09:28:17 -08:00 -
fix: add integration tests for codex-exec-mcp-server with execpolicy (#7617)
This PR introduces integration tests that run [codex-shell-tool-mcp](https://www.npmjs.com/package/@openai/codex-shell-tool-mcp) as a user would. Note that this requires running our fork of Bash, so we introduce a [DotSlash](https://dotslash-cli.com/) file for `bash` so that we can run the integration tests on multiple platforms without having to check the binaries into the repository. (As noted in the DotSlash file, it is slightly more heavyweight than necessary, which may be worth addressing as disk space in CI is limited: https://github.com/openai/codex/pull/7678.) To start, this PR adds two tests: - `list_tools()` makes the `list_tools` request to the MCP server and verifies we get the expected response - `accept_elicitation_for_prompt_rule()` defines a `prefix_rule()` with `decision="prompt"` and verifies the elicitation flow works as expected Though the `accept_elicitation_for_prompt_rule()` test **only works on Linux**, as this PR reveals that there are currently issues when running the Bash fork in a read-only sandbox on Linux. This will have to be fixed in a follow-up PR. Incidentally, getting this test run to correctly on macOS also requires a recent fix we made to `brew` that hasn't hit a mainline release yet, so getting CI green in this PR required https://github.com/openai/codex/pull/7680.
Michael Bolin ·
2025-12-07 06:39:38 +00:00 -
chore: refactor exec-server to prepare it for standalone MCP use (#6944)
This PR reorganizes things slightly so that: - Instead of a single multitool executable, `codex-exec-server`, we now have two executables: - `codex-exec-mcp-server` to launch the MCP server - `codex-execve-wrapper` is the `execve(2)` wrapper to use with the `BASH_EXEC_WRAPPER` environment variable - `BASH_EXEC_WRAPPER` must be a single executable: it cannot be a command string composed of an executable with args (i.e., it no longer adds the `escalate` subcommand, as before) - `codex-exec-mcp-server` takes `--bash` and `--execve` as options. Though if `--execve` is not specified, the MCP server will check the directory containing `std::env::current_exe()` and attempt to use the file named `codex-execve-wrapper` within it. In development, this works out since these executables are side-by-side in the `target/debug` folder. With respect to testing, this also fixes an important bug in `dummy_exec_policy()`, as I was using `ends_with()` as if it applied to a `String`, but in this case, it is used with a `&Path`, so the semantics are slightly different. Putting this all together, I was able to test this by running the following: ``` ~/code/codex/codex-rs$ npx @modelcontextprotocol/inspector \ ./target/debug/codex-exec-mcp-server --bash ~/code/bash/bash ``` If I try to run `git status` in `/Users/mbolin/code/codex` via the `shell` tool from the MCP server: <img width="1589" height="1335" alt="image" src="https://github.com/user-attachments/assets/9db6aea8-7fbc-4675-8b1f-ec446685d6c4" /> then I get prompted with the following elicitation, as expected: <img width="1589" height="1335" alt="image" src="https://github.com/user-attachments/assets/21b68fe0-494d-4562-9bad-0ddc55fc846d" /> Though a current limitation is that the `shell` tool defaults to a timeout of 10s, which means I only have 10s to respond to the elicitation. Ideally, the time spent waiting for a response from a human should not count against the timeout for the command execution. I will address this in a subsequent PR. --- Note `~/code/bash/bash` was created by doing: ``` cd ~/code git clone https://github.com/bminor/bash cd bash git checkout a8a1c2fac029404d3f42cd39f5a20f24b6e4fe4b <apply the patch below> ./configure make ``` The patch: ``` diff --git a/execute_cmd.c b/execute_cmd.c index 070f5119..d20ad2b9 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -6129,6 +6129,19 @@ shell_execve (char *command, char **args, char **env) char sample[HASH_BANG_BUFSIZ]; size_t larray; + char* exec_wrapper = getenv("BASH_EXEC_WRAPPER"); + if (exec_wrapper && *exec_wrapper && !whitespace (*exec_wrapper)) + { + char *orig_command = command; + + larray = strvec_len (args); + + memmove (args + 2, args, (++larray) * sizeof (char *)); + args[0] = exec_wrapper; + args[1] = orig_command; + command = exec_wrapper; + } + ```Michael Bolin ·
2025-11-19 16:38:14 -08:00