13 Commits

Author SHA1 Message Date
Adam Perry @ OpenAI
45528c5132 Allow overriding Codex package versions (#39298)
## What changed

- Add `--package-version` to set the version written to `codex-package.json`, while retaining the workspace package version as the default.
- Reject values that are not runtime-compatible semantic versions, including overflowing numeric components and numeric prerelease identifiers with leading zeroes.
- Document the new option.

## Testing

- Add unit coverage for valid release, prerelease, and build versions, plus malformed and out-of-range values.

GitOrigin-RevId: cee996a6721e3fac9bd88f0bc0302a7ec7d2b2fb
2026-08-18 22:16:48 +00:00
Channing Conger
a453588416 Sign bundled macOS helper binaries (#35264)
## Why

The macOS release workflow fetched `rg` and zsh while assembling package
archives, after the signing stage. This left the bundled helper executables
outside the workflow's signing and notarization checks.

## What changed

- Fetch, sign, notarize, and upload the pinned macOS `rg` and zsh binaries with
  the other release artifacts.
- Build package archives from those signed helpers via `--rg-bin` and the new
  `--zsh-bin` override.
- Verify the helpers' architecture, signatures, and absence of entitlements in
  the final package.

## Testing

- Cover the prebuilt zsh override and verify that package assembly preserves
  the supplied helper binaries.

GitOrigin-RevId: a3865c04fa2f0f4df32e627ee7202bc87bdc3241
2026-07-24 23:44:55 +00:00
Channing Conger
3f61570044 [codex] bundle code mode host in release packages (#30202)
## Summary

- build, strip, sign, and publish `codex-code-mode-host` with the
primary Codex release binaries on Linux, macOS, and Windows
- place the host beside `codex[.exe]` in canonical package archives,
macOS DMGs, and the legacy Linux bundle so the runtime's sibling lookup
succeeds
- preserve and validate the host through standalone installers and
Python runtime wheel staging
- add package-builder coverage for source selection and the resulting
package layout

## Why

The process-owned code-mode client launches `codex-code-mode-host` as a
sibling of the running Codex executable. Release artifacts currently
build and bundle `codex` without that host, so code mode cannot start
from installed packages.
2026-07-06 16:58:05 -07:00
Michael Bolin
e23e7cbe46 release: consume standalone zsh artifacts (#30116)
## Why

Once #30114 publishes zsh independently, regular Rust releases should
reuse that protected, versioned artifact set instead of rebuilding
identical zsh binaries for every Codex version. Keeping the zsh release
tag explicit in the workflow also makes future artifact upgrades
deliberate and easy to review.

This PR assumes the first standalone artifact release will be published
as `codex-zsh-v0.1.0` before this change lands.

## What changed

- Added `CODEX_ZSH_RELEASE_TAG` near the top of
`.github/workflows/rust-release.yml`, initially pinned to
`codex-zsh-v0.1.0`.
- Download the standalone release’s generated `codex-zsh` DotSlash
manifest before assembling Linux and macOS Codex packages.
- Added a `--zsh-manifest` package-builder override so release packaging
fetches the matching target archive and verifies the size and SHA-256
digest recorded in that manifest.
- Removed the reusable zsh build job from regular Rust releases.
- Stopped copying zsh archives into each Rust release and stopped
regenerating a zsh DotSlash manifest there.

Windows packaging remains unchanged because the patched zsh resource is
only shipped for supported Unix targets.

## Testing

- Added package-helper coverage that supplies a standalone manifest
override and verifies the extracted zsh bytes.
- Ran the `scripts/codex_package` unit test suite.
- Validated `.github/scripts/build-codex-package-archive.sh` with `bash
-n`.
2026-06-25 14:05:49 -07:00
Adam Perry @ OpenAI
281b416c44 Check root Python script formatting in CI (#25165)
## Why

Python files under `scripts/` were not covered by the repository
formatting recipe or the CI formatting job, so formatting drift could
merge unnoticed.

## What

- Add a dedicated `scripts/pyproject.toml` and `scripts/uv.lock` so
root-script formatting uses a locked Ruff version.
- Extend `just fmt` to format root Python scripts and add
`fmt-scripts-check` for CI.
- Run `just fmt-scripts-check` from `.github/workflows/ci.yml`,
installing `uv` through SHA-pinned `astral-sh/setup-uv` while retaining
the `uv` `0.11.3` pin.
- Apply Ruff formatting to the root Python scripts, including
`scripts/just-shell.py`, and extend
`sdk/python/tests/test_artifact_workflow_and_binaries.py` to cover the
root formatting recipe.
- Update `AGENTS.md` so agents run `just fmt` after code changes
anywhere in the repository.

## Validation

- Extended the existing Python SDK workflow test to assert that `just
fmt` includes root Python scripts.
2026-06-01 18:50:23 +00:00
Michael Bolin
c7bcb90f9b 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
2026-05-22 17:54:07 -07:00
Michael Bolin
c07f66c9ec packaging: move rg manifest out of npm bin (#23833)
## Why

Installing `@openai/codex` currently places a Dotslash `rg` manifest at
`node_modules/@openai/codex/bin/rg`, even though the native optional
dependency already ships the actual helper under
`vendor/<target>/codex-path/rg`. The launcher prepends that `codex-path`
directory, so the top-level `bin/rg` file is redundant in the npm
install.

The remaining direct consumers of the manifest are package-building
paths: `scripts/codex_package/ripgrep.py` and
`codex-cli/scripts/install_native_deps.py`. Keeping the manifest under
`codex-cli/bin` makes it look like a shipped npm binary, so this moves
it next to the package-builder code that owns it. The checked-in
`@openai/codex` package metadata should likewise describe only the meta
package payload; generated platform packages continue to publish
`vendor`.

## What Changed

- Moved the Dotslash ripgrep manifest from `codex-cli/bin/rg` to
`scripts/codex_package/rg`.
- Updated the package builder, npm native-artifact hydrator, README, and
CLI help text to reference the new manifest location.
- Stopped `codex-cli/scripts/build_npm_package.py` from copying `rg`
into the `@openai/codex` meta package.
- Narrowed the checked-in meta package `files` whitelist to
`bin/codex.js`.

## Verification

- `python3 -m unittest discover -s scripts/codex_package -p "test_*.py"`
- `python3 -m unittest discover -s codex-cli/scripts -p "test_*.py"`
- `python3 -m py_compile codex-cli/scripts/build_npm_package.py
codex-cli/scripts/install_native_deps.py
scripts/codex_package/ripgrep.py scripts/codex_package/cli.py
scripts/stage_npm_packages.py`
- `codex-cli/scripts/build_npm_package.py --package codex --version
0.0.0-test --pack-output <tmp>/codex-meta-no-vendor.tgz`
- `tar -tf <tmp>/codex-meta-no-vendor.tgz` showed only
`package/bin/codex.js`, `package/package.json`, and `package/README.md`.
- Direct staging check showed `codex` uses `files: ["bin/codex.js"]`
while `codex-darwin-arm64` still uses `files: ["vendor"]`.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23833).
* #23836
* __->__ #23833
2026-05-21 15:48:42 +00:00
Michael Bolin
80c4a978f8 release: package prebuilt resource binaries (#23759)
## Why

Release packaging should be a staging step once release binaries have
already been built and signed. The Windows release job was downloading
and signing `codex-command-runner.exe` and
`codex-windows-sandbox-setup.exe`, but `scripts/build_codex_package.py`
still rebuilt those helpers while creating the package archives.

That makes the package step slower and, more importantly, risks putting
helper binaries in the archive that were produced after the signing
step. Linux had the same shape for package resources: `bwrap` could be
rebuilt by the package builder instead of being passed in as a prebuilt
release artifact.

This builds on #23752, which fixes `.tar.zst` creation when Windows
runners rely on the repository DotSlash `zstd` wrapper.

## What changed

- Add explicit prebuilt resource inputs to the Codex package builder:
  - `--bwrap-bin`
  - `--codex-command-runner-bin`
  - `--codex-windows-sandbox-setup-bin`
- Make `.github/scripts/build-codex-package-archive.sh` pass resource
binaries from the release output directory when they are already
present.
- Build Linux `bwrap` for app-server release jobs too, so app-server
package creation does not invoke Cargo just to supply the package
resource.
- Keep macOS package creation as a no-Cargo path when `--entrypoint-bin`
is provided, since macOS packages have no resource binaries.
- Add unit coverage showing prebuilt macOS, Linux, and Windows package
inputs result in no source-built binaries.

## Verification

- `python3 -m unittest discover -s scripts/codex_package -p 'test_*.py'`
- `python3 -m py_compile scripts/codex_package/*.py`
- `bash -n .github/scripts/build-codex-package-archive.sh`
- Dry-ran Linux and Windows package builds with fake prebuilt resources
and a nonexistent Cargo path to verify the package builder did not
invoke Cargo.


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23759).
* #23760
* __->__ #23759
2026-05-20 14:51: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
Michael Bolin
343a74076f build: package prebuilt Codex entrypoints (#23586)
## Why

The package builder should describe the binaries it is actually
packaging, not require callers to restate release metadata out of band.
A caller-provided `--version` flag can drift from the workspace version,
but running the target entrypoint to discover its version breaks
cross-target packages when the produced binary cannot execute on the
build host.

This PR keeps package metadata tied to the repository source of truth by
reading `[workspace.package].version` from `codex-rs/Cargo.toml`. It
also prepares the package layout for `codex-app-server` packages: the
same package structure can now represent either the CLI entrypoint or
the app-server entrypoint while keeping shared sidecars such as `rg`,
`bwrap`, and Windows sandbox helpers in the existing package
directories.

## What changed

- Removes the `--version` CLI flag from
`scripts/build_codex_package.py`.
- Adds Cargo.toml version discovery for `codex-package.json.version` via
`codex-rs/Cargo.toml`.
- Adds `--entrypoint-bin` so callers can package a prebuilt entrypoint
instead of rebuilding it with Cargo.
- Makes `--variant` an explicit choice between `codex` and
`codex-app-server`, and uses it to select the cargo binary and packaged
`bin/` entrypoint name.
- Updates `scripts/codex_package/README.md` to document variants,
prebuilt entrypoints, and Cargo.toml version detection.

## Verification

- Compiled `scripts/build_codex_package.py` and
`scripts/codex_package/*.py` with `PYTHONDONTWRITEBYTECODE=1`.
- Ran `scripts/build_codex_package.py --help` and verified `--version`
is gone while `--variant` and `--entrypoint-bin` are present.
- Verified the package builder reads version `0.0.0` from
`codex-rs/Cargo.toml`.
- Built a fake cross-target `codex-app-server` package using a
non-executable `--entrypoint-bin`; verified metadata records version
`0.0.0`, variant `codex-app-server`, and `bin/codex-app-server` as the
entrypoint.
2026-05-19 22:10:03 -07:00
Michael Bolin
79f044ed34 build: default Codex package target and output (#23541)
## Why

The package builder should be easy to run during local iteration.
Requiring callers to provide both a target triple and an output
directory every time makes the common host-package case more awkward
than necessary.

This PR keeps explicit overrides available, but makes the default
invocation useful: build for the current host platform and place the
package in a fresh temporary directory. Because a temp output path is
otherwise easy to lose, the builder continues to print the final package
directory path when it completes.

## What changed

- Makes `--target` optional and maps the host OS/architecture to
supported Codex package target triples.
- Uses GNU Linux target triples for Linux host defaults, while keeping
the musl targets available for release jobs that pass `--target`
explicitly.
- Makes `--package-dir` optional and creates a new `codex-package-*`
temp directory when omitted.
- Documents the new defaults in `scripts/codex_package/README.md`.

## Verification

- Compiled `scripts/build_codex_package.py` and
`scripts/codex_package/*.py` with `PYTHONDONTWRITEBYTECODE=1`.
- Ran `scripts/build_codex_package.py --help` from outside the repo.
- Verified Linux host detection maps `x86_64` and `aarch64` to GNU
target triples.
- Ran a fake-Cargo package build while omitting both `--target` and
`--package-dir`; verified the generated metadata target, expected
package files, and printed temp package path.
- Ran a fake-Cargo package build for `x86_64-unknown-linux-gnu` and
verified `codex`, `bwrap`, and `rg` are assembled into the package.
2026-05-20 00:05:43 +00:00
Michael Bolin
59f262a2b4 build: fetch rg for Codex packages (#23526)
## Why

The Codex package builder should produce a complete package without
requiring callers to pre-populate `rg` under `codex-cli/vendor` or have
`dotslash` installed on `PATH`. The repo already tracks the
authoritative DotSlash manifest in `codex-cli/bin/rg`, so the builder
can read that metadata directly and fetch the correct ripgrep archive
for the target it is packaging.

## What changed

- Added `scripts/codex_package/ripgrep.py` to parse `codex-cli/bin/rg`
after stripping the shebang, select the target platform entry, download
the configured artifact, and verify the recorded size and SHA-256
digest.
- Added a cache under `$TMPDIR/codex-package/<target>-rg` so verified
archives can be reused without fetching again.
- Extracted `rg`/`rg.exe` from `tar.gz` and `zip` artifacts into the
package-builder cache, then copied that into `codex-path` through the
existing package layout flow.
- Kept `--rg-bin` as an explicit local override for offline tests and
unusual local workflows.
- Documented the default `rg` fetch/cache behavior in
`scripts/codex_package/README.md`.

## Verification

- Ran wrapper/module syntax compilation.
- Ran `scripts/build_codex_package.py --help` from `/private/tmp`.
- Ran a local manifest fetch test covering shebang-stripped manifest
parsing, `tar.gz` extraction, `zip` extraction, size/SHA-256
verification, and cache reuse after deleting the original source
archives.
- Ran fake-cargo package/archive builds for macOS, Linux, and Windows
target layouts with `--rg-bin`, including an assertion that generated
tar archives contain no duplicate member names.




---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23526).
* #23541
* __->__ #23526
2026-05-19 15:52:17 -07:00
Michael Bolin
7f4d7ae3a4 build: add Codex package builder (#23513)
## Why

Codex CLI packaging is currently split across npm staging, standalone
installers, and release bundle creation, which makes it hard to define
and validate a single valid package directory. This adds the first
standalone package builder so later release paths can converge on the
same canonical layout.

## What changed

- Added `scripts/build_codex_package.py` as the stable executable
wrapper around `scripts/codex_package`.
- Added modules for CLI parsing, target metadata, grouped cargo builds,
package layout validation, and archive writing.
- The builder creates a package directory with `codex-package.json`,
`bin/`, `codex-resources/`, and `codex-path`, and can serialize it as
`.tar.gz`, `.tar.zst`, or `.zip`.
- Source-built artifacts are built by one grouped `cargo build`: `codex`
for all targets, `bwrap` for Linux, and the Windows sandbox helpers for
Windows. `rg` remains an input because it is vendored from upstream
rather than built from this repo.
- Added `scripts/codex_package/README.md` to document the package
layout, source-built artifacts, and cargo profile behavior.

## Verification

- Ran wrapper/module syntax compilation.
- Ran `scripts/build_codex_package.py --help` from `/private/tmp`.
- Ran fake-cargo package/archive builds for macOS, Linux, and Windows
target layouts, including an assertion that generated tar archives
contain no duplicate member names.


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23513).
* #23526
* __->__ #23513
2026-05-19 19:54:03 +00:00