## 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.
Codex package builder
This package contains the implementation behind scripts/build_codex_package.py.
The top-level script is the stable executable entry point; these modules keep the
package-building logic split by responsibility.
The builder creates a canonical Codex package directory:
.
├── codex-package.json
├── bin
│ └── <entrypoint>[.exe]
├── codex-resources
│ ├── bwrap # Linux only
│ ├── codex-command-runner.exe # Windows only
│ └── codex-windows-sandbox-setup.exe # Windows only
└── codex-path
└── rg[.exe]
The package directory is the primary artifact. Archive formats such as
.tar.gz, .tar.zst, and .zip are serializations of that directory.
If --target is omitted, the builder uses the release target for the current
host platform. On Linux, that default is a musl target to match Codex release
artifacts; pass a GNU Linux target explicitly for native glibc local builds. If
--package-dir is omitted, the builder creates a new temporary directory and
prints its path after the package is built.
The --variant flag selects the package entrypoint. Supported variants are
codex and codex-app-server. The version field in codex-package.json is
read from [workspace.package].version in codex-rs/Cargo.toml.
Source-built artifacts
Artifacts built from this repository are always built by the package builder in
one grouped cargo build command per package when they are needed:
- all targets: the selected entrypoint, unless
--entrypoint-binis provided - Linux targets:
bwrap - Windows targets:
codex-command-runnerandcodex-windows-sandbox-setup
The default cargo profile is dev-small because local iteration should favor
fast, small builds. Release jobs should pass --cargo-profile release and an
explicit target. Release jobs that already built and signed/notarized the
entrypoint should pass --entrypoint-bin so the package contains that exact
binary instead of rebuilding it.
rg is not built from this repository, so the builder fetches it from the
DotSlash manifest at codex-cli/bin/rg. Downloaded archives are cached under
$TMPDIR/codex-package/<target>-rg and are reused only after the recorded size
and SHA-256 digest have been verified. Pass --rg-bin to use a local ripgrep
executable instead.