mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
da86cedbd439d38fbd7e613e4e88f8f6f138debb
116 Commits
-
Make skill loading filesystem-aware (#17720)
Migrates skill loading to support reading repo skills from the remote environment.
pakrym-oai ·
2026-04-14 15:40:40 -07:00 -
[codex] Remove unused Rust helpers (#17146)
## Summary Removes high-confidence unused Rust helper functions and exports across `codex-tui`, `codex-shell-command`, and utility crates. The cleanup includes dead TUI helper methods, unused path/string/elapsed/fuzzy-match utilities, an unused Windows PowerShell lookup helper, and the unused terminal palette version counter. This keeps the remaining public surface smaller without changing behavior. ## Validation - `just fmt` - `cargo test -p codex-tui -p codex-shell-command -p codex-utils-elapsed -p codex-utils-fuzzy-match -p codex-utils-string -p codex-utils-path` - `just fix -p codex-tui -p codex-shell-command -p codex-utils-elapsed -p codex-utils-fuzzy-match -p codex-utils-string -p codex-utils-path` - `git diff --check`
pakrym-oai ·
2026-04-13 18:27:00 -07:00 -
Use AbsolutePathBuf in skill loading and codex_home (#17407)
Helps with FS migration later
pakrym-oai ·
2026-04-13 10:26:51 -07:00 -
Fix thread/list cwd filtering for Windows verbatim paths (#17414)
Addresses #17302 Problem: `thread/list` compared cwd filters with raw path equality, so `resume --last` could miss Windows sessions when the saved cwd used a verbatim path form and the current cwd did not. Solution: Normalize cwd comparisons through the existing path comparison utilities before falling back to direct equality, and add Windows regression coverage for verbatim paths. I made this a general utility function and replaced all of the duplicated instance of it across the code base.
Eric Traut ·
2026-04-10 23:08:02 -07:00 -
fix(permissions): fix symlinked writable roots in sandbox permissions (#15981)
## Summary - preserve logical symlink paths during permission normalization and config cwd handling - bind real targets for symlinked readable/writable roots in bwrap and remap carveouts and unreadable roots there - add regressions for symlinked carveouts and nested symlink escape masking ## Root cause Permission normalization canonicalized symlinked writable roots and cwd to their real targets too early. That drifted policy checks away from the logical paths the sandboxed process can actually address, while bwrap still needed the real targets for mounts. The mismatch caused shell and apply_patch failures on symlinked writable roots. ## Impact Fixes #15781. Also fixes #17079: - #17079 is the protected symlinked carveout side: bwrap now binds the real symlinked writable-root target and remaps carveouts before masking. Related to #15157: - #15157 is the broader permission-check side of this path-identity problem. This PR addresses the shared logical-vs-canonical normalization issue, but the reported Darwin prompt behavior should be validated separately before auto-closing it. This should also fix #14672, #14694, #14715, and #15725: - #14672, #14694, and #14715 are the same Linux symlinked-writable-root/bwrap family as #15781. - #15725 is the protected symlinked workspace path variant; the PR preserves the protected logical path in policy space while bwrap applies read-only or unreadable treatment to the resolved target so file-vs-directory bind mismatches do not abort sandbox setup. ## Notes - Added Linux-only regressions for symlinked writable ancestors and protected symlinked directory targets, including nested symlink escape masking without rebinding the escape target writable. --------- Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-04-10 17:00:58 -07:00 -
feat: single app-server bootstrap in TUI (#16582)
Before this, the TUI was starting 2 app-server. One to check the login status and one to actually start the session This PR make only one app-server startup and defer the login check in async, outside of the frame rendering path --------- Co-authored-by: Codex <noreply@openai.com>
jif-oai ·
2026-04-08 13:49:06 +01:00 -
[codex] Migrate apply_patch to executor filesystem (#17027)
- Migrate apply-patch verification and application internals to use the async `ExecutorFileSystem` abstraction from `exec-server`. - Convert apply-patch `cwd` handling to `AbsolutePathBuf` through the verifier/parser/handler boundary. Doesn't change how the tool itself works.
pakrym-oai ·
2026-04-07 21:20:22 +00:00 -
[codex] Make AbsolutePathBuf joins infallible (#16981)
Having to check for errors every time join is called is painful and unnecessary.
pakrym-oai ·
2026-04-07 10:52:08 -07:00 -
[codex] reduce module visibility (#16978)
## Summary - reduce public module visibility across Rust crates, preferring private or crate-private modules with explicit crate-root public exports - update external call sites and tests to use the intended public crate APIs instead of reaching through module trees - add the module visibility guideline to AGENTS.md ## Validation - `cargo check --workspace --all-targets --message-format=short` passed before the final fix/format pass - `just fix` completed successfully - `just fmt` completed successfully - `git diff --check` passed
pakrym-oai ·
2026-04-07 08:03:35 -07:00 -
remove temporary ownership re-exports (#16626)
Stacked on #16508. This removes the temporary `codex-core` / `codex-login` re-export shims from the ownership split and rewrites callsites to import directly from `codex-model-provider-info`, `codex-models-manager`, `codex-api`, `codex-protocol`, `codex-feedback`, and `codex-response-debug-context`. No behavior change intended; this is the mechanical import cleanup layer split out from the ownership move. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-03 00:33:34 -07:00 -
Extract MCP into codex-mcp crate (#15919)
- Split MCP runtime/server code out of `codex-core` into the new `codex-mcp` crate. New/moved public structs/types include `McpConfig`, `McpConnectionManager`, `ToolInfo`, `ToolPluginProvenance`, `CodexAppsToolsCacheKey`, and the `McpManager` API (`codex_mcp::mcp::McpManager` plus the `codex_core::mcp::McpManager` wrapper/shim). New/moved functions include `with_codex_apps_mcp`, `configured_mcp_servers`, `effective_mcp_servers`, `collect_mcp_snapshot`, `collect_mcp_snapshot_from_manager`, `qualified_mcp_tool_name_prefix`, and the MCP auth/skill-dependency helpers. Why: this creates a focused MCP crate boundary and shrinks `codex-core` without forcing every consumer to migrate in the same PR. - Move MCP server config schema and persistence into `codex-config`. New/moved structs/enums include `AppToolApproval`, `McpServerToolConfig`, `McpServerConfig`, `RawMcpServerConfig`, `McpServerTransportConfig`, `McpServerDisabledReason`, and `codex_config::ConfigEditsBuilder`. New/moved functions include `load_global_mcp_servers` and `ConfigEditsBuilder::replace_mcp_servers`/`apply`. Why: MCP TOML parsing/editing is config ownership, and this keeps config validation/round-tripping (including per-tool approval overrides and inline bearer-token rejection) in the config crate instead of `codex-core`. - Rewire `codex-core`, app-server, and plugin call sites onto the new crates. Updated `Config::to_mcp_config(&self, plugins_manager)`, `codex-rs/core/src/mcp.rs`, `codex-rs/core/src/connectors.rs`, `codex-rs/core/src/codex.rs`, `CodexMessageProcessor::list_mcp_server_status_task`, and `utils/plugins/src/mcp_connector.rs` to build/pass the new MCP config/runtime types. Why: plugin-provided MCP servers still merge with user-configured servers, and runtime auth (`CodexAuth`) is threaded into `with_codex_apps_mcp` / `collect_mcp_snapshot` explicitly so `McpConfig` stays config-only.
Ahmed Ibrahim ·
2026-04-01 19:03:26 -07:00 -
ci: verify codex-rs Cargo manifests inherit workspace settings (#16353)
## Why Bazel clippy now catches lints that `cargo clippy` can still miss when a crate under `codex-rs` forgets to opt into workspace lints. The concrete example here was `codex-rs/app-server/tests/common/Cargo.toml`: Bazel flagged a clippy violation in `models_cache.rs`, but Cargo did not because that crate inherited workspace package metadata without declaring `[lints] workspace = true`. We already mirror the workspace clippy deny list into Bazel after [#15955](https://github.com/openai/codex/pull/15955), so we also need a repo-side check that keeps every `codex-rs` manifest opted into the same workspace settings. ## What changed - add `.github/scripts/verify_cargo_workspace_manifests.py`, which parses every `codex-rs/**/Cargo.toml` with `tomllib` and verifies: - `version.workspace = true` - `edition.workspace = true` - `license.workspace = true` - `[lints] workspace = true` - top-level crate names follow the `codex-*` / `codex-utils-*` conventions, with explicit exceptions for `windows-sandbox-rs` and `utils/path-utils` - run that script in `.github/workflows/ci.yml` - update the current outlier manifests so the check is enforceable immediately - fix the newly exposed clippy violations in the affected crates (`app-server/tests/common`, `file-search`, `feedback`, `shell-escalation`, and `debug-client`) --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/16353). * #16351 * __->__ #16353
Michael Bolin ·
2026-03-31 21:59:28 +00:00 -
chore: clean up argument-comment lint and roll out all-target CI on macOS (#16054)
## Why `argument-comment-lint` was green in CI even though the repo still had many uncommented literal arguments. The main gap was target coverage: the repo wrapper did not force Cargo to inspect test-only call sites, so examples like the `latest_session_lookup_params(true, ...)` tests in `codex-rs/tui_app_server/src/lib.rs` never entered the blocking CI path. This change cleans up the existing backlog, makes the default repo lint path cover all Cargo targets, and starts rolling that stricter CI enforcement out on the platform where it is currently validated. ## What changed - mechanically fixed existing `argument-comment-lint` violations across the `codex-rs` workspace, including tests, examples, and benches - updated `tools/argument-comment-lint/run-prebuilt-linter.sh` and `tools/argument-comment-lint/run.sh` so non-`--fix` runs default to `--all-targets` unless the caller explicitly narrows the target set - fixed both wrappers so forwarded cargo arguments after `--` are preserved with a single separator - documented the new default behavior in `tools/argument-comment-lint/README.md` - updated `rust-ci` so the macOS lint lane keeps the plain wrapper invocation and therefore enforces `--all-targets`, while Linux and Windows temporarily pass `-- --lib --bins` That temporary CI split keeps the stricter all-targets check where it is already cleaned up, while leaving room to finish the remaining Linux- and Windows-specific target-gated cleanup before enabling `--all-targets` on those runners. The Linux and Windows failures on the intermediate revision were caused by the wrapper forwarding bug, not by additional lint findings in those lanes. ## Validation - `bash -n tools/argument-comment-lint/run.sh` - `bash -n tools/argument-comment-lint/run-prebuilt-linter.sh` - shell-level wrapper forwarding check for `-- --lib --bins` - shell-level wrapper forwarding check for `-- --tests` - `just argument-comment-lint` - `cargo test` in `tools/argument-comment-lint` - `cargo test -p codex-terminal-detection` ## Follow-up - Clean up remaining Linux-only target-gated callsites, then switch the Linux lint lane back to the plain wrapper invocation. - Clean up remaining Windows-only target-gated callsites, then switch the Windows lint lane back to the plain wrapper invocation.
Michael Bolin ·
2026-03-27 19:00:44 -07:00 -
chore: move pty and windows sandbox to Rust 2024 (#15954)
## Why `codex-utils-pty` and `codex-windows-sandbox` were the remaining crates in `codex-rs` that still overrode the workspace's Rust 2024 edition. Moving them forward in a separate PR keeps the baseline edition update isolated from the follow-on Bazel clippy workflow in #15955, while making linting and formatting behavior consistent with the rest of the workspace. This PR also needs Cargo and Bazel to agree on the edition for `codex-windows-sandbox`. Without the Bazel-side sync, the experimental Bazel app-server builds fail once they compile `windows-sandbox-rs`. ## What changed - switch `codex-rs/utils/pty` and `codex-rs/windows-sandbox-rs` to `edition = "2024"` - update `codex-utils-pty` callsites and tests to use the collapsed `if let` form that Clippy expects under the new edition - fix the Rust 2024 fallout in `windows-sandbox-rs`, including the reserved `gen` identifier, `unsafe extern` requirements, and new Clippy findings that surfaced under the edition bump - keep the edition bump separate from a larger unsafe cleanup by temporarily allowing `unsafe_op_in_unsafe_fn` in the Windows entrypoint modules that now report it under Rust 2024 - update `codex-rs/windows-sandbox-rs/BUILD.bazel` to `crate_edition = "2024"` so Bazel compiles the crate with the same edition as Cargo --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/15954). * #15976 * #15955 * __->__ #15954
Michael Bolin ·
2026-03-27 02:31:08 -07:00 -
Expand home-relative paths on Windows (#15817)
Follow up to: https://github.com/openai/codex/pull/9193, also support this for Windows. --------- Co-authored-by: Michael Bolin <mbolin@openai.com>
Tiffany Citra ·
2026-03-25 21:19:57 -07:00 -
Extract codex-utils-plugins crate (#15746)
## Summary - extract shared plugin path and manifest helpers into codex-utils-plugins - update codex-core to consume the utility crate ## Testing - CI --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-25 11:05:35 -07:00 -
feat: rendering library v1 (#15778)
The goal will be to replace askama
jif-oai ·
2026-03-25 16:07:04 +00:00 -
Use AbsolutePathBuf for cwd state (#15710)
Migrate `cwd` and related session/config state to `AbsolutePathBuf` so downstream consumers consistently see absolute working directories. Add test-only `.abs()` helpers for `Path`, `PathBuf`, and `TempDir`, and update branch-local tests to use them instead of `AbsolutePathBuf::try_from(...)`. For the remaining TUI/app-server snapshot coverage that renders absolute cwd values, keep the snapshots unchanged and skip the Windows-only cases where the platform-specific absolute path layout differs.
pakrym-oai ·
2026-03-25 16:02:22 +00:00 -
Ahmed Ibrahim ·
2026-03-24 18:10:53 -07:00 -
Move string truncation helpers into codex-utils-string (#15572)
- move the shared byte-based middle truncation logic from `core` into `codex-utils-string` - keep token-specific truncation in `codex-core` so rollout can reuse the shared helper in the next stacked PR --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-24 15:45:40 -07:00 -
Move git utilities into a dedicated crate (#15564)
- create `codex-git-utils` and move the shared git helpers into it with file moves preserved for diff readability - move the `GitInfo` helpers out of `core` so stacked rollout work can depend on the shared crate without carrying its own git info module --------- Co-authored-by: Ahmed Ibrahim <219906144+aibrahim-oai@users.noreply.github.com> Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-24 13:26:23 -07:00 -
Use released DotSlash package for argument-comment lint (#15199)
## Why The argument-comment lint now has a packaged DotSlash artifact from [#15198](https://github.com/openai/codex/pull/15198), so the normal repo lint path should use that released payload instead of rebuilding the lint from source every time. That keeps `just clippy` and CI aligned with the shipped artifact while preserving a separate source-build path for people actively hacking on the lint crate. The current alpha package also exposed two integration wrinkles that the repo-side prebuilt wrapper needs to smooth over: - the bundled Dylint library filename includes the host triple, for example `@nightly-2025-09-18-aarch64-apple-darwin`, and Dylint derives `RUSTUP_TOOLCHAIN` from that filename - on Windows, Dylint's driver path also expects `RUSTUP_HOME` to be present in the environment Without those adjustments, the prebuilt CI jobs fail during `cargo metadata` or driver setup. This change makes the checked-in prebuilt wrapper normalize the packaged library name to the plain `nightly-2025-09-18` channel before invoking `cargo-dylint`, and it teaches both the wrapper and the packaged runner source to infer `RUSTUP_HOME` from `rustup show home` when the environment does not already provide it. After the prebuilt Windows lint job started running successfully, it also surfaced a handful of existing anonymous literal callsites in `windows-sandbox-rs`. This PR now annotates those callsites so the new cross-platform lint job is green on the current tree. ## What Changed - checked in the current `tools/argument-comment-lint/argument-comment-lint` DotSlash manifest - kept `tools/argument-comment-lint/run.sh` as the source-build wrapper for lint development - added `tools/argument-comment-lint/run-prebuilt-linter.sh` as the normal enforcement path, using the checked-in DotSlash package and bundled `cargo-dylint` - updated `just clippy` and `just argument-comment-lint` to use the prebuilt wrapper - split `.github/workflows/rust-ci.yml` so source-package checks live in a dedicated `argument_comment_lint_package` job, while the released lint runs in an `argument_comment_lint_prebuilt` matrix on Linux, macOS, and Windows - kept the pinned `nightly-2025-09-18` toolchain install in the prebuilt CI matrix, since the prebuilt package still relies on rustup-provided toolchain components - updated `tools/argument-comment-lint/run-prebuilt-linter.sh` to normalize host-qualified nightly library filenames, keep the `rustup` shim directory ahead of direct toolchain `cargo` binaries, and export `RUSTUP_HOME` when needed for Windows Dylint driver setup - updated `tools/argument-comment-lint/src/bin/argument-comment-lint.rs` so future published DotSlash artifacts apply the same nightly-filename normalization and `RUSTUP_HOME` inference internally - fixed the remaining Windows lint violations in `codex-rs/windows-sandbox-rs` by adding the required `/*param*/` comments at the reported callsites - documented the checked-in DotSlash file, wrapper split, archive layout, nightly prerequisite, and Windows `RUSTUP_HOME` requirement in `tools/argument-comment-lint/README.md`
Michael Bolin ·
2026-03-20 03:19:22 +00:00 -
Return image URL from view_image tool (#15072)
Cleanup image semantics in code mode. `view_image` now returns `{image_url:string, details?: string}` `image()` now allows both string parameter and `{image_url:string, details?: string}`pakrym-oai ·
2026-03-18 13:58:20 -07:00 -
Add FS abstraction and use in view_image (#14960)
Adds an environment crate and environment + file system abstraction. Environment is a combination of attributes and services specific to environment the agent is connected to: File system, process management, OS, default shell. The goal is to move most of agent logic that assumes environment to work through the environment abstraction.
pakrym-oai ·
2026-03-17 17:36:23 -07:00 -
Apply argument comment lint across codex-rs (#14652)
## Why Once the repo-local lint exists, `codex-rs` needs to follow the checked-in convention and CI needs to keep it from drifting. This commit applies the fallback `/*param*/` style consistently across existing positional literal call sites without changing those APIs. The longer-term preference is still to avoid APIs that require comments by choosing clearer parameter types and call shapes. This PR is intentionally the mechanical follow-through for the places where the existing signatures stay in place. After rebasing onto newer `main`, the rollout also had to cover newly introduced `tui_app_server` call sites. That made it clear the first cut of the CI job was too expensive for the common path: it was spending almost as much time installing `cargo-dylint` and re-testing the lint crate as a representative test job spends running product tests. The CI update keeps the full workspace enforcement but trims that extra overhead from ordinary `codex-rs` PRs. ## What changed - keep a dedicated `argument_comment_lint` job in `rust-ci` - mechanically annotate remaining opaque positional literals across `codex-rs` with exact `/*param*/` comments, including the rebased `tui_app_server` call sites that now fall under the lint - keep the checked-in style aligned with the lint policy by using `/*param*/` and leaving string and char literals uncommented - cache `cargo-dylint`, `dylint-link`, and the relevant Cargo registry/git metadata in the lint job - split changed-path detection so the lint crate's own `cargo test` step runs only when `tools/argument-comment-lint/*` or `rust-ci.yml` changes - continue to run the repo wrapper over the `codex-rs` workspace, so product-code enforcement is unchanged Most of the code changes in this commit are intentionally mechanical comment rewrites or insertions driven by the lint itself. ## Verification - `./tools/argument-comment-lint/run.sh --workspace` - `cargo test -p codex-tui-app-server -p codex-tui` - parsed `.github/workflows/rust-ci.yml` locally with PyYAML --- * -> #14652 * #14651
Michael Bolin ·
2026-03-16 16:48:15 -07:00 -
windows-sandbox: add runner IPC foundation for future unified_exec (#14139)
# Summary This PR introduces the Windows sandbox runner IPC foundation that later unified_exec work will build on. The key point is that this is intentionally infrastructure-only. The new IPC transport, runner plumbing, and ConPTY helpers are added here, but the active elevated Windows sandbox path still uses the existing request-file bootstrap. In other words, this change prepares the transport and module layout we need for unified_exec without switching production behavior over yet. Part of this PR is also a source-layout cleanup: some Windows sandbox files are moved into more explicit `elevated/`, `conpty/`, and shared locations so it is clearer which code is for the elevated sandbox flow, which code is legacy/direct-spawn behavior, and which helpers are shared between them. That reorganization is intentional in this first PR so later behavioral changes do not also have to carry a large amount of file-move churn. # Why This Is Needed For unified_exec Windows elevated sandboxed unified_exec needs a long-lived, bidirectional control channel between the CLI and a helper process running under the sandbox user. That channel has to support: - starting a process and reporting structured spawn success/failure - streaming stdout/stderr back incrementally - forwarding stdin over time - terminating or polling a long-lived process - supporting both pipe-backed and PTY-backed sessions The existing elevated one-shot path is built around a request-file bootstrap and does not provide those primitives cleanly. Before we can turn on Windows sandbox unified_exec, we need the underlying runner protocol and transport layer that can carry those lifecycle events and streams. # Why Windows Needs More Machinery Than Linux Or macOS Linux and macOS can generally build unified_exec on top of the existing sandbox/process model: the parent can spawn the child directly, retain normal ownership of stdio or PTY handles, and manage the lifetime of the sandboxed process without introducing a second control process. Windows elevated sandboxing is different. To run inside the sandbox boundary, we cross into a different user/security context and then need to manage a long-lived process from outside that boundary. That means we need an explicit helper process plus an IPC transport to carry spawn, stdin, output, and exit events back and forth. The extra code here is mostly that missing Windows sandbox infrastructure, not a conceptual difference in unified_exec itself. # What This PR Adds - the framed IPC message types and transport helpers for parent <-> runner communication - the renamed Windows command runner with both the existing request-file bootstrap and the dormant IPC bootstrap - named-pipe helpers for the elevated runner path - ConPTY helpers and process-thread attribute plumbing needed for PTY-backed sessions - shared sandbox/process helpers that later PRs will reuse when switching live execution paths over - early file/module moves so later PRs can focus on behavior rather than layout churn # What This PR Does Not Yet Do - it does not switch the active elevated one-shot path over to IPC yet - it does not enable Windows sandbox unified_exec yet - it does not remove the existing request-file bootstrap yet So while this code compiles and the new path has basic validation, it is not yet the exercised production path. That is intentional for this first PR: the goal here is to land the transport and runner foundation cleanly before later PRs start routing real command execution through it. # Follow-Ups Planned follow-up PRs will: 1. switch elevated one-shot Windows sandbox execution to the new runner IPC path 2. layer Windows sandbox unified_exec sessions on top of the same transport 3. remove the legacy request-file path once the IPC-based path is live # Validation - `cargo build -p codex-windows-sandbox`
iceweasel-oai ·
2026-03-16 19:45:06 +00:00 -
fix: preserve zsh-fork escalation fds across unified-exec spawn paths (#13644)
## Why `zsh-fork` sessions launched through unified-exec need the escalation socket to survive the wrapper -> server -> child handoff so later intercepted `exec()` calls can still reach the escalation server. The inherited-fd spawn path also needs to avoid closing Rust's internal exec-error pipe, and the shell-escalation handoff needs to tolerate the receive-side case where a transferred fd is installed into the same stdio slot it will be mapped onto. ## What Changed - Added `SpawnLifecycle::inherited_fds()` in `codex-rs/core/src/unified_exec/process.rs` and threaded inherited fds through `codex-rs/core/src/unified_exec/process_manager.rs` so unified-exec can preserve required descriptors across both PTY and no-stdin pipe spawn paths. - Updated `codex-rs/core/src/tools/runtimes/shell/zsh_fork_backend.rs` to expose the escalation socket fd through the spawn lifecycle. - Added inherited-fd-aware spawn helpers in `codex-rs/utils/pty/src/pty.rs` and `codex-rs/utils/pty/src/pipe.rs`, including Unix pre-exec fd pruning that preserves requested inherited fds while leaving `FD_CLOEXEC` descriptors alone. The pruning helper is now named `close_inherited_fds_except()` to better describe that behavior. - Updated `codex-rs/shell-escalation/src/unix/escalate_client.rs` to duplicate local stdio before transfer and send destination stdio numbers in `SuperExecMessage`, so the wrapper keeps using its own `stdin`/`stdout`/`stderr` until the escalated child takes over. - Updated `codex-rs/shell-escalation/src/unix/escalate_server.rs` so the server accepts the overlap case where a received fd reuses the same stdio descriptor number that the child setup will target with `dup2`. - Added comments around the PTY stdio wiring and the overlap regression helper to make the fd handoff and controlling-terminal setup easier to follow. ## Verification - `cargo test -p codex-utils-pty` - covers preserved-fd PTY spawn behavior, PTY resize, Python REPL continuity, exec-failure reporting, and the no-stdin pipe path - `cargo test -p codex-shell-escalation` - covers duplicated-fd transfer on the client side and verifies the overlap case by passing a pipe-backed stdin payload through the server-side `dup2` path --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/13644). * #14624 * __->__ #13644
Michael Bolin ·
2026-03-13 20:25:31 +00:00 -
refactor: make bubblewrap the default Linux sandbox (#13996)
## Summary - make bubblewrap the default Linux sandbox and keep `use_legacy_landlock` as the only override - remove `use_linux_sandbox_bwrap` from feature, config, schema, and docs surfaces - update Linux sandbox selection, CLI/config plumbing, and related tests/docs to match the new default - fold in the follow-up CI fixes for request-permissions responses and Linux read-only sandbox error text
viyatb-oai ·
2026-03-11 23:31:18 -07:00 -
Stabilize pipe process stdin round-trip test (#14013)
## What changed - keep the explicit stdin-close behavior after writing so the child still receives EOF deterministically - on Windows, stop using `python -c` for the round-trip assertion and instead run a native `cmd.exe` pipeline that reads one line from stdin with `set /p` and echoes it back - send ` ` on Windows so the stdin payload matches the platform-native line ending the shell reader expects ## Why this fixes flakiness The failing branch-local flake was not in `spawn_pipe_process` itself. The child exited cleanly, but the Windows ARM runner sometimes produced an empty stdout string when the test used Python as the stdin consumer. That makes the test sensitive to Python startup and stdin-close timing rather than the pipe primitive we actually want to validate. Switching the Windows path to a native `cmd.exe` reader keeps the assertion focused on our pipe behavior: bytes written to stdin should come back on stdout before EOF closes the process. The explicit ` ` write removes line-ending ambiguity on Windows. ## Scope - test-only - no production logic change
Ahmed Ibrahim ·
2026-03-11 12:33:09 -07:00 -
Stabilize split PTY output on Windows (#14003)
## Summary - run the split stdout/stderr PTY test through the normal shell helper on every platform - use a Windows-native command string instead of depending on Python to emit split streams - assert CRLF line endings on Windows explicitly ## Why this fixes the flake The earlier PTY split-output test used a Python one-liner on Windows while the rest of the file exercised shell-command behavior. That made the test depend on runner-local Python availability and masked the real Windows shell output shape. Using a native cmd-compatible command and asserting the actual CRLF output makes the split stdout/stderr coverage deterministic on Windows runners.
Ahmed Ibrahim ·
2026-03-11 12:33:07 -07:00 -
start of hooks engine (#13276)
(Experimental) This PR adds a first MVP for hooks, with SessionStart and Stop The core design is: - hooks live in a dedicated engine under codex-rs/hooks - each hook type has its own event-specific file - hook execution is synchronous and blocks normal turn progression while running - matching hooks run in parallel, then their results are aggregated into a normalized HookRunSummary On the AppServer side, hooks are exposed as operational metadata rather than transcript-native items: - new live notifications: hook/started, hook/completed - persisted/replayed hook results live on Turn.hookRuns - we intentionally did not add hook-specific ThreadItem variants Hooks messages are not persisted, they remain ephemeral. The context changes they add are (they get appended to the user's prompt)
Andrei Eternal ·
2026-03-10 04:11:31 +00:00 -
Stabilize PTY Python REPL test (#13883)
## What changed - The PTY Python REPL test now starts Python with a startup marker already embedded in argv. - The test waits for that marker in PTY output before making assertions. ## Why this fixes the flake - The old version tried to probe the live REPL almost immediately after spawn. - That races PTY initialization, Python startup, and prompt buffering, all of which vary across platforms and CI load. - By having the child process emit a known marker as part of its own startup path, the test gets a deterministic synchronization point that comes from the process under test rather than from guessed timing. ## Scope - Test-only change.
Ahmed Ibrahim ·
2026-03-09 10:08:36 -07:00 -
fix(ci): restore guardian coverage and bazel unit tests (#13912)
## Summary - restore the guardian review request snapshot test and its tracked snapshot after it was dropped from `main` - make Bazel Rust unit-test wrappers resolve runfiles correctly on manifest-only platforms like macOS and point Insta at the real workspace root - harden the shell-escalation socket-closure assertion so the musl Bazel test no longer depends on fd reuse behavior ## Verification - cargo test -p codex-core guardian_review_request_layout_matches_model_visible_request_snapshot - cargo test -p codex-shell-escalation - bazel test //codex-rs/exec:exec-unit-tests //codex-rs/shell-escalation:shell-escalation-unit-tests Supersedes #13894. --------- Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com> Co-authored-by: viyatb-oai <viyatb@openai.com> Co-authored-by: Codex <noreply@openai.com>
Charley Cunningham ·
2026-03-08 12:05:19 -07:00 -
Fix inverted Windows PTY
TerminateProcesshandling (#13989)Addresses #13945 The vendored WezTerm ConPTY backend in `codex-rs/utils/pty/src/win/mod.rs` treated `TerminateProcess` return values backwards: nonzero success was handled as failure, and `0` failure was handled as success. This is likely causing a number of bugs reported against Codex running on Windows native where processes are not cleaned up.
Eric Traut ·
2026-03-08 11:52:16 -06:00 -
utils/pty: add streaming spawn and terminal sizing primitives (#13695)
Enhance pty utils: * Support closing stdin * Separate stderr and stdout streams to allow consumers differentiate them * Provide compatibility helper to merge both streams back into combined one * Support specifying terminal size for pty, including on-demand resizes while process is already running * Support terminating the process while still consuming its outputs
Ruslan Nigmatullin ·
2026-03-06 15:13:12 -08:00 -
jif-oai ·
2026-03-04 10:17:29 +00:00 -
Feat: Preserve network access on read-only sandbox policies (#13409)
## Summary `PermissionProfile.network` could not be preserved when additional or compiled permissions resolved to `SandboxPolicy::ReadOnly`, because `ReadOnly` had no network_access field. This change makes read-only + network enabled representable directly and threads that through the protocol, app-server v2 mirror, and permission- merging logic. ## What changed - Added `network_access: bool` to `SandboxPolicy::ReadOnly` in the core protocol and app-server v2 protocol. - Kept backward compatibility by defaulting the new field to false, so legacy read-only payloads still deserialize unchanged. - Updated `has_full_network_access()` and sandbox summaries to respect read-only network access. - Preserved PermissionProfile.network when: - compiling skill permission profiles into sandbox policies - normalizing additional permissions - merging additional permissions into existing sandbox policies - Updated the approval overlay to show network in the rendered permission rule when requested. - Regenerated app-server schema fixtures for the new v2 wire shape.Celia Chen ·
2026-03-04 02:41:57 +00:00 -
Add under-development original-resolution view_image support (#13050)
## Summary Add original-resolution support for `view_image` behind the under-development `view_image_original_resolution` feature flag. When the flag is enabled and the target model is `gpt-5.3-codex` or newer, `view_image` now preserves original PNG/JPEG/WebP bytes and sends `detail: "original"` to the Responses API instead of using the legacy resize/compress path. ## What changed - Added `view_image_original_resolution` as an under-development feature flag. - Added `ImageDetail` to the protocol models and support for serializing `detail: "original"` on tool-returned images. - Added `PromptImageMode::Original` to `codex-utils-image`. - Preserves original PNG/JPEG/WebP bytes. - Keeps legacy behavior for the resize path. - Updated `view_image` to: - use the shared `local_image_content_items_with_label_number(...)` helper in both code paths - select original-resolution mode only when: - the feature flag is enabled, and - the model slug parses as `gpt-5.3-codex` or newer - Kept local user image attachments on the existing resize path; this change is specific to `view_image`. - Updated history/image accounting so only `detail: "original"` images use the docs-based GPT-5 image cost calculation; legacy images still use the old fixed estimate. - Added JS REPL guidance, gated on the same feature flag, to prefer JPEG at 85% quality unless lossless is required, while still allowing other formats when explicitly requested. - Updated tests and helper code that construct `FunctionCallOutputContentItem::InputImage` to carry the new `detail` field. ## Behavior ### Feature off - `view_image` keeps the existing resize/re-encode behavior. - History estimation keeps the existing fixed-cost heuristic. ### Feature on + `gpt-5.3-codex+` - `view_image` sends original-resolution images with `detail: "original"`. - PNG/JPEG/WebP source bytes are preserved when possible. - History estimation uses the GPT-5 docs-based image-cost calculation for those `detail: "original"` images. #### [git stack](https://github.com/magus/git-stack-cli) - 👉 `1` https://github.com/openai/codex/pull/13050 - ⏳ `2` https://github.com/openai/codex/pull/13331 - ⏳ `3` https://github.com/openai/codex/pull/13049Curtis 'Fjord' Hawthorne ·
2026-03-03 15:56:54 -08:00 -
Use model catalog default for reasoning summary fallback (#12873)
## Summary - make `Config.model_reasoning_summary` optional so unset means use model default - resolve the optional config value to a concrete summary when building `TurnContext` - add protocol support for `default_reasoning_summary` in model metadata ## Validation - `cargo test -p codex-core --lib client::tests -- --nocapture` --------- Co-authored-by: Codex <noreply@openai.com>
pakrym-oai ·
2026-02-26 09:31:13 -08:00 -
tui: restore visible line numbers for hidden file links (#12870)
we recently changed file linking so the model uses markdown links when it wants something to be clickable. This works well across the GUI surfaces because they can render markdown cleanly and use the full absolute path in the anchor target. A previous pass hid the absolute path in the TUI (and only showed the label), but that also meant we could lose useful location info when the model put the line number or range in the anchor target instead of the label. This follow-up keeps the TUI behavior simple while making local file links feel closer to the old TUI file reference style. key changes: - Local markdown file links in the TUI keep the old file-ref feel: code styling, no underline, no visible absolute path. - If the hidden local anchor target includes a location suffix and the label does not already include one, we append that suffix to the visible label. - This works for single lines, line/column references, and ranges. - If the label already includes the location, we leave it alone. - normal web links keep the old TUI markdown-link behavior some examples: - `[foo.rs](/abs/path/foo.rs)` renders as `foo.rs` - `[foo.rs](/abs/path/foo.rs:45)` renders as `foo.rs:45` - `[foo.rs](/abs/path/foo.rs:45:3-48:9)` renders as `foo.rs:45:3-48:9` - `[foo.rs:45](/abs/path/foo.rs:45)` stays `foo.rs:45` - `[docs](https://example.com/docs)` still renders like a normal web link how it looks: <img width="732" height="813" alt="Screenshot 2026-02-26 at 9 27 55 AM" src="https://github.com/user-attachments/assets/d51bf236-653a-4e83-96e4-9427f0804471" />
pash-openai ·
2026-02-26 10:29:54 +00:00 -
feat: adding stream parser (#12666)
Add a stream parser to extract citations (and others) from a stream. This support cases where markers are split in differen tokens. Codex never manage to make this code work so everything was done manually. Please review correctly and do not touch this part of the code without a very clear understanding of it
jif-oai ·
2026-02-25 13:27:58 +00:00 -
feat(sleep-inhibitor): add Linux and Windows idle-sleep prevention (#11766)
## Background - follow-up to previous macOS-only PR: https://github.com/openai/codex/pull/11711 - follow-up macOS refactor PR (current structural approach used here): https://github.com/openai/codex/pull/12340 ## Summary - extend `codex-utils-sleep-inhibitor` with Linux and Windows backends while preserving existing macOS behavior - Linux backend: - use `systemd-inhibit` (`--what=idle --mode=block`) when available - fall back to `gnome-session-inhibit` (`--inhibit idle`) when available - keep no-op behavior if neither backend exists on host - Windows backend: - use Win32 power request handles (`PowerCreateRequest` + `PowerSetRequest` / `PowerClearRequest`) with `PowerRequestSystemRequired` - make `prevent_idle_sleep` Experimental on macOS/Linux/Windows; keep under development on other targets ## Testing - `just fmt` - `cargo test -p codex-utils-sleep-inhibitor` - `cargo test -p codex-core features::tests::` - `cargo test -p codex-tui chatwidget::tests::` - `just fix -p codex-utils-sleep-inhibitor` - `just fix -p codex-core` ## Semantics and API references - Goal remains: prevent idle system sleep while a turn is running. - Linux: - `systemd-inhibit` / login1 inhibitor model: - https://www.freedesktop.org/software/systemd/man/latest/systemd-inhibit.html - https://www.freedesktop.org/software/systemd/man/org.freedesktop.login1.html - https://systemd.io/INHIBITOR_LOCKS/ - xdg-desktop-portal Inhibit (relevant for sandboxed apps): - https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Inhibit.html - Windows: - `PowerCreateRequest`: - https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-powercreaterequest - `PowerSetRequest`: - https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-powersetrequest - `PowerClearRequest`: - https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-powerclearrequest - `SetThreadExecutionState` (alternative baseline API): - https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate ## Chromium vs this PR - Chromium Linux backend: - https://github.com/chromium/chromium/blob/main/services/device/wake_lock/power_save_blocker/power_save_blocker_linux.cc - Chromium Windows backend: - https://github.com/chromium/chromium/blob/main/services/device/wake_lock/power_save_blocker/power_save_blocker_win.cc - Electron powerSaveBlocker entry point: - https://github.com/electron/electron/blob/main/shell/browser/api/electron_api_power_save_blocker.cc ## Why we differ from Chromium - Linux implementation mechanism: - Chromium uses in-process D-Bus APIs plus UI-integrated screen-saver suspension. - This PR uses command-based inhibitor backends (`systemd-inhibit`, `gnome-session-inhibit`) instead of linking a Linux D-Bus client in this crate. - Reason: keep `codex-utils-sleep-inhibitor` dependency-light and avoid Linux CI/toolchain fragility from new native D-Bus linkage, while preserving the same runtime intent (hold an inhibitor while a turn runs). - Linux UI integration scope: - Chromium also uses `display::Screen::SuspendScreenSaver()` in its UI stack. - Codex `codex-rs` does not have that display abstraction in this crate, so this PR scopes Linux behavior to process-level sleep inhibition only. - Windows wake-lock type breadth: - Chromium supports both display/system wake-lock types and extra display-specific handling for some pre-Win11 scenarios. - Codex’s feature is scoped to turn execution continuity (not forcing display on), so this PR uses `PowerRequestSystemRequired` only.
Yaroslav Volovich ·
2026-02-24 11:51:44 -08:00 -
feat: use process group to kill the PTY (#12688)
Use the process group kill logic to kill the PTY
jif-oai ·
2026-02-24 16:55:23 +00:00 -
Avoid
AbsolutePathBuf::parent()panic underEMFILEby skipping re-absolutization (#12647)Fixes #12216 Fixes a panic in `AbsolutePathBuf::parent()` when the process hits file descriptor exhaustion (`EMFILE` / "Too many open files"). ### Root cause `AbsolutePathBuf::parent()` was re-validating the parent path via `from_absolute_path(...).expect(...)`. `from_absolute_path()` calls `path_absolutize::absolutize()`, which can depend on `std::env::current_dir()`. Under `EMFILE`, that can fail, causing `parent()` to panic even though the parent of an absolute path is already known. ### Change - Stop re-absolutizing the result of `self.0.parent()` - Construct `AbsolutePathBuf` directly from the known parent path - Keep an invariant check with `debug_assert!(p.is_absolute())` ### Why this is safe `self` is already an `AbsolutePathBuf`, so `self.0` is absolute/normalized. The parent of an absolute path is expected to be absolute, so re-running fallible normalization here is unnecessary and can introduce unrelated panics.
Eric Traut ·
2026-02-23 21:59:33 -08:00 -
jif-oai ·
2026-02-23 14:14:36 +00:00 -
chore: remove codex-core public protocol/shell re-exports (#12432)
## Why `codex-rs/core/src/lib.rs` re-exported a broad set of types and modules from `codex-protocol` and `codex-shell-command`. That made it easy for workspace crates to import those APIs through `codex-core`, which in turn hides dependency edges and makes it harder to reduce compile-time coupling over time. This change removes those public re-exports so call sites must import from the source crates directly. Even when a crate still depends on `codex-core` today, this makes dependency boundaries explicit and unblocks future work to drop `codex-core` dependencies where possible. ## What Changed - Removed public re-exports from `codex-rs/core/src/lib.rs` for: - `codex_protocol::protocol` and related protocol/model types (including `InitialHistory`) - `codex_protocol::config_types` (`protocol_config_types`) - `codex_shell_command::{bash, is_dangerous_command, is_safe_command, parse_command, powershell}` - Migrated workspace Rust call sites to import directly from: - `codex_protocol::protocol` - `codex_protocol::config_types` - `codex_protocol::models` - `codex_shell_command` - Added explicit `Cargo.toml` dependencies (`codex-protocol` / `codex-shell-command`) in crates that now import those crates directly. - Kept `codex-core` internal modules compiling by using `pub(crate)` aliases in `core/src/lib.rs` (internal-only, not part of the public API). - Updated the two utility crates that can already drop a `codex-core` dependency edge entirely: - `codex-utils-approval-presets` - `codex-utils-cli` ## Verification - `cargo test -p codex-utils-approval-presets` - `cargo test -p codex-utils-cli` - `cargo check --workspace --all-targets` - `just clippy`Michael Bolin ·
2026-02-20 23:45:35 -08:00 -
Move sanitizer into codex-secrets (#12306)
## Summary - move the sanitizer implementation into `codex-secrets` (`secrets/src/sanitizer.rs`) and re-export `redact_secrets` - switch `codex-core` to depend on/import `codex-secrets` for sanitizer usage - remove the old `utils/sanitizer` crate wiring and refresh lockfiles ## Testing - `just fmt` - `cargo test -p codex-secrets` - `cargo test -p codex-core --no-run` - `cargo clippy -p codex-secrets -p codex-core --all-targets --all-features -- -D warnings` - `just bazel-lock-update` - `just bazel-lock-check` ## Notes - not run: `cargo test --all-features` (full workspace suite)
viyatb-oai ·
2026-02-20 22:47:54 +00:00 -
fix: simplify macOS sleep inhibitor FFI (#12340)
Summary - simplify the macOS sleep inhibitor FFI by replacing `dlopen` / `dlsym` / `transmute` with normal IOKit extern calls and `SAFETY` comments - switch to cfg-selected platform implementations (`imp::SleepInhibitor`) instead of `Box<dyn ...>` - check in minimal IOKit bindings generated with `bindgen` and include them from the macOS backend - enable direct IOKit linkage in Bazel macOS builds by registering `IOKit` in the Bazel `osx.framework(...)` toolchain extension list - update `Cargo.lock` and `MODULE.bazel.lock` after removing the build-time `bindgen` dependency path Testing - `just fmt` - `cargo clippy -p codex-utils-sleep-inhibitor --all-targets -- -D warnings` - `cargo test -p codex-utils-sleep-inhibitor` - `bazel test //codex-rs/utils/sleep-inhibitor:all --test_output=errors` - `just bazel-lock-update` - `just bazel-lock-check` Context - follow-up to #11711 addressing Ryan's review comments - `bindgen` is used to generate the checked-in bindings file, but not at build time
Yaroslav Volovich ·
2026-02-20 09:52:21 -08:00 -
feat(tui): prevent macOS idle sleep while turns run (#11711)
## Summary - add a shared `codex-core` sleep inhibitor that uses native macOS IOKit assertions (`IOPMAssertionCreateWithName` / `IOPMAssertionRelease`) instead of spawning `caffeinate` - wire sleep inhibition to turn lifecycle in `tui` (`TurnStarted` enables; `TurnComplete` and abort/error finalization disable) - gate this behavior behind a `/experimental` feature toggle (`[features].prevent_idle_sleep`) instead of a dedicated `[tui]` config flag - expose the toggle in `/experimental` on macOS; keep it under development on other platforms - keep behavior no-op on non-macOS targets <img width="1326" height="577" alt="image" src="https://github.com/user-attachments/assets/73fac06b-97ae-46a2-800a-30f9516cf8a3" /> ## Testing - `cargo check -p codex-core -p codex-tui` - `cargo test -p codex-core sleep_inhibitor::tests -- --nocapture` - `cargo test -p codex-core tui_config_missing_notifications_field_defaults_to_enabled -- --nocapture` - `cargo test -p codex-core prevent_idle_sleep_is_ -- --nocapture` ## Semantics and API references - This PR targets `caffeinate -i` semantics: prevent *idle system sleep* while allowing display idle sleep. - `caffeinate -i` mapping in Apple open source (`assertionMap`): - `kIdleAssertionFlag -> kIOPMAssertionTypePreventUserIdleSystemSleep` - Source: https://github.com/apple-oss-distributions/PowerManagement/blob/PowerManagement-1846.60.12/caffeinate/caffeinate.c#L52-L54 - Apple IOKit docs for assertion types and API: - https://developer.apple.com/documentation/iokit/iopmlib_h/iopmassertiontypes - https://developer.apple.com/documentation/iokit/1557092-iopmassertioncreatewithname - https://developer.apple.com/library/archive/qa/qa1340/_index.html ## Codex Electron vs this PR (full stack path) - Codex Electron app requests sleep blocking with `powerSaveBlocker.start("prevent-app-suspension")`: - https://github.com/openai/codex/blob/main/codex/codex-vscode/electron/src/electron-message-handler.ts - Electron maps that string to Chromium wake lock type `kPreventAppSuspension`: - https://github.com/electron/electron/blob/main/shell/browser/api/electron_api_power_save_blocker.cc - Chromium macOS backend maps wake lock types to IOKit assertion constants and calls IOKit: - `kPreventAppSuspension -> kIOPMAssertionTypeNoIdleSleep` - `kPreventDisplaySleep / kPreventDisplaySleepAllowDimming -> kIOPMAssertionTypeNoDisplaySleep` - https://github.com/chromium/chromium/blob/main/services/device/wake_lock/power_save_blocker/power_save_blocker_mac.cc ## Why this PR uses a different macOS constant name - This PR uses `"PreventUserIdleSystemSleep"` directly, via `IOPMAssertionCreateWithName`, in `codex-rs/core/src/sleep_inhibitor.rs`. - Apple’s IOKit header documents `kIOPMAssertionTypeNoIdleSleep` as deprecated and recommends `kIOPMAssertPreventUserIdleSystemSleep` / `kIOPMAssertionTypePreventUserIdleSystemSleep`: - https://github.com/apple-oss-distributions/IOKitUser/blob/IOKitUser-100222.60.2/pwr_mgt.subproj/IOPMLib.h#L1000-L1030 - So Chromium and this PR are using different constant names, but semantically equivalent idle-system-sleep prevention behavior. ## Future platform support The architecture is intentionally set up for multi-platform extensions: - UI code (`tui`) only calls `SleepInhibitor::set_turn_running(...)` on turn lifecycle boundaries. - Platform-specific behavior is isolated in `codex-rs/core/src/sleep_inhibitor.rs` behind `cfg(...)` blocks. - Feature exposure is centralized in `core/src/features.rs` and surfaced via `/experimental`. - Adding new OS backends should not require additional TUI wiring; only the backend internals and feature stage metadata need to change. Potential follow-up implementations: - Windows: - Add a backend using Win32 power APIs (`SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED)` as baseline). - Optionally move to `PowerCreateRequest` / `PowerSetRequest` / `PowerClearRequest` for richer assertion semantics. - Linux: - Add a backend using logind inhibitors over D-Bus (`org.freedesktop.login1.Manager.Inhibit` with `what="sleep"`). - Keep a no-op fallback where logind/D-Bus is unavailable. This PR keeps the cross-platform API surface minimal so future PRs can add Windows/Linux support incrementally with low churn. --------- Co-authored-by: jif-oai <jif@openai.com>
Yaroslav Volovich ·
2026-02-13 10:31:39 -08:00 -
feat: introduce Permissions (#11633)
## Why We currently carry multiple permission-related concepts directly on `Config` for shell/unified-exec behavior (`approval_policy`, `sandbox_policy`, `network`, `shell_environment_policy`, `windows_sandbox_mode`). Consolidating these into one in-memory struct makes permission handling easier to reason about and sets up the next step: supporting named permission profiles (`[permissions.PROFILE_NAME]`) without changing behavior now. This change is mostly mechanical: it updates existing callsites to go through `config.permissions`, but it does not yet refactor those callsites to take a single `Permissions` value in places where multiple permission fields are still threaded separately. This PR intentionally **does not** change the on-disk `config.toml` format yet and keeps compatibility with legacy config keys. ## What Changed - Introduced `Permissions` in `core/src/config/mod.rs`. - Added `Config::permissions` and moved effective runtime permission fields under it: - `approval_policy` - `sandbox_policy` - `network` - `shell_environment_policy` - `windows_sandbox_mode` - Updated config loading/building so these effective values are still derived from the same existing config inputs and constraints. - Updated Windows sandbox helpers/resolution to read/write via `permissions`. - Threaded the new field through all permission consumers across core runtime, app-server, CLI/exec, TUI, and sandbox summary code. - Updated affected tests to reference `config.permissions.*`. - Renamed the struct/field from `EffectivePermissions`/`effective_permissions` to `Permissions`/`permissions` and aligned variable naming accordingly. ## Verification - `just fix -p codex-core -p codex-tui -p codex-cli -p codex-app-server -p codex-exec -p codex-utils-sandbox-summary` - `cargo build -p codex-core -p codex-tui -p codex-cli -p codex-app-server -p codex-exec -p codex-utils-sandbox-summary`
Michael Bolin ·
2026-02-12 14:42:54 -08:00