fix(plugins): dedupe manifest diagnostics

This commit is contained in:
Vincent Koc
2026-05-03 13:51:14 -07:00
parent 9ebdd26020
commit 5355ef0f08
3 changed files with 46 additions and 1 deletions

View File

@@ -400,6 +400,36 @@ describe("loadPluginManifestRegistry", () => {
expect(warning?.message).toContain(path.join(configDir, "index.ts"));
});
it("deduplicates compatibility diagnostics when a config plugin replaces a global candidate", () => {
const globalDir = makeTempDir();
const configDir = makeTempDir();
const manifest = {
id: "external-chat",
channels: ["external-chat"],
configSchema: { type: "object" },
};
writeManifest(globalDir, manifest);
writeManifest(configDir, manifest);
const registry = loadRegistry([
createPluginCandidate({
idHint: "external-chat",
rootDir: globalDir,
origin: "global",
}),
createPluginCandidate({
idHint: "external-chat",
rootDir: configDir,
origin: "config",
}),
]);
const channelConfigWarnings = registry.diagnostics.filter((diagnostic) =>
diagnostic.message.includes("without channelConfigs metadata"),
);
expect(channelConfigWarnings).toHaveLength(1);
});
it("suppresses duplicate warnings for explicit installed globals overriding bundled plugins", () => {
const bundledDir = makeTempDir();
const globalDir = makeTempDir();

View File

@@ -490,6 +490,20 @@ function pushManifestCompatibilityDiagnostics(params: {
pushNonBundledChannelConfigDescriptorDiagnostic(params);
}
function dedupePluginDiagnostics(diagnostics: PluginDiagnostic[]): PluginDiagnostic[] {
const seen = new Set<string>();
const deduped: PluginDiagnostic[] = [];
for (const diagnostic of diagnostics) {
const key = JSON.stringify([diagnostic.level, diagnostic.pluginId ?? "", diagnostic.message]);
if (seen.has(key)) {
continue;
}
seen.add(key);
deduped.push(diagnostic);
}
return deduped;
}
function matchesInstalledPluginRecord(params: {
pluginId: string;
candidate: PluginCandidate;
@@ -786,6 +800,6 @@ export function loadPluginManifestRegistry(
pushManifestCompatibilityDiagnostics({ record, diagnostics });
}
const registry = { plugins: records, diagnostics };
const registry = { plugins: records, diagnostics: dedupePluginDiagnostics(diagnostics) };
return registry;
}