Appearance
本页是 OpenClaw 插件打包配置的完整参考,解决 package.json openclaw 字段(extensions/setupEntry/channel/install/compat/build/startup)、manifest 文件格式、setup-entry.ts 与完整入口分工、延迟加载(deferConfiguredChannelFullLoadUntilAfterListen)配置、config schema 定义(JSON Schema 或 Zod/TypeBox)、ChannelSetupWizard 向导编写以及 ClawHub 发布命令。先确认插件类型(渠道/Provider/工具),再对照表格填写元数据。setupEntry 只注册 gateway 监听前所需的最小集,完整入口处理重任务。
OpenClaw 插件打包配置:package.json、manifest、setup entry 完整指南
本页是插件 package.json 元数据、manifest(openclaw.plugin.json)、setup entry 和 config schema 的完整参考。如果已经了解流程,可作为快速查阅表;如果首次开发,先参阅 渠道插件开发 或 Provider 插件开发。
Package 元数据
package.json 需要 openclaw 字段,告诉插件系统你的插件提供了什么。根据插件类型选择下方模板:
渠道插件
json
{
"name": "@myorg/openclaw-my-channel",
"version": "1.0.0",
"type": "module",
"openclaw": {
"extensions": ["./index.ts"],
"setupEntry": "./setup-entry.ts",
"channel": {
"id": "my-channel",
"label": "My Channel",
"blurb": "Short description of the channel."
}
}
}Provider 插件 / ClawHub 发布基线
json
{
"name": "@myorg/openclaw-my-plugin",
"version": "1.0.0",
"type": "module",
"openclaw": {
"extensions": ["./index.ts"],
"compat": {
"pluginApi": ">=2026.3.24-beta.2",
"minGatewayVersion": "2026.3.24-beta.2"
},
"build": {
"openclawVersion": "2026.3.24-beta.2",
"pluginSdkVersion": "2026.3.24-beta.2"
}
}
}注意: 发布到 ClawHub 时,
compat和build字段必填。规范发布代码片段见docs/snippets/plugin-publish/。
openclaw 字段总览
| 字段 | 类型 | 说明 |
|---|---|---|
extensions | string[] | 入口文件(相对于包根目录) |
setupEntry | string | 轻量 setup-only 入口(可选) |
channel | object | 渠道目录元数据,用于 setup/picker/quickstart/status 面 |
providers | string[] | 此插件注册的 Provider id |
install | object | 安装提示:npmSpec, localPath, defaultChoice, minHostVersion, expectedIntegrity, allowInvalidConfigRecovery |
startup | object | 启动行为标志 |
openclaw.channel 字段详解
openclaw.channel 是廉价元数据,仅用于渠道发现和 setup 面,不涉及 runtime 加载。
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 规范渠道 id |
label | string | 主要渠道标签 |
selectionLabel | string | 选择器/setup 标签(与 label 不同时使用) |
detailLabel | string | 次要标签,用于更丰富的渠道目录和状态面 |
docsPath | string | setup 和选择链接的文档路径 |
docsLabel | string | 文档链接中使用的标签(与 channel id 不同时使用) |
blurb | string | 简短引导/目录描述 |
order | number | 渠道目录中的排序顺序 |
aliases | string[] | 渠道选择的额外别名 |
preferOver | string[] | 本渠道优先于这些低优先级插件/渠道 id |
systemImage | string | 可选的图标/系统图片名称 |
selectionDocsPrefix | string | 选择面中文档链接前的前缀文本 |
selectionDocsOmitLabel | boolean | 在选择面中直接显示文档路径而不是带标签的文档链接 |
selectionExtras | string[] | 额外短字符串,附加在选择副本中 |
markdownCapable | boolean | 标记渠道支持 markdown 出站格式化 |
exposure | object | 渠道在 setup/configured/docs 面的可见性控制 |
quickstartAllowFrom | boolean | 将渠道纳入标准 quickstart allowFrom 设置流程 |
forceAccountBinding | boolean | 即使只有一个账号也要求显式账号绑定 |
preferSessionLookupForAnnounceTarget | boolean | 解析通知目标时优先使用会话查找 |
完整示例:
json
{
"openclaw": {
"channel": {
"id": "my-channel",
"label": "My Channel",
"selectionLabel": "My Channel (self-hosted)",
"detailLabel": "My Channel Bot",
"docsPath": "/channels/my-channel",
"docsLabel": "my-channel",
"blurb": "Webhook-based self-hosted chat integration.",
"order": 80,
"aliases": ["mc"],
"preferOver": ["my-channel-legacy"],
"selectionDocsPrefix": "Guide:",
"selectionExtras": ["Markdown"],
"markdownCapable": true,
"exposure": {
"configured": true,
"setup": true,
"docs": true
},
"quickstartAllowFrom": true
}
}
}exposure 对象支持三个子字段:
configured:是否包含在已配置/状态列表面setup:是否包含在交互式 setup/配置选择器docs:是否在文档/导航面中公开
旧版别名
showConfigured和showInSetup仍受支持,建议优先使用exposure。
openclaw.install 字段详解
openclaw.install 属于包元数据,不是 manifest 元数据。
| 字段 | 类型 | 说明 |
|---|---|---|
clawhubSpec | string | 规范 ClawHub spec,用于安装/更新和引导按需安装流程 |
npmSpec | string | 规范 npm spec,用于安装/更新回退流程 |
localPath | string | 本地开发或内置安装路径 |
defaultChoice | "clawhub" | "npm" | "local" | 多种安装源可用时的首选来源 |
minHostVersion | string | 最低支持的 OpenClaw 版本,格式 >=x.y.z 或 >=x.y.z-prerelease |
expectedIntegrity | string | 预期 npm dist integrity 字符串(通常 sha512-...),用于固定安装 |
allowInvalidConfigRecovery | boolean | 允许内置插件重装流程从特定的过期配置故障中恢复 |
引导行为
交互式引导也使用 openclaw.install 实现按需安装面。如果插件在 runtime 加载前暴露 provider 认证选项或渠道 setup/目录元数据,引导流程可以显示这些选项,提示用户选择 ClawHub/npm/本地安装,安装或启用插件,然后继续所选流程。ClawHub 引导选项使用 clawhubSpec,优先可用;npm 选项需要注册表元数据中带有 npmSpec;精确版本和 expectedIntegrity 是可选的 npm 固定项。
minHostVersion 强制
设置了 minHostVersion 后,安装和非捆绑 manifest 注册加载都会强制检查。旧版 host 会跳过外部插件;无效版本字符串会被拒绝。内置源码插件假定与 host 代码同版本。
固定 npm 安装
json
{
"openclaw": {
"install": {
"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3",
"expectedIntegrity": "sha512-REPLACE_WITH_NPM_DIST_INTEGRITY",
"defaultChoice": "npm"
}
}
}allowInvalidConfigRecovery 范围
allowInvalidConfigRecovery 不是配置损坏的通用绕过项。它只用于狭窄的内置插件恢复场景:重装/setup 可以修复已知的升级遗留问题(如丢失的内置插件路径或同一插件过时的 channels.<id> 条目)。如果配置因无关原因损坏,安装仍然失败关闭,并提示运行 openclaw doctor --fix。
延迟完整加载(Deferred Full Load)
渠道插件可以开启延迟加载,减少启动时间:
json
{
"openclaw": {
"extensions": ["./index.ts"],
"setupEntry": "./setup-entry.ts",
"startup": {
"deferConfiguredChannelFullLoadUntilAfterListen": true
}
}
}开启后,即使渠道已配置,OpenClaw 在 pre-listen 启动阶段也只加载 setupEntry,完整入口在 gateway 开始监听后才加载。
警告: 仅当
setupEntry已注册 gateway 监听前所需的全部内容(渠道注册、HTTP 路由、gateway 方法)时才启用延迟加载。如果完整入口拥有必要的启动能力,保持默认行为。
如果 setup/完整入口注册了 gateway RPC 方法,务必将它们放在插件特有的前缀下。保留的核心管理命名空间(config.*、exec.approvals.*、wizard.*、update.*)始终归属于核心,并解析到 operator.admin。
Plugin Manifest
每个原生插件必须在包根目录下提供 openclaw.plugin.json,用于在执行插件代码之前验证配置。
基础模板:
json
{
"id": "my-plugin",
"name": "My Plugin",
"description": "Adds My Plugin capabilities to OpenClaw",
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"webhookSecret": {
"type": "string",
"description": "Webhook verification secret"
}
}
}
}渠道插件需加 kind 和 channels:
json
{
"id": "my-channel",
"kind": "channel",
"channels": ["my-channel"],
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {}
}
}即使不接受任何配置的插件也必须提供 manifest,空 schema 合法:
json
{
"id": "my-plugin",
"configSchema": {
"type": "object",
"additionalProperties": false
}
}完整 manifest 字段参考见 Plugin Manifest。
ClawHub 发布
对于插件包,使用包专用的 ClawHub 命令:
bash
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
clawhub skill publish是旧版技能专用别名,插件包始终使用clawhub package publish。
Setup Entry
setup-entry.ts 是 index.ts 的轻量替代。当 OpenClaw 只需要 setup 面(引导、配置修复、禁用渠道检查)时加载。
typescript
// setup-entry.ts
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
import { myChannelPlugin } from "./src/channel.js";
export default defineSetupPluginEntry(myChannelPlugin);这样可以避免在 setup 流程中加载繁重的 runtime 代码(加密库、CLI 注册、后台服务)。
内置工作区渠道如果已经在 sidecar 模块中保持了 setup 安全的导出,可以使用 defineBundledChannelSetupEntry(...)(来自 openclaw/plugin-sdk/channel-entry-contract)替代 defineSetupPluginEntry(...)。该内置合约还支持可选的 runtime 导出,使 setup 时的 runtime 接线保持轻量和显式。
什么时候会使用 setupEntry 而非完整入口?
- 渠道已禁用但需要 setup/引导面
- 渠道已启用但未配置
- 开启了延迟加载(
deferConfiguredChannelFullLoadUntilAfterListen)
setupEntry 必须注册的内容
- 渠道插件对象(通过
defineSetupPluginEntry) - gateway 监听前所需的 HTTP 路由
- 启动时所需的 gateway 方法
- 这些启动 gateway 方法应避免使用保留的核心管理命名空间(如
config.*、update.*)
setupEntry 不应包含的内容
- CLI 注册
- 后台服务
- 繁重的 runtime 导入(加密、SDK)
- 只在启动后才需要的 gateway 方法
窄型 Setup Helper 导入
对于热门 setup-only 路径,优先使用窄型 helper 而非宽泛的 plugin-sdk/setup:
| 导入路径 | 用途 | 关键导出 |
|---|---|---|
plugin-sdk/setup-runtime | setup 时的 runtime helper,在 setupEntry/延迟渠道启动中可用 | createSetupTranslator, createPatchedAccountSetupAdapter, createEnvPatchedAccountSetupAdapter, createSetupInputPresenceValidator, noteChannelLookupFailure, noteChannelLookupSummary, promptResolvedAllowFrom, splitSetupEntries, createAllowlistSetupWizardProxy, createDelegatedSetupWizardProxy |
plugin-sdk/setup-adapter-runtime | 已废弃的兼容别名;使用 plugin-sdk/setup-runtime | createEnvPatchedAccountSetupAdapter |
plugin-sdk/setup-tools | setup/安装 CLI/归档/文档 helper | formatCliCommand, detectBinary, extractArchive, resolveBrewExecutable, formatDocsLink, CONFIG_DIR |
需要完整 setup 工具箱(包含配置 patch helper 如 moveSingleAccountChannelSectionToDefaultAccount(...))时,使用宽泛的 plugin-sdk/setup。
使用 createSetupTranslator(...) 创建固定 setup 向导文本。它遵循 CLI 向导区域设置(OPENCLAW_LOCALE,然后是系统区域设置变量),默认回退到英语。插件特有的 setup 文本应放在插件拥有的代码中,只对常见的 setup 标签、状态文本和官方内置插件 setup 副本使用共享目录键。
setup patch 适配器在热路径上是安全的:其内置的单账号升级合约接口查找是惰性的,导入 plugin-sdk/setup-runtime 不会在适配器实际使用前急切加载合约接口发现。
渠道自有的单账号升级
当渠道从顶层单账号配置升级到 channels.<id>.accounts.* 时,默认共享行为是将升级后的账号值移入 accounts.default。
内置渠道可通过其 setup 合约接口缩窄或覆盖该升级策略:
singleAccountKeysToMove:应移入升级账号的额外顶层键namedAccountPromotionKeys:当命名账号已存在时,只将这些键移入升级账号;共享策略/交付键保留在渠道根resolveSingleAccountPromotionTarget(...):选择哪个已有账号接收升级值
Matrix 是当前的内置示例。如果恰好有一个已命名的 Matrix 账号存在,或
defaultAccount指向非规范键(如Ops),升级会保留该账号而非创建新的accounts.default条目。
Config Schema
插件配置按 manifest 中的 JSON Schema 验证。用户通过以下配置来配置插件:
json5
{
plugins: {
entries: {
"my-plugin": {
config: {
webhookSecret: "abc123",
},
},
},
},
}插件注册期间通过 api.pluginConfig 接收此配置。
渠道特定配置使用渠道配置区块:
json5
{
channels: {
"my-channel": {
token: "bot-token",
allowFrom: ["user1", "user2"],
},
},
}构建渠道 Config Schema
使用 buildChannelConfigSchema(来自 openclaw/plugin-sdk/channel-config-schema)将 Zod schema 转换为 OpenClaw 验证的 ChannelConfigSchema 包装器:
typescript
import { z } from "zod";
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
const accountSchema = z.object({
token: z.string().optional(),
allowFrom: z.array(z.string()).optional(),
accounts: z.object({}).catchall(z.any()).optional(),
defaultAccount: z.string().optional(),
});
const configSchema = buildChannelConfigSchema(accountSchema);如果你已经将合约编写为 JSON Schema 或 TypeBox,使用直接 helper 可以让 OpenClaw 在元数据路径上跳过 Zod 到 JSON Schema 的转换:
typescript
import { Type } from "typebox";
import { buildJsonChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
const configSchema = buildJsonChannelConfigSchema(
Type.Object({
token: Type.Optional(Type.String()),
allowFrom: Type.Optional(Type.Array(Type.String())),
}),
);对于第三方插件,冷路径合约仍然是插件 manifest:将生成的 JSON Schema 镜像到 openclaw.plugin.json#channelConfigs,这样配置 schema、setup 和 UI 面可以在不加载 runtime 代码的情况下检查 channels.<id>。
Setup 向导
渠道插件可以为 openclaw onboard 提供交互式 setup 向导。向导是一个 ChannelSetupWizard 对象,位于 ChannelPlugin 上:
typescript
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/channel-setup";
const setupWizard: ChannelSetupWizard = {
channel: "my-channel",
status: {
configuredLabel: "Connected",
unconfiguredLabel: "Not configured",
resolveConfigured: ({ cfg }) => Boolean((cfg.channels as any)?.["my-channel"]?.token),
},
credentials: [
{
inputKey: "token",
providerHint: "my-channel",
credentialLabel: "Bot token",
preferredEnvVar: "MY_CHANNEL_BOT_TOKEN",
envPrompt: "Use MY_CHANNEL_BOT_TOKEN from environment?",
keepPrompt: "Keep current token?",
inputPrompt: "Enter your bot token:",
inspect: ({ cfg, accountId }) => {
const token = (cfg.channels as any)?.["my-channel"]?.token;
return {
accountConfigured: Boolean(token),
hasConfiguredValue: Boolean(token),
};
},
},
],
};ChannelSetupWizard 类型支持 credentials、textInputs、dmPolicy、allowFrom、groupAccess、prepare、finalize 等。完整示例参考内置插件包(如 Discord 插件的 src/channel.setup.ts)。
共享 allowFrom 提示
对于只需标准 note → prompt → parse → merge → patch 流程的 DM allowlist 提示,优先使用 openclaw/plugin-sdk/setup 中的共享 helper:createPromptParsedAllowFromForAccount(...)、createTopLevelChannelParsedAllowFromPrompt(...)、createNestedChannelParsedAllowFromPrompt(...)。
标准渠道 setup 状态
对于仅因标签、评分和可选额外行而不同的渠道 setup 状态块,优先使用 openclaw/plugin-sdk/setup 中的 createStandardChannelSetupStatus(...),而不是在每个插件中手写相同的 status 对象。
可选渠道 setup 面
对于只在特定上下文中出现的可选 setup 面,使用 createOptionalChannelSetupSurface:
typescript
import { createOptionalChannelSetupSurface } from "openclaw/plugin-sdk/channel-setup";
const setupSurface = createOptionalChannelSetupSurface({
channel: "my-channel",
label: "My Channel",
npmSpec: "@myorg/openclaw-my-channel",
docsPath: "/channels/my-channel",
});
// 返回 { setupAdapter, setupWizard }plugin-sdk/channel-setup 还暴露了底层构建器 createOptionalChannelSetupAdapter(...) 和 createOptionalChannelSetupWizard(...),适用于只需要可选安装面的半边情况。生成的可选适配器/向导在真实配置写入时故障关闭;它们复用一条"安装必需"的消息,适用于 validateInput、applyAccountConfig 和 finalize,当设置了 docsPath 时会附加文档链接。
二进制后端 setup helper
对于二进制后端 setup UI,优先使用共享委托 helper:
createDetectedBinaryStatus(...):状态块仅依赖于标签、提示、评分和二进制检测createCliPathTextInput(...):路径后端的文本输入createDelegatedSetupWizardStatusResolvers(...)、createDelegatedPrepare(...)、createDelegatedFinalize(...)、createDelegatedResolveConfigured(...):当setupEntry需要惰性委托给更重的完整向导时使用createDelegatedTextInputShouldPrompt(...):当setupEntry只需要委托textInputs[*].shouldPrompt决策时使用
发布与安装
外部插件: 发布到 ClawHub 或 npm,然后安装:
bash
openclaw plugins install @myorg/openclaw-my-plugin裸包 spec 会在启动切换期间从 npm 安装。
bash
# 强制 ClawHub
openclaw plugins install clawhub:@myorg/openclaw-my-plugin
# 强制 npm(适用于未迁移的包)
openclaw plugins install npm:@myorg/openclaw-my-plugin内部仓库插件: 放入内置插件工作区目录,构建时自动发现。
用户安装方式:
bash
openclaw plugins install <package-name>
openclaw plugins install会在~/.openclaw/npm下安装包,并禁用生命周期脚本。保持插件依赖树为纯 JS/TS,避免需要postinstall构建的包。
Gateway 启动不会安装插件依赖。npm/git/ClawHub 安装流程负责依赖汇聚;本地插件必须已安装其依赖。
内置包元数据是显式的,而不是在 gateway 启动时从构建的 JavaScript 推断。runtime 依赖属于拥有它们的插件包;打包后的 OpenClaw 启动永远不会修复或镜像插件依赖。
相关文档
- 构建插件入门 — 分步指南
- Plugin Manifest 参考 — 完整 manifest schema
- SDK 入口点 —
definePluginEntry和defineChannelPluginEntry
常见问题
setupEntry 和完整入口(index.ts)的职责怎么划分?
setupEntry 只注册"渠道禁用/未配置时也需要的最小集合":渠道插件对象本身(通过 defineSetupPluginEntry)、setup 流程中需要的 HTTP 路由和 gateway 方法。繁重的后台服务、CLI 注册器、SDK 初始化都放完整入口。原则:setupEntry 不引入 runtime 依赖,开机即可加载。
什么情况下需要开启 deferConfiguredChannelFullLoadUntilAfterListen?
当渠道 runtime 较重(如需要动态编译、大量 SDK 初始化)且 pre-listen 阶段不需要它时,开启延迟加载可以缩短 gateway 启动时间。前提是 setupEntry 已经注册好 gateway 监听前所需的全部内容。如果完整入口有启动必需的内容,不要开启,否则 gateway 可能在完整入口加载完成前就开始处理请求。
发布插件时 compat.minGatewayVersion 有什么作用?
minGatewayVersion 声明插件运行所需的最低 OpenClaw 版本。用户使用旧版 gateway 安装插件时,系统会提示版本不兼容并拒绝安装,防止因接口不匹配导致的静默错误。发布到 ClawHub 时此字段必填。如果设置不当导致版本冲突,可以用 openclaw doctor --fix 检查。