Skip to content

源码仓库目录地图

梳理 Codex 仓库的根目录、Rust 工作空间、SDK、构建工具、生成物与测试资产。

基于rust-v0.150.0
CodexRepositoryArchitecture

源码仓库目录地图 ​

Codex 不是一个只有 Rust crate 的单语言项目。仓库同时保存 Rust 运行时、 Node launcher、Python/TypeScript SDK、Cargo 与 Bazel 构建图、发布脚本、协议生成物、 测试 fixture 和仓库自用的 Codex skills。如果不先区分这些资产,很容易把生成文件 当成协议事实源,或者在 target/ 与 bazel-* 中追踪不属于 Git 的构建产物。

本版本的 Git 树包含 13 个顶层目录、32 个顶层文件和 6587 个受跟踪文件。 codex-rs/ 独占 6156 个文件,但其他 12 个目录决定了 Codex 如何交付、测试和发布。

本文是一张“先去哪里找”的仓库地图,不承担运行机制教学。它可以帮助读者区分手写源码、生成物、 fixture 和本地产物,并选择第一个实现目录;当问题已经收敛到 Thread、Turn、工具调用或安全策略时, 就应该停止横向浏览目录,进入文末链接的专题文章和对应测试。

1. 五种仓库资产 ​

目录名不能单独说明文件是否可编辑。例如 schema/ 在仓库中受 Git 跟踪, 却由 Rust 类型生成;tests/ 中既有测试代码,也有作为对比基线的 fixture。

资产类型判定方式代表路径修改方式
手写产品源码定义运行时行为codex-rs/*/src/、sdk/*/src/直接编辑并补测试
仓库与发布工具构建、打包、检查或 CIscripts/、bazel/、.github/、tools/编辑工具源码和工作流
受跟踪生成物文件由 generator 重建app-server-protocol/schema/、openai_codex/generated/修改上游类型后运行 generator
测试资产验证行为或固化输出tests/、fixtures/、*.snap修改测试;审查后才更新基线
本地构建产物由构建过程产生且被 ignorecodex-rs/target*/、bazel-*、dist/删除后可重建,不应当成源码

这张图按“在仓库中承担什么职责”分组,不是运行时依赖图。例如 patches/ 不参与 Agent 运行,但会改变 Bazel 构建时看到的第三方源码。

2. 顶层目录导航 ​

下表覆盖全部 13 个顶层目录。“直接内容”列只展开一层,因此它和根目录 组合起来就是两层地图。

根目录直接内容主要职责
.codex/environments/、skills/仓库自身的 Codex 运行环境和 14 个维护/review skill
.devcontainer/codex-install/、两套 Dockerfile/devcontainer 配置、防火墙与启动脚本贡献者容器和带网络限制的 secure 容器
.github/ISSUE_TEMPLATE/、actions/、codex/、scripts/、workflows/,以及 CODEOWNERS、Dependabot 和 PR 模板GitHub 协作、CI、签名、跨平台发布与仓库自动化
.vscode/extensions.json、launch.json、settings.json受跟踪的 VS Code 开发体验配置
bazel/modules/、platforms/、rules/Bzlmod 补充模块、平台/发布产物定义和仓库自定义规则
codex-cli/bin/、scripts/、package.json、.gitignore@openai/codex Node launcher 与 npm staging,不是 Agent 业务实现
codex-rs/101 个直接子目录,以及 Cargo/Bazel/Rust 工作空间配置产品主体:入口、核心、协议、工具、安全、状态和扩展
docs/15 篇 Markdown,覆盖安装、认证、配置、sandbox、skills、exec 与贡献仓库内用户/贡献者文档;正式用户文档还会链接外部站点
patches/BUILD.bazel 和 19 个 *.patch修正 LLVM、V8、rules_rust、ring 及 Windows 相关依赖的 Bazel/跨平台构建问题
scripts/codex_package/、install/、mcp_conformance/,以及 17 个顶层脚本打包、安装、格式化、Bazel 检查、npm staging、MCP 一致性和远程环境测试
sdk/python-runtime/、python/、typescript/Python 运行时 wheel、Python SDK 和 TypeScript SDK
third_party/powershell/、v8/、wezterm/、wine/受审查的外部构建输入、版本 pin、BUILD 适配和 license
tools/argument-comment-lint/、buildifier独立 Dylint 规则工程和按平台下载 buildifier 的 DotSlash manifest

2.1 .codex 配置 ​

.codex/environments/environment.toml 定义仓库的 Codex 运行 action;文件头明确标记为 自动生成。.codex/skills/ 则是受跟踪的维护指令,包括 PR 看护、破坏性变更审查、 TUI 测试、远程 executor 测试和 V8 版本升级。它们是“用 Codex 开发 Codex”的资产, 不等于最终用户安装后的内置 skill 目录。

2.2 根目录控制面 ​

类别完整文件集用途
项目与政策AGENTS.md、README.md、CHANGELOG.md、SECURITY.md、LICENSE、NOTICE、announcement_tip.toml贡献规则、产品入口、安全报告、授权和 TUI 公告样例
Git 与工作树.gitattributes、.gitignore、.worktreeinclude文本属性、本地产物边界和 worktree 复制范围
格式与文本检查.codespellignore、.codespellrc、.markdownlint-cli2.yaml、.prettierignore、.prettierrc.toml拼写、Markdown 与 Prettier 规则
Bazel.bazelignore、.bazelrc、.bazelversion、BUILD.bazel、MODULE.bazel、MODULE.bazel.lock、defs.bzl、rbe.bzl、两个 workspace_root_test_launcher.*.tplBzlmod、工具链、RBE、公共 crate 规则和测试 launcher
Node/pnpm.npmrc、package.json、pnpm-lock.yaml、pnpm-workspace.yaml仓库级格式化、npm workspace 和依赖供应链约束
Nixflake.nix、flake.lock可复现开发 shell 和 Codex package
统一命令入口justfile把常用 Cargo、Bazel、格式化、schema 和发布命令收敛为 just target

3. codex-rs/目录 ​

codex-rs/ 是 Cargo workspace 根,但“一个直接子目录”不等于“一个 crate”:

  • .cargo/、.config/、docs/、scripts/ 和 vendor/ 不是 workspace package;
  • ext/、memories/ 和 utils/ 是容器目录,其 crate 在更深一层;
  • exec-server/tests/support 等测试支持 crate 也不会出现为一级目录。

因此,本篇按阅读职责归类目录,不用目录数推导 package 数。下表的 7 组共覆盖 107 个直接子目录;同一组也不代表 crate 之间可以自由反向依赖。

导航组数量目录
Workspace 配置与附带资产5.cargo、.config、docs、scripts、vendor
产品入口与长运行服务9cli、tui、exec、app-server、app-server-daemon、app-server-test-client、mcp-server、thread-manager-sample、chatgpt
会话核心、协议与状态23core、core-api、protocol、codex-api、codex-client、app-server-client、app-server-protocol、app-server-protocol-noop-macros、app-server-transport、config、context-fragments、message-history、rollout、rollout-trace、thread-store、state、agent-graph-store、agent-identity、collaboration-mode-templates、prompts、features、install-context、codex-home
模型、后端、认证与网络21backend-client、codex-backend-openapi-models、model-provider、model-provider-info、models-manager、responses-api-proxy、response-debug-context、http-client、websocket-client、network-proxy、aws-auth、cloud-config、cloud-tasks、cloud-tasks-client、cloud-tasks-mock-client、lmstudio、ollama、login、secrets、keyring-store、connectors
工具、执行、文件与安全24apply-patch、shell-command、shell-escalation、sandboxing、linux-sandbox、windows-sandbox-rs、bwrap、process-hardening、exec-server、exec-server-protocol、execpolicy、file-system、file-search、file-watcher、git-utils、terminal-detection、stdio-to-uds、uds、code-mode、code-mode-host、code-mode-protocol、code-mode-runtime、v8-poc、tools
扩展、MCP、Skills 与记忆10ext、plugin、skills、core-skills、core-plugins、hooks、codex-mcp、rmcp-client、memories、external-agent-migration
可观测性与通用支撑9analytics、otel、feedback、test-binary-support、ansi-escape、arg0、async-utils、utils、codex-experimental-api-macros

图中的横向组是导航入口:读一次 Turn 先进 core/,读命令副作用再进 shell-command/、sandboxing/ 和平台 sandbox,读 IDE 协议则进 app-server/ 与 app-server-protocol/。真正的 crate 依赖方向要由 Cargo metadata 确定,不能从这张导航图推断。

3.1 容器目录 ​

text
codex-rs/
├── ext/                         # 12 个扩展 crate
│   ├── agent/                   # Agent 扩展 API
│   ├── connectors/              # Connector 扩展
│   ├── extension-api/           # 共享扩展边界
│   ├── git-attribution/         # Git attribution
│   ├── goal/                    # Goal 扩展
│   ├── guardian/                # Guardian 扩展
│   ├── image-generation/        # 图像生成
│   ├── items/                   # Item 扩展类型
│   ├── mcp/                     # MCP 扩展
│   ├── memories/                # Memory 扩展
│   ├── skills/                  # Skill 扩展
│   └── web-search/              # Web search 扩展
├── memories/
│   ├── read/                    # 记忆注入与引用解析
│   └── write/                   # 两阶段提取与合并
└── utils/                        # 24 个小型通用 crate
    ├── absolute-path/           # 绝对路径类型
    ├── pty/                     # PTY 封装
    ├── path-uri/                # Path URI 边界
    ├── stream-parser/           # 流式解析
    └── ...                      # 其余路径、图像、缓存与 CLI 工具

memories/README.md 还特别说明:读写 crate 放在 memories/,但启动时编排仍在 core/src/memories/。所以阅读目录时要区分“能力所有者”和“调度所有者”。

3.2 Crate构建入口 ​

codex-rs/docs/bazel.md 明确规定 Cargo 仍是 crate 和 feature 的事实源,Bazel 负责密封构建、 工具链和跨平台产物。因此典型 crate 目录会同时包含:

text
codex-rs/core/
├── Cargo.toml             # package、feature 与 Cargo 依赖事实源
├── BUILD.bazel           # Bazel target、data 和测试适配
├── src/                  # 库实现与近场 unit test
├── tests/                # 集成测试、suite、fixture 和支持代码
├── templates/            # 运行时模板
├── config.schema.json    # 受跟踪的配置 schema
└── *.md                  # prompt 和 crate 说明

app-server/、tui/ 和 exec-server/ 也采用 src/ + tests/ 结构,但会额外保存 protocol fixture、TUI frame/snapshot 或远程 executor 测试支持。所以“先读 src/lib.rs” 是起点,“再读同级 tests/”才能确认边界。

4. 三套构建图 ​

仓库根的 justfile 把工作目录设为 codex-rs/,因此 just codex、just fmt 和 测试 target 是面向贡献者的高层入口,不是第四套构建系统。

源码位置:justfile :: working-directory, codex, exec, fmt-check, test

makefile
# 普通recipe默认在codex-rs执行,调用者不需要手工cd到Cargo workspace。
set working-directory := "codex-rs"
set positional-arguments
export JUST_SHELL := justfile_directory() / "scripts/just-shell.py"
set shell := ["python3", "-c", 'import os, runpy; runpy.run_path(os.environ["JUST_SHELL"], run_name="__main__")']
set windows-shell := ["python", "-c", 'import os, runpy; runpy.run_path(os.environ["JUST_SHELL"], run_name="__main__")']

# `codex`
alias c := codex
codex *args:
    cargo run --bin codex -- {args}

# `codex exec`
exec *args:
    cargo run --bin codex -- exec {args}

# 格式检查回到根scripts目录,统一覆盖Rust之外的工程资产。
fmt-check:
    @{{ python }} ../scripts/format.py --check

# Run nextest with --no-fail-fast so all tests are run.
[unix]
test *args:
    RUST_MIN_STACK={{ rust_min_stack }} NEXTEST_PROFILE=local cargo nextest run --no-fail-fast "$@"

[windows]
test *args:
    $env:RUST_MIN_STACK = "{{ rust_min_stack }}"; $env:NEXTEST_PROFILE = "local"; cargo nextest run --no-fail-fast @($args | Select-Object -Skip 1)

[no-cd] recipe 是显式例外:GitHub scripts 或跨目录 shell wrapper 需要从仓库根解析路径时,会覆盖默认 working directory。由此可见,just 只编排 Cargo、Bazel、Python 和脚本入口,并不重新定义 crate 或 feature 的事实源。

构建面事实源覆盖范围
Cargocodex-rs/Cargo.toml、Cargo.lock、各 crate manifestRust package、feature、依赖与常规本地开发
Bazel/BzlmodMODULE.bazel、defs.bzl、bazel/、*/BUILD.bazel密封工具链、跨平台构建、RBE 和发布产物
pnpmpnpm-workspace.yaml、pnpm-lock.yamlcodex-cli、responses-api-proxy/npm 和 sdk/typescript
Nixflake.nix、flake.lock、codex-rs/default.nixLinux/macOS 开发 shell 和 Nix package

重要的阅读规则是:增加 Rust 依赖时先看 Cargo,再检查 Bazel 是否需要 annotation、patch 或 data 配置;不能因为 BUILD.bazel 中有一条边,就把它当成 Cargo feature 的定义。

5. SDK与发布资产 ​

5.1 SDK交付单元 ​

目录关键子目录/文件交付角色
sdk/python-runtime/src/、hatch_build.py、pyproject.toml生成只包平台 Codex 二进制的 openai-codex-cli-bin wheel,不发布 sdist
sdk/python/src/、tests/、docs/、examples/、notebooks/、scripts/长连接 App Server 的 Python SDK、生成类型、示例与发布逻辑
sdk/typescript/src/、tests/、samples/、package.json基于 codex exec --experimental-json 的 TypeScript SDK

5.2 scripts/ ​

scripts/build_codex_package.py 是 package builder 的稳定入口,实现被拆到 scripts/codex_package/。它会组装入口二进制、Code Mode host、平台 sandbox 资源、 rg 和可选 zsh,最后形成可序列化为 zip/tar 的标准 package 目录。

scripts/install/ 保存 Unix 和 PowerShell 安装器及测试;scripts/mcp_conformance/ 则保存 真实 Codex 二进制对官方 MCP conformance suite 的 adapter、已审查 baseline 和 fixture 自测试。 顶层的 format.py、stage_npm_packages.py、run_tui_with_exec_server.sh 等则负责跨子工程编排。

6. 生成物与Fixture ​

6.1 Git跟踪边界 ​

app-server-protocol/schema/ 在该 tag 中包含 688 个 TypeScript schema 文件和 295 个 JSON schema 文件。它们由 schema_fixtures.rs 从 Rust 协议类型生成,生成函数会先清空 旧目录,防止已删除类型留下过期文件。

源码位置:codex-rs/app-server-protocol/src/schema_fixtures.rs :: write_schema_fixtures, write_schema_fixtures_with_options

rust
// 生成前清空输出目录,避免已删除协议类型留下陈旧 schema。
pub fn write_schema_fixtures(schema_root: &Path, prettier: Option<&Path>) -> Result<()> {
    write_schema_fixtures_with_options(schema_root, prettier, SchemaFixtureOptions::default())
}

pub fn write_schema_fixtures_with_options(
    schema_root: &Path,
    prettier: Option<&Path>,
    options: SchemaFixtureOptions,
) -> Result<()> {
    if options.experimental_api {
        return write_experimental_precomputed_exports(schema_root, prettier);
    }

    let typescript_out_dir = schema_root.join("typescript");
    let json_out_dir = schema_root.join("json");

    ensure_empty_dir(&typescript_out_dir)?;
    ensure_empty_dir(&json_out_dir)?;

    crate::export::generate_ts_with_options(
        &typescript_out_dir,
        prettier,
        crate::export::GenerateTsOptions::default(),
    )?;
    crate::export::generate_json(&json_out_dir)?;

    let internal_dir = tempfile::tempdir().context("create internal schema temp dir")?;
    crate::export::generate_internal_json_schema(internal_dir.path())?;
    let exports = PrecomputedExports {
        typescript: collect_export_files_recursive(&typescript_out_dir)?,
        json_schema: collect_export_files_recursive(&json_out_dir)?,
        internal_json_schema: collect_export_files_recursive(internal_dir.path())?,
    };
    write_precomputed_exports(schema_root, "stable", &exports)?;

    Ok(())
}

fn write_experimental_precomputed_exports(
    schema_root: &Path,
    prettier: Option<&Path>,
) -> Result<()> {
    // 实验 schema 在临时目录生成,避免污染稳定的 typescript/json 树。
    let temp_dir = tempfile::tempdir().context("create experimental schema temp dir")?;
    let typescript_out_dir = temp_dir.path().join("typescript");
    let json_out_dir = temp_dir.path().join("json");
    // ...
}

Python SDK 也把生成类型提交到 src/openai_codex/generated/。它的 contract test 会用 pyproject.toml 精确 pin 的 runtime wheel 重新生成,再比较前后字节:

源码位置:sdk/python/tests/test_contract_generation.py :: test_generated_files_are_up_to_date

python
# 测试在受控 runtime 环境中重生成,并以完整快照比较检测漂移。
def test_generated_files_are_up_to_date():
    """Regenerating from the pinned runtime package should leave artifacts unchanged."""
    before = _snapshot_targets(ROOT)

    assert importlib.metadata.version("openai-codex-cli-bin") == "0.147.0"
    env = os.environ.copy()
    env.pop("CODEX_EXEC_PATH", None)
    python_bin = str(Path(sys.executable).parent)
    env["PATH"] = f"{python_bin}{os.pathsep}{env.get('PATH', '')}"

    subprocess.run(
        [sys.executable, "scripts/update_sdk_artifacts.py", "generate-types"],
        cwd=ROOT,
        check=True,
        env=env,
    )

    after = _snapshot_targets(ROOT)
    assert before == after, "Generated files drifted after regeneration"

这条链说明,对生成物的正确修改顺序是“改 Rust 类型或 generator → 重新生成 → 审查 diff → 运行 drift test”,而不是直接编辑数百个 .ts 或 .json 文件。

其他明确的受跟踪生成物还包括:

路径生成源/工具识别证据
codex-rs/codex-backend-openapi-models/src/models/OpenAPI Generator模型文件头包含 Generated by
codex-rs/exec-server/src/proto/*.rsprost-build文件头包含 @generated by prost-build
codex-rs/utils/sleep-inhibitor/src/iokit_bindings.rsrust-bindgen文件头标记 automatically generated
.codex/environments/environment.tomlCodex 环境生成器文件头标记不得手工修改

6.2 Fixture快照 ​

该 Git 树中有 690 个 *.snap 文件,主要用于 TUI 和格式化输出的快照验证。 core/tests/、app-server/tests/、tui/tests/、exec-server/tests/ 中的 suite、fixture 和 support 代码则提供更接近真实运行时的反向证据。

Snapshot 变化不应被视为普通格式化噪声。它记录的就是用户可见布局或结构化输出; 应先确认产品行为为什么改变,再审查更新后的基线。

生成物从源码变化到重新成为可信基线,经历的是一个审阅状态机,而不是“测试失败后直接覆盖文件”。

Updated 不是自动终态:只有 diff 经过审阅并随源码一同提交,生成物才重新回到 Clean。失败路径应回到 源类型或生成器定位原因,而不是手工编辑派生文件。

6.3 不受跟踪的目录 ​

根 .gitignore 排除 node_modules/、dist/、bazel-*、build/、out/、.cache/、 .venv/ 和多种前端缓存;codex-rs/.gitignore 另外排除 target/、target-*、 target-amd64/ 和 target-arm64/。

源码位置:.gitignore 与 codex-rs/.gitignore(节选)。

gitignore
node_modules
dist/
bazel-*
build/
out/
.cache/
.venv/

/target/
/target-*/
/target-amd64/
/target-arm64/

搜索结果出现在这些目录时,应回到生成它的源文件。它们可以用于调试, 却不能作为“当前 tag 定义了什么”的稳定证据。

7. 问题阅读入口 ​

问题第一入口第二证据
codex 参数如何进入产品codex-cli/bin/、codex-rs/cli/cli/src/main.rs 的分派和 CLI 测试
一次 Turn 如何运行codex-rs/core/core/tests/suite/ 与 protocol 事件类型
IDE 怎样控制 Codexapp-server/、app-server-protocol/schema fixture 与 app-server/tests/
命令如何被限制shell-command/、sandboxing/linux-sandbox/、windows-sandbox-rs/ 和平台测试
扩展如何被发现plugin/、skills/、ext/core-plugins/、core-skills/ 与 App Server API
会话如何保存thread-store/、state/、rollout/rollout-trace/ 与恢复测试
二进制如何发布scripts/codex_package/.github/workflows/、bazel/、third_party/
SDK 类型为什么改变Rust protocol 类型schema/、SDK generator 和 drift test

最有效的阅读单元通常不是一个孤立目录,而是“实现目录 + 协议类型 + 同级测试

  • 必要的生成器”。这种组合既能找到正常路径,也能看到跨平台分支、失败语义和对外契约。

8. Git树统计 ​

本文数量全部来自受跟踪 Git tree,不扫描工作区中的 target/、缓存或未跟踪文件。 以下命令从仓库 Git tree 读取统计结果:

bash
# 以下命令均针对本文声明的源码版本,避免把其他版本的文件混入统计。
git describe --tags --exact-match HEAD
git rev-parse HEAD

# 整个Git树与根目录。
git ls-files | wc -l
git ls-tree -d --name-only HEAD | wc -l
git ls-tree HEAD | awk '$2=="blob" {n++} END {print n}'

# Rust子树规模;直接子目录不等于Cargo package。
git ls-files 'codex-rs/**' | wc -l
git ls-tree -d --name-only HEAD:codex-rs | wc -l

# 受跟踪schema与snapshot。
git ls-files 'codex-rs/app-server-protocol/schema/typescript/**' | wc -l
git ls-files 'codex-rs/app-server-protocol/schema/json/**' | wc -l
git ls-files | rg '\.snap$' | wc -l
统计项结果这个数字不能代表什么
统计来源当前 Git tree不代表后续 tag 的目录状态
全部受跟踪文件6004不包含未跟踪生成物和本地缓存
顶层目录 / 文件13 / 32不表示模块或 package 数
codex-rs 文件 / 一级目录5576 / 101一级目录不等于 Cargo crate
TypeScript / JSON schema642 / 285是生成物数量,不是协议 method 数
*.snap690不等于测试用例数量

若未来 tag 数字变化,应先重跑命令,再判断是新增产品资产、生成器输出变化还是目录重组。不要为了维持 旧文章中的数字而删减新目录,也不要用 find 扫描当前工作区后与 Git tree 统计混合比较。

9. 目录地图与专题 ​

下面的“停止条件”用于防止读者长期停留在目录清单:一旦已经选定专题,就转入对应正文,而不是继续从 文件名猜测运行机制。

当前问题地图给出的入口对应专题正文何时停止使用本地图
产品入口与进程关系cli/、tui/、exec/、app-server/Codex 产品形态全景已确定调用方和连接寿命
Cargo workspace与packagecodex-rs/Cargo.toml、各 manifestCargo 工作空间全景已找到 owning package
crate依赖方向Cargo metadata、BUILD.bazelCrate依赖边界已确定上下游consumer
异步Task与Channelcore/、app-server-client/运行时任务拓扑已定位 task owner 和关闭入口
一次Turn如何执行core/src/session/、tasks/、tools/Turn端到端链路已进入具体入口函数
Thread/Turn对象关系thread_manager.rs、state/核心数据对象关系已区分对象生命周期
文件、网络与扩展安全sandboxing/、network-proxy/、hooks/、codex-mcp/Codex信任边界已找到实际enforcement主体
平台实现差异linux-sandbox/、windows-sandbox-rs/、utils/pty/跨平台能力矩阵已选中目标平台fixture
测试、schema与snapshot同级 tests/、schema/、*.snap源码测试与生成物地图已找到可运行测试或generator
不知道先读哪篇本文第7节按问题选入口Codex源码阅读路线已选定阅读问题与验证任务

如果目标已经是 Core 的具体实现,可以直接进入 Core运行时架构总览; 目录地图不会重复解释 Session、Task、背压或关闭协议。