Codex CLI 是什么 · 开源的是哪一部分
Codex CLI 是 OpenAI 在你本机运行的编码 agent,仓库 openai/codex 以 Apache-2.0 开源。开源的是本地这一侧:Rust 写的 CLI、TUI、app-server、agent 内核、工具与三套沙箱,外加 npm 启动器和 TypeScript、Python 两个 SDK;模型、ChatGPT 后端、IDE 扩展与桌面应用都不在仓库里。npm 包里的 codex.js 只是一个挑平台二进制、转发信号的启动器。
Codex CLI 是什么 · 开源的是哪一部分
仓库根目录 README.md 的第一句是:Codex CLI is a coding agent from OpenAI that runs locally on your computer——OpenAI 出品、在你本机运行的编码 agent。它读你的代码、改文件、跑命令、调 MCP 工具:模型推理在云端,这些动作都在你的机器上执行。
本专栏读的就是这份代码:github.com/openai/codex,Apache-2.0 许可,2025-04-13 建仓,基准 tag rust-v0.158.0(版本、commit 与统计口径见专栏封面)。这一篇先回答两个问题:这个仓库里到底有什么,没有什么。
先看它怎么用
README.md 给了四种安装方式:官方安装脚本(install.sh、install.ps1)、npm 包 @openai/codex、Homebrew 的 codex cask,以及 GitHub Release 里的单文件二进制(Linux 版用 musl 目标构建,文件名形如 codex-x86_64-unknown-linux-musl)。装好之后:
- 直接敲
codex,进入全屏终端界面(TUI),也就是日常用的交互模式; codex exec "..."非交互地跑完一个任务,适合脚本和 CI;codex app-server把同一套 agent 以 JSON-RPC 服务的形式开放出去,IDE 扩展、Python SDK 等都通过它接入。
codex-rs/cli/src/main.rs:143 的 Subcommand 枚举一共 30 个变体,其中 4 个标了 hide = true(tcp-tunnel、execpolicy、responses-api-proxy、stdio-to-uds),属于内部工具。各命令的用法、登录方式与配置,见《Codex 中文手册》的安装、登录与升级和启动命令行选项,这里不重复。
仓库里有什么
git 跟踪的 8,670 个文件里,8,145 个在 codex-rs/ 下。顶层目录的分工如下:
| 目录 | 内容 |
|---|---|
codex-rs/ | Rust Cargo workspace,members 共 153 个:CLI、TUI、app-server、内核 codex-core、工具、沙箱、MCP、登录、持久化……发布出去的 codex 二进制全部出自这里 |
codex-cli/ | npm 包 @openai/codex 的外壳,运行时只有 bin/codex.js 一个文件,另有打包脚本 |
sdk/typescript/ | @openai/codex-sdk:启动 codex exec --experimental-json,经 stdin、stdout 交换 JSONL 事件 |
sdk/python/ | openai-codex:以 codex app-server --listen stdio:// 启动子进程,走 JSON-RPC |
sdk/python-runtime/ | openai-codex-cli-bin:给 Python SDK 带上对应平台的 Codex 二进制,只发 wheel |
docs/ | 多数页面只剩一句指向 developers.openai.com 的链接,install.md、contributing.md 等少数几篇有正文 |
MODULE.bazel、defs.bzl、bazel/、patches/ | Bazel 构建(下一篇细讲) |
scripts/、.github/ | 打包发布脚本与 CI 工作流 |
.codex/skills/ | 仓库自带的 Codex skills:代码审查、PR 描述、远程测试等,供在这个仓库里干活的 Codex 使用 |
third_party/、tools/ | 第三方资源(v8、wezterm 等)与自有工具(argument-comment-lint、buildifier) |
docs/ 几乎是空壳并非疏忽。根目录 AGENTS.md 明确要求不要往 docs/ 里写面向用户的产品文档,官方文档另有去处,唯一的例外是 app-server 的 API 文档。
NOTICE 里还有一条值得一提:仓库包含从 Ratatui(MIT 许可)派生的代码,TUI 的终端渲染就建在 ratatui 之上。
不在仓库里的
开源的是“本机这一侧”。下图把仓库内外画在一起:
逐项看:
- 模型:仓库里只有调用方。模型提供方的线协议枚举
WireApi只剩一个变体Responses(codex-rs/model-provider-info/src/lib.rs:103),注释写明是 OpenAI 在/v1/responses暴露的 Responses API;HTTP 与 WebSocket 客户端在codex-api,怎么调用见模型客户端。 - Codex Cloud:
codex cloud子命令(cratecodex-cloud-tasks)只是一个浏览云端任务、把 diff 应用到本地的客户端,默认后端地址是https://chatgpt.com/backend-api(codex-rs/cloud-tasks/src/lib.rs:55)。后端接口的数据类型放在codex-backend-openapi-models,它的lib.rs注明其中没有手写类型,全部由脚本从 OpenAPI 生成。 - IDE 扩展:源码不在这里,但留下了接入痕迹。
codex app-server以SessionSource::VSCode作为会话来源启动(codex-rs/cli/src/main.rs:1270),参数--analytics-default-enabled的注释说,这是给 VS Code 扩展这类第一方用例准备的(codex-rs/cli/src/main.rs:591)。扩展与 app-server 之间怎么通信,见 app-server。 - 桌面应用:
codex app(只在 macOS 与 Windows 上编译)负责打开或安装它,macOS 从persistent.oaistatic.com下载 DMG,Windows 走 Microsoft Store(codex-rs/cli/src/desktop_app/),应用本身不开源。
npm 包里的 codex.js:一个启动器
很多人是 npm install -g @openai/codex 装上的,于是以为 Codex 是个 Node 程序。其实 codex-cli/bin/codex.js 不到 300 行,只做四件事:
- 按
process.platform和process.arch算出目标三元组,一共六种:Linux 的 x64 与 arm64(都用 musl)、macOS 的 x64 与 arm64、Windows 的 x64 与 arm64,找到对应的平台包; - 在平台包的
vendor/<三元组>/bin/下找codex(Windows 上是codex.exe),找不到就按探测到的包管理器提示一条重装命令; - 探测是被 npm、bun、pnpm 还是 Vite+ 装上的,把结果写进环境变量;
- 启动原生二进制,
stdio直通,转发终止信号,最后照搬子进程的退出方式。
第 3、4 步是这一段:
const env = {
...process.env,
CODEX_MANAGED_PACKAGE_ROOT: codexPackageRoot,
};
delete env.CODEX_MANAGED_BY_NPM;
delete env.CODEX_MANAGED_BY_BUN;
delete env.CODEX_MANAGED_BY_PNPM;
delete env.CODEX_MANAGED_BY_VITE_PLUS;
env[packageManagerEnvVar] = "1";
const child = spawn(binaryPath, process.argv.slice(2), {
stdio: "inherit",
env,
});(codex-cli/bin/codex.js:231)
CODEX_MANAGED_BY_* 是写给 Rust 侧看的:codex-install-context crate 据此判断安装方式(codex-rs/install-context/src/lib.rs:121 的 InstallContext::current),升级提示才能给出对的命令。信号方面,SIGINT、SIGTERM、SIGHUP 原样转给子进程;子进程若被信号杀死,父进程用同一个信号结束自己,这样 shell 看到的退出码(128 加信号编号)与直接运行二进制时一致。平台包是怎么被挑中、装进 node_modules 的,留到下一篇讲。
读之前知道的两件事
不收外部代码贡献。 docs/contributing.md 开宗明义:We do not accept external code contributions or pull requests。社区的参与方式是提 issue、给复现步骤和根因分析,代码由 Codex 团队来改。团队内部遵循的工程约定集中写在根目录 AGENTS.md 里,读代码前值得先过一遍,见读源码之前。
它也是写给 AI 看的。 AGENTS.md 里有这样的话:你在沙箱里运行,用 shell 工具时会设置 CODEX_SANDBOX_NETWORK_DISABLED=1(AGENTS.md:9)。这份开发规范的读者包括 Codex 自己,仓库的 .codex/skills/ 也是为它准备的。
另外说一句版本:发布工作流 .github/workflows/rust-release.yml 只认 rust-v*.*.* 形式的 tag,CHANGELOG.md 第一句就把人指向 GitHub Releases 页面。本专栏的行号都固定在 rust-v0.158.0 上,你手上的版本若更新,细节可能已经变了。
和《Codex 中文手册》的分工
两本书读同一个版本,分工不同:
- 《Codex 中文手册》依据官方文档整理,讲怎么用:命令、参数、配置项、斜杠命令、沙箱与审批的选项;
- 本专栏读
rust-v0.158.0的源码,讲怎么实现:一个功能经过哪些 crate、数据怎么流、边界契约是什么。
所以每一篇都先用一两段交代“用户看到的样子”,并链接到手册的对应页面,然后翻进源码。遇到手册与代码对不上的地方,以代码为准并在文中点明。
和《从 LLM 到 Coding Agent》对照
《从 LLM 到 Coding Agent》从裸 API 调用起步,手搓了一个最小的 agent 循环:问模型、执行工具、把结果喂回去、再问。Codex 的内核做的是同一件事,只是外面多了几层:一个所有前端共用的 app-server,三个操作系统各自的沙箱,一套审批与执行策略,以及会话持久化、上下文压缩和扩展机制。读完这一部分的消息生命周期,你会在代码里认出那个最小循环的每一步。
上一篇:专栏封面 · 下一篇:从源码构建与运行 · Cargo、Bazel 与 npm 包装