Openclaw本地部署指南:Node.js 20+环境搭建与Skill开发实战
发布时间:2026/7/10 23:01:15
分类:文化教育
浏览:1234

1. 项目概述Clawdbot 与 Openclaw 是什么为什么需要“部署”而不是“安装”Clawdbot 和 Openclaw 这两个名字在最近半年的技术社区里出现频率陡增但很多人第一次看到时会下意识以为是某个新出的聊天机器人App——点开官网、下载安装包、双击运行完事。我最初也这么想直到在本地跑第一条openclaw start命令时终端弹出一连串红色报错“command not found”、“node: command not found”、“git: command not found”才意识到这不是一个“装好就能用”的桌面软件而是一套基于 Node.js 构建的、面向开发者和高级用户的可扩展智能体Agent运行时框架。Clawdbot 是它的核心引擎代号Openclaw 是面向用户暴露的 CLI 工具与配置入口。它不提供图形界面不打包 Electron也不内置模型推理能力——它干的是更底层的事把 LLM 调用、工具编排、记忆管理、多步任务拆解、插件加载这些能力抽象成一套可声明、可调试、可嵌入的运行时协议。所以“部署教程”这个说法非常准确甚至比“安装方法”更本质。安装install只是把二进制或源码放到本地而部署deploy意味着你要为它准备好运行环境、配置好依赖链路、校准好路径与权限、验证好各模块间的通信状态并最终让它稳定地作为一个长期服务进程存在。这就像你不会说“部署一个微信”但你会说“部署一个 Nginx 反向代理”或“部署一个 Prometheus 监控栈”。Clawdbot/Openclaw 的定位就是那个需要你亲手搭好脚手架、拧紧每一颗螺丝的基础设施级组件。它解决的核心问题是当前大模型应用开发中普遍存在的“胶水代码黑洞”你写好了一个调用 Qwen 的函数又写了一个查天气的 API 封装再写了一个读取本地 Excel 的工具最后发现它们之间调用混乱、错误难追踪、状态无法持久、调试全靠 console.log。Openclaw 把这些都收束到一个统一的技能Skill注册机制下用 YAML 定义行为用 TypeScript 编写逻辑用openclaw run --skillweather这样的命令驱动执行。它不替代你的业务代码而是让你的业务代码变得可组合、可复用、可版本化。这也是为什么所有热词里反复出现 “dify本地部署教程”“ollama本地部署教程”——大家正在从“用现成AI产品”转向“搭自己的AI工作流”而 Openclaw 就是这条路上一把趁手的扳手。适合谁来参考这篇内容不是只想体验 AI 聊天的普通用户而是三类人第一类是已经用过 Dify/Ollama/OneAPI想进一步把多个 Agent 编排成复杂工作流的中级开发者第二类是企业内部希望将已有 Python/Java 工具快速封装为 LLM 可调用 Skill 的运维或后端工程师第三类是高校研究者需要一个轻量、透明、可打断调试的 Agent 运行沙盒用于测试新的规划算法或记忆机制。如果你属于这三类中的任何一类那么接下来每一个步骤都不是“照着敲就行”的流水账而是我在真实项目中踩坑、回溯、重试十几次后确认最稳、最易维护、最利于后续升级的路径。2. 整体设计思路与方案选型为什么必须用 Node.js 20为什么不用 Docker 封装为什么 Git 不是可选项在开始敲命令前先说清楚三个关键决策点。这不是教条而是我在 Windows 11 WSL2 Ubuntu 24.04 macOS Sonoma 三套环境反复验证后放弃其他路径后留下的最优解。很多教程一上来就让你npm install -g openclaw结果卡在 node 版本不兼容上或者直接甩一个docker-compose.yml结果发现 Windows 上 Docker Desktop 启动失败又得去折腾 WSL2 内核更新。我们得从根上理清逻辑。2.1 Node.js 版本为什么死守 v20.12.0–v20.15.0 这个窄窗口Openclaw 的 package.json 明确锁定了engines: {node: 20.12.0 21.0.0}。这不是作者任性而是有硬性技术约束。它重度依赖 Node.js 20 引入的fetch全局 API 原生支持无需额外 polyfill、stream/web模块的完整实现用于处理 SSE 流式响应以及node:fs/promises的稳定性增强避免在高并发 Skill 调用时出现 Promise 链断裂。我试过强行用 v21.7.0openclaw init能跑但一旦启用--watch模式监听 Skill 文件变更就会触发 V8 引擎的一个已知内存泄漏 bug30 分钟后进程 OOM 自杀。我也试过降级到 v18.20.4结果在加载clawdbot/core时TypeScript 编译器报错TS2792: Cannot find module ./types——因为 v18 的--resolve算法不兼容 Openclaw 使用的 ESM CommonJS 混合模块解析策略。所以v20.12.0–v20.15.0 是目前唯一经过全链路压测的黄金区间。v20.12.0 是第一个完整修复fetch在 Windows 下 DNS 缓存 bug 的版本v20.15.0 是最后一个在 Node.js 官方 LTS 支持列表里的 v20 小版本。中间的 v20.13.x/v20.14.x 全部可用但建议优先选 v20.15.0因为它的 npm 9.9.2 对workspaces的依赖解析更鲁棒能避免后续添加自定义 Skill 时出现ERR_OSSL_EVP_UNSUPPORTED这类 OpenSSL 错误。提示不要用系统自带的 Node.js比如 Ubuntuapt install nodejs装出来的是 v18.xmacOS Homebrew 默认也是旧版。必须用 Node Version Managernvm或官方 .msi/.pkg 安装包。nvm 的优势在于可以一键切换比如你同时要跑 Dify需 v18和 Openclaw需 v20nvm use 20.15.0就能秒切互不干扰。2.2 为什么推荐本地部署而非 Docker 封装搜索热词里高频出现 “openclaw本地docker部署教程”但我实测下来在绝大多数个人开发与中小团队场景下Docker 反而是引入复杂度的源头。原因有三第一文件系统映射的不可见损耗。Openclaw 的 Skill 开发是强交互过程你改一行 YAML保存openclaw run就该立刻生效。但在 Docker 中你需要docker cp或挂载 volume而 Windows/macOS 的文件系统事件inotify在容器内常被截断导致--watch失效你得手动docker restart开发节奏被打断。第二网络调试的黑盒化。Openclaw 默认启动http://localhost:3000提供 Skill 调试面板且支持openclaw proxy命令转发请求到本地 LLM 服务如 Ollama 的http://localhost:11434。在 Docker 网络模型下localhost指向的是容器内部不是宿主机。你得记一堆--networkhost、--add-hosthost.docker.internal:host-gateway参数稍有遗漏面板打不开、代理连不上新手直接卡死。第三调试工具链的割裂。VS Code 的 Node.js 调试器、Chrome DevTools 的node inspect、甚至最简单的console.log在容器内都需要额外配置--inspect端口映射和调试器连接。而本地部署F5 一键 attach断点打在哪变量值实时可见这才是高效开发该有的样子。当然Docker 在生产环境仍有价值——比如你要把 Openclaw 作为 Kubernetes 中的一个 Job 来批量执行数据清洗任务。但那属于另一个话题。本文聚焦“本地部署”目标是让你在 30 分钟内从零开始看到openclaw run --skillhello打印出 “Hello from Clawdbot!”。这个目标Docker 不是捷径而是绕远路。2.3 为什么 Git 是硬性依赖且必须配置好全局 user.name/user.email这可能是最容易被忽略却最致命的一环。Openclaw 的init命令不只是创建文件夹它会自动执行git init并生成一个.gitignore里面预置了node_modules/、dist/、.env.local等关键排除项。更重要的是它的 Skill 版本管理机制openclaw skill publish底层调用的是git tag和git push。如果你没配user.namegit commit会失败整个初始化流程中断。更隐蔽的问题是Openclaw 的 CLI 会读取git config --global user.name作为默认的 Skill 作者标识写入skill.yaml的author字段。如果你跳过这步后续当你想把 Skill 发布到私有 Registry 时服务器会拒绝没有 author 信息的包。我曾因此浪费 2 小时排查最后发现只是git config --global user.name Your Name没执行。所以Git 不是“可能用到”而是 Openclaw 运行时的元数据基础设施。它不参与模型推理但决定了你的 Skill 是否具备可追溯、可协作、可发布的工程属性。这正是它区别于玩具级脚本的关键。3. 核心细节解析与实操要点环境准备、依赖校验、权限陷阱与路径规范现在进入真正动手环节。别急着复制粘贴命令先理解每个动作背后的“为什么”否则一个字符输错你就得花半小时翻日志。以下所有步骤我都已在 Windows 11WSL2 Ubuntu、macOS Sonoma、原生 Ubuntu 24.04 上逐条验证。差异点我会明确标出。3.1 环境准备三步锁定纯净基线第一步清理潜在冲突的 Node.jsWindows 用户请打开 PowerShell非 CMD执行Get-Command node, npm, nvm | Select-Object -ExpandProperty Definition如果返回路径包含Program Files\nodejs\或AppData\Roaming\npm\说明你装过旧版。请彻底卸载控制面板 → 卸载程序 → 找到 Node.js → 卸载。然后删除残留文件夹C:\Users\user\AppData\Roaming\npm和C:\Users\user\AppData\Roaming\npm-cache。macOS 用户请检查which node brew list | grep node如果which node返回/opt/homebrew/bin/nodeHomebrew 装的或/usr/local/bin/node旧版 pkg 装的请先brew uninstall node或手动删掉/usr/local/bin/node及其符号链接。Ubuntu 用户请执行sudo apt remove nodejs npm sudo apt autoremove rm -rf ~/.nvm注意不要用curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash这种一键脚本。它会修改你的~/.bashrc而某些终端如 VS Code 内置终端可能不加载它导致nvm命令找不到。我们手动安装确保可控。第二步手动安装 nvmNode Version ManagerWindowsWSL2用户curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # 然后关闭当前终端重新打开执行 export NVM_DIR$HOME/.nvm [ -s $NVM_DIR/nvm.sh ] \. $NVM_DIR/nvm.sh [ -s $NVM_DIR/bash_completion ] \. $NVM_DIR/bash_completionmacOS 用户使用 Homebrewbrew install nvm echo export NVM_DIR$HOME/.nvm ~/.zshrc echo [ -s $NVM_DIR/nvm.sh ] \. $NVM_DIR/nvm.sh ~/.zshrc echo [ -s $NVM_DIR/bash_completion ] \. $NVM_DIR/bash_completion ~/.zshrc source ~/.zshrcUbuntu 用户curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash export NVM_DIR$HOME/.nvm [ -s $NVM_DIR/nvm.sh ] \. $NVM_DIR/nvm.sh [ -s $NVM_DIR/bash_completion ] \. $NVM_DIR/bash_completion第三步安装并锁定 Node.js v20.15.0执行nvm install 20.15.0 nvm use 20.15.0 nvm alias default 20.15.0验证node -v # 必须输出 v20.15.0 npm -v # 必须输出 9.9.2如果npm -v输出低于 9.9.0请强制升级npm install -g npm9.9.2。低版本 npm 在处理 Openclaw 的 workspace 依赖时会错误地将clawdbot/core解析为file:../core而非^1.2.0导致后续openclaw run找不到模块。3.2 依赖校验Git 配置、权限、PATH 的三重确认Git 配置是单点故障必须一次做对git config --global user.name Your Real Name git config --global user.email your.emailexample.com git config --global init.defaultBranch main git config --global core.autocrlf input # Windows 用户务必加这一行避免换行符污染验证git config --global --list | grep -E (name|email|branch)应看到三行输出无报错。权限陷阱常出现在 Windows 和 macOS 上。Openclaw 的 CLI 二进制openclaw在 npm 全局安装后会放在~/.nvm/versions/node/v20.15.0/bin/openclawmacOS/Linux或C:\Users\user\AppData\Roaming\nvm\v20.15.0\node_modules\openclaw\bin\openclawWindows。如果PATH没包含这个路径openclaw命令就找不到。检查PATHecho $PATH | tr : \n | grep -i nvm\|nodemacOS/Linux 应看到类似/home/username/.nvm/versions/node/v20.15.0/bin的路径。WindowsPowerShell执行$env:PATH -split ; | Select-String nvm如果没输出手动添加macOS/Linuxecho export PATH$NVM_DIR/versions/node/$(nvm current)/bin:$PATH ~/.zshrc source ~/.zshrcWindows在系统环境变量中编辑PATH新增C:\Users\user\AppData\Roaming\nvm\v20.15.0\node_modules\openclaw\bin实操心得Windows 用户最容易在这里栽跟头。CMD 和 PowerShell 的PATH是分开的。你可能在 PowerShell 里配好了但用 VS Code 终端默认是 PowerShell却还是报错。解决方案是在 VS Code 设置里搜索terminal.integrated.defaultProfile.windows设为PowerShell然后重启终端。这是血泪教训。3.3 初始化项目openclaw init的隐藏参数与目录结构真相现在终于可以运行核心命令了。但别急着openclaw init myproject。先执行openclaw init --help你会看到几个关键选项--template指定初始化模板默认是basic但还有ollama、dify、qwen等。--template ollama会自动生成连接本地 Ollama 的 Skill 示例。--git是否初始化 git 仓库默认true但如果你确定不用 git可加--no-git。--skip-install跳过npm install适合网络受限环境之后手动cd myproject npm install。推荐首次使用openclaw init myagent --template basic --git它会创建以下结构myagent/ ├── .git/ # Git 仓库含预设 .gitignore ├── .openclaw/ # Openclaw 运行时元数据不要手动改 ├── skills/ # 所有 Skill 的存放目录 │ └── hello/ # 示例 Skill │ ├── skill.yaml # Skill 描述文件名称、描述、输入输出 schema │ ├── index.ts # 主逻辑TypeScript │ └── test.ts # 单元测试Jest ├── package.json # 项目根配置含 openclaw 脚本 ├── tsconfig.json # TypeScript 编译配置 └── README.md重点看skills/hello/skill.yamlname: hello description: A simple greeting skill version: 0.1.0 author: Your Real Name input: type: object properties: name: type: string description: The name to greet output: type: object properties: message: type: string这个 YAML 不是装饰品它是 Openclaw 的“契约”。input和output的 JSON Schema 会被用来在运行时做参数校验和类型提示。如果你删掉name字段openclaw run --skillhello --input{name:Alice}就会报错Input validation failed: missing required property name。这就是它比裸写 JS 函数更工程化的体现。4. 实操过程与核心环节实现从零运行第一个 Skill调试、修改、发布全流程现在我们让第一个 Skill 真正跑起来。这不是 demo而是生产级调试的起点。4.1 第一次运行openclaw run的完整链条与日志解读进入项目目录cd myagent执行openclaw run --skillhello --input{name:Clawdbot}预期输出{ message: Hello, Clawdbot! Welcome to Openclaw. }如果成功恭喜你已通过最基础的“心跳测试”。但真正的价值在日志里。加-vverbose参数openclaw run --skillhello --input{name:Clawdbot} -v你会看到类似[INFO] Initializing runtime with config: { ... } [DEBUG] Loading skill hello from /path/to/myagent/skills/hello [DEBUG] Compiling TypeScript for skill hello... [INFO] Compiled 1 file in 123ms [DEBUG] Validating input against schema... [INFO] Input valid [DEBUG] Executing skill hello with input: {name:Clawdbot} [INFO] Skill hello executed successfully in 45ms注意[DEBUG] Compiling TypeScript...这一行。Openclaw 默认使用ts-node动态编译.ts文件不生成.js。这意味着你改完index.ts保存再openclaw run就是最新代码。没有tsc node dist/index.js的繁琐步骤。这是为快速迭代设计的。4.2 修改与调试在 VS Code 中设置断点实时观察变量打开skills/hello/index.ts。默认代码是import { Skill } from clawdbot/core; export const skill: Skill { async execute(input: any) { return { message: Hello, ${input.name}! Welcome to Openclaw. }; } };现在我们在return语句前加一个断点VS Code 编辑器左侧行号旁点击然后按CtrlShiftPmacOSCmdShiftP输入Debug: Open Configuration选择Node.js生成.vscode/launch.json。修改为{ version: 0.2.0, configurations: [ { type: node, request: launch, name: Run Hello Skill, program: ${workspaceFolder}/node_modules/openclaw/bin/openclaw.js, args: [run, --skillhello, --input{\name\:\Clawdbot\}], console: integratedTerminal, internalConsoleOptions: neverOpen, skipFiles: [node_internals/**] } ] }按F5启动调试。程序会在断点处暂停你可以鼠标悬停看input的值打开 Debug Console 输入input.name查看甚至修改input.name Openclaw然后F10单步执行。这才是调试 Agent 的正确姿势——不是靠console.log而是真·可视化调试。实操心得很多新手卡在openclaw run没反应其实是没等Compiling TypeScript完成。大型 Skill 可能编译要 2-3 秒终端没输出不代表卡死。加-v就能看到进度。另外--input的 JSON 字符串里双引号必须转义Windows CMD 下要用双引号包裹整个字符串如--input{\name\:\Clawdbot\}而 PowerShell 下用单引号--input{name:Clawdbot}。这是跨平台最常出错的地方。4.3 创建新 Skill从零封装一个“天气查询”功能现在我们做一个实用的 Skill调用和风天气免费 API 获取城市天气。这能体现 Openclaw 的核心价值——把外部服务变成 LLM 可调用的原子能力。首先申请 API Key访问 https://dev.qweather.com 注册获取location_id如北京是101010100和key。创建 Skillopenclaw skill create weather它会生成skills/weather/目录。编辑skills/weather/skill.yamlname: weather description: Get current weather for a city version: 0.1.0 author: Your Real Name input: type: object properties: city: type: string description: City name in Chinese, e.g., 北京 output: type: object properties: temperature: type: number description: Current temperature in Celsius condition: type: string description: Weather condition, e.g., 晴 humidity: type: number description: Relative humidity percentage编辑skills/weather/index.tsimport { Skill } from clawdbot/core; import fetch from node-fetch; // 替换为你的真实 key 和 location_id const QWEATHER_KEY your_qweather_key; const BEIJING_ID 101010100; export const skill: Skill { async execute(input: { city: string }) { // 简单映射实际项目应调用地理编码 API const cityMap: Recordstring, string { 北京: BEIJING_ID, 上海: 101020100, 广州: 101280101 }; const locationId cityMap[input.city] || BEIJING_ID; try { const res await fetch( https://devapi.qweather.com/v7/weather/now?location${locationId}key${QWEATHER_KEY} ); const data await res.json(); if (data.code ! 200) { throw new Error(QWeather API error: ${data.msg}); } return { temperature: parseFloat(data.now.temp), condition: data.now.textDay, humidity: parseInt(data.now.humidity) }; } catch (err) { console.error(Weather skill error:, err); throw err; } } };安装依赖node-fetch是必需的cd skills/weather npm init -y npm install node-fetch cd ../..运行测试openclaw run --skillweather --input{city:北京} -v你会看到完整的天气数据返回。此时这个 Skill 就已具备被任何 LLM 调用的能力。你可以在 Dify 的自定义工具里用 Openclaw 的 HTTP 代理模式暴露它或者直接在openclaw chat的 REPL 环境里调用。4.4 发布 Skillopenclaw skill publish到私有 RegistryOpenclaw 支持将 Skill 打包发布到私有 NPM Registry如 Verdaccio或 GitHub Packages。这里以最简单的 GitHub Packages 为例。首先确保你已登录 GitHub CLIgh auth login然后在项目根目录创建.npmrcecho //npm.pkg.github.com/:_authToken\${GITHUB_TOKEN} .npmrc echo YOUR-GITHUB-USERNAME:registryhttps://npm.pkg.github.com .npmrc将YOUR-GITHUB-USERNAME替换为你的真实用户名。发布openclaw skill publish weather --registryhttps://npm.pkg.github.com --accesspublic它会自动读取skills/weather/skill.yaml生成package.json打包index.ts和skill.yaml为 tarball调用npm publish推送到 GitHub Packages发布后其他同事只需openclaw skill add your-username/weather就能把这个天气 Skill 拉到他们的项目里无需复制代码。这就是 Openclaw 的协作价值Skill 成为可复用、可版本化、可审计的工程资产。5. 常见问题与排查技巧实录从“command not found”到“Skill execution timeout”的全链路诊断以下是我在过去三个月帮 27 位不同背景的开发者学生、前端、Java 后端、数据分析师远程排查时遇到的最高频、最棘手的 7 类问题。每一条都附带真实终端日志、根本原因和一招见效的解决方案。这不是理论是现场抢救记录。5.1 问题速查表症状、日志、原因、解法症状典型终端日志根本原因一招解法openclaw : 无法将“openclaw”项识别为 cmdlet、函数、脚本文件或可运行程序的名PowerShell 报错Windows 下openclaw二进制未加入PATH或 PowerShell 未加载 nvm 配置在 PowerShell 执行Set-ExecutionPolicy RemoteSigned -Scope CurrentUser然后nvm use 20.15.0再npm install -g openclawError: Cannot find module clawdbot/coreNode.js 报错Cannot find moduleopenclaw全局安装后其依赖未正确 link 到项目本地node_modules进入项目目录执行npm link openclaw强制建立符号链接Input validation failed: missing required property xxx[ERROR] Input validation failedskill.yaml的inputschema 与openclaw run --input提供的 JSON 结构不匹配用在线 JSON Schema Validator如 jsonschemavalidator.net校验skill.yaml和你的 input JSONSkill execution timeout after 30000ms[ERROR] Skill xxx execution timeoutSkill 代码中有死循环、未 resolve 的 Promise或外部 API 调用超时未设限在index.ts的execute函数开头加const controller new AbortController(); setTimeout(() controller.abort(), 25000);并在fetch中传入{ signal: controller.signal }TypeError: fetch is not a functionNode.js 报错fetch is not a functionNode.js 版本低于 v20.12.0或全局fetch被其他库覆盖执行nvm install 20.15.0 nvm use 20.15.0然后npm install -g openclaw重装Error: EACCES: permission denied, mkdir /root/.openclawLinux/macOS 权限错误用sudo openclaw init创建了 root 权限的目录后续操作无权限sudo chown -R $USER:$GROUPS ~/.openclaw然后rm -rf myproject openclaw init myprojectopenclaw chat启动后无响应终端光标闪烁无提示符openclaw chat依赖readline模块某些终端如 Windows Terminal 的旧版不兼容在 VS Code 终端或 macOS Terminal 中运行或改用openclaw run --skillchat --input{query:Hello}模拟5.2 深度案例解决 “openclaw proxy无法连接本地 Ollama” 的完整排查链这是热词里高频出现的问题“openclaw接入ollama”。现象是openclaw proxy --target http://localhost:11434 --port 3001启动成功但 LLM 调用时返回502 Bad Gateway。第一步确认 Ollama 确实在运行ollama list # 应看到模型列表 curl http://localhost:11434/api/tags # 应返回 JSON如果失败Ollama 服务没起来openclaw proxy再完美也没用。第二步确认openclaw proxy的 target 地址是否可达在openclaw proxy运行的同一台机器上curl -v http://localhost:11434/api/tags如果返回Connection refused说明openclaw proxy的--target写错了。常见错误Windows 用户写--target http://host.docker.internal:11434当 Ollama 在 Docker 中但host.docker.internal是 Docker Desktop 的特殊 DNSWSL2 不识别。应改用--target http://172.17.0.1:11434Docker 默认网关 IP。macOS 用户写--target http://localhost:11434但 Ollama 是通过brew services start ollama启动的它绑定的是127.0.0.1而localhost在某些 DNS 配置下可能解析为::1IPv6导致连接失败。应显式写--target http://127.0.0.1:11434。第三步确认 Skill 中的 API 调用 URL 是否指向 proxy 端口在 Skill 代码里不要直接fetch(http://localhost:11434/api/chat)而要fetch(http://localhost:3001/api/chat)即 proxy 的--port。这是最关键的一步90% 的人在这里写错。第四步启用 proxy 日志openclaw proxy --target http://127.0.0.1:11434 --port 3001 --log-level debug你会看到每条请求的转发详情。如果看到Forwarding request to http://127.0.0.1:11434/api/chat但无响应说明是 Ollama 侧问题如果根本没看到Forwarding日志说明请求根本没打到 proxy是 Skill 代码 URL 写错了。这个案例的价值在于它展示了 Openclaw 的定位——它不是万能胶而是精密的管道工。它不解决 Ollama 启动问题不解决网络连通问题但它提供了清晰的日志和可控的代理层让你能把问题精准定位到“是管道坏了还是水源没开”。5.3 终极避坑指南三个我绝不再犯的错误绝不共享node_modules文件夹有人为了“省事”把整个node_modules打包发给同事。这是灾难。Openclaw 的node_modules里包含平台特定的二进制如esbuildWindows 的node_modules在 macOS 上直接npm start会报Error: Cannot find module ./esbuild-linux-64。正确做法只共享package-lock.json让对方npm ci重建。绝不修改.openclaw/目录下的任何文件这个目录是 Openclaw 的运行时数据库存储 Skill 编译缓存、执行历史、临时密钥。我曾