From 76c327c0964a0bfcec73e72931fff00613addc34 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 2 May 2026 11:33:11 -0700 Subject: [PATCH] fix(plugins): remove unsupported bundle metadata --- docs/plugins/manifest.md | 3 +++ extensions/qqbot/package.json | 3 --- scripts/lib/bundled-plugin-build-entries.mjs | 7 ++----- scripts/postinstall-bundled-plugins.mjs | 14 +------------- src/plugins/bundle-manifest.test.ts | 10 ++++++++++ test/scripts/postinstall-bundled-plugins.test.ts | 8 -------- 6 files changed, 16 insertions(+), 29 deletions(-) diff --git a/docs/plugins/manifest.md b/docs/plugins/manifest.md index 273b6c8b1bf..bdb88364a0c 100644 --- a/docs/plugins/manifest.md +++ b/docs/plugins/manifest.md @@ -1149,6 +1149,9 @@ If you are unsure where a piece of metadata belongs, use this rule: Some pre-runtime plugin metadata intentionally lives in `package.json` under the `openclaw` block instead of `openclaw.plugin.json`. +`openclaw.bundle` and `openclaw.bundle.json` are not OpenClaw plugin contracts; +native plugins must use `openclaw.plugin.json` plus the supported +`package.json#openclaw` fields below. Important examples: diff --git a/extensions/qqbot/package.json b/extensions/qqbot/package.json index 697b0a0e330..d79e9d4c965 100644 --- a/extensions/qqbot/package.json +++ b/extensions/qqbot/package.json @@ -55,9 +55,6 @@ "build": { "openclawVersion": "2026.5.2" }, - "bundle": { - "includeInCore": false - }, "release": { "publishToClawHub": true, "publishToNpm": true diff --git a/scripts/lib/bundled-plugin-build-entries.mjs b/scripts/lib/bundled-plugin-build-entries.mjs index ca868c59026..272c28846af 100644 --- a/scripts/lib/bundled-plugin-build-entries.mjs +++ b/scripts/lib/bundled-plugin-build-entries.mjs @@ -9,6 +9,7 @@ import { shouldBuildBundledCluster } from "./optional-bundled-clusters.mjs"; const TOP_LEVEL_PUBLIC_SURFACE_EXTENSIONS = new Set([".ts", ".js", ".mts", ".cts", ".mjs", ".cjs"]); export const NON_PACKAGED_BUNDLED_PLUGIN_DIRS = new Set(["qa-channel", "qa-lab", "qa-matrix"]); +const EXCLUDED_CORE_BUNDLED_PLUGIN_DIRS = new Set(["qqbot"]); const toPosixPath = (value) => value.replaceAll("\\", "/"); function readBundledPluginPackageJson(packageJsonPath) { @@ -47,10 +48,6 @@ function collectPluginSourceEntries(packageJson) { return packageEntries.length > 0 ? packageEntries : ["./index.ts"]; } -function shouldIncludeBundledPluginInCore(packageJson) { - return packageJson?.openclaw?.bundle?.includeInCore !== false; -} - function collectTopLevelPublicSurfaceEntries(pluginDir) { if (!fs.existsSync(pluginDir)) { return []; @@ -115,7 +112,7 @@ export function collectBundledPluginBuildEntries(params = {}) { if (!shouldBuildBundledCluster(dirent.name, env, { packageJson })) { continue; } - if (!shouldIncludeBundledPluginInCore(packageJson)) { + if (EXCLUDED_CORE_BUNDLED_PLUGIN_DIRS.has(dirent.name)) { continue; } diff --git a/scripts/postinstall-bundled-plugins.mjs b/scripts/postinstall-bundled-plugins.mjs index f533198d5ef..6dee0164a4a 100644 --- a/scripts/postinstall-bundled-plugins.mjs +++ b/scripts/postinstall-bundled-plugins.mjs @@ -713,22 +713,10 @@ export async function runPluginRegistryPostinstallMigration(params = {}) { export function isSourceCheckoutRoot(params) { const pathExists = params.existsSync ?? existsSync; - const readFile = params.readFileSync ?? readFileSync; const hasPostinstallInventory = pathExists(join(params.packageRoot, DIST_INVENTORY_PATH)); - let hasDeclaredMirroredPackageRuntimeDeps = false; - try { - const packageJson = JSON.parse(readFile(join(params.packageRoot, "package.json"), "utf8")); - const mirrored = packageJson?.openclaw?.bundle?.mirroredRootRuntimeDependencies; - hasDeclaredMirroredPackageRuntimeDeps = Array.isArray(mirrored) && mirrored.length > 0; - } catch { - hasDeclaredMirroredPackageRuntimeDeps = false; - } - const hasPackagedRuntimeDepsLayout = - hasPostinstallInventory || hasDeclaredMirroredPackageRuntimeDeps; return ( (pathExists(join(params.packageRoot, ".git")) || - (pathExists(join(params.packageRoot, "pnpm-workspace.yaml")) && - !hasPackagedRuntimeDepsLayout)) && + (pathExists(join(params.packageRoot, "pnpm-workspace.yaml")) && !hasPostinstallInventory)) && pathExists(join(params.packageRoot, "src")) && pathExists(join(params.packageRoot, "extensions")) ); diff --git a/src/plugins/bundle-manifest.test.ts b/src/plugins/bundle-manifest.test.ts index 3bb1b0503ef..4eb130decd1 100644 --- a/src/plugins/bundle-manifest.test.ts +++ b/src/plugins/bundle-manifest.test.ts @@ -133,6 +133,16 @@ afterEach(() => { }); describe("bundle manifest parsing", () => { + it("does not treat openclaw.bundle.json as a bundle manifest", () => { + const rootDir = makeTempDir(); + writeBundleManifest(rootDir, "openclaw.bundle.json", { + name: "Not Real", + skills: ["skills"], + }); + + expect(detectBundleManifestFormat(rootDir)).toBeNull(); + }); + it.each([ { name: "detects and loads Codex bundle manifests", diff --git a/test/scripts/postinstall-bundled-plugins.test.ts b/test/scripts/postinstall-bundled-plugins.test.ts index dbd451cc5a3..d13c14d849d 100644 --- a/test/scripts/postinstall-bundled-plugins.test.ts +++ b/test/scripts/postinstall-bundled-plugins.test.ts @@ -152,14 +152,6 @@ describe("bundled plugin postinstall", () => { isSourceCheckoutRoot({ packageRoot, existsSync: (value: string) => existingPaths.has(value), - readFileSync: () => - JSON.stringify({ - openclaw: { - bundle: { - mirroredRootRuntimeDependencies: ["json5"], - }, - }, - }), }), ).toBe(false); });