mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
3cf6f08da562ee1bf6866fbc2db45a3c3af620ff
832 Commits
-
Move cloud requirements crate to cloud config (#24621)
## Summary - Moves the existing `codex-cloud-requirements` crate to `codex-cloud-config`. - Updates workspace dependencies and imports to the new crate name. - Intentionally keeps runtime behavior unchanged: this still fetches the legacy cloud requirements endpoint. ## Details This PR exists to make the lineage obvious before the bundle migration. GitHub should show the old `codex-rs/cloud-requirements/src/lib.rs` implementation as moved to `codex-rs/cloud-config/src/lib.rs`, rather than as unrelated new code. The follow-up PR adapts this moved crate to the new config bundle API and switches runtime consumers over.
joeflorencio-openai ·
2026-06-01 16:43:52 -07:00 -
app-server: remove experimental persist_extended_history bool flag (#25712)
## Summary Remove the dead experimental `persistExtendedHistory` app-server flag and collapse rollout persistence to the single policy app-server already used. ## What Changed - Removed `persistExtendedHistory` from v2 thread start/resume/fork params and deleted its deprecation notice path. - Removed the persistence-mode enums and plumbing through core, rollout, and thread-store. - Made rollout filtering mode-free, keeping the existing limited persisted-history behavior. ## Test Plan - `just write-app-server-schema` - `cargo nextest run --no-fail-fast -p codex-app-server-protocol schema_fixtures` - `cargo nextest run --no-fail-fast -p codex-app-server thread_shell_command_history_responses_exclude_persisted_command_executions` - `cargo nextest run --no-fail-fast -p codex-rollout -p codex-thread-store` - final `rg` for removed flag/type names
Owen Lin ·
2026-06-01 23:33:42 +00:00 -
Wire managed MITM CA trust into child env (#22668)
## Stack 1. Parent PR: #18240 uses named MITM permissions config. 2. This PR wires managed MITM CA trust into spawned child processes. ## Why When Codex terminates HTTPS for limited mode or MITM hooks, child HTTPS clients need to trust Codex's managed MITM CA. Exporting proxy URLs alone is not enough, but blindly replacing user CA settings would be wrong: it can break custom enterprise/test roots, leak unreadable CA files into generated bundles, or make the child env disagree with its sandbox policy. ## Summary 1. Build immutable managed CA bundles under `$CODEX_HOME/proxy` that include native roots, the managed MITM CA, and only inherited or command-scoped CA bundles the child is allowed to read. 2. Export curated CA env vars alongside managed proxy env vars while preserving user CA override semantics, including nested Codex `SSL_CERT_FILE` precedence. 3. Thread generated CA bundle paths into child sandbox readable roots, including debug sandbox execution, so the exported env vars work inside sandboxed commands. 4. Remove only Codex-generated MITM CA bundle env when a child intentionally drops managed proxying for escalation or no-proxy retry. 5. Document the managed CA bundle behavior and cover env injection, per-child bundle generation, sandbox readable roots, and no-proxy cleanup in tests. ## Validation 1. Ran `just test -p codex-network-proxy`. 2. Ran `just test -p codex-protocol`. 3. Ran `just fix -p codex-network-proxy -p codex-protocol`. 4. Tried focused `codex-core` validation, but the crate currently fails to compile in `core/tests/suite/guardian_review.rs` because an existing `Op::UserInput` initializer is missing `additional_context`. --------- Co-authored-by: Eva Wong <evawong@openai.com>
Winston Howes ·
2026-06-01 23:23:59 +00:00 -
[codex] Consolidate shared prompts in codex-prompts (#25151)
## Why `codex_core` is consistently a bottleneck for incremental builds during iteration. The simplest fix is to make the crate smaller. ## Summary `codex-core` owns several reusable prompt renderers and static prompt assets, which makes the crate harder to split apart. Rename `codex-review-prompts` to `codex-prompts` and move shared review, goal, permissions, compaction, realtime, hierarchical AGENTS.md, and `apply_patch` prompts into it. Move prompt-only tests and update consumers and `CODEOWNERS`. ## Validation - `just test -p codex-prompts -p codex-apply-patch` - `just test -p codex-core prompt_caching` - Bazel builds for the affected crates
Adam Perry @ OpenAI ·
2026-06-01 18:45:07 +00:00 -
Preserve plugin app manifest order (#25491)
## Summary - Preserve app declaration order when loading plugin .app.json files. - Keep plugin connector summaries in plugin app order after connector metadata is merged and filtered. - Add regression coverage for .app.json order and connector summary order. ## Validation - just fmt - just test -p codex-chatgpt connectors_for_plugin_apps_returns_only_requested_plugin_apps - just test -p codex-core-plugins effective_apps_preserves_app_config_order - just fix -p codex-core-plugins (passes with existing clippy large_enum_variant warning in core-plugins/src/manifest.rs) - just fix -p codex-chatgpt - just bazel-lock-update - just bazel-lock-check
charlesgong-openai ·
2026-06-01 11:04:21 -07:00 -
Read compressed rollouts and materialize before append (#25087)
## Why Local rollout compression needs a cold `.jsonl.zst` representation without letting compressed physical paths leak into append-mode writers. The unsafe case is resume or metadata update code successfully reading a compressed rollout and then appending raw JSONL bytes to the zstd file. This PR folds the former #25088 materialization slice into the read-support PR so the reader changes and append-safety invariant land together. ## What Changed - Teach rollout readers, discovery, listing, search, and ID lookup to understand compressed `.jsonl.zst` rollouts. - Keep `.jsonl` as the logical/stored rollout path while allowing read paths to open either plain or compressed storage. - Materialize compressed rollouts back to plain `.jsonl` before append-mode writes, including resume and direct metadata append paths. - Preserve compressed-file permissions when materializing back to plain JSONL. - Refresh thread-store resolved rollout paths after compatibility metadata writes so reconciliation follows the materialized file. - Avoid treating transient compression temp files as real rollout lookup results. ## Remaining Stack #25089 remains the separate worker PR. It is based directly on this PR and stays behind the disabled `local_thread_store_compression` feature flag. The worker still has a broader coordination question: a resume or metadata update can race with background compression while a plain file is being replaced by `.jsonl.zst`. This PR handles the read and materialize-before-append primitives; it does not make the worker production-ready. ## Validation - `just test -p codex-rollout` - `just test -p codex-thread-store` - `just fix -p codex-rollout` - `just fix -p codex-thread-store` - `just bazel-lock-check`
jif-oai ·
2026-06-01 15:14:19 +02:00 -
Use templates for goal steering prompts (#25576)
## Why Goal steering prompts have grown into long inline Rust strings, which makes the authored prompt text hard to review and easy to damage while changing the surrounding plumbing. Moving those prompts into embedded Markdown templates keeps the policy text in the shape reviewers actually read, while preserving the existing runtime substitution and objective escaping behavior. ## What changed - Added `ext/goal/templates/goals/continuation.md`, `budget_limit.md`, and `objective_updated.md` for the three goal steering prompts. - Updated `ext/goal/src/steering.rs` to parse those embedded templates once with `codex-utils-template` and render the existing goal values into them. - Kept user objectives XML-escaped before rendering and converted budget counters into template variables. - Added the template directory to `ext/goal/BUILD.bazel` `compile_data` so Bazel has the same embedded prompt inputs as Cargo. ## Testing - Not run locally.
jif-oai ·
2026-06-01 10:55:14 +02:00 -
code-mode: introduce durable session interface (#24180)
## Summary Introduce a `CodeModeSession` interface for executing and managing code-mode cells. This moves cell lifecycle, callback delegation, termination, and shutdown behind a session abstraction, while continuing to use the existing in-process implementation, and the ability to implement an external process one behind this interface. A Codex session owns one `CodeModeSession`, which in turn owns its running cells and stored code-mode state. Each cell is represented to the caller as a `StartedCell`, exposing its cell ID and initial response. It also introduces a `CodeModeSessionDelegate` callback interface. A session uses the delegate to invoke nested host tools and emit notifications while a cell is running, allowing the runtime to communicate with its owning Codex session without depending directly on core turn handling. <img width="2121" height="1001" alt="image" src="https://github.com/user-attachments/assets/c349a819-2a59-485c-bda4-2caf68ac4c31" />
Channing Conger ·
2026-05-29 11:42:52 -07:00 -
Route extension image generation through the native image completion pipeline (#24972)
## Why The standalone `image_gen.imagegen` extension should behave like native image generation for artifact persistence and UI completion, while returning its save-location guidance as part of the tool result instead of injecting a developer message. ## What Changed - Added an image-generation completion hook for extension tools so core can persist generated images and emit the existing `ImageGeneration` lifecycle events. - Reused core image artifact persistence for extension output and removed extension-local save-path/file-writing logic. - Split shared image persistence from built-in finalization so native image generation keeps its existing developer-message instruction behavior. - Returned the generated image save-location instruction through the extension `FunctionCallOutput`, alongside the generated image input for model follow-up. - Preserved the existing image-generation event shape for current UI and replay compatibility. - Avoided cloning the full generated-image base64 payload when emitting the in-progress image item. - Removed dependencies no longer needed after moving persistence out of the extension crate. ## Fast Follow - Adjust the existing Extension API and add a general `TurnItem` finalization path for re-usability of code ## Validation - Ran `just fmt`. - Ran `just bazel-lock-update`. - Ran `just bazel-lock-check`. - Ran `just test -p codex-tools -p codex-extension-api -p codex-image-generation-extension`. - Ran `just test -p codex-core image_generation_publication_is_finalized_by_core`. - Ran `just test -p codex-core handle_output_item_done_records_image_save_history_message`. - Ran `just fix -p codex-tools -p codex-extension-api -p codex-core -p codex-image-generation-extension`.
Won Park ·
2026-05-29 17:33:13 +00:00 -
Show activity for standalone web search calls (#24693)
## Why Standalone `web.run` calls run in the extension, so they need normal web-search progress activity while a request is in flight and durable completed activity after a thread is reloaded. Follow-up to #23823; uses the extension turn-item emission path added in #24813. ## What changed - Emit standalone `web.run` start/completion items through the host turn-item emitter, preserving standard client delivery and rollout persistence. - Include useful completion detail for queries, image queries, and literal-URL `open`/`find` commands. - Render completed searches as `Searched the web` or `Searched the web for <detail>`, with snapshot coverage for the detail-free case. - Extend the app-server round-trip test to verify completed search activity is reconstructed by `thread/read` after a fresh-process reload. ## Testing - `just test -p codex-web-search-extension` - `just test -p codex-app-server -E "test(standalone_web_search_round_trips_encrypted_output)"`
sayan-oai ·
2026-05-29 16:12:58 +00:00 -
jif-oai ·
2026-05-29 12:53:31 +02:00 -
Add feature-gated standalone image generation extension (#24723)
## Why Add a standalone image generation path that can be exercised independently of hosted Responses image generation, while retaining the hosted tool as fallback unless the extension is actually available to the model. ## What changed - Added the `codex-image-generation-extension` crate with standalone generate/edit execution, prior-image selection for edits, model-visible image output, and local generated-image persistence. - Installed the extension in app-server behind the disabled-by-default `imagegenext` feature and backend eligibility checks. - Updated core tool planning so eligible `image_gen.imagegen` exposure replaces hosted `image_generation`, while unavailable configurations retain hosted fallback. - Added coverage for extension behavior, edit history reuse, feature gating, auth eligibility, and hosted-tool replacement. - The extension is installed through app-server only in this PR; other execution paths retain hosted image generation because hosted replacement occurs only when the standalone executor is actually registered and model-visible. - The initial extension contract intentionally fixes the image model to `gpt-image-2` and uses automatic image parameters. - Native generated-image history/card parity and rollout persistence cleanup are intentionally deferred follow-up work. ## Validation - `just test -p codex-image-generation-extension` - `just test -p codex-features` - `just test -p codex-core hosted_tools_follow_provider_auth_model_and_config_gates` - `just test -p codex-app-server` - `just fix -p codex-image-generation-extension -p codex-features -p codex-core -p codex-app-server` - `just fmt` - `just bazel-lock-update` - `just bazel-lock-check` --------- Co-authored-by: jif-oai <jif@openai.com>
Won Park ·
2026-05-28 11:44:55 -07:00 -
Revert "Add app-server startup benchmark crate" (#24937)
Reverts openai/codex#24651, broke musl job https://github.com/openai/codex/actions/runs/26585495205/job/78330166927
Adam Perry @ OpenAI ·
2026-05-28 17:49:41 +00:00 -
Add app-server startup benchmark crate (#24651)
## Summary - Add a new `app-server-start-bench` crate to measure app-server startup performance - Wire the benchmark into the workspace and Bazel build so it can be run consistently - Update lockfiles and repo automation to account for the new package
Adam Perry @ OpenAI ·
2026-05-28 08:46:30 -07:00 -
Update rmcp to 1.7.0 (#24763)
WIll make it easier to uprev when the new draft spec is supported. Also updates reqwest where needed for compatibility but doesn't update it everywhere since this is already a large diff. The new version of rmcp handles certain kinds of authentication failures differently, this patch includes support for identifying the failing scope in a WWW-Authenticate header.
Adam Perry @ OpenAI ·
2026-05-27 14:52:06 -07:00 -
Allow API-key auth for remote exec-server registration (#24666)
## Overview Allow remote `codex exec-server` registration to use existing API-key auth while restricting where those credentials can be sent. - Accept `CodexAuth::ApiKey` for the normal `--remote` registration path. - Restrict API-key remote registration to HTTPS `openai.com` and `openai.org` hosts and subdomains, with explicit HTTP loopback support for local development. - Disable registry registration redirects so credentials cannot be forwarded to an unvalidated destination. - Retain `--use-agent-identity-auth` as the explicit Agent Identity path. - Document remote registration using `CODEX_API_KEY`. ## Big picture Callers can now provide an API key directly to `exec-server` registration without first establishing ChatGPT login state: ```sh CODEX_API_KEY="$OPENAI_API_KEY" \ codex exec-server \ --remote "https://<host>.openai.org/api" \ --environment-id "$ENVIRONMENT_ID" ``` ## Validation - `cargo fmt --all` (`just fmt` is not installed on this host) - `cargo test -p codex-cli -p codex-exec-server`
Steve Coffey ·
2026-05-27 21:17:38 +00:00 -
Bump SQLx to pick up newer bundled SQLite (#24728)
## Why Codex stores thread, log, goal, and memory state in bundled SQLite databases through SQLx. We have a suspected SQLite WAL-reset corruption issue under heavy concurrent writer load, especially when multiple subagents are active. The existing `sqlx 0.8.6` dependency kept us on an older `libsqlite3-sys` / bundled SQLite, so this PR moves the SQLx stack far enough forward to pick up the newer bundled SQLite library. ## What changed - Bump the workspace `sqlx` dependency to `0.9.0`. - Use the SQLx 0.9 feature names explicitly: `runtime-tokio`, `tls-rustls`, and `sqlite-bundled`. - Update `Cargo.lock` so `sqlx-sqlite` resolves through `libsqlite3-sys 0.37.0`. - Refresh `MODULE.bazel.lock` for the dependency changes. - Adapt `codex-state` to SQLx 0.9: - build dynamic state queries with `QueryBuilder<Sqlite>` instead of passing dynamic `String`s to `sqlx::query`; - remove the old `QueryBuilder` lifetime parameter from helper signatures; - preserve SQLx's new `Migrator` fields when constructing runtime migrators. ## Verification - `just test -p codex-state` - `just bazel-lock-check` - `cargo check -p codex-state --tests`
jif-oai ·
2026-05-27 18:44:07 +02:00 -
Attach Windows sandbox log to feedback reports (#24623)
## Why Windows sandbox diagnostics are currently hard to recover from `/feedback` even though they are often the most useful artifact when debugging sandbox behavior. Now that sandbox logging uses daily rolling files, feedback can safely include the current day's sandbox log without uploading the old ever-growing legacy `sandbox.log`. ## What changed - Add a `codex-windows-sandbox` helper that resolves the current daily sandbox log from `codex_home`. - When feedback is submitted with logs enabled on Windows, app-server attaches today's sandbox log if it exists. - Upload the attachment under the stable filename `windows-sandbox.log`, independent of the dated on-disk filename. - Keep existing raw `extra_log_files` behavior unchanged for rollout and desktop log attachments. ## Verification - `cargo fmt -p codex-app-server -p codex-windows-sandbox` - `cargo test -p codex-windows-sandbox current_log_file_path_for_codex_home_uses_sandbox_dir` - `cargo test -p codex-app-server windows_sandbox_log_attachment_uses_current_log` - Manual CLI/TUI `/feedback` test confirmed Sentry received `windows-sandbox.log`.
iceweasel-oai ·
2026-05-26 15:59:25 -07:00 -
tui: keep inaccessible apps out of mentions (#24625)
## Summary Fix the TUI `$` app mention paths so App Directory rows that are not accessible are not treated as usable apps. This includes the core preservation fix from #24104, but expands it to the other app mention paths: - preserve app-server `is_accessible` flags when partial `app/list/updated` snapshots reach the TUI - require apps to be both accessible and enabled when resolving exact `$slug` mentions - require restored/stale `app://...` bindings to point at accessible, enabled apps before emitting structured app mentions - remove the now-unused `codex-chatgpt` dependency from `codex-tui`, which addresses the `cargo shear` failure seen on #24104 ## Root Cause The app server already sends merged app snapshots with accessibility computed. The TUI handled app-server app list updates as partial app loads and re-ran the old accessible-app merge path. That path treated every notification row as accessible, so App Directory entries with `isAccessible=false` could appear in `$` suggestions. Regression source: #22914 routed app-list updates through the app server while reusing the old TUI partial-load handling. Related precursor: #14717 introduced the partial-load path, but #22914 made it user-visible for app-server updates. ## Issues Fixes #24145 Fixes #24205 Fixes #24319 ## Validation - `just fmt` - `git diff --check` - `just bazel-lock-update` - `just bazel-lock-check` - `just argument-comment-lint -p codex-tui` - `just test -p codex-tui chatwidget::tests::popups_and_settings::apps_notification_update_excludes_inaccessible_apps_from_mentions chatwidget::tests::composer_submission::submit_user_message_ignores_inaccessible_app_mentions_from_bindings chatwidget::skills::tests::find_app_mentions_requires_accessible_enabled_apps_for_bound_paths chatwidget::skills::tests::find_app_mentions_requires_accessible_enabled_apps_for_slugs`
canvrno-oai ·
2026-05-26 12:09:07 -07:00 -
standalone websearch extension (#23823)
## Summary Add the extension-backed standalone `web.run` tool so Codex can call the standalone search endpoint through the `codex-api` search client and return its encrypted output to Responses. - gate the new tool behind `standalone_web_search` - install the extension in the app-server thread registry and hide hosted `web_search` when standalone search is enabled for OpenAI providers so the two paths stay mutually exclusive - build search context from persisted history using a small tail heuristic: previous user message, assistant text between the last two user turns capped at about 1k tokens, and current user message ## Test Plan - `cargo test -p codex-web-search-extension` - `cargo test -p codex-api` - `cargo test -p codex-core hosted_tools_follow_provider_auth_model_and_config_gates`
sayan-oai ·
2026-05-26 11:12:24 -07:00 -
Add goal extension telemetry parity (#24615)
## Why `core/src/goals.rs` already emits OTEL metrics for goal creation, resume, terminal transitions, token counts, and duration. As `/goal` moves into `ext/goal`, the extension needs to preserve that telemetry contract instead of only emitting app-visible `ThreadGoalUpdated` events. This keeps the existing `codex.goal.*` metric surface intact while goal lifecycle ownership shifts toward the extension. ## What changed - Added an extension-local `GoalMetrics` helper that records the existing `codex.goal.*` counters and histograms through `codex-otel`. - Threaded an optional `MetricsClient` through `install_with_backend`, `GoalExtension`, `GoalRuntimeHandle`, and `GoalToolExecutor`. - Emitted created, resumed, and terminal goal metrics from the extension paths that create goals, restore active goals on thread resume, account budget limits, complete or block goals, and handle external goal mutations. - Updated existing goal extension test setup callsites to pass `None` for metrics when instrumentation is not under test. ## Verification Not run locally.
jif-oai ·
2026-05-26 19:48:32 +02:00 -
fix: drop flake (#24588)
Dropping already commented out stuff
jif-oai ·
2026-05-26 15:07:26 +02:00 -
chore: move memory prompt builder into extension (#24558)
## Why The memories extension now owns the read-path developer instructions it injects at thread start. Keeping that prompt builder and template in `codex-memories-read` left the extension depending on a helper crate for extension-specific prompt assembly, and kept async template/truncation dependencies in the read crate after the remaining read surface no longer needed them. ## What changed - Moved `prompts.rs`, its tests, and `templates/memories/read_path.md` from `memories/read` into `ext/memories`. - Wired `MemoryExtension` to call the local prompt builder and added the moved templates to `ext/memories/BUILD.bazel` compile data. - Removed the now-unused prompt export and prompt-related dependencies from `codex-memories-read`. ## Testing - Not run locally.
jif-oai ·
2026-05-26 11:53:47 +02:00 -
chore: drop orphaned codex memories MCP crate (#24555)
## Why The memory read-tool surface had two implementations: the app-server extension path under `ext/memories`, and an unused `codex-memories-mcp` workspace crate under `memories/mcp`. The MCP crate no longer has reverse dependents, so keeping it around preserves duplicate backend, schema, and tool code that is not part of the live app-server memory path. Dropping the orphaned crate makes the remaining memory crate split clearer: `memories/read` owns read-path prompt/citation helpers, `memories/write` owns the write pipeline, and `ext/memories` owns the app-server extension integration. ## What changed - Removed the `memories/mcp` crate and its Bazel/Cargo metadata. - Removed `memories/mcp` from the Rust workspace and lockfile. - Updated `memories/README.md` so it only lists the remaining reusable memory crates. ## Verification - `cargo metadata --format-version 1 --no-deps` succeeds.
jif-oai ·
2026-05-26 11:29:37 +02:00 -
Add doctor thread inventory audit (#24305)
## Why Users have been reporting missing sessions in the app. The app server thread listing is backed by the SQLite state DB, but the durable source of truth for a thread still exists on disk as rollout JSONL. When the state DB is incomplete, doctor should be able to show the mismatch directly instead of leaving users with a generic state health result. ## What changed This adds a `threads` doctor check that compares active and archived rollout files under `CODEX_HOME` with rows in the SQLite `threads` table. The check reports missing rollout rows, stale DB rows, archive flag mismatches, duplicate rollout thread IDs, duplicate DB paths, source/provider summaries, and bounded samples of affected rollout paths. It also adds a read-only state audit helper in `codex-rs/state` so doctor can inspect thread rows without creating, migrating, or repairing the database. ## Sample output ```text ⚠ threads rollout files are missing from the state DB default model provider openai rollout DB active files 3910 rollout DB archived files 2037 rollout DB scan errors 0 rollout DB malformed file names 0 rollout DB scan cap reached false rollout DB rows 5499 rollout DB active rows 3462 rollout DB archived rows 2037 rollout DB missing active rows 448 rollout DB missing archived rows 0 rollout DB stale rows 0 rollout DB archive mismatches 0 rollout DB duplicate rollout thread ids 0 rollout DB duplicate DB paths 0 rollout DB model providers openai=5359, lmstudio=35, mock_provider=33, lite_llm=26, proxy=26, ollama=15, lms=4, local-usage-limit=1 rollout DB sources vscode=2587, cli=1494, subagent:thread_spawn=577, subagent:other=502, exec=281, subagent:memory_consolidation=46, subagent:review=9, unknown=3 rollout DB missing active sample ~/.codex/sessions/2026/0…857e-a923c712e066.jsonl rollout DB missing active sample ~/.codex/sessions/2025/0…877a-766dff25c68d.jsonl rollout DB missing active sample ~/.codex/sessions/2025/0…a8b1-7bbadc836f6e.jsonl rollout DB missing active sample ~/.codex/sessions/2025/0…a218-e6197f3f62f8.jsonl rollout DB missing active sample ~/.codex/sessions/2025/0…9011-7e30784f9932.jsonl ```Eric Traut ·
2026-05-25 10:29:06 -07:00 -
feat(doctor): add environment diagnostics (#24261)
## Why Issue #23031 was hard to diagnose from existing `codex doctor` output because support could not see the OS language, resolved Git install, Git repo metadata, Windows console mode/code page, or terminal-title inputs that affect the TUI startup path. This adds those read-only signals to `codex doctor` so Windows, Linux, and macOS reports carry the context needed to investigate similar terminal rendering regressions. Refs #23031 ## What Changed - Add a `system.environment` check for OS type/version, OS language, and locale env vars. - Add a `git.environment` check for the selected Git executable, PATH Git candidates, version, exec path/build options, repository root, branch, `.git` entry, and `core.fsmonitor`. - Add Windows console code page and VT-processing mode details to terminal diagnostics. - Add a `terminal.title` check for configured/default title items and resolved project-title source/value. - Surface startup warning counts in config diagnostics and teach human output to render the new categories. ## How to Test 1. On Windows, check out this branch and run `cargo run -p codex-cli -- doctor --summary`. 2. Confirm the Environment section includes `system`, `git`, `terminal`, and `title` rows. 3. Run `cargo run -p codex-cli -- doctor --json`. 4. Confirm the JSON contains `system.environment`, `git.environment`, and `terminal.title`; on Windows, confirm `terminal.env` details include console code pages and `VT processing` for stdout/stderr. 5. From a non-git directory, run the same `doctor --json` command and confirm the Git check reports `repo detected: false` rather than warning. Targeted tests: - `cargo test -p codex-cli doctor` - `cargo test -p codex-cli`
Felipe Coury ·
2026-05-24 15:34:35 +00:00 -
package: include zsh fork in Codex package (#23756)
## Why The package layout gives Codex a stable place for runtime helpers that should travel with the entrypoint. `shell_zsh_fork` still required users to configure `zsh_path` manually, even though we already publish prebuilt zsh fork artifacts. This PR builds on #24129 and uses the shared DotSlash artifact fetcher to include the zsh fork in Codex packages when a matching target artifact exists. Packaged Codex builds can then discover the bundled fork automatically; the user/profile `zsh_path` override is removed so the feature uses the package-managed artifact instead of a legacy path knob. ## What Changed - Added `scripts/codex_package/codex-zsh`, a checked-in DotSlash manifest for the current macOS arm64 and Linux zsh fork artifacts. - Taught `scripts/build_codex_package.py` to fetch the matching zsh fork artifact and install it at `codex-resources/zsh/bin/zsh` when available for the selected target. - Added package layout validation for the optional bundled zsh resource. - Added `InstallContext::bundled_zsh_path()` and `InstallContext::bundled_zsh_bin_dir()` for package-layout resource discovery. - Threaded the packaged zsh path through config loading as the runtime `zsh_path` for packaged installs, and removed the config/profile/CLI override path. - Kept the packaged default zsh override typed as `AbsolutePathBuf` until the existing runtime `Config::zsh_path` boundary. - Updated app-server zsh-fork integration tests to spawn `codex-app-server` from a temporary package layout with `codex-resources/zsh/bin/zsh`, matching the new packaged discovery path instead of setting `zsh_path` in config. - Switched package executable copying from metadata-preserving `copy2()` to `copyfile()` plus explicit executable bits, which avoids macOS file-flag failures when local smoke tests use system binaries as inputs. ## Testing To verify that the `zsh` executable from the Codex package is picked up correctly, first I ran: ```shell ./scripts/build_codex_package.py ``` which created: ``` /private/var/folders/vw/x2knqmks50sfhfpy27nftl900000gp/T/codex-package-pms94kdp/ ``` so then I ran: ``` /private/var/folders/vw/x2knqmks50sfhfpy27nftl900000gp/T/codex-package-pms94kdp/bin/codex exec --enable shell_zsh_fork 'run `echo $0`' ``` which reported the following, as expected: ``` /private/var/folders/vw/x2knqmks50sfhfpy27nftl900000gp/T/codex-package-pms94kdp/codex-resources/zsh/bin/zsh ``` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23756). * #23768 * __->__ #23756
Michael Bolin ·
2026-05-22 17:54:07 -07:00 -
chore: add JSON schema policy fixture coverage (#24152)
## Why Before changing the Codex Bridge JSON schema policy, add integration coverage around real connector-like MCP tool schemas. The existing unit tests cover individual sanitizer behaviors, but they do not make it easy to see whether full fixture schemas keep model-visible guidance, prune only unreachable definitions, drop unsupported JSON Schema fields, and stay within the Responses API schema budget. ## What Changed - Added `tools/tests/json_schema_policy_fixtures.rs`, which converts MCP tool fixtures through `mcp_tool_to_responses_api_tool` and validates the resulting Responses tool parameters. - Added connector-style fixtures for Slack, Google Calendar, Google Drive, Notion, and Microsoft Outlook Email under `tools/tests/fixtures/json_schema_policy/`. - Added fixture assertions for preserved guidance, pruned definitions, expected field drops after `JsonSchema` conversion, marker count baselines, and dangling local `$ref` prevention. - Added a real oversized golden Notion `create_page` input schema fixture to exercise the compaction path that strips descriptions, drops root `$defs`, rewrites local refs, and fits the compacted schema under the budget.
Celia Chen ·
2026-05-22 16:31:33 -07:00 -
[codex] Add image re-encoding benchmarks (#23935)
## Summary - add Divan benchmarks for prompt image re-encoding paths - wire the image benchmark smoke test into Rust CI workflows ## Why Image prompt handling includes re-encoding work that benefits from repeatable benchmark coverage so changes can be measured in CI and locally. This already helped identify a potential regression from changing compiler flags. ## Impact Developers can run and compare the new image re-encoding benchmarks, and CI exercises the benchmark target via the Rust benchmark smoke test.
Adam Perry @ OpenAI ·
2026-05-22 22:38:40 +00:00 -
[codex] Use rolling files for Windows sandbox logs (#24117)
## Why Windows sandbox diagnostics currently append to a single `sandbox.log` under `CODEX_HOME/.sandbox`. That file never rolls over, which makes it hard to safely include sandbox diagnostics in future feedback reports without risking unbounded growth. ## What changed - Replaced direct append-open sandbox logging with `tracing_appender::rolling::RollingFileAppender`. - Configured sandbox logs to rotate daily using names like `sandbox.YYYY-MM-DD.log`. - Added a conservative `MAX_LOG_FILES` cap of 90 retained matching log files. - Routed the Windows sandbox setup helper through the same rolling writer. - Added helpers for resolving the current daily sandbox log path so future feedback upload work can use the same filename logic. - Updated tests and test diagnostics to read the dated daily log file. This intentionally does not include sandbox logs in `/feedback` yet; scrubbing and attachment behavior can happen in a follow-up. ## Testing - `cargo fmt -p codex-windows-sandbox` - `cargo check -p codex-windows-sandbox` - `cargo test -p codex-windows-sandbox` - `cargo test -p codex-windows-sandbox logging::tests` - `cargo clippy -p codex-windows-sandbox --all-targets -- -D warnings`
iceweasel-oai ·
2026-05-22 11:37:01 -07:00 -
feat: support local refs and defs in tool input schemas (#23357)
# Why Some connector tool input schemas use local JSON Schema references and definition tables to avoid duplicating large nested shapes. Codex previously lowered these schemas into the supported subset in a way that could discard `$ref`-only schema objects and lose the corresponding definitions, which made non-strict tool registration less faithful than the original connector schema. This keeps the existing minimal-lowering policy: Codex still does not raw-pass through arbitrary JSON Schema, but it now preserves local reference structure that fits the Responses-compatible subset and prunes definition entries that cannot be reached by following `$ref`s from the root schema after sanitization, including refs found transitively inside other reachable definitions. The pruning matters because Responses parses definition tables even when entries are unused, so keeping dead definitions wastes prompt tokens. # What changed - Added `$ref`, `$defs`, and legacy `definitions` fields to the tool `JsonSchema` representation. - Updated `parse_tool_input_schema` lowering so `$ref`-only schema objects survive sanitization instead of becoming `{}`. - Sanitized definition tables recursively and dropped malformed definition tables so non-strict registration degrades gracefully. - Added reachability pruning for root definition tables by starting from refs outside definition tables, then following refs inside reachable definitions. - Added JSON Pointer decoding for local definition refs such as `#/$defs/Foo~1Bar`. # Verification ran local golden-schema probes against representative connector schemas to validate behavior on real generated schemas: | Golden schema | Before bytes | After bytes | `$defs` before -> after | `$ref` before -> after | Result | |---|---:|---:|---:|---:|---| | `google_calendar/create_space` | 7111 | 4526 | 7 -> 7 | 7 -> 7 | all definitions preserved because all are reachable | | `figma/apply_file_variable_changes` | 4609 | 999 | 8 -> 5 | 8 -> 5 | unused defs pruned after unsupported `oneOf` shapes lower away | | `snowflake/list_catalog_integrations` | 1380 | 404 | 3 -> 0 | 0 -> 0 | all defs pruned because none are referenced | | `dropbox/create_shared_link` | 8894 | 1836 | 14 -> 4 | 9 -> 4 | only defs reachable from the root schema after sanitization are retained, including transitively through other retained defs | Token increase across golden schema due to this change: <img width="817" height="366" alt="Screenshot 2026-05-19 at 1 47 04 PM" src="https://github.com/user-attachments/assets/d5c80fe9-da85-41e6-8ac7-a01d1e0b0f71" />Celia Chen ·
2026-05-22 00:32:14 +00:00 -
[codex] Make thread search case-insensitive (#23921)
## Summary - make rollout content search prefilter rollout files case-insensitively - keep the no-ripgrep fallback scan and visible snippet matcher aligned with that behavior - cover a lowercase `thread/search` query matching mixed-case conversation content ## Why The rollout-backed `thread/search` path used exact string matching in both its `rg` prefilter and semantic snippet generation. A content result could be missed solely because the query casing did not match the stored conversation text. ## Validation - `just fmt` - `cargo test -p codex-app-server thread_search_returns_content_matches` - `cargo test -p codex-rollout` - `just bazel-lock-update` - `just bazel-lock-check` - `cargo build -p codex-cli` - launched a local Electron dev instance with the rebuilt CLI binary
Francis Chalissery ·
2026-05-21 14:14:01 -07:00 -
[codex] Add rollout-backed thread content search (#23519)
## Summary - add experimental `thread/search` for local rollout-backed thread search using `rg` over JSONL rollouts - return search-specific result rows with optional previews instead of storing preview data on `StoredThread` or ordinary `Thread` responses - keep `thread/list` separate from full-content search and document the new app-server surface ## Testing - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-app-server thread_search_returns_content_and_title_matches -- --nocapture`
Francis Chalissery ·
2026-05-21 11:52:24 -07:00 -
jif-oai ·
2026-05-21 13:46:29 +02:00 -
Use named MITM permissions config (#18240)
## Stack 1. Parent PR: #18868 adds MITM hook config and model only. 2. Parent PR: #20659 wires hook enforcement into the proxy request path. 3. This PR changes the user facing PermissionProfile TOML shape. ## Why 1. The broader goal is to make MITM clamping usable from the same permission profile that already controls network behavior. 2. This PR is the config UX layer for the stack. It moves MITM policy into `[permissions.<profile>.network.mitm]` instead of exposing the flat runtime shape to users. 3. The named hook and action tables belong here because users need reusable policy blocks that are easy to review, while the proxy runtime only needs a flat hook list. 4. This PR validates action refs during config parsing so mistakes in the user facing policy fail before a proxy session starts. 5. Keeping the lowering here lets the proxy keep its simpler runtime model and lets PermissionProfile remain the single source of network permission policy. ## Summary 1. Keep MITM policy inside `[permissions.<profile>.network.mitm]` so the selected PermissionProfile owns network proxy policy. 2. Use named MITM hooks under `[permissions.<profile>.network.mitm.hooks.<name>]`. 3. Put host, methods, path prefixes, query, headers, body, and action refs on the hook table. 4. Define reusable action blocks under `[permissions.<profile>.network.mitm.actions.<name>]`. 5. Represent action blocks with `NetworkMitmActionToml`, then lower them into the proxy runtime action config. 6. Reject unknown refs, empty refs, and empty action blocks during config parsing. 7. Keep the runtime hook model unchanged by lowering config into the existing proxy hook list. 8. Preserve the #20659 activation fix for nested MITM policy. ## Example ```toml [permissions.workspace.network.mitm] enabled = true [permissions.workspace.network.mitm.hooks.github_write] host = "api.github.com" methods = ["POST", "PUT"] path_prefixes = ["/repos/openai/"] action = ["strip_auth"] [permissions.workspace.network.mitm.actions.strip_auth] strip_request_headers = ["authorization"] ``` ## Validation 1. Regenerated the config schema. 2. Ran the core MITM config parsing and validation tests. 3. Ran the core PermissionProfile MITM proxy activation tests. 4. Ran the core config schema fixture test. 5. Ran the network proxy MITM policy tests. 6. Ran the scoped Clippy fixer for the network proxy crate. 7. Ran the scoped Clippy fixer for the core crate. --------- Co-authored-by: Winston Howes <winston@openai.com>
evawong-oai ·
2026-05-20 17:10:37 -07:00 -
Remove Windows sandbox resource stamping (#23764)
## Why The `codex-windows-sandbox` crate was embedding Windows resource metadata through a package-level `build.rs`. Because that package also exposes the `codex_windows_sandbox` library, downstream binaries that link the library could inherit `FileDescription` / `ProductName` values of `codex-windows-sandbox`. That made ordinary Codex binaries, including the long-lived `codex.exe` app-server sidecar, appear as `codex-windows-sandbox` in Windows UI surfaces such as Task Manager / file properties. We do not rely on this metadata enough to justify a larger bin-only resource split, so this removes the resource stamping entirely. ## What changed - Removed the `windows-sandbox-rs` build script that invoked `winres`. - Removed the setup manifest that was only consumed by that build script. - Removed the `winres` build dependency and corresponding `Cargo.lock` / `MODULE.bazel.lock` entries. - Removed the now-unused Bazel build-script data. ## Verification - `cargo build -p codex-windows-sandbox --bins` - `cargo build -p codex-cli --bin codex` - `bazel mod deps --lockfile_mode=update` via Bazelisk, with local remote-cache-disabling flags because `bazel` is not installed on PATH here - `bazel mod deps --lockfile_mode=error` via Bazelisk, with the same local flags - Verified rebuilt `codex.exe`, `codex-command-runner.exe`, and `codex-windows-sandbox-setup.exe` now have blank `FileDescription` / `ProductName` fields. - `cargo test -p codex-windows-sandbox` still fails on two legacy Windows sandbox tests with `CreateRestrictedToken failed: 87` and the follow-on poisoned test lock; 85 passed, 2 ignored.
iceweasel-oai ·
2026-05-20 16:15:21 -07:00 -
fix(config): resolve cloud requirements deny-read globs (#23729)
## Why Cloud-managed `requirements.toml` contents were deserialized without an `AbsolutePathBuf` base directory. Relative managed `permissions.filesystem.deny_read` glob entries therefore failed while the equivalent local system requirements path succeeded under its `AbsolutePathBufGuard`. This follows the `codex_home` base path convention clarified in https://github.com/openai/codex/pull/15707. ## What changed - Resolve cloud requirements TOML under an `AbsolutePathBufGuard` rooted at `codex_home`. - Reuse the same base for cloud requirements loaded from the signed cache. - Add a regression test for a relative cloud-managed `deny_read` glob. ## Validation - `just fmt` - `cargo test -p codex-cloud-requirements` - `cargo clippy -p codex-cloud-requirements --all-targets --no-deps` - `just bazel-lock-update` - `just bazel-lock-check` - `git diff --check`
viyatb-oai ·
2026-05-20 12:15:44 -07:00 -
feat: add turn_id and truncation_policy to extension tool calls (#23666)
## Why Extension-owned tools currently receive a stripped `ToolCall` with only `call_id`, `tool_name`, and `payload`. That makes extension work that needs turn-local execution context awkward, especially web-search extension work that needs the active `truncation_policy` at tool invocation time. Reconstructing that value from config or `ExtensionData` would be indirect and could drift from the actual turn context, so the cleaner fix is to pass the needed turn metadata directly on the extension-facing invocation type. ## What changed - added `turn_id` and `truncation_policy` to `codex_tools::ToolCall` - populated those fields when core adapts `ToolInvocation` into an extension tool call - added a focused adapter test that verifies extension executors receive the forwarded turn metadata - updated the memories extension tests to construct the richer `ToolCall` - added the `codex-utils-output-truncation` dependency to `codex-tools` and refreshed lockfiles ## Testing - `cargo test -p codex-tools` - `cargo test -p codex-memories-extension` - `cargo test -p codex-core passes_turn_fields_to_extension_call` - `just bazel-lock-update` - `just bazel-lock-check`
jif-oai ·
2026-05-20 20:14:41 +02:00 -
runtime: use install context for bundled bwrap (#23634)
## Summary The Linux sandbox should find bundled `bwrap` through the same package-layout abstraction as the rest of the runtime, instead of maintaining a separate standalone-specific lookup path. This adds an `InstallContext` helper for bundled resources and updates `codex-linux-sandbox` to ask the current install context for `codex-resources/bwrap` before falling back to the old executable-relative probes. The tests cover npm-style, standalone, and canonical package layouts so `bwrap` lookup follows the package structure introduced earlier in the stack. ## Test plan - `cargo test -p codex-install-context` - `cargo test -p codex-linux-sandbox --lib` - `just fix -p codex-install-context -p codex-linux-sandbox` - `just bazel-lock-check` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23634). * #23638 * #23637 * #23636 * #23635 * __->__ #23634
Michael Bolin ·
2026-05-20 08:24:43 -07:00 -
feat: wire goal extension tools to the dedicated goal store (#23685)
## Why `ext/goal` already had the tool specs and contributor wiring for `/goal`, but the installed tools still depended on a placeholder backend that always errored. That meant the extension could not actually own goal persistence even though the dedicated `thread_goals` store already exists. This change wires the extension tools directly to the dedicated goal store so the extension can create, read, and complete goals against real state instead of falling back to host-side placeholders. ## What changed - make `install_with_backend(...)` require `Arc<codex_state::StateRuntime>` so goal storage is always available when the extension is installed - remove the unused no-backend/public backend abstraction from `ext/goal` and have the tool executors talk directly to `StateRuntime` - map `thread_goals` rows into the existing protocol response shape for `get_goal`, `create_goal`, and `update_goal` - preserve current thread-list behavior by filling an empty thread preview from the goal objective when a goal is created through the extension path - add integration coverage for the installed tool surface, including successful goal creation and duplicate-create rejection ## Testing - `cargo test -p codex-goal-extension`
jif-oai ·
2026-05-20 14:44:17 +02:00 -
runtime: detect Codex package layout (#23596)
## Why The package-builder stack now creates a canonical Codex package directory where the entrypoint lives under `bin/`, bundled helper resources live under `codex-resources/`, and bundled PATH-style tools live under `codex-path/`. That layout is not specific to the standalone installer: npm, brew, install scripts, and manually unpacked artifacts should all be able to use the same package shape. The Rust runtime still only knew about the legacy standalone release layout, where resources sit next to the executable. A packaged binary therefore would not identify its package root or prefer the bundled `rg` from `codex-path/`. ## What changed - Adds `CodexPackageLayout` to `codex-install-context` and detects it from an executable path shaped like `<package>/bin/<entrypoint>` when `<package>/codex-package.json` is present. - Splits `InstallContext` into an install `method` plus an optional package layout so the layout is shared across npm, bun, brew, standalone, and other launch contexts. - Stores package-layout paths as `AbsolutePathBuf` values. - Keeps `codex-resources/` and `codex-path/` optional so Codex can still run with degraded behavior if sidecar directories are missing. - Updates `InstallContext::rg_command()` to prefer bundled `codex-path/rg` or `rg.exe`, then fall back to the legacy standalone resources location, then system `rg`. - Updates `codex doctor` reporting so package installs show package, bin, resources, and path directories, and so bundled search detection recognizes `codex-path/` for any install method. ## Test plan - `cargo test -p codex-install-context` - `cargo test -p codex-cli` - `cargo test -p codex-tui update_action::tests::maps_install_context_to_update_action` - `just bazel-lock-check`
Michael Bolin ·
2026-05-19 23:13:49 -07:00 -
CI: Customize v8 building (#22086)
## Summary Move the rusty_v8 artifact production into hermetic Bazel path and bump the `v8` crate to `147.4.0` The new flow builds V8 release artifacts from source for Darwin and Linux targets, publishes both the current release-compatible artifacts and sandbox-enabled variants, and keeps Cargo consumers on prebuilt binaries by continuing to feed the `v8` crate the archive and generated binding files it already expects. ## Why We need control over V8 build-time features without giving up prebuilt artifacts for downstream Cargo builds. Upstream `rusty_v8` already supports source-only features such as `v8_enable_sandbox`, but its normal prebuilt release assets do not cover every feature combination we need. Building the artifacts ourselves lets us enable settings such as the V8 sandbox and pointer compression at artifact build time, then publish those outputs so ordinary Cargo builds can still consume prebuilts instead of compiling V8 locally. This keeps the fast consumer experience of prebuilt `rusty_v8` archives while giving us a reproducible path to ship featureful variants that upstream does not currently publish for us. ## Implementation Notes The Bazel graph in this PR is not copied wholesale from `rusty_v8`; `rusty_v8`'s normal source build is still GN/Ninja-based. Instead, this change starts from upstream V8's Bazel rules and adapts them to Codex's hermetic toolchains and dependency layout. Where we intentionally follow `rusty_v8`, we mirror its existing artifact contract: - the same `v8` crate version and generated binding expectations - the same sandbox feature relationship, where sandboxing requires pointer compression - the same custom libc++ model expected by Cargo's default `use_custom_libcxx` feature - the same release-style archive plus `src_binding` outputs consumed by the `v8` crate To preserve that contract, the Bazel release path pins the libc++, libc++abi, and llvm-libc revisions used by `rusty_v8 v147.4.0`, builds release artifacts with `--config=rusty-v8-upstream-libcxx`, and folds the matching runtime objects into the final static archive. ## Windows Windows is annoyingly handled differently. Codex's current hermetic Bazel Windows C++ platform is `windows-gnullvm` / `x86_64-w64-windows-gnu`, while upstream `rusty_v8` publishes Windows prebuilts for `*-pc-windows-msvc`. Those are different ABIs, so the Bazel graph cannot truthfully reproduce the upstream MSVC artifacts until we add a real MSVC-targeting C++ toolchain. For now: - Windows MSVC consumers continue to use upstream `rusty_v8` release archives. - Windows GNU targets are built in-tree so they link against a matching GNU ABI. - The canary workflow separately exercises upstream `rusty_v8` source builds for MSVC sandbox artifacts, but MSVC is not yet part of the Bazel-produced release matrix. ## Validation This PR is technically self validating through CI. I have already published it as a release tag so the artifacts from this branch are published to https://github.com/openai/codex/releases/tag/rusty-v8-v147.4.0 CI for this PR should therefore consume our own release targets. I have also locally tested for linux and darwin. --------- Co-authored-by: Codex <noreply@openai.com>
Channing Conger ·
2026-05-18 21:33:05 -07:00 -
fix(plugins): keep version upgrades additive (#23356)
## Why Windows can reject plugin cache upgrades when a running MCP server still has its working directory inside the currently active plugin version. The existing cache refresh path replaces `plugins/cache/<marketplace>/<plugin>` as a whole, so a live handle under the old version can make an otherwise ordinary version bump fail. This PR keeps the existing plugin-selection model intact while making version bumps less disruptive. ## What changed - When installing a new version beside an existing plugin cache root, move only the staged version directory into place instead of replacing the whole plugin root. - Best-effort prune older sibling version directories after the new version is activated. - Preserve the existing whole-root replacement path for first installs and same-version refreshes. - Add regression coverage for upgrading from `1.0.0` to `2.0.0` without replacing the plugin root. ## Verification - `cargo test -p codex-core-plugins install_with_new_version` - `cargo fmt --package codex-core-plugins --check`
iceweasel-oai ·
2026-05-19 04:02:30 +00:00 -
Make extension lifecycle hooks async (#23291)
## Why Extension lifecycle hooks sit on the host/extension boundary, but the current trait surface only allows synchronous callbacks. That forces extensions that need to seed, rehydrate, observe, or flush extension-owned state during thread and turn transitions to either block inside the callback or move async work into separate host plumbing. This PR makes those lifecycle callbacks awaitable so extension implementations can perform async work directly at the lifecycle point where the host already has the relevant session, thread, or turn stores available. ## What changed - Makes `ThreadLifecycleContributor` and `TurnLifecycleContributor` async in `codex-extension-api`. - Awaits thread start/resume/stop and turn start/stop/abort lifecycle callbacks from `codex-core`. - Updates the guardian and memories extensions to implement the async lifecycle trait surface. - Updates the existing lifecycle tests to use async contributor implementations. - Adds `async-trait` to the crates that now expose or implement these async object-safe lifecycle traits. ## Testing - Existing `codex-core` lifecycle tests were updated to cover async implementations for thread stop and turn abort ordering.
jif-oai ·
2026-05-18 13:53:58 +02:00 -
chore: goal ext skeleton (#23288)
Skeleton of `/goal` in extension Lot's of follow-ups coming
jif-oai ·
2026-05-18 13:32:21 +02: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 -
Move memory prompt injection to app-server extension (#22841)
## Why Memory prompt injection should be owned by the extension path that app-server composes at runtime, not by an inlined special case inside `codex-core`. This keeps `codex-core` focused on session orchestration while allowing the memories extension to own its app-server prompt behavior. ## What Changed - Registers `codex-memories-extension` in the app-server extension registry. - Moves the memory developer-instruction injection out of `core/src/session/mod.rs` and into the memories extension prompt contributor. - Adds config-change handling so the extension keeps its per-thread memory settings in sync after startup. - Leaves memories read/retrieval tools unregistered for now so this PR only changes prompt injection. - Removes the stale `cargo-shear` ignore now that app-server depends on the extension crate. ## Validation Not run locally; validation is left to CI.
jif-oai ·
2026-05-15 16:19:34 +02:00 -
permissions: support workspace roots in profiles (#22610)
## Why This is the configuration/model half of the alternative permissions migration we discussed as a comparison point for [#22401](https://github.com/openai/codex/pull/22401) and [#22402](https://github.com/openai/codex/pull/22402). The old `workspace-write` model mixes three concerns that we want to keep separate: - reusable profile rules that should stay immutable once selected - user/runtime workspace roots from `cwd`, `--add-dir`, and legacy workspace-write config - internal Codex writable roots such as memories, which should not be shown as user workspace roots This PR gives permission profiles first-class `workspace_roots` so users can opt multiple repositories into the same `:workspace_roots` rules without using broad absolute-path write grants. It also starts separating the raw selected profile from the effective runtime profile by making `Permissions` expose explicit accessors instead of public mutable fields. A representative `config.toml` looks like this: ```toml default_permissions = "dev" [permissions.dev.workspace_roots] "~/code/openai" = true "~/code/developers-website" = true [permissions.dev.filesystem.":workspace_roots"] "." = "write" ".codex" = "read" ".git" = "read" ".vscode" = "read" ``` If Codex starts in `~/code/codex` with that profile selected, the effective workspace-root set becomes: - `~/code/codex` from the runtime `cwd` - `~/code/openai` from the profile - `~/code/developers-website` from the profile The `:workspace_roots` rules are materialized across each root, so `.git`, `.codex`, and `.vscode` stay scoped the same way everywhere. Runtime additions such as `--add-dir` can still layer on later stack entries without mutating the selected profile. ## Stack Shape This PR intentionally stops before the profile-identity cleanup in [#22683](https://github.com/openai/codex/pull/22683) so the base review stays focused on config loading, workspace-root materialization, and compatibility with legacy `workspace-write`. The representation in this PR is therefore transitional: `Permissions` carries enough state to distinguish the raw constrained profile from the effective runtime profile, and there are still call sites that must keep the active profile identity and constrained profile value in sync. The follow-up PR replaces that with a single resolved profile state (`ResolvedPermissionProfile` / `PermissionProfileState`) that keeps the profile id, immutable `PermissionProfile`, and profile-declared workspace roots together. That follow-up removes APIs such as `set_constrained_permission_profile_with_active_profile()` where separate arguments could drift out of sync. Downstream PRs then build on this base to switch app-server turn updates to profile ids plus runtime workspace roots and to finish the user-visible summary behavior. Reviewers should judge this PR as the workspace-roots foundation, not as the final in-memory shape of selected permission profiles. ## Review Guide Suggested review order: 1. Start with `codex-rs/core/src/config/mod.rs`. This is the main shape change in the base slice. `Permissions` now stores a private raw `Constrained<PermissionProfile>` plus runtime `workspace_roots`. Callers use `permission_profile()` when they need the raw constrained value and `effective_permission_profile()` when they need a materialized runtime profile. As noted above, [#22683](https://github.com/openai/codex/pull/22683) replaces this transitional shape with a resolved profile state that keeps identity and profile data together. 2. Review `codex-rs/config/src/permissions_toml.rs` and `codex-rs/core/src/config/permissions.rs`. These add `[permissions.<id>.workspace_roots]`, resolve enabled entries relative to the policy cwd, and keep `:workspace_roots` deny-read glob patterns symbolic until the actual roots are known. 3. Review `codex-rs/protocol/src/permissions.rs` and `codex-rs/protocol/src/models.rs`. These add the policy/profile materialization helpers that expand exact `:workspace_roots` entries and scoped deny-read globs over every workspace root. This is also where `ActivePermissionProfileModification` is removed from the core model. 4. Review the legacy bridge in `Config::load_from_base_config_with_overrides` and `Config::set_legacy_sandbox_policy`. This is where legacy `workspace-write` roots become runtime workspace roots, while Codex internal writable roots stay internal and do not appear as user-facing workspace roots. 5. Then skim downstream call sites. The interesting pattern is raw-vs-effective access: state/proxy/bwrap paths keep the raw constrained profile, while execution, summaries, and user-visible status use the effective profile and workspace-root list. ## What Changed - added `[permissions.<id>.workspace_roots]` to the config model and schema - added runtime `workspace_roots` state to `Config`/`Permissions` and `ConfigOverrides` - made `Permissions` profile fields private and replaced direct mutation with accessors/setters - added `PermissionProfile` and `FileSystemSandboxPolicy` helpers for materializing `:workspace_roots` exact paths and deny-read globs across all roots - moved legacy additional writable roots into runtime workspace-root state instead of active profile modifications - removed `ActivePermissionProfileModification` and its app-server protocol/schema export - updated sandbox/status summary paths so internal writable roots are not reported as user workspace roots ## Verification Strategy The targeted tests cover the behavior at the layers where regressions are most likely: - `codex-rs/core/src/config/config_tests.rs` verifies config loading, legacy workspace-root seeding, effective profile materialization, and memory-root handling. - `codex-rs/core/src/config/permissions_tests.rs` verifies profile `workspace_roots` parsing and `:workspace_roots` scoped/glob compilation. - `codex-rs/protocol/src/permissions.rs` unit tests verify exact and glob materialization over multiple workspace roots. - `codex-rs/tui/src/status/tests.rs` and `codex-rs/utils/sandbox-summary/src/sandbox_summary.rs` verify the user-facing summaries show effective workspace roots and hide internal writes. I also ran `cargo check --tests` locally after the latest stack refresh to catch cross-crate API breakage from the private-field/accessor changes. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22610). * #22612 * #22611 * #22683 * __->__ #22610
Michael Bolin ·
2026-05-14 18:25:23 -07:00 -
Trim TUI legacy core helper usage (#22695)
## Why The TUI still had a few low-risk dependencies flowing through the transitional `legacy_core` namespace after the app-server migration. These helpers either already have clearer non-core owners or are presentation logic that does not belong in `codex-core`, so moving them out reduces the compatibility surface without changing product behavior. ## What changed This is a low-risk change, almost completely mechanical in nature. - Route TUI Codex-home lookup through `codex-utils-home-dir`, use `Config::log_dir` directly, and call `codex-sandboxing::system_bwrap_warning` without going through `legacy_core`. - Move shared `codex resume` hint formatting from `codex-core` into `codex-utils-cli`. - Update CLI and TUI call sites to use the shared CLI utility, and keep the resume-command behavior covered by tests in its new home. ## Verification - `cargo test -p codex-utils-cli` - `cargo test -p codex-utils-cli resume_command`
Eric Traut ·
2026-05-14 16:54:59 -07:00 -
[codex] add plugin marketplace CLI commands (#21396)
## Why Plugin CLI installs should behave more like `apt-get install`: configured marketplaces are the only install sources, the local marketplace snapshot is the package index used at install time, and `plugins/cache` is only a cache of already-downloaded plugin bytes. That distinction matters once marketplaces and plugins have auth or availability state. A repo-local marketplace manifest or leftover cached plugin artifact should not silently become an install source unless the marketplace was explicitly configured and its readable snapshot still authorizes the plugin. ## What Changed - add CLI commands to list configured marketplaces and add, list, or remove marketplace plugins - accept stable `plugin@marketplace` ids for add/remove while preserving the explicit `--marketplace` form - restrict `codex plugin add` and `codex plugin list` to configured marketplaces instead of also discovering current-working-directory marketplace roots - fail `codex plugin add` and `codex plugin list` when a configured marketplace snapshot is missing or malformed instead of treating it as an empty source or a generic plugin miss - preserve marketplace snapshot semantics: a configured local/Git marketplace snapshot can authorize installs without consulting the original upstream source - allow `plugins/cache` reuse only after configured marketplace resolution succeeds - keep removal resilient after marketplace deletion or drift and ignore malformed marketplace config entries in listing ## Commands Added - `codex plugin add <plugin>@<marketplace>` - `codex plugin add <plugin> --marketplace <marketplace>` - `codex plugin list` - `codex plugin list --marketplace <marketplace>` - `codex plugin remove <plugin>@<marketplace>` - `codex plugin remove <plugin> --marketplace <marketplace>` - `codex plugin marketplace add <source>` - `codex plugin marketplace add <source> --ref <ref>` - `codex plugin marketplace add <source> --sparse <path>` - `codex plugin marketplace list` - `codex plugin marketplace upgrade` - `codex plugin marketplace upgrade <marketplace>` - `codex plugin marketplace remove <marketplace>` ## CLI Help Output <details> <summary><code>codex plugin --help</code></summary> ```text Manage Codex plugins Usage: codex plugin [OPTIONS] <COMMAND> Commands: add Install a plugin from a configured marketplace snapshot list List plugins available from configured marketplace snapshots marketplace Add, list, upgrade, or remove configured plugin marketplaces remove Remove an installed plugin from local config and cache help Print this message or the help of the given subcommand(s) ``` </details> <details> <summary><code>codex plugin add --help</code></summary> ```text Install a plugin from a configured marketplace snapshot. Pass either `PLUGIN@MARKETPLACE` or pass `PLUGIN` with `--marketplace MARKETPLACE`. Usage: codex plugin add [OPTIONS] <PLUGIN[@MARKETPLACE]> Arguments: <PLUGIN[@MARKETPLACE]> Plugin selector to install: either PLUGIN@MARKETPLACE or PLUGIN with --marketplace Options: -m, --marketplace <MARKETPLACE> Configured marketplace name to use when PLUGIN does not include @MARKETPLACE Examples: codex plugin add sample@debug codex plugin add sample --marketplace debug ``` </details> <details> <summary><code>codex plugin list --help</code></summary> ```text List plugins available from configured marketplace snapshots Usage: codex plugin list [OPTIONS] Options: -m, --marketplace <MARKETPLACE> Only list plugins from this configured marketplace name Examples: codex plugin list codex plugin list --marketplace debug ``` </details> <details> <summary><code>codex plugin remove --help</code></summary> ```text Remove an installed plugin from local config and cache. Pass either `PLUGIN@MARKETPLACE` or pass `PLUGIN` with `--marketplace MARKETPLACE`. Usage: codex plugin remove [OPTIONS] <PLUGIN[@MARKETPLACE]> Arguments: <PLUGIN[@MARKETPLACE]> Plugin selector to remove: either PLUGIN@MARKETPLACE or PLUGIN with --marketplace Options: -m, --marketplace <MARKETPLACE> Marketplace name to use when PLUGIN does not include @MARKETPLACE Examples: codex plugin remove sample@debug codex plugin remove sample --marketplace debug ``` </details> <details> <summary><code>codex plugin marketplace --help</code></summary> ```text Add, list, upgrade, or remove configured plugin marketplaces Usage: codex plugin marketplace [OPTIONS] <COMMAND> Commands: add Add a local or Git marketplace to the configured marketplace sources list List configured marketplace names and their local snapshot roots upgrade Refresh configured Git marketplace snapshots remove Remove a configured marketplace source by name ``` </details> <details> <summary><code>codex plugin marketplace add --help</code></summary> ```text Add a local or Git marketplace to the configured marketplace sources Usage: codex plugin marketplace add [OPTIONS] <SOURCE> Arguments: <SOURCE> Marketplace source: a local path, owner/repo[@ref], HTTPS Git URL, or SSH Git URL Options: --ref <REF> Git ref to fetch for Git marketplace sources --sparse <PATH> Sparse checkout path for Git marketplace sources. Can be repeated Examples: codex plugin marketplace add ./path/to/marketplace codex plugin marketplace add owner/repo --ref main codex plugin marketplace add https://github.com/owner/repo --sparse plugins/foo ``` </details> <details> <summary><code>codex plugin marketplace list --help</code></summary> ```text List configured marketplace names and their local snapshot roots Usage: codex plugin marketplace list [OPTIONS] ``` </details> <details> <summary><code>codex plugin marketplace upgrade --help</code></summary> ```text Refresh configured Git marketplace snapshots. Omit MARKETPLACE_NAME to upgrade all configured Git marketplaces. Usage: codex plugin marketplace upgrade [OPTIONS] [MARKETPLACE_NAME] Arguments: [MARKETPLACE_NAME] Optional configured marketplace name to upgrade. Omit to upgrade all Git marketplaces Examples: codex plugin marketplace upgrade codex plugin marketplace upgrade debug ``` </details> <details> <summary><code>codex plugin marketplace remove --help</code></summary> ```text Remove a configured marketplace source by name Usage: codex plugin marketplace remove [OPTIONS] <MARKETPLACE_NAME> Arguments: <MARKETPLACE_NAME> Configured marketplace name to remove Example: codex plugin marketplace remove debug ``` </details> ## Public Semantics - `codex plugin add <plugin>@<marketplace>` succeeds only when `<marketplace>` is configured and its local marketplace snapshot contains `<plugin>` - repo-local marketplaces are not install sources until the user runs `codex plugin marketplace add ...` - configured marketplace snapshots must be readable; missing or malformed snapshots fail the CLI operation rather than silently falling through to cache or empty results - cached plugin artifacts can satisfy reinstall only when the configured marketplace snapshot still authorizes that plugin - cached plugin artifacts alone never make a plugin installable ## Tests - `cargo test -p codex-cli --test plugin_cli` - `cargo clippy -p codex-cli --tests -- -D warnings` - `cargo test -p codex-cli` - `git diff --check` - `just bazel-lock-update` - `just bazel-lock-check`Casey Chow ·
2026-05-14 09:33:38 -07:00