




















@@ -1696,6 +1696,42 @@ describe("ensureBundledPluginRuntimeDeps", () => {
16961696).toEqual({ installedSpecs: [], retainSpecs: [] });
16971697});
169816981699+it("resolves nested cache pluginRoot to enclosing versioned cache (regression for #72956)", () => {
1700+const packageRoot = makeTempDir();
1701+const stageDir = makeTempDir();
1702+fs.writeFileSync(
1703+path.join(packageRoot, "package.json"),
1704+JSON.stringify({ name: "openclaw", version: "2026.4.25" }),
1705+);
1706+const pluginRoot = path.join(packageRoot, "dist", "extensions", "telegram");
1707+fs.mkdirSync(pluginRoot, { recursive: true });
1708+fs.writeFileSync(
1709+path.join(pluginRoot, "package.json"),
1710+JSON.stringify({ dependencies: { grammy: "^1.42.0" } }),
1711+);
1712+const env = { OPENCLAW_PLUGIN_STAGE_DIR: stageDir };
1713+const installRoot = resolveBundledRuntimeDependencyInstallRoot(pluginRoot, { env });
1714+1715+// Simulate a deeply-nested pluginRoot inside the existing cache directory
1716+// (e.g. plugin-sdk loaded as a transitive dep). The path no longer matches
1717+// `<root>/dist/extensions/<plugin>`, so resolveBundledPluginPackageRoot()
1718+// returns null and the caller previously fell back to the raw pluginRoot,
1719+// generating a self-referential `openclaw-unknown-*` cache directory.
1720+const nestedPluginRoot = path.join(
1721+installRoot,
1722+"dist",
1723+"extensions",
1724+"node_modules",
1725+"openclaw",
1726+"plugin-sdk",
1727+);
1728+fs.mkdirSync(nestedPluginRoot, { recursive: true });
1729+1730+const resolved = resolveBundledRuntimeDependencyInstallRoot(nestedPluginRoot, { env });
1731+expect(resolved).toBe(installRoot);
1732+expect(path.basename(resolved).startsWith("openclaw-unknown-")).toBe(false);
1733+});
1734+16991735it("links source-checkout runtime deps from the cache instead of copying them", () => {
17001736const packageRoot = makeTempDir();
17011737fs.writeFileSync(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。