mirror of
https://github.com/openai/codex.git
synced 2026-02-25 10:13:49 +00:00
Compare commits
3 Commits
pr12756
...
codex/dire
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8ac3d922c | ||
|
|
a594cc229a | ||
|
|
60d533f5ec |
5
.github/workflows/rust-release.yml
vendored
5
.github/workflows/rust-release.yml
vendored
@@ -488,6 +488,11 @@ jobs:
|
||||
--package codex-responses-api-proxy \
|
||||
--package codex-sdk
|
||||
|
||||
- name: Stage installer scripts
|
||||
run: |
|
||||
cp scripts/install/install.sh dist/install.sh
|
||||
cp scripts/install/install.ps1 dist/install.ps1
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
|
||||
16
README.md
16
README.md
@@ -1,4 +1,4 @@
|
||||
<p align="center"><code>npm i -g @openai/codex</code><br />or <code>brew install --cask codex</code></p>
|
||||
<p align="center"><code>curl -fsSL https://chatgpt.com/codex/install.sh | sh</code><br /><code>powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://chatgpt.com/codex/install.ps1 | iex"</code><br />or <code>npm i -g @openai/codex</code><br />or <code>brew install --cask codex</code></p>
|
||||
<p align="center"><strong>Codex CLI</strong> is a coding agent from OpenAI that runs locally on your computer.
|
||||
<p align="center">
|
||||
<img src="https://github.com/openai/codex/blob/main/.github/codex-cli-splash.png" alt="Codex CLI splash" width="80%" />
|
||||
@@ -14,7 +14,19 @@ If you want Codex in your code editor (VS Code, Cursor, Windsurf), <a href="http
|
||||
|
||||
### Installing and running Codex CLI
|
||||
|
||||
Install globally with your preferred package manager:
|
||||
Install the latest Codex release directly:
|
||||
|
||||
```shell
|
||||
# Install on macOS or Linux
|
||||
curl -fsSL https://chatgpt.com/codex/install.sh | sh
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Install on Windows (PowerShell)
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://chatgpt.com/codex/install.ps1 | iex"
|
||||
```
|
||||
|
||||
You can also install with your preferred package manager:
|
||||
|
||||
```shell
|
||||
# Install using npm
|
||||
|
||||
@@ -4,10 +4,25 @@
|
||||
|
||||
| Requirement | Details |
|
||||
| --------------------------- | --------------------------------------------------------------- |
|
||||
| Operating systems | macOS 12+, Ubuntu 20.04+/Debian 10+, or Windows 11 **via WSL2** |
|
||||
| Operating systems | macOS 12+, Ubuntu 20.04+/Debian 10+, or Windows 11 |
|
||||
| Git (optional, recommended) | 2.23+ for built-in PR helpers |
|
||||
| RAM | 4-GB minimum (8-GB recommended) |
|
||||
|
||||
### Install the latest release
|
||||
|
||||
```bash
|
||||
# macOS or Linux
|
||||
curl -fsSL https://chatgpt.com/codex/install.sh | sh
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Windows (PowerShell)
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://chatgpt.com/codex/install.ps1 | iex"
|
||||
```
|
||||
|
||||
The direct installers download the latest matching GitHub Release package for your platform and
|
||||
place both `codex` and `rg` in a user-local directory.
|
||||
|
||||
### DotSlash
|
||||
|
||||
The GitHub Release also contains a [DotSlash](https://dotslash-cli.com/) file for the Codex CLI named `codex`. Using a DotSlash file makes it possible to make a lightweight commit to source control to ensure all contributors use the same version of an executable, regardless of what platform they use for development.
|
||||
|
||||
192
scripts/install/install.ps1
Normal file
192
scripts/install/install.ps1
Normal file
@@ -0,0 +1,192 @@
|
||||
param(
|
||||
[Parameter(Position=0)]
|
||||
[string]$Version = "latest"
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
function Write-Step {
|
||||
param(
|
||||
[string]$Message
|
||||
)
|
||||
|
||||
Write-Host "==> $Message"
|
||||
}
|
||||
|
||||
function Normalize-Version {
|
||||
param(
|
||||
[string]$RawVersion
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($RawVersion) -or $RawVersion -eq "latest") {
|
||||
return "latest"
|
||||
}
|
||||
|
||||
if ($RawVersion.StartsWith("rust-v")) {
|
||||
return $RawVersion.Substring(6)
|
||||
}
|
||||
|
||||
if ($RawVersion.StartsWith("v")) {
|
||||
return $RawVersion.Substring(1)
|
||||
}
|
||||
|
||||
return $RawVersion
|
||||
}
|
||||
|
||||
function Get-ReleaseUrl {
|
||||
param(
|
||||
[string]$AssetName,
|
||||
[string]$ResolvedVersion
|
||||
)
|
||||
|
||||
return "https://github.com/openai/codex/releases/download/rust-v$ResolvedVersion/$AssetName"
|
||||
}
|
||||
|
||||
function Path-Contains {
|
||||
param(
|
||||
[string]$PathValue,
|
||||
[string]$Entry
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($PathValue)) {
|
||||
return $false
|
||||
}
|
||||
|
||||
$needle = $Entry.TrimEnd("\")
|
||||
foreach ($segment in $PathValue.Split(";", [System.StringSplitOptions]::RemoveEmptyEntries)) {
|
||||
if ($segment.TrimEnd("\") -ieq $needle) {
|
||||
return $true
|
||||
}
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
function Resolve-Version {
|
||||
$normalizedVersion = Normalize-Version -RawVersion $Version
|
||||
if ($normalizedVersion -ne "latest") {
|
||||
return $normalizedVersion
|
||||
}
|
||||
|
||||
$release = Invoke-RestMethod -Uri "https://api.github.com/repos/openai/codex/releases/latest"
|
||||
if (-not $release.tag_name) {
|
||||
Write-Error "Failed to resolve the latest Codex release version."
|
||||
exit 1
|
||||
}
|
||||
|
||||
return (Normalize-Version -RawVersion $release.tag_name)
|
||||
}
|
||||
|
||||
if ($env:OS -ne "Windows_NT") {
|
||||
Write-Error "install.ps1 supports Windows only. Use install.sh on macOS or Linux."
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (-not [Environment]::Is64BitOperatingSystem) {
|
||||
Write-Error "Codex requires a 64-bit version of Windows."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$architecture = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
||||
$target = $null
|
||||
$platformLabel = $null
|
||||
$npmTag = $null
|
||||
switch ($architecture) {
|
||||
"Arm64" {
|
||||
$target = "aarch64-pc-windows-msvc"
|
||||
$platformLabel = "Windows (ARM64)"
|
||||
$npmTag = "win32-arm64"
|
||||
}
|
||||
"X64" {
|
||||
$target = "x86_64-pc-windows-msvc"
|
||||
$platformLabel = "Windows (x64)"
|
||||
$npmTag = "win32-x64"
|
||||
}
|
||||
default {
|
||||
Write-Error "Unsupported architecture: $architecture"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($env:CODEX_INSTALL_DIR)) {
|
||||
$installDir = Join-Path $env:LOCALAPPDATA "Programs\OpenAI\Codex\bin"
|
||||
} else {
|
||||
$installDir = $env:CODEX_INSTALL_DIR
|
||||
}
|
||||
|
||||
$codexPath = Join-Path $installDir "codex.exe"
|
||||
$installMode = if (Test-Path $codexPath) { "Updating" } else { "Installing" }
|
||||
|
||||
Write-Step "$installMode Codex CLI"
|
||||
Write-Step "Detected platform: $platformLabel"
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $installDir | Out-Null
|
||||
|
||||
$resolvedVersion = Resolve-Version
|
||||
Write-Step "Resolved version: $resolvedVersion"
|
||||
$packageAsset = "codex-npm-$npmTag-$resolvedVersion.tgz"
|
||||
|
||||
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ("codex-install-" + [System.Guid]::NewGuid().ToString("N"))
|
||||
New-Item -ItemType Directory -Force -Path $tempDir | Out-Null
|
||||
|
||||
try {
|
||||
$archivePath = Join-Path $tempDir $packageAsset
|
||||
$extractDir = Join-Path $tempDir "extract"
|
||||
$url = Get-ReleaseUrl -AssetName $packageAsset -ResolvedVersion $resolvedVersion
|
||||
|
||||
Write-Step "Downloading Codex CLI"
|
||||
Invoke-WebRequest -Uri $url -OutFile $archivePath
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $extractDir | Out-Null
|
||||
tar -xzf $archivePath -C $extractDir
|
||||
|
||||
$vendorRoot = Join-Path $extractDir "package/vendor/$target"
|
||||
Write-Step "Installing to $installDir"
|
||||
$copyMap = @{
|
||||
"codex/codex.exe" = "codex.exe"
|
||||
"codex/codex-command-runner.exe" = "codex-command-runner.exe"
|
||||
"codex/codex-windows-sandbox-setup.exe" = "codex-windows-sandbox-setup.exe"
|
||||
"path/rg.exe" = "rg.exe"
|
||||
}
|
||||
|
||||
foreach ($relativeSource in $copyMap.Keys) {
|
||||
$sourcePath = Join-Path $vendorRoot $relativeSource
|
||||
$destinationPath = Join-Path $installDir $copyMap[$relativeSource]
|
||||
Move-Item -Force $sourcePath $destinationPath
|
||||
}
|
||||
} finally {
|
||||
Remove-Item -Recurse -Force $tempDir -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
||||
$pathNeedsNewShell = $false
|
||||
if (-not (Path-Contains -PathValue $userPath -Entry $installDir)) {
|
||||
if ([string]::IsNullOrWhiteSpace($userPath)) {
|
||||
$newUserPath = $installDir
|
||||
} else {
|
||||
$newUserPath = "$userPath;$installDir"
|
||||
}
|
||||
|
||||
[Environment]::SetEnvironmentVariable("Path", $newUserPath, "User")
|
||||
if (-not (Path-Contains -PathValue $env:Path -Entry $installDir)) {
|
||||
$env:Path = "$env:Path;$installDir"
|
||||
}
|
||||
Write-Step "PATH updated for future PowerShell sessions."
|
||||
$pathNeedsNewShell = $true
|
||||
} elseif (Path-Contains -PathValue $env:Path -Entry $installDir) {
|
||||
Write-Step "$installDir is already on PATH."
|
||||
} else {
|
||||
Write-Step "PATH is already configured for future PowerShell sessions."
|
||||
$pathNeedsNewShell = $true
|
||||
}
|
||||
|
||||
if ($pathNeedsNewShell) {
|
||||
Write-Step ('Run now: $env:Path = "{0};$env:Path"; codex' -f $installDir)
|
||||
Write-Step "Or open a new PowerShell window and run: codex"
|
||||
} else {
|
||||
Write-Step "Run: codex"
|
||||
}
|
||||
|
||||
Write-Host "Codex CLI $resolvedVersion installed successfully."
|
||||
244
scripts/install/install.sh
Executable file
244
scripts/install/install.sh
Executable file
@@ -0,0 +1,244 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
VERSION="${1:-latest}"
|
||||
INSTALL_DIR="${CODEX_INSTALL_DIR:-$HOME/.local/bin}"
|
||||
path_action="already"
|
||||
path_profile=""
|
||||
|
||||
step() {
|
||||
printf '==> %s\n' "$1"
|
||||
}
|
||||
|
||||
normalize_version() {
|
||||
case "$1" in
|
||||
"" | latest)
|
||||
printf 'latest\n'
|
||||
;;
|
||||
rust-v*)
|
||||
printf '%s\n' "${1#rust-v}"
|
||||
;;
|
||||
v*)
|
||||
printf '%s\n' "${1#v}"
|
||||
;;
|
||||
*)
|
||||
printf '%s\n' "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
download_file() {
|
||||
url="$1"
|
||||
output="$2"
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL "$url" -o "$output"
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget -q -O "$output" "$url"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "curl or wget is required to install Codex." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
download_text() {
|
||||
url="$1"
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL "$url"
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget -q -O - "$url"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "curl or wget is required to install Codex." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
add_to_path() {
|
||||
path_action="already"
|
||||
path_profile=""
|
||||
|
||||
case ":$PATH:" in
|
||||
*":$INSTALL_DIR:"*)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
profile="$HOME/.profile"
|
||||
case "${SHELL:-}" in
|
||||
*/zsh)
|
||||
profile="$HOME/.zshrc"
|
||||
;;
|
||||
*/bash)
|
||||
profile="$HOME/.bashrc"
|
||||
;;
|
||||
esac
|
||||
|
||||
path_profile="$profile"
|
||||
path_line="export PATH=\"$INSTALL_DIR:\$PATH\""
|
||||
if [ -f "$profile" ] && grep -F "$path_line" "$profile" >/dev/null 2>&1; then
|
||||
path_action="configured"
|
||||
return
|
||||
fi
|
||||
|
||||
{
|
||||
printf '\n# Added by Codex installer\n'
|
||||
printf '%s\n' "$path_line"
|
||||
} >>"$profile"
|
||||
path_action="added"
|
||||
}
|
||||
|
||||
release_url_for_asset() {
|
||||
asset="$1"
|
||||
resolved_version="$2"
|
||||
|
||||
printf 'https://github.com/openai/codex/releases/download/rust-v%s/%s\n' "$resolved_version" "$asset"
|
||||
}
|
||||
|
||||
require_command() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
echo "$1 is required to install Codex." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_command mktemp
|
||||
require_command tar
|
||||
|
||||
resolve_version() {
|
||||
normalized_version="$(normalize_version "$VERSION")"
|
||||
|
||||
if [ "$normalized_version" != "latest" ]; then
|
||||
printf '%s\n' "$normalized_version"
|
||||
return
|
||||
fi
|
||||
|
||||
release_json="$(download_text "https://api.github.com/repos/openai/codex/releases/latest")"
|
||||
resolved="$(printf '%s\n' "$release_json" | sed -n 's/.*"tag_name":[[:space:]]*"rust-v\([^"]*\)".*/\1/p' | head -n 1)"
|
||||
|
||||
if [ -z "$resolved" ]; then
|
||||
echo "Failed to resolve the latest Codex release version." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s\n' "$resolved"
|
||||
}
|
||||
|
||||
case "$(uname -s)" in
|
||||
Darwin)
|
||||
os="darwin"
|
||||
;;
|
||||
Linux)
|
||||
os="linux"
|
||||
;;
|
||||
*)
|
||||
echo "install.sh supports macOS and Linux. Use install.ps1 on Windows." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$(uname -m)" in
|
||||
x86_64 | amd64)
|
||||
arch="x86_64"
|
||||
;;
|
||||
arm64 | aarch64)
|
||||
arch="aarch64"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported architecture: $(uname -m)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$os" = "darwin" ] && [ "$arch" = "x86_64" ]; then
|
||||
if [ "$(sysctl -n sysctl.proc_translated 2>/dev/null || true)" = "1" ]; then
|
||||
arch="aarch64"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$os" = "darwin" ]; then
|
||||
if [ "$arch" = "aarch64" ]; then
|
||||
npm_tag="darwin-arm64"
|
||||
vendor_target="aarch64-apple-darwin"
|
||||
platform_label="macOS (Apple Silicon)"
|
||||
else
|
||||
npm_tag="darwin-x64"
|
||||
vendor_target="x86_64-apple-darwin"
|
||||
platform_label="macOS (Intel)"
|
||||
fi
|
||||
else
|
||||
if [ "$arch" = "aarch64" ]; then
|
||||
npm_tag="linux-arm64"
|
||||
vendor_target="aarch64-unknown-linux-musl"
|
||||
platform_label="Linux (ARM64)"
|
||||
else
|
||||
npm_tag="linux-x64"
|
||||
vendor_target="x86_64-unknown-linux-musl"
|
||||
platform_label="Linux (x64)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -x "$INSTALL_DIR/codex" ]; then
|
||||
install_mode="Updating"
|
||||
else
|
||||
install_mode="Installing"
|
||||
fi
|
||||
|
||||
step "$install_mode Codex CLI"
|
||||
step "Detected platform: $platform_label"
|
||||
|
||||
resolved_version="$(resolve_version)"
|
||||
asset="codex-npm-$npm_tag-$resolved_version.tgz"
|
||||
download_url="$(release_url_for_asset "$asset" "$resolved_version")"
|
||||
|
||||
step "Resolved version: $resolved_version"
|
||||
|
||||
tmp_dir="$(mktemp -d)"
|
||||
cleanup() {
|
||||
rm -rf "$tmp_dir"
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
archive_path="$tmp_dir/$asset"
|
||||
|
||||
step "Downloading Codex CLI"
|
||||
download_file "$download_url" "$archive_path"
|
||||
|
||||
tar -xzf "$archive_path" -C "$tmp_dir"
|
||||
|
||||
step "Installing to $INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
cp "$tmp_dir/package/vendor/$vendor_target/codex/codex" "$INSTALL_DIR/codex"
|
||||
cp "$tmp_dir/package/vendor/$vendor_target/path/rg" "$INSTALL_DIR/rg"
|
||||
chmod 0755 "$INSTALL_DIR/codex"
|
||||
chmod 0755 "$INSTALL_DIR/rg"
|
||||
|
||||
add_to_path
|
||||
|
||||
case "$path_action" in
|
||||
added)
|
||||
step "PATH updated for future shells in $path_profile"
|
||||
step "Run now: export PATH=\"$INSTALL_DIR:\$PATH\" && codex"
|
||||
step "Or open a new terminal and run: codex"
|
||||
;;
|
||||
configured)
|
||||
step "PATH is already configured for future shells in $path_profile"
|
||||
step "Run now: export PATH=\"$INSTALL_DIR:\$PATH\" && codex"
|
||||
step "Or open a new terminal and run: codex"
|
||||
;;
|
||||
*)
|
||||
step "$INSTALL_DIR is already on PATH"
|
||||
step "Run: codex"
|
||||
;;
|
||||
esac
|
||||
|
||||
printf 'Codex CLI %s installed successfully.\n' "$resolved_version"
|
||||
Reference in New Issue
Block a user