fix(plugins): warn when npm install is shadowed

This commit is contained in:
Yuyummy
2026-05-03 18:20:05 +08:00
committed by Peter Steinberger
parent 0459bff556
commit f73a614d66
4 changed files with 177 additions and 1 deletions

View File

@@ -78,6 +78,40 @@ describe("plugins cli list", () => {
expect(runtimeLogs).toContain("No plugin issues detected.");
});
it("reports config-selected plugin source shadowing in doctor output", async () => {
buildPluginDiagnosticsReport.mockReturnValue({
plugins: [
createPluginRecord({
id: "discord",
origin: "config",
source: "/tmp/openclaw-upstream/extensions/discord/index.ts",
status: "error",
error: "Cannot find module 'chalk'",
}),
],
diagnostics: [
{
level: "warn",
pluginId: "discord",
source: "/tmp/openclaw/npm/node_modules/@openclaw/discord/index.ts",
message:
"duplicate plugin id resolved by explicit config-selected plugin; global plugin will be overridden by config plugin (/tmp/openclaw-upstream/extensions/discord/index.ts)",
},
],
});
await runPluginsCommand(["plugins", "doctor"]);
const output = runtimeLogs.join("\n");
expect(output).toContain("Plugin source shadowing:");
expect(output).toContain(
"discord: duplicate plugin id resolved by explicit config-selected plugin",
);
expect(output).toContain("active: /tmp/openclaw-upstream/extensions/discord/index.ts");
expect(output).toContain("shadowed: /tmp/openclaw/npm/node_modules/@openclaw/discord/index.ts");
expect(output).toContain("openclaw plugins registry --refresh");
});
it("reports persisted plugin registry state without refreshing", async () => {
inspectPluginRegistry.mockResolvedValue({
state: "stale",