万字解析 OpenClaw 源码架构-插件开发前言

11 阅读15分钟

插件 SDK 架构

OpenClaw 将插件 SDK 的入口与能力导出集中在 src/plugin-sdk/ 目录,核心加载与运行时在 src/plugins/ 下实现,典型插件示例位于 extensions/ 目录中。下图展示关键模块之间的组织关系:

graph TB
subgraph "插件 SDK 入口"
SDK[index.ts]
Runtime[runtime.ts]
end
subgraph "插件子系统"
Loader[loader.ts]
Discovery[discovery.ts]
Registry[registry.ts]
Manifest[manifest.ts]
RuntimeIdx[runtime/index.ts]
RTTypes[runtime/types.ts]
Types[types.ts]
end
subgraph "示例插件"
Diffs[diffs/openclaw.plugin.json]
end
SDK --> Loader
Loader --> Discovery
Loader --> Manifest
Loader --> Registry
Loader --> RuntimeIdx
RuntimeIdx --> RTTypes
Registry --> Types
Diffs --> Manifest

核心组件

  • 插件定义与 API:通过统一的插件定义接口与 OpenClawPluginApi,插件可注册工具、钩子、HTTP 路由、通道适配器、网关方法、CLI 命令、服务、上下文引擎等。
  • 加载器:负责发现候选插件、校验路径安全、解析清单、验证配置、按策略启用/禁用、延迟初始化运行时、执行注册回调。
  • 注册表:集中管理已加载插件及其注册项(工具、钩子、HTTP 路由、通道、提供方、服务、命令),并进行冲突检测与诊断记录。
  • 运行时:为插件提供版本、配置、系统、媒体、TTS/STT、工具、通道、事件、日志、状态目录等能力;在非请求期间提供“不可用”占位以避免误用。
  • 清单与发现:支持 openclaw.plugin.json 清单与 package.json 扩展元数据,自动扫描多源路径(工作区、全局、捆绑)并进行安全检查。

架构总览

下图展示从启动到插件注册完成的端到端流程,包括安全边界、配置校验与运行时注入的关键节点:

sequenceDiagram
participant Boot as "启动器"
participant Loader as "插件加载器"
participant Disc as "插件发现"
participant Man as "清单加载"
participant Reg as "注册表"
participant Rt as "运行时"
participant Plug as "插件模块"
Boot->>Loader : 初始化加载参数
Loader->>Disc : 发现候选插件
Disc-->>Loader : 候选列表+诊断
Loader->>Man : 解析 openclaw.plugin.json
Man-->>Loader : 清单信息
Loader->>Loader : 安全校验/路径检查
Loader->>Rt : 按需创建运行时
Loader->>Reg : 创建 API 并注册
Loader->>Plug : 调用 register/activate
Plug-->>Reg : 注册工具/钩子/路由/通道等
Reg-->>Boot : 返回注册结果与诊断

详细组件分析

组件一:插件加载与生命周期

  • 发现阶段:扫描工作区、全局、捆绑与显式路径,支持 package.json 扩展入口与默认入口文件,过滤无效目录,记录诊断信息。
  • 安全校验:严格限制插件根目录边界,拒绝硬链接、越界路径、世界可写权限与可疑所有权,确保只加载可信代码。
  • 配置校验:基于清单中的 JSON Schema 对插件配置进行验证,错误即刻阻断并记录。
  • 启用策略:根据允许白名单、内存槽位策略与测试环境默认策略决定是否启用插件。
  • 注册阶段:创建 API,调用插件导出的 register/activate,收集注册项并更新注册表。
  • 运行时注入:采用惰性代理运行时,仅在首次访问时创建,避免无谓的重依赖加载。
flowchart TD
Start([开始]) --> Discover["发现候选插件"]
Discover --> Validate["安全校验<br/>边界/权限/所有权"]
Validate --> ParseManifest["解析清单<br/>openclaw.plugin.json"]
ParseManifest --> ValidateCfg["配置 Schema 校验"]
ValidateCfg --> EnablePolicy{"启用策略?<br/>白名单/内存槽位/测试默认"}
EnablePolicy --> |否| Disabled["标记为 disabled 并记录原因"]
EnablePolicy --> |是| CreateRuntime["惰性创建运行时"]
CreateRuntime --> CreateAPI["创建插件 API"]
CreateAPI --> CallRegister["调用 register/activate"]
CallRegister --> Collect["收集注册项<br/>工具/钩子/路由/通道等"]
Collect --> Done([完成])
Disabled --> Done

组件二:插件注册表与 API

  • 注册表职责:维护插件清单、工具工厂、钩子条目、HTTP 路由、通道适配器、提供方、服务、命令与诊断信息;提供冲突检测与重复注册拦截。
  • API 设计:向插件暴露统一的注册方法,包括工具、钩子、HTTP 路由、通道、网关方法、CLI、服务、命令、上下文引擎等;提供路径解析与 typed hook 注册。
  • 类型约束:严格的类型定义确保钩子名称、事件集合与结果字段一致,保障扩展稳定性。
classDiagram
class PluginRegistry {
+plugins : PluginRecord[]
+tools : PluginToolRegistration[]
+hooks : PluginHookRegistration[]
+typedHooks : TypedPluginHookRegistration[]
+channels : PluginChannelRegistration[]
+providers : PluginProviderRegistration[]
+gatewayHandlers : GatewayRequestHandlers
+httpRoutes : PluginHttpRouteRegistration[]
+cliRegistrars : PluginCliRegistration[]
+services : PluginServiceRegistration[]
+commands : PluginCommandRegistration[]
+diagnostics : PluginDiagnostic[]
}
class OpenClawPluginApi {
+id : string
+name : string
+version? : string
+description? : string
+source : string
+config : OpenClawConfig
+pluginConfig? : Record<string, unknown>
+runtime : PluginRuntime
+logger : PluginLogger
+registerTool()
+registerHook()
+registerHttpRoute()
+registerChannel()
+registerGatewayMethod()
+registerCli()
+registerService()
+registerCommand()
+registerContextEngine()
+resolvePath()
+on()
}
PluginRegistry --> OpenClawPluginApi : "创建 API"

组件三:运行时系统与子代理

  • 运行时能力:版本号、配置、系统、媒体、TTS/STT、工具、通道、事件、日志、状态目录等;在非请求期间提供“不可用”占位,防止误用。
  • 子代理接口:支持运行、等待、获取会话消息、删除会话等操作,用于派生子任务或会话管理。
  • 惰性初始化:仅在首次访问时创建实际运行时,减少启动开销。
classDiagram
class PluginRuntime {
+version : string
+config
+subagent
+system
+media
+tts
+stt
+tools
+channel
+events
+logging
+state
}
class SubagentRunParams {
+sessionKey : string
+message : string
+extraSystemPrompt? : string
+lane? : string
+deliver? : boolean
+idempotencyKey? : string
}
class SubagentRunResult {
+runId : string
}
PluginRuntime --> SubagentRunParams : "run()"
PluginRuntime --> SubagentRunResult : "run()"

组件四:插件清单与配置

  • 清单格式:openclaw.plugin.json 必须包含 id 与 configSchema,可选 name/description/version/kind/channels/providers/skills/uiHints。
  • 配置校验:使用 JSON Schema 对插件配置进行强类型校验,错误信息汇总到诊断。
  • 包装元数据:支持 package.json 中的扩展元数据,用于安装与选择逻辑。
flowchart TD
LoadManifest["加载 openclaw.plugin.json"] --> ValidateSchema{"存在 configSchema?"}
ValidateSchema --> |否| Fail["失败: 缺少 configSchema"]
ValidateSchema --> |是| Parse["解析清单字段"]
Parse --> BuildUI["构建 UI 提示"]
BuildUI --> Done([完成])

依赖关系分析

  • 松耦合:插件通过 API 注册,不直接依赖主系统内部实现;注册表统一管理注册项,避免循环依赖。
  • 外部依赖:Jiti 动态导入、边界文件读取、路径安全工具、钩子系统、网关方法类型等。
  • 冲突检测:HTTP 路由重叠、网关方法重复、提供方重复、命令重复等均在注册阶段被拦截并记录诊断。
graph LR
Loader["loader.ts"] --> Discovery["discovery.ts"]
Loader --> Manifest["manifest.ts"]
Loader --> Registry["registry.ts"]
Loader --> RuntimeIdx["runtime/index.ts"]
Registry --> Types["types.ts"]
RuntimeIdx --> RTTypes["runtime/types.ts"]

性能考虑

  • 惰性运行时:仅在首次访问时创建运行时,避免不必要的重依赖加载,显著降低启动成本。
  • 发现缓存:插件发现结果带 TTL 缓存,减少频繁扫描带来的 IO 开销。
  • 异步与并行:注册阶段对每个插件独立处理,充分利用异步能力;部分钩子事件可在后台异步处理而不阻塞主流程。
  • 资源隔离:HTTP 路由与网关方法冲突检测在注册阶段完成,避免运行期资源竞争。

插件测试与调试

OpenClaw 使用 Vitest 作为测试框架,按“套件”组织测试:默认单元/集成、端到端(E2E)、实时(Live)。测试入口与配置位于仓库根目录,插件测试集中在 extensions 目录下,配套的测试工具位于 extensions/test-utils 中。

graph TB
A["根配置<br/>vitest.config.ts"] --> B["单元/集成套件<br/>vitest.unit.config.ts"]
A --> C["端到端套件<br/>vitest.e2e.config.ts"]
A --> D["实时套件<br/>vitest.live.config.ts"]
E["测试初始化<br/>test/setup.ts"] --> A
F["插件测试样例<br/>extensions/diffs/index.test.ts"] --> A
G["插件内存测试<br/>extensions/memory-lancedb/index.test.ts"] --> A
H["插件运行时模拟<br/>extensions/test-utils/plugin-runtime-mock.ts"] --> F
I["运行时环境模拟<br/>extensions/test-utils/runtime-env.ts"] --> F

核心组件

  • 测试套件与配置
    • 默认单元/集成:通过 vitest.unit.config.ts 聚合 src 与 extensions 的 *.test.ts 文件,排除高复杂度模块以保证覆盖率稳定与执行效率。
    • 端到端(E2E):通过 vitest.e2e.config.ts 运行 src//*.e2e.test.ts 与 test//*.e2e.test.ts,采用进程隔离(forks)确保跨文件状态隔离。
    • 实时(Live):通过 vitest.live.config.ts 运行 src/**/*.live.test.ts,单 worker 串行执行,便于真实 Provider/模型行为验证。
  • 测试初始化与隔离
    • test/setup.ts 在每个测试前设置 HOME/状态隔离、安装全局警告过滤器、创建默认插件注册表、统一清理假定时器等,避免跨用例污染。
  • 插件测试工具
    • plugin-runtime-mock.ts 提供完整的 PluginRuntime 模拟对象,覆盖 config、system、media、tts、stt、tools、channel、events、logging、state、subagent 等子域,默认返回空实现或可配置的桩函数。
    • runtime-env.ts 提供最小化 RuntimeEnv 模拟,包含 log/error/exit,便于断言插件在异常路径的行为。

架构总览

下图展示测试套件、初始化脚本与插件测试之间的关系,以及插件测试中常用的模拟对象注入方式。

graph TB
subgraph "测试套件"
U["单元/集成<br/>vitest.unit.config.ts"]
E["端到端<br/>vitest.e2e.config.ts"]
L["实时<br/>vitest.live.config.ts"]
end
S["初始化<br/>test/setup.ts"]
subgraph "插件测试"
D["插件样例测试<br/>extensions/diffs/index.test.ts"]
M["内存插件测试<br/>extensions/memory-lancedb/index.test.ts"]
end
subgraph "测试工具"
PM["运行时模拟<br/>plugin-runtime-mock.ts"]
RE["运行时环境模拟<br/>runtime-env.ts"]
end
U --> D
U --> M
E --> D
L --> M
S --> U
S --> E
S --> L
D --> PM
D --> RE
M --> PM

详细组件分析

单元/集成测试(默认套件)

  • 范围与目标
    • 纯单元测试、进程内集成测试(网关认证、路由、工具链、解析、配置等),以及对已知问题的确定性回归。
    • 避免真实网络与外部服务,保证快速、稳定与可重复。
  • 关键特性
    • 支持 vmForks(Node 22/23)加速分片,Node 24+ 自动回退至 forks 以规避 VM 链接错误。
    • 可通过环境变量强制选择 fork 或 vmForks。
  • 建议实践
    • 优先在本地运行单元测试,配合覆盖率门禁(test:coverage)确保质量门槛。
    • 对于需要真实环境但又不希望引入外部依赖的场景,使用 mock 工具(见后文)。

端到端测试(E2E)

  • 范围与目标
    • 多实例网关端到端行为、WebSocket/HTTP 表面、节点配对与较重的网络交互。
  • 关键特性
    • 默认使用 vmForks 加速文件启动,CI 使用自适应工作进程(2-4),本地使用更高并发(4-8)。
    • 可通过环境变量控制工作进程数量与输出静默级别。
  • 建议实践
    • 在涉及网关协议、配对流程或多通道交互时,补充 E2E 覆盖。
    • 为长耗时场景设置合理超时,避免误判失败。

实时测试(Live)

  • 范围与目标
    • 验证真实 Provider/模型在当前时间点是否可用,捕获格式变更、调用异常、鉴权问题与限流行为。
  • 关键特性
    • 默认关闭,需显式开启(OPENCLAW_LIVE_TEST=1)。
    • 支持按模型/提供商白名单缩小范围,减少成本与波动。
    • 支持从配置文件与环境变量加载密钥,自动重试限流响应。
  • 建议实践
    • 将真实 Provider 的变更纳入实时测试矩阵,定期轮换覆盖集。
    • 对于特定 Provider 的问题,保留窄范围的实时回归用例。

插件测试样例:diffs 插件

该测试展示了插件注册、工具注册、HTTP 路由注册与系统提示钩子的验证流程,以及通过模拟 HTTP 请求验证视图渲染参数的正确性。

sequenceDiagram
participant T as "测试用例<br/>extensions/diffs/index.test.ts"
participant P as "插件实例<br/>plugin.register()"
participant RT as "运行时模拟<br/>plugin-runtime-mock.ts"
participant HR as "HTTP 路由处理器"
T->>P : 调用 register(...) 注入 RT
P->>RT : 注册工具/钩子/HTTP 路由
T->>HR : 发送 GET 请求到 /plugins/diffs 视图
HR-->>T : 返回 200 并携带主题/布局等参数

插件测试样例:memory-lancedb 插件

该测试覆盖配置模式校验、嵌入维度传递、自动捕获规则、上下文转义与注入检测、分类逻辑,以及在具备密钥时的端到端实时测试。

flowchart TD
Start(["开始"]) --> Parse["解析配置模式<br/>configSchema.parse"]
Parse --> Valid{"配置有效?"}
Valid --> |否| Throw["抛出错误"]
Valid --> |是| Embed["调用嵌入 API<br/>传递 dimensions"]
Embed --> Capture["shouldCapture 规则判断"]
Capture --> Escape["formatRelevantMemoriesContext 转义"]
Escape --> Injection["looksLikePromptInjection 检测"]
Injection --> Category["detectCategory 分类"]
Category --> Live{"存在密钥且启用实时?"}
Live --> |是| EndLive["端到端工具链测试"]
Live --> |否| EndSkip["跳过实时测试"]
Throw --> End
EndLive --> End
EndSkip --> End

测试框架使用指南

  • 套件选择与命令
    • 默认单元/集成:pnpm test
    • 覆盖率门禁:pnpm test:coverage
    • 端到端:pnpm test:e2e
    • 实时:pnpm test:live
  • 环境变量
    • 单元/集成:OPENCLAW_TEST_VM_FORKS(强制 vmForks 或 forks)
    • E2E:OPENCLAW_E2E_WORKERS(工作进程数)、OPENCLAW_E2E_VERBOSE(输出开关)
    • 实时:OPENCLAW_LIVE_TEST、OPENCLAW_LIVE_MODELS、OPENCLAW_LIVE_GATEWAY_MODELS、OPENCLAW_LIVE_PROVIDERS、OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS 等
  • 初始化与隔离
    • test/setup.ts 统一设置 HOME/状态隔离、安装警告过滤器、默认插件注册表、清理假定时器,避免跨用例污染。

模拟对象创建与测试数据准备

  • 插件运行时模拟(PluginRuntime)
    • 通过 createPluginRuntimeMock 创建完整模拟对象,覆盖 config、system、media、tts、stt、tools、channel、events、logging、state、subagent 等子域。
    • 可通过 DeepPartial 参数局部覆盖默认行为,便于聚焦测试点。
  • 运行时环境模拟(RuntimeEnv)
    • 通过 createRuntimeEnv 创建最小化环境模拟,包含 log/error/exit,适合断言插件在异常路径的行为。
  • 测试数据准备
    • 使用 Vitest 的 mock 机制替换外部依赖(如 OpenAI、LanceDB),并通过 describeLive 条件执行真实 API 调用。
    • 利用临时目录与数据库路径隔离测试状态,确保可重复与可清理。

调试工具、日志记录与错误排查

  • 日志与输出
    • E2E 套件支持静默模式,可通过 OPENCLAW_E2E_VERBOSE=1 开启详细输出。
    • 实时测试支持从配置文件与环境变量加载密钥,必要时可在容器中挂载 ~/.profile 以提供密钥。
  • 错误排查
    • 使用 test/setup.ts 安装的警告过滤器减少噪音。
    • 通过 createRuntimeEnv 捕获插件退出码,定位异常路径。
    • 对于 Provider/模型问题,优先使用实时测试的窄范围白名单,逐步缩小问题域。

性能测试与安全测试要点

  • 性能测试
    • 单元/集成套件默认使用 vmForks(Node 22/23)提升分片速度;在 Node 24+ 回退至 forks 以避免 VM 链接错误。
    • E2E 套件默认串行或低并发,确保确定性;可通过 OPENCLAW_E2E_WORKERS 调整。
  • 安全测试
    • 内存插件对敏感内容捕获与上下文转义有明确规则,防止注入与历史数据滥用。
    • 插件注册与钩子在测试中被严格验证,确保不会引入未受控的系统提示或上下文污染。

测试自动化与持续集成最佳实践

  • 套件划分
    • 默认单元/集成:必须通过 CI;用于快速反馈与稳定性保障。
    • 端到端:建议在 CI 中启用,但需注意资源与时间开销。
    • 实时:默认不进入 CI,仅在本地或受控环境中运行,避免成本与波动。
  • 环境变量与密钥
    • 通过 OPENCLAW_LIVE_* 与 Provider 特定变量控制实时测试范围与密钥来源。
    • 使用 Docker Runner 在 Linux 环境复现问题,挂载本地配置与工作区。
  • 质量门禁
    • 使用覆盖率阈值与套件超时配置,确保测试质量与执行稳定性。

依赖关系分析

  • 套件依赖
    • 所有套件共享根配置 vitest.config.ts,分别通过子配置文件覆盖 include/exclude/pool/maxWorkers 等参数。
  • 初始化依赖
    • test/setup.ts 在各套件运行前执行,负责环境隔离与默认插件注册表设置。
  • 插件测试依赖
    • 插件测试通过 plugin-runtime-mock.ts 注入运行时模拟,减少对外部系统的耦合。
    • 对真实 Provider 的测试通过 describeLive 条件执行,避免在无密钥环境下失败。
graph LR
Root["根配置<br/>vitest.config.ts"] --> Unit["单元/集成<br/>vitest.unit.config.ts"]
Root --> E2E["端到端<br/>vitest.e2e.config.ts"]
Root --> Live["实时<br/>vitest.live.config.ts"]
Setup["初始化<br/>test/setup.ts"] --> Unit
Setup --> E2E
Setup --> Live
Diff["插件样例测试<br/>extensions/diffs/index.test.ts"] --> PMock["运行时模拟<br/>plugin-runtime-mock.ts"]
Mem["内存插件测试<br/>extensions/memory-lancedb/index.test.ts"] --> PMock

性能考虑

  • 单元/集成:优先使用 vmForks(Node 22/23)提升分片速度;在 Node 24+ 回退至 forks。
  • E2E:默认低并发,避免跨文件状态泄漏;可通过环境变量调整工作进程数。
  • 实时:单 worker 串行,按需缩小模型/提供商白名单,降低成本与波动。
  • 覆盖率:仅统计实际被测试覆盖的源文件,避免无关目录影响整体阈值。

插件发布与分发

围绕插件发布与分发,仓库中与之直接相关的关键位置如下:

  • 插件清单与示例:docs/plugins/manifest.md;各扩展目录下的 openclaw.plugin.json
  • 发布检查与版本同步:scripts/release-check.ts、scripts/sync-plugin-versions.ts、scripts/sparkle-build.ts
  • CI 流水线:.github/workflows/ci.yml
  • 文档与社区插件收录:docs/plugins/community.md
  • macOS 更新通道与 Sparkle 版本规则:appcast.xml
graph TB
A["根目录"] --> B["scripts/"]
A --> C[".github/workflows/"]
A --> D["docs/plugins/"]
A --> E["extensions/*/"]
A --> F["appcast.xml"]
B --> B1["release-check.ts"]
B --> B2["sync-plugin-versions.ts"]
B --> B3["sparkle-build.ts"]
C --> C1["ci.yml"]
D --> D1["manifest.md"]
D --> D2["community.md"]
E --> E1["openclaw.plugin.json (示例)"]

核心组件

  • 插件清单与配置校验
    • 每个插件必须在根目录提供 openclaw.plugin.json,用于声明 id、配置 schema、可选的 kind/channels/providers/skills 等元数据。该清单在不执行插件代码的前提下完成配置校验,缺失或非法将阻断安装/启用。
  • 版本同步与发布检查
    • 同步脚本确保插件版本与核心版本一致,并维护变更日志条目;发布检查脚本在打包前进行多维度校验(包内文件、Sparkle 版本规则、插件 SDK 导出完整性、根依赖镜像一致性等)。
  • CI/CD 集成
    • CI 流水线按变更范围裁剪测试矩阵,包含 Node、Windows、macOS、Android 等多平台任务,以及文档变更检测、安全扫描、工作流审计等保障环节。
  • 分发渠道与审核
    • npm 发布与社区插件收录遵循明确的质量门槛与提交流程;macOS 应用更新通过 Sparkle appcast 进行版本与构建号校验。

架构总览

下图展示插件发布与分发的关键路径:从本地开发到 CI 校验,再到 npm/ClawHub 分发与 macOS Sparkle 更新。

sequenceDiagram
participant Dev as "开发者"
participant Repo as "仓库"
participant CI as "CI 流水线"
participant RC as "发布检查脚本"
participant SV as "版本同步脚本"
participant NPM as "npm 仓库"
participant Hub as "ClawHub"
participant Appcast as "Sparkle Appcast"
Dev->>Repo : 提交插件与清单
Dev->>SV : 执行版本同步对齐核心版本
Repo->>CI : 推送/发起 PR
CI->>RC : 运行发布检查包文件/SDK导出/Sparkle
RC-->>CI : 校验结果
CI-->>Dev : 测试/构建报告
Dev->>NPM : 发布插件包
Dev->>Hub : 提交社区插件收录 PR
Dev->>Appcast : 更新 macOS 版本与构建号

详细组件分析

组件一:插件清单与配置校验

  • 必备字段与行为
    • id 与 configSchema 为必填;未知 channels.* 或未知插件 id 将触发错误;禁用状态下的配置会保留但提示警告。
  • JSON Schema 要求
    • 每个插件必须提供 JSON Schema,即使为空;schema 在读写时而非运行时验证。
  • 元数据与发现
    • kind/channels/providers/skills 等可选字段用于注册与发现;排他性功能通过 plugins.slots.* 选择。
flowchart TD
Start(["开始"]) --> ReadManifest["读取 openclaw.plugin.json"]
ReadManifest --> ValidateSchema["校验 configSchema 结构"]
ValidateSchema --> SchemaOK{"schema 合法?"}
SchemaOK --> |否| Fail["报错并阻断安装/启用"]
SchemaOK --> |是| Discover["解析 kind/channels/providers/skills"]
Discover --> KnownIDs{"引用的插件 id 是否已发现?"}
KnownIDs --> |否| Fail
KnownIDs --> |是| Done(["通过"])

组件二:版本管理与同步

  • 版本对齐策略
    • 插件版本需与核心版本保持一致;同步脚本会自动更新插件 package.json 的 version 字段,并在 CHANGELOG.md 中添加对应条目。
  • 变更日志与依赖清理
    • 对于使用 workspace:* 的 openclaw 开发依赖,同步脚本会移除以避免发布污染。
  • 触发时机
    • 在核心版本升级后统一执行,保证生态一致性。
flowchart TD
A["核心版本更新"] --> B["执行 sync-plugin-versions.ts"]
B --> C["读取根 package.json.version"]
C --> D{"遍历 extensions/*"}
D --> |每个插件| E["写入 package.json.version"]
D --> |记录变更| F["追加 CHANGELOG.md 条目"]
D --> |清理依赖| G["移除 workspace:* 开发依赖"]
E --> H["完成"]
F --> H
G --> H

组件三:发布检查与质量门禁

  • 包内容校验
    • 检查 npm pack --dry-run 输出是否包含必需文件组;禁止打包特定前缀路径。
  • Sparkle 版本规则
    • 基于 appcast.xml 中的 sparkle:version 与短版本号计算楼层,确保构建号不低于规则要求。
  • 插件 SDK 导出完整性
    • 校验 dist/plugin-sdk/index.js 导出集合是否包含关键 API,防止插件运行时崩溃。
  • 根依赖镜像一致性
    • 校验插件 package.json 的依赖是否被根 package.json 的 dependencies/optionalDependencies 完整镜像,避免运行期缺失。
flowchart TD
Start(["开始发布检查"]) --> P1["校验 npm pack 文件集"]
P1 --> P2["校验 Sparkle 版本规则"]
P2 --> P3["校验插件 SDK 导出"]
P3 --> P4["校验根依赖镜像"]
P4 --> Pass{"全部通过?"}
Pass --> |否| Fail["失败并输出原因"]
Pass --> |是| Done(["通过"])

组件四:CI/CD 集成与自动化

  • 变更范围裁剪
    • 通过检测文档变更与改动范围,跳过无关重任务,提升效率。
  • 多平台矩阵
    • Node、Windows、macOS、Android 等多任务并行/分片执行;Swift 代码 lint/build/test 单独收敛。
  • 安全与合规
    • 秘密扫描、私钥检测、工作流审计、生产依赖审计等。
  • 发布检查集成
    • 在主分支推送时运行 release-check,确保发布包质量。
sequenceDiagram
participant GH as "GitHub Actions"
participant Scope as "变更范围检测"
participant Build as "构建产物"
participant Check as "发布检查"
participant Test as "多平台测试"
GH->>Scope : 检测 docs/changed-scope
Scope-->>GH : 返回需要运行的任务
GH->>Build : 构建 dist
Build-->>GH : 上传 artifacts
GH->>Check : 运行 release-check
Check-->>GH : 通过/失败
GH->>Test : 并行执行 Node/Windows/macOS/Android

组件五:分发渠道与审核标准

  • npm 发布
    • 插件作为独立 npm 包发布,供用户通过 openclaw plugins install 安装。
  • ClawHub 收录
    • 社区插件收录需满足:可在 npm 安装、源码公开、具备使用文档与问题跟踪、有明确维护信号。
  • 审核与提交流程
    • 通过 PR 添加条目,遵循候选格式,由维护团队评估质量与安全性。

组件六:macOS 更新与 Sparkle 规则

  • 版本号与构建号
    • 使用 Sparkle 的短版本号与构建号规则,appcast.xml 中的 sparkle:version 与 sparkle:shortVersionString 需满足楼层约束。
  • 构建号计算
    • 通过脚本将 CalVer 形式的短版本号转换为 Sparkle 构建号,确保单调递增与规则匹配。

依赖关系分析

  • 插件清单依赖
    • 插件 id 与 channels.* 必须在清单中声明,否则视为未知 id,导致配置校验失败。
  • 版本依赖
    • 插件版本与核心版本对齐;根依赖镜像一致性用于避免运行期缺失。
  • CI 依赖
    • CI 依赖发布检查脚本与多平台测试矩阵;发布检查依赖 appcast 与 SDK 导出。
graph LR
Manifest["openclaw.plugin.json"] --> Validate["配置校验"]
Sync["版本同步脚本"] --> Manifest
Release["发布检查脚本"] --> Pack["npm pack 校验"]
Release --> Sparkle["Sparkle 版本规则"]
Release --> SDK["SDK 导出校验"]
CI["CI 流水线"] --> Release

性能考量

  • CI 并行与分片
    • Windows 测试采用分片策略,限制并发与内存占用,减少资源争用。
  • 变更范围检测
    • 仅在必要范围内运行重型任务,缩短反馈周期。
  • 缓存与复用
    • SwiftPM 缓存、pnpm store 缓存等提升重复运行效率。