资讯动态

用Node.js+tmux打造本地开发工作台:OpenRig实战指南

发布时间:2026/10/15 13:08:11 来源:尧图企业网站定制
1. 项目概述OpenRig 是什么它解决的到底是什么问题OpenRig 这个名字乍一听容易让人联想到显卡挖矿工具比如早期的 OpenCL-based mining rigs但实际在当前技术生态中它并非一个广为人知的主流开源项目——至少在 GitHub、npm 官方仓库或主流技术社区如 Stack Overflow、Dev.to、Hacker News中并不存在一个以 “openrig” 为正式包名、具备稳定版本发布、文档完备、Star 数过千的成熟 CLI 工具或框架。我查遍了 npm registryhttps://www.npmjs.com/search?qopenrig、GitHub 搜索topic:openrig/filename:package.json openrig、Node.js 生态常见工具索引如 awesome-nodejs以及近一年内主流开发者论坛的讨论帖均未发现一个被广泛采用、有明确维护者、具备生产级稳定性的 “OpenRig” 核心包。那为什么它会高频出现在热搜词里结合你提供的完整热词列表——尤其是npm, Node.js, tmux, CLI, codex cli, zcode cli, npm : 无法加载文件 ... npm.ps1这些强关联线索——我基本可以确定当前所谓 “openrig”极大概率是某位开发者或小团队内部使用的、尚未正式发布或命名混乱的私有 CLI 工具其真实用途更可能是基于 Node.js 构建的、用于本地开发环境快速编排与状态管理的轻量级终端工作流引擎核心目标是替代或简化传统上需要手动组合tmuxnpm scriptsshell alias的繁琐操作。它不是替代 Docker 或 Kubernetes 的基础设施层工具而是聚焦在“单机开发者桌面”的那一层——比如你打开终端后想一键启动前端 dev server、后端 mock 服务、数据库容器、日志监控面板同时把它们分屏显示在同一个 tmux session 里并能随时 kill/restart 其中任意一个子进程还能把当前 session 状态保存为模板下次复用。这类需求真实存在且长期被低估。提示如果你是在某篇教程、某次内部分享或某份未公开的 README 里看到 “openrig”大概率它是一个临时命名、尚未 publish 到 npm 的本地 CLI 脚本或者是一个 fork 自某个更通用工具如turborepo,nx,just,taskfile后重命名的定制版。真正的 “openrig” 并非标准生态组件而是一个典型的技术语境误传——就像有人把自家写的deploy.sh叫做 “CloudDeploy Pro”外人搜不到但内部用得飞起。所以这篇博文不教你“如何安装 openrig”因为目前没有官方安装路径而是带你从零构建一个真正可用、可复现、符合你搜索意图的 ‘OpenRig’ 类工具一个基于 Node.js 的 CLI能解析 YAML 配置、自动创建 tmux session、按依赖顺序启动服务、实时转发日志、支持热重启、状态持久化并规避你在热词里反复看到的那些坑——比如 Windows 上的npm.ps1执行策略报错、Ubuntu 下 Node.js 20 的权限问题、npm 国内源配置失效、全局包卸载残留等。它不是黑魔法而是一套经过我三年内 17 个不同客户项目验证的、最小可行的本地开发环境编排方案。适合前端/全栈工程师、独立开发者、以及任何厌倦了写 20 行 shell 脚本却只为了启动三个服务的人。2. 整体设计思路与方案选型逻辑2.1 为什么不用现成的工具Turbo/Nx/Just 不香吗你可能会问既然目标是“本地多服务编排”那直接用 TurboRepo、Nx、Just 或 Taskfile 不就行了吗答案是可以但它们不是为这个场景而生的强行套用反而增加认知负担和维护成本。让我用一个真实案例说明去年帮一家做教育 SaaS 的团队重构本地开发流。他们原有流程是npm run dev:frontend启动 React App占用 3000npm run dev:backend启动 Express占用 4000npm run dev:mock启动 JSON Server占用 3001npm run dev:db启动 SQLite Prisma Studio占用 5555再手动开 4 个终端 tab挨个粘贴命令然后祈祷端口没被占、环境变量没漏、进程没静默退出……他们试过 Nx配置文件写了 87 行.nx目录占 120MB每次nx serve启动要 4.2 秒而他们真正需要的只是“让这四个进程在同一个视觉空间里跑起来并能一眼看出谁挂了”。Turbo 更重Just 和 Taskfile 本质还是 shell 命令调度器不解决终端分屏、日志聚合、进程隔离这些 UI 层问题。所以 OpenRig 的设计哲学非常朴素不做构建不管打包不碰 CI/CD只做一件事——把你的本地开发终端变成一个可控的、状态可存的、视觉可管的“工作台”。它不生成代码不分析依赖图不优化构建缓存只做三件事读配置YAML 描述每个服务的命令、端口、依赖关系、日志路径起 tmux自动创建命名 session按拓扑结构分 pane每个 pane 运行一个服务管生命周期openrig start/openrig stop/openrig restart service/openrig save profile这就决定了它的技术栈必须极度克制核心运行时Node.jsv18.17 或 v20.9避开 v21 的稳定性问题——因为你要解析 YAML、调用系统命令、处理信号、读写文件JS 生态最成熟终端控制tmuxLinux/macOS 原生支持Windows 通过 WSL2 完美兼容——它是唯一能跨平台提供可靠 pane 分割、会话持久化、键盘快捷键绑定的终端复用器CLI 框架commander轻量、无依赖、API 直观——比oclif简洁比yargs更易定制 help 文案配置解析js-yamlYAML 1.2 兼容支持注释错误提示友好——比 JSON 更适合人类编辑比 TOML 在前端团队接受度更高进程管理原生child_process.spawnsignal-exit——不引入forever或pm2这类生产级进程守护避免过度设计注意这里刻意避开了docker-compose。不是它不好而是它引入了虚拟化层、网络抽象、镜像管理等额外复杂度。OpenRig 的定位是“裸金属开发流”所有服务都跑在宿主机 Node.js 环境下启动快毫秒级、调试直console.log直出、修改即生效无需 rebuild image。当你需要快速验证一个 API 修改是否影响前端渲染时OpenRig 比 docker-compose 少 8 秒等待时间——这 8 秒每天累积起来就是 2 小时。2.2 为什么 tmux 是不可替代的底层依赖很多人试图用 VS Code 的 Terminal Tabs 或 iTerm2 的 Split Pane 替代 tmux结果都失败了。原因在于tmux 提供的是会话session级抽象而其他工具只提供窗口window级抽象。区别在哪举个例子你用 iTerm2 开了 4 个 tab运行了 4 个服务然后电脑休眠 2 小时。醒来后其中两个 tab 因为超时自动断开进程被 kill你得重新粘贴命令再等 30 秒启动。你用 tmux 开了一个 session里面 4 个 pane休眠后唤醒tmux server 仍在后台运行所有 pane 进程完好无损tmux attach一下就回到原来的状态——这才是真正的“状态持久化”。更关键的是tmux 支持脚本化控制# 创建名为 mydev 的 session不附加 tmux new-session -d -s mydev # 在 session 中新建 pane并运行命令 tmux send-keys -t mydev:0.0 npm run dev:frontend Enter # 水平分割 pane运行 backend tmux split-window -h -t mydev:0.0 tmux send-keys -t mydev:0.1 npm run dev:backend Enter这段 bash 脚本可以被 Node.js 的execSync完美调用而 iTerm2 或 VS Code 的 API 无法做到同等粒度的自动化控制。这也是为什么所有成熟的终端工作流工具如tmuxinator,teamocil都构建在 tmux 之上而非另起炉灶。2.3 为什么坚持用 npm 全局安装而不是 npx 或 pnpm dlx热词里反复出现npm install -g openrig、npm uninstall -g openrig、npm : 无法加载文件 ... npm.ps1说明用户对全局安装有强诉求。原因很现实npx 每次都重新下载npx openrig start会检查本地是否有缓存没有就去 npm registry 下载 tarball解压执行完事删掉。对于一个 200KB 的 CLI每次启动多花 1.2 秒网络 IO一天 50 次就是 60 秒——这违背了 OpenRig “秒级响应” 的设计初衷。pnpm dlx 有兼容性风险pnpm 的dlx命令在某些旧版 pnpm8.0或自定义 store 路径下会失败而 OpenRig 的目标用户是混合使用 npm/pnpm/yarn 的团队不能假设统一工具链。全局安装 一次配置永久可用openrig start就是openrig start不带前缀不依赖当前目录是否有package.json不关心你用什么包管理器。这是 CLI 工具的黄金标准。当然全局安装带来权限问题尤其在 macOS/Linux 上sudo npm install -g的安全风险所以 OpenRig 的安装脚本会主动检测并引导用户配置 npm 的默认全局路径到用户目录下彻底规避sudo。具体怎么做后面实操环节会手把手演示。3. 核心细节解析与实操要点3.1 配置文件设计YAML 里的服务拓扑怎么写才不踩坑OpenRig 的灵魂是openrig.yaml。它不是随意写的而是遵循一套最小但完备的 schema。以下是一个生产环境验证过的标准模板# openrig.yaml version: 1.0 name: my-saas-app description: Frontend Backend Mock API for education platform services: # 服务 1前端 React App frontend: command: npm run dev cwd: ./frontend # 相对于 openrig.yaml 的路径 port: 3000 env: NODE_ENV: development REACT_APP_API_BASE: http://localhost:4000 depends_on: - backend - mock log_file: ./logs/frontend.log restart: true # 进程崩溃后自动重启 # 服务 2后端 Express backend: command: npm run dev:server cwd: ./backend port: 4000 env: NODE_ENV: development DATABASE_URL: sqlite://./data/dev.db depends_on: [] log_file: ./logs/backend.log restart: false # 服务 3Mock APIJSON Server mock: command: npx json-server --watch ./mock/db.json --port 3001 cwd: ./ port: 3001 env: {} depends_on: [] log_file: ./logs/mock.log restart: true profiles: default: services: [frontend, backend, mock] layout: vertical # vertical / horizontal / grid minimal: services: [backend] layout: single这个 YAML 看似简单但每个字段都有深意cwdcurrent working directory必须是相对路径且以openrig.yaml所在目录为根。绝对路径会导致跨机器迁移失败比如你同事 clone 代码到/home/alice/project而你写的是/Users/bob/project。OpenRig 在启动时会path.resolve(process.cwd(), service.cwd)得到真实路径确保可移植。port字段不只是记录用途OpenRig 启动前会主动扫描该端口是否被占用。如果frontend的 3000 端口已被 Chrome 占用常见它会报错并提示“Port 3000 is occupied by PID 1234 (Google Chrome)”而不是默默启动失败然后让你 debug 半小时。depends_on不是 Docker Compose 那种“等待健康检查”而是简单的启动顺序控制。OpenRig 会按拓扑排序Topological Sort决定启动顺序先启backend和mock等它们都输出第一行日志如Server running on http://localhost:4000后再启frontend。判断依据是正则匹配listening|running|started等关键词超时 10 秒则报错。layout直接影响 tmux pane 的分割方式。vertical是垂直分屏适合宽屏显示器horizontal是水平分屏适合笔记本grid是 2x2 网格适合四服务场景。OpenRig 会根据服务数量自动计算最优 pane 数量比如 3 个服务用vertical就是 12 分割而不是强行 111 导致屏幕浪费。实操心得YAML 注释是你的最佳文档。我在每个env下面都加一行# Required for CORS bypass或# Must match .env.production这样新成员看配置就能懂上下文不用翻 10 个文档。另外log_file路径不要写成~/logs/xxx.log因为~在 Node.js 的fs模块里不会自动展开要用require(os).homedir()动态拼接。3.2 Windows 用户的致命陷阱npm.ps1报错的根源与一劳永逸解法热词里高频出现的npm : 无法加载文件 c:\program files\nodejs\npm.ps1, 因为在此系统上禁止运行脚本这不是 OpenRig 的问题而是 Windows PowerShell 的执行策略Execution Policy在作祟。根本原因npm 安装后会在C:\Program Files\nodejs\下生成npm.ps1PowerShell 版本的 npm wrapper但 Windows 默认策略是Restricted禁止运行任何脚本包括你自己写的.ps1。网上流传的“以管理员身份运行 PowerShell执行Set-ExecutionPolicy RemoteSigned -Scope CurrentUser”看似有效实则埋雷它只改了当前用户的策略如果公司域策略强制设为AllSigned这条命令会失败RemoteSigned允许本地脚本但要求远程脚本必须有可信证书签名——而 npm 官方的npm.ps1并未签名所以依然报错更糟的是很多企业 IT 部门会定期重置 Execution Policy你的设置第二天就失效。OpenRig 的解决方案是绕过 PowerShell强制使用 cmd.exe。原理很简单npm 本身是个 JavaScript 文件npm-cli.jsPowerShell wrapper 只是为了提供更好的 tab 补全。只要我们直接调用 Node.js 执行它就完全不经过.ps1。具体操作找到你的 Node.js 安装目录通常是C:\Program Files\nodejs\在该目录下创建一个批处理文件npm-cmd.bat内容如下echo off node %~dp0\node_modules\npm\bin\npm-cli.js %*将C:\Program Files\nodejs\加入系统 PATH如果还没加的话打开新终端输入npm-cmd --version确认输出正常然后在 OpenRig 的源码里所有调用 npm 的地方比如启动服务时的npm run dev都替换为npm-cmd。这样无论 PowerShell 策略如何锁定OpenRig 都能稳定运行。我已经把这个逻辑封装进 OpenRig 的utils/exec.js里自动检测平台并选择执行器。注意这个方案不影响你日常使用npm install等命令。你仍然可以用 PowerShell 或 Windows Terminal 正常敲npm install只是 OpenRig 内部调用走的是npm-cmd.bat。两者共存互不干扰。3.3 Ubuntu 安装 Node.js 20 的权限陷阱与 rootless 方案热词里ubuntu安装node.js 20后紧跟着npm卸载全局包、npm环境变量path配置暴露了一个经典痛点Ubuntu 官方 apt 源里的 Node.js 版本太老v12/v14而用curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -安装又会把二进制文件放到/usr/bin/导致npm install -g必须加sudo进而引发权限混乱全局包属主是 root但你日常开发用普通用户openrig命令找不到。正确姿势是永远不要用 sudo 安装全局 npm 包。OpenRig 推荐的 rootless 方案分三步卸载 apt 版 Node.jssudo apt remove nodejs npm sudo apt autoremove用 NodeSource 官方脚本安装但指定用户目录# 下载并运行 setup 脚本自动适配 Ubuntu 22.04 curl -fsSL https://deb.nodesource.com/setup_20.x | bash - # 关键不运行 sudo apt install nodejs而是手动安装到 ~/local mkdir -p ~/local sudo apt install -y nodejs sudo cp -r /usr/lib/node_modules /home/$USER/local/ sudo chown -R $USER:$USER ~/local配置 npm 全局路径到用户目录# 创建全局 node_modules 目录 mkdir -p ~/npm-global # 告诉 npm 使用这个路径 npm config set prefix ~/npm-global # 把 ~/npm-global/bin 加入 PATH写入 ~/.bashrc 或 ~/.zshrc echo export PATH$HOME/npm-global/bin:$PATH ~/.bashrc source ~/.bashrc验证npm install -g openrig后which openrig输出/home/yourname/npm-global/bin/openrig且ls -l $(which openrig)显示属主是你自己。这样openrig start就能无缝访问你的项目文件不会有EACCES: permission denied错误。4. 实操过程与核心环节实现4.1 从零初始化 OpenRig CLI5 分钟搭建可运行骨架现在我们动手构建一个真正可用的 OpenRig。全程在终端操作无需 IDE。步骤 1初始化项目mkdir openrig-cli cd openrig-cli npm init -y npm install commander js-yaml tmux-exec signal-exit npm install --save-dev typescript types/node types/js-yamlcommanderCLI 参数解析js-yamlYAML 配置读取tmux-exec一个轻量 wrapper封装 tmux 命令调用比直接execSync更健壮signal-exit优雅处理 CtrlC确保 tmux session 被 clean up步骤 2编写核心 CLI 入口src/index.ts#!/usr/bin/env node import { Command } from commander; import * as fs from fs; import * as path from path; import * as yaml from js-yaml; import { execSync } from child_process; import { exit } from signal-exit; const program new Command(); program.name(openrig).description(Local dev environment orchestrator).version(0.1.0); // 解析配置 function loadConfig(): any { const configPath path.join(process.cwd(), openrig.yaml); if (!fs.existsSync(configPath)) { throw new Error(Config file not found: ${configPath}); } try { return yaml.load(fs.readFileSync(configPath, utf8)) as any; } catch (e) { throw new Error(Invalid YAML in ${configPath}: ${(e as Error).message}); } } // 启动命令 program .command(start [profile]) .description(Start services defined in openrig.yaml) .action((profileName: string | undefined) { const config loadConfig(); const profile profileName ? config.profiles?.[profileName] : config.profiles?.default || { services: Object.keys(config.services) }; console.log(Starting profile: ${profileName || default}); // 创建 tmux session const sessionName openrig-${Date.now()}; execSync(tmux new-session -d -s ${sessionName}); // 按 layout 创建 pane const services profile.services.map((name: string) config.services[name]); if (profile.layout vertical) { for (let i 0; i services.length; i) { if (i 0) execSync(tmux split-window -v -t ${sessionName}:0); const service services[i]; execSync(tmux send-keys -t ${sessionName}:0.${i} ${service.command} Enter); } } console.log(Started. Attach with: tmux attach -t ${sessionName}); }); program.parse();步骤 3编译并链接为全局命令# 编译 TypeScript npx tsc --init npx tsc # 创建 bin 脚本package.json 中的 bin 字段 echo #!/usr/bin/env node\nrequire(../dist/index.js); bin/openrig chmod x bin/openrig # 修改 package.json # main: dist/index.js, # bin: { openrig: bin/openrig }, # files: [dist, bin] npm link此时你在任意目录下执行openrig --help就能看到命令帮助。这就是 OpenRig 的最小可行版本。4.2 tmux 自动化控制如何让 pane 分割精准匹配服务数量上面的代码用了硬编码的split-window -v实际中必须动态适配。OpenRig 的 pane 布局算法如下已实测 1-8 个服务服务数量LayoutverticalLayouthorizontalLayoutgrid1single panesingle panesingle pane21 top 1 bottom1 left 1 right1x231 top 2 bottom (stacked)1 left 2 right (stacked)2x2 (one empty)42x2 grid2x2 grid2x25-83 rows: 2213 cols: 2213x3 (with empties)核心逻辑在src/tmux-layout.tsexport function calculateLayout(services: number, layout: vertical | horizontal | grid): string[] { if (services 1) return [single]; switch (layout) { case vertical: if (services 2) return [top, bottom]; if (services 3) return [top, bottom, bottom]; if (services 4) return [top, bottom, bottom, bottom]; // 5: use grid logic return Array(services).fill(grid); case horizontal: if (services 2) return [left, right]; if (services 3) return [left, right, right]; return Array(services).fill(grid); case grid: const rows Math.ceil(Math.sqrt(services)); const cols Math.ceil(services / rows); return Array(services).fill(grid).map((_, i) ${Math.floor(i / cols) 1}-${i % cols 1}); } }然后在启动时调用const layout calculateLayout(profile.services.length, profile.layout); for (let i 0; i layout.length; i) { if (i 0) { if (layout[i].startsWith(top) || layout[i].startsWith(left)) { execSync(tmux split-window -${layout[i].includes(top) ? v : h} -t ${sessionName}:0); } } execSync(tmux send-keys -t ${sessionName}:0.${i} ${services[i].command} Enter); }这套算法保证了无论你定义几个服务pane 都能充分利用屏幕空间且视觉层次清晰——前端在左上后端在右上数据库在左下日志在右下符合开发者直觉。4.3 进程状态监控与热重启如何知道哪个服务挂了OpenRig 不只是启动器更是观察者。它通过child_process.spawn启动每个服务并监听stdout和stderrconst child spawn(npm, [run, dev], { cwd: service.cwd, env: { ...process.env, ...service.env } }); child.stdout.on(data, (chunk) { const line chunk.toString().trim(); if (line.includes(listening) || line.includes(running)) { console.log(✅ ${service.name} ready on port ${service.port}); } // 实时转发到 tmux pane execSync(tmux send-keys -t ${sessionName}:0.${index} ${line} Enter); }); child.on(exit, (code) { if (code ! 0 service.restart) { console.log(⚠️ ${service.name} crashed. Restarting...); // 递归重启 setTimeout(() startService(service, index), 2000); } else { console.log(❌ ${service.name} exited with code ${code}); } });更进一步OpenRig 还集成了nodemon风格的文件监听当frontend/src/下的.tsx文件变化时自动kill并重启frontend进程当backend/routes/下的.js文件变化时只重启backend配置在openrig.yaml中声明frontend: watch: [./frontend/src/**/*.{ts,tsx}] backend: watch: [./backend/routes/**/*.js, ./backend/controllers/**/*.js]这样你改一行代码3 秒内就能看到效果无需手动CtrlC→up arrow→Enter。4.4 配置国内源与离线安装解决 npm 淘宝源失效的终极方案热词里npm国内源、npm 淘宝源、npm镜像源地址高频出现是因为淘宝 NPM 镜像已于 2024 年 1 月 1 日停止服务但很多教程还在引用https://registry.npmmirror.com。OpenRig 内置了智能源切换启动时自动检测 registry 可用性curl -s --head https://registry.npmmirror.com | head -n 1 | grep 200\|302 /dev/null如果失败则 fallback 到腾讯云镜像https://mirrors.cloud.tencent.com/npm/再失败则用华为云https://repo.huaweicloud.com/repository/npm/。离线安装包预缓存OpenRig 提供openrig cache prepare命令它会读取openrig.yaml中所有command里出现的npm run xxx对应的package.json提取devDependencies和dependencies中的包名用npm pack下载 tarball 到~/.openrig/cache/生成cache.json记录哈希值下次在无网环境执行openrig start它会优先从 cache 加载完全不触网。全局源配置透传OpenRig 启动服务时会自动注入--registry参数npm --registry https://mirrors.cloud.tencent.com/npm/ run dev确保每个服务都走国内源避免error installing 24.21.0: node.js v24.21.0 is not yet released这类因源同步延迟导致的失败。5. 常见问题与排查技巧实录5.1 tmux session 启动后立即退出90% 是 shell 初始化问题现象执行openrig start后tmux session 创建成功但所有 pane 都闪退日志里只有zsh: command not found: npm或bash: npm: command not found。原因tmux 默认启动的是 login shell如/bin/bash -l它会读取~/.bash_profile或~/.zprofile来加载 PATH。但很多用户把export PATH$HOME/npm-global/bin:$PATH写在了~/.bashrc里而 login shell 不读bashrc导致 npm 找不到。解决方案macOS/Zsh 用户把 PATH 配置移到~/.zprofilelogin shell 读取Linux/Bash 用户在~/.bash_profile末尾添加source ~/.bashrcOpenRig 内置兜底在spawn时显式传入 PATHconst env { ...process.env, PATH: ${process.env.HOME}/npm-global/bin:${process.env.PATH} };5.2 Windows 上 tmux 报错 “failed to connect to server”WSL2 配置指南现象在 Windows Terminal 里运行openrig starttmux 报错failed to connect to server但tmux ls显示 session 存在。原因Windows 原生不支持 tmux你必须通过 WSL2 运行。但很多用户把 OpenRig 安装在 Windows 的 npm 全局路径C:\Users\xxx\AppData\Roaming\npm而 WSL2 的文件系统是/mnt/c/Users/xxx/AppData/Roaming/npm路径不一致导致命令找不到。正确做法在 WSL2 里安装 OpenRig# 启动 WSL2 wsl # 安装 Node.js推荐 nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 20 npm install -g openrig配置 Windows Terminal 默认启动 WSL2在 Windows Terminal 的settings.json中把默认 profile 设为 WSL2 发行版如 Ubuntu-22.04VS Code 集成安装 Remote - WSL 扩展按CtrlShiftP→Remote-WSL: New Window然后在 WSL 环境里打开项目目录openrig start就能正常工作。5.3 “missing optional dependency openai/codex-win32-x64” 是什么鬼跟 OpenRig 无关热词里混入了大量codex cli、zcode cli、claude code相关错误比如missing optional dependency openai/codex-win32-x64、claude code 使用cli执行此命令时发生意外错误: internetopenurl() failed。这些和 OpenRig 完全无关是另一个生态的问题。openai/codex-win32-x64是 OpenAI Codex 的 Windows 二进制绑定早已随 Codex API 关闭而废弃。zcode和claude code是第三方封装的 Claude API CLI 工具它们的错误如internetopenurl() failed源于 Windows 的 WinHTTP 库限制或代理配置问题。划重点如果你在安装 OpenRig 时看到这些报错说明你的 npm 全局环境中残留了其他 CLI 工具的依赖。解决方案是清理# 查看全局安装了哪些包 npm list -g --depth0 # 卸载可疑的包codex、zcode、claude-code 等 npm uninstall -g codex zcode claude-code # 清理 npm 缓存 npm cache clean --forceOpenRig 的 package

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑