openclaw/plugin-inspector
GitHub: openclaw/plugin-inspector
一个用于在离线、免凭证环境下检查 OpenClaw 插件兼容性的 CI 工具,在插件交付前自动验证 manifest 契约、hook 注册和 SDK 导入,并输出 JSON、Markdown、SARIF、JUnit 等多格式报告。
Stars: 20 | Forks: 7

# OpenClaw 插件检查器
`@openclaw/plugin-inspector` 是 OpenClaw 插件包和插件 fixture 套件的离线兼容性检查器。
它负责解答在插件交付给用户之前的那些关键问题:
- OpenClaw 能否发现包元数据和 `openclaw.plugin.json` manifest?
- 插件使用了哪些 hook、注册调用、manifest 契约以及 SDK 导入?
- 在没有本地 OpenClaw 内部模块的情况下,插件是否依然保持兼容?
- 如果 CI 发现了故障,下游自动化流程应该读取哪些 JSON、Markdown、SARIF、JUnit 和摘要产出物?
- 当像 Crabpot 这样的 fixture 套件测试工具运行大量插件时,哪些发现属于严重故障、已知警告、实时问题、弃用或检查器验证漏洞?
默认路径是静态、离线且无需凭证的。运行时捕获功能虽然存在,但需要主动开启,因为它会导入插件代码。
## 环境要求
- Node.js 22 或更高版本。
- 一个包含 `package.json` 的插件包根目录。
- 当插件使用 OpenClaw manifest 契约时,需要 `openclaw.plugin.json`。
- 默认检查不需要 OpenClaw 代码检出、凭证、网络服务或实时 provider 访问权限。
当 CI 不应与本地 OpenClaw 检出进行比较时,请传入 `--no-openclaw`。如果通过 `--openclaw
` 提供 OpenClaw 检出路径,检查器只会读取公共兼容性接口,例如兼容性记录、SDK 导出、hook 名称、manifest 字段和注册器元数据。
## 快速开始
在插件包的根目录下运行以下命令:
```
npx @openclaw/plugin-inspector inspect --no-openclaw
```
等效的一次性运行方式:
```
pnpm dlx @openclaw/plugin-inspector inspect --no-openclaw
yarn dlx @openclaw/plugin-inspector inspect --no-openclaw
bunx @openclaw/plugin-inspector inspect --no-openclaw
```
该命令会写入:
- `reports/plugin-inspector-report.json`
- `reports/plugin-inspector-report.md`
- `reports/plugin-inspector-issues.md`
当发现严重的兼容性故障时,它将以非零状态退出。警告、建议、问题分类和日志将保留在报告中,但不一定会导致命令执行失败。
## 在插件仓库中安装
当您需要可重复的本地脚本和 CI 时,请安装该包:
```
npm install --save-dev @openclaw/plugin-inspector
```
添加脚本:
```
{
"scripts": {
"plugin:check": "plugin-inspector inspect --no-openclaw",
"plugin:ci": "plugin-inspector ci --no-openclaw --runtime --mock-sdk --allow-execute"
}
}
```
然后运行:
```
npm run plugin:check
```
初始化程序可以写入初始配置、包脚本和 GitHub Actions 工作流:
```
npx @openclaw/plugin-inspector init --ci --scripts --dry-run
npx @openclaw/plugin-inspector init --ci --scripts
```
`init` 会检测 `packageManager` 和常见的 lockfile。可以使用 `--package-manager npm`、`--package-manager pnpm`、`--package-manager yarn` 或 `--package-manager bun` 进行覆盖。除非您传入 `--force`,否则现有文件将受到保护。
## 配置
小型插件仓库可以将配置保存在 `package.json` 中:
```
{
"scripts": {
"plugin:check": "plugin-inspector inspect --no-openclaw",
"plugin:ci": "plugin-inspector ci --no-openclaw --runtime --mock-sdk --allow-execute"
},
"pluginInspector": {
"version": 1,
"plugin": {
"id": "weather",
"priority": "high",
"seams": ["dynamic-tool"],
"sourceRoot": "src",
"expect": {
"registrations": ["registerTool"]
}
},
"capture": {
"mockSdk": true
}
}
}
```
使用 `plugin-inspector.config.json` 作为独立的配置文件:
```
{
"version": 1,
"plugin": {
"id": "weather",
"priority": "high",
"seams": ["dynamic-tool"],
"sourceRoot": "src",
"expect": {
"registrations": ["registerTool"]
}
},
"capture": {
"mockSdk": true
},
"openclaw": {
"defaultCheckoutPath": "../openclaw"
}
}
```
在配置 CI 之前,请检查已解析的配置:
```
plugin-inspector config --json
```
可直接复制的示例位于:
- `examples/plugin-inspector.config.json`
- `examples/package-json-plugin-inspector.json`
## 命令
| 命令 | 用途 |
| --- | --- |
| `plugin-inspector` | `check` 的默认别名。 |
| `plugin-inspector check` | 对脚本友好的插件根目录检查。 |
| `plugin-inspector inspect` | 除非提供 `--config`,否则检查插件根目录;如果提供 `--config`,则运行 fixture 报告。 |
| `plugin-inspector ci` | 兼容性报告以及 CI 摘要、SARIF 和 JUnit 输出。 |
| `plugin-inspector config` | 以文本或 JSON 格式打印已解析的插件根目录配置。 |
| `plugin-inspector init` | 写入初始配置、脚本和可选的 GitHub Actions 工作流。 |
| `plugin-inspector report` | 使用包含多个插件的 fixture 套件配置运行。 |
| `plugin-inspector batch` | 发现文件夹下的插件根目录,并生成一份汇总的影响报告。 |
| `plugin-inspector capture` | 直接对入口点进行运行时捕获。 |
常用选项:
| 选项 | 含义 |
| --- | --- |
| `--plugin-root ` / `--root ` | 检查当前目录以外的插件。 |
| `--config ` | 读取独立的配置文件。fixture 套件的 `report` 必需。 |
| `--out ` | 将报告写入 `reports/` 以外的目录。 |
| `--openclaw ` | 与本地 OpenClaw 检出进行比较。 |
| `--no-openclaw` | 禁用 OpenClaw 检出比较。 |
| `--runtime` / `--capture` | 增加可选的运行时注册捕获。 |
| `--no-runtime` / `--no-capture` | 即使配置启用了运行时捕获,也将其禁用。 |
| `--mock-sdk` / `--sdk mock` | 在运行时捕获时使用生成的 SDK 和外部包 mock。 |
| `--real-sdk` / `--sdk real` | 使用已安装的真实 SDK 依赖而不是 mock。 |
| `--allow-execute` | 允许执行导入插件代码的命令。 |
| `--author-facing` | 将 `check`、`ci` 和 `batch` 报告的范围限制为仅包含带有 `authorRemediation` 指导的发现。 |
| `--json` | 将机器可读的 JSON 打印到标准输出。 |
| `--sarif [path]` | 从 `check` 或 `inspect` 写入 SARIF;`ci` 默认启用此项。 |
| `--junit [path]` | 从 `check` 或 `inspect` 写入 JUnit XML;`ci` 默认启用此项。 |
| `--no-sarif` / `--no-junit` | 禁用默认的 `ci` 输出。 |
运行内置帮助以获取确切的 CLI 接口:
```
plugin-inspector --help
```
## 运行时捕获
运行时捕获会在一个隔离的子进程中导入插件入口点,并记录 `register(api)` 的具体操作。当静态检查无法证明运行时实际发生的注册时,请使用此功能。
```
plugin-inspector inspect --no-openclaw --runtime --mock-sdk --allow-execute
```
`--allow-execute` 是专门的安全开关。如果没有它,导入插件代码的模式将以安全方式失败(fail closed)。对于自定义测试工具,旧版环境守卫依然有效:
```
PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector inspect --no-openclaw --runtime --mock-sdk
```
默认情况下,运行时捕获会对 `openclaw/plugin-sdk` 子路径以及在插件导入图中发现的未解析外部包使用生成的 mock。这使得兼容性 CI 保持离线和免凭证状态。它不会调用实时服务、启动 OpenClaw、运行 provider SDK,也不会模拟服务生命周期的副作用。
仅当插件工作区已经安装了真实的 SDK 依赖,并且您有意要测试该路径时,才使用 `--real-sdk`。
运行时捕获会写入:
- `reports/plugin-inspector-runtime-capture.json`
- `reports/plugin-inspector-runtime-capture.md`
直接捕获单个入口点:
```
plugin-inspector capture ./dist/index.js --mock-sdk --allow-execute
```
## CI
`plugin-inspector ci` 会写入常规的兼容性报告,以及 CI 原生的摘要、SARIF 和 JUnit 产出物。
最小化的 GitHub Actions 工作流:
```
name: plugin-inspector
on:
pull_request:
push:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
cache: npm
- run: npm ci
- run: npx @openclaw/plugin-inspector ci --no-openclaw --runtime --mock-sdk --allow-execute
- uses: actions/upload-artifact@v5
if: always()
with:
name: plugin-inspector-reports
path: reports/plugin-inspector-*
```
生成的 `ci` 产出物:
- `reports/plugin-inspector-report.json`
- `reports/plugin-inspector-report.md`
- `reports/plugin-inspector-issues.md`
- `reports/plugin-inspector-ci-summary.json`
- `reports/plugin-inspector-ci-summary.md`
- `reports/plugin-inspector.sarif`
- `reports/plugin-inspector.junit.xml`
CI 示例:
- `examples/github-actions-plugin-inspector.yml`
- `examples/github-actions-code-scanning.yml`
- `examples/gitlab-ci-plugin-inspector.yml`
- `examples/circleci-plugin-inspector.yml`
## 报告接口
兼容性报告是主要的契约。请保留字段名和发现代码,因为下游 CI 和 Crabpot 报告可能会使用它们。
重要的报告部分:
| 字段 | 含义 |
| --- | --- |
| `status` | 除非存在严重故障,否则为 `pass`。 |
| `summary` | fixture、故障、警告、建议、问题、问题类别和契约探针的计数。 |
| `targetOpenClaw` | 从可选的 OpenClaw 检出中读取的状态和公共兼容性数据。 |
| `fixtures` | 各插件的元数据、hook、注册、manifest 契约、包数据、SDK 导入和 SDK 弃用证据。 |
| `breakages` | 阻塞性的兼容性失败。 |
| `warnings` / `suggestions` | 非阻塞性的兼容性发现。 |
| `issues` | 带有严重级别和类别的标准化问题记录。 |
| `contractProbes` | 根据观察到的契约推导出的建议合成探针。 |
| `logs` | 信息性的资产清单和覆盖率记录。 |
| `decisions` | 面向维护者的后续行动或兼容性策略决策。 |
默认的 `check`、`ci` 和 `batch` 报告同时包含面向开发者的发现和内部发现。在生成面向插件开发者的输出时,请传入 `--author-facing`;该过滤后的视图仅包含带有 `authorRemediation.summary` 和 `authorRemediation.docsUrl` 的发现。
当前面向开发者的弃用警告包括已弃用的 SDK 辅助方法,例如当插件仍然依赖于旧版整个 store 的 session 结构时的 `loadSessionStore(...)`。
## CI 策略与共享报告原语
`plugin-inspector` 拥有共享的 CI 策略和报告渲染原语。像 Crabpot 这样的 fixture 套件测试工具应该调用这些导出,而不是重新实现评分、摘要、Markdown、SARIF 或 JUnit 处理。
根 API 暴露了分组的 helper:
```
import { ci } from "@openclaw/plugin-inspector";
const policyReport = ci.buildPolicyReport({
policy,
compatibilityReport,
executionResults,
strict: false,
});
await ci.writePolicyReport(policyReport);
```
CI 策略报告默认写入:
- `reports/plugin-inspector-ci-policy.json`
- `reports/plugin-inspector-ci-policy.md`
一个策略必须使用 `version: 1` 并定义:
- `allowedBlocked`
- `expectedWarnings`
- `thresholds`
- `fixtureSets`
策略评分会对严重故障、未知的阻塞性合成探针、严重的 ref diff 回归、失败的执行结果、严格的实时 P0 问题以及严格的已分类阻塞项判定为失败。非严格模式会将已分类的阻塞探针和实时 P0 问题保留为警告状态进行展示。
CI 摘要 helper 会从 `reports/` 读取已知的报告集,并生成一份机器可读格式的汇总和一份 Markdown 格式的汇总:
- 兼容性
- 运行时捕获
- 合成探针
- 冷导入就绪状态
- 工作区计划
- 平台探针
- 导入循环 profile
- 执行结果
- 运行时 profile
- ref diff
- profile diff
- CI 策略
## Fixture 套件
大多数插件开发者应该使用插件根目录工作流。当一个仓库有意检查多个插件或包时(如 Crabpot 所做的那样),请使用 fixture 套件。
```
plugin-inspector report --config crabpot.config.json --out reports
plugin-inspector report --config crabpot.config.json --out reports --check
plugin-inspector ci --config crabpot.config.json --out reports --no-openclaw
```
fixture 套件配置通过显式的 fixture helper 加载。这使得常规的插件根目录配置保持简单,同时依然支持批量兼容性测试工具。
## 公共 API
对于常规的插件仓库,请优先使用 CLI。当测试工具需要直接组合工作流时,请导入公共 API:
```
import { pluginRoot } from "@openclaw/plugin-inspector";
const { report, paths } = await pluginRoot.runCheck({
pluginRoot: process.cwd(),
openclawPath: false,
outDir: "reports",
});
console.log(report.status, paths.jsonPath);
```
稳定的分组 facade:
| Facade | 用途 |
| --- | --- |
| `pluginRoot` | 加载配置、执行检查、运行测试、捕获入口点或设置插件仓库。 |
| `fixtureSuites` | 加载 fixture 套件配置、运行报告并构建 fixture 套件就绪计划。 |
| `staticInspection` | 在不经过兼容性报告层的情况下,检查源文本或 fixture 集合。 |
| `reports` | 渲染/写入报告并对问题发现进行分类。 |
| `contracts` | 构建、渲染、验证并写入契约捕获和覆盖率。 |
| `ci` | 构建摘要、策略报告、执行结果、SARIF 和 JUnit 输出。 |
| `batch` | 发现插件根目录并汇总整个代码库的兼容性发现。 |
| `runtime` | 构建运行时 profile、profile diff、ref diff 和导入循环 profile。 |
| `synthetic` | 构建并运行合成探针计划。 |
对于现有的自动化流程,命名导出依然可用。对于新代码,请优先使用分组的 facade,因为它们能清晰展示归属并保持下游封装层的精简。
## 开发
仓库检查有意设计得小巧且离线:
```
npm test
npm run release:contents
npm run check
```
`npm run check` 会运行 Node 测试套件和包内容守卫。内容守卫通过 shell 调用 `npm pack --dry-run --json`,并验证 npm tarball 是否包含包入口点、示例、README 资源,并且不包含私有的 `test/`、`scripts/` 或 `.github/` 路径。
有用的发布准备命令:
```
npm run release:local
npm run release:readiness
npm run release:notes
npm run release:plan
npm run release:crabpot -- --crabpot ../crabpot
```
`release:readiness` 会验证本地包并检查pot 的后续跟进情况。它不会执行发布。
请保持此包轻量依赖。除非能确实降低复杂度,否则不要添加运行时依赖。默认检查必须保持离线且无需凭证。
## 发布说明
该包通过 GitHub Actions 从带有注释的 `v*` 标签进行发布。发布工作流会运行测试套件、验证 npm tarball、发布 GitHub release,并通过 npm trusted publishing 发布公开的 npm 包。
在打发布标签之前:
1. 将 `CHANGELOG.md` 的 `Unreleased` 说明移至带版本号的章节中。
2. 将 `package.json` 更新为相同的版本。
3. 将 Crabpot 的 `pluginInspectorRef` 更新为发布提交。
4. 运行 `npm run release:readiness`。
5. 运行由 `npm run release:crabpot -- --crabpot ../crabpot` 打印的 Crabpot 插件检查器冒烟测试命令。
在 npm 发布之后,更新 Crabpot 的包版本固定并运行:
```
npm run release:crabpot -- --crabpot ../crabpot --published
```
未经所有者明确批准,请勿发布 npm 包。
## 贡献说明
本仓库中没有 `CONTRIBUTING.md`。在该文件建立之前,请将上述仓库脚本作为本地契约,并遵循以下项目规则:
- 保留稳定的报告字段名和发现代码;
- 优先使用公共的 OpenClaw 插件契约,而不是核心内部模块;
- 将所有 OpenClaw 源码解析隔离在显式的 helper 之后;
- 将运行时执行保留在 `--allow-execute` 或 `PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1` 的控制之下;
- 当行为、入口点、发布元数据或 npm 包版本发生变化时,更新 Crabpot 的 `@openclaw/plugin-inspector` 版本固定/文档/冒烟测试路径,并在宣布工作完成之前运行 Crabpot 插件检查器冒烟测试。标签:GNU通用公共许可证, MITM代理, Node.js, SOC Prime, 云安全监控, 兼容性检查, 开发工具, 插件测试, 数据可视化, 暗色界面, 自定义脚本, 静态分析