





















@@ -1,4 +1,5 @@
11import fs from "node:fs";
2+import { normalizeProviderId } from "../../../agents/provider-id.js";
23import type { OpenClawConfig } from "../../../config/types.openclaw.js";
34import {
45loadPluginInstallRecords,
@@ -13,9 +14,9 @@ import {
1314type InstalledPluginIndexStoreOptions,
1415} from "../../../plugins/installed-plugin-index-store.js";
1516import {
16-listEnabledInstalledPluginRecords,
1717loadInstalledPluginIndex,
1818type InstalledPluginIndex,
19+type InstalledPluginIndexRecord,
1920type LoadInstalledPluginIndexParams,
2021} from "../../../plugins/installed-plugin-index.js";
2122@@ -111,6 +112,134 @@ async function readMigrationConfig(
111112return await configModule.readBestEffortConfig();
112113}
113114115+function normalizeRegistryReference(value: unknown): string | undefined {
116+if (typeof value !== "string") {
117+return undefined;
118+}
119+const trimmed = value.trim();
120+return trimmed ? trimmed.toLowerCase() : undefined;
121+}
122+123+function createMigrationPluginIdNormalizer(
124+index: InstalledPluginIndex,
125+): (pluginId: string) => string {
126+const aliases = new Map<string, string>();
127+for (const plugin of index.plugins) {
128+const pluginId = normalizeRegistryReference(plugin.pluginId);
129+if (!pluginId) {
130+continue;
131+}
132+aliases.set(pluginId, plugin.pluginId);
133+for (const alias of [
134+ ...plugin.contributions.providers,
135+ ...plugin.contributions.channels,
136+ ...plugin.contributions.setupProviders,
137+ ...plugin.contributions.cliBackends,
138+ ...plugin.contributions.modelCatalogProviders,
139+]) {
140+const normalizedAlias = normalizeRegistryReference(alias);
141+if (normalizedAlias && !aliases.has(normalizedAlias)) {
142+aliases.set(normalizedAlias, plugin.pluginId);
143+}
144+}
145+}
146+return (pluginId: string) => {
147+const normalized = normalizeRegistryReference(pluginId);
148+return normalized ? (aliases.get(normalized) ?? pluginId.trim()) : pluginId.trim();
149+};
150+}
151+152+function addPluginReference(
153+references: Set<string>,
154+normalizePluginId: (pluginId: string) => string,
155+value: unknown,
156+): void {
157+if (typeof value !== "string") {
158+return;
159+}
160+const normalized = normalizePluginId(value);
161+if (normalized) {
162+references.add(normalized);
163+}
164+}
165+166+function listConfiguredChannelIds(config: OpenClawConfig): Set<string> {
167+const channels = config.channels;
168+if (!channels || typeof channels !== "object" || Array.isArray(channels)) {
169+return new Set();
170+}
171+return new Set(
172+Object.keys(channels)
173+.map((channelId) => normalizeRegistryReference(channelId))
174+.filter((channelId): channelId is string => Boolean(channelId)),
175+);
176+}
177+178+function listConfiguredModelProviderIds(config: OpenClawConfig): Set<string> {
179+const providers = config.models?.providers;
180+if (!providers || typeof providers !== "object" || Array.isArray(providers)) {
181+return new Set();
182+}
183+return new Set(
184+Object.keys(providers)
185+.map((providerId) => normalizeProviderId(providerId))
186+.filter(Boolean),
187+);
188+}
189+190+export function listMigrationRelevantPluginRecords(params: {
191+index: InstalledPluginIndex;
192+config: OpenClawConfig;
193+installRecords: Record<string, unknown>;
194+}): readonly InstalledPluginIndexRecord[] {
195+const normalizePluginId = createMigrationPluginIdNormalizer(params.index);
196+const referencedPluginIds = new Set<string>();
197+const installedPluginIds = new Set<string>();
198+199+for (const pluginId of Object.keys(params.installRecords)) {
200+addPluginReference(installedPluginIds, normalizePluginId, pluginId);
201+}
202+203+const plugins = params.config.plugins;
204+for (const pluginId of plugins?.allow ?? []) {
205+addPluginReference(referencedPluginIds, normalizePluginId, pluginId);
206+}
207+for (const pluginId of plugins?.deny ?? []) {
208+addPluginReference(referencedPluginIds, normalizePluginId, pluginId);
209+}
210+for (const pluginId of Object.keys(plugins?.entries ?? {})) {
211+addPluginReference(referencedPluginIds, normalizePluginId, pluginId);
212+}
213+for (const pluginId of Object.values(plugins?.slots ?? {})) {
214+if (normalizeRegistryReference(pluginId) === "none") {
215+continue;
216+}
217+addPluginReference(referencedPluginIds, normalizePluginId, pluginId);
218+}
219+220+const configuredChannelIds = listConfiguredChannelIds(params.config);
221+const configuredModelProviderIds = listConfiguredModelProviderIds(params.config);
222+223+return params.index.plugins.filter((plugin) => {
224+if (plugin.origin !== "bundled") {
225+return true;
226+}
227+if (installedPluginIds.has(plugin.pluginId) || referencedPluginIds.has(plugin.pluginId)) {
228+return true;
229+}
230+if (
231+plugin.contributions.channels.some((channelId) =>
232+configuredChannelIds.has(normalizeRegistryReference(channelId) ?? ""),
233+)
234+) {
235+return true;
236+}
237+return plugin.contributions.providers.some((providerId) =>
238+configuredModelProviderIds.has(normalizeProviderId(providerId)),
239+);
240+});
241+}
242+114243export async function migratePluginRegistryForInstall(
115244params: PluginRegistryInstallMigrationParams = {},
116245): Promise<PluginRegistryInstallMigrationResult> {
@@ -139,7 +268,11 @@ export async function migratePluginRegistryForInstall(
139268const current: InstalledPluginIndex = {
140269 ...candidateIndex,
141270refreshReason: "migration",
142-plugins: listEnabledInstalledPluginRecords(candidateIndex, config),
271+plugins: listMigrationRelevantPluginRecords({
272+index: candidateIndex,
273+ config,
274+ installRecords,
275+}),
143276};
144277if (Object.keys(installRecords).length > 0) {
145278await writePersistedPluginInstallLedger(installRecords, params);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。