@openclaw/plugin-inspector 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +81 -138
- package/examples/github-actions-plugin-inspector.yml +2 -2
- package/examples/plugin-inspector.config.json +3 -0
- package/package.json +3 -2
- package/src/advanced.js +195 -0
- package/src/api.js +91 -0
- package/src/capture-api.js +180 -12
- package/src/cli.js +69 -27
- package/src/config.js +16 -2
- package/src/index.js +9 -184
- package/src/init.js +150 -0
- package/src/inspector.js +89 -14
- package/src/mock-sdk-capture-runner.js +110 -17
- package/src/runtime-capture-report.js +11 -1
- package/src/sdk-mock.js +1266 -13
- package/src/synthetic-probes.js +153 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.2 - 2026-04-27
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Add public SDK subpath mocks, registrar return profiles, richer lifecycle capture probes, and plugin-root `init`/`--plugin-root` CLI flows.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Harden runtime capture for TypeScript entrypoints, extensionless local imports, mocked external packages, namespace imports, async output capture, and explicit mock/real SDK lanes.
|
|
12
|
+
- Refresh README and CI examples around `npx @openclaw/plugin-inspector check --no-openclaw` and opt-in runtime capture.
|
|
13
|
+
|
|
14
|
+
## 0.1.1 - 2026-04-27
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Refresh npm package docs with the simplified CLI-first README and public API surface cleanup.
|
|
19
|
+
|
|
3
20
|
## 0.1.0 - 2026-04-27
|
|
4
21
|
|
|
5
22
|
Initial public package release for `@openclaw/plugin-inspector`.
|
package/README.md
CHANGED
|
@@ -1,39 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
<img src="docs/plugin-inspector-banner.jpg" alt="openclaw plugin inspector banner"/>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
wraps the static inspection, registration capture, and report model prototyped
|
|
5
|
-
in crabpot into an npm-publishable package.
|
|
3
|
+
# OpenClaw Plugin Inspector
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
`plugin-inspector` is the offline compatibility check for OpenClaw plugins. Run
|
|
6
|
+
it from a plugin root to inspect package metadata, `openclaw.plugin.json`, SDK
|
|
7
|
+
imports, `api.on(...)`, `api.register*`, and optional runtime registration
|
|
8
|
+
capture.
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## Quick Start
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
From a plugin package directory:
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
|
-
|
|
15
|
-
npx plugin-inspector check --no-openclaw
|
|
15
|
+
npx @openclaw/plugin-inspector
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
That runs `check`, writes report artifacts to `reports/`, and exits non-zero
|
|
19
|
+
when compatibility breakages are found.
|
|
20
|
+
|
|
21
|
+
Add a local config and GitHub Actions workflow:
|
|
20
22
|
|
|
21
23
|
```bash
|
|
22
|
-
|
|
23
|
-
npx @openclaw/plugin-inspector check
|
|
24
|
+
npx @openclaw/plugin-inspector init --ci
|
|
24
25
|
```
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
Or install it as a dev dependency:
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
```bash
|
|
30
|
+
npm install --save-dev @openclaw/plugin-inspector
|
|
31
|
+
npx plugin-inspector check
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
29
35
|
|
|
30
36
|
```bash
|
|
31
|
-
plugin-inspector check
|
|
37
|
+
npx @openclaw/plugin-inspector check
|
|
38
|
+
npx @openclaw/plugin-inspector check --plugin-root ./plugins/weather
|
|
39
|
+
npx @openclaw/plugin-inspector init --ci --package-manager pnpm
|
|
32
40
|
```
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
`api.register*`, and writes:
|
|
42
|
+
`check` reads the current directory as one plugin unless `--plugin-root` is set.
|
|
43
|
+
It writes:
|
|
37
44
|
|
|
38
45
|
- `reports/plugin-inspector-report.json`
|
|
39
46
|
- `reports/plugin-inspector-report.md`
|
|
@@ -46,8 +53,8 @@ checkout:
|
|
|
46
53
|
plugin-inspector check --no-openclaw
|
|
47
54
|
```
|
|
48
55
|
|
|
49
|
-
Use
|
|
50
|
-
expected seams:
|
|
56
|
+
Use `plugin-inspector.config.json` when CI needs stable fixture metadata,
|
|
57
|
+
expected seams, or runtime capture defaults:
|
|
51
58
|
|
|
52
59
|
```json
|
|
53
60
|
{
|
|
@@ -61,6 +68,9 @@ expected seams:
|
|
|
61
68
|
"registrations": ["registerTool"]
|
|
62
69
|
}
|
|
63
70
|
},
|
|
71
|
+
"capture": {
|
|
72
|
+
"mockSdk": true
|
|
73
|
+
},
|
|
64
74
|
"openclaw": {
|
|
65
75
|
"defaultCheckoutPath": "../openclaw"
|
|
66
76
|
}
|
|
@@ -73,48 +83,51 @@ Then run:
|
|
|
73
83
|
plugin-inspector check --config plugin-inspector.config.json
|
|
74
84
|
```
|
|
75
85
|
|
|
76
|
-
|
|
86
|
+
`init --ci` writes this shape for you, plus
|
|
87
|
+
`.github/workflows/plugin-inspector.yml`. Copy-ready examples also live in
|
|
88
|
+
`examples/plugin-inspector.config.json` and
|
|
77
89
|
`examples/github-actions-plugin-inspector.yml`.
|
|
78
90
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
plugin-inspector report --config crabpot.config.json --out reports
|
|
83
|
-
```
|
|
91
|
+
## Runtime Capture
|
|
84
92
|
|
|
85
|
-
|
|
93
|
+
Runtime capture imports plugin entrypoints in an isolated subprocess and records
|
|
94
|
+
the registrations made during `register(api)`. It is opt-in because it executes
|
|
95
|
+
plugin code:
|
|
86
96
|
|
|
87
97
|
```bash
|
|
88
|
-
PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector
|
|
98
|
+
PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 npx @openclaw/plugin-inspector check --runtime --mock-sdk
|
|
89
99
|
```
|
|
90
100
|
|
|
91
|
-
|
|
101
|
+
By default, runtime capture uses a generated mock for `openclaw/plugin-sdk` and
|
|
102
|
+
common external packages so plugin code can load in clean CI without OpenClaw
|
|
103
|
+
installed. Use `--real-sdk` only when the plugin workspace already has real SDK
|
|
104
|
+
dependencies installed and you intentionally want to test that path.
|
|
92
105
|
|
|
93
|
-
|
|
94
|
-
PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector check --no-openclaw --capture
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Runtime capture creates a temporary mock `openclaw/plugin-sdk` package, imports
|
|
98
|
-
declared OpenClaw package entrypoints, calls their `register(api)` function with
|
|
99
|
-
the capture API, and writes:
|
|
106
|
+
Runtime capture writes:
|
|
100
107
|
|
|
101
108
|
- `reports/plugin-inspector-runtime-capture.json`
|
|
102
109
|
- `reports/plugin-inspector-runtime-capture.md`
|
|
103
110
|
|
|
104
|
-
|
|
111
|
+
You can also capture one entrypoint directly:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector capture ./dist/index.js --mock-sdk
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## CI
|
|
105
118
|
|
|
106
|
-
|
|
119
|
+
Minimal package scripts:
|
|
107
120
|
|
|
108
121
|
```json
|
|
109
122
|
{
|
|
110
123
|
"scripts": {
|
|
111
124
|
"plugin:check": "plugin-inspector check --no-openclaw",
|
|
112
|
-
"plugin:check:runtime": "PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector check --no-openclaw --
|
|
125
|
+
"plugin:check:runtime": "PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector check --no-openclaw --runtime --mock-sdk"
|
|
113
126
|
}
|
|
114
127
|
}
|
|
115
128
|
```
|
|
116
129
|
|
|
117
|
-
GitHub Actions:
|
|
130
|
+
GitHub Actions without a local dev dependency:
|
|
118
131
|
|
|
119
132
|
```yaml
|
|
120
133
|
name: plugin-inspector
|
|
@@ -134,8 +147,8 @@ jobs:
|
|
|
134
147
|
node-version: 24
|
|
135
148
|
cache: npm
|
|
136
149
|
- run: npm ci
|
|
137
|
-
- run:
|
|
138
|
-
- run:
|
|
150
|
+
- run: npx @openclaw/plugin-inspector check --no-openclaw
|
|
151
|
+
- run: PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 npx @openclaw/plugin-inspector check --no-openclaw --runtime --mock-sdk
|
|
139
152
|
- uses: actions/upload-artifact@v5
|
|
140
153
|
if: always()
|
|
141
154
|
with:
|
|
@@ -143,101 +156,31 @@ jobs:
|
|
|
143
156
|
path: reports/plugin-inspector-*
|
|
144
157
|
```
|
|
145
158
|
|
|
146
|
-
##
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
buildColdImportReadiness,
|
|
153
|
-
buildContractCapture,
|
|
154
|
-
buildExecutionResultsReport,
|
|
155
|
-
buildImportLoopProfile,
|
|
156
|
-
buildPlatformProbes,
|
|
157
|
-
buildProfileDiff,
|
|
158
|
-
buildRefDiff,
|
|
159
|
-
buildRuntimeProfile,
|
|
160
|
-
buildRuntimeCaptureReport,
|
|
161
|
-
buildWorkspacePlan,
|
|
162
|
-
createCaptureApi,
|
|
163
|
-
inspectFixtureSet,
|
|
164
|
-
loadInspectorConfig,
|
|
165
|
-
readOpenClawTargetSurface,
|
|
166
|
-
renderCiPolicyMarkdown,
|
|
167
|
-
renderColdImportReadinessMarkdown,
|
|
168
|
-
renderContractCaptureMarkdown,
|
|
169
|
-
renderExecutionResultsMarkdown,
|
|
170
|
-
renderImportLoopProfileMarkdown,
|
|
171
|
-
renderPlatformProbesMarkdown,
|
|
172
|
-
renderProfileDiffMarkdown,
|
|
173
|
-
renderRefDiffMarkdown,
|
|
174
|
-
renderRuntimeProfileMarkdown,
|
|
175
|
-
renderRuntimeCaptureMarkdown,
|
|
176
|
-
renderWorkspacePlanMarkdown,
|
|
177
|
-
renderMarkdownReport,
|
|
178
|
-
validateCiPolicyReport,
|
|
179
|
-
validateContractCoverage,
|
|
180
|
-
writeCiSummary,
|
|
181
|
-
writeCiPolicyReport,
|
|
182
|
-
writeColdImportReadiness,
|
|
183
|
-
writeContractCapture,
|
|
184
|
-
writeExecutionResultsReport,
|
|
185
|
-
writeImportLoopProfile,
|
|
186
|
-
writePlatformProbes,
|
|
187
|
-
writeProfileDiff,
|
|
188
|
-
writeRefDiff,
|
|
189
|
-
writeRuntimeProfile,
|
|
190
|
-
writeRuntimeCaptureReport,
|
|
191
|
-
writeWorkspacePlan,
|
|
192
|
-
writeReport,
|
|
193
|
-
} from "@openclaw/plugin-inspector";
|
|
194
|
-
|
|
195
|
-
const config = await loadInspectorConfig("crabpot.config.json");
|
|
196
|
-
const report = await inspectFixtureSet(config);
|
|
197
|
-
await writeReport(report, { outDir: "reports" });
|
|
198
|
-
|
|
199
|
-
const summary = await buildCiSummary({ reportsDir: "reports" });
|
|
200
|
-
await writeCiSummary(summary);
|
|
201
|
-
|
|
202
|
-
const policyReport = buildCiPolicyReport({ policy, compatibilityReport: report });
|
|
203
|
-
await writeCiPolicyReport(policyReport);
|
|
204
|
-
|
|
205
|
-
const capture = buildContractCapture({ report });
|
|
206
|
-
await writeContractCapture(capture);
|
|
207
|
-
const coverageErrors = validateContractCoverage(report);
|
|
208
|
-
|
|
209
|
-
const readiness = buildColdImportReadiness({ report });
|
|
210
|
-
await writeColdImportReadiness(readiness);
|
|
211
|
-
|
|
212
|
-
const target = await readOpenClawTargetSurface({ manifest: config });
|
|
213
|
-
|
|
214
|
-
const workspacePlan = await buildWorkspacePlan({ report, readiness });
|
|
215
|
-
await writeWorkspacePlan(workspacePlan);
|
|
216
|
-
|
|
217
|
-
const platformProbes = buildPlatformProbes({ plan: workspacePlan });
|
|
218
|
-
await writePlatformProbes(platformProbes);
|
|
219
|
-
|
|
220
|
-
const executionResults = await buildExecutionResultsReport({ resultsDir: ".plugin-inspector/results" });
|
|
221
|
-
await writeExecutionResultsReport(executionResults);
|
|
222
|
-
|
|
223
|
-
const importLoop = await buildImportLoopProfile({ entrypoint: "dist/index.js", runs: 3 });
|
|
224
|
-
await writeImportLoopProfile(importLoop);
|
|
225
|
-
|
|
226
|
-
const runtimeProfile = await buildRuntimeProfile({
|
|
227
|
-
commands: [{ id: "node-boot", label: "Node boot", category: "baseline", args: ["-e", "0"] }],
|
|
228
|
-
});
|
|
229
|
-
await writeRuntimeProfile(runtimeProfile);
|
|
230
|
-
|
|
231
|
-
const runtimeCapture = await buildRuntimeCaptureReport({ report, rootDir: process.cwd() });
|
|
232
|
-
await writeRuntimeCaptureReport(runtimeCapture);
|
|
233
|
-
|
|
234
|
-
const refDiff = await buildRefDiff({ baseReport, headReport });
|
|
235
|
-
await writeRefDiff(refDiff);
|
|
236
|
-
|
|
237
|
-
const profileDiff = await buildProfileDiff({ current, baseline, policy });
|
|
238
|
-
await writeProfileDiff(profileDiff);
|
|
159
|
+
## Fixture Suites
|
|
160
|
+
|
|
161
|
+
Fixture-set configs are still supported for crabpot-style compatibility suites:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
plugin-inspector report --config crabpot.config.json --out reports
|
|
239
165
|
```
|
|
240
166
|
|
|
167
|
+
Use fixture suites when one repo wants to inspect many plugins. Use plugin-root
|
|
168
|
+
`check` for normal plugin CI.
|
|
169
|
+
|
|
170
|
+
## Mocking Model
|
|
171
|
+
|
|
172
|
+
Default inspection is static, offline, and credential-free. Runtime capture is
|
|
173
|
+
the only mode that imports plugin code.
|
|
174
|
+
|
|
175
|
+
When `--mock-sdk` is enabled, the inspector generates temporary modules for
|
|
176
|
+
`openclaw/plugin-sdk` subpaths and unresolved external packages discovered in
|
|
177
|
+
the plugin import graph. The mock SDK captures registrations; it does not call
|
|
178
|
+
network services, launch OpenClaw, run provider SDKs, or emulate service
|
|
179
|
+
lifecycle side effects.
|
|
180
|
+
|
|
181
|
+
Use the mock lane for plugin compatibility CI. Keep live provider/service tests
|
|
182
|
+
in the plugin repo behind their own credentials and explicit opt-in flags.
|
|
183
|
+
|
|
241
184
|
## Scope
|
|
242
185
|
|
|
243
186
|
Default inspection is offline and credential-free. It reads manifests, package
|
|
@@ -246,5 +189,5 @@ metadata, and source files, then reports observed `api.on(...)`,
|
|
|
246
189
|
OpenClaw target checkout parsing is limited to public compatibility registries,
|
|
247
190
|
SDK package exports, manifest types, hooks, and captured registrar metadata.
|
|
248
191
|
|
|
249
|
-
Cold import capture
|
|
250
|
-
Live lanes
|
|
192
|
+
Cold import capture, synthetic contract probes, and runtime capture are explicit
|
|
193
|
+
opt-in modes. Live lanes stay credential-gated and must never run in default CI.
|
|
@@ -15,8 +15,8 @@ jobs:
|
|
|
15
15
|
node-version: 24
|
|
16
16
|
cache: npm
|
|
17
17
|
- run: npm ci
|
|
18
|
-
- run:
|
|
19
|
-
- run:
|
|
18
|
+
- run: npx @openclaw/plugin-inspector check --no-openclaw
|
|
19
|
+
- run: PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 npx @openclaw/plugin-inspector check --no-openclaw --runtime --mock-sdk
|
|
20
20
|
- uses: actions/upload-artifact@v5
|
|
21
21
|
if: always()
|
|
22
22
|
with:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/plugin-inspector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Offline compatibility inspector for OpenClaw plugins.",
|
|
6
6
|
"type": "module",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"exports": {
|
|
24
24
|
".": "./src/index.js",
|
|
25
|
+
"./advanced": "./src/advanced.js",
|
|
25
26
|
"./capture-api": "./src/capture-api.js",
|
|
26
27
|
"./ci-policy": "./src/ci-policy.js",
|
|
27
28
|
"./cold-import-readiness": "./src/cold-import-readiness.js",
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"LICENSE"
|
|
46
47
|
],
|
|
47
48
|
"scripts": {
|
|
48
|
-
"check": "npm test && npm pack --dry-run
|
|
49
|
+
"check": "npm test && npm pack --dry-run",
|
|
49
50
|
"release:local": "npm run check",
|
|
50
51
|
"test": "node --test test/*.test.js"
|
|
51
52
|
},
|
package/src/advanced.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
export {
|
|
2
|
+
escapeMarkdownTableCell,
|
|
3
|
+
renderArtifactContent,
|
|
4
|
+
renderMarkdownTable,
|
|
5
|
+
renderPaddedMarkdownTable,
|
|
6
|
+
writeArtifacts,
|
|
7
|
+
writeJsonMarkdownArtifacts,
|
|
8
|
+
} from "./artifacts.js";
|
|
9
|
+
export {
|
|
10
|
+
normalizeRepoPath,
|
|
11
|
+
posixJoin,
|
|
12
|
+
resolveFromRoot,
|
|
13
|
+
resolveRequiredFromRoot,
|
|
14
|
+
slugForArtifact,
|
|
15
|
+
toRepoPath,
|
|
16
|
+
} from "./path-utils.js";
|
|
17
|
+
export { readJsonFile, readOptionalJsonFile } from "./json-file.js";
|
|
18
|
+
export { assertRunCount, percentile } from "./stats.js";
|
|
19
|
+
export { createCaptureApi } from "./capture-api.js";
|
|
20
|
+
export {
|
|
21
|
+
buildCiPolicyReport,
|
|
22
|
+
defaultCiPolicyReportOptions,
|
|
23
|
+
renderCiPolicyMarkdown,
|
|
24
|
+
validateCiPolicy,
|
|
25
|
+
validateCiPolicyReport,
|
|
26
|
+
writeCiPolicyReport,
|
|
27
|
+
} from "./ci-policy.js";
|
|
28
|
+
export {
|
|
29
|
+
buildCiSummary,
|
|
30
|
+
defaultCiReportPaths,
|
|
31
|
+
deriveCiStatus,
|
|
32
|
+
readCiReports,
|
|
33
|
+
renderCiSummaryMarkdown,
|
|
34
|
+
writeCiSummary,
|
|
35
|
+
} from "./ci-summary.js";
|
|
36
|
+
export {
|
|
37
|
+
buildContractProbes,
|
|
38
|
+
contractProbeRules,
|
|
39
|
+
probePriority,
|
|
40
|
+
} from "./contract-probes.js";
|
|
41
|
+
export {
|
|
42
|
+
buildContractCapture,
|
|
43
|
+
defaultHookAssertions,
|
|
44
|
+
defaultHookContexts,
|
|
45
|
+
defaultHookEvents,
|
|
46
|
+
defaultRegistrationArguments,
|
|
47
|
+
defaultRegistrationAssertions,
|
|
48
|
+
renderContractCaptureMarkdown,
|
|
49
|
+
validateContractCapture,
|
|
50
|
+
writeContractCapture,
|
|
51
|
+
} from "./contract-capture.js";
|
|
52
|
+
export {
|
|
53
|
+
renderCompatibilityIssuesReport,
|
|
54
|
+
renderCompatibilityMarkdownReport,
|
|
55
|
+
} from "./compatibility-report.js";
|
|
56
|
+
export {
|
|
57
|
+
knownIssueClasses,
|
|
58
|
+
validateContractCoverage,
|
|
59
|
+
} from "./contract-coverage.js";
|
|
60
|
+
export {
|
|
61
|
+
buildColdImportReadiness,
|
|
62
|
+
renderColdImportReadinessMarkdown,
|
|
63
|
+
validateColdImportReadiness,
|
|
64
|
+
writeColdImportReadiness,
|
|
65
|
+
} from "./cold-import-readiness.js";
|
|
66
|
+
export {
|
|
67
|
+
buildIssues,
|
|
68
|
+
classifyIssueFinding,
|
|
69
|
+
deprecatedCompatRecords,
|
|
70
|
+
issueId,
|
|
71
|
+
issueMetadata,
|
|
72
|
+
issueMetadataByCode,
|
|
73
|
+
knownIssueCodes,
|
|
74
|
+
summarizeIssueClasses,
|
|
75
|
+
} from "./issues.js";
|
|
76
|
+
export {
|
|
77
|
+
buildExecutionResultsReport,
|
|
78
|
+
defaultExecutionResultsOptions,
|
|
79
|
+
renderExecutionResultsMarkdown,
|
|
80
|
+
writeExecutionResultsReport,
|
|
81
|
+
} from "./execution-results.js";
|
|
82
|
+
export {
|
|
83
|
+
buildCompatibilityFixtureReport,
|
|
84
|
+
classifyCompatibilityFixture,
|
|
85
|
+
classifyPackageContracts,
|
|
86
|
+
classifyTargetOpenClawCoverage,
|
|
87
|
+
readPackageSummaries,
|
|
88
|
+
readPluginManifests,
|
|
89
|
+
summarizePackage,
|
|
90
|
+
} from "./fixture-summary.js";
|
|
91
|
+
export {
|
|
92
|
+
buildImportLoopProfile,
|
|
93
|
+
defaultImportLoopProfileOptions,
|
|
94
|
+
renderImportLoopProfileMarkdown,
|
|
95
|
+
validateImportLoopProfile,
|
|
96
|
+
writeImportLoopProfile,
|
|
97
|
+
} from "./import-loop-profile.js";
|
|
98
|
+
export {
|
|
99
|
+
defaultOpenClawCheckoutPaths,
|
|
100
|
+
openClawTargetPathCandidates,
|
|
101
|
+
parseCompatRecordEntries,
|
|
102
|
+
parseExportedStringArray,
|
|
103
|
+
parsePluginSdkExports,
|
|
104
|
+
parseTypeFields,
|
|
105
|
+
readOpenClawTargetSurface,
|
|
106
|
+
} from "./openclaw-target.js";
|
|
107
|
+
export {
|
|
108
|
+
captureEntrypoint,
|
|
109
|
+
captureEntrypointWithMockSdk,
|
|
110
|
+
inspectCompatibilityFixtureSet,
|
|
111
|
+
inspectFixtureSet,
|
|
112
|
+
inspectPlugin,
|
|
113
|
+
inspectSourceText,
|
|
114
|
+
} from "./inspector.js";
|
|
115
|
+
export {
|
|
116
|
+
defaultPluginRootConfigFiles,
|
|
117
|
+
fixtureCheckoutPath,
|
|
118
|
+
fixtureSourceRoot,
|
|
119
|
+
inferPluginSeams,
|
|
120
|
+
loadInspectorConfig,
|
|
121
|
+
loadPluginRootConfig,
|
|
122
|
+
normalizeInspectorConfig,
|
|
123
|
+
normalizePluginRootConfig,
|
|
124
|
+
packageId,
|
|
125
|
+
validateInspectorConfig,
|
|
126
|
+
} from "./config.js";
|
|
127
|
+
export {
|
|
128
|
+
buildPluginInspectorConfig,
|
|
129
|
+
defaultInitConfigPath,
|
|
130
|
+
defaultInitWorkflowPath,
|
|
131
|
+
renderGithubActionsWorkflow,
|
|
132
|
+
writePluginInspectorInit,
|
|
133
|
+
} from "./init.js";
|
|
134
|
+
export {
|
|
135
|
+
buildPlatformProbes,
|
|
136
|
+
defaultPlatformTargets,
|
|
137
|
+
renderPlatformProbesMarkdown,
|
|
138
|
+
validatePlatformProbes,
|
|
139
|
+
writePlatformProbes,
|
|
140
|
+
} from "./platform-probes.js";
|
|
141
|
+
export {
|
|
142
|
+
buildProfileDiff,
|
|
143
|
+
defaultProfileDiffOptions,
|
|
144
|
+
renderProfileDiffMarkdown,
|
|
145
|
+
validateProfileDiff,
|
|
146
|
+
writeProfileDiff,
|
|
147
|
+
} from "./profile-diff.js";
|
|
148
|
+
export {
|
|
149
|
+
buildRefDiff,
|
|
150
|
+
defaultRefDiffDimensions,
|
|
151
|
+
defaultRefDiffOptions,
|
|
152
|
+
renderRefDiffMarkdown,
|
|
153
|
+
validateRefDiff,
|
|
154
|
+
writeRefDiff,
|
|
155
|
+
} from "./ref-diff.js";
|
|
156
|
+
export {
|
|
157
|
+
buildCompatibilityReport,
|
|
158
|
+
classifyCompatRecordCoverage,
|
|
159
|
+
renderMarkdownReport,
|
|
160
|
+
renderTextSummary,
|
|
161
|
+
writeCompatibilityReport,
|
|
162
|
+
writeReport,
|
|
163
|
+
} from "./report.js";
|
|
164
|
+
export {
|
|
165
|
+
buildRuntimeProfile,
|
|
166
|
+
defaultRuntimeProfileCommands,
|
|
167
|
+
defaultRuntimeProfileOptions,
|
|
168
|
+
renderRuntimeProfileMarkdown,
|
|
169
|
+
validateRuntimeProfile,
|
|
170
|
+
writeRuntimeProfile,
|
|
171
|
+
} from "./runtime-profile.js";
|
|
172
|
+
export {
|
|
173
|
+
buildRuntimeCaptureReport,
|
|
174
|
+
renderRuntimeCaptureMarkdown,
|
|
175
|
+
writeRuntimeCaptureReport,
|
|
176
|
+
} from "./runtime-capture-report.js";
|
|
177
|
+
export { createMockSdkPackage } from "./sdk-mock.js";
|
|
178
|
+
export {
|
|
179
|
+
buildSyntheticProbePlan,
|
|
180
|
+
defaultSyntheticHookContexts,
|
|
181
|
+
defaultSyntheticHookEvents,
|
|
182
|
+
defaultSyntheticRegistrationArguments,
|
|
183
|
+
renderSyntheticProbeMarkdown,
|
|
184
|
+
runCapturedSyntheticProbes,
|
|
185
|
+
syntheticRegistrationExecutionProfiles,
|
|
186
|
+
validateSyntheticProbePlan,
|
|
187
|
+
writeSyntheticProbePlan,
|
|
188
|
+
} from "./synthetic-probes.js";
|
|
189
|
+
export {
|
|
190
|
+
buildWorkspacePlan,
|
|
191
|
+
defaultWorkspacePlanOptions,
|
|
192
|
+
renderWorkspacePlanMarkdown,
|
|
193
|
+
validateWorkspacePlan,
|
|
194
|
+
writeWorkspacePlan,
|
|
195
|
+
} from "./workspace-plan.js";
|
package/src/api.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { createCaptureApi } from "./capture-api.js";
|
|
3
|
+
import { loadInspectorConfig, loadPluginRootConfig } from "./config.js";
|
|
4
|
+
import { writePluginInspectorInit } from "./init.js";
|
|
5
|
+
import { captureEntrypoint } from "./inspector.js";
|
|
6
|
+
import { renderTextSummary, writeCompatibilityReport } from "./report.js";
|
|
7
|
+
import { buildRuntimeCaptureReport, writeRuntimeCaptureReport } from "./runtime-capture-report.js";
|
|
8
|
+
import { inspectCompatibilityFixtureSet, inspectFixtureSet } from "./inspector.js";
|
|
9
|
+
|
|
10
|
+
export async function loadPluginConfig(options = {}) {
|
|
11
|
+
if (options.config) {
|
|
12
|
+
return options.config;
|
|
13
|
+
}
|
|
14
|
+
const cwd = options.pluginRoot ?? options.cwd;
|
|
15
|
+
if (options.configPath) {
|
|
16
|
+
return options.fixtureSet === true
|
|
17
|
+
? loadInspectorConfig(options.configPath, { cwd })
|
|
18
|
+
: loadPluginRootConfig(options.configPath, { cwd });
|
|
19
|
+
}
|
|
20
|
+
return loadPluginRootConfig(null, { cwd });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function inspectPluginRoot(options = {}) {
|
|
24
|
+
const config = await loadPluginConfig(options);
|
|
25
|
+
return inspectCompatibilityFixtureSet(config, {
|
|
26
|
+
generatedAt: options.generatedAt,
|
|
27
|
+
openclawPath: options.openclawPath,
|
|
28
|
+
targetOpenClaw: options.targetOpenClaw,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function inspectFixtureSetConfig(options = {}) {
|
|
33
|
+
const config = options.config ?? (await loadInspectorConfig(options.configPath, { cwd: options.cwd }));
|
|
34
|
+
return inspectFixtureSet(config, { generatedAt: options.generatedAt });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function writePluginReports(report, options = {}) {
|
|
38
|
+
return writeCompatibilityReport(report, {
|
|
39
|
+
basename: options.basename,
|
|
40
|
+
check: options.check,
|
|
41
|
+
cwd: options.cwd ?? options.pluginRoot,
|
|
42
|
+
issuesBasename: options.issuesBasename,
|
|
43
|
+
outDir: options.outDir,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function runPluginCheck(options = {}) {
|
|
48
|
+
const outDir = options.outDir ?? "reports";
|
|
49
|
+
const config = await loadPluginConfig(options);
|
|
50
|
+
const report = await inspectPluginRoot({ ...options, config });
|
|
51
|
+
const paths = await writePluginReports(report, { ...options, pluginRoot: config.rootDir, outDir });
|
|
52
|
+
const result = { report, paths };
|
|
53
|
+
const capture = options.capture ?? config.capture?.runtime ?? false;
|
|
54
|
+
const mockSdk = options.mockSdk ?? config.capture?.mockSdk ?? true;
|
|
55
|
+
|
|
56
|
+
if (capture === true) {
|
|
57
|
+
if (process.env.PLUGIN_INSPECTOR_EXECUTE_ISOLATED !== "1") {
|
|
58
|
+
throw new Error("runtime capture imports plugin code; rerun with PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 in an isolated workspace");
|
|
59
|
+
}
|
|
60
|
+
const runtimeCapture = await buildRuntimeCaptureReport({
|
|
61
|
+
mockSdk,
|
|
62
|
+
report,
|
|
63
|
+
rootDir: config.rootDir,
|
|
64
|
+
});
|
|
65
|
+
const runtimeCapturePaths = await writeRuntimeCaptureReport(runtimeCapture, {
|
|
66
|
+
jsonPath: path.resolve(config.rootDir, outDir, "plugin-inspector-runtime-capture.json"),
|
|
67
|
+
markdownPath: path.resolve(config.rootDir, outDir, "plugin-inspector-runtime-capture.md"),
|
|
68
|
+
});
|
|
69
|
+
result.runtimeCapture = runtimeCapture;
|
|
70
|
+
result.runtimeCapturePaths = runtimeCapturePaths;
|
|
71
|
+
if (runtimeCapture.summary.failedCount > 0) {
|
|
72
|
+
throw new Error(`plugin-inspector runtime capture failed for ${runtimeCapture.summary.failedCount} entrypoints`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (options.failOnBreakages === true && report.status !== "pass") {
|
|
77
|
+
throw new Error(`plugin-inspector found ${report.summary.breakageCount} breakages`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function capturePluginEntrypoint(entrypoint, options = {}) {
|
|
84
|
+
return captureEntrypoint(entrypoint, options);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function setupPluginInspector(options = {}) {
|
|
88
|
+
return writePluginInspectorInit(options);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { createCaptureApi, renderTextSummary };
|