From f6360da116cea1f4f18559bad7999460a803d164 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 20 Apr 2026 15:03:09 +0100 Subject: [PATCH] fix(deps): remove extension-owned deps from root install (#69335) * fix(deps): remove extension runtime deps from root install * fix(deps): keep bundled plugin deps local * test(plugins): assert matrix deps stay plugin-local --- package.json | 32 ---- pnpm-lock.yaml | 159 ------------------ .../bundled-plugin-root-runtime-mirrors.mjs | 21 --- scripts/root-dependency-ownership-audit.mjs | 14 +- .../package-manifest.contract.test.ts | 70 ++++++-- ...in-sdk-package-contract-guardrails.test.ts | 22 +-- test/openclaw-npm-postpublish-verify.test.ts | 12 +- test/release-check.test.ts | 12 +- .../root-dependency-ownership-audit.test.ts | 8 +- 9 files changed, 80 insertions(+), 270 deletions(-) diff --git a/package.json b/package.json index 60158dd81fe..645898b150b 100644 --- a/package.json +++ b/package.json @@ -1503,65 +1503,39 @@ "dependencies": { "@agentclientprotocol/sdk": "0.19.0", "@anthropic-ai/vertex-sdk": "^0.16.0", - "@aws-sdk/client-bedrock": "3.1032.0", - "@aws-sdk/client-bedrock-runtime": "3.1032.0", - "@aws-sdk/credential-provider-node": "3.972.32", - "@aws/bedrock-token-generator": "^1.1.0", - "@buape/carbon": "0.16.0", "@clack/prompts": "^1.2.0", - "@google/genai": "^1.50.1", - "@grammyjs/runner": "^2.0.3", - "@grammyjs/transformer-throttler": "^1.2.1", "@homebridge/ciao": "^1.3.6", - "@lancedb/lancedb": "^0.27.2", - "@larksuiteoapi/node-sdk": "^1.60.0", "@lydell/node-pty": "1.2.0-beta.12", "@mariozechner/pi-agent-core": "0.67.68", "@mariozechner/pi-ai": "0.67.68", "@mariozechner/pi-coding-agent": "0.67.68", "@mariozechner/pi-tui": "0.67.68", - "@matrix-org/matrix-sdk-crypto-wasm": "18.1.0", "@modelcontextprotocol/sdk": "1.29.0", "@mozilla/readability": "^0.6.0", - "@pierre/diffs": "1.1.15", "@sinclair/typebox": "0.34.49", - "@slack/bolt": "^4.7.0", - "@slack/web-api": "^7.15.1", - "@whiskeysockets/baileys": "7.0.0-rc.9", "ajv": "^8.18.0", "chalk": "^5.6.2", "chokidar": "^5.0.0", "cli-highlight": "^2.1.11", "commander": "^14.0.3", "croner": "^10.0.1", - "discord-api-types": "^0.38.47", "dotenv": "^17.4.2", "express": "^5.2.1", "file-type": "22.0.1", "gaxios": "7.1.4", - "google-auth-library": "^10.6.2", - "grammy": "^1.42.0", "https-proxy-agent": "^9.0.0", "ipaddr.js": "^2.3.0", - "jimp": "^1.6.1", "jiti": "^2.6.1", "json5": "^2.2.3", "jszip": "^3.10.1", "linkedom": "^0.18.12", "markdown-it": "14.1.1", - "matrix-js-sdk": "41.3.0", - "mpg123-decoder": "^1.0.3", - "node-edge-tts": "^1.2.10", - "nostr-tools": "^2.23.3", "openai": "^6.34.0", - "opusscript": "^0.1.1", "osc-progress": "^0.3.0", "pdfjs-dist": "^5.6.205", - "playwright-core": "1.59.1", "proxy-agent": "^8.0.1", "qrcode-terminal": "^0.12.0", "sharp": "^0.34.5", - "silk-wasm": "^3.7.1", "sqlite-vec": "0.1.9", "tar": "7.5.13", "tslog": "^4.10.2", @@ -1605,12 +1579,6 @@ "optional": true } }, - "optionalDependencies": { - "@discordjs/opus": "^0.10.0", - "@matrix-org/matrix-sdk-crypto-nodejs": "^0.4.0", - "fake-indexeddb": "^6.2.5", - "music-metadata": "^11.12.3" - }, "overrides": { "axios": "1.15.0", "follow-redirects": "1.16.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd144d9b170..e3424ef1067 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,42 +44,12 @@ importers: '@anthropic-ai/vertex-sdk': specifier: ^0.16.0 version: 0.16.0(zod@4.3.6) - '@aws-sdk/client-bedrock': - specifier: 3.1032.0 - version: 3.1032.0 - '@aws-sdk/client-bedrock-runtime': - specifier: 3.1032.0 - version: 3.1032.0 - '@aws-sdk/credential-provider-node': - specifier: 3.972.32 - version: 3.972.32 - '@aws/bedrock-token-generator': - specifier: ^1.1.0 - version: 1.1.0 - '@buape/carbon': - specifier: 0.16.0 - version: 0.16.0(@discordjs/opus@0.10.0)(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(opusscript@0.1.1) '@clack/prompts': specifier: ^1.2.0 version: 1.2.0 - '@google/genai': - specifier: ^1.50.1 - version: 1.50.1(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6)) - '@grammyjs/runner': - specifier: ^2.0.3 - version: 2.0.3(grammy@1.42.0) - '@grammyjs/transformer-throttler': - specifier: ^1.2.1 - version: 1.2.1(grammy@1.42.0) '@homebridge/ciao': specifier: ^1.3.6 version: 1.3.6 - '@lancedb/lancedb': - specifier: ^0.27.2 - version: 0.27.2(apache-arrow@18.1.0) - '@larksuiteoapi/node-sdk': - specifier: ^1.60.0 - version: 1.60.0 '@lydell/node-pty': specifier: 1.2.0-beta.12 version: 1.2.0-beta.12 @@ -95,9 +65,6 @@ importers: '@mariozechner/pi-tui': specifier: 0.67.68 version: 0.67.68 - '@matrix-org/matrix-sdk-crypto-wasm': - specifier: 18.1.0 - version: 18.1.0 '@modelcontextprotocol/sdk': specifier: 1.29.0 version: 1.29.0(zod@4.3.6) @@ -107,21 +74,9 @@ importers: '@napi-rs/canvas': specifier: ^0.1.89 version: 0.1.92 - '@pierre/diffs': - specifier: 1.1.15 - version: 1.1.15(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@sinclair/typebox': specifier: 0.34.49 version: 0.34.49 - '@slack/bolt': - specifier: ^4.7.0 - version: 4.7.0(@types/express@5.0.6) - '@slack/web-api': - specifier: ^7.15.1 - version: 7.15.1 - '@whiskeysockets/baileys': - specifier: 7.0.0-rc.9 - version: 7.0.0-rc.9(patch_hash=23ec8efe1484afa57c51b96955ba331d1467521a8e676a18c2690da7e70a6201)(audio-decode@2.2.3)(jimp@1.6.1)(sharp@0.34.5) ajv: specifier: ^8.18.0 version: 8.18.0 @@ -140,9 +95,6 @@ importers: croner: specifier: ^10.0.1 version: 10.0.1 - discord-api-types: - specifier: ^0.38.47 - version: 0.38.47 dotenv: specifier: ^17.4.2 version: 17.4.2 @@ -155,21 +107,12 @@ importers: gaxios: specifier: 7.1.4 version: 7.1.4 - google-auth-library: - specifier: ^10.6.2 - version: 10.6.2 - grammy: - specifier: ^1.42.0 - version: 1.42.0 https-proxy-agent: specifier: ^9.0.0 version: 9.0.0 ipaddr.js: specifier: ^2.3.0 version: 2.3.0 - jimp: - specifier: ^1.6.1 - version: 1.6.1 jiti: specifier: ^2.6.1 version: 2.6.1 @@ -185,36 +128,18 @@ importers: markdown-it: specifier: 14.1.1 version: 14.1.1 - matrix-js-sdk: - specifier: 41.3.0 - version: 41.3.0 - mpg123-decoder: - specifier: ^1.0.3 - version: 1.0.3 - node-edge-tts: - specifier: ^1.2.10 - version: 1.2.10 node-llama-cpp: specifier: 3.18.1 version: 3.18.1(typescript@6.0.2) - nostr-tools: - specifier: ^2.23.3 - version: 2.23.3(typescript@6.0.3) openai: specifier: ^6.34.0 version: 6.34.0(ws@8.20.0)(zod@4.3.6) - opusscript: - specifier: ^0.1.1 - version: 0.1.1 osc-progress: specifier: ^0.3.0 version: 0.3.0 pdfjs-dist: specifier: ^5.6.205 version: 5.6.205 - playwright-core: - specifier: 1.59.1 - version: 1.59.1 proxy-agent: specifier: ^8.0.1 version: 8.0.1 @@ -224,9 +149,6 @@ importers: sharp: specifier: ^0.34.5 version: 0.34.5 - silk-wasm: - specifier: ^3.7.1 - version: 3.7.1 sqlite-vec: specifier: 0.1.9 version: 0.1.9 @@ -321,19 +243,6 @@ importers: vitest: specifier: ^4.1.4 version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1))(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) - optionalDependencies: - '@discordjs/opus': - specifier: ^0.10.0 - version: 0.10.0 - '@matrix-org/matrix-sdk-crypto-nodejs': - specifier: ^0.4.0 - version: 0.4.0 - fake-indexeddb: - specifier: ^6.2.5 - version: 6.2.5 - music-metadata: - specifier: ^11.12.3 - version: 11.12.3 extensions/acpx: dependencies: @@ -8730,26 +8639,6 @@ snapshots: - opusscript - utf-8-validate - '@buape/carbon@0.16.0(@discordjs/opus@0.10.0)(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(opusscript@0.1.1)': - dependencies: - '@types/node': 25.6.0 - discord-api-types: 0.38.45 - optionalDependencies: - '@cloudflare/workers-types': 4.20260405.1 - '@discordjs/voice': 0.19.2(@discordjs/opus@0.10.0)(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(opusscript@0.1.1) - '@types/bun': 1.3.11 - '@types/ws': 8.18.1 - ws: 8.20.0 - transitivePeerDependencies: - - '@discordjs/opus' - - '@emnapi/core' - - '@emnapi/runtime' - - bufferutil - - ffmpeg-static - - node-opus - - opusscript - - utf-8-validate - '@cacheable/memory@2.0.8': dependencies: '@cacheable/utils': 2.4.1 @@ -8918,25 +8807,6 @@ snapshots: - opusscript - utf-8-validate - '@discordjs/voice@0.19.2(@discordjs/opus@0.10.0)(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(opusscript@0.1.1)': - dependencies: - '@snazzah/davey': 0.1.11(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) - '@types/ws': 8.18.1 - discord-api-types: 0.38.47 - prism-media: 1.3.5(@discordjs/opus@0.10.0)(opusscript@0.1.1) - tslib: 2.8.1 - ws: 8.20.0 - transitivePeerDependencies: - - '@discordjs/opus' - - '@emnapi/core' - - '@emnapi/runtime' - - bufferutil - - ffmpeg-static - - node-opus - - opusscript - - utf-8-validate - optional: true - '@emnapi/core@1.9.2': dependencies: '@emnapi/wasi-threads': 1.2.1 @@ -11016,14 +10886,6 @@ snapshots: - '@emnapi/runtime' optional: true - '@snazzah/davey-wasm32-wasi@0.1.11(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': - dependencies: - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' - optional: true - '@snazzah/davey-win32-arm64-msvc@0.1.11': optional: true @@ -11053,27 +10915,6 @@ snapshots: - '@emnapi/core' - '@emnapi/runtime' - '@snazzah/davey@0.1.11(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': - optionalDependencies: - '@snazzah/davey-android-arm-eabi': 0.1.11 - '@snazzah/davey-android-arm64': 0.1.11 - '@snazzah/davey-darwin-arm64': 0.1.11 - '@snazzah/davey-darwin-x64': 0.1.11 - '@snazzah/davey-freebsd-x64': 0.1.11 - '@snazzah/davey-linux-arm-gnueabihf': 0.1.11 - '@snazzah/davey-linux-arm64-gnu': 0.1.11 - '@snazzah/davey-linux-arm64-musl': 0.1.11 - '@snazzah/davey-linux-x64-gnu': 0.1.11 - '@snazzah/davey-linux-x64-musl': 0.1.11 - '@snazzah/davey-wasm32-wasi': 0.1.11(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) - '@snazzah/davey-win32-arm64-msvc': 0.1.11 - '@snazzah/davey-win32-ia32-msvc': 0.1.11 - '@snazzah/davey-win32-x64-msvc': 0.1.11 - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' - optional: true - '@standard-schema/spec@1.1.0': {} '@swc/helpers@0.5.21': diff --git a/scripts/lib/bundled-plugin-root-runtime-mirrors.mjs b/scripts/lib/bundled-plugin-root-runtime-mirrors.mjs index 6b31b788aa4..7ae46cbce66 100644 --- a/scripts/lib/bundled-plugin-root-runtime-mirrors.mjs +++ b/scripts/lib/bundled-plugin-root-runtime-mirrors.mjs @@ -194,7 +194,6 @@ export function collectRootDistBundledRuntimeMirrors(params) { } export function collectBundledPluginRootRuntimeMirrorErrors(params) { - const rootRuntimeDeps = collectRuntimeDependencySpecs(params.rootPackageJson); const errors = []; for (const [dependencyName, record] of params.bundledRuntimeDependencySpecs) { @@ -205,25 +204,5 @@ export function collectBundledPluginRootRuntimeMirrorErrors(params) { } } - for (const [dependencyName, mirror] of params.requiredRootMirrors) { - const rootSpec = rootRuntimeDeps.get(dependencyName); - const importers = [...mirror.importers].toSorted((left, right) => left.localeCompare(right)); - const importerLabel = importers.join(", "); - const pluginLabel = mirror.pluginIds - .toSorted((left, right) => left.localeCompare(right)) - .join(", "); - if (typeof rootSpec !== "string" || rootSpec.length === 0) { - errors.push( - `root dist imports bundled plugin runtime dependency '${dependencyName}' from ${importerLabel}; mirror '${dependencyName}: ${mirror.spec}' in root package.json (declared by ${pluginLabel}).`, - ); - continue; - } - if (rootSpec !== mirror.spec) { - errors.push( - `root dist imports bundled plugin runtime dependency '${dependencyName}' from ${importerLabel}; root package.json has '${rootSpec}' but plugin manifest declares '${mirror.spec}' (${pluginLabel}).`, - ); - } - } - return errors; } diff --git a/scripts/root-dependency-ownership-audit.mjs b/scripts/root-dependency-ownership-audit.mjs index ad72ea61d24..cb8e10925b3 100644 --- a/scripts/root-dependency-ownership-audit.mjs +++ b/scripts/root-dependency-ownership-audit.mjs @@ -130,11 +130,13 @@ export function classifyRootDependencyOwnership(record) { const sections = new Set(record.sections); if (record.rootMirrorImporters.length > 0) { - return { - category: "extension_only_root_mirror", - recommendation: - "blocked by packaged host graph: remove root mirror only after bundled runtime resolution stops importing it from root dist", - }; + if (!sectionSetContainsCore(sections)) { + return { + category: "extension_only_localizable", + recommendation: + "remove from root package.json and rely on owning extension manifests plus doctor --fix", + }; + } } if (sections.size === 0) { @@ -169,7 +171,7 @@ export function classifyRootDependencyOwnership(record) { return { category: "extension_only_localizable", recommendation: - "candidate to remove from root package.json and rely on owning extension manifests", + "remove from root package.json and rely on owning extension manifests plus doctor --fix", }; } diff --git a/src/plugins/contracts/package-manifest.contract.test.ts b/src/plugins/contracts/package-manifest.contract.test.ts index 3f1d4de2bfb..6749a1c4b03 100644 --- a/src/plugins/contracts/package-manifest.contract.test.ts +++ b/src/plugins/contracts/package-manifest.contract.test.ts @@ -6,31 +6,34 @@ const packageManifestContractTests: PackageManifestContractParams[] = [ { pluginId: "bluebubbles", minHostVersionBaseline: "2026.3.22" }, { pluginId: "discord", - mirroredRootRuntimeDeps: [ + pluginLocalRuntimeDeps: [ "@buape/carbon", "@discordjs/opus", + "@discordjs/voice", + "@snazzah/davey", "discord-api-types", - "https-proxy-agent", "opusscript", ], + mirroredRootRuntimeDeps: ["https-proxy-agent"], minHostVersionBaseline: "2026.3.22", }, { pluginId: "feishu", - mirroredRootRuntimeDeps: ["@larksuiteoapi/node-sdk"], + pluginLocalRuntimeDeps: ["@larksuiteoapi/node-sdk"], + mirroredRootRuntimeDeps: ["@sinclair/typebox", "qrcode-terminal"], minHostVersionBaseline: "2026.3.22", }, - { pluginId: "google", mirroredRootRuntimeDeps: ["@google/genai"] }, + { pluginId: "google", pluginLocalRuntimeDeps: ["@google/genai"] }, { pluginId: "googlechat", - mirroredRootRuntimeDeps: ["google-auth-library"], + pluginLocalRuntimeDeps: ["google-auth-library"], minHostVersionBaseline: "2026.3.22", }, { pluginId: "irc", minHostVersionBaseline: "2026.3.22" }, { pluginId: "line", minHostVersionBaseline: "2026.3.22" }, { pluginId: "amazon-bedrock", - mirroredRootRuntimeDeps: [ + pluginLocalRuntimeDeps: [ "@aws-sdk/client-bedrock", "@aws-sdk/client-bedrock-runtime", "@aws-sdk/credential-provider-node", @@ -38,34 +41,73 @@ const packageManifestContractTests: PackageManifestContractParams[] = [ }, { pluginId: "amazon-bedrock-mantle", - mirroredRootRuntimeDeps: ["@aws/bedrock-token-generator"], + pluginLocalRuntimeDeps: ["@aws/bedrock-token-generator"], + }, + { + pluginId: "diffs", + pluginLocalRuntimeDeps: ["@pierre/diffs", "@pierre/theme", "playwright-core"], + mirroredRootRuntimeDeps: ["@sinclair/typebox"], + }, + { + pluginId: "matrix", + pluginLocalRuntimeDeps: [ + "@matrix-org/matrix-sdk-crypto-nodejs", + "@matrix-org/matrix-sdk-crypto-wasm", + "fake-indexeddb", + "matrix-js-sdk", + "music-metadata", + ], + mirroredRootRuntimeDeps: ["markdown-it"], + minHostVersionBaseline: "2026.3.22", }, - { pluginId: "matrix", minHostVersionBaseline: "2026.3.22" }, { pluginId: "mattermost", minHostVersionBaseline: "2026.3.22" }, { pluginId: "memory-lancedb", - mirroredRootRuntimeDeps: ["@lancedb/lancedb", "openai"], + pluginLocalRuntimeDeps: ["@lancedb/lancedb"], + mirroredRootRuntimeDeps: ["@sinclair/typebox", "openai"], + minHostVersionBaseline: "2026.3.22", + }, + { + pluginId: "msteams", + pluginLocalRuntimeDeps: [ + "@azure/identity", + "@microsoft/teams.api", + "@microsoft/teams.apps", + "jsonwebtoken", + "jwks-rsa", + ], + mirroredRootRuntimeDeps: ["@sinclair/typebox", "express"], minHostVersionBaseline: "2026.3.22", }, - { pluginId: "msteams", minHostVersionBaseline: "2026.3.22" }, { pluginId: "nextcloud-talk", minHostVersionBaseline: "2026.3.22" }, - { pluginId: "nostr", minHostVersionBaseline: "2026.3.22" }, + { + pluginId: "nostr", + pluginLocalRuntimeDeps: ["nostr-tools"], + minHostVersionBaseline: "2026.3.22", + }, { pluginId: "openshell", pluginLocalRuntimeDeps: ["openshell"] }, + { + pluginId: "qqbot", + pluginLocalRuntimeDeps: ["mpg123-decoder", "silk-wasm"], + mirroredRootRuntimeDeps: ["ws"], + }, { pluginId: "slack", - mirroredRootRuntimeDeps: ["@slack/bolt", "@slack/web-api", "https-proxy-agent"], + pluginLocalRuntimeDeps: ["@slack/bolt", "@slack/web-api"], + mirroredRootRuntimeDeps: ["https-proxy-agent"], }, { pluginId: "synology-chat", minHostVersionBaseline: "2026.3.22" }, { pluginId: "telegram", - mirroredRootRuntimeDeps: ["@grammyjs/runner", "@grammyjs/transformer-throttler", "grammy"], + pluginLocalRuntimeDeps: ["@grammyjs/runner", "@grammyjs/transformer-throttler", "grammy"], }, { pluginId: "tlon", minHostVersionBaseline: "2026.3.22" }, { pluginId: "twitch", minHostVersionBaseline: "2026.3.22" }, { pluginId: "voice-call", minHostVersionBaseline: "2026.3.22" }, { pluginId: "whatsapp", - mirroredRootRuntimeDeps: ["@whiskeysockets/baileys", "jimp"], + pluginLocalRuntimeDeps: ["@whiskeysockets/baileys", "jimp"], + mirroredRootRuntimeDeps: ["qrcode-terminal"], minHostVersionBaseline: "2026.3.22", }, { pluginId: "zalo", minHostVersionBaseline: "2026.3.22" }, diff --git a/src/plugins/contracts/plugin-sdk-package-contract-guardrails.test.ts b/src/plugins/contracts/plugin-sdk-package-contract-guardrails.test.ts index 35815290d53..7f30425ebca 100644 --- a/src/plugins/contracts/plugin-sdk-package-contract-guardrails.test.ts +++ b/src/plugins/contracts/plugin-sdk-package-contract-guardrails.test.ts @@ -1,7 +1,6 @@ import { readdirSync, readFileSync } from "node:fs"; -import { createRequire } from "node:module"; import { dirname, join, relative, resolve } from "node:path"; -import { fileURLToPath, pathToFileURL } from "node:url"; +import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; import { pluginSdkEntrypoints } from "../../plugin-sdk/entrypoints.js"; @@ -77,10 +76,6 @@ function collectRuntimeDependencySpecs(packageJson: { ]); } -function createRootPackageRequire() { - return createRequire(pathToFileURL(resolve(REPO_ROOT, "package.json")).href); -} - function collectExtensionFiles(dir: string): string[] { const entries = readdirSync(dir, { withFileTypes: true }); const files: string[] = []; @@ -163,7 +158,7 @@ describe("plugin-sdk package contract guardrails", () => { expect(failures).toEqual([]); }); - it("mirrors package runtime deps needed by bundled host graphs", () => { + it("keeps Matrix runtime deps local to the Matrix plugin", () => { const rootRuntimeDeps = collectRuntimeDependencySpecs(readRootPackageJson()); const matrixPackageJson = readMatrixPackageJson(); const matrixRuntimeDeps = collectRuntimeDependencySpecs(matrixPackageJson); @@ -174,21 +169,12 @@ describe("plugin-sdk package contract guardrails", () => { "fake-indexeddb", "matrix-js-sdk", ]) { - expect(rootRuntimeDeps.get(dep)).toBe(matrixRuntimeDeps.get(dep)); + expect(matrixRuntimeDeps.get(dep)).toBeDefined(); + expect(rootRuntimeDeps.has(dep)).toBe(false); } expect(rootRuntimeDeps.has("@openclaw/plugin-package-contract")).toBe(false); }); - it("resolves matrix crypto WASM from the root runtime surface", () => { - const rootRequire = createRootPackageRequire(); - // Normalize filesystem separators so the package assertion stays portable. - const resolvedPath = rootRequire - .resolve("@matrix-org/matrix-sdk-crypto-wasm") - .replaceAll("\\", "/"); - - expect(resolvedPath).toContain("@matrix-org/matrix-sdk-crypto-wasm"); - }); - it("keeps extension sources on public sdk or local package seams", () => { expect(collectExtensionCoreImportLeaks()).toEqual([]); }); diff --git a/test/openclaw-npm-postpublish-verify.test.ts b/test/openclaw-npm-postpublish-verify.test.ts index dc26443e113..43c92c8796c 100644 --- a/test/openclaw-npm-postpublish-verify.test.ts +++ b/test/openclaw-npm-postpublish-verify.test.ts @@ -170,7 +170,7 @@ describe("collectInstalledMirroredRootDependencyManifestErrors", () => { writeFileSync(fullPath, `${JSON.stringify(value, null, 2)}\n`, "utf8"); } - it("flags missing root mirrors for bundled plugin deps imported by root dist", () => { + it("does not require root mirrors for bundled plugin deps imported by root dist", () => { const packageRoot = makeInstalledPackageRoot(); try { @@ -190,9 +190,7 @@ describe("collectInstalledMirroredRootDependencyManifestErrors", () => { "utf8", ); - expect(collectInstalledMirroredRootDependencyManifestErrors(packageRoot)).toEqual([ - "root dist imports bundled plugin runtime dependency '@slack/web-api' from probe-Cz2PiFtC.js; mirror '@slack/web-api: ^7.15.0' in root package.json (declared by slack).", - ]); + expect(collectInstalledMirroredRootDependencyManifestErrors(packageRoot)).toEqual([]); } finally { rmSync(packageRoot, { recursive: true, force: true }); } @@ -226,7 +224,7 @@ describe("collectInstalledMirroredRootDependencyManifestErrors", () => { } }); - it("flags root mirror dependency version mismatches", () => { + it("does not compare root mirror dependency versions", () => { const packageRoot = makeInstalledPackageRoot(); try { @@ -248,9 +246,7 @@ describe("collectInstalledMirroredRootDependencyManifestErrors", () => { "utf8", ); - expect(collectInstalledMirroredRootDependencyManifestErrors(packageRoot)).toEqual([ - "root dist imports bundled plugin runtime dependency '@slack/web-api' from probe-Cz2PiFtC.js; root package.json has '^7.16.0' but plugin manifest declares '^7.15.0' (slack).", - ]); + expect(collectInstalledMirroredRootDependencyManifestErrors(packageRoot)).toEqual([]); } finally { rmSync(packageRoot, { recursive: true, force: true }); } diff --git a/test/release-check.test.ts b/test/release-check.test.ts index dad4d74379e..70e31d1c9b7 100644 --- a/test/release-check.test.ts +++ b/test/release-check.test.ts @@ -192,7 +192,7 @@ describe("bundled plugin root runtime mirrors", () => { } }); - it("flags missing root mirrors for plugin deps imported by root dist", () => { + it("does not require root mirrors for plugin deps imported by root dist", () => { expect( collectBundledPluginRootRuntimeMirrorErrors({ bundledRuntimeDependencySpecs: makeBundledSpecs(), @@ -208,12 +208,10 @@ describe("bundled plugin root runtime mirrors", () => { ]), rootPackageJson: { dependencies: {} }, }), - ).toEqual([ - "root dist imports bundled plugin runtime dependency '@larksuiteoapi/node-sdk' from probe-Cz2PiFtC.js; mirror '@larksuiteoapi/node-sdk: ^1.60.0' in root package.json (declared by feishu).", - ]); + ).toEqual([]); }); - it("flags root mirror version drift from plugin manifests", () => { + it("does not compare root mirror versions for plugin manifest deps", () => { expect( collectBundledPluginRootRuntimeMirrorErrors({ bundledRuntimeDependencySpecs: makeBundledSpecs(), @@ -229,9 +227,7 @@ describe("bundled plugin root runtime mirrors", () => { ]), rootPackageJson: { dependencies: { "@larksuiteoapi/node-sdk": "^1.61.0" } }, }), - ).toEqual([ - "root dist imports bundled plugin runtime dependency '@larksuiteoapi/node-sdk' from probe-Cz2PiFtC.js; root package.json has '^1.61.0' but plugin manifest declares '^1.60.0' (feishu).", - ]); + ).toEqual([]); }); it("accepts matching root mirrors for plugin deps imported by root dist", () => { diff --git a/test/scripts/root-dependency-ownership-audit.test.ts b/test/scripts/root-dependency-ownership-audit.test.ts index cb5ad499504..8884344719d 100644 --- a/test/scripts/root-dependency-ownership-audit.test.ts +++ b/test/scripts/root-dependency-ownership-audit.test.ts @@ -18,16 +18,16 @@ describe("collectModuleSpecifiers", () => { }); describe("classifyRootDependencyOwnership", () => { - it("treats root-dist bundled runtime mirrors as blocked extension deps", () => { + it("treats root-dist bundled runtime imports as localizable extension deps", () => { expect( classifyRootDependencyOwnership({ sections: ["extensions"], rootMirrorImporters: ["discovery-DZDwKJdJ.js"], }), ).toEqual({ - category: "extension_only_root_mirror", + category: "extension_only_localizable", recommendation: - "blocked by packaged host graph: remove root mirror only after bundled runtime resolution stops importing it from root dist", + "remove from root package.json and rely on owning extension manifests plus doctor --fix", }); }); @@ -52,7 +52,7 @@ describe("classifyRootDependencyOwnership", () => { ).toEqual({ category: "extension_only_localizable", recommendation: - "candidate to remove from root package.json and rely on owning extension manifests", + "remove from root package.json and rely on owning extension manifests plus doctor --fix", }); });