Files
codex/installer/README.md
Michael Bolin c1ff22bc6c feat: This PR adds a first-party curl-based installer that downloads only the binaries needed for the current platform and wires it into Codex’s existing update UX.
It introduces a dedicated `installer/` folder for non-Rust install/update assets, a `CODEX_HOME`-aware on-disk layout, and a wrapper that makes helper CLIs available to Codex without globally polluting the user’s shell.

## Why

Today the recommended install path is `npm i -g @openai/codex`, but the npm package bundles native binaries for all platforms (and `rg`), leading to very large installs (hundreds of MB unpacked) even though a single platform binary is much smaller.

Homebrew avoids this on macOS by downloading only the matching artifact. This PR brings that same property to a cross-platform one-liner:

```sh
curl -fsSL https://raw.githubusercontent.com/openai/codex/main/installer/install.sh | bash
```

Key goals:

- Download only the user’s platform artifacts.
- Keep curl-managed installs isolated under `CODEX_HOME`.
- Preserve compatibility with npm/brew installs (shadowing is fine, breaking is not).
- Provide a clean place to add helper CLIs that should be available when Codex runs.

## How It Works

### Install root and layout

All curl-managed artifacts live under `CODEX_HOME` (default: `~/.codex`).

The layout is:

- `CODEX_HOME/bin/`
- `CODEX_HOME/versions/<version>/bin/`
- `CODEX_HOME/versions/current` (symlink)
- `CODEX_HOME/tools/bin/`

This design supports atomic version switches and helper CLIs:

- The user’s global `PATH` only needs `CODEX_HOME/bin`.
- The runtime `PATH` is extended inside the wrapper to include helper CLIs.

See `installer/README.md:1`.

### Installer scripts

#### `installer/install.sh`

`installer/install.sh:1` is the public entrypoint:

- Requires Bash explicitly (we use Bash features like `mapfile`).
- Loads `installer/lib.sh` locally when run from a checkout, or downloads it when piped from curl.
- Detects `arch`/`os`, resolves the version (via `CODEX_VERSION` or GitHub Releases), downloads the correct tarball, installs it, activates it, and updates the user’s rc file.

#### `installer/lib.sh`

`installer/lib.sh:10` centralizes the mechanics:

- Resolves `CODEX_HOME` with a fallback to `~/.codex`.
- Detects OS/arch and builds release URLs.
- Idempotently updates the user rc file via a marker block that respects non-default `CODEX_HOME` values: `installer/lib.sh:106`.
- Installs a wrapper at `CODEX_HOME/bin/codex` that:
  - Sets `CODEX_MANAGED_BY_CURL=1`.
  - Extends `PATH` at runtime to include:
    - `CODEX_HOME/bin`
    - `CODEX_HOME/tools/bin`
    - `CODEX_HOME/versions/current/bin`
  - Execs the active versioned binary: `installer/lib.sh:154`.
- Installs the tarball into a versioned `bin/` directory and preserves any additional CLIs present in the tarball (not just `codex`): `installer/lib.sh:181`.
- Keeps the last two installed versions and avoids deleting the `current` symlink: `installer/lib.sh:239`.

#### `installer/update.sh`

`installer/update.sh:1` mirrors the installer flow but always targets the latest release.

### Update UX integration in the CLI

Codex’s update prompt already knows how to run a package-manager-specific update command after the TUI exits.

This PR adds a curl-managed update action in `codex-rs/tui/src/update_action.rs:3`:

- Adds `UpdateAction::CurlInstallerUpdate`.
- Detects curl-managed installs via `CODEX_MANAGED_BY_CURL` (set by the wrapper): `codex-rs/tui/src/update_action.rs:40`.
- Uses the curl updater one-liner for the update command: `codex-rs/tui/src/update_action.rs:21`.

This keeps update behavior consistent with npm/brew while avoiding fragile path heuristics.

## Docs updates

- The curl installer is now the first recommended install path in `README.md:1` and `README.md:18`.
- `docs/install.md:11` adds a curl install section and points to `installer/README.md` for the detailed mechanics.

## Compatibility and safety notes

- This does not modify npm or Homebrew installs.
- The rc-file change only adds `CODEX_HOME/bin` to `PATH`.
- Additional helper CLIs are available to Codex via the wrapper’s runtime `PATH`, rather than being forced into the user’s global shell.
- The installer honors `CODEX_HOME` everywhere, falling back to `~/.codex`.

## Testing

Commands run:

```sh
cd codex-rs
just fmt
cargo test -p codex-tui
```

Notes:

- In this environment, `cargo test -p codex-tui` required running outside the sandbox due to a macOS `SystemConfiguration` panic; it passed once run with escalated permissions.
- No new VS Code diagnostics were reported.

## Follow-ups (explicitly not in this PR)

- Ensure the release tarballs include any helper CLIs we expect to be available at runtime (for example, Windows sandbox helpers).
- Add an explicit `codex self-update` command that delegates to `installer/update.sh`.
- Decide how we want to manage third-party tools like `rg` under `CODEX_HOME/tools/` and whether the CLI should probe a managed fallback path.
2026-01-25 21:09:29 -08:00

3.2 KiB

Codex Curl Installer

This folder contains the non-Rust assets for the curl-based Codex installer and update flow. Rust code lives under codex-rs/.

Goals

  • Download only the binaries needed for the current platform.
  • Keep the install isolated under CODEX_HOME (default: ~/.codex).
  • Avoid breaking npm/brew installs; shadowing is acceptable.
  • Support additional helper CLIs without globally polluting PATH.

Install Root (CODEX_HOME)

The installer treats CODEX_HOME as the install root:

  • If CODEX_HOME is set, it is used as-is.
  • Otherwise, the default is ~/.codex.

All curl-managed artifacts should live under this root.

On-Disk Layout

The layout is designed to support multiple versions, helper binaries, and atomic updates:

  • CODEX_HOME/bin/
  • CODEX_HOME/versions/<version>/
  • CODEX_HOME/versions/<version>/bin/
  • CODEX_HOME/tools/<tool>/<version>/
  • CODEX_HOME/tools/bin/

Key conventions:

  • The user-facing entrypoint is CODEX_HOME/bin/codex.
  • CODEX_HOME/versions/current is a symlink to the active version directory.
  • Helper CLIs that ship with Codex (for example, Windows sandbox helpers) live in CODEX_HOME/versions/<version>/bin/.
  • Third-party tools we fetch (for example, rg) live under CODEX_HOME/tools/..., with optional shims in CODEX_HOME/tools/bin/.

PATH Strategy

We separate the user's global PATH from Codex's runtime PATH:

  1. The installer ensures CODEX_HOME/bin is on the user's PATH.
  2. The codex wrapper augments PATH at runtime to include:
    • CODEX_HOME/bin
    • CODEX_HOME/tools/bin
    • CODEX_HOME/versions/current/bin

This keeps helper CLIs available to Codex without exposing them as global commands in every shell session.

Versioning And Atomic Updates

Curl-managed installs should be versioned:

  1. Download into a versioned directory:
    • CODEX_HOME/versions/<version>/
  2. Link CODEX_HOME/versions/current to the new version atomically.
  3. Keep a small number of prior versions for rollback.

Because the wrapper resolves through versions/current, repointing the symlink updates the effective version without editing shell rc files again.

Helper CLI Placement

Any additional CLIs that Codex needs at runtime should follow these rules:

  • Bundled CLIs that are version-coupled to Codex:
    • Place in CODEX_HOME/versions/<version>/bin/
  • Third-party tools that may be shared across versions:
    • Place in CODEX_HOME/tools/<tool>/<version>/
    • Optionally add a stable shim in CODEX_HOME/tools/bin/

The wrapper then makes them available during execution.

Ripgrep (rg)

The preferred approach is:

  • Use a system rg when available.
  • Otherwise, allow curl-managed installs to place rg under CODEX_HOME/tools/rg/<version>/ with a shim in CODEX_HOME/tools/bin/rg.

Codex CLI can optionally honor an explicit CODEX_RG_PATH to point directly to a managed rg.

Scripts

Planned/expected scripts in this folder:

  • installer/install.sh
  • installer/lib.sh
  • installer/update.sh

The public one-liner should look like:

curl -fsSL https://raw.githubusercontent.com/openai/codex/main/installer/install.sh | bash

All scripts must honor CODEX_HOME with a fallback to ~/.codex.