fix: narrow bundled runtime mirror materialization

This commit is contained in:
Peter Steinberger
2026-04-27 23:52:46 +01:00
parent 9f9bcfe231
commit 87345c0667
3 changed files with 44 additions and 1 deletions

View File

@@ -71,6 +71,9 @@ const BUNDLED_RUNTIME_MIRROR_MATERIALIZED_EXTENSIONS = new Set([".cjs", ".js", "
const BUNDLED_EXTENSION_DIST_DIR = "extensions";
const MIRRORED_CORE_RUNTIME_DEP_NAMES = ["tslog"] as const;
const MIRRORED_PACKAGE_RUNTIME_DEP_PLUGIN_ID = "openclaw-core";
const BUNDLED_RUNTIME_MIRROR_PLUGIN_REGION_RE = /(?:^|\n)\/\/#region extensions\/[^/\s]+(?:\/|$)/u;
const BUNDLED_RUNTIME_MIRROR_IMPORT_SPECIFIER_RE =
/(?:^|[;\n])\s*(?:import|export)\s+(?:[^'"()]+?\s+from\s+)?["']([^"']+)["']|\bimport\(\s*["']([^"']+)["']\s*\)|\brequire\(\s*["']([^"']+)["']\s*\)/g;
const registeredBundledRuntimeDepNodePaths = new Set<string>();
@@ -81,7 +84,31 @@ export type BundledRuntimeDepsNpmRunner = {
};
export function shouldMaterializeBundledRuntimeMirrorDistFile(sourcePath: string): boolean {
return BUNDLED_RUNTIME_MIRROR_MATERIALIZED_EXTENSIONS.has(path.extname(sourcePath));
if (!BUNDLED_RUNTIME_MIRROR_MATERIALIZED_EXTENSIONS.has(path.extname(sourcePath))) {
return false;
}
let source: string;
try {
source = fs.readFileSync(sourcePath, "utf8");
} catch {
return false;
}
if (BUNDLED_RUNTIME_MIRROR_PLUGIN_REGION_RE.test(source)) {
return true;
}
for (const match of source.matchAll(BUNDLED_RUNTIME_MIRROR_IMPORT_SPECIFIER_RE)) {
const specifier = match[1] ?? match[2] ?? match[3] ?? "";
if (
specifier !== "" &&
!specifier.startsWith(".") &&
!specifier.startsWith("/") &&
!specifier.startsWith("node:") &&
!specifier.includes(":")
) {
return false;
}
}
return true;
}
export function materializeBundledRuntimeMirrorDistFile(

View File

@@ -51,6 +51,11 @@ describe("prepareBundledPluginRuntimeRoot", () => {
"export const shared = 'mirrored-without-region';\n",
"utf8",
);
fs.writeFileSync(
path.join(packageRoot, "dist", "config-runtime.js"),
"import JSON5 from 'json5'; export const parse = JSON5.parse;\n",
"utf8",
);
fs.writeFileSync(
path.join(pluginRoot, "index.js"),
`import { marker } from "../../pw-ai.js"; export default { id: "browser", marker };\n`,
@@ -118,6 +123,9 @@ describe("prepareBundledPluginRuntimeRoot", () => {
expect(fs.lstatSync(path.join(installRoot, "dist", "shared-runtime.js")).isSymbolicLink()).toBe(
false,
);
expect(fs.lstatSync(path.join(installRoot, "dist", "config-runtime.js")).isSymbolicLink()).toBe(
true,
);
});
it("does not copy staged runtime mirror dist files onto themselves", () => {

View File

@@ -1745,6 +1745,11 @@ module.exports = {
"export const shared = 'mirrored-without-region';\n",
"utf-8",
);
fs.writeFileSync(
path.join(packageRoot, "dist", "config-runtime.js"),
"import JSON5 from 'json5'; export const parse = JSON5.parse;\n",
"utf-8",
);
fs.writeFileSync(
path.join(pluginRoot, "index.js"),
[
@@ -1841,6 +1846,9 @@ module.exports = {
expect(
fs.lstatSync(path.join(actualInstallRoot, "dist", "shared-runtime.js")).isSymbolicLink(),
).toBe(false);
expect(
fs.lstatSync(path.join(actualInstallRoot, "dist", "config-runtime.js")).isSymbolicLink(),
).toBe(true);
});
it("loads bundled plugins with plugin-sdk imports from an external stage dir", () => {