refactor: simplify plugin dependency handling

Simplify plugin installation and runtime loading around package-manager-owned dependencies, with Jiti reserved for local/TS fallback paths.

Also scans npm plugin install roots so hoisted transitive dependencies are covered by dependency denylist and node_modules symlink checks.
This commit is contained in:
Peter Steinberger
2026-05-01 21:32:22 +01:00
committed by GitHub
parent 2e8e9cd6ca
commit ed8f50f240
294 changed files with 2562 additions and 25454 deletions

View File

@@ -106,68 +106,18 @@ describe("resolveTsdownBuildInvocation", () => {
).rejects.toThrow();
});
it("cleans tsdown output roots before using tsdown --no-clean without deleting staged runtime deps", async () => {
it("cleans tsdown output roots before using tsdown --no-clean", async () => {
const rootDir = createTempDir("openclaw-tsdown-clean-");
const distFile = path.join(rootDir, "dist", "stale.js");
const pluginManifest = path.join(rootDir, "extensions", "telegram", "openclaw.plugin.json");
const pluginSourceManifest = path.join(rootDir, "extensions", "telegram", "package.json");
const pluginGeneratedFile = path.join(rootDir, "dist", "extensions", "telegram", "index.js");
const pluginRuntimeDepFile = path.join(
rootDir,
"dist",
"extensions",
"telegram",
"node_modules",
"grammy",
"package.json",
);
const stalePluginRuntimeDepFile = path.join(
rootDir,
"dist",
"extensions",
"old-plugin",
"node_modules",
"left-pad",
"package.json",
);
const unstagedPluginSourceManifest = path.join(
rootDir,
"extensions",
"unstaged-plugin",
"package.json",
);
const unstagedPluginRuntimeDepFile = path.join(
rootDir,
"dist",
"extensions",
"unstaged-plugin",
"node_modules",
"left-pad",
"package.json",
);
const distRuntimeFile = path.join(rootDir, "dist-runtime", "stale.js");
const unrelatedFile = path.join(rootDir, "tmp", "keep.js");
await fsPromises.mkdir(path.dirname(distFile), { recursive: true });
await fsPromises.mkdir(path.dirname(pluginManifest), { recursive: true });
await fsPromises.mkdir(path.dirname(pluginSourceManifest), { recursive: true });
await fsPromises.mkdir(path.dirname(pluginGeneratedFile), { recursive: true });
await fsPromises.mkdir(path.dirname(pluginRuntimeDepFile), { recursive: true });
await fsPromises.mkdir(path.dirname(stalePluginRuntimeDepFile), { recursive: true });
await fsPromises.mkdir(path.dirname(unstagedPluginSourceManifest), { recursive: true });
await fsPromises.mkdir(path.dirname(unstagedPluginRuntimeDepFile), { recursive: true });
await fsPromises.mkdir(path.dirname(distRuntimeFile), { recursive: true });
await fsPromises.mkdir(path.dirname(unrelatedFile), { recursive: true });
await fsPromises.writeFile(distFile, "stale\n");
await fsPromises.writeFile(pluginManifest, '{"id":"telegram"}\n');
await fsPromises.writeFile(
pluginSourceManifest,
'{"openclaw":{"bundle":{"stageRuntimeDependencies":true}}}\n',
);
await fsPromises.writeFile(pluginGeneratedFile, "generated\n");
await fsPromises.writeFile(pluginRuntimeDepFile, "{}\n");
await fsPromises.writeFile(stalePluginRuntimeDepFile, "{}\n");
await fsPromises.writeFile(unstagedPluginSourceManifest, "{}\n");
await fsPromises.writeFile(unstagedPluginRuntimeDepFile, "{}\n");
await fsPromises.writeFile(distRuntimeFile, "stale\n");
await fsPromises.writeFile(unrelatedFile, "keep\n");
@@ -175,13 +125,6 @@ describe("resolveTsdownBuildInvocation", () => {
await expect(fsPromises.stat(distFile)).rejects.toThrow();
await expect(fsPromises.stat(pluginGeneratedFile)).rejects.toThrow();
await expect(fsPromises.readFile(pluginRuntimeDepFile, "utf8")).resolves.toBe("{}\n");
await expect(
fsPromises.stat(path.join(rootDir, "dist", "extensions", "old-plugin")),
).rejects.toThrow();
await expect(
fsPromises.stat(path.join(rootDir, "dist", "extensions", "unstaged-plugin")),
).rejects.toThrow();
await expect(fsPromises.stat(path.join(rootDir, "dist-runtime"))).rejects.toThrow();
await expect(fsPromises.readFile(unrelatedFile, "utf8")).resolves.toBe("keep\n");
});