

























面向 OpenClaw.NET 用户与贡献者的
compat/public-smoke.json完整技术指南。
compat/public-smoke.json 是 OpenClaw.NET 兼容性验证体系的核心清单文件。它承担着以下关键职责:
OpenClaw.Core 程序集,对 NativeAOT 完全友好,运行时无需访问文件系统。无论是发布前的回归验证、外部集成方的兼容性自查,还是社区贡献者新增插件,都以该清单为唯一事实来源(Single Source of Truth)。
清单顶层是一个带版本号的 JSON 对象,entries 字段为条目数组:
{
"version": 2,
"entries": [
{
"id": "agentseo-plugin",
"category": "ts-jiti-plugin",
"kind": "npm-plugin",
"spec": "@agentseo/openclaw-plugin@0.1.4",
"packageName": "@agentseo/openclaw-plugin",
"pluginId": "agentseo",
"expectedStatus": "compatible",
"configJson": "{\"apiKey\":\"test_key\"}",
"expectedToolNames": ["agentseo_audit", "agentseo_keywords"],
"expectedSkillNames": ["agentseo"]
}
]
}
字段按用途分为三组:通用字段、技能专用字段、插件专用字段。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | 场景唯一标识,须在 entries 中保持唯一 |
category |
string | 场景分类:pure-skill、js-tool-plugin、ts-jiti-plugin、config-schema-plugin、unsupported-surface-plugin |
kind |
string | 资源类型:clawhub-skill 或 npm-plugin |
kind == "clawhub-skill")| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
slug |
string | ✅ | ClawHub 中的技能标识符 |
version |
string | ✅ | 技能的 SemVer 版本 |
expectedRelativePath |
string | ✅ | 安装后的预期相对路径,如 skills/my-skill/SKILL.md |
kind == "npm-plugin")| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
spec |
string | ✅ | NPM 包规范,如 @agentseo/openclaw-plugin@0.1.4 |
packageName |
string | ✅ | NPM 包名 |
pluginId |
string | ✅ | 插件唯一标识 |
expectedStatus |
string | ✅ | 预期兼容性状态:compatible 或 incompatible |
configJson |
string | ⭕️ | JSON 字符串形式的示例配置 |
installExtraPackages |
string[] | ⭕️ | 需要额外安装的依赖包列表 |
expectedToolNames |
string[] | ⭕️ | 预期暴露的工具名称(仅 compatible 场景) |
expectedSkillNames |
string[] | ⭕️ | 预期提供的技能名称(仅 compatible 场景) |
expectedDiagnosticCodes |
string[] | ⭕️ | 预期的诊断错误码(仅 incompatible 场景) |
⚠️ 注意:NPM 插件条目必须显式指定
expectedStatus,编译期校验会拒绝缺失该字段的条目。
OpenClaw.NET 共定义了 5 种 category,覆盖了从纯技能到负面用例的全部典型场景:
| Category | 说明 | 测试目的 | 典型示例 |
|---|---|---|---|
pure-skill |
独立技能包,无 NPM 依赖 | 验证 SKILL.md 格式与 ClawHub 安装流程 | pdf-form-filler |
js-tool-plugin |
JavaScript 编写的桥接插件 | 验证 JS 插件加载与工具导出 | @example/js-plugin |
ts-jiti-plugin |
TypeScript + JITI 转译的插件 | 验证 TypeScript 转译与 JITI 集成 | @agentseo/openclaw-plugin |
config-schema-plugin |
配置校验负面场景 | 验证无效配置被检测并返回诊断码 | 缺失必填字段 / 字段类型错误 |
unsupported-surface-plugin |
不支持功能的负面场景 | 验证不支持的 API 被显式拒绝 | 注册 CLI 命令 / 调用受限 API |
expectedStatus = "compatible")expectedToolNames 与 expectedSkillNames 进行断言;expectedStatus = "incompatible")expectedDiagnosticCodes 断言错误码;| 诊断码 | 含义 |
|---|---|
config_one_of_mismatch |
配置不满足 oneOf 约束 |
unsupported_cli_registration |
插件尝试注册不支持的 CLI 命令 |
unsupported_surface_call |
调用了未公开/受限的 API 表面 |
schema_required_missing |
必填字段缺失 |
OpenClaw CLI 提供 compatibility catalog 子命令,便于本地查询与脚本消费:
# 查看所有条目
openclaw compatibility catalog
# 按状态过滤
openclaw compatibility catalog --status compatible
openclaw compatibility catalog --status incompatible
# 按类型与分类过滤
openclaw compatibility catalog --kind npm-plugin --category ts-jiti-plugin
# JSON 格式输出(适用于程序化消费)
openclaw compatibility catalog --json
# 简写形式
openclaw compat catalog
Gateway 通过 /api/integration/compatibility 路由族对外暴露:
GET /api/integration/compatibility/catalog
GET /api/integration/compatibility/catalog?compatibilityStatus=compatible
GET /api/integration/compatibility/catalog?kind=npm-plugin&category=ts-jiti-plugin
GET /api/integration/compatibility/export
/catalog 端点支持 compatibilityStatus、kind、category 三个查询参数过滤;/export 端点返回完整的兼容性报告,包含运行时模式(AOT / JIT)、安全态势(Security Posture)、通道就绪状态(Channel Readiness)等额外维度,适合在 CI 中归档或对接外部门户。测试类 PublicCompatibilitySmokeTests 在运行时自动读取清单并迭代执行:
OPENCLAW_PUBLIC_SMOKE=1 必须设置,否则测试整体跳过;npx clawhub 安装并校验 expectedRelativePath 文件存在;compatible 插件:执行安装、加载、然后断言 expectedToolNames / expectedSkillNames 完整暴露;incompatible 插件:执行安装、加载,断言加载失败且诊断码集合至少包含 expectedDiagnosticCodes 中的全部条目。在 GitHub Actions 中,public-compatibility-smoke 作业承担清单的回归验证:
schedule)或手动派发(workflow_dispatch);npm 与 clawhub 命令链路);dotnet test + --filter Category=PublicSmoke;{
"id": "my-new-skill",
"category": "pure-skill",
"kind": "clawhub-skill",
"slug": "my-new-skill",
"version": "1.0.0",
"expectedRelativePath": "skills/my-new-skill/SKILL.md"
}
{
"id": "my-plugin",
"category": "js-tool-plugin",
"kind": "npm-plugin",
"spec": "@my-org/openclaw-plugin@1.0.0",
"packageName": "@my-org/openclaw-plugin",
"pluginId": "my-plugin",
"expectedStatus": "compatible",
"configJson": "{\"apiKey\":\"test_key\"}",
"expectedToolNames": ["my_tool_1", "my_tool_2"],
"expectedSkillNames": ["my-skill"]
}
{
"id": "broken-plugin-example",
"category": "config-schema-plugin",
"kind": "npm-plugin",
"spec": "@my-org/broken-plugin@1.0.0",
"packageName": "@my-org/broken-plugin",
"pluginId": "broken-plugin",
"expectedStatus": "incompatible",
"configJson": "{\"wrongField\": 123}",
"expectedDiagnosticCodes": ["config_one_of_mismatch"]
}
在 compat/public-smoke.json 的 entries 数组末尾追加条目;
确保必填字段完整:
expectedStatus、spec、packageName、pluginId;slug、version、expectedRelativePath;本地设置 OPENCLAW_PUBLIC_SMOKE=1 并执行:
dotnet test OpenClaw.Net.slnx --filter Category=PublicSmoke
如引入了新的 category 或 kind,需同步:
version 字段;PublicCompatibilityCatalog 中的枚举与转换逻辑;清单在运行时通过 PublicCompatibilityCatalog.CreateCatalog() 转换为富目录(Rich Catalog),以便 CLI 与 REST API 直接消费。核心映射规则如下:
| 源字段 | 生成字段 | 转换逻辑 |
|---|---|---|
slug / packageName / pluginId / id |
Subject |
按优先级取第一个非空值 |
kind + spec / slug |
InstallCommand |
技能:openclaw clawhub install {slug}插件: openclaw plugins install {spec} --dry-run |
category + expectedStatus |
Summary |
根据场景性质生成人类可读描述 |
expectedStatus |
ScenarioType |
compatible → "positive"incompatible → "negative" |
| 多字段组合 | Guidance[] |
上下文相关的操作建议(如"配置 schema 错误,请参考插件文档") |
OpenClaw.NET 的 NativeAOT 约束直接影响清单的加载与序列化方式:
compat/public-smoke.json 在 .csproj 中以 <EmbeddedResource> 方式编译进 OpenClaw.Core.dll,运行时无任何文件 I/O;CoreJsonContext(基于 JsonSerializerContext 的 source generator)反序列化清单,完全规避反射;plugin-bridge.mjs 走 JSON-RPC over stdio,避免在主进程中动态加载托管程序集;| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| 测试报告 "plugin failed to load" | configJson 格式错误或字段类型不匹配 |
检查 JSON 是否符合插件实际 schema,使用 --dry-run 先行验证 |
| "expected tool not found" | 插件未声明该工具或工具名拼写错误 | 校对 expectedToolNames 与插件运行时实际暴露的工具名 |
| 编译期错误 "npm-plugin must declare expectedStatus" | 新条目缺少 expectedStatus 字段 |
明确指定 "compatible" 或 "incompatible" |
| 烟雾测试整体未运行 | 环境变量未设置 | 设置 OPENCLAW_PUBLIC_SMOKE=1 后重试 |
clawhub 安装失败 |
Node.js 未安装或版本过低 | 安装 Node.js 20+ 并确保 npx 可用 |
expectedDiagnosticCodes 不匹配 |
错误码命名变更或新增 | 查阅最新诊断码列表,必要时同步更新清单 |
| AOT 模式启动报缺少元数据 | 新增字段未在 CoreJsonContext 中声明 |
在源生成上下文中添加对应类型 |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。