Yoda
参考Agent 设计指南Runtime 生命周期

安装

CC 五渠道(原生脚本/npm/brew/winget/Linux 签名仓库)+ XDG 多版本布局 vs Codex 三渠道(npm shim/brew cask/standalone);harness 用 PTY 跑 installCommand + 重探测闭环

安装

结论

两家的最终交付物都已收敛为「平台原生二进制」,差异在分发面与落盘布局。CC 渠道最全:原生脚本(curl claude.ai/install.sh,可带 stable/latest/具体版本参数)、npm(包本身只是壳,二进制走平台 optionalDependency)、Homebrew 双 cask、WinGet、apt/dnf/apk 签名仓库,落盘遵循 XDG 规范(二进制 ~/.local/bin/claude,版本库 ~/.local/share/claude/versions/,staging ~/.cache/claude/staging,锁 ~/.local/state/claude/locks),且 CLI 自带 claude install 子命令可自我重装并清理旧 npm 安装/shell alias。Codex 是 npm shim(bin/codex.js 按平台三元组解析 @openai/codex-darwin-arm64 等可选包并注入 CODEX_MANAGED_BY_NPM)、brew cask、standalone 脚本(chatgpt.com/codex/install.shCODEX_NON_INTERACTIVE=1 即静默)三条路,落盘进 $CODEX_HOME/packages/standalone/releases/。首次运行侧,CC 走 OAuth 浏览器登录(CI 用 claude setup-tokenANTHROPIC_API_KEY),Codex 走 codex login(ChatGPT OAuth / --with-api-key stdin / --device-auth)。Yoda 的自动安装是「注册表声明 installCommand → PTY 执行 → 失败分类 → 重探测」的闭环,并自动把 ~/.local/bin 补进 PATH。

研究问题

  • 各 CLI 的官方安装渠道与静默安装参数?
  • 安装位置与 PATH 注入的差异?
  • 首次运行(登录、onboarding)如何自动化?headless/CI 怎么装?
  • harness 如何代替用户执行安装并验证成功?

各 Agent 设计与实现

Claude Code

渠道一:原生安装脚本(官方推荐)curl -fsSL https://claude.ai/install.sh | bash,Windows 有 install.ps1(PowerShell)和 install.cmd(CMD)两套;脚本接受位置参数 stable / latest / 2.1.89 指定渠道或版本,安装时选择的渠道成为后续自更新默认渠道(docs setup.md "Install a specific version")[一手文档]。原生安装自动后台更新 [一手文档]。

落盘布局(XDG)utils/nativeInstaller/installer.ts:115-132getBaseDirectories() [一手源码]:

versions:   join(getXDGDataHome(),  'claude', 'versions')   // ~/.local/share/claude/versions
staging:    join(getXDGCacheHome(), 'claude', 'staging')    // ~/.cache/claude/staging
locks:      join(getXDGStateHome(), 'claude', 'locks')      // ~/.local/state/claude/locks
executable: join(getUserBinDir(),   executableName)         // ~/.local/bin/claude

下载到 staging 后「先拷到 install 路径旁的临时文件再 rename」,避免 staging 与 install 跨文件系统时 rename 报 EXDEVinstaller.ts:307-315 注释)[一手源码];Windows 不用 symlink 而是直接拷贝可执行文件,旧文件先 rename 成 claude.exe.old.<ts> 以绕过文件锁(installer.ts:646-701)[一手源码]。安装后检查 ~/.local/bin 是否在 PATH,不在则生成带平台指引的 setup message(installer.ts:895-918)[一手源码]。

渠道二:npmnpm install -g @anthropic-ai/claude-code。npm 包装的是同一个原生二进制:通过平台 optionalDependency(如 @anthropic-ai/claude-code-darwin-arm64)拉取,postinstall 链接到位,装好的 claude 不经过 Node(docs setup.md "Install with npm";支持 8 个平台三元组)[一手文档]。文档明确警告不要 sudo npm install -g,升级要用 @latest 而非 npm update -g [一手文档]。

渠道三~五:Homebrew 双 cask(claude-code=stable / claude-code@latest=latest,渠道由 cask 名决定);WinGet Anthropic.ClaudeCode;apt/dnf/apk 签名仓库(GPG 指纹 31DD DE24 ... 1A7E CACE,发布物附 manifest.json + 分离签名,macOS/Windows 二进制带平台代码签名)(docs setup.md)[一手文档]。musl 发行版需 libgcc libstdc++ ripgrep + USE_BUILTIN_RIPGREP=0(docs setup.md "Alpine Linux")[一手文档]。

CLI 内自装claude install [target] [--force] 命令的状态机为 checking → cleaning-npm → installing → setting-up(commands/install.tsx:21-41),调用链 installLatest(channelOrVersion, force)checkInstall(true)cleanupNpmInstallations()cleanupShellAliases()commands/install.tsx:110-155)——原生安装会主动清掉旧的 npm 全局安装与旧版安装器留下的 shell alias,避免多安装冲突 [一手源码]。自更新路径同样先 removeClaudeAliasesFromShellConfigs()utils/autoUpdater.ts:472-473, 539-561)[一手源码]。

首次运行 / CI:交互模式首跑 claude 走浏览器 OAuth(docs setup.md "Authenticate")。headless/CI 三条路:claude setup-token 生成长期 OAuth token(打印不落盘);ANTHROPIC_API_KEY 环境变量(-p 非交互模式下有 key 即直接使用,交互模式首次需确认);apiKeyHelper 脚本做动态/轮换凭证(docs cli-reference.md:39authentication.md:123-136)[一手文档]。

Codex CLI

渠道一:npmnpm install -g @openai/codex。包里只有壳脚本 bin/codex.jscodex-cli/package.json:6-8, 13-15),运行时按 process.platform/arch 映射 Rust 平台三元组(Linux 一律 musl 静态链接:x86_64-unknown-linux-musl 等),再解析对应平台包(@openai/codex-darwin-arm64 等)中的真实二进制(codex-cli/bin/codex.js:17-76)[一手源码]。spawn 真实二进制时注入 CODEX_MANAGED_BY_NPM=1(bun 环境为 CODEX_MANAGED_BY_BUN)与 CODEX_MANAGED_PACKAGE_ROOT,stdio 直通、转发终止信号(codex-cli/bin/codex.js:140-153)——这两个变量是后续 update/doctor 判定安装方式的依据 [一手源码]。

渠道二:brew cask。检测依据是可执行文件位于 /opt/homebrew/usr/local(仅 macOS,install-context/src/lib.rs:220-224);升级命令 brew upgrade --cask codextui/src/update_action.rs:43)[一手源码]。

渠道三:standalone 安装脚本curl -fsSL https://chatgpt.com/codex/install.sh | sh,环境变量 CODEX_NON_INTERACTIVE=1 进入静默模式(该命令串硬编码于 tui/src/update_action.rs:44-50,更新即重跑安装器)[一手源码]。落盘 $CODEX_HOME/packages/standalone/releases/<version>-<triple>/,新版包布局含 bin/codex-resources/(捆绑 rg、zsh)、codex-path/(应被 prepend 到 PATH 的目录)和元数据文件 codex-package.jsoninstall-context/src/lib.rs:8-14, 23-54)[一手源码]。GitHub Release 另附 DotSlash 文件,可把「团队统一 codex 版本」做成一个轻量受控文件提交进仓库(codex/docs/install.md "DotSlash")[一手文档]。源码构建走 cargo buildcodex/docs/install.md)[一手文档]。

首次运行 / CIcodex login 默认 ChatGPT OAuth;自动化场景用 printenv OPENAI_API_KEY | codex login --with-api-key(key 从 stdin 读,不进 shell history)、--with-access-token、或无浏览器环境的 --device-authcodex login status 可脚本化查询(cli/src/main.rs:417-456, 1247-1289)[一手源码]。直接传 --api-key <key> 已废弃,会退出并提示改用 stdin 方式(cli/src/main.rs:433-441)[一手源码]。

代理 / 受限网络下的失败模式

安装与更新链路上的远端请求两家都做了短超时 + 优雅降级,但安装脚本本身(curl 管道)在代理未配置时会直接 TLS 超时:

  • CC 的 npm view 探测带 5s AbortSignal.timeout,GCS 渠道指针请求 axios timeout: 5000,失败只记 debug 日志并返回 null,不阻塞主流程(utils/autoUpdater.ts:326-341, 384-397)[一手源码];
  • Codex doctor 的远端版本探测统一 curl -fsSL --max-time 5,失败降级为 warning(cli/src/doctor/updates.rs:174-180)[一手源码];
  • 安装脚本(claude.ai/install.shchatgpt.com/codex/install.sh)与 npm registry 在中国大陆等网络下需先 export https_proxy,harness 代跑安装时应把代理 env 一并注入 PTY [推断,基于本机 ClashX 环境实测经验]。

差异矩阵

维度Claude CodeCodex CLI
推荐渠道原生脚本 claude.ai/install.sh(支持渠道/版本参数)npm @openai/codex
npm 包性质平台 optionalDependency + postinstall 链接,claude 不经 Node壳脚本 codex.js 每次启动经 Node 转发 spawn
包管理器brew 双 cask、winget、apt/dnf/apk 签名仓库brew cask(单一)
静默安装管道本身非交互;版本作位置参数CODEX_NON_INTERACTIVE=1 + 管道
落盘位置XDG:~/.local/bin + ~/.local/share/claude/versions$CODEX_HOME/packages/standalone/releases/(standalone)或 npm/brew 前缀
PATH 注入安装到 ~/.local/bin,缺失时给平台化指引包布局含 codex-path/ 目录(捆绑 rg 等待 prepend)
CLI 自装/重装claude install [version],附带清理 npm 旧装与 alias无(codex update 仅升级)
完整性验证GPG 签名 manifest + 平台代码签名 + 仓库签名GitHub Release(DotSlash 文件含校验)
交互登录浏览器 OAuth(Pro/Max/Team/Enterprise/Console)codex login ChatGPT OAuth
CI 凭证claude setup-token / ANTHROPIC_API_KEY / apiKeyHelpercodex login --with-api-key(stdin)/ --device-auth

最小复现

# CC:原生安装指定渠道(静默)
curl -fsSL https://claude.ai/install.sh | bash -s stable
ls ~/.local/share/claude/versions/   # 多版本目录
readlink ~/.local/bin/claude         # symlink 指向当前激活版本

# Codex:npm 安装并验证 shim 注入
npm install -g @openai/codex
codex --version

# Codex:CI 登录(key 不进 history)
printenv OPENAI_API_KEY | codex login --with-api-key && codex login status

Harness 接入建议(Yoda 实践)

Yoda 已上线「一键安装依赖」,核心是注册表驱动的闭环 [一手源码]:

  1. 声明:每个 runtime 在注册表声明 installCommand(CC 用原生脚本 curl -fsSL https://claude.ai/install.sh | bash,Codex 用 npm install -g @openai/codexsrc/shared/runtime-registry.ts:196, 220);
  2. 执行runLocalInstallCommandPTY 里以 os.homedir() 为 cwd 跑安装命令(80x24),而非普通 child_process——不少安装脚本检测 TTY 才正常输出/不挂起(core/dependencies/install-runner.ts:62-99);
  3. 失败分类:退出码非零时剥 ANSI 后正则匹配 EACCES|permission denied 归类 permission-denied,其余 command-failed,带原始输出返回 UI(install-runner.ts:19-42);
  4. PATH 修复:安装成功后 ensureUserBinDirsInPath()~/.local/bin prepend 进当前进程 PATH——否则 Electron 进程在本次生命周期内找不到刚装好的 CC(install-runner.ts:93-98utils/userEnv.ts:40, 75-89);Windows 另有 ensureWindowsNpmGlobalBinInPath() 处理 %APPDATA%\npmuserEnv.ts:91-99);
  5. 验证:安装后强制重新 probe,status !== 'available' 则返回 not-detected-after-install 错误(dependency-manager.ts:186-211);
  6. 远程:SSH 场景用 createSshInstallCommandRunner 在远端 PTY 跑同一条命令(install-runner.ts:101-117)。

踩坑记录:Yoda 启动时用 $SHELL -ilc 'env' 捕获登录 shell 环境来获得完整 PATH,但必须注入 DISABLE_AUTO_UPDATE=true 等 guard 变量防止 oh-my-zsh 自更新挂住探测;Linux AppImage 下还要剥掉 APPIMAGE/APPDIR 等变量防止登录 shell hook 重入 AppImage 造成 fork-bomb(utils/userEnv.ts:34-38, 110-159,含 issue #1679 注释)[一手源码]。

改进方向:CC 安装后的登录仍需用户在 PTY 里走 OAuth;Yoda 可检测 claude auth status(退出码 0/1,见 docs cli-reference.md)与 codex login status,把「已安装但未登录」做成独立状态而非笼统 available [推断]。

失效条件

  • CC install.sh 参数约定(stable|latest|x.y.z 位置参数)变化
  • CC npm 包平台包命名(@anthropic-ai/claude-code-<platform>)或 postinstall 机制变更
  • CC XDG 目录布局或 claude install 子命令语义变化(源为 v2.1.88 重构源,结论以 docs 交叉验证)
  • Codex standalone 安装 URL(chatgpt.com/codex/install.sh)或 CODEX_NON_INTERACTIVE 约定迁移
  • Codex npm shim 改为 postinstall 链接(不再每次经 Node 转发)
  • codex login 增删登录方式(--with-api-key/--device-auth 语义)

参考资料

  • CC docs:claude-code-docs/docs/setup.md(Install / Windows / Linux package managers / npm / Binary integrity / Uninstall)、authentication.mdcli-reference.mdtroubleshoot-install.md
  • CC 重构源:src_2026-03-31/utils/nativeInstaller/{installer,download,packageManagers}.tscommands/install.tsxutils/xdg.ts
  • Codex 源(b89ce9a):codex-cli/bin/codex.jscodex-cli/package.jsoncodex-rs/install-context/src/lib.rscodex-rs/cli/src/main.rs(LoginCommand)、codex/docs/install.md
  • Yoda 源:src/main/core/dependencies/install-runner.tssrc/main/utils/userEnv.tssrc/shared/runtime-registry.ts

On this page