























1+import fs from "node:fs/promises";
2+import os from "node:os";
3+import path from "node:path";
4+import { describe, expect, it } from "vitest";
5+import { runPostUpgradeProbes } from "./doctor-post-upgrade.js";
6+7+async function makeFixtureRoot(prefix: string): Promise<string> {
8+return await fs.mkdtemp(path.join(os.tmpdir(), `doctor-post-upgrade-${prefix}-`));
9+}
10+11+describe("runPostUpgradeProbes — plugin.entry_unresolved", () => {
12+it("flags an enabled plugin whose declared entry does not exist on disk", async () => {
13+const root = await makeFixtureRoot("entry-unresolved");
14+const pluginDir = path.join(root, "user-plugins", "ghost");
15+await fs.mkdir(pluginDir, { recursive: true });
16+// Plugin package.json declares ./dist/index.js but no dist/.
17+await fs.writeFile(
18+path.join(pluginDir, "package.json"),
19+JSON.stringify({
20+name: "ghost",
21+version: "0.0.1",
22+type: "module",
23+openclaw: { extensions: ["./dist/index.js"] },
24+}),
25+"utf-8",
26+);
27+await fs.writeFile(
28+path.join(pluginDir, "openclaw.plugin.json"),
29+JSON.stringify({ id: "ghost" }),
30+"utf-8",
31+);
32+33+const installsPath = path.join(root, "plugins", "installs.json");
34+await fs.mkdir(path.dirname(installsPath), { recursive: true });
35+await fs.writeFile(
36+installsPath,
37+JSON.stringify({
38+version: 1,
39+plugins: [
40+{
41+pluginId: "ghost",
42+manifestPath: path.join(pluginDir, "openclaw.plugin.json"),
43+rootDir: pluginDir,
44+enabled: true,
45+packageJson: { path: "package.json" },
46+},
47+],
48+}),
49+"utf-8",
50+);
51+52+const report = await runPostUpgradeProbes({ installsPath });
53+const finding = report.findings.find((f) => f.code === "plugin.entry_unresolved");
54+expect(finding).toBeDefined();
55+expect(finding?.level).toBe("error");
56+expect(finding?.plugin).toBe("ghost");
57+expect(finding?.entry).toBe("./dist/index.js");
58+});
59+60+it("emits no entry_unresolved findings when the entry resolves", async () => {
61+const root = await makeFixtureRoot("entry-ok");
62+const pluginDir = path.join(root, "user-plugins", "good");
63+await fs.mkdir(path.join(pluginDir, "dist"), { recursive: true });
64+await fs.writeFile(path.join(pluginDir, "dist", "index.js"), "export default {};", "utf-8");
65+await fs.writeFile(
66+path.join(pluginDir, "package.json"),
67+JSON.stringify({
68+name: "good",
69+version: "0.0.1",
70+type: "module",
71+openclaw: { extensions: ["./dist/index.js"] },
72+}),
73+"utf-8",
74+);
75+await fs.writeFile(
76+path.join(pluginDir, "openclaw.plugin.json"),
77+JSON.stringify({ id: "good" }),
78+"utf-8",
79+);
80+81+const installsPath = path.join(root, "plugins", "installs.json");
82+await fs.mkdir(path.dirname(installsPath), { recursive: true });
83+await fs.writeFile(
84+installsPath,
85+JSON.stringify({
86+version: 1,
87+plugins: [
88+{
89+pluginId: "good",
90+manifestPath: path.join(pluginDir, "openclaw.plugin.json"),
91+rootDir: pluginDir,
92+enabled: true,
93+packageJson: { path: "package.json" },
94+},
95+],
96+}),
97+"utf-8",
98+);
99+100+const report = await runPostUpgradeProbes({ installsPath });
101+expect(report.findings.filter((f) => f.code === "plugin.entry_unresolved")).toHaveLength(0);
102+});
103+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。