CLI 与发现
用于本地 Gateway 发现、插件自有 CLI 命令和本地 AI CLI 后端的注册器。属于 Plugin SDK 概述 的一部分。
Gateway 发现注册¶
api.registerGatewayDiscoveryService(...) 允许插件在 mDNS/Bonjour 等本地发现传输协议上广播当前活动的 Gateway。OpenClaw 在启用本地发现时于 Gateway 启动期间调用该服务,传入当前 Gateway 端口和非机密 TXT 提示数据,并在 Gateway 关闭时调用返回的 stop 处理器。
api.registerGatewayDiscoveryService({
id: "my-discovery",
async advertise(ctx) {
// startMyAdvertiser is your plugin's own mDNS/Bonjour helper, not an SDK export.
const handle = await startMyAdvertiser({
gatewayPort: ctx.gatewayPort,
tls: ctx.gatewayTlsEnabled,
displayName: ctx.machineDisplayName,
});
return { stop: () => handle.stop() };
},
});
Gateway 发现插件不得将广播的 TXT 值视为机密或认证凭据。发现仅作路由提示;信任仍由 Gateway 认证和 TLS 证书固定负责。
CLI 注册元数据¶
可执行 CLI 还拥有通过 openclaw/plugin-sdk/provider-catalog-runtime 在注册、操作执行或清理期间借用的提供者回调。它会在调用实际工作完成后释放这些 SDK 声明(claims),即使清理警告已经报告了超时。强制进程退出仍可能中断异步释放。调用方拥有的程序和 Gateway 启动过程不会仅仅因为调用了 CLI 辅助函数就成为可执行 CLI 的拥有者;请参阅保留的 SDK 契约。
api.registerCli(registrar, opts?) 接受两种命令元数据:
commands:由注册器拥有的显式命令名descriptors:解析期命令描述符,用于 CLI 帮助、路由和插件 CLI 的懒加载注册parentPath:可选父命令路径,用于嵌套命令组,例如["nodes"]
对于配对节点(paired-node)功能,优先使用 api.registerNodeCliFeature(registrar, opts?)。它是 api.registerCli(..., { parentPath: ["nodes"] }) 的轻量封装,使 openclaw nodes canvas 等命令成为显式的插件自有节点功能。
当插件自有的节点命令需要相同的 Gateway 标志、调用封装(invoke envelope)、终端呈现和授权提示时,请复用核心节点 CLI 拥有者:
import {
buildNodeInvokeParams,
getNodesTheme,
nodesCallOpts,
runNodesCommand,
} from "openclaw/plugin-sdk/node-cli-runtime";
如果希望插件命令在常规根 CLI 路径中保持懒加载,请提供覆盖该注册器暴露的每个顶层命令根的 descriptors。
api.registerCli(
async ({ program }) => {
const { registerMatrixCli } = await import("./src/cli.js");
registerMatrixCli({ program });
},
{
descriptors: [
{
name: "matrix",
description: "Manage Matrix accounts, verification, devices, and profile state",
hasSubcommands: true,
},
],
},
);
当命令为 JSON、JSONL 或其他机器可读格式保留 stdout,且不单纯依赖字面量 --json 标志时,根描述符还可以声明 machineOutput({ argv, stdoutIsTTY })。OpenClaw 在插件激活之前评估此解析器,以便启动诊断信息可以路由到 stderr。解析器必须是同步的纯函数且依赖极轻:仅检查提供的原始 argv 和 stdout 的 TTY 状态。在轻量 CLI 元数据和完整注册中复用同一解析器,以确保发现与执行不会产生分歧。当解析器需要命令路径令牌时,请使用 openclaw/plugin-sdk/cli-argv 中的 getRootOptionAwareCommandPath;它接受位于命令根之前或之后的受支持根选项。machineOutput 是根元数据;嵌套描述符不能使用它,因为其所属根必须在它们可见之前已经处于激活状态。
嵌套命令接收解析后的父命令作为 program:
api.registerCli(
async ({ program }) => {
const { registerNodesCanvasCommands } = await import("./src/cli.js");
registerNodesCanvasCommands(program);
},
{
parentPath: ["nodes"],
descriptors: [
{
name: "canvas",
description: "Present hosted widgets on a paired Mac",
hasSubcommands: true,
},
],
},
);
仅当不需要懒加载根 CLI 注册时,才单独使用 commands。该即时(eager)兼容路径仍然受支持,但它不会为解析期懒加载安装基于描述符的占位符。
注册器接收原生的 Commander 对象。注册器内注册的回调会保留插件实例,供后续操作、钩子、解析、帮助和事件使用。通过 program.addCommand 添加的预配置命令树也会将其回调转移到添加方实例。注册前已附加到宿主上的命令仍归调用方所有;命令身份以及函数型参数或选项数据不会改变。重新加载或禁用会拒绝新的回调调用,同时等待已受理的异步操作完成。
CLI 后端注册¶
api.registerCliBackend(...) 允许插件拥有本地 AI CLI 后端(如 claude-cli 或 my-cli)的默认配置。
- 后端
id成为模型引用中的提供者前缀,例如my-cli/gpt-5。 - 后端
config是权威的命令适配器:argv、环境、解析器、会话、图像和可靠性行为都位于插件代码中。 - 用户通过模型引用或模型作用域的
agentRuntime.id选择后端;openclaw.json不会重写该适配器。 - 当已注册的静态字段需要感知运行时的规范化处理时,使用
normalizeConfig。 - 对于属于 CLI 方言的请求级 argv 重写,使用
resolveExecutionArgs,例如将 OpenClaw 思考级别映射到原生 effort 标志。该钩子接收ctx.executionMode;使用"side-question"为临时/btw调用添加后端原生的隔离标志。如果这些标志对于原本始终开启的 CLI 能可靠地禁用原生工具,请同时声明sideQuestionToolMode: "disabled"。 - 对于后端拥有的启动环境或临时认证/配置桥接,使用
prepareExecution。其ctx.contextTokenBudget是为本次运行选择的有效令牌限制,因此支持原生压缩的后端可以在无需提供者特定核心分支的情况下对齐自身的阈值。对于通过启动环境或分阶段配置来应用该级别的后端,其可选的ctx.thinkingLevel表示off、minimal、low、medium、high、xhigh、adaptive或max中的实际生效选择。当后端暂存必须扩展捆绑的 MCP 设置时,它还会接收核心准备好的ctx.env。 - 能够在特定运行中禁用所有原生工具的后端可以声明
nativeToolMode: "selectable"。受限调用会传递精确的ctx.toolAvailability.native列表以及规范的ctx.toolAvailability.openClaw名称。声明toolAvailabilityEnforcement: "execution-args"并在最终的 fresh/resume argv 中执行该契约;或声明"prepare-execution",在分阶段策略中强制执行,并返回toolAvailabilityEnforced: true。OpenClaw 会针对运行时上限(如 crontoolsAllow)禁用原生工具,并且当声明的执行路径不完整时以关闭状态失败(fail closed)。
有关端到端编写指南,请参阅 CLI 后端插件。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw