mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix: quiet installed plugin override warnings
This commit is contained in:
@@ -30,6 +30,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Plugins/discovery: follow symlinked plugin directories in global and workspace plugin roots while keeping broken links ignored and existing package safety checks in place. Fixes #36754; carries forward #72695 and #63206. Thanks @Quackstro, @ming1523, and @xsfX20.
|
||||
- Plugins/install: allow exact package-manager peer links back to the trusted OpenClaw host package during install security scans while continuing to block spoofed or nested escaping `node_modules` symlinks. Carries forward #70819. Thanks @fgabelmannjr.
|
||||
- Plugins/install: resolve plugin install destinations from the active profile state dir across CLI, ClawHub, marketplace, local path, and channel setup installs, so `openclaw --profile <name> plugins install ...` no longer writes into the default profile. Fixes #69960; carries forward #69971. Thanks @FrancisLyman and @Sanjays2402.
|
||||
- Plugins/registry: suppress duplicate-plugin startup warnings when a tracked npm-installed plugin intentionally overrides the bundled plugin with the same id. Carries forward #48673. Thanks @abdushsk.
|
||||
- Plugins/startup: reuse canonical realpath lookups throughout each plugin discovery pass, including package and manifest boundary checks, so Windows npm-global startups no longer repeat expensive path resolution for the same plugin roots. Fixes #65733. Thanks @welfo-beo.
|
||||
- Reply/link understanding: keep media and link preprocessing on stable runtime entrypoints and continue with raw message content if optional enrichment fails, so URL-bearing messages are no longer dropped after stale runtime chunk upgrades. Fixes #68466. Thanks @songshikang0111.
|
||||
- Discord: persist routed model-picker overrides when the hidden `/model` dispatch succeeds but the bound thread session store is still stale, including LM Studio suffixed model ids. Carries forward #61473. Thanks @Nanako0129.
|
||||
|
||||
@@ -370,7 +370,7 @@ describe("loadPluginManifestRegistry", () => {
|
||||
expect(warning?.message).toContain(path.join(configDir, "index.ts"));
|
||||
});
|
||||
|
||||
it("reports explicit installed globals as the effective duplicate winner", () => {
|
||||
it("suppresses duplicate warnings for explicit installed globals overriding bundled plugins", () => {
|
||||
const bundledDir = makeTempDir();
|
||||
const globalDir = makeTempDir();
|
||||
const manifest = { id: "zalouser", configSchema: { type: "object" } };
|
||||
@@ -399,11 +399,41 @@ describe("loadPluginManifestRegistry", () => {
|
||||
],
|
||||
});
|
||||
|
||||
expect(
|
||||
registry.diagnostics.some((diag) =>
|
||||
diag.message.includes("bundled plugin will be overridden by global plugin"),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(countDuplicateWarnings(registry)).toBe(0);
|
||||
expect(registry.plugins).toHaveLength(1);
|
||||
expect(registry.plugins[0]?.origin).toBe("global");
|
||||
});
|
||||
|
||||
it("suppresses duplicate warnings when the installed global is discovered before bundled", () => {
|
||||
const bundledDir = makeTempDir();
|
||||
const globalDir = makeTempDir();
|
||||
const manifest = { id: "zalouser", configSchema: { type: "object" } };
|
||||
writeManifest(bundledDir, manifest);
|
||||
writeManifest(globalDir, manifest);
|
||||
|
||||
const registry = loadPluginManifestRegistry({
|
||||
cache: false,
|
||||
installRecords: {
|
||||
zalouser: {
|
||||
source: "npm",
|
||||
installPath: globalDir,
|
||||
},
|
||||
},
|
||||
candidates: [
|
||||
createPluginCandidate({
|
||||
idHint: "zalouser",
|
||||
rootDir: globalDir,
|
||||
origin: "global",
|
||||
}),
|
||||
createPluginCandidate({
|
||||
idHint: "zalouser",
|
||||
rootDir: bundledDir,
|
||||
origin: "bundled",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
expect(countDuplicateWarnings(registry)).toBe(0);
|
||||
expect(registry.plugins).toHaveLength(1);
|
||||
expect(registry.plugins[0]?.origin).toBe("global");
|
||||
});
|
||||
|
||||
@@ -558,6 +558,34 @@ function resolveDuplicatePrecedenceRank(params: {
|
||||
return 4;
|
||||
}
|
||||
|
||||
function isIntentionalInstalledBundledDuplicate(params: {
|
||||
pluginId: string;
|
||||
left: PluginCandidate;
|
||||
right: PluginCandidate;
|
||||
config?: OpenClawConfig;
|
||||
env: NodeJS.ProcessEnv;
|
||||
installRecords: Record<string, PluginInstallRecord>;
|
||||
}): boolean {
|
||||
const leftIsInstalled = matchesInstalledPluginRecord({
|
||||
pluginId: params.pluginId,
|
||||
candidate: params.left,
|
||||
config: params.config,
|
||||
env: params.env,
|
||||
installRecords: params.installRecords,
|
||||
});
|
||||
const rightIsInstalled = matchesInstalledPluginRecord({
|
||||
pluginId: params.pluginId,
|
||||
candidate: params.right,
|
||||
config: params.config,
|
||||
env: params.env,
|
||||
installRecords: params.installRecords,
|
||||
});
|
||||
return (
|
||||
(leftIsInstalled && params.right.origin === "bundled") ||
|
||||
(rightIsInstalled && params.left.origin === "bundled")
|
||||
);
|
||||
}
|
||||
|
||||
export function loadPluginManifestRegistry(
|
||||
params: {
|
||||
config?: OpenClawConfig;
|
||||
@@ -740,6 +768,18 @@ export function loadPluginManifestRegistry(
|
||||
seenIds.set(manifest.id, { candidate, recordIndex: existing.recordIndex });
|
||||
pushManifestCompatibilityDiagnostics({ record, diagnostics });
|
||||
}
|
||||
if (
|
||||
isIntentionalInstalledBundledDuplicate({
|
||||
pluginId: manifest.id,
|
||||
left: candidate,
|
||||
right: existing.candidate,
|
||||
config,
|
||||
env,
|
||||
installRecords: getInstallRecords(),
|
||||
})
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
diagnostics.push({
|
||||
level: "warn",
|
||||
pluginId: manifest.id,
|
||||
|
||||
Reference in New Issue
Block a user