From 703fb38d2a0be48d37f0f11de1c3941f504428df Mon Sep 17 00:00:00 2001 From: pakrym-oai Date: Wed, 11 Feb 2026 16:20:10 -0800 Subject: [PATCH] Make codex-sdk depend on openai/codex (#11503) Do not bundle all binaries inside the SDK as it makes the package huge. Instead depend on openai/codex --- codex-cli/scripts/build_npm_package.py | 14 +++++------ sdk/typescript/README.md | 2 +- sdk/typescript/src/exec.ts | 35 ++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/codex-cli/scripts/build_npm_package.py b/codex-cli/scripts/build_npm_package.py index 6e1c677b3..eda6c2615 100755 --- a/codex-cli/scripts/build_npm_package.py +++ b/codex-cli/scripts/build_npm_package.py @@ -76,7 +76,7 @@ PACKAGE_NATIVE_COMPONENTS: dict[str, list[str]] = { "codex-win32-x64": ["codex", "rg", "codex-windows-sandbox-setup", "codex-command-runner"], "codex-win32-arm64": ["codex", "rg", "codex-windows-sandbox-setup", "codex-command-runner"], "codex-responses-api-proxy": ["codex-responses-api-proxy"], - "codex-sdk": ["codex"], + "codex-sdk": [], } PACKAGE_TARGET_FILTERS: dict[str, str] = { @@ -205,7 +205,6 @@ def main() -> int: f"Staged version {version} for release in {staging_dir_str}\n\n" "Verify the SDK contents:\n" f" ls {staging_dir_str}/dist\n" - f" ls {staging_dir_str}/vendor\n" " node -e \"import('./dist/index.js').then(() => console.log('ok'))\"\n\n" ) else: @@ -318,12 +317,11 @@ def stage_sources(staging_dir: Path, version: str, package: str) -> None: if isinstance(scripts, dict): scripts.pop("prepare", None) - files = package_json.get("files") - if isinstance(files, list): - if "vendor" not in files: - files.append("vendor") - else: - package_json["files"] = ["dist", "vendor"] + dependencies = package_json.get("dependencies") + if not isinstance(dependencies, dict): + dependencies = {} + dependencies[CODEX_NPM_NAME] = version + package_json["dependencies"] = dependencies with open(staging_dir / "package.json", "w", encoding="utf-8") as out: json.dump(package_json, out, indent=2) diff --git a/sdk/typescript/README.md b/sdk/typescript/README.md index ae87b63fa..09886c061 100644 --- a/sdk/typescript/README.md +++ b/sdk/typescript/README.md @@ -2,7 +2,7 @@ Embed the Codex agent in your workflows and apps. -The TypeScript SDK wraps the bundled `codex` binary. It spawns the CLI and exchanges JSONL events over stdin/stdout. +The TypeScript SDK wraps the `codex` CLI from `@openai/codex`. It spawns the CLI and exchanges JSONL events over stdin/stdout. ## Installation diff --git a/sdk/typescript/src/exec.ts b/sdk/typescript/src/exec.ts index 6f8048e5e..ea85a6a27 100644 --- a/sdk/typescript/src/exec.ts +++ b/sdk/typescript/src/exec.ts @@ -1,7 +1,7 @@ import { spawn } from "node:child_process"; import path from "node:path"; import readline from "node:readline"; -import { fileURLToPath } from "node:url"; +import { createRequire } from "node:module"; import type { CodexConfigObject, CodexConfigValue } from "./codexOptions"; import { SandboxMode, ModelReasoningEffort, ApprovalMode, WebSearchMode } from "./threadOptions"; @@ -41,6 +41,18 @@ export type CodexExecArgs = { const INTERNAL_ORIGINATOR_ENV = "CODEX_INTERNAL_ORIGINATOR_OVERRIDE"; const TYPESCRIPT_SDK_ORIGINATOR = "codex_sdk_ts"; +const CODEX_NPM_NAME = "@openai/codex"; + +const PLATFORM_PACKAGE_BY_TARGET: Record = { + "x86_64-unknown-linux-musl": "@openai/codex-linux-x64", + "aarch64-unknown-linux-musl": "@openai/codex-linux-arm64", + "x86_64-apple-darwin": "@openai/codex-darwin-x64", + "aarch64-apple-darwin": "@openai/codex-darwin-arm64", + "x86_64-pc-windows-msvc": "@openai/codex-win32-x64", + "aarch64-pc-windows-msvc": "@openai/codex-win32-arm64", +}; + +const moduleRequire = createRequire(import.meta.url); export class CodexExec { private executablePath: string; @@ -298,9 +310,6 @@ function isPlainObject(value: unknown): value is CodexConfigObject { return typeof value === "object" && value !== null && !Array.isArray(value); } -const scriptFileName = fileURLToPath(import.meta.url); -const scriptDirName = path.dirname(scriptFileName); - function findCodexPath() { const { platform, arch } = process; @@ -351,7 +360,23 @@ function findCodexPath() { throw new Error(`Unsupported platform: ${platform} (${arch})`); } - const vendorRoot = path.join(scriptDirName, "..", "vendor"); + const platformPackage = PLATFORM_PACKAGE_BY_TARGET[targetTriple]; + if (!platformPackage) { + throw new Error(`Unsupported target triple: ${targetTriple}`); + } + + let vendorRoot: string; + try { + const codexPackageJsonPath = moduleRequire.resolve(`${CODEX_NPM_NAME}/package.json`); + const codexRequire = createRequire(codexPackageJsonPath); + const platformPackageJsonPath = codexRequire.resolve(`${platformPackage}/package.json`); + vendorRoot = path.join(path.dirname(platformPackageJsonPath), "vendor"); + } catch { + throw new Error( + `Unable to locate Codex CLI binaries. Ensure ${CODEX_NPM_NAME} is installed with optional dependencies.`, + ); + } + const archRoot = path.join(vendorRoot, targetTriple); const codexBinaryName = process.platform === "win32" ? "codex.exe" : "codex"; const binaryPath = path.join(archRoot, "codex", codexBinaryName);