@openclaw/plugin-inspector 0.3.20 → 0.3.22

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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 0.3.22 - 2026-08-30
6
+
7
+ ### Fixed
8
+
9
+ - Finish OpenClaw target archive extraction before cleanup so strict extraction errors cannot race unfinished filesystem writes.
10
+
11
+ ### Changed
12
+
13
+ - Refresh Crabbox hydration tooling to pnpm 11.24.0 and pnpm/action-setup 6.0.10.
14
+ - Update the code-scanning example to CodeQL's Node 24-based SARIF upload action.
15
+
16
+ ## 0.3.21 - 2026-08-05
17
+
18
+ ### Fixed
19
+
20
+ - Preserve record predicate and coercion contracts in generated SDK mocks so schema-aware plugin imports cannot recurse through primitive values.
21
+ - Read raw plugin manifest fields from packed OpenClaw declarations instead of runtime registry fields, avoiding false unknown-field warnings for supported metadata such as `uiHints`.
22
+
3
23
  ## 0.3.20 - 2026-07-31
4
24
 
5
25
  ### Added
@@ -20,7 +20,7 @@ jobs:
20
20
  cache: npm
21
21
  - run: npm ci
22
22
  - run: npx @openclaw/plugin-inspector ci --no-openclaw --runtime --mock-sdk --allow-execute
23
- - uses: github/codeql-action/upload-sarif@v3
23
+ - uses: github/codeql-action/upload-sarif@v4
24
24
  if: always()
25
25
  with:
26
26
  sarif_file: reports/plugin-inspector.sarif
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/plugin-inspector",
3
- "version": "0.3.20",
3
+ "version": "0.3.22",
4
4
  "private": false,
5
5
  "description": "Offline compatibility inspector for OpenClaw plugins.",
6
6
  "type": "module",
@@ -284,12 +284,12 @@ async function readPackedOpenClawTargetSurface({ rootDir, requestedPaths, reques
284
284
  }))
285
285
  .sort((left, right) => right.values.length - left.values.length)[0];
286
286
  const hookDeclaration = declarations.find((declaration) => declaration.source.includes("type PluginHookName ="));
287
- const manifestDeclaration = declarations.find((declaration) => declaration.source.includes("type PluginManifestRecord ="));
287
+ const manifestDeclaration = declarations.find((declaration) => declaration.source.includes("type PluginManifest ="));
288
288
  const manifestContractDeclaration = declarations.find((declaration) => declaration.source.includes("type PluginManifestContracts ="));
289
289
  const apiRegistrars = apiDeclaration?.values ?? [];
290
290
  const hookNames = hookDeclaration ? parseStringUnion(hookDeclaration.source, "PluginHookName") : [];
291
291
  const manifestFields = manifestDeclaration
292
- ? parseObjectTypeFields(manifestDeclaration.source, "PluginManifestRecord")
292
+ ? parseObjectTypeFields(manifestDeclaration.source, "PluginManifest")
293
293
  : [];
294
294
  const manifestContractFields = manifestContractDeclaration
295
295
  ? parseObjectTypeFields(manifestContractDeclaration.source, "PluginManifestContracts")
@@ -149,7 +149,9 @@ async function preparePackageArchive(resolvedTarget, options) {
149
149
  try {
150
150
  const archivePath = path.join(temporaryDir, "openclaw.tgz");
151
151
  await writeFile(archivePath, archive);
152
- await extractTar({ cwd: temporaryDir, file: archivePath, strict: true });
152
+ // Async tar rejection can leave filesystem writes running. Finish extraction
153
+ // before finally removes its workspace, including when strict validation fails.
154
+ extractTar({ cwd: temporaryDir, file: archivePath, strict: true, sync: true });
153
155
  const packageDir = path.join(temporaryDir, "package");
154
156
  if (!(await isPreparedPackage(packageDir, resolvedTarget.version))) {
155
157
  throw new Error(`downloaded OpenClaw ${resolvedTarget.version} archive has unexpected package metadata`);
package/src/sdk-mock.js CHANGED
@@ -621,6 +621,21 @@ function isValidExportName(name) {
621
621
  }
622
622
 
623
623
  function genericExportStatement(name) {
624
+ if (name === "isRecord") {
625
+ return "export function isRecord(value) { return isPlainObject(value); }";
626
+ }
627
+ if (name === "asRecord") {
628
+ return 'export function asRecord(value) { return value !== null && typeof value === "object" ? value : {}; }';
629
+ }
630
+ if (name === "asOptionalRecord") {
631
+ return "export function asOptionalRecord(value) { return isPlainObject(value) ? value : undefined; }";
632
+ }
633
+ if (name === "asNullableRecord") {
634
+ return "export function asNullableRecord(value) { return isPlainObject(value) ? value : null; }";
635
+ }
636
+ if (name === "readStringField") {
637
+ return 'export function readStringField(record, key) { const value = record?.[key]; return typeof value === "string" ? value : undefined; }';
638
+ }
624
639
  if (name === "z") {
625
640
  return "export const z = createZNamespace();";
626
641
  }