fix: suppress false duplicate plugin id warning for symlinked extensions

When the same plugin directory is discovered through different path
representations (e.g. symlinks), the manifest registry incorrectly
warns about a duplicate plugin id. This is a false positive that
appears for bundled extensions like feishu (#16208).

Compare fs.realpathSync() of both candidates' rootDir before emitting
the duplicate warning. If they resolve to the same physical directory,
silently skip the duplicate instead of warning.

Also change seenIds from Set<string> to Map<string, PluginCandidate>
to track the first-seen candidate for comparison.

Closes #16208
This commit is contained in:
shadril238
2026-02-14 19:49:23 +06:00
committed by Peter Steinberger
parent 1a7e180e68
commit 788ea6e9d1
2 changed files with 155 additions and 3 deletions

View File

@@ -138,7 +138,7 @@ export function loadPluginManifestRegistry(params: {
const diagnostics: PluginDiagnostic[] = [...discovery.diagnostics];
const candidates: PluginCandidate[] = discovery.candidates;
const records: PluginManifestRecord[] = [];
const seenIds = new Set<string>();
const seenIds = new Map<string, PluginCandidate>();
for (const candidate of candidates) {
const manifestRes = loadPluginManifest(candidate.rootDir);
@@ -161,7 +161,21 @@ export function loadPluginManifestRegistry(params: {
});
}
if (seenIds.has(manifest.id)) {
const existingCandidate = seenIds.get(manifest.id);
if (existingCandidate) {
// Check whether both candidates point to the same physical directory
// (e.g. via symlinks or different path representations). If so, this
// is a false-positive duplicate and can be silently skipped.
let samePlugin = false;
try {
samePlugin =
fs.realpathSync(existingCandidate.rootDir) === fs.realpathSync(candidate.rootDir);
} catch {
// If either path is inaccessible, fall through to duplicate warning
}
if (samePlugin) {
continue;
}
diagnostics.push({
level: "warn",
pluginId: manifest.id,
@@ -169,7 +183,7 @@ export function loadPluginManifestRegistry(params: {
message: `duplicate plugin id detected; later plugin may be overridden (${candidate.source})`,
});
} else {
seenIds.add(manifest.id);
seenIds.set(manifest.id, candidate);
}
const configSchema = manifest.configSchema;