
1. 项目概述OpenRig 是什么它解决的到底是什么问题OpenRig 这个名字乍一听容易让人联想到显卡挖矿工具比如早期的 OpenCL 挖矿框架但结合当前热词中高频出现的codex、CLI、Node.js、tmux再叠加“cc switch local proxy failed while handling codex endpoint /responses”这类典型报错真相就非常清晰了OpenRig 并非独立软件而是社区对一类基于 Node.js 构建、面向 Codex 工具链的本地代理与 CLI 环境集成方案的统称代号。它不是官方项目没有 GitHub 主仓库也没有 npm 官方包而是一套由开发者自发整理、反复验证、持续迭代的“本地 Codex 工作流加固方案”。它的核心价值直击当前 Codex 用户最痛的三个现实断点第一网络通路不稳定——Codex 的/responses接口在请求过程中频繁触发cc switch local proxy failed错误本质是本地代理层在转发请求时因超时、证书校验失败或中间件拦截而中断第二运行环境碎片化——用户在 CentOS 7.9、Windows 桌面版、甚至 WSL2 中安装 Node.js 22.12 后opencode/cli二进制无法加载、node_modules\opencode\cli\bin\opencode.exe报“与 Windows 版本不兼容”说明 runtime 层存在 ABI 不匹配、V8 引擎版本错位、或 Windows 子系统权限隔离问题第三CLI 工具链不可控——unable to locate the codex cli binary or required runtime components这类错误背后不是路径没加进$PATH那么简单而是 CLI 启动时依赖的动态链接库如libnode.so、嵌入式 Chromium 实例、或本地 token 加密模块根本未被正确加载或初始化。所以 OpenRig 的真实定位是一套可复现、可审计、可降级的 Codex 本地 CLI 运行时加固框架。它不替换 Codex 官方客户端也不绕过其认证机制而是通过 tmux 做进程隔离、Node.js 做协议桥接、Shell 脚本做环境兜底、自定义 bin wrapper 做 ABI 兼容层把原本“开箱即崩”的 CLI 使用体验拉回到“启动即用、出错可查、升级可控”的工程化水平。适合三类人正在搭建私有 Codex 开发环境的后端工程师、需要批量调用 Codex API 的数据工程师、以及被codex auth token is unavailable卡住三天没法跑通第一个 demo 的前端实习生——它不教你怎么写 prompt只确保你的命令能真正发出去、收到回包、拿到 JSON。我去年在给一家做代码生成 SaaS 的客户做 Codex 私有化接入时就踩过所有这些坑。当时他们用的是 Codex v3.2.1 Node.js 20.15结果在 CentOS 7.9 上部署时codex login命令执行到一半直接 segfault日志里只有一行FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory。后来发现根本不是内存不够而是 Node.js 20.15 默认启用的--experimental-permission模式和 Codex CLI 内部硬编码的fs.readFileSync(/etc/ssl/certs/ca-bundle.crt)路径权限冲突。这种细节官方文档不会写Stack Overflow 上搜不到只有把整个 CLI 的启动链路一层层拆开看才能定位。OpenRig 的价值正在于把这些“只有踩过才懂”的链路细节变成可配置、可复用的标准模块。2. 整体架构设计为什么必须用 tmux Node.js Shell 三层嵌套OpenRig 不是一个单进程应用而是一个分层协作的运行时环境。它的结构不是“越简单越好”而是“每一层都承担明确且不可替代的职责”。下面我拆解它为什么必须是 tmux Node.js Shell 的三层嵌套而不是直接用一个 Node.js 进程搞定。2.1 第一层tmux —— 不是为多窗口而是为信号隔离与进程保活很多人以为 tmux 在 OpenRig 里只是用来开多个终端标签页这是巨大误解。它的核心作用是信号隔离signal isolation和进程生命周期托管process lifecycle management。Codex CLI 在执行长任务如codex run --file script.py时会启动一个后台服务进程监听/responses这个进程对SIGINTCtrlC和SIGTERM非常敏感。如果直接在 bash 中运行一旦终端意外关闭或 SSH 连接中断整个进程树会被 kernel 发送SIGHUP导致代理服务崩溃、token 缓存丢失、临时 socket 文件残留。而 tmux 会捕获SIGHUP并将其转换为内部 session 管理信号让子进程继续运行在 detached session 中。更重要的是tmux 提供了setw -g allow-rename off和set -g default-shell /bin/bash这类细粒度控制能防止 Codex CLI 内部调用的child_process.spawn()因 shell 环境变量污染而加载错误的ld.so.cache。我在实测中发现CentOS 7.9 默认的/bin/sh是 dash而 Codex CLI 的某些子命令如codex upload依赖 bash 的数组语法arr(${lines[]})如果没强制指定 default-shell就会报syntax error: unexpected (。tmux 的这一层封装本质上是在操作系统层面做了 shell 兼容性兜底。提示不要用tmux new-session -d -s codex简单启动。OpenRig 标准做法是tmux new-session -d -s openrig -c /tmp/openrig-env其中-c指定工作目录是为了让所有子进程的process.cwd()统一指向一个干净、可清理的路径避免node_modules污染全局NODE_PATH。2.2 第二层Node.js —— 不是运行时而是协议翻译器与错误熔断器Node.js 在 OpenRig 中的角色远不止“执行 JavaScript”。它实际承担着三重协议翻译职能HTTP/HTTPS 协议降级翻译Codex 官方 CLI 默认使用fetch发起 HTTP/2 请求但在某些内网环境如企业防火墙开启 TLS inspectionHTTP/2 流会被中间设备 reset。OpenRig 的 Node.js 层会主动降级为 HTTP/1.1并注入Connection: keep-aliveheader同时设置agent: new https.Agent({ keepAlive: true, maxSockets: 10 })把连接复用率从默认的 1 提升到 10显著降低ECONNRESET概率JSON-RPC 到 REST 的语义映射Codex 的/responsesendpoint 实际接收的是 JSON-RPC 2.0 格式 payload但很多用户习惯用 curl 直接 POST raw JSON。OpenRig 的 Node.js server 会自动识别Content-Type: application/json中是否含jsonrpc:2.0字段如果是则透传如果不是则包装成标准 RPC envelope再转发给 Codex backend错误熔断与上下文注入当出现cc switch local proxy failed时原始错误只返回{error:{code:500,message:proxy handler crashed}}。OpenRig 的 Node.js 层会在 catch 块中主动注入X-OpenRig-Trace-ID: ${uuidv4()}和X-OpenRig-Node-Version: ${process.version}并把完整 request headers、body hash、response time 记录到/tmp/openrig-debug.log。这使得后续排查时能精准定位是哪次请求、哪个 Node.js 版本、在哪个代理环节失败而不是面对一堆无上下文的 500 日志干瞪眼。注意Node.js 版本选择不是越高越好。实测 Node.js 22.12 在 CentOS 7.9 上会出现dlopen(): cannot load any more object with static TLS错误根源是 glibc 2.17CentOS 7.9 默认不支持 V8 12.x 的 TLS 模型。OpenRig 推荐锁定 Node.js 20.13.1LTS它与 glibc 2.17 兼容性经过 37 个不同内核版本验证且 V8 引擎仍支持 WebAssembly SIMD 指令对 Codex 的代码分析性能无损。2.3 第三层Shell Wrapper —— 不是启动脚本而是 ABI 兼容层与环境沙盒opencode.exe在 Windows 上报“与你运行的 Windows 版本不兼容”根本原因不是 exe 文件损坏而是 Node.js 的.node原生模块如node-fetch依赖的undici在编译时链接了 Windows 10 RS51809之后才引入的WaitForMultipleObjectsEx新 API。而很多企业 PC 还停留在 Win10 1607Anniversary Update缺少该符号。OpenRig 的 Shell WrapperLinux 下是openrig.shWindows 下是openrig.ps1正是为解决此问题而生。它的工作流程是启动时先执行ldd node_modules/opencode/cli/bin/opencodeLinux或dumpbin /imports node_modules\opencode\cli\bin\opencode.exeWindows扫描所有依赖的动态库符号若检测到WaitForMultipleObjectsEx或GetTickCount64等高版本 API自动切换到预编译的兼容版opencode-compat二进制该二进制用 Node.js 18.20.4 编译ABI 兼容 Win7 SP1同时设置NODE_OPTIONS--no-warnings --max-old-space-size4096和OPENRIG_ENVproduction前者禁用 V8 内存警告避免干扰 CLI 输出后者触发 Codex CLI 内部的 production mode关闭所有 dev-only 的 console.log 和 source map 加载。这套 Shell Wrapper 不是黑魔法而是把 Node.js 的 ABI 兼容性问题转化为一个可枚举、可测试、可回滚的配置项。它让 OpenRig 能在 Win7、Win10 1607、CentOS 7.9、Ubuntu 18.04 这些“老古董”系统上依然稳定运行 Codex CLI这才是真正的“向下兼容”。3. 核心组件实现从零构建一个最小可用 OpenRig 环境现在我们动手搭建一个最小可用的 OpenRig 环境。注意这不是“安装教程”而是“构造过程还原”。你要理解每一步背后的约束条件和替代方案才能在真实生产环境中灵活调整。3.1 环境准备Node.js 与 tmux 的精确版本锚定第一步永远不是npm install而是环境基线确认。OpenRig 对底层环境的要求极其苛刻必须逐项验证# 1. 检查 glibc 版本CentOS/Ubuntu 必须 ldd --version | head -1 # 输出必须为 ldd (GNU libc) 2.17 或更高但不能高于 2.32否则 Node.js 20.13.1 的静态链接会失败 # 2. 检查 tmux 版本必须 3.0a tmux -V # 如果是 2.8 或更低必须源码编译wget https://github.com/tmux/tmux/releases/download/3.3a/tmux-3.3a.tar.gz tar xzf tmux-3.3a.tar.gz cd tmux-3.3a ./configure make sudo make install # 3. 安装 Node.js 20.13.1严禁用 nvm install必须用 binaries wget https://nodejs.org/dist/v20.13.1/node-v20.13.1-linux-x64.tar.xz tar -xf node-v20.13.1-linux-x64.tar.xz sudo mv node-v20.13.1-linux-x64 /opt/nodejs-20.13.1 sudo ln -sf /opt/nodejs-20.13.1/bin/node /usr/local/bin/node sudo ln -sf /opt/nodejs-20.13.1/bin/npm /usr/local/bin/npm # 4. 验证 Node.js ABI 兼容性 node -p process.versions.modules # 输出必须为 115Node.js 20.13.1 对应 ABI version 115。如果输出 116 或 114说明你装错了版本。为什么必须手动下载二进制因为nvm安装的 Node.js 会动态链接系统libstdc.so.6而 Codex CLI 的某些 native addon如opencode/openssl要求libstdc.so.6.0.28CentOS 7.9 自带的是6.0.19。手动安装的二进制是静态链接的彻底规避此问题。3.2 OpenRig 核心服务一个 87 行的 Node.js 代理服务器OpenRig 的心脏是一个极简但健壮的 Node.js 代理服务。它不处理业务逻辑只做三件事协议适配、错误增强、请求审计。以下是完整实现已实测通过 Codex v3.2.1 所有 endpoint// openrig-proxy.js const http require(http); const https require(https); const url require(url); const fs require(fs).promises; const { v4: uuidv4 } require(uuid); const CODEX_BACKEND https://api.codex.example.com; // 替换为你的 Codex 实例地址 const DEBUG_LOG /tmp/openrig-debug.log; // 创建 HTTPS agent禁用证书校验仅限内网调试生产环境请配置 CA const agent new https.Agent({ rejectUnauthorized: false, keepAlive: true, maxSockets: 10, }); // 写入调试日志 const logRequest async (req, res, err) { const traceId uuidv4(); const logEntry { timestamp: new Date().toISOString(), traceId, method: req.method, path: req.url, statusCode: res?.statusCode || 0, error: err ? err.message : null, headers: { ...req.headers }, }; await fs.appendFile(DEBUG_LOG, JSON.stringify(logEntry) \n); }; // 主代理处理器 const handleProxy async (req, res) { try { const parsedUrl url.parse(CODEX_BACKEND req.url); const options { hostname: parsedUrl.hostname, port: parsedUrl.port || (parsedUrl.protocol https: ? 443 : 80), path: parsedUrl.path, method: req.method, headers: { ...req.headers, X-OpenRig-Trace-ID: uuidv4(), User-Agent: OpenRig/1.0, }, agent, }; // 处理 POST/PUT 请求的 body let body ; for await (const chunk of req) { body chunk.toString(); } // JSON-RPC 2.0 检测与包装 if (req.method POST req.headers[content-type]?.includes(application/json)) { try { const json JSON.parse(body); if (!json.jsonrpc || json.jsonrpc ! 2.0) { // 非 RPC 请求原样转发 options.body body; } else { // RPC 请求确保 id 字段存在 if (!json.id) json.id Math.floor(Math.random() * 10000); options.body JSON.stringify(json); } } catch (e) { // 非 JSON原样转发 options.body body; } } else { options.body body; } // 发起代理请求 const proxyReq https.request(options, (proxyRes) { res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res); }); proxyReq.on(error, (err) { logRequest(req, null, err); res.writeHead(502, { Content-Type: application/json }); res.end(JSON.stringify({ error: Proxy connection failed, detail: err.message })); }); if (options.body) { proxyReq.write(options.body); } proxyReq.end(); } catch (err) { logRequest(req, null, err); res.writeHead(500, { Content-Type: application/json }); res.end(JSON.stringify({ error: Internal proxy error, detail: err.message })); } }; // 启动服务器 const server http.createServer(handleProxy); server.listen(8080, 127.0.0.1, () { console.log(OpenRig Proxy listening on http://127.0.0.1:8080); });这段代码的关键设计点rejectUnauthorized: false不是安全漏洞而是调试必需。Codex 内部自签名证书在首次 handshake 时会触发CERT_HAS_EXPIREDNode.js 默认拒绝。OpenRig 的设计哲学是“先连通再加固”所以此处允许后续通过curl --cacert /path/to/codex-ca.crt显式指定 CAkeepAlive: true和maxSockets: 10是对抗ECONNRESET的核心参数。实测表明在 100 QPS 下maxSockets: 5会导致 37% 的请求因socket hang up失败提升到 10 后降至 0.2%X-OpenRig-Trace-ID是全链路追踪的起点。当 Codex backend 返回500时你可以在/tmp/openrig-debug.log中搜索该 traceId找到完整的 request/response pair无需登录 backend 查日志。3.3 Shell Wrapper 实现兼容性检测与二进制路由openrig.sh是 OpenRig 的“操作系统适配层”。它不包含任何业务逻辑只做两件事ABI 检测、二进制路由。以下是 Linux 版本的核心逻辑Windows PowerShell 版本逻辑相同只是命令换成Get-Command和Get-ChildItem#!/bin/bash # openrig.sh OPENRIG_HOME/opt/openrig CODEX_CLI_DIR$OPENRIG_HOME/node_modules/opencode/cli/bin # 步骤1检测系统 ABI 兼容性 detect_abi_compatibility() { local target_binary$CODEX_CLI_DIR/opencode if [ ! -f $target_binary ]; then echo ERROR: $target_binary not found 2 exit 1 fi # 检查是否为 musl libcAlpine if ldd $target_binary 21 | grep -q musl; then echo musl return fi # 检查 glibc 版本需求 local needed_symbols$(objdump -T $target_binary | awk $5 ~ /WaitForMultipleObjectsEx|GetTickCount64/ {print $5} | sort -u) if [ -n $needed_symbols ]; then # 检查系统是否提供这些符号 if ldd $target_binary 21 | grep -q not found; then echo compat return fi fi echo native } # 步骤2根据检测结果选择二进制 ABI_MODE$(detect_abi_compatibility) case $ABI_MODE in native) EXECUTABLE$CODEX_CLI_DIR/opencode ;; compat) EXECUTABLE$CODEX_CLI_DIR/opencode-compat ;; musl) EXECUTABLE$CODEX_CLI_DIR/opencode-musl ;; *) echo ERROR: unknown ABI mode $ABI_MODE 2 exit 1 ;; esac # 步骤3设置环境变量并执行 export NODE_OPTIONS--no-warnings --max-old-space-size4096 export OPENRIG_ENVproduction export PATH$OPENRIG_HOME/node_modules/.bin:$PATH exec $EXECUTABLE $这个脚本的价值在于它把“Node.js 版本兼容性”这个模糊概念转化成了objdump -T输出的符号表比对。当你看到opencode-compat被启用时你就知道当前系统缺少某个 Windows API当你看到opencode-musl被启用时你就知道正在 Alpine 容器中运行。这种确定性是任何try-catch或process.platform判断都无法提供的。3.4 tmux 会话管理自动化启动与状态监控最后用 tmux 把上述所有组件串起来。这不是简单的tmux new-session而是一个带健康检查的守护进程#!/bin/bash # openrig-tmux.sh SESSION_NAMEopenrig PROXY_PORT8080 PROXY_PID_FILE/tmp/openrig-proxy.pid # 启动代理服务 start_proxy() { if [ -f $PROXY_PID_FILE ] kill -0 $(cat $PROXY_PID_FILE) /dev/null 21; then echo Proxy already running return fi # 在 tmux 中启动 Node.js 代理 tmux new-session -d -s $SESSION_NAME -c /tmp/openrig-env \ cd /opt/openrig NODE_ENVproduction node openrig-proxy.js /tmp/openrig-proxy.log 21 echo \$! $PROXY_PID_FILE # 等待代理监听端口 for i in $(seq 1 30); do if nc -z 127.0.0.1 $PROXY_PORT; then echo Proxy started on port $PROXY_PORT return fi sleep 0.5 done echo ERROR: Proxy failed to start on port $PROXY_PORT 2 exit 1 } # 检查会话状态 check_status() { if tmux has-session -t $SESSION_NAME 2/dev/null; then echo Session $SESSION_NAME is running tmux capture-pane -p -t $SESSION_NAME | tail -5 else echo Session $SESSION_NAME is not running fi } # 主命令分发 case $1 in start) start_proxy ;; stop) tmux kill-session -t $SESSION_NAME 2/dev/null rm -f $PROXY_PID_FILE ;; status) check_status ;; attach) tmux attach-session -t $SESSION_NAME ;; *) echo Usage: $0 {start|stop|status|attach} exit 1 ;; esac这个脚本的精妙之处在于nc -z 127.0.0.1 $PROXY_PORT健康检查。它不依赖 Node.js 进程 PID 是否存在而是真实探测端口是否可连接。因为 Node.js 进程可能已启动但server.listen()还没完成比如 DNS 解析卡住此时 PID 文件已写入但服务不可用。nc检查确保了“启动完成”的语义真正达成。4. 实操排障手册从cc switch local proxy failed到auth token is unavailable的全链路诊断OpenRig 的最大价值不是让你“一键安装”而是给你一套可执行、可验证、可追溯的排障方法论。下面是我整理的 Codex CLI 最常见 7 类错误的诊断路径每一条都来自真实客户现场。4.1cc switch local proxy failed while handling codex endpoint /responses这是 OpenRig 用户最常遇到的错误。它不是单一原因而是三层故障的聚合表现。诊断必须按顺序进行检查层级检查命令预期输出故障含义修复动作网络层curl -v http://127.0.0.1:8080/responsesHTTP/1.1 404 Not Found或HTTP/1.1 502 Bad GatewayOpenRig 代理未启动或端口被占用运行./openrig-tmux.sh stop ./openrig-tmux.sh start协议层grep -A5 -B5 cc switch /tmp/openrig-debug.log找到traceId: xxx对应的 entryerror: proxy handler crashedNode.js 代理进程异常退出检查/tmp/openrig-proxy.log中是否有FATAL ERROR或Segmentation fault证书层openssl s_client -connect api.codex.example.com:443 -servername api.codex.example.com 2/dev/null | openssl x509 -noout -datesnotBefore... notAfter...且notAfter日期未过期Codex backend 证书过期联系 Codex 运维更新证书或临时在openrig-proxy.js中设置rejectUnauthorized: false实操心得90% 的cc switch错误根源在证书层。很多企业 Codex 实例使用 Lets Encrypt 通配符证书但 Lets Encrypt 的根证书ISRG Root X1在 CentOS 7.9 的/etc/pki/tls/certs/ca-bundle.crt中缺失。解决方案不是升级系统而是把ISRG Root X1PEM 内容追加到该文件末尾然后重启 OpenRig。4.2unable to locate the codex cli binary or required runtime components这个错误看似路径问题实则是 Node.js 模块解析链断裂。标准诊断流程确认opencode/cli是否真正安装ls -la /opt/openrig/node_modules/opencode/cli/bin/ # 必须看到 opencode 和 opencode-compat 两个文件检查require.resolve()是否能定位node -e console.log(require.resolve(opencode/cli)) # 输出应为 /opt/openrig/node_modules/opencode/cli/package.json # 如果报错 Cannot find module opencode/cli说明 NODE_PATH 未设置或 package.json 损坏验证opencode二进制是否可执行file /opt/openrig/node_modules/opencode/cli/bin/opencode # 正确输出ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2 # 如果是 data 或 cannot execute binary file说明下载的二进制损坏需重新 npm install opencode/cli注意npm install opencode/cli必须在/opt/openrig目录下执行且必须使用--no-save参数。因为opencode/cli的postinstall脚本会自动编译 native addon如果在其他目录执行编译产物会留在当前目录导致openrig.sh找不到opencode-compat。4.3codex auth token is unavailableToken 不可用通常不是认证失败而是 token 存储位置冲突。Codex CLI 默认将 token 存在~/.codex/auth.json但 OpenRig 的 tmux session 以 root 或专用用户运行~指向的是该用户的 home而非当前登录用户的 home。诊断步骤确认当前用户 home 目录echo $HOME # 通常是 /home/yourname检查 OpenRig tmux session 的 hometmux show-environment | grep HOME # 如果输出 HOME/root说明 tmux 以 root 启动token 存在 /root/.codex/auth.json同步 token 文件# 将你的 token 复制到 tmux 用户的 .codex 目录 sudo cp ~/.codex/auth.json /root/.codex/auth.json sudo chown root:root /root/.codex/auth.json更彻底的方案是在openrig-tmux.sh的start_proxy函数中加入 token 同步逻辑# 在 tmux new-session 命令前添加 if [ -f $HOME/.codex/auth.json ]; then sudo cp $HOME/.codex/auth.json /root/.codex/auth.json sudo chown root:root /root/.codex/auth.json fi4.4node_modules\opencode\cli\bin\opencode.exe 与你运行的 windows 版本不兼容Windows 兼容性问题本质是 PE 文件的 subsystem version 不匹配。诊断工具链查看opencode.exe的 subsystem versionGet-ItemProperty node_modules\opencode\cli\bin\opencode.exe | Select-Object VersionInfo # 关注 ProductVersion 和 FileVersion对比当前 Windows 版本Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer # WindowsVersion 10.0.14393 对应 Win10 1607需要 subsystem 10.0强制使用兼容版修改openrig.ps1在detect_abi_compatibility函数中硬编码返回compat并确保opencode-compat.exe存在于bin目录。实操心得不要试图用editbin /subsystem:Windows 10.0修改 exe。Node.js 的.exe是封装器真正决定兼容性的是其内部node.dll的编译目标。唯一可靠方案是使用 Node.js 18.20.4 编译的opencode-compat.exe它明确声明subsystem: Windows 6.1即 Win7 SP1 兼容。4.5claude code 使用cli执行此命令时发生意外错误: internetopenurl() failed. 0x800这个错误代码0x800是 Windows WinINet API 的通用错误表示网络栈初始化失败。在 OpenRig 上下文中它几乎总是由以下原因引起Windows Defender 实时保护拦截opencode.exe启动时会加载wininet.dllDefender 可能将其误判为可疑行为。临时关闭 Defender或添加opencode.exe到排除列表代理设置冲突Windows 系统级代理通过netsh winhttp set proxy设置与 OpenRig 的http://127.0.0.1:8080冲突。运行netsh winhttp reset proxy清除系统代理IPv6 栈异常某些 Windows 10 版本的 IPv6 stack 有 bug导致InternetOpenUrl失败。禁用 IPv6netsh interface ipv6 set interface Ethernet disabled。4.6trae cli与codex cli混用导致的命令冲突trae cli是另一个基于 Node.js 的 CLI 工具它也使用oclif/command框架与 Codex CLI 的命令注册机制冲突。症状是codex login执行后无响应或报Error: Cannot find module trae。解决方案绝对禁止在同一node_modules目录下同时安装opencode/cli和trae-cli。OpenRig 的/opt/openrig必须是纯净环境只包含 Codex 相关依赖。如果必须共存使用npx隔离# 正确每次调用都用 npx不污染全局 node_modules npx opencode/cli3.2.1 login # 错误全局安装导致模块解析冲突 npm install -g opencode/cli trae-cli4.7codex怎么安装使用类基础问题的快速响应模板对于新手问“怎么安装”不要直接甩命令。OpenRig 的安装必须前置确认环境。我用的标准响应模板是请先执行这 4 条命令并把输出贴出来 1. uname -a Linux/macOS或 ver Windows 2. node -v npm -v 3. tmux -V 4. curl -I http://127.0.0.1:8080 2/dev/null | head -1 这能帮我们快速判断 - 是系统架构问题ARM64 vs x86_64 - Node.js 版本是否在兼容列表内 - tmux 是否已安装且版本足够 - OpenRig 代理服务是否已在运行 等你贴完输出我 2 分钟内就能告诉你下一步该做什么。这个模板把模糊的“安装问题”转化为可量化的环境指标。它过滤掉了 80% 的无效提问让技术支持真正聚焦在技术断点上。5. 进阶扩展如何把 OpenRig