Commit Graph
16199 Commits
Author SHA1 Message Date
Michael Bolin 87625dbdb4 Merge 3bdbb6a0c8 into sapling-pr-archive-bolinfest 2026-05-20 14:11:36 -07:00
Michael Bolin 3bdbb6a0c8 release: use DotSlash zstd for package archives 2026-05-20 14:11:08 -07:00
Michael Bolin 1748ba94b9 Merge 4ca3e9eaa6 into sapling-pr-archive-bolinfest 2026-05-20 13:59:28 -07:00
Michael Bolin 4ca3e9eaa6 core: pass permission profiles to Windows runner 2026-05-20 13:59:10 -07:00
Michael Bolin e7578efcda windows-sandbox: add profile-native elevated APIs 2026-05-20 13:59:10 -07:00
Michael Bolin 4bab69b553 windows-sandbox: feed setup from resolved permissions 2026-05-20 13:59:10 -07:00
Michael Bolin f800277a1a windows-sandbox: drive write roots from resolved permissions 2026-05-20 13:59:10 -07:00
Abhinav af49d38373 Support compact SessionStart hooks (#21272)
# Why

Compaction replaces the live conversation history, so hooks that use
`SessionStart` to re-inject durable model context need a way to run
again after that rewrite.

Related - #19905 adds dedicated compact lifecycle hooks

# What

- add `compact` as a supported `SessionStart` source and matcher value
- change pending `SessionStart` state from a single slot to a small FIFO
queue so `resume` / `startup` / `clear` can be preserved alongside a
later `compact`
- drain all queued `SessionStart` sources before the next model request,
preserving their original order

# Testing

The new integration coverage verifies both the basic `compact` matcher
path and the stacked `resume` -> `compact` case where both hooks
contribute `additionalContext` to the next model turn.
2026-05-20 20:46:19 +00:00
Casey Chow 9265701b7f [skills] Create a personal update flow for plugin creator (#23542)
## Summary
Creates a personal-marketplace update flow for the plugin-creator skill
when iterating on an existing local plugin.

## Context
Plugin creation already had a scaffold path, but the follow-up story for
updating an existing local plugin during development was not explicit.
The goal of this change is to make that default personal-marketplace
update loop legible at the point of use instead of leaving it implied or
hidden behind a larger helper.

## Decision
Keep the scaffold flow intact, add a dedicated update/reinstall
reference centered on the personal marketplace, document the actual
`codex plugin add` and marketplace-check commands directly, and keep
helper automation narrowly scoped to the repetitive local-update steps.

## Changes
- update plugin-creator to point existing-plugin iteration at a
personal-marketplace update flow
- add `references/installing-and-updating.md` with the explicit
marketplace check and reinstall sequence
- add small helper scripts for reading marketplace names and updating
plugin versions during local iteration

## Tests
- `python3
codex-rs/skills/src/assets/samples/skill-creator/scripts/quick_validate.py
codex-rs/skills/src/assets/samples/plugin-creator`
- `python3 -m py_compile
codex-rs/skills/src/assets/samples/plugin-creator/scripts/create_basic_plugin.py
codex-rs/skills/src/assets/samples/plugin-creator/scripts/read_marketplace_name.py
codex-rs/skills/src/assets/samples/plugin-creator/scripts/update_plugin_cachebuster.py`
2026-05-20 16:44:41 -04:00
Michael Bolin d1e3d54192 cli: add strict config to exec-server (#23719)
## Why

PR #20559 added opt-in strict config parsing to the config-loading
command surfaces, but `codex exec-server` was left out. That meant
`codex exec-server --strict-config` was rejected even though the command
can load config for remote registration, and local server startup had no
way to fail fast on misspelled config keys.

## What Changed

- Added `--strict-config` to `codex exec-server`.
- Allowed root-level inheritance from `codex --strict-config
exec-server`.
- Validated config before local exec-server startup when strict mode is
requested.
- Reused the loaded strict-config-aware config for remote exec-server
registration auth.
- Added CLI coverage showing `codex exec-server --strict-config` rejects
unknown config fields.

## Verification

- `cargo test -p codex-cli`
- New integration test:
`strict_config_rejects_unknown_config_fields_for_exec_server`

## Documentation

Any strict-config command list on developers.openai.com/codex should
include `codex exec-server` with the other supported config-loading
entry points.
2026-05-20 13:12:31 -07:00
viyatb-oai fe7c069fe6 feat(permissions): resolve permission profile inheritance (#22270)
## Stack

This is the foundation PR for the permission-profile inheritance stack.

- This PR adds config-level `extends` resolution and merge semantics.
- Follow-up: #23705 applies resolved profiles at runtime and updates the
active-profile protocol surfaces.

## Why

Permission profiles are starting to carry enough policy that
copy-pasting near-identical definitions becomes hard to review and easy
to drift. Before the runtime can consume inherited profiles, the config
layer needs one explicit resolver that can merge parent chains and
reject unsafe or invalid inheritance shapes.

## What changed

- Add `extends` to permission-profile TOML and resolve parent chains in
inheritance order.
- Merge inherited profile TOML with the existing config merge behavior
while preserving the permission-specific normalization needed for
network domain keys.
- Keep parent descriptions out of resolved child profiles and record
inherited profile names separately for downstream consumers.
- Reject undefined parents, unsupported built-in parents, and
inheritance cycles with targeted errors.
- Cover resolver behavior with TOML fixture tests and refresh the
generated config schema.

## Validation

- `cargo test -p codex-config`
- `cargo test -p codex-core permissions_profiles_`
2026-05-20 20:12:07 +00:00
Michael Bolin 891ad97017 merge commit for archive created by Sapling 2026-05-20 12:53:37 -07:00
Michael Bolin 8600d7b0d9 core: pass permission profiles to Windows runner 2026-05-20 12:52:26 -07:00
Michael Bolin a5ba7c9b12 windows-sandbox: add profile-native elevated APIs 2026-05-20 12:52:26 -07:00
Michael Bolin 5d17344bd7 windows-sandbox: feed setup from resolved permissions 2026-05-20 12:52:25 -07:00
Michael Bolin 2bd530da8a windows-sandbox: drive write roots from resolved permissions 2026-05-20 12:51:51 -07:00
evawong-oai 3d94e24a3d Add MITM hook config model (#18868)
## Stack
1. This PR adds MITM hook config and model only.
2. Runtime follow up: #20659 wires hook enforcement into the proxy
request path.
3. User facing config follow up: #18240 moves MITM policy into the
PermissionProfile network tree.

## Why
1. Viyat asked for the original parent PR to be split so reviewers can
inspect the policy model before request behavior changes.
2. This PR gives the proxy a typed MITM hook model, validation, matcher
compilation, permissions TOML plumbing, schema support, and config
tests.
3. This PR deliberately does not change CONNECT or MITM request
handling.
4. Keeping runtime behavior out of this PR makes the review boundary
simple: does the policy model parse, validate, compile, and lower
correctly.

## Summary
1. Add the MITM hook config model and matcher compilation.
2. Validate hosts, methods, paths, query matchers, header matchers,
secret sources, and reserved body matching.
3. Add wildcard matcher support for path, query value, and header value
matching.
4. Add permissions TOML and schema support for flat runtime hook config.
5. Add config loader tests for MITM hook overlay behavior.

## Validation
1. Regenerated the config schema.
2. Ran the network proxy MITM hook unit tests.
3. Ran the core permission profile MITM hook parsing tests.
4. Ran the core config schema fixture test.
5. Ran the scoped Clippy fixer for the network proxy crate.
6. Ran the scoped Clippy fixer for the core crate.

## Notes
1. Runtime enforcement moved to #20659.
2. User facing PermissionProfile TOML shape remains in #18240.
2026-05-20 12:51:12 -07:00
Michael Bolin 61aae56571 windows-sandbox: share bundled helper lookup (#23735)
## Summary

Follow-up to #23636 review feedback: the Windows sandbox had two copies
of the same bundled-helper lookup order, one for
`codex-command-runner.exe` in `helper_materialization.rs` and one for
`codex-windows-sandbox-setup.exe` in `setup.rs`.

This PR centralizes that lookup in
`helper_materialization::bundled_executable_path_for_exe()` and has
setup reuse it for `codex-windows-sandbox-setup.exe`. The lookup
behavior is unchanged: direct sibling first, package-root
`codex-resources/` when running from `bin/`, then legacy sibling
`codex-resources/`.

## Test plan

- `cargo test -p codex-windows-sandbox`

## Notes

I also attempted `cargo check -p codex-windows-sandbox --target
x86_64-pc-windows-gnullvm`, but this local host is missing
`x86_64-w64-mingw32-clang`.
2026-05-20 19:50:38 +00:00
Michael Bolin 4155a04143 merge commit for archive created by Sapling 2026-05-20 12:43:25 -07:00
Michael Bolin a337a8f3bd core: pass permission profiles to Windows runner 2026-05-20 12:42:03 -07:00
Michael Bolin fcfb007f25 windows-sandbox: add profile-native elevated APIs 2026-05-20 12:42:03 -07:00
Michael Bolin 83a0cc132c windows-sandbox: feed setup from resolved permissions 2026-05-20 12:42:03 -07:00
Michael Bolin 412eabaf3d windows-sandbox: drive write roots from resolved permissions 2026-05-20 12:41:15 -07:00
Michael Bolin 729bdf3c8d windows-sandbox: send permission profiles to elevated runner (#22918)
## Why

This is the next PR in the Windows sandbox migration stack after #22896.
The bottom PR introduces a Windows-local resolved permissions helper
while existing callers still start from legacy `SandboxPolicy`. This PR
moves the elevated runner IPC boundary to `PermissionProfile`, which
makes the direction of the stack visible without changing the public
core call sites yet.

Because that changes the CLI-to-command-runner message shape, the framed
IPC protocol version is bumped in the same PR so the boundary change is
explicit.

## What changed

- Replaced elevated IPC `policy_json_or_preset`/`sandbox_policy_cwd`
fields with `permission_profile`/`permission_profile_cwd`.
- Bumped the elevated command-runner IPC protocol to
`IPC_PROTOCOL_VERSION = 2` and switched parent/runner frames to use the
shared constant.
- Converted the parent elevated paths from the parsed legacy policy into
a materialized `PermissionProfile` before sending the runner request.
- Added `WindowsSandboxTokenMode` resolution for managed
`PermissionProfile` values and made the runner choose read-only vs
writable-root capability tokens from that resolved profile.
- Rejected disabled, external, unrestricted, and full-disk-write
profiles before token selection.
- Added IPC JSON coverage for tagged `PermissionProfile` payloads and
token-mode unit coverage for the resolved permission helper.

## Verification

- `cargo test -p codex-windows-sandbox`
- `just fix -p codex-windows-sandbox`
- `cargo check -p codex-windows-sandbox --target x86_64-pc-windows-msvc
--tests` was attempted locally but blocked before crate type-checking
because the macOS compiler environment lacks Windows C headers such as
`windows.h` and `assert.h`; GitHub Windows CI is the required
verification for the runner path.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22918).
* #23715
* #23714
* #23167
* #22923
* __->__ #22918
2026-05-20 12:41:06 -07:00
Michael Bolin dd3da0f60e Merge 92a0893e4f into sapling-pr-archive-bolinfest 2026-05-20 12:30:17 -07:00
Michael Bolin 92a0893e4f windows-sandbox: share bundled helper lookup
Summary:
- reuse the helper materialization bundled-executable lookup for sandbox setup helper resolution
- remove duplicate direct-sibling/package-resources/legacy-resources lookup code from setup.rs

Test plan:
- just fmt
- cargo test -p codex-windows-sandbox
- just fix -p codex-windows-sandbox

Also attempted cargo check -p codex-windows-sandbox --target x86_64-pc-windows-gnullvm, but the local host is missing x86_64-w64-mingw32-clang.
2026-05-20 12:28:46 -07:00
Michael Bolin cb05de6724 dotslash: publish Codex entrypoints from package archives (#23638)
## Summary

DotSlash should resolve the same canonical package archives used by
standalone installers and npm platform packages, rather than continuing
to point at single-binary zstd artifacts or the older Linux bundle
archive.

This updates the Codex CLI and `codex-app-server` DotSlash release
config entries to match `codex-package-<target>.tar.gz` and
`codex-app-server-package-<target>.tar.gz`, with paths that select
`bin/codex` or `bin/codex-app-server` inside the extracted package. The
other helper outputs stay on their existing per-binary artifacts for
now.

## Test plan

- `python3 -m json.tool .github/dotslash-config.json > /dev/null`
- Ran a Python regex smoke test that checked every updated `codex` and
`codex-app-server` platform entry against the archive names emitted by
`.github/scripts/build-codex-package-archive.sh`.
2026-05-20 12:18:10 -07:00
viyatb-oai 0edcc4b94e 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`
2026-05-20 12:15:44 -07:00
Michael Bolin f15f967069 Merge c1665a0a53 into sapling-pr-archive-bolinfest 2026-05-20 12:10:23 -07:00
Michael Bolin c1665a0a53 dotslash: publish Codex entrypoints from package archives
## Summary

DotSlash should resolve the same canonical package layout used by standalone installers and npm platform packages, but it should not take the size regression of downloading gzip-compressed package archives. Installers continue to use `.tar.gz` because that format is broadly available, while DotSlash can use zstd-compressed tar archives.

This updates the package archive release helper to emit both `*.tar.gz` and `*.tar.zst` package archives from the same package directory. The Codex CLI and `codex-app-server` DotSlash release config entries now match `codex-package-<target>.tar.zst` and `codex-app-server-package-<target>.tar.zst`, with paths that select `bin/codex` or `bin/codex-app-server` inside the extracted package. The Windows release compression loop also skips prebuilt `.tar.zst` archives so it does not try to recompress them as ordinary files.

The other helper outputs stay on their existing per-binary artifacts for now.

## Test plan

- `python3 -m json.tool .github/dotslash-config.json > /dev/null`
- `bash -n .github/scripts/build-codex-package-archive.sh`
- `python3 -m py_compile scripts/codex_package/cli.py`
- `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/rust-release-windows.yml"); puts "ok"'`
- Ran a Python regex smoke test that checked every updated `codex` and `codex-app-server` platform entry against the `.tar.zst` archive names emitted by `.github/scripts/build-codex-package-archive.sh`.
- Ran `scripts/build_codex_package.py` with synthetic macOS entrypoint and `rg` binaries and repeated `--archive-output` values for `.tar.gz` and `.tar.zst`, verifying both archives were written.
2026-05-20 12:10:11 -07:00
Michael Bolin 86e2591663 Merge f858dff816 into sapling-pr-archive-bolinfest 2026-05-20 12:03:05 -07:00
Michael Bolin f858dff816 dotslash: publish Codex entrypoints from package archives
## Summary

DotSlash should resolve the same canonical package layout used by standalone installers and npm platform packages, but it should not take the size regression of downloading gzip-compressed package archives. Installers continue to use `.tar.gz` because that format is broadly available, while DotSlash can use zstd-compressed tar archives.

This updates the package archive release helper to emit both `*.tar.gz` and `*.tar.zst` package archives from the same package directory. The Codex CLI and `codex-app-server` DotSlash release config entries now match `codex-package-<target>.tar.zst` and `codex-app-server-package-<target>.tar.zst`, with paths that select `bin/codex` or `bin/codex-app-server` inside the extracted package. The Windows release compression loop also skips prebuilt `.tar.zst` archives so it does not try to recompress them as ordinary files.

The other helper outputs stay on their existing per-binary artifacts for now.

## Test plan

- `python3 -m json.tool .github/dotslash-config.json > /dev/null`
- `bash -n .github/scripts/build-codex-package-archive.sh`
- `python3 -m py_compile scripts/codex_package/cli.py`
- `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/rust-release-windows.yml"); puts "ok"'`
- Ran a Python regex smoke test that checked every updated `codex` and `codex-app-server` platform entry against the `.tar.zst` archive names emitted by `.github/scripts/build-codex-package-archive.sh`.
- Ran `scripts/build_codex_package.py` with synthetic macOS entrypoint and `rg` binaries and repeated `--archive-output` values for `.tar.gz` and `.tar.zst`, verifying both archives were written.
2026-05-20 12:02:38 -07:00
Michael Bolin e389e01f83 npm: ship platform packages in Codex package layout (#23637)
## Summary

The npm platform packages should stop carrying a bespoke native layout
now that the release workflow builds canonical Codex package archives.
Keeping npm on the same `bin/`, `codex-resources/`, and `codex-path/`
structure lets the Rust package-layout detection behave consistently
across standalone, npm, and future DotSlash installs.

This changes platform npm packages to stage the `codex-package` artifact
for each target under `vendor/<target>`. The Node launcher now resolves
`bin/codex` and prepends `codex-path`, while retaining legacy
`vendor/<target>/codex` and `vendor/<target>/path` fallback support for
local development and migration. The npm staging helper downloads
`codex-package` archives instead of rebuilding the CLI payload from
individual `codex`, `rg`, `bwrap`, and sandbox helper artifacts.

CI still needs to stage npm packages from historical rust-release
workflow artifacts that predate package archives, so the staging scripts
expose an explicit `--allow-legacy-codex-package` fallback. That
fallback synthesizes the canonical package layout from legacy per-binary
artifacts and is wired only into the CI smoke path; release staging
remains strict and continues to require real package archives.

For direct local use, `install_native_deps.py` now points its built-in
default workflow at the same recent artifact run used by CI and
automatically enables legacy package synthesis only when
`--workflow-url` is omitted. Explicit workflow URLs remain strict unless
callers opt in with `--allow-legacy-codex-package`.

## Test plan

- `python3 -m py_compile codex-cli/scripts/build_npm_package.py
codex-cli/scripts/install_native_deps.py scripts/stage_npm_packages.py
scripts/codex_package/cli.py`
- `node --check codex-cli/bin/codex.js`
- `ruby -e 'require "yaml";
YAML.load_file(".github/workflows/rust-release.yml");
YAML.load_file(".github/workflows/ci.yml"); puts "ok"'`
- Staged a synthetic `codex-linux-x64` platform package from a canonical
vendor tree and verified it copied only `bin/`, `codex-path/`,
`codex-resources/`, and `codex-package.json`.
- Imported `install_native_deps.py` and extracted a synthetic
`codex-package-x86_64-unknown-linux-musl.tar.gz` into `vendor/<target>`.
- Ran legacy-layout conversion smokes for Linux, Windows, and unsigned
macOS artifact naming.
- Ran a synthetic `install_native_deps.py` default-workflow smoke that
verifies legacy package synthesis is automatic only when
`--workflow-url` is omitted.
- `NPM_CONFIG_CACHE="$tmp_dir/npm-cache" python3
./scripts/stage_npm_packages.py --release-version 0.125.0 --workflow-url
https://github.com/openai/codex/actions/runs/26131514935 --package codex
--allow-legacy-codex-package --output-dir "$tmp_dir"`
- `node codex-cli/bin/codex.js --version`


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23637).
* #23638
* __->__ #23637
2026-05-20 12:02:32 -07:00
Eric Traut 7c3cc1db81 Fix thread settings clippy failure (#23724)
## Why

`main` picked up two small Rust build failures after nearby merges:

- #23507 added a real handler for
`ServerNotification::ThreadSettingsUpdated`, but the same variant was
still listed in the ignored-notification match arm. Full Clippy runs
treat the resulting unreachable-pattern warning as an error.
- #23666 added `turn_id` and `truncation_policy` to
`codex_tools::ToolCall`, while the goal extension backend test fixtures
from the goal-extension work still used the old shape. That left
`codex-goal-extension` tests unable to compile once the branches met on
`main`.

## What changed

Removed the duplicate `ThreadSettingsUpdated` match pattern from
`tui/src/chatwidget/protocol.rs`.

Updated the goal extension test `tool_call` helper to populate the new
`ToolCall` fields, and reused that helper for the one direct literal
that still had the old field list.

## Verification

- `just fix -p codex-tui`
- `cargo test -p codex-goal-extension`
2026-05-20 11:58:23 -07:00
sayan-oai ed6d73b3b9 add standalone websearch api client (#23655)
add standalone web search request types and a `codex-api` client ahead
of the extension-contributed search tool.

this adds typed commands/settings and opaque encrypted output handling
for the new standalone search flow. the endpoint types are close to
finalized but may still shift slightly as that API settles.
2026-05-20 11:38:21 -07:00
jif-oai d84b824d53 [codex] Preserve failed goal accounting flushes (#23717)
## What
- Preserve database accounting failures from the goal extension instead
of collapsing them into `None`
- Warn with turn/tool context when a flush fails
- Keep stop/abort accounting snapshots alive when the final flush did
not persist

## Why
PR #23696 can finish and discard a turn snapshot after
`account_thread_goal_usage` fails. That loses the final accumulated
accounting state silently. This follow-up keeps that failure explicit
and avoids deleting the local snapshot in the failing path.

## Testing
- `just fmt`
- `cargo test -p codex-goal-extension`
2026-05-20 20:37:27 +02:00
Michael Bolin c12f6ab7ed Merge a917a7e585 into sapling-pr-archive-bolinfest 2026-05-20 11:30:58 -07:00
Michael Bolin a917a7e585 dotslash: publish Codex entrypoints from package archives
## Summary

DotSlash should resolve the same canonical package layout used by standalone installers and npm platform packages, but it should not take the size regression of downloading gzip-compressed package archives. Installers continue to use `.tar.gz` because that format is broadly available, while DotSlash can use zstd-compressed tar archives.

This updates the package archive release helper to emit both `*.tar.gz` and `*.tar.zst` package archives from the same package directory. The Codex CLI and `codex-app-server` DotSlash release config entries now match `codex-package-<target>.tar.zst` and `codex-app-server-package-<target>.tar.zst`, with paths that select `bin/codex` or `bin/codex-app-server` inside the extracted package. The Windows release compression loop also skips prebuilt `.tar.zst` archives so it does not try to recompress them as ordinary files.

The other helper outputs stay on their existing per-binary artifacts for now.

## Test plan

- `python3 -m json.tool .github/dotslash-config.json > /dev/null`
- `bash -n .github/scripts/build-codex-package-archive.sh`
- `python3 -m py_compile scripts/codex_package/cli.py`
- `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/rust-release-windows.yml"); puts "ok"'`
- Ran a Python regex smoke test that checked every updated `codex` and `codex-app-server` platform entry against the `.tar.zst` archive names emitted by `.github/scripts/build-codex-package-archive.sh`.
- Ran `scripts/build_codex_package.py` with synthetic macOS entrypoint and `rg` binaries and repeated `--archive-output` values for `.tar.gz` and `.tar.zst`, verifying both archives were written.
2026-05-20 11:30:40 -07:00
Michael Bolin e78996daa6 npm: ship platform packages in Codex package layout
## Summary

The npm platform packages should stop carrying a bespoke native layout now that the release workflow builds canonical Codex package archives. Keeping npm on the same `bin/`, `codex-resources/`, and `codex-path/` structure lets the Rust package-layout detection behave consistently across standalone, npm, and future DotSlash installs.

This changes platform npm packages to stage the `codex-package` artifact for each target under `vendor/<target>`. The Node launcher now resolves `bin/codex` and prepends `codex-path`, while retaining legacy `vendor/<target>/codex` and `vendor/<target>/path` fallback support for local development and migration. The npm staging helper downloads `codex-package` archives instead of rebuilding the CLI payload from individual `codex`, `rg`, `bwrap`, and sandbox helper artifacts.

CI still needs to stage npm packages from historical rust-release workflow artifacts that predate package archives, so the staging scripts now expose an explicit `--allow-legacy-codex-package` fallback. That fallback synthesizes the canonical package layout from legacy per-binary artifacts and is wired only into the CI smoke path; release staging remains strict and continues to require real package archives.

For direct local use, `install_native_deps.py` now points its built-in default workflow at the same recent artifact run used by CI and automatically enables legacy package synthesis only when `--workflow-url` is omitted. Explicit workflow URLs remain strict unless callers opt in with `--allow-legacy-codex-package`.

## Test plan

- `python3 -m py_compile codex-cli/scripts/build_npm_package.py codex-cli/scripts/install_native_deps.py scripts/stage_npm_packages.py scripts/codex_package/cli.py`
- `node --check codex-cli/bin/codex.js`
- `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/rust-release.yml"); YAML.load_file(".github/workflows/ci.yml"); puts "ok"'`
- Staged a synthetic `codex-linux-x64` platform package from a canonical vendor tree and verified it copied only `bin/`, `codex-path/`, `codex-resources/`, and `codex-package.json`.
- Imported `install_native_deps.py` and extracted a synthetic `codex-package-x86_64-unknown-linux-musl.tar.gz` into `vendor/<target>`.
- Ran legacy-layout conversion smokes for Linux, Windows, and unsigned macOS artifact naming.
- Ran a synthetic `install_native_deps.py` default-workflow smoke that verifies legacy package synthesis is automatic only when `--workflow-url` is omitted.
- `NPM_CONFIG_CACHE="$tmp_dir/npm-cache" python3 ./scripts/stage_npm_packages.py --release-version 0.125.0 --workflow-url https://github.com/openai/codex/actions/runs/26131514935 --package codex --allow-legacy-codex-package --output-dir "$tmp_dir"`
- `node codex-cli/bin/codex.js --version`
2026-05-20 11:30:40 -07:00
Michael Bolin 683e2b0b1f merge commit for archive created by Sapling 2026-05-20 11:28:21 -07:00
Michael Bolin d73d9c0cbb npm: ship platform packages in Codex package layout
## Summary

The npm platform packages should stop carrying a bespoke native layout now that the release workflow builds canonical Codex package archives. Keeping npm on the same `bin/`, `codex-resources/`, and `codex-path/` structure lets the Rust package-layout detection behave consistently across standalone, npm, and future DotSlash installs.

This changes platform npm packages to stage the `codex-package` artifact for each target under `vendor/<target>`. The Node launcher now resolves `bin/codex` and prepends `codex-path`, while retaining legacy `vendor/<target>/codex` and `vendor/<target>/path` fallback support for local development and migration. The npm staging helper downloads `codex-package` archives instead of rebuilding the CLI payload from individual `codex`, `rg`, `bwrap`, and sandbox helper artifacts.

CI still needs to stage npm packages from historical rust-release workflow artifacts that predate package archives, so the staging scripts now expose an explicit `--allow-legacy-codex-package` fallback. That fallback synthesizes the canonical package layout from legacy per-binary artifacts and is wired only into the CI smoke path; release staging remains strict and continues to require real package archives.

For direct local use, `install_native_deps.py` now points its built-in default workflow at the same recent artifact run used by CI and automatically enables legacy package synthesis only when `--workflow-url` is omitted. Explicit workflow URLs remain strict unless callers opt in with `--allow-legacy-codex-package`.

## Test plan

- `python3 -m py_compile codex-cli/scripts/build_npm_package.py codex-cli/scripts/install_native_deps.py scripts/stage_npm_packages.py scripts/codex_package/cli.py`
- `node --check codex-cli/bin/codex.js`
- `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/rust-release.yml"); YAML.load_file(".github/workflows/ci.yml"); puts "ok"'`
- Staged a synthetic `codex-linux-x64` platform package from a canonical vendor tree and verified it copied only `bin/`, `codex-path/`, `codex-resources/`, and `codex-package.json`.
- Imported `install_native_deps.py` and extracted a synthetic `codex-package-x86_64-unknown-linux-musl.tar.gz` into `vendor/<target>`.
- Ran legacy-layout conversion smokes for Linux, Windows, and unsigned macOS artifact naming.
- Ran a synthetic `install_native_deps.py` default-workflow smoke that verifies legacy package synthesis is automatic only when `--workflow-url` is omitted.
- `NPM_CONFIG_CACHE="$tmp_dir/npm-cache" python3 ./scripts/stage_npm_packages.py --release-version 0.125.0 --workflow-url https://github.com/openai/codex/actions/runs/26131514935 --package codex --allow-legacy-codex-package --output-dir "$tmp_dir"`
- `node codex-cli/bin/codex.js --version`
2026-05-20 11:27:45 -07:00
Michael Bolin 2f880d13b4 Merge 35dcf0713c into sapling-pr-archive-bolinfest 2026-05-20 11:20:56 -07:00
Michael Bolin 35dcf0713c dotslash: publish Codex entrypoints from package archives
## Summary

DotSlash should resolve the same canonical package layout used by standalone installers and npm platform packages, but it should not take the size regression of downloading gzip-compressed package archives. Installers continue to use `.tar.gz` because that format is broadly available, while DotSlash can use zstd-compressed tar archives.

This updates the package archive release helper to emit both `*.tar.gz` and `*.tar.zst` package archives from the same package directory. The Codex CLI and `codex-app-server` DotSlash release config entries now match `codex-package-<target>.tar.zst` and `codex-app-server-package-<target>.tar.zst`, with paths that select `bin/codex` or `bin/codex-app-server` inside the extracted package. The Windows release compression loop also skips prebuilt `.tar.zst` archives so it does not try to recompress them as ordinary files.

The other helper outputs stay on their existing per-binary artifacts for now.

## Test plan

- `python3 -m json.tool .github/dotslash-config.json > /dev/null`
- `bash -n .github/scripts/build-codex-package-archive.sh`
- `python3 -m py_compile scripts/codex_package/cli.py`
- `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/rust-release-windows.yml"); puts "ok"'`
- Ran a Python regex smoke test that checked every updated `codex` and `codex-app-server` platform entry against the `.tar.zst` archive names emitted by `.github/scripts/build-codex-package-archive.sh`.
- Ran `scripts/build_codex_package.py` with synthetic macOS entrypoint and `rg` binaries and repeated `--archive-output` values for `.tar.gz` and `.tar.zst`, verifying both archives were written.
2026-05-20 11:20:42 -07:00
Michael Bolin ffd7dd9fde npm: ship platform packages in Codex package layout
## Summary

The npm platform packages should stop carrying a bespoke native layout now that the release workflow builds canonical Codex package archives. Keeping npm on the same `bin/`, `codex-resources/`, and `codex-path/` structure lets the Rust package-layout detection behave consistently across standalone, npm, and future DotSlash installs.

This changes platform npm packages to stage the `codex-package` artifact for each target under `vendor/<target>`. The Node launcher now resolves `bin/codex` and prepends `codex-path`, while retaining legacy `vendor/<target>/codex` and `vendor/<target>/path` fallback support for local development and migration. The npm staging helper downloads `codex-package` archives instead of rebuilding the CLI payload from individual `codex`, `rg`, `bwrap`, and sandbox helper artifacts.

CI still needs to stage npm packages from historical rust-release workflow artifacts that predate package archives, so the staging scripts now expose an explicit `--allow-legacy-codex-package` fallback. That fallback synthesizes the canonical package layout from legacy per-binary artifacts and is wired only into the CI smoke path; release staging remains strict and continues to require real package archives.

## Test plan

- `python3 -m py_compile codex-cli/scripts/build_npm_package.py codex-cli/scripts/install_native_deps.py scripts/stage_npm_packages.py scripts/codex_package/cli.py`
- `node --check codex-cli/bin/codex.js`
- `ruby -e 'require "yaml"; YAML.load_file(".github/workflows/rust-release.yml"); YAML.load_file(".github/workflows/ci.yml"); puts "ok"'`
- Staged a synthetic `codex-linux-x64` platform package from a canonical vendor tree and verified it copied only `bin/`, `codex-path/`, `codex-resources/`, and `codex-package.json`.
- Imported `install_native_deps.py` and extracted a synthetic `codex-package-x86_64-unknown-linux-musl.tar.gz` into `vendor/<target>`.
- Ran legacy-layout conversion smokes for Linux, Windows, and unsigned macOS artifact naming.
- `NPM_CONFIG_CACHE="$tmp_dir/npm-cache" python3 ./scripts/stage_npm_packages.py --release-version 0.125.0 --workflow-url https://github.com/openai/codex/actions/runs/26131514935 --package codex --allow-legacy-codex-package --output-dir "$tmp_dir"`
- `node codex-cli/bin/codex.js --version`
2026-05-20 11:20:42 -07:00
Michael Bolin 110b30d545 install: consume Codex package archives (#23636)
## Summary

Standalone installs should exercise the same canonical package archive
layout that release builds produce, rather than unpacking npm platform
packages and reconstructing a parallel install tree.

This updates `install.sh` and `install.ps1` to prefer
`codex-package-<target>.tar.gz` plus `codex-package_SHA256SUMS`
introduced in https://github.com/openai/codex/pull/23635, authenticate
the checksum manifest against GitHub release metadata, verify the
selected package archive against the authenticated manifest, and install
the package archive directly.

## Compatibility Notes

Package installs still leave a compatibility command at `current/codex`
for managed daemon flows, while visible command shims point at
`bin/codex` inside the package layout.

Recent releases that predate package archives still publish per-platform
npm artifacts, so both installers keep a legacy platform npm fallback
for those versions and verify those archives against release metadata
directly.

Releases old enough to publish only the single root
`codex-npm-<version>.tgz` archive are intentionally out of scope. The
installers fail clearly when neither package archives nor per-platform
npm archives are present.

On Windows, the runtime helper lookups now recognize package-layout
installs where `codex.exe` runs from `bin/`, so
`codex-command-runner.exe` and `codex-windows-sandbox-setup.exe` resolve
from the top-level `codex-resources/` directory. The direct-sibling and
older sibling-resource fallbacks are preserved.

## Test plan

- `sh -n scripts/install/install.sh`
- `bash -n scripts/install/install.sh`
- `pwsh -NoProfile -Command '$tokens=$null; $errors=$null; $null =
[System.Management.Automation.Language.Parser]::ParseFile("scripts/install/install.ps1",
[ref]$tokens, [ref]$errors); if ($errors.Count) { $errors | Format-List
*; exit 1 }'`
- `HOME="$home_dir" CODEX_HOME="$tmp_dir/codex-home"
CODEX_INSTALL_DIR="$bin_dir" PATH="$bin_dir:$PATH" sh
scripts/install/install.sh --release 0.125.0`
- Verified the 0.125.0 isolated install leaves the visible command
pointed at `current/codex` and includes the legacy `codex-resources/rg`
payload.
- `cargo test -p codex-windows-sandbox`
- `just fix -p codex-windows-sandbox`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23636).
* #23638
* #23637
* __->__ #23636
2026-05-20 11:20:11 -07:00
jif-oai c5bd131567 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`
2026-05-20 20:14:41 +02:00
Eric Traut edc48e4612 Sync TUI thread settings through app server (#23507)
Builds on #23502.

## Why

#23502 adds the app-server `thread/settings/update` API and matching
`thread/settings/updated` notification. The TUI already lets users
change thread-scoped settings such as model, reasoning effort, service
tier, approvals, permissions, personality, and collaboration mode, but
those updates need to flow through the app server so embedded and
connected clients observe the same thread state.

This is a rework (simplification) of PR
https://github.com/openai/codex/pull/22510. It has the same
functionality, but the underlying `thread/settings/update` api is now
simpler in that it no longer returns the effective settings as a
response. Now, clients receive the effective settings only through the
`thread/settings/updated` notification.

## What Changed

This updates the TUI to send `thread/settings/update` whenever those
thread-scoped settings change and to treat the RPC response as the
authoritative acknowledgement. It also routes `thread/settings/updated`
notifications back into cached session state and the visible chat widget
so active and inactive threads stay in sync after app-server-originated
changes.

The implementation is kept to the TUI layer: settings conversion and
merge logic live under `codex-rs/tui/src/app/thread_settings.rs`, with
dispatch/routing hooks in the existing app and chat widget paths.

## Verification

I manually tested using `codex app-server --listen unix://` and then
launching two copies of the TUI that use the same local app server. I
then resumed the same thread on both and verified that changes like plan
mode, fast mode, model, reasoning effort, etc. are reflected "live" in
the second client when modified in the first and vice versa.
2026-05-20 11:05:14 -07:00
Eric Traut 771a4e74ac Add thread/settings/update app-server API (#23502)
## Why

App-server clients need a way to update a thread's next-turn settings
without starting a turn, adding transcript content, or waiting for turn
lifecycle events. This gives settings UI a direct path for durable
thread settings while clients observe the eventual effective state
through a notification.

This is a simplified rework of PR
https://github.com/openai/codex/pull/22509. In particular, it changes
the `thread/settings/update` api to return immediately rather than
waiting and returning the effective (updated) thread settings. This
makes the new api consistent with `turn/start` and greatly reduces the
complexity of the implementation relative to the earlier attempt.

## What Changed

- Adds experimental `thread/settings/update` with partial-update request
fields and an empty acknowledgment response.
- Adds experimental `thread/settings/updated`, carrying full effective
`ThreadSettings` and scoped by `threadId` to subscribed clients for the
affected thread.
- Shares durable settings validation with `turn/start`, including
`sandboxPolicy` plus `permissions` rejection and `serviceTier: null`
clearing.
- Emits the same settings notification when `turn/start` overrides
change the stored effective thread settings.
- Regenerates app-server protocol schema fixtures and updates
`app-server/README.md`.
2026-05-20 11:03:20 -07:00
Michael Bolin cbee57767e merge commit for archive created by Sapling 2026-05-20 11:00:44 -07:00
Michael Bolin 2917f37335 install: consume Codex package archives
## Summary

Standalone installs should exercise the same canonical package archive layout that release builds produce, rather than unpacking npm platform packages and reconstructing a parallel install tree.

This updates `install.sh` and `install.ps1` to prefer `codex-package-<target>.tar.gz` plus `codex-package_SHA256SUMS`, authenticate the checksum manifest against GitHub release metadata, verify the selected package archive against the authenticated manifest, and install the package archive directly. Package installs now also leave a compatibility command at `current/codex` for managed daemon flows while visible command shims point at `bin/codex`.

Recent releases that predate package archives still publish per-platform npm artifacts, so both installers keep a legacy platform npm fallback for those versions and verify those archives against release metadata directly. Releases old enough to publish only the single root `codex-npm-<version>.tgz` archive are intentionally out of scope; the installers fail clearly when neither package archives nor per-platform npm archives are present.

On Windows, the runtime helper lookups now also recognize the package layout when `codex.exe` runs from `bin/`, so `codex-command-runner.exe` and `codex-windows-sandbox-setup.exe` resolve from the top-level `codex-resources/` directory while preserving the direct-sibling and older sibling-resource fallbacks.

## Test plan

- `sh -n scripts/install/install.sh`
- `bash -n scripts/install/install.sh`
- `pwsh -NoProfile -Command '$tokens=$null; $errors=$null; $null = [System.Management.Automation.Language.Parser]::ParseFile("scripts/install/install.ps1", [ref]$tokens, [ref]$errors); if ($errors.Count) { $errors | Format-List *; exit 1 }'`
- `HOME="$home_dir" CODEX_HOME="$tmp_dir/codex-home" CODEX_INSTALL_DIR="$bin_dir" PATH="$bin_dir:$PATH" sh scripts/install/install.sh --release 0.125.0`
- Verified the 0.125.0 isolated install leaves the visible command pointed at `current/codex` and includes the legacy `codex-resources/rg` payload.
- `cargo test -p codex-windows-sandbox`
- `just fix -p codex-windows-sandbox`
2026-05-20 10:59:48 -07:00