跳转至

依赖

OpenClaw 仅在安装/更新时处理插件依赖。运行时加载绝不会运行包管理器、修复依赖树,或修改 OpenClaw 包目录。

职责划分

插件包拥有自己的依赖图:

  • 运行时依赖位于插件包的 dependencies 或 optionalDependencies 中。
  • SDK/核心导入是 peer 依赖或 OpenClaw 提供的导入。
  • 本地开发插件自带其已安装的依赖。
  • npm 和 git 插件安装到由 OpenClaw 拥有的包根目录中。

OpenClaw 仅负责插件生命周期:

  • 发现插件来源。
  • 在明确请求时安装或更新包。
  • 记录安装元数据。
  • 加载插件入口点。
  • 当依赖缺失时,以可操作的错误失败。

安装根目录

OpenClaw 使用按来源划分的稳定根目录:

  • npm 包安装到 ~/.openclaw/npm/projects/<encoded-package> 下的按插件划分的项目中。
  • git 包克隆到 ~/.openclaw/git 下。
  • 本地/路径/归档安装会被复制或引用,且不会进行依赖修复。

npm 安装在该按插件划分的项目根目录中运行,命令为:

cd ~/.openclaw/npm/projects/<encoded-package>
npm install --omit=dev --omit=peer --legacy-peer-deps --ignore-scripts --no-audit --no-fund

npm-pack 压缩包安装

openclaw plugins install npm-pack:<path.tgz> 对于本地 npm-pack 压缩包使用相同的按插件划分的 npm 项目根目录:OpenClaw 读取压缩包的 npm 元数据,将其作为复制的 file: 依赖添加到受管项目中,运行上述常规 npm 安装,然后在信任插件之前验证已安装的 lockfile 元数据。此路径用于包验收和发布候选证明,其中本地 pack 产物应表现得像它所模拟的注册表产物。

在发布前测试官方或外部插件包时,请使用 npm-pack:。原始归档或路径安装对本地调试有用,但它不能证明与已安装的 npm 或 ClawHub 包相同的依赖路径。npm-pack: 证明受管包安装形态;它本身并不能证明该插件是目录关联的官方内容。

当行为取决于捆绑插件或受信任官方插件状态时,请将本地包证明与目录支持的官方安装或记录官方信任的已发布包路径配对。特权辅助程序访问和受信任官方范围处理应在该受信任安装路径上验证,而不是从本地压缩包安装中推断。

缺失的运行时导入

如果插件因缺失导入而在运行时失败,请修复包清单,而不是手动修复受管项目。运行时导入应位于插件包的 dependencies 或 optionalDependencies 中;对于受管运行时项目,不会安装 devDependencies。在 ~/.openclaw/npm/projects/<encoded-package> 内运行本地 npm install 可以解除临时诊断的阻塞,但它不是包验收证明,因为下一次安装或更新会根据包元数据重新创建项目。

提升的传递依赖

npm 可能会将传递依赖提升到按插件划分的项目的 node_modules 中,与插件包并列。OpenClaw 在信任安装之前会扫描受管项目根目录,并在卸载时删除该项目,因此提升的运行时依赖仍保留在该插件的清理边界内。

Lockfile 策略

由 OpenClaw 拥有的 npm 插件包从不附带 npm lockfile。该仓库使用 pnpm-lock.yaml 作为其已提交的产品依赖审查边界,然后仅在临时目录中生成 npm 包锁文件,以验证可发布的依赖图:

pnpm deps:npm-lock:check
pnpm deps:npm-lock:check:changed

检查器会移除插件的 devDependencies,应用工作区覆盖策略,并拒绝 pnpm-lock.yaml 中不存在的生成版本。不会向检出目录写入任何内容。第三方插件包仍可根据其自身的打包策略包含 lockfile;OpenClaw 的安装器将该 npm 行为交给已安装的 npm 版本处理。

验证包压缩包

在将本地包视为发布候选证明之前,请检查将要安装的压缩包:

npm pack --pack-destination /tmp
tar -xOf /tmp/<plugin-package>.tgz package/package.json
tar -tf /tmp/<plugin-package>.tgz | grep '^package/dist/'

对于依赖变更,还需验证生产安装能否在不包含开发依赖的情况下解析运行时包:

tmpdir=$(mktemp -d)
(
  cd "$tmpdir"
  npm init -y >/dev/null
  npm install --package-lock-only --omit=dev --omit=peer --legacy-peer-deps --ignore-scripts /tmp/<plugin-package>.tgz
)
rm -rf "$tmpdir"

捆绑的运行时依赖

由 OpenClaw 拥有的 npm 插件包也可以显式使用 bundledDependencies 进行发布。npm 发布路径会覆盖运行时依赖名称列表,从已发布清单中移除仅开发用的工作区元数据,暂存一个不包含源 node_modules 的独立包目录,并在那里为运行时依赖运行无脚本的 npm 安装。然后,它会打包或发布包含这些依赖文件的插件压缩包,并删除暂存目录。由 pnpm 拥有的源依赖树保持不变。

当某个直接运行时依赖针对其精确版本拥有已批准的工作区补丁时,npm 和 ClawHub 打包会从匹配的冻结 pnpm 安装中包含该依赖。打包会验证已安装补丁的身份,并将其字节打包到临时依赖安装中,然后在已发布清单中恢复原始公开版本说明符。当禁用捆绑所有运行时依赖时,这也适用;无关依赖保留其正常安装行为。过期的源安装或显式的 bundleRuntimeDependencies: false 退出选项会停止打包,而不是发布未打补丁的依赖。

原生密集型包(Codex、ACPX、Copilot、llama.cpp、memory-lancedb、Microsoft Teams、Tlon)通过 openclaw.release.bundleRuntimeDependencies: false 退出;它们仍会附带精确固定的清单,但 npm 会在安装期间解析运行时依赖,而不是将每个平台二进制文件嵌入插件压缩包。根 openclaw 包也会在安装时解析依赖,并且不会捆绑其完整依赖树。参见 依赖锁定。

宿主对等依赖

导入 openclaw/plugin-sdk/* 的插件会将 openclaw 声明为对等依赖。OpenClaw 不允许 npm 将宿主包的独立 registry 副本安装到受管项目中,因为过期的宿主包可能影响该插件内部的 npm 对等依赖解析。受管 npm 安装会跳过 npm 对等依赖解析/实例化,并且 OpenClaw 会在安装或更新后,为声明宿主对等依赖的已安装包重新建立插件本地的 node_modules/openclaw 链接。

git 安装

git 安装会克隆或刷新仓库,然后运行:

npm install --omit=dev --ignore-scripts --no-audit --no-fund

已安装的插件随后从该包目录加载,因此包本地和父级 node_modules 解析方式与普通 Node 包相同。

本地插件

本地插件是由开发者控制的目录。OpenClaw 从不为它们运行 npm install、pnpm install 或依赖修复;如果本地插件有依赖项,请在加载该插件之前在该插件中安装它们。

第三方 TypeScript 本地插件会通过 Jiti 作为紧急路径加载。打包的 JavaScript 插件和内置的内部插件则通过原生 import/require 加载。

启动与重新加载

Gateway 启动和配置重新加载从不安装插件依赖项。它们读取插件安装记录,计算入口点,然后加载它。

运行时缺少依赖项会导致插件加载失败,并给出一个指向明确修复方式的错误:

openclaw plugins update <id>
openclaw plugins install <source>
openclaw doctor --fix

doctor --fix 会移除悬空的全局插件运行时符号链接,并且当配置仍引用本地安装记录中缺失的可下载插件时,可以恢复这些插件。Doctor 不会修复已安装本地插件的依赖项。

内置插件

轻量级和核心关键的内置插件作为 OpenClaw 的一部分发布。它们要么不应携带沉重的运行时依赖树,要么应迁移到 ClawHub/npm 上的可下载包。

对于当前生成的随核心包发布、外部安装或仅保留源码的插件列表,请参阅 插件清单。

内置插件清单不得请求依赖项暂存。大型或可选插件功能应打包为普通插件,并通过与第三方插件相同的 npm/git/ClawHub 路径安装。

内部内置插件在其自身清单中保留依赖项声明。未编译到 dist 中的运行时依赖项还必须声明在根 OpenClaw 包的 dependencies 或 optionalDependencies 中,因为根包提供它们的运行时。 外部插件保持其运行时依赖项为插件本地。

包验证使用构建生成的 dist/runtime-dependency-ownership.json 来识别仅由插件使用的 chunk。每个条目将 chunk 文件名和 SHA-256 哈希绑定到其所属 插件;每个所有者都必须在其内置或已安装的 @openclaw/<id> 包清单中声明该依赖项。根导入,包括根对否则由插件拥有的 chunk 的引用,仍然需要根依赖项声明。 对于使用元数据生成器构建的候选项,缺失的元数据或更改的 chunk 字节不能授予插件豁免。

发布预检对早于 scripts/lib/runtime-dependency-ownership-build-plugin.mts 的源码检出具有兼容性例外。当所有权 元数据缺失时,它可以将生成插件区域内的单个导入归因于该插件的打包或受信任源清单。这些区域之外的导入仍需要根声明。对 chunk 的根引用会撤销其插件豁免,包括通过传递相对导入。 提升的静态导入遵循 chunk 的图所有权;插件区域之外的可执行导入仍为根引用。公共包入口点始终计为根所有。存在但无效的元数据永远不会回退到区域所有权。此验证不会更改 Node 的运行时依赖项解析。

在源码检出中,使用 pnpm install,然后使用 pnpm build。OpenClaw 优先使用 dist/extensions,然后是 dist-runtime/extensions,当两个构建树都不可用时回退到 extensions。pnpm 拥有源依赖项树:postinstall 和构建准备会保留插件本地版本和工作区链接。原生 Node 导入从每个插件包解析;打包的内置运行时仍使用上述根运行时声明。 使用构建树时,重新构建以获取源编辑。源码检出开发仅限 pnpm;普通的 npm install 在仓库根目录不会准备 pnpm 工作区。

安装形态 内置插件位置 依赖项所有者
全局 npm 安装 包内的构建运行时树 内部内置运行时的根 OpenClaw 包
Git 检出加 pnpm install + pnpm build dist/extensions,然后是 dist-runtime/extensions 根运行时声明加插件清单
未构建的源码检出 当不存在构建树时回退到 extensions/<id> 具有显式根运行时依赖项的 pnpm 工作区
openclaw plugins install ... 受管 npm 项目/git/ClawHub 根 插件安装/更新流程

对于全局 npm 行,在 npm 12 或 npm 11.16+ 上使用 npm install -g openclaw --allow-scripts=openclaw。 在 npm 11.15 及更早版本上,省略 --allow-scripts=openclaw。插件依赖项 收敛仍然有意禁用脚本,并继续使用上述 --ignore-scripts 命令。

独立源码构建的原生导入

若要直接使用 Node 导入已构建的 extensions/<package>/dist,请使用 pnpm 安装的主机链接。如果该链接缺失,请从源码检出根目录显式准备它:

node scripts/lib/plugin-npm-runtime-build.mjs --prepare-native-import extensions/<package>

这需要 dist/plugin-sdk 中已存在的根 SDK 输出,以及所选包的独立运行时输出。如果包输出缺失,请先使用 node scripts/lib/plugin-npm-runtime-build.mjs extensions/<package> 构建它。 独立构建会运行所选包的资源构建命令,并将其声明的 openclaw.build.staticAssets 复制到 dist,包括尚未被 Git 跟踪的新包。缺失的已声明源文件会导致构建失败。

根构建和独立构建会从插件已安装的依赖项中解析 node_modules/<package>/... 下的源文件,包括提升安装的依赖项。这些是物理包路径;子路径导出映射不会限制已声明的资源。所选依赖项中缺失的文件不会借用另一个已安装版本。

在 openclaw.build.workerEntries 中声明私有 worker 源文件,使用相对于包的路径,例如 ./src/store.worker.ts。独立构建会在 dist 下的对应路径输出它们,例如 dist/src/store.worker.js(CommonJS 包为 .cjs)。当插件被选入根捆绑构建时,这些条目也会被包含。声明 worker 不会将其注册为插件入口点,也不会添加公共包导出。

准备命令不会重新构建任一输出,也不会执行插件代码。它只会将检出链接为 node_modules/openclaw,用于声明 peerDependencies 或 dependencies 中包含 openclaw 的真实直接源包。它不会安装第三方依赖项;这些依赖项必须已通过 pnpm 工作区可用。

准备过程会拒绝符号链接包路径、不安全的清单以及冲突的依赖项路径,而不是报告成功。普通包构建仍然只生成产物。Postinstall 和根构建准备会保留源插件本地 node_modules,包括此链接。运行时加载永远不会执行此设置或运行包管理器。

遗留清理

旧版 OpenClaw 会在启动或 doctor 修复期间生成捆绑插件依赖项根目录。打包版 postinstall 现在只清理其自身安装:过时的捆绑插件 node_modules 和 dist/extensions 下的 .openclaw-install-stage* 目录、打包清单中不存在的 dist 文件,以及空的 dist 目录。

doctor --fix 仅当别名本身确实悬空时,才会移除指向 plugin-runtime-deps 的全局 Node 前缀包符号链接。有效别名会被保留。Doctor 和 postinstall 都不会删除共享的 plugin-runtime-deps 根目录或镜像,因为它们可能仍在为另一个安装或配置文件提供服务。自 2026.9.2 起,已弃用的 core/doctor/legacy-plugin-dependencies 选择器仅用于信息提示;它不再扫描共享根目录以进行删除。

共享的 ~/.openclaw/npm/node_modules 根目录是 2026.5.28 之前的 npm 安装布局。安装、更新、卸载和 doctor 流程仍然识别该旧版扁平根目录,仅用于恢复和清理。2026.5.28 及之后的安装会改为创建按插件划分的 project roots。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw