安装
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.sh,CODEX_NON_INTERACTIVE=1 即静默)三条路,落盘进 $CODEX_HOME/packages/standalone/releases/。首次运行侧,CC 走 OAuth 浏览器登录(CI 用 claude setup-token 或 ANTHROPIC_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-132 的 getBaseDirectories() [一手源码]:
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 报 EXDEV(installer.ts:307-315 注释)[一手源码];Windows 不用 symlink 而是直接拷贝可执行文件,旧文件先 rename 成 claude.exe.old.<ts> 以绕过文件锁(installer.ts:646-701)[一手源码]。安装后检查 ~/.local/bin 是否在 PATH,不在则生成带平台指引的 setup message(installer.ts:895-918)[一手源码]。
渠道二:npm。npm 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:39、authentication.md:123-136)[一手文档]。
Codex CLI
渠道一:npm。npm install -g @openai/codex。包里只有壳脚本 bin/codex.js(codex-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 codex(tui/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.json(install-context/src/lib.rs:8-14, 23-54)[一手源码]。GitHub Release 另附 DotSlash 文件,可把「团队统一 codex 版本」做成一个轻量受控文件提交进仓库(codex/docs/install.md "DotSlash")[一手文档]。源码构建走 cargo build(codex/docs/install.md)[一手文档]。
首次运行 / CI:codex login 默认 ChatGPT OAuth;自动化场景用 printenv OPENAI_API_KEY | codex login --with-api-key(key 从 stdin 读,不进 shell history)、--with-access-token、或无浏览器环境的 --device-auth;codex 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探测带 5sAbortSignal.timeout,GCS 渠道指针请求 axiostimeout: 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.sh、chatgpt.com/codex/install.sh)与 npm registry 在中国大陆等网络下需先 exporthttps_proxy,harness 代跑安装时应把代理 env 一并注入 PTY [推断,基于本机 ClashX 环境实测经验]。
差异矩阵
| 维度 | Claude Code | Codex 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 / apiKeyHelper | codex 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 statusHarness 接入建议(Yoda 实践)
Yoda 已上线「一键安装依赖」,核心是注册表驱动的闭环 [一手源码]:
- 声明:每个 runtime 在注册表声明
installCommand(CC 用原生脚本curl -fsSL https://claude.ai/install.sh | bash,Codex 用npm install -g @openai/codex,src/shared/runtime-registry.ts:196, 220); - 执行:
runLocalInstallCommand在 PTY 里以os.homedir()为 cwd 跑安装命令(80x24),而非普通 child_process——不少安装脚本检测 TTY 才正常输出/不挂起(core/dependencies/install-runner.ts:62-99); - 失败分类:退出码非零时剥 ANSI 后正则匹配
EACCES|permission denied归类permission-denied,其余command-failed,带原始输出返回 UI(install-runner.ts:19-42); - PATH 修复:安装成功后
ensureUserBinDirsInPath()把~/.local/binprepend 进当前进程 PATH——否则 Electron 进程在本次生命周期内找不到刚装好的 CC(install-runner.ts:93-98、utils/userEnv.ts:40, 75-89);Windows 另有ensureWindowsNpmGlobalBinInPath()处理%APPDATA%\npm(userEnv.ts:91-99); - 验证:安装后强制重新 probe,
status !== 'available'则返回not-detected-after-install错误(dependency-manager.ts:186-211); - 远程: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.md、cli-reference.md、troubleshoot-install.md - CC 重构源:
src_2026-03-31/utils/nativeInstaller/{installer,download,packageManagers}.ts、commands/install.tsx、utils/xdg.ts - Codex 源(b89ce9a):
codex-cli/bin/codex.js、codex-cli/package.json、codex-rs/install-context/src/lib.rs、codex-rs/cli/src/main.rs(LoginCommand)、codex/docs/install.md - Yoda 源:
src/main/core/dependencies/install-runner.ts、src/main/utils/userEnv.ts、src/shared/runtime-registry.ts