
















@@ -1,6 +1,7 @@
11import { replaceConfigFile } from "../config/config.js";
22import type { OpenClawConfig } from "../config/types.openclaw.js";
33import { type HookInstallUpdate, recordHookInstall } from "../hooks/installs.js";
4+import { isPathInside } from "../infra/path-guards.js";
45import { enablePluginInConfig } from "../plugins/enable.js";
56import {
67loadInstalledPluginIndexInstallRecords,
@@ -12,7 +13,7 @@ import { tracePluginLifecyclePhaseAsync } from "../plugins/plugin-lifecycle-trac
1213import { buildPluginSnapshotReport } from "../plugins/status.js";
1314import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
1415import { theme } from "../terminal/theme.js";
15-import { shortenHomePath } from "../utils.js";
16+import { resolveUserPath, shortenHomePath } from "../utils.js";
1617import {
1718applySlotSelectionForPlugin,
1819enableInternalHookEntries,
@@ -60,6 +61,16 @@ export type ConfigSnapshotForInstallPersist = {
6061baseHash: string | undefined;
6162};
626364+function sourceMatchesInstalledPath(params: {
65+activeSource: string;
66+installedSource: string;
67+env?: NodeJS.ProcessEnv;
68+}): boolean {
69+const activeSource = resolveUserPath(params.activeSource, params.env);
70+const installedSource = resolveUserPath(params.installedSource, params.env);
71+return activeSource === installedSource || isPathInside(installedSource, activeSource);
72+}
73+6374function logShadowedNpmInstallWarning(params: {
6475config: OpenClawConfig;
6576pluginId: string;
@@ -79,7 +90,11 @@ function logShadowedNpmInstallWarning(params: {
7990onlyPluginIds: [params.pluginId],
8091});
8192const active = report.plugins.find((plugin) => plugin.id === params.pluginId);
82-if (!active || active.origin !== "config" || active.source === installedSource) {
93+if (
94+!active ||
95+active.origin !== "config" ||
96+sourceMatchesInstalledPath({ activeSource: active.source, installedSource })
97+) {
8398return;
8499}
85100此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。