fix(plugins): remove unsupported bundle metadata

This commit is contained in:
Vincent Koc
2026-05-02 11:33:11 -07:00
parent 62aa4df3da
commit 76c327c096
6 changed files with 16 additions and 29 deletions

View File

@@ -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:

View File

@@ -55,9 +55,6 @@
"build": {
"openclawVersion": "2026.5.2"
},
"bundle": {
"includeInCore": false
},
"release": {
"publishToClawHub": true,
"publishToNpm": true

View File

@@ -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;
}

View File

@@ -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"))
);

View File

@@ -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",

View File

@@ -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);
});