包和导入路径
插件应导入哪些 SDK 子路径、软件包打包如何将扩展转换为插件,以及频道包可以发布的目录和安装元数据。属于 插件架构内部机制 指南的一部分。
插件 SDK 导入路径¶
在编写新插件时,请使用更窄的 SDK 子路径,而不是单体式 openclaw/plugin-sdk 根 barrel。核心子路径:
| 子路径 | 用途 |
|---|---|
openclaw/plugin-sdk/plugin-entry |
插件注册原语 |
openclaw/plugin-sdk/channel-core |
频道入口/构建辅助 |
openclaw/plugin-sdk/core |
通用共享辅助和总括契约 |
频道插件可从一组窄接缝中选择 — channel-setup、
setup-runtime、setup-tools、channel-pairing、
channel-contract、channel-feedback、channel-inbound、channel-outbound、
command-auth、secret-input、webhook-ingress、
channel-targets 和 channel-actions。审批行为应集中到一个 approvalCapability 契约,而不是混用不相关的插件字段。参见 频道插件。
运行时和配置辅助位于对应的聚焦 *-runtime 子路径下
(approval-runtime、agent-runtime、lazy-runtime、directory-runtime、
text-utility-runtime、runtime-store、system-event-runtime、heartbeat-runtime、
channel-activity-runtime 等)。请优先使用 config-contracts、
plugin-config-runtime、runtime-config-snapshot 和 config-mutation,
而不是已移除的宽泛 config-runtime 兼容 barrel。
Info
openclaw/plugin-sdk/channel-lifecycle、channel-message、
channel-reply-pipeline、config-runtime 和 infra-runtime 已于 2026 年 9 月 30 日经 SDK 负责人明确批准移除。升级前请迁移到
聚焦的公共契约;替代路径不会导出所有旧辅助函数或命名类型。
仓库内部入口点(每个捆绑插件包根目录):
index.js— 捆绑插件入口api.js— 辅助/类型 barrelruntime-api.js— 仅运行时 barrelsetup-entry.js— 设置插件入口
外部插件只应导入 openclaw/plugin-sdk/* 子路径。切勿从核心或另一个插件导入其他插件包的 src/*。通过 Facade 加载的入口点会优先使用当前活动的运行时配置快照(如果存在),然后回退到磁盘上解析出的配置文件。
设置和提供程序发现回调会保留加载器的作用域 SDK 解析,用于延迟导入,包括打包插件中的私有块。这些导入使用正在运行的宿主 SDK,无需在插件内部建立 openclaw 依赖链接。退役所属清单也会退役其回调。
诸如 image-generation、media-understanding 和 speech 等特定能力子路径存在,是因为捆绑插件会导入它们。它们不会自动成为长期冻结的外部契约——依赖它们时请查看相关 SDK 参考页。
软件包打包¶
插件目录可以包含带有 openclaw.extensions 的 package.json:
{
"name": "my-pack",
"openclaw": {
"extensions": ["./src/safety.ts", "./src/tools.ts"],
"setupEntry": "./src/setup-entry.ts"
}
}
每个条目都会变成一个插件。如果该包列出多个扩展,插件 id 会变成 <manifestOrPackageName>/<fileBase>(存在 manifest id 时优先使用 manifest id;否则使用未带范围的 package.json 名称)。
如果你的插件导入 npm 依赖,请在该目录中安装它们,以便 node_modules 可用(npm install / pnpm install)。
安全护栏:每个 openclaw.extensions 条目在符号链接解析后都必须保留在插件目录内。逃逸出包目录的条目会被拒绝。
安全说明:openclaw plugins install 会使用项目本地的 npm install --omit=dev --ignore-scripts 安装插件依赖(不运行生命周期脚本,运行时不包含开发依赖),并忽略继承的全局 npm 安装设置。请保持插件依赖树为“纯 JS/TS”,避免需要 postinstall 构建的包。
可选:openclaw.setupEntry 可以指向一个轻量级的仅设置模块。当 OpenClaw 需要为已禁用的频道插件提供设置界面,或者频道插件已启用但尚未配置时,它会加载 setupEntry 而不是完整插件入口。当你的主插件入口还接入了工具、钩子或其他仅运行时代码时,这可以让启动和设置更轻量。
捆绑频道还可以发布仅设置的契约界面辅助函数,核心可以在完整频道运行时加载之前查询它们。当前的设置提升界面是:
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
核心在需要将旧版单账号频道配置提升为 channels.<id>.accounts.* 而不加载完整插件入口时使用该界面。Matrix 是当前捆绑示例:当已存在命名账号时,它只会将 auth/bootstrap 键移动到命名提升账号中,并且可以保留已配置的非规范默认账号键,而不是始终创建 accounts.default。
这些设置补丁适配器让捆绑契约界面发现保持惰性。导入时间保持轻量;提升界面只在首次使用时加载,而不是在模块导入时重新进入捆绑频道启动。
当设置界面包含网关 RPC 方法时,请将其放在插件专属前缀下。核心管理命名空间(config.*、exec.approvals.*、wizard.*、update.*)仍然保留,并且始终解析为 operator.admin,即使插件请求更窄的作用域。
频道目录元数据¶
频道插件可以通过 openclaw.channel 发布设置/发现元数据,并通过 openclaw.install 发布安装提示。这使核心目录保持无数据状态。
示例:
{
"name": "@openclaw/nextcloud-talk",
"openclaw": {
"extensions": ["./index.ts"],
"channel": {
"id": "nextcloud-talk",
"label": "Nextcloud Talk",
"selectionLabel": "Nextcloud Talk (self-hosted)",
"docsPath": "/channels/nextcloud-talk",
"docsLabel": "nextcloud-talk",
"blurb": "Self-hosted chat via Nextcloud Talk webhook bots.",
"order": 65,
"aliases": ["nc-talk", "nc"]
},
"install": {
"npmSpec": "@openclaw/nextcloud-talk",
"localPath": "<bundled-plugin-local-path>",
"defaultChoice": "npm"
}
}
}
最小示例之外有用的 openclaw.channel 字段:
detailLabel:用于更丰富的目录/状态界面的次要标签docsLabel:覆盖文档链接的链接文本preferOver:此目录条目应优先于其的低优先级插件/频道 IDselectionDocsPrefix、selectionDocsOmitLabel、selectionExtras:选择界面文案控制markdownCapable:将频道标记为支持 Markdown,用于出站格式决策exposure.configured:设置为false时,从已配置频道列表界面中隐藏该频道exposure.setup:设置为false时,从交互式设置/配置选择器中隐藏该频道exposure.docs:将频道标记为内部/私有,用于文档导航界面quickstartAllowFrom:让频道加入标准快速入门allowFrom流程forceAccountBinding:即使只有一个账户,也要求显式账户绑定preferSessionLookupForAnnounceTarget:解析公告目标时优先使用会话查找
OpenClaw 还可以合并外部频道目录(例如 MPM 注册表导出)。将 JSON 文件放到以下任一位置:
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
或将 OPENCLAW_PLUGIN_CATALOG_PATHS(或 OPENCLAW_MPM_CATALOG_PATHS)指向一个或多个 JSON 文件(以逗号/分号/PATH 分隔)。每个文件应包含 { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }。解析器还将 "packages" 或 "plugins" 作为 "entries" 键的旧版别名接受。
生成的频道目录条目和提供商安装目录条目会在原始 openclaw.install 块旁边暴露归一化的安装来源事实。这些归一化事实会识别 npm 规范是精确版本还是浮动选择器、是否存在预期的完整性元数据,以及是否也可用本地源路径。当目录/包身份已知时,如果解析出的 npm 包名与该身份不一致,归一化事实会发出警告。当 defaultChoice 无效或指向不可用的来源时,以及当存在 npm 完整性元数据但没有有效 npm 来源时,它们也会发出警告。消费者应将 installSource 视为附加可选字段,这样手工构建的条目和目录兼容层就不必合成它。这使得入门和诊断能够解释源平面状态,而无需导入插件运行时。
官方外部 npm 条目应优先使用精确的 npmSpec 加上 expectedIntegrity。裸包名和 dist-tags 出于兼容性仍然可用,但它们会暴露源平面警告,以便目录能够朝着固定版本且经过完整性校验的安装演进,同时不破坏现有插件。当官方包被重命名时,目录条目可以声明 legacyNpmPackageNames 并包含旧包名。受信任更新会将匹配的 npm 记录重写为当前 npmSpec,并将目录查找别名(例如频道 ID)迁移到规范插件 ID。重复的别名+规范记录仅在规范安装也是受信任官方时才会被丢弃。legacyPluginIds 仍然是非查找别名的插件 ID 切换的约定。当入门从本地目录路径安装时,如果可能,它会记录一个受管插件索引条目,其中 source: "path" 以及相对于工作区的 sourcePath。绝对操作加载路径保留在 plugins.load.paths 中;安装记录避免将本地工作站路径重复到长期配置中。这使本地开发安装对源平面诊断可见,而不会增加第二个原始文件系统路径暴露面。持久化的 config_machine_state 值位于 plugins.installedIndex 下,是安装来源的事实来源,并且可以在不加载插件运行时模块的情况下刷新。其 installRecords 映射即使在插件清单缺失或无效时也是持久的;其 plugins 负载是可重建的清单视图。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw