@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.
@@ -1,15 +1,68 @@
1
+ export const defaultCaptureApiRegistrarProfiles = {
2
+ registerChannel: {
3
+ returnValue: ({ args }) => registrationObject(args, { id: "channel" }),
4
+ },
5
+ registerCli: {
6
+ returnValue: ({ args }) => registrationObject(args, { name: "cli" }),
7
+ },
8
+ registerCommand: {
9
+ returnValue: ({ args }) => registrationObject(args, { name: "command" }),
10
+ },
11
+ registerContextEngine: {
12
+ returnValue: ({ args }) => registrationObject(args, { id: "context-engine" }),
13
+ },
14
+ registerGatewayMethod: {
15
+ returnValue: ({ args }) => registrationObject(args, { name: "gateway.method" }),
16
+ },
17
+ registerHook: {
18
+ returnValue: ({ api }) => api,
19
+ },
20
+ registerHttpRoute: {
21
+ returnValue: ({ args }) => ({
22
+ ...registrationObject(args, { method: "GET", path: "/" }),
23
+ unregister() {},
24
+ }),
25
+ },
26
+ registerInteractiveHandler: {
27
+ returnValue: ({ args }) => registrationObject(args, { id: "interactive-handler" }),
28
+ },
29
+ registerMemoryPromptSection: {
30
+ returnValue: ({ args }) => registrationObject(args, { id: "memory-prompt-section" }),
31
+ },
32
+ registerMemoryRuntime: {
33
+ returnValue: ({ args }) => registrationObject(args, { id: "memory-runtime" }),
34
+ },
35
+ registerProvider: {
36
+ returnValue: ({ args }) => registrationObject(args, { id: "provider" }),
37
+ },
38
+ registerService: {
39
+ returnValue: ({ args }) => ({
40
+ ...registrationObject(args, { name: "service" }),
41
+ start: async () => undefined,
42
+ stop: async () => undefined,
43
+ }),
44
+ },
45
+ registerSpeechProvider: {
46
+ returnValue: ({ args }) => registrationObject(args, { id: "speech-provider" }),
47
+ },
48
+ registerTool: {
49
+ returnValue: ({ args }) => registrationObject(args, { name: "tool" }),
50
+ },
51
+ };
52
+
1
53
  export function createCaptureApi(options = {}) {
2
54
  const captured = [];
3
55
  const retained = [];
4
- const knownRegistrars = new Set(options.knownRegistrars ?? []);
56
+ const registrarProfiles = {
57
+ ...defaultCaptureApiRegistrarProfiles,
58
+ ...(options.registrarProfiles ?? {}),
59
+ };
60
+ const knownRegistrars = new Set(options.knownRegistrars ?? Object.keys(registrarProfiles));
5
61
  const retainHandlers = options.retainHandlers === true;
6
62
 
7
63
  const api = new Proxy(
8
64
  {
9
- config: options.config ?? {},
10
- logger: options.logger ?? console,
11
- pluginConfig: options.pluginConfig ?? {},
12
- runtime: options.runtime ?? {},
65
+ ...createCaptureContext(options),
13
66
  on(name, handler) {
14
67
  const captureIndex =
15
68
  captured.push({
@@ -42,6 +95,7 @@ export function createCaptureApi(options = {}) {
42
95
  }
43
96
  if (typeof property === "string" && isRegistrarProperty(property)) {
44
97
  return (...args) => {
98
+ const returnValue = registrationReturnValue(property, args, { api, registrarProfiles });
45
99
  const captureIndex =
46
100
  captured.push({
47
101
  kind: "registration",
@@ -54,10 +108,11 @@ export function createCaptureApi(options = {}) {
54
108
  kind: "registration",
55
109
  name: property,
56
110
  arguments: args,
111
+ returnValue,
57
112
  captureIndex,
58
113
  });
59
114
  }
60
- return registrationReturnValue(property, args);
115
+ return returnValue;
61
116
  };
62
117
  }
63
118
  return undefined;
@@ -68,19 +123,122 @@ export function createCaptureApi(options = {}) {
68
123
  return api;
69
124
  }
70
125
 
126
+ export function createCaptureContext(options = {}) {
127
+ return {
128
+ config: options.config ?? {},
129
+ logger: options.logger ?? console,
130
+ pluginConfig: options.pluginConfig ?? {},
131
+ runtime: options.runtime ?? createRuntimeContext(options),
132
+ secrets: options.secrets ?? createSecretContext(options),
133
+ store: options.store ?? createStoreContext(options),
134
+ paths: options.paths ?? {
135
+ cacheDir: ".plugin-inspector/cache",
136
+ configDir: ".plugin-inspector/config",
137
+ dataDir: ".plugin-inspector/data",
138
+ },
139
+ agent: options.agent ?? {
140
+ id: "plugin-inspector-agent",
141
+ accountId: "default",
142
+ },
143
+ gateway: options.gateway ?? {
144
+ baseUrl: "http://127.0.0.1:0",
145
+ registerRoute(route) {
146
+ return {
147
+ ...route,
148
+ unregister() {},
149
+ };
150
+ },
151
+ },
152
+ fetch: options.fetch ?? (async () => ({ ok: true, status: 200, json: async () => ({}), text: async () => "" })),
153
+ };
154
+ }
155
+
71
156
  function isRegistrarProperty(property) {
72
157
  return property.startsWith("register") || property.startsWith("define");
73
158
  }
74
159
 
75
- function registrationReturnValue(name, args) {
76
- if (name === "registerService") {
160
+ function registrationReturnValue(name, args, context) {
161
+ const profile = context.registrarProfiles[name];
162
+ if (profile?.returnValue) {
163
+ return profile.returnValue({ name, args, api: context.api });
164
+ }
165
+ return registrationObject(args, {});
166
+ }
167
+
168
+ function createRuntimeContext(options) {
169
+ const runtime = options.runtime ?? {};
170
+ return {
171
+ ...runtime,
172
+ agent: runtime.agent ?? {},
173
+ env: options.env ?? {},
174
+ logger: options.logger ?? console,
175
+ now: () => new Date(0),
176
+ tts: runtime.tts ?? {},
177
+ state: {
178
+ resolveStateDir: () => options.stateDir ?? process.cwd(),
179
+ ...(runtime.state ?? {}),
180
+ },
181
+ };
182
+ }
183
+
184
+ function createSecretContext(options) {
185
+ const secrets = new Map(Object.entries(options.secretValues ?? {}));
186
+ return {
187
+ async get(name) {
188
+ return secrets.get(name) ?? null;
189
+ },
190
+ async has(name) {
191
+ return secrets.has(name);
192
+ },
193
+ async require(name) {
194
+ if (!secrets.has(name)) {
195
+ throw new Error(`Missing mocked secret: ${name}`);
196
+ }
197
+ return secrets.get(name);
198
+ },
199
+ async resolve(value) {
200
+ return typeof value === "string" && value.startsWith("secret:") ? (secrets.get(value.slice(7)) ?? null) : value;
201
+ },
202
+ };
203
+ }
204
+
205
+ function createStoreContext() {
206
+ const values = new Map();
207
+ return {
208
+ async delete(key) {
209
+ return values.delete(key);
210
+ },
211
+ async get(key) {
212
+ return values.get(key);
213
+ },
214
+ async list() {
215
+ return [...values.keys()].sort();
216
+ },
217
+ async set(key, value) {
218
+ values.set(key, value);
219
+ return value;
220
+ },
221
+ };
222
+ }
223
+
224
+ function registrationObject(args, defaults) {
225
+ const first = args[0];
226
+ if (first && typeof first === "object") {
77
227
  return {
78
- name: objectName(args[0]),
79
- start: async () => undefined,
80
- stop: async () => undefined,
228
+ ...defaults,
229
+ ...first,
230
+ name: objectName(first) ?? defaults.name,
231
+ id: objectId(first) ?? defaults.id,
81
232
  };
82
233
  }
83
- return objectName(args[0]) ?? undefined;
234
+ if (typeof first === "string") {
235
+ return {
236
+ ...defaults,
237
+ name: first,
238
+ id: defaults.id,
239
+ };
240
+ }
241
+ return { ...defaults };
84
242
  }
85
243
 
86
244
  function summarizeArguments(args) {
@@ -113,3 +271,13 @@ function objectName(value) {
113
271
  }
114
272
  return typeof value.id === "string" ? value.id : null;
115
273
  }
274
+
275
+ function objectId(value) {
276
+ if (!value || typeof value !== "object") {
277
+ return null;
278
+ }
279
+ if (typeof value.id === "string") {
280
+ return value.id;
281
+ }
282
+ return typeof value.name === "string" ? value.name : null;
283
+ }
package/src/cli.js CHANGED
@@ -1,17 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- buildRuntimeCaptureReport,
3
+ renderTextSummary,
4
+ runPluginCheck,
5
+ } from "./index.js";
6
+ import {
4
7
  captureEntrypoint,
5
- inspectCompatibilityFixtureSet,
6
8
  inspectFixtureSet,
7
9
  loadInspectorConfig,
8
- loadPluginRootConfig,
9
- renderTextSummary,
10
+ writePluginInspectorInit,
10
11
  writeArtifacts,
11
- writeCompatibilityReport,
12
12
  writeReport,
13
- writeRuntimeCaptureReport,
14
- } from "./index.js";
13
+ } from "./advanced.js";
15
14
 
16
15
  const args = process.argv.slice(2);
17
16
  const command = args[0]?.startsWith("-") ? "check" : (args[0] ?? "check");
@@ -22,6 +21,8 @@ try {
22
21
  printHelp();
23
22
  } else if (command === "check") {
24
23
  await runCheck(commandArgs);
24
+ } else if (command === "init") {
25
+ await runInit(commandArgs);
25
26
  } else if (command === "inspect" || command === "report" || command === "ci") {
26
27
  await runReport(command, commandArgs);
27
28
  } else if (command === "capture") {
@@ -36,26 +37,13 @@ try {
36
37
 
37
38
  async function runCheck(commandArgs) {
38
39
  const configPath = readFlag(commandArgs, "--config");
40
+ const pluginRoot = readFlag(commandArgs, "--plugin-root") ?? readFlag(commandArgs, "--root");
39
41
  const outDir = readFlag(commandArgs, "--out") ?? "reports";
40
42
  const openclawPath = commandArgs.includes("--no-openclaw") ? false : readFlag(commandArgs, "--openclaw");
41
43
  const json = commandArgs.includes("--json");
42
- const capture = commandArgs.includes("--capture");
43
- const config = configPath ? await loadInspectorConfig(configPath) : await loadPluginRootConfig();
44
- const report = await inspectCompatibilityFixtureSet(config, { openclawPath });
45
- await writeCompatibilityReport(report, { outDir });
46
- if (capture) {
47
- if (process.env.PLUGIN_INSPECTOR_EXECUTE_ISOLATED !== "1") {
48
- throw new Error("check --capture imports plugin code; rerun with PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 in an isolated workspace");
49
- }
50
- const captureReport = await buildRuntimeCaptureReport({ report, rootDir: config.rootDir, mockSdk: true });
51
- await writeRuntimeCaptureReport(captureReport, {
52
- jsonPath: `${outDir}/plugin-inspector-runtime-capture.json`,
53
- markdownPath: `${outDir}/plugin-inspector-runtime-capture.md`,
54
- });
55
- if (captureReport.summary.failedCount > 0) {
56
- throw new Error(`plugin-inspector runtime capture failed for ${captureReport.summary.failedCount} entrypoints`);
57
- }
58
- }
44
+ const capture = readRuntimeFlag(commandArgs);
45
+ const mockSdk = readMockSdkFlag(commandArgs);
46
+ const { report } = await runPluginCheck({ configPath, pluginRoot, outDir, openclawPath, capture, mockSdk });
59
47
 
60
48
  if (json) {
61
49
  console.log(JSON.stringify(report, null, 2));
@@ -68,6 +56,25 @@ async function runCheck(commandArgs) {
68
56
  }
69
57
  }
70
58
 
59
+ async function runInit(commandArgs) {
60
+ const pluginRoot = readFlag(commandArgs, "--plugin-root") ?? readFlag(commandArgs, "--root");
61
+ const configPath = readFlag(commandArgs, "--config") ?? undefined;
62
+ const workflowPath = readFlag(commandArgs, "--workflow") ?? undefined;
63
+ const packageManager = readFlag(commandArgs, "--package-manager") ?? "npm";
64
+ const result = await writePluginInspectorInit({
65
+ pluginRoot,
66
+ configPath,
67
+ workflowPath,
68
+ packageManager,
69
+ ci: commandArgs.includes("--ci"),
70
+ force: commandArgs.includes("--force"),
71
+ });
72
+
73
+ for (const filePath of result.written) {
74
+ console.log(`wrote ${filePath}`);
75
+ }
76
+ }
77
+
71
78
  async function runReport(command, commandArgs) {
72
79
  const configPath = readFlag(commandArgs, "--config");
73
80
  const outDir = readFlag(commandArgs, "--out") ?? "reports";
@@ -92,7 +99,7 @@ async function runCapture(commandArgs) {
92
99
  const entrypoint = commandArgs.find((arg) => !arg.startsWith("-"));
93
100
  const outputPath = readFlag(commandArgs, "--output");
94
101
  const pluginRoot = readFlag(commandArgs, "--plugin-root");
95
- const mockSdk = commandArgs.includes("--mock-sdk");
102
+ const mockSdk = readMockSdkFlag(commandArgs) ?? commandArgs.includes("--mock-sdk");
96
103
  if (!entrypoint) {
97
104
  throw new Error("capture requires an entrypoint path");
98
105
  }
@@ -117,14 +124,49 @@ function readFlag(commandArgs, name) {
117
124
  return commandArgs[index + 1] ?? null;
118
125
  }
119
126
 
127
+ function readRuntimeFlag(commandArgs) {
128
+ if (commandArgs.includes("--runtime") || commandArgs.includes("--capture")) {
129
+ return true;
130
+ }
131
+ if (commandArgs.includes("--no-runtime") || commandArgs.includes("--no-capture")) {
132
+ return false;
133
+ }
134
+ return undefined;
135
+ }
136
+
137
+ function readMockSdkFlag(commandArgs) {
138
+ const sdk = readFlag(commandArgs, "--sdk");
139
+ if (sdk === "mock") {
140
+ return true;
141
+ }
142
+ if (sdk === "real") {
143
+ return false;
144
+ }
145
+ if (sdk && !["mock", "real"].includes(sdk)) {
146
+ throw new Error("--sdk must be mock or real");
147
+ }
148
+ if (commandArgs.includes("--mock-sdk")) {
149
+ return true;
150
+ }
151
+ if (commandArgs.includes("--real-sdk")) {
152
+ return false;
153
+ }
154
+ return undefined;
155
+ }
156
+
120
157
  function printHelp() {
121
158
  console.log(`plugin-inspector
122
159
 
123
160
  Usage:
124
- plugin-inspector check [--config <path>] [--out <dir>] [--openclaw <path>] [--no-openclaw] [--capture] [--json]
161
+ plugin-inspector
162
+ plugin-inspector check [--plugin-root <path>] [--config <path>] [--out <dir>] [--openclaw <path>] [--no-openclaw] [--runtime] [--mock-sdk|--real-sdk] [--json]
163
+ plugin-inspector init [--plugin-root <path>] [--config <path>] [--ci] [--package-manager npm|pnpm|yarn|bun] [--force]
125
164
  plugin-inspector report --config <path> [--out <dir>] [--check] [--json]
126
165
  plugin-inspector inspect --config <path> [--out <dir>] [--check] [--json]
127
166
  plugin-inspector ci --config <path> [--out <dir>]
128
- PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector capture <entrypoint> [--mock-sdk] [--plugin-root <path>] [--output <path>]
167
+ PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector capture <entrypoint> [--mock-sdk|--real-sdk] [--plugin-root <path>] [--output <path>]
168
+
169
+ Default check runs from the current plugin root and writes reports/ unless --out is set.
170
+ Runtime capture is opt-in because it imports plugin code; use --runtime with PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1.
129
171
  `);
130
172
  }
package/src/config.js CHANGED
@@ -52,6 +52,19 @@ export function validateInspectorConfig(config) {
52
52
  errors.push("config.fixtures must be a non-empty array");
53
53
  }
54
54
 
55
+ if (config.capture !== undefined) {
56
+ if (!config.capture || typeof config.capture !== "object" || Array.isArray(config.capture)) {
57
+ errors.push("config.capture must be an object when present");
58
+ } else {
59
+ if (config.capture.runtime !== undefined && typeof config.capture.runtime !== "boolean") {
60
+ errors.push("config.capture.runtime must be a boolean when present");
61
+ }
62
+ if (config.capture.mockSdk !== undefined && typeof config.capture.mockSdk !== "boolean") {
63
+ errors.push("config.capture.mockSdk must be a boolean when present");
64
+ }
65
+ }
66
+ }
67
+
55
68
  const ids = new Set();
56
69
  const paths = new Set();
57
70
  for (const fixture of config.fixtures ?? []) {
@@ -134,6 +147,7 @@ export async function normalizePluginRootConfig(config, options = {}) {
134
147
  return {
135
148
  version: 1,
136
149
  submoduleRoot: ".",
150
+ capture: config.capture,
137
151
  openclaw: config.openclaw,
138
152
  fixtures: [fixture],
139
153
  };
@@ -157,7 +171,7 @@ async function readJsonIfExists(filePath) {
157
171
  return JSON.parse(await readFile(filePath, "utf8"));
158
172
  }
159
173
 
160
- function packageId(packageName) {
174
+ export function packageId(packageName) {
161
175
  if (!packageName) {
162
176
  return null;
163
177
  }
@@ -170,7 +184,7 @@ function packageId(packageName) {
170
184
  .toLowerCase();
171
185
  }
172
186
 
173
- function inferPluginSeams(pluginManifest, packageJson) {
187
+ export function inferPluginSeams(pluginManifest, packageJson) {
174
188
  const contracts = Object.keys(pluginManifest?.contracts ?? {});
175
189
  if (contracts.includes("tools")) {
176
190
  return ["dynamic-tool"];
package/src/index.js CHANGED
@@ -1,186 +1,11 @@
1
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
- loadInspectorConfig,
120
- loadPluginRootConfig,
121
- normalizeInspectorConfig,
122
- normalizePluginRootConfig,
123
- validateInspectorConfig,
124
- } from "./config.js";
125
- export {
126
- buildPlatformProbes,
127
- defaultPlatformTargets,
128
- renderPlatformProbesMarkdown,
129
- validatePlatformProbes,
130
- writePlatformProbes,
131
- } from "./platform-probes.js";
132
- export {
133
- buildProfileDiff,
134
- defaultProfileDiffOptions,
135
- renderProfileDiffMarkdown,
136
- validateProfileDiff,
137
- writeProfileDiff,
138
- } from "./profile-diff.js";
139
- export {
140
- buildRefDiff,
141
- defaultRefDiffDimensions,
142
- defaultRefDiffOptions,
143
- renderRefDiffMarkdown,
144
- validateRefDiff,
145
- writeRefDiff,
146
- } from "./ref-diff.js";
147
- export {
148
- buildCompatibilityReport,
149
- classifyCompatRecordCoverage,
150
- renderMarkdownReport,
2
+ capturePluginEntrypoint,
3
+ createCaptureApi,
4
+ inspectFixtureSetConfig,
5
+ inspectPluginRoot,
6
+ loadPluginConfig,
151
7
  renderTextSummary,
152
- writeCompatibilityReport,
153
- writeReport,
154
- } from "./report.js";
155
- export {
156
- buildRuntimeProfile,
157
- defaultRuntimeProfileCommands,
158
- defaultRuntimeProfileOptions,
159
- renderRuntimeProfileMarkdown,
160
- validateRuntimeProfile,
161
- writeRuntimeProfile,
162
- } from "./runtime-profile.js";
163
- export {
164
- buildRuntimeCaptureReport,
165
- renderRuntimeCaptureMarkdown,
166
- writeRuntimeCaptureReport,
167
- } from "./runtime-capture-report.js";
168
- export { createMockSdkPackage } from "./sdk-mock.js";
169
- export {
170
- buildSyntheticProbePlan,
171
- defaultSyntheticHookContexts,
172
- defaultSyntheticHookEvents,
173
- defaultSyntheticRegistrationArguments,
174
- renderSyntheticProbeMarkdown,
175
- runCapturedSyntheticProbes,
176
- syntheticRegistrationExecutionProfiles,
177
- validateSyntheticProbePlan,
178
- writeSyntheticProbePlan,
179
- } from "./synthetic-probes.js";
180
- export {
181
- buildWorkspacePlan,
182
- defaultWorkspacePlanOptions,
183
- renderWorkspacePlanMarkdown,
184
- validateWorkspacePlan,
185
- writeWorkspacePlan,
186
- } from "./workspace-plan.js";
8
+ runPluginCheck,
9
+ setupPluginInspector,
10
+ writePluginReports,
11
+ } from "./api.js";