fix(update): infer legacy bundled sidecars

This commit is contained in:
Ayaan Zaidi
2026-04-15 11:43:22 +05:30
parent 2a8226f8e2
commit 8b79141997
2 changed files with 49 additions and 1 deletions

View File

@@ -421,4 +421,27 @@ describe("update global helpers", () => {
);
});
});
it("verifies legacy sidecars for installed bundled plugins without inventory", async () => {
await withTempDir({ prefix: "openclaw-update-global-legacy-plugin-" }, async (packageRoot) => {
await fs.writeFile(
path.join(packageRoot, "package.json"),
JSON.stringify({ name: "openclaw", version: "1.0.0" }),
"utf-8",
);
const matrixPackageJson = path.join(
packageRoot,
"dist",
"extensions",
"matrix",
"package.json",
);
await fs.mkdir(path.dirname(matrixPackageJson), { recursive: true });
await fs.writeFile(matrixPackageJson, JSON.stringify({ name: "@openclaw/matrix" }), "utf-8");
await expect(collectInstalledGlobalPackageErrors({ packageRoot })).resolves.toContain(
`missing bundled runtime sidecar ${MATRIX_HELPER_API}`,
);
});
});
});

View File

@@ -3,6 +3,7 @@ import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { NPM_UPDATE_COMPAT_SIDECAR_PATHS } from "../../scripts/lib/npm-update-compat-sidecars.mjs";
import { BUNDLED_RUNTIME_SIDECAR_PATHS } from "../plugins/runtime-sidecar-paths.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { pathExists } from "../utils.js";
import {
@@ -110,12 +111,36 @@ async function collectInstalledPackageDistErrors(packageRoot: string): Promise<s
}
return await collectInstalledPathErrors({
packageRoot,
expectedFiles: [...NPM_UPDATE_COMPAT_SIDECAR_PATHS],
expectedFiles: await collectLegacyInstalledPackageDistPaths(packageRoot),
actualFiles: null,
missingMessage: (relativePath) => `missing bundled runtime sidecar ${relativePath}`,
});
}
async function collectLegacyInstalledPackageDistPaths(packageRoot: string): Promise<string[]> {
const expectedFiles = new Set(NPM_UPDATE_COMPAT_SIDECAR_PATHS);
await Promise.all(
BUNDLED_RUNTIME_SIDECAR_PATHS.map(async (relativePath) => {
const pluginRoot = resolveBundledPluginRoot(relativePath);
if (pluginRoot === null) {
return;
}
if (
(await pathExists(path.join(packageRoot, pluginRoot, "package.json"))) ||
(await pathExists(path.join(packageRoot, pluginRoot, "openclaw.plugin.json")))
) {
expectedFiles.add(relativePath);
}
}),
);
return [...expectedFiles].toSorted((left, right) => left.localeCompare(right));
}
function resolveBundledPluginRoot(relativePath: string): string | null {
const match = /^dist\/extensions\/[^/]+/u.exec(relativePath);
return match ? match[0] : null;
}
async function collectInstalledPathErrors(params: {
packageRoot: string;
expectedFiles: string[];