@openclaw/plugin-inspector 0.3.4 → 0.3.6

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/src/sdk-mock.js CHANGED
@@ -254,9 +254,20 @@ export async function createMockSdkPackage(rootDir, options = {}) {
254
254
  )}\n`,
255
255
  "utf8",
256
256
  );
257
- await writeFile(path.join(pluginSdkDir, "index.js"), mockSdkSource(), "utf8");
257
+ const rootExportNames = new Set([
258
+ ...mockSdkExportNames,
259
+ ...(imports.bySpecifier.get("openclaw/plugin-sdk") ?? []),
260
+ ]);
261
+ await writeFile(path.join(pluginSdkDir, "index.js"), mockSdkSource(rootExportNames), "utf8");
258
262
  for (const [subpath, exportNames] of Object.entries(mockSdkSubpathExports)) {
259
- await writeFile(path.join(pluginSdkDir, `${subpath}.js`), mockSdkSubpathSource(exportNames), "utf8");
263
+ const specifier = `openclaw/plugin-sdk/${subpath}`;
264
+ await writeFile(
265
+ path.join(pluginSdkDir, `${subpath}.js`),
266
+ mockSdkSubpathSource(exportNames, imports.bySpecifier.get(specifier) ?? new Set(), {
267
+ zod: subpath === "zod",
268
+ }),
269
+ "utf8",
270
+ );
260
271
  }
261
272
  for (const specifier of imports.openclawSdkSpecifiers) {
262
273
  if (specifier === "openclaw/plugin-sdk") {
@@ -428,6 +439,9 @@ export async function resolve(specifier, context, nextResolve) {
428
439
  const subpath = specifier.slice("openclaw/plugin-sdk/".length);
429
440
  return moduleUrl(path.join(pluginSdkDir, \`\${subpath}.js\`));
430
441
  }
442
+ if (externalMap.has(specifier)) {
443
+ return moduleUrl(externalMap.get(specifier));
444
+ }
431
445
  try {
432
446
  return await nextResolve(specifier, context);
433
447
  } catch (error) {
@@ -531,6 +545,12 @@ function genericExportStatement(name) {
531
545
  if (["createChatChannelPlugin", "createPlugin", "defineChannelPluginEntry", "definePlugin", "definePluginEntry", "defineSetupPluginEntry"].includes(name)) {
532
546
  return name === "definePluginEntry" ? "export { definePluginEntry };" : `export const ${name} = definePluginEntry;`;
533
547
  }
548
+ if (name === "defineBundledChannelEntry") {
549
+ return "export { defineBundledChannelEntry };";
550
+ }
551
+ if (name === "defineBundledChannelSetupEntry") {
552
+ return "export { defineBundledChannelSetupEntry };";
553
+ }
534
554
  if (/^[A-Z].*Schema$/u.test(name)) {
535
555
  return `export const ${name} = createSchema();`;
536
556
  }
@@ -547,9 +567,41 @@ function genericMockRuntimeSource(options = {}) {
547
567
  }
548
568
  return typeof entry === "function" ? { register: entry } : entry;
549
569
  }
570
+
571
+ function defineBundledChannelEntry(entry = {}) {
572
+ return {
573
+ ...entry,
574
+ kind: "bundled-channel-entry",
575
+ register(api) {
576
+ if (api?.registrationMode === "cli-metadata") {
577
+ return entry.registerCliMetadata?.(api);
578
+ }
579
+ if (api?.registrationMode !== "tool-discovery") {
580
+ api?.registerChannel?.({
581
+ id: entry.id,
582
+ name: entry.name,
583
+ description: entry.description,
584
+ plugin: { id: entry.id, name: entry.name },
585
+ });
586
+ }
587
+ entry.registerCliMetadata?.(api);
588
+ return entry.registerFull?.(api);
589
+ },
590
+ };
591
+ }
592
+
593
+ function defineBundledChannelSetupEntry(entry = {}) {
594
+ return {
595
+ ...entry,
596
+ kind: "bundled-channel-setup-entry",
597
+ };
598
+ }
550
599
  ` : ""}
551
600
  function createMockValue(name) {
552
601
  function fn(...args) {
602
+ if (name === "resolvePreferredOpenClawTmpDir") {
603
+ return process.env.TMPDIR || "/tmp";
604
+ }
553
605
  if (name.startsWith("normalize")) {
554
606
  return typeof args[0] === "string" ? args[0] : "";
555
607
  }
@@ -728,7 +780,8 @@ function createTypeNamespace() {
728
780
  `;
729
781
  }
730
782
 
731
- function mockSdkSource() {
783
+ function mockSdkSource(exportNames = mockSdkExportNames) {
784
+ const dynamicExportNames = [...exportNames].filter((name) => !mockSdkExportNames.includes(name));
732
785
  return `function normalizeEntry(entry) {
733
786
  return typeof entry === "function" ? { register: entry } : entry;
734
787
  }
@@ -1538,15 +1591,20 @@ export const OPENAI_RESPONSES_STREAM_HOOKS = buildProviderStreamFamilyHooks("ope
1538
1591
  export const OPENROUTER_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("openrouter-thinking");
1539
1592
  export const TOOL_STREAM_DEFAULT_ON_HOOKS = buildProviderStreamFamilyHooks("tool-stream-default");
1540
1593
  export const pluginSdkMock = true;
1594
+ ${dynamicExportNames.map(genericExportStatement).join("\n")}
1541
1595
 
1542
1596
  export default {
1543
- ${mockSdkExportNames.map((name) => ` ${name},`).join("\n")}
1597
+ ${[...exportNames].map((name) => ` ${name},`).join("\n")}
1544
1598
  };
1545
1599
  `;
1546
1600
  }
1547
1601
 
1548
- function mockSdkSubpathSource(exportNames) {
1549
- return `${exportNames.map((name) => `export { ${name} } from "./index.js";`).join("\n")}
1602
+ function mockSdkSubpathSource(staticExportNames, importedExportNames, options = {}) {
1603
+ const staticNames = new Set(staticExportNames);
1604
+ const dynamicNames = [...importedExportNames].filter((name) => !staticNames.has(name));
1605
+ return `${[...staticNames].map((name) => `export { ${name} } from "./index.js";`).join("\n")}
1606
+ ${dynamicNames.length > 0 ? genericMockRuntimeSource({ includeSdkRuntime: true, zod: options.zod }) : ""}
1607
+ ${dynamicNames.map(genericExportStatement).join("\n")}
1550
1608
  export { default } from "./index.js";
1551
1609
  `;
1552
1610
  }
@@ -1,11 +1,21 @@
1
1
  import { renderPaddedMarkdownTable, writeJsonMarkdownArtifacts } from "./artifacts.js";
2
2
 
3
3
  export const syntheticRegistrationExecutionProfiles = {
4
+ createChatChannelPlugin: {
5
+ mode: "metadata-only",
6
+ callableProperties: [],
7
+ reason: "channel plugin factory metadata is captured before channel runtime execution",
8
+ },
4
9
  defineChannelPluginEntry: {
5
10
  mode: "metadata-only",
6
11
  callableProperties: [],
7
12
  reason: "entry wrapper metadata is captured before channel runtime execution",
8
13
  },
14
+ defineBundledChannelEntry: {
15
+ mode: "metadata-only",
16
+ callableProperties: [],
17
+ reason: "bundled channel entry metadata is captured before channel runtime execution",
18
+ },
9
19
  definePluginEntry: {
10
20
  mode: "metadata-only",
11
21
  callableProperties: [],
@@ -21,6 +31,11 @@ export const syntheticRegistrationExecutionProfiles = {
21
31
  callableProperties: [],
22
32
  reason: "agent harness factories are captured as registration metadata; agent runtime execution remains isolated opt-in",
23
33
  },
34
+ registerAgentEventSubscription: {
35
+ mode: "metadata-only",
36
+ callableProperties: [],
37
+ reason: "agent event subscriptions are captured as registration metadata before agent event dispatch",
38
+ },
24
39
  registerAgentToolResultMiddleware: {
25
40
  mode: "metadata-only",
26
41
  callableProperties: [],
@@ -64,6 +79,11 @@ export const syntheticRegistrationExecutionProfiles = {
64
79
  callableProperties: [],
65
80
  reason: "context engine factories are captured as registration metadata; engine startup remains isolated opt-in",
66
81
  },
82
+ registerControlUiDescriptor: {
83
+ mode: "metadata-only",
84
+ callableProperties: [],
85
+ reason: "control UI descriptors are captured as registration metadata before UI composition",
86
+ },
67
87
  registerDetachedTaskRuntime: {
68
88
  mode: "metadata-only",
69
89
  callableProperties: [],
@@ -151,6 +171,11 @@ export const syntheticRegistrationExecutionProfiles = {
151
171
  callableProperties: [],
152
172
  reason: "node host commands are captured as registration metadata before host process execution",
153
173
  },
174
+ registerNodeInvokePolicy: {
175
+ mode: "metadata-only",
176
+ callableProperties: [],
177
+ reason: "node invoke policies are captured as registration metadata before host authorization checks",
178
+ },
154
179
  registerProvider: {
155
180
  mode: "metadata-only",
156
181
  callableProperties: [],
@@ -171,6 +196,11 @@ export const syntheticRegistrationExecutionProfiles = {
171
196
  callableProperties: [],
172
197
  reason: "reload handlers are captured as registration metadata before runtime reload execution",
173
198
  },
199
+ registerRuntimeLifecycle: {
200
+ mode: "metadata-only",
201
+ callableProperties: [],
202
+ reason: "runtime lifecycle handlers are captured as registration metadata before lifecycle dispatch",
203
+ },
174
204
  registerSecurityAuditCollector: {
175
205
  mode: "metadata-only",
176
206
  callableProperties: [],
@@ -181,6 +211,16 @@ export const syntheticRegistrationExecutionProfiles = {
181
211
  callableProperties: ["start", "stop", "dispose"],
182
212
  option: "includeLifecycle",
183
213
  },
214
+ registerSessionExtension: {
215
+ mode: "metadata-only",
216
+ callableProperties: [],
217
+ reason: "session extensions are captured as registration metadata before session runtime execution",
218
+ },
219
+ registerSessionSchedulerJob: {
220
+ mode: "metadata-only",
221
+ callableProperties: [],
222
+ reason: "session scheduler jobs are captured as registration metadata before scheduler execution",
223
+ },
184
224
  registerSpeechProvider: {
185
225
  mode: "provider-opt-in",
186
226
  callableProperties: ["speak", "synthesize", "tts"],
@@ -190,6 +230,11 @@ export const syntheticRegistrationExecutionProfiles = {
190
230
  mode: "direct",
191
231
  callableProperties: ["run", "handler", "execute"],
192
232
  },
233
+ registerToolMetadata: {
234
+ mode: "metadata-only",
235
+ callableProperties: [],
236
+ reason: "tool metadata descriptors are captured as registration metadata before tool runtime execution",
237
+ },
193
238
  registerTextTransforms: {
194
239
  mode: "metadata-only",
195
240
  callableProperties: [],
@@ -200,6 +245,11 @@ export const syntheticRegistrationExecutionProfiles = {
200
245
  callableProperties: [],
201
246
  reason: "video generation providers are captured as registration metadata before provider runtime execution",
202
247
  },
248
+ registerTrustedToolPolicy: {
249
+ mode: "metadata-only",
250
+ callableProperties: [],
251
+ reason: "trusted tool policies are captured as registration metadata before trust-policy enforcement",
252
+ },
203
253
  registerWebFetchProvider: {
204
254
  mode: "metadata-only",
205
255
  callableProperties: [],
@@ -326,6 +376,7 @@ export const defaultSyntheticHookContexts = {
326
376
  };
327
377
 
328
378
  export const defaultSyntheticRegistrationArguments = {
379
+ createChatChannelPlugin: [{ base: { id: "fixture-channel" }, outbound: { sendText: "function" } }],
329
380
  defineChannelPluginEntry: [{ id: "fixture-channel", setup: "function", receive: "function" }],
330
381
  definePluginEntry: [{ id: "fixture-plugin", register: "function" }],
331
382
  registerChannel: [{ id: "fixture-channel", send: "function", receive: "function" }],
@@ -71,6 +71,7 @@ export async function buildWorkspacePlan(options = {}) {
71
71
  installStepCount: allSteps.filter((step) => step.kind === "install").length,
72
72
  auditStepCount: allSteps.filter((step) => step.kind === "audit").length,
73
73
  buildStepCount: allSteps.filter((step) => step.kind === "build").length,
74
+ pruneDevWorkspaceDependencyStepCount: allSteps.filter((step) => step.kind === "prune-dev-workspace-deps").length,
74
75
  artifactStepCount: allSteps.filter((step) => step.kind === "prepare-artifacts").length,
75
76
  captureStepCount: allSteps.filter((step) => step.kind === "capture").length,
76
77
  syntheticProbeStepCount: allSteps.filter((step) => step.kind === "synthetic-probe").length,
@@ -179,6 +180,7 @@ export function renderWorkspacePlanMarkdown(plan, options = {}) {
179
180
  ["Artifact dirs", plan.summary.artifactStepCount],
180
181
  ["Install steps", plan.summary.installStepCount],
181
182
  ["Audit steps", plan.summary.auditStepCount],
183
+ ["Prune dev workspace dependency steps", plan.summary.pruneDevWorkspaceDependencyStepCount],
182
184
  ["Build steps", plan.summary.buildStepCount],
183
185
  ["Capture steps", plan.summary.captureStepCount],
184
186
  ["Synthetic probe steps", plan.summary.syntheticProbeStepCount],
@@ -248,6 +250,14 @@ async function buildEntrypointPlan({ fixtureId, entrypoint, packageSummary, pack
248
250
  }
249
251
 
250
252
  if (requiredCapabilities.includes("dependency-install")) {
253
+ if (hasWorkspaceProtocolDevDependencies(packageJson)) {
254
+ steps.push({
255
+ kind: "prune-dev-workspace-deps",
256
+ command: `node ${helperScript(settings, workspacePath, settings.pruneWorkspaceDevDepsScript, "prune-workspace-dev-deps-cli.js")}`,
257
+ cwd: workspacePath,
258
+ reason: "remove workspace: devDependencies from the isolated runtime install; the mock SDK supplies OpenClaw host imports",
259
+ });
260
+ }
251
261
  steps.push({
252
262
  kind: "install",
253
263
  command: installCommand(packageManager),
@@ -319,6 +329,7 @@ function workspaceSettings(options) {
319
329
  resultsRoot: repoRelative(options.resultsRoot ?? defaultWorkspacePlanOptions.resultsRoot),
320
330
  rootDir: path.resolve(options.rootDir ?? process.cwd()),
321
331
  syntheticProbeScript: options.syntheticProbeScript ?? defaultWorkspacePlanOptions.syntheticProbeScript,
332
+ pruneWorkspaceDevDepsScript: options.pruneWorkspaceDevDepsScript,
322
333
  workspaceRoot: repoRelative(options.workspaceRoot ?? defaultWorkspacePlanOptions.workspaceRoot),
323
334
  };
324
335
  }
@@ -377,6 +388,12 @@ function hasHostLinkedOpenClawDependency(packageSummary) {
377
388
  ].includes("openclaw");
378
389
  }
379
390
 
391
+ function hasWorkspaceProtocolDevDependencies(packageJson) {
392
+ return Object.values(packageJson.devDependencies ?? {}).some(
393
+ (value) => typeof value === "string" && value.startsWith("workspace:"),
394
+ );
395
+ }
396
+
380
397
  function detectPackageManager(rootDir, packageDir, packageJson) {
381
398
  const declared = typeof packageJson.packageManager === "string" ? packageJson.packageManager.split("@")[0] : null;
382
399
  if (declared) {
@@ -458,15 +475,13 @@ function runCommand(packageManager, script) {
458
475
  }
459
476
 
460
477
  function captureCommand(settings, fixtureId, entrypoint, workspacePath) {
461
- const loader = entrypoint.blockers.some((blocker) => blocker.code === "ts-loader-required") ? " --import tsx" : "";
462
478
  const script = helperScript(settings, workspacePath, settings.captureScript, "capture-cli.js");
463
- return `${settings.optInEnv} node${loader} ${script} ${entrypoint.specifier} --mock-sdk --output ${workspaceArtifactPath(settings, fixtureId, entrypoint, workspacePath, "capture")}`;
479
+ return `${settings.optInEnv} node ${script} ${entrypoint.specifier} --mock-sdk --output ${workspaceArtifactPath(settings, fixtureId, entrypoint, workspacePath, "capture")}`;
464
480
  }
465
481
 
466
482
  function syntheticProbeCommand(settings, fixtureId, entrypoint, workspacePath) {
467
- const loader = entrypoint.blockers.some((blocker) => blocker.code === "ts-loader-required") ? " --import tsx" : "";
468
483
  const script = helperScript(settings, workspacePath, settings.syntheticProbeScript, "synthetic-probes-cli.js");
469
- return `${settings.optInEnv} node${loader} ${script} --entrypoint ${entrypoint.specifier} --mock-sdk --output ${workspaceArtifactPath(settings, fixtureId, entrypoint, workspacePath, "synthetic")}`;
484
+ return `${settings.optInEnv} node ${script} --entrypoint ${entrypoint.specifier} --mock-sdk --output ${workspaceArtifactPath(settings, fixtureId, entrypoint, workspacePath, "synthetic")}`;
470
485
  }
471
486
 
472
487
  function helperScript(settings, workspacePath, configuredScript, helperFileName) {