OpenViking OpenClaw 插件安装与打包契约解析:从包结构到发布流水线的稳定边界
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
导读
OpenViking 通过@openviking/openclaw-plugin为 OpenClaw 提供长期记忆、知识库检索、语义检索与 RAG 上下文能力,而要让这个插件在 OpenClaw 生态中被稳定地安装、加载和升级,必须在打包与安装环节守住一组明确的契约。本文以 openviking-install-package-contract.md 为骨架,结合仓库中的 package.json、install-manifest.json、契约测试 package-install-contract.test.ts 与发布流水线 clawhub-dev-release.yml,完整还原这组契约的内容、动机与落地方式。读完本文,你将掌握:插件包必须包含哪些条目、openclaw.extensions与setupEntry为什么必须指向编译产物、为何发布前必须剥离devDependencies、install-manifest.json如何定义安装期文件契约,以及如何用契约测试守住这条稳定边界。
契约的背景与定位
openviking-install-package-contract.md记录的是当前 main 分支真实生效的安装/打包契约,其定位非常明确:契约以仓库中"实际会被构建并被安装"的 npm/OpenClaw 包形态为准,而不是以某个尚未合入的发布流程为准。
文档特别指出,历史上的 #2613 分支曾包含一套未公开的 TOS(对象存储)shell 脚本发布流程草案,但当前 main 分支并不包含这些 TOS 发布脚本。因此,把包契约建立在"仓库中真正存在、真正被 OpenClaw 安装的包形状"之上才是安全的,这既避免了文档与代码脱节,也保证了任何按文档执行的人(或自动化 Agent)都能得到可复现的结果。
从仓库现状可以印证这一判断:插件的实际发布产物由 .github/workflows/clawhub-dev-release.yml 流水线生成,其打包步骤基于npm pack而不是任何 TOS 上传脚本;插件目录下也确实没有独立的 TOS 发布脚本文件。
插件包必须包含的条目
契约要求发布出去的插件包必须包含以下条目,每一项都有其不可替代的职责:
| 包内条目 | 为什么必须存在 |
|---|---|
dist/ | 编译后的运行时,由 OpenClaw 实际加载 |
dist/index.js | 主扩展入口(extension entry) |
dist/commands/setup.js | OpenClaw 使用的 setup 入口 |
package.json | OpenClaw 包元数据与运行时依赖声明 |
openclaw.plugin.json | 插件清单(manifest),声明工具、skills、setup 与配置 schema |
install-manifest.json | 安装期文件契约 |
README.md、INSTALL.md、INSTALL-ZH.md | 面向用户的安装与使用文档 |
skills/ | 随包分发的 OpenViking skills |
此外,契约规定:在plugin/下新增的辅助模块,必须出现在包的files白名单中,或者被包级目录规则整体包含,否则它们不会进入最终发布物。这是 npmfiles字段"白名单制"的直接后果——未列入的模块在npm pack时会被静默排除。
在 package.json 中可以看到这份契约的实际落地:files数组完整列出dist/、*.ts、adapters/、commands/setup.ts、config/feature-gates.json、registries/、routing/、shared/、plugin/、services/、install-manifest.json、openclaw.plugin.json、README.md、INSTALL.md、INSTALL-ZH.md、INSTALL-AGENT.md、images/、skills/,并用!vitest.config.ts明确排除测试配置(package.json)。其中*.ts规则与plugin/、services/、adapters/、registries/、routing/、shared/等目录规则,正是文档所说的"包级目录规则"覆盖方式——它保证源码形态的安装(如ov-install备用路径)也能拿到完整文件。
OpenClaw 元数据契约:扩展入口与 setup 入口
package.json中必须始终保有如下 OpenClaw 字段,且取值必须合法:
{ "openclaw": { "extensions": ["./dist/index.js"], "setupEntry": "./dist/commands/setup.js" } }契约强调了一个容易被忽视的硬性要求:setupEntry必须指向编译后的 JavaScript,而不是源码 TypeScript。这与 OpenClaw 的版本演进直接相关。根据 INSTALL.md 中的说明:
- OpenClaw
2026.5.3开始校验包安装,TypeScript 插件入口需要编译后的 JS 输出; 2026.5.4及以后,当编译后的 JS 缺失时,不再回退加载已安装/全局插件的.ts源码;- 当前插件的最低 OpenClaw 版本是
2026.5.27(install-manifest.json 的compatibility.minOpenclawVersion字段与 package.json 的engines.openclaw均为此值)。
也就是说,"setup 入口是 JS"不仅是当前契约的要求,更是 OpenClaw 新版本下的硬约束。实际仓库中的 package.json 还进一步扩展了元数据:openclaw.extensions指向./dist/index.js,openclaw.setupEntry指向./dist/commands/setup.js,同时声明了compat.pluginApi、compat.minGatewayVersion与构建期使用的openclawVersion/pluginSdkVersion。
编译产物由构建脚本保证。在 package.json 中,build脚本先通过node -e "require('node:fs').rmSync('dist', { recursive: true, force: true })"清空dist/,再执行tsc -p tsconfig.build.json;prepack钩子会自动触发npm run build,确保任何一次npm pack前都先产出最新的编译结果。tsconfig.build.json 配置了outDir: dist、rootDir: .,并把顶层*.ts、commands/**/*.ts与shared/**/*.mjs纳入编译,同时排除tests、__tests__与vitest.config.ts。
运行时依赖与 devDependencies 剥离
契约对依赖管理提出了明确的"运行时/开发期"边界:
- 运行时依赖必须包含编译后插件在运行时 import 的一切;仅用于开发与测试的构建包必须放在
devDependencies中。 - 发布到 npm 与 ClawHub 的产物必须在
npm ci之后、npm pack之前删除devDependencies字段。
为什么要如此严格地剥离 dev 依赖?文档给出的原因非常具体:OpenClaw 会把解压后的产物当作项目根目录(project root)安装,而即使使用npm install --omit=dev,npm 仍会解析根目录的 dev 依赖图。一旦这份依赖图被打包带入安装环境,就可能触发 npm Arborist 的 peer-resolution 失败——即使这些包在运行时根本用不到,安装过程也会因此报错。
此外,当前包还保留了一个axiosoverride(package.json 中的"overrides": { "axios": "^1.16.1" }),目的是避免通过 OpenClaw 打包链路装上存在漏洞或不兼容的传递依赖版本。
这条契约在发布流水线中被忠实地执行。查看 clawhub-dev-release.yml 的 "Pack OpenViking plugin" 步骤,可以看到严格的顺序:
npm version --no-git-tag-version --allow-same-version "$VERSION" npm ci npm run prepack # OpenClaw installs the extracted artifact as a project root. Even with # --omit=dev, npm resolves devDependencies and can hit Arborist peer bugs. npm pkg delete devDependencies npm pack --ignore-scripts --pack-destination "$pack_dir"即:先安装完整依赖(含 dev)→ 构建 →删除 devDependencies→ 以--ignore-scripts打包(避免重复触发构建)。ClawHub 旧版 zip 打包路径 "Prepare ClawHub legacy package folder" 也遵循完全相同的"构建 → 剥离 → 打包"顺序,保证两种发布形态行为一致。
安装清单:install-manifest.json
install-manifest.json是 OpenClaw 安装流程读取的"文件契约"。它的核心规则是:每当index.ts或 setup 代码新 import 一个运行时源码模块,就必须把它加入files.required,否则源码形态安装可能拿到残缺的包。
从文档列出的必选条目看,安装清单覆盖了运行时核心模块与元数据文件:
index.ts(扩展入口源码)config.tscontext-engine.tsclient.tsauto-recall.tsrecall-trace.tscommands/setup.tspackage.jsonopenclaw.plugin.json
仓库中的 install-manifest.json 是这份契约的完整现实版本,远不止文档举例的 9 项。files.required(install-manifest.json)共 28 项,包含process-manager.ts、memory-ranking.ts、token-estimator.ts、text-utils.ts、tool-call-id.ts、session-transcript-repair.ts、runtime-utils.ts、request-headers.ts、query-config.ts等运行时模块,以及adapters/、registries/、routing/、shared/、plugin/、services/、config/feature-gates.json、tsconfig.json、tsconfig.build.json、package.json、openclaw.plugin.json、install-manifest.json等目录与配置文件。
files.optional(install-manifest.json)则收录"提升安装体验但不是加载运行时所必需"的文件,包括package-lock.json、.gitignore、三个 skill 的SKILL.md与INSTALL-AGENT.md。optional 条目的取舍逻辑与文档描述一致:锁文件与额外文档不会影响运行时加载,但会改善可复现性与使用体验。
清单还携带了插件的身份与兼容性元数据(install-manifest.json 与 install-manifest.json):id为openviking、kind为context-engine、slot为contextEngine;minOpenclawVersion为2026.5.27、推荐2026.6.6;minOpenvikingVersion与推荐版本均为0.4.1。npm段(install-manifest.json)声明了安装期行为:install: true、omitDev: true、build: true、构建脚本为build、buildMinOpenclawVersion为2026.5.3(即上文提到的"开始校验包安装"的版本),以及构建后裁剪pruneAfterBuild: true。
验证清单:如何守住契约
契约必须有可执行的验证手段。发布或合并包契约相关改动前,需依次运行:
npm test -- tests/ut/package-install-contract.test.ts npm run typecheck npm run build git diff --check其中npm test -- tests/ut/package-install-contract.test.ts是契约守护测试,必须验证以下全部内容:
- 构建后编译扩展入口存在;
- 构建后编译 setup 入口存在;
openclaw.extensions与openclaw.setupEntry指向dist/*.js;- 包
files包含运行时资源与文档; - 安装清单 required 文件存在;
- 运行时依赖与 overrides 存在;
- 两条发布打包路径都在
npm pack前剥离devDependencies。
这些要求与 tests/ut/package-install-contract.test.ts 中的实际断言一一对应。该测试共七个用例,例如:
- "uses compiled OpenClaw runtime entries"(第 14-21 行):断言
openclaw.extensions等于["./dist/index.js"]、setupEntry等于"./dist/commands/setup.js",且 build 脚本包含清理dist与tsc -p tsconfig.build.json; - "keeps source install manifest aligned with required source files"(第 23-62 行):断言清单身份字段,并对
files.required中的每一项执行existsSync实存检查——缺文件即测试失败; - "ships npm package files needed by source and compiled installs"(第 64-88 行):断言
package.json的files覆盖dist/、*.ts、各目录、文档与 skills; - "strips dev dependencies before packing npm and ClawHub release artifacts"(第 90-114 行):直接读取 clawhub-dev-release.yml 工作流文件,校验两个发布步骤中
npm run prepack→npm pkg delete devDependencies→npm pack --ignore-scripts的相对顺序,防止任何人无意中打乱剥离时序; - "ships and registers the canonical Experience skill"(第 116-128 行):断言打包的
skills/ov-experience-memory/SKILL.md与仓库规范副本逐字节一致; - "keeps runtime dependencies and overrides available"(第 130-138 行):断言
@sinclair/typebox、fflate运行时依赖存在,overrides.axios匹配^1.,且typescript、vitest位于 devDependencies; - "keeps setup helper fallback metadata compatible"(第 140-152 行):校验 setup-helper/install.js 中的回退元数据与当前清单的
id/kind/slot保持一致。
可以看到,"剥离 devDependencies 后再打包"不仅写在文档里,还以"读工作流文件断言步骤顺序"的方式被测试强制锁定,双重保障契约不被漂移。
契约在发布流水线中的完整闭环
将以上各节串联起来,一次发布在 clawhub-dev-release.yml 中的完整闭环是:
- guard:解析发布渠道(
auto/dev/latest)与版本号。dev渠道要求YYYY.M.D-dev.N格式,latest渠道要求YYYY.M.D或YYYY.M.D-N,并依据上游仓库与仓库变量决定是否允许发布; - prepare-package-source:checkout 指定 ref →
npm ci→npm run prepack(触发npm run build生成dist/)→npm pkg delete devDependencies→npm pack --ignore-scripts产出 tarball; - publish-clawhub:解包 tarball 得到 legacy zip 产物,调用 ClawHub CLI 发布,并轮询验证产物可见且为
legacy-zip/zip格式; - publish-npm:复用同一 tarball,以 npm 11.14.1 的 CLI 执行带 provenance 的公开发布,tag 使用解析出的渠道。
流水线顶部注释点明了拆分两条发布路径的原因:在 ClawHub 旧版/download哈希与 npm-pack 发布兼容之前,legacy zip 与 npm tarball 必须分开维护。这与契约文档"以当前仓库实际构建安装的包形态为准"的立场完全一致。
契约范围之外:什么不该被写入文档
契约文档的"Out Of Scope"部分给出了一个值得推广的纪律:#2613 分支中的 TOS 发布/安装说明草案,依赖当前 main 不存在的发布脚本与对象存储上传流程,因此不应作为独立文档存在,只应在对应的脚本与 CI/发布流程一并合入时再补充。
换句话说,契约文档只描述"当前仓库真实验证过的东西";对尚未实现、尚未合入的流程保持缄默,正是这份契约可信度的来源。这也给所有维护者划出了红线:发布相关文档必须与发布代码同生共死,不能超前于实现。
总结
OpenViking OpenClaw 插件的安装与打包契约是一组"小而硬"的稳定性保障:
- 包条目契约:
dist/、dist/index.js、dist/commands/setup.js、package.json、openclaw.plugin.json、install-manifest.json、安装文档与skills/缺一不可,新增辅助模块必须进files白名单; - 元数据契约:
openclaw.extensions与openclaw.setupEntry指向编译后的dist/*.js,这是 OpenClaw>= 2026.5.3的硬性要求; - 依赖契约:运行时依赖齐备,发布前必须剥离
devDependencies以避免 Arborist peer-resolution 失败,并保留axiosoverride 规避传递依赖风险; - 安装清单契约:
install-manifest.json的files.required与运行时 import 保持同步,files.optional承载非必需但有益的安装内容; - 验证契约:package-install-contract.test.ts 用七个用例覆盖入口、清单、files、依赖与流水线顺序,配合
npm run typecheck、npm run build、git diff --check形成发布前防线; - 范围纪律:未合入的发布流程不进文档,文档只描述仓库真实构建与安装的包形态。
对于希望深入验证或二次开发的读者,建议从三处入手:先阅读契约原文 openviking-install-package-contract.md,再对照 install-manifest.json 与 package.json 理解条目落地,最后运行契约测试npm test -- tests/ut/package-install-contract.test.ts观察每条断言如何守护这条稳定边界。
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考