defineToolPlugin、definePluginEntry、
defineChannelPluginEntry、defineSetupPluginEntry。
包条目
已安装的插件会将package.json 中的 openclaw 字段指向源条目和
构建后的条目:
extensions和setupEntry是源条目,用于工作区和 git 检出开发。runtimeExtensions和runtimeSetupEntry优先用于已安装的 包:它们让 npm 包跳过运行时 TypeScript 编译。runtimeExtensions在存在时,数组长度必须与extensions一致 (条目按位置配对)。runtimeSetupEntry需要setupEntry。- 如果声明了
runtimeExtensions/runtimeSetupEntry资源但它缺失, 安装/发现会因打包错误而失败;OpenClaw 不会静默回退到源代码。 源代码回退(见下文)仅在完全没有声明运行时条目时适用。 - 如果已安装的包只声明了一个 TypeScript 源条目,OpenClaw 会
查找匹配的构建后
dist/*.js(或.mjs/.cjs)同级文件并使用它; 否则会回退到 TypeScript 源文件。 - 所有条目路径都必须保留在插件包目录内。运行时
条目和推断出的构建后 JS 同级文件不会使越界的
extensions或setupEntry源路径变得有效。
defineToolPlugin
导入: openclaw/plugin-sdk/tool-plugin
适用于只添加代理工具的插件。它保持源代码简洁,可从 TypeBox schema 推断 config
和工具参数类型,将普通返回值包装为 OpenClaw 工具结果格式,并暴露静态元数据,
openclaw plugins build 会将其写入插件清单(contracts.tools、
configSchema)。
configSchema是可选的;省略它时会使用严格的空对象 schema (生成的清单仍会包含configSchema)。execute返回普通字符串或可序列化为 JSON 的值;该辅助函数会将其包装为文本工具结果,并将details设置为原始的(未转换为字符串的)返回值。outputSchema可选地描述原始的details值,供代码模式和工具搜索使用。目录调用会在执行前拒绝无效 schema,并在返回前验证最终值。- 对于自定义工具结果,
openclaw/plugin-sdk/tool-results导出textResult和jsonResult。 - 工具名称是静态的,因此
openclaw plugins build会从声明的工具中推导出contracts.tools,无需手动重复名称。 - 运行时加载仍保持严格:已安装的插件仍需要
openclaw.plugin.json和package.json中的openclaw.extensions。OpenClaw 绝不会执行插件代码来推断缺失的清单数据。
definePluginEntry
导入: openclaw/plugin-sdk/plugin-entry
适用于提供程序插件、高级工具插件、钩子插件,以及任何
不是 消息通道的内容。
-
id必须与openclaw.plugin.json清单中的值匹配。 -
外部会话目录使用
openclaw/plugin-sdk/session-catalog,并通过api.registerSessionCatalog(...)注册SessionCatalogProvider。必需的提供程序字段为id、label、list和read;可选钩子包括resolveCreateSession、continueSession、checkUpstreamActivity、archive、openTerminal和startTerminalSession。核心负责sessions.catalog.*网关方法;提供程序返回主机、会话、转录记录和终端计划的投影,而无需注册 RPC。列表提供程序应在每个主机完成处理时调用可选的onHost(host)回调;返回的主机数组仍必须作为最终的兼容性快照提供。resolveCreateSession({ agentId })必须在 OpenClaw 宣布支持创建会话或调用startTerminalSession之前,返回一个从配置派生的模型/运行时目标。 使用api.runtime.agent.resolveSessionCatalogCreateTarget(...)应用主机的运行时和模型允许列表策略,而不是重复实现这些逻辑。startTerminalSession({ agentId, cwd, initialMessage?, nodeId? })会创建一个全新的 CLI 终端计划。返回本地计划(kind: "local"、argv和精确的cwd,以及可选的env、pathEnv和title),或配对节点计划(kind: "node"、nodeId、command、paramsJSON和精确的cwd)。sessions.catalog.startTerminalRPC 要求具备operator.admin权限,并启用gateway.cliAgents.enabled和gateway.terminal.enabled。调用方负责提供cwd;网关要求本地目录已存在且为绝对路径,拒绝发生变化的计划cwd或主机,并在打开 PTY 之前执行常规的代理沙箱、节点配对、截止时间和连接所有权检查。 -
kind已弃用:应改为在openclaw.plugin.json清单的kind字段中声明一个互斥插槽("memory"或"context-engine")。运行时入口中的kind仅作为旧版插件的兼容性回退保留。 -
configSchema可以是一个函数,以便延迟求值。OpenClaw 会在首次访问时解析并缓存 schema,因此开销较大的 schema 构建器只会运行一次。 -
nodeHostCommands描述符可以定义isAvailable({ config, env })。返回false会从无头节点的网关声明中省略该命令及其能力。OpenClaw 会根据节点本地的启动配置对其进行评估;命令处理程序在调用时仍应验证可用性。
defineChannelPluginEntry
导入: openclaw/plugin-sdk/channel-core
使用通道专用连接封装 definePluginEntry:它会自动调用
api.registerChannel({ plugin }),提供可选的根帮助 CLI
元数据扩展点,并根据注册模式控制能力回调和完整运行时回调。
回调会根据注册模式运行(完整表格见
注册模式):
setRuntime在除"cli-metadata"和"tool-discovery"之外的所有模式下运行。在此处保存运行时引用,通常通过createPluginRuntimeStore完成。registerCliMetadata在"cli-metadata"、"discovery"和"full"模式下运行。将其作为通道自有 CLI 描述符的规范注册位置,以便根帮助保持非激活状态、发现快照包含静态命令元数据,并使常规 CLI 注册与完整插件加载保持兼容。registerFull仅在"full"和"tool-discovery"模式下运行。对于"tool-discovery",它会替代通道注册:OpenClaw 会完全跳过registerChannel/setRuntime,而是调用完整运行时回调,随后调用能力回调。将工具注册放在registerFull中,将能力提供者放在registerCapabilities中。registerCapabilities在"discovery"、"full"和"tool-discovery"模式下运行。在此处注册不产生副作用的已声明提供者,以便只读能力发现可以找到它们,而不会启动套接字、客户端、工作线程或服务。- 发现注册不会激活,但并非不导入:OpenClaw 可能会计算受信任的插件入口和通道插件模块,以构建快照。确保顶层导入没有副作用,并将套接字、客户端、工作线程和服务置于仅
"full"模式的路径之后。 - 与
definePluginEntry一样,configSchema可以是延迟工厂;OpenClaw 会在首次访问时缓存解析后的 schema。
- 对于希望延迟加载、但又不想从根 CLI 解析树中消失的插件自有根 CLI 命令,使用
api.registerCli(..., { descriptors: [...] })。描述符名称必须匹配字母、数字、连字符和下划线,并且以字母或数字开头;OpenClaw 会拒绝其他形式,并在渲染帮助信息前移除描述中的终端控制序列。应覆盖注册器暴露的每个顶层命令根。单独使用commands仍会走即时加载兼容路径。 - 根描述符可以为 JSON、JSONL 或其他不会仅因
--json而选中的机器可读 stdout 模式定义同步、纯函数式的machineOutput({ argv, stdoutIsTTY })解析器。使用openclaw/plugin-sdk/cli-argv中的getRootOptionAwareCommandPath解析命令令牌。将解析器放在轻量级 CLI 元数据中,并与完整注册共享。嵌套描述符不提供此字段。 - 对于成对节点的功能命令,使用
api.registerNodeCliFeature(...),使其归入openclaw nodes下(等价于registerCli(registrar, { parentPath: ["nodes"], ... }))。 - 对于其他嵌套插件命令,添加
parentPath,并在传递给注册器的program对象上注册命令;OpenClaw 会在调用插件前将其解析为父命令。 - 对于通道插件,从
registerCliMetadata注册 CLI 描述符,并让registerFull专注于仅运行时相关的工作。 - 如果
registerFull还注册网关 RPC 方法,请将其置于插件专用前缀下。保留的核心管理命名空间(config.*、exec.approvals.*、wizard.*、update.*)始终会强制使用operator.admin。
defineSetupPluginEntry
导入: openclaw/plugin-sdk/channel-core
用于轻量级的 setup-entry.ts 文件。只返回 { plugin },不包含运行时或 CLI 接线。
defineSetupPluginEntry(...) 与以下更窄的设置辅助工具系列搭配使用:
将重量级 SDK、CLI 注册和长期运行的运行时服务保留在完整入口中。
拆分设置和运行时接口的打包工作区通道可以改用
openclaw/plugin-sdk/channel-entry-contract 中的 defineBundledChannelSetupEntry(...)。它允许设置入口保留设置安全的插件/机密导出,同时仍然暴露一个运行时 setter:
registerSetupRuntime 仅在 "setup-runtime" 加载时运行;请将其限制为配置专用路由,或该设置流程所需的方法。
注册模式
api.registrationMode 会告诉你的插件它是如何被加载的:
defineChannelPluginEntry 会自动处理这种拆分。如果你直接为频道使用
definePluginEntry,请自行检查模式,并记住
"tool-discovery" 会跳过频道注册:
plugin.<plugin-id>.changed。事件名称必须是
一个小写段,负载必须是有界 JSON,并且 scope 必须是
operator.read、operator.write 或 operator.admin。发射器仅在
服务生命周期内存在,并会在停止或启动失败后撤销。优先使用版本
或失效负载,而不是完整记录,这样被授权的客户端可以通过插件的作用域
Gateway 方法重新读取规范状态。
发现模式会构建一个不会激活的注册表快照。它仍然可能
评估插件入口和频道插件对象,以便 OpenClaw 可以
注册频道能力和静态 CLI 描述符。将发现模式下的模块
评估视为可信但轻量:顶层不要进行网络客户端、
子进程、监听器、数据库连接、后台 worker、
凭据读取或其他实时运行时副作用。
将 "setup-runtime" 视为这样一个窗口:此时必须存在仅用于设置启动的入口,
但不能重新进入完整打包的频道运行时。适合的内容包括
频道注册、设置安全的 HTTP 路由、设置安全的网关方法,以及
委派的设置辅助程序。繁重的后台服务、CLI 注册器,以及
provider/client SDK 启动逻辑仍然应属于 "full"。
插件形态
OpenClaw 根据已加载插件的注册行为对其进行分类:
使用
openclaw plugins inspect <id> 查看插件的形态。