diff --git a/CHANGELOG.md b/CHANGELOG.md index 07e3f775f26..9387f5a94ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Docs: https://docs.openclaw.ai - Plugins/startup: normalize startup and provider plugin enablement through registry aliases so boot paths do not need the legacy manifest alias scan. Thanks @vincentkoc. - Providers/plugins: resolve provider ownership, provider discovery scopes, and catalog-hook provider ids from the cold plugin registry instead of rescanning manifests on those paths. Thanks @vincentkoc. - Plugins/registry: keep installed plugin index records focused on install/state/load paths and resolve plugin capabilities from manifests scoped to indexed plugins. Thanks @shakkernerd. +- Plugins/registry: route cold manifest and capability lookups through the installed plugin index so setup, channels, config, secrets, doctor, and provider metadata paths avoid broad plugin-root scans before runtime execution. Thanks @shakkernerd. - Plugins/chat commands: refresh the persisted plugin registry after `/plugins enable` and `/plugins disable`, matching the CLI mutation path. Thanks @vincentkoc. - Plugins/compat: mark `OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY` as a deprecated break-glass switch and point operators at registry repair instead. Thanks @vincentkoc. - Plugins/registry: ignore stale persisted registry reads when plugin policy no longer matches current config, and stamp generated registry files with a do-not-edit warning. Thanks @vincentkoc. diff --git a/src/agents/model-auth-markers.ts b/src/agents/model-auth-markers.ts index 63a65970379..3b89f084efe 100644 --- a/src/agents/model-auth-markers.ts +++ b/src/agents/model-auth-markers.ts @@ -1,6 +1,5 @@ import type { SecretRefSource } from "../config/types.secrets.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js"; -import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { listKnownProviderEnvApiKeyNames } from "./model-auth-env-vars.js"; export const MINIMAX_OAUTH_MARKER = "minimax-oauth"; @@ -45,20 +44,14 @@ function listKnownEnvApiKeyMarkers(): Set { } export function listKnownNonSecretApiKeyMarkers(): string[] { - knownNonSecretApiKeyMarkersCache ??= (() => { - const index = loadPluginRegistrySnapshot({}); - return [ - ...new Set([ - ...CORE_NON_SECRET_API_KEY_MARKERS, - ...loadPluginManifestRegistryForInstalledIndex({ - index, - includeDisabled: true, - }).plugins.flatMap((plugin) => - plugin.origin === "bundled" ? (plugin.nonSecretAuthMarkers ?? []) : [], - ), - ]), - ]; - })(); + knownNonSecretApiKeyMarkersCache ??= [ + ...new Set([ + ...CORE_NON_SECRET_API_KEY_MARKERS, + ...loadPluginManifestRegistryForPluginRegistry({ includeDisabled: true }).plugins.flatMap( + (plugin) => (plugin.origin === "bundled" ? (plugin.nonSecretAuthMarkers ?? []) : []), + ), + ]), + ]; return [...knownNonSecretApiKeyMarkersCache]; } diff --git a/src/agents/pi-project-settings-snapshot.ts b/src/agents/pi-project-settings-snapshot.ts index 8487d7212e8..fa0046a1695 100644 --- a/src/agents/pi-project-settings-snapshot.ts +++ b/src/agents/pi-project-settings-snapshot.ts @@ -10,9 +10,8 @@ import { normalizePluginsConfigWithResolver, resolveEffectivePluginActivationState, } from "../plugins/config-policy.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js"; import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { isRecord } from "../utils.js"; import { loadEmbeddedPiMcpConfig } from "./embedded-pi-mcp.js"; @@ -105,12 +104,7 @@ export function loadEnabledBundlePiSettingsSnapshot(params: { if (!workspaceDir) { return {}; } - const index = loadPluginRegistrySnapshot({ - workspaceDir, - config: params.cfg, - }); - const registry = loadPluginManifestRegistryForInstalledIndex({ - index, + const registry = loadPluginManifestRegistryForPluginRegistry({ workspaceDir, config: params.cfg, includeDisabled: true, diff --git a/src/agents/pi-project-settings.bundle.test.ts b/src/agents/pi-project-settings.bundle.test.ts index a2198b6405e..9dc7a919f70 100644 --- a/src/agents/pi-project-settings.bundle.test.ts +++ b/src/agents/pi-project-settings.bundle.test.ts @@ -45,9 +45,39 @@ vi.mock("../plugins/manifest-registry-installed.js", async () => { }; }); -vi.mock("../plugins/plugin-registry.js", () => ({ - loadPluginRegistrySnapshot: () => ({ plugins: [] }), -})); +vi.mock("../plugins/plugin-registry.js", async () => { + const fs = await import("node:fs"); + const path = await import("node:path"); + const loadRegistry = (params: { workspaceDir?: string }) => { + const rootDir = path.join( + params.workspaceDir ?? "", + ".openclaw", + "extensions", + "claude-bundle", + ); + if (!fs.existsSync(path.join(rootDir, ".claude-plugin", "plugin.json"))) { + return { plugins: [], diagnostics: [] }; + } + const resolvedRootDir = fs.realpathSync(rootDir); + return { + diagnostics: [], + plugins: [ + { + id: "claude-bundle", + origin: "workspace", + format: "bundle", + bundleFormat: "claude", + settingsFiles: ["settings.json"], + rootDir: resolvedRootDir, + }, + ], + }; + }; + return { + loadPluginManifestRegistryForPluginRegistry: loadRegistry, + loadPluginRegistrySnapshot: () => ({ plugins: [] }), + }; +}); vi.mock("./embedded-pi-mcp.js", async () => { const fs = await import("node:fs"); diff --git a/src/agents/provider-attribution.ts b/src/agents/provider-attribution.ts index 00968a8f8b4..22d6e7ea829 100644 --- a/src/agents/provider-attribution.ts +++ b/src/agents/provider-attribution.ts @@ -1,5 +1,4 @@ -import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js"; -import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { normalizeOptionalLowercaseString, normalizeOptionalString, @@ -209,11 +208,7 @@ function isManifestProviderEndpointClass(value: string): value is ProviderEndpoi function loadManifestProviderEndpointCache(): ManifestProviderEndpointCacheEntry[] { if (!manifestProviderEndpointCache) { - const index = loadPluginRegistrySnapshot({ cache: true }); - const registry = loadPluginManifestRegistryForInstalledIndex({ - index, - includeDisabled: true, - }); + const registry = loadPluginManifestRegistryForPluginRegistry({ includeDisabled: true }); const entries: ManifestProviderEndpointCacheEntry[] = []; for (const plugin of registry.plugins) { for (const endpoint of plugin.providerEndpoints ?? []) { diff --git a/src/agents/provider-auth-aliases.test.ts b/src/agents/provider-auth-aliases.test.ts index 0fbb2e7b06c..f4296bb1386 100644 --- a/src/agents/provider-auth-aliases.test.ts +++ b/src/agents/provider-auth-aliases.test.ts @@ -1,9 +1,13 @@ import { describe, expect, it, vi } from "vitest"; -const pluginRegistryMocks = vi.hoisted(() => ({ - loadPluginManifestRegistryForInstalledIndex: vi.fn(), - loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), -})); +const pluginRegistryMocks = vi.hoisted(() => { + const loadManifestRegistry = vi.fn(); + return { + loadPluginManifestRegistryForInstalledIndex: loadManifestRegistry, + loadPluginManifestRegistryForPluginRegistry: loadManifestRegistry, + loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), + }; +}); vi.mock("../plugins/manifest-registry-installed.js", () => ({ loadPluginManifestRegistryForInstalledIndex: @@ -11,6 +15,8 @@ vi.mock("../plugins/manifest-registry-installed.js", () => ({ })); vi.mock("../plugins/plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: + pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry, loadPluginRegistrySnapshot: pluginRegistryMocks.loadPluginRegistrySnapshot, })); diff --git a/src/agents/provider-auth-aliases.ts b/src/agents/provider-auth-aliases.ts index bf791cedf1c..8b8b45881ab 100644 --- a/src/agents/provider-auth-aliases.ts +++ b/src/agents/provider-auth-aliases.ts @@ -1,12 +1,11 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js"; import type { PluginManifestRecord } from "../plugins/manifest-registry.js"; import { isWorkspacePluginAllowedByConfig, normalizePluginConfigId, } from "../plugins/plugin-config-trust.js"; import type { PluginOrigin } from "../plugins/plugin-origin.types.js"; -import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { normalizeProviderId } from "./provider-id.js"; export type ProviderAuthAliasLookupParams = { @@ -84,13 +83,7 @@ function setPreferredAlias(params: { export function resolveProviderAuthAliasMap( params?: ProviderAuthAliasLookupParams, ): Record { - const index = loadPluginRegistrySnapshot({ - config: params?.config, - workspaceDir: params?.workspaceDir, - env: params?.env, - }); - const registry = loadPluginManifestRegistryForInstalledIndex({ - index, + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params?.config, workspaceDir: params?.workspaceDir, env: params?.env, diff --git a/src/agents/skills/plugin-skills.test.ts b/src/agents/skills/plugin-skills.test.ts index f4e0c84813f..0fdd1757fed 100644 --- a/src/agents/skills/plugin-skills.test.ts +++ b/src/agents/skills/plugin-skills.test.ts @@ -5,16 +5,21 @@ import type { OpenClawConfig } from "../../config/config.js"; import type { PluginManifestRegistry } from "../../plugins/manifest-registry.js"; import { createTrackedTempDirs } from "../../test-utils/tracked-temp-dirs.js"; -const hoisted = vi.hoisted(() => ({ - loadPluginManifestRegistryForInstalledIndex: vi.fn(), - loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), -})); +const hoisted = vi.hoisted(() => { + const loadManifestRegistry = vi.fn(); + return { + loadPluginManifestRegistryForInstalledIndex: loadManifestRegistry, + loadPluginManifestRegistryForPluginRegistry: loadManifestRegistry, + loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), + }; +}); vi.mock("../../plugins/manifest-registry-installed.js", () => ({ loadPluginManifestRegistryForInstalledIndex: hoisted.loadPluginManifestRegistryForInstalledIndex, })); vi.mock("../../plugins/plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: hoisted.loadPluginManifestRegistryForPluginRegistry, loadPluginRegistrySnapshot: hoisted.loadPluginRegistrySnapshot, })); diff --git a/src/agents/skills/plugin-skills.ts b/src/agents/skills/plugin-skills.ts index 20d71245293..68cae6d570e 100644 --- a/src/agents/skills/plugin-skills.ts +++ b/src/agents/skills/plugin-skills.ts @@ -7,9 +7,8 @@ import { resolveEffectivePluginActivationState, resolveMemorySlotDecision, } from "../../plugins/config-policy.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "../../plugins/manifest-registry-installed.js"; import type { PluginManifestRegistry } from "../../plugins/manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "../../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../../plugins/plugin-registry.js"; import { hasKind } from "../../plugins/slots.js"; import { isPathInsideWithRealpath } from "../../security/scan-paths.js"; @@ -50,12 +49,7 @@ export function resolvePluginSkillDirs(params: { if (!workspaceDir) { return []; } - const index = loadPluginRegistrySnapshot({ - workspaceDir, - config: params.config, - }); - const registry = loadPluginManifestRegistryForInstalledIndex({ - index, + const registry = loadPluginManifestRegistryForPluginRegistry({ workspaceDir, config: params.config, includeDisabled: true, diff --git a/src/channels/plugins/read-only.ts b/src/channels/plugins/read-only.ts index e2b0c58057d..4cfc5e47c37 100644 --- a/src/channels/plugins/read-only.ts +++ b/src/channels/plugins/read-only.ts @@ -7,9 +7,8 @@ import { resolveDiscoverableScopedChannelPluginIds, } from "../../plugins/channel-plugin-ids.js"; import { loadOpenClawPlugins } from "../../plugins/loader.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "../../plugins/manifest-registry-installed.js"; import type { PluginManifestRecord } from "../../plugins/manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "../../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../../plugins/plugin-registry.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; import { sanitizeForLog } from "../../terminal/ansi.js"; import { getBundledChannelSetupPlugin } from "./bundled.js"; @@ -521,17 +520,11 @@ export function resolveReadOnlyChannelPluginsForConfig( ): ReadOnlyChannelPluginResolution { const env = options.env ?? process.env; const workspaceDir = resolveReadOnlyWorkspaceDir(cfg, options); - const pluginIndex = loadPluginRegistrySnapshot({ + const manifestRecords = loadPluginManifestRegistryForPluginRegistry({ config: cfg, workspaceDir, env, cache: options.cache, - }); - const manifestRecords = loadPluginManifestRegistryForInstalledIndex({ - index: pluginIndex, - config: cfg, - workspaceDir, - env, includeDisabled: true, }).plugins; const externalManifestRecords = listExternalChannelManifestRecords(manifestRecords); diff --git a/src/commands/doctor/shared/channel-plugin-blockers.ts b/src/commands/doctor/shared/channel-plugin-blockers.ts index 0facd1e0d56..e046837a45f 100644 --- a/src/commands/doctor/shared/channel-plugin-blockers.ts +++ b/src/commands/doctor/shared/channel-plugin-blockers.ts @@ -4,7 +4,7 @@ import { normalizePluginsConfig, resolveEffectivePluginActivationState, } from "../../../plugins/config-state.js"; -import { loadPluginManifestRegistry } from "../../../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../../../plugins/plugin-registry.js"; import { sanitizeForLog } from "../../../terminal/ansi.js"; export type ChannelPluginBlockerHit = { @@ -45,9 +45,10 @@ export function scanConfiguredChannelPluginBlockers( } const pluginsConfig = normalizePluginsConfig(cfg.plugins); - const registry = loadPluginManifestRegistry({ + const registry = loadPluginManifestRegistryForPluginRegistry({ config: cfg, env, + includeDisabled: true, }); const hits: ChannelPluginBlockerHit[] = []; diff --git a/src/commands/doctor/shared/stale-plugin-config.ts b/src/commands/doctor/shared/stale-plugin-config.ts index 360dbf0300b..23da42aaaf6 100644 --- a/src/commands/doctor/shared/stale-plugin-config.ts +++ b/src/commands/doctor/shared/stale-plugin-config.ts @@ -1,7 +1,7 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../../agents/agent-scope.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { normalizePluginId } from "../../../plugins/config-state.js"; -import { loadPluginManifestRegistry } from "../../../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../../../plugins/plugin-registry.js"; import { sanitizeForLog } from "../../../terminal/ansi.js"; import { asObjectRecord } from "./object.js"; @@ -23,10 +23,11 @@ function collectPluginRegistryState( env?: NodeJS.ProcessEnv, ): StalePluginRegistryState { const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg)); - const registry = loadPluginManifestRegistry({ + const registry = loadPluginManifestRegistryForPluginRegistry({ config: cfg, workspaceDir: workspaceDir ?? undefined, env, + includeDisabled: true, }); return { knownIds: new Set(registry.plugins.map((plugin) => plugin.id)), diff --git a/src/config/plugin-auto-enable.shared.ts b/src/config/plugin-auto-enable.shared.ts index c24d593bfb9..bc1a0cf338f 100644 --- a/src/config/plugin-auto-enable.shared.ts +++ b/src/config/plugin-auto-enable.shared.ts @@ -6,11 +6,10 @@ import { } from "../channels/config-presence.js"; import { getChatChannelMeta, normalizeChatChannelId } from "../channels/registry.js"; import { - loadPluginManifestRegistry, - resolveManifestContractOwnerPluginId, type PluginManifestRecord, type PluginManifestRegistry, } from "../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { resolveOwningPluginIdsForModelRef } from "../plugins/providers.js"; import { resolvePluginSetupAutoEnableReasons } from "../plugins/setup-registry.js"; import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; @@ -211,12 +210,20 @@ function resolvePluginIdForConfiguredWebFetchProvider( providerId: string | undefined, env: NodeJS.ProcessEnv, ): string | undefined { - return resolveManifestContractOwnerPluginId({ - contract: "webFetchProviders", - value: normalizeOptionalLowercaseString(providerId) ?? "", - origin: "bundled", + const normalizedProviderId = normalizeOptionalLowercaseString(providerId); + if (!normalizedProviderId) { + return undefined; + } + return loadPluginManifestRegistryForPluginRegistry({ env, - }); + includeDisabled: true, + }).plugins.find( + (plugin) => + plugin.origin === "bundled" && + (plugin.contracts?.webFetchProviders ?? []).some( + (candidate) => normalizeOptionalLowercaseString(candidate) === normalizedProviderId, + ), + )?.id; } function normalizeManifestChannelId(channelId: string): string { @@ -785,7 +792,11 @@ export function resolvePluginAutoEnableManifestRegistry(params: { return ( params.manifestRegistry ?? (configMayNeedPluginManifestRegistry(params.config, params.env) - ? loadPluginManifestRegistry({ config: params.config, env: params.env }) + ? loadPluginManifestRegistryForPluginRegistry({ + config: params.config, + env: params.env, + includeDisabled: true, + }) : EMPTY_PLUGIN_MANIFEST_REGISTRY) ); } diff --git a/src/config/runtime-schema.ts b/src/config/runtime-schema.ts index 50e5c46d6cb..b32313fe2b7 100644 --- a/src/config/runtime-schema.ts +++ b/src/config/runtime-schema.ts @@ -1,5 +1,5 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; -import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { collectChannelSchemaMetadata, collectPluginSchemaMetadata, @@ -10,11 +10,12 @@ import { buildConfigSchema, type ConfigSchemaResponse } from "./schema.js"; function loadManifestRegistry(config: OpenClawConfig, env?: NodeJS.ProcessEnv) { const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config)); - return loadPluginManifestRegistry({ + return loadPluginManifestRegistryForPluginRegistry({ config, cache: false, env, workspaceDir, + includeDisabled: true, }); } diff --git a/src/config/validation.ts b/src/config/validation.ts index 89ae9eea326..caa3ef4369e 100644 --- a/src/config/validation.ts +++ b/src/config/validation.ts @@ -13,10 +13,8 @@ import { listPluginDoctorLegacyConfigRules, } from "../plugins/doctor-contract-registry.js"; import { resolveManifestCommandAliasOwner } from "../plugins/manifest-command-aliases.runtime.js"; -import { - loadPluginManifestRegistry, - resolveManifestContractPluginIds, -} from "../plugins/manifest-registry.js"; +import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { validateJsonSchemaValue } from "../plugins/schema-validator.js"; import { hasKind } from "../plugins/slots.js"; import { collectLegacySecretRefEnvMarkerCandidates } from "../secrets/legacy-secretref-env-marker.js"; @@ -760,7 +758,7 @@ function validateConfigObjectWithPluginsBase( }; type RegistryInfo = { - registry: ReturnType; + registry: PluginManifestRegistry; knownIds?: Set; overriddenPluginIds?: Set; normalizedPlugins?: ReturnType; @@ -788,24 +786,27 @@ function validateConfigObjectWithPluginsBase( return compatPluginIds; } const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config)); + const registry = loadPluginManifestRegistryForPluginRegistry({ + config, + workspaceDir: workspaceDir ?? undefined, + env: opts.env, + includeDisabled: true, + }); const overriddenBundledPluginIds = new Set( - loadPluginManifestRegistry({ - config, - workspaceDir: workspaceDir ?? undefined, - env: opts.env, - }) - .diagnostics.filter((diag) => diag.message.includes("duplicate plugin id detected")) + registry.diagnostics + .filter((diag) => diag.message.includes("duplicate plugin id detected")) .map((diag) => diag.pluginId) .filter((pluginId): pluginId is string => typeof pluginId === "string" && pluginId !== ""), ); compatPluginIds = new Set( - resolveManifestContractPluginIds({ - contract: "webSearchProviders", - origin: "bundled", - config, - workspaceDir: workspaceDir ?? undefined, - env: opts.env, - }).filter((pluginId) => !overriddenBundledPluginIds.has(pluginId)), + registry.plugins + .filter( + (plugin) => + plugin.origin === "bundled" && + (plugin.contracts?.webSearchProviders?.length ?? 0) > 0 && + !overriddenBundledPluginIds.has(plugin.id), + ) + .map((plugin) => plugin.id), ); return compatPluginIds; }; @@ -838,10 +839,11 @@ function validateConfigObjectWithPluginsBase( effectiveConfig, resolveDefaultAgentId(effectiveConfig), ); - const registry = loadPluginManifestRegistry({ + const registry = loadPluginManifestRegistryForPluginRegistry({ config: effectiveConfig, workspaceDir: workspaceDir ?? undefined, env: opts.env, + includeDisabled: true, }); for (const diag of registry.diagnostics) { diff --git a/src/hooks/plugin-hooks.ts b/src/hooks/plugin-hooks.ts index fc689a92f3e..a7cdf2fce0f 100644 --- a/src/hooks/plugin-hooks.ts +++ b/src/hooks/plugin-hooks.ts @@ -7,7 +7,7 @@ import { resolveEffectivePluginActivationState, resolveMemorySlotDecision, } from "../plugins/config-state.js"; -import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { hasKind } from "../plugins/slots.js"; import { isPathInsideWithRealpath } from "../security/scan-paths.js"; @@ -26,11 +26,12 @@ export function resolvePluginHookDirs(params: { if (!workspaceDir) { return []; } - const registry = loadPluginManifestRegistry({ + const registry = loadPluginManifestRegistryForPluginRegistry({ workspaceDir, config: params.config, // Hook discovery should reflect freshly written bundle manifests immediately. cache: false, + includeDisabled: true, }); if (registry.plugins.length === 0) { return []; diff --git a/src/infra/provider-usage.auth.ts b/src/infra/provider-usage.auth.ts index 3d48d1435e2..f3c2a872487 100644 --- a/src/infra/provider-usage.auth.ts +++ b/src/infra/provider-usage.auth.ts @@ -17,10 +17,8 @@ import { isActivatedManifestOwner, passesManifestOwnerBasePolicy, } from "../plugins/manifest-owner-policy.js"; -import { - loadPluginManifestRegistry, - type PluginManifestRecord, -} from "../plugins/manifest-registry.js"; +import type { PluginManifestRecord } from "../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { resolveProviderUsageAuthWithPlugin } from "../plugins/provider-runtime.js"; import { resolveProviderAuthEnvVarCandidates } from "../secrets/provider-env-vars.js"; import { normalizeSecretInput } from "../utils/normalize-secret-input.js"; @@ -183,9 +181,10 @@ function resolveUsageCredentialProviderIds(params: { const providerIds = new Set(normalizeProviderIds([params.provider])); const providerIdSet = new Set(providerIds); try { - const registry = loadPluginManifestRegistry({ + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params.state.cfg, env: params.state.env, + includeDisabled: true, }); for (const plugin of registry.plugins) { const pluginProviderIds = normalizeProviderIds(plugin.providers); diff --git a/src/media-understanding/manifest-metadata.ts b/src/media-understanding/manifest-metadata.ts index a993679f945..0df3b4cb149 100644 --- a/src/media-understanding/manifest-metadata.ts +++ b/src/media-understanding/manifest-metadata.ts @@ -1,5 +1,5 @@ import type { OpenClawConfig } from "../config/types.js"; -import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { normalizeMediaProviderId } from "./provider-id.js"; import type { MediaUnderstandingProvider } from "./types.js"; @@ -7,9 +7,10 @@ export function buildMediaUnderstandingManifestMetadataRegistry( cfg?: OpenClawConfig, ): Map { const registry = new Map(); - for (const plugin of loadPluginManifestRegistry({ + for (const plugin of loadPluginManifestRegistryForPluginRegistry({ config: cfg, env: process.env, + includeDisabled: true, }).plugins) { const declaredProviders = new Set( (plugin.contracts?.mediaUnderstandingProviders ?? []).map((providerId) => diff --git a/src/plugins/activation-planner.test.ts b/src/plugins/activation-planner.test.ts index b5be07c4b5c..37356e966de 100644 --- a/src/plugins/activation-planner.test.ts +++ b/src/plugins/activation-planner.test.ts @@ -8,6 +8,11 @@ vi.mock("./manifest-registry.js", () => ({ loadPluginManifestRegistry: (...args: unknown[]) => mocks.loadPluginManifestRegistry(...args), })); +vi.mock("./plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: (...args: unknown[]) => + mocks.loadPluginManifestRegistry(...args), +})); + let resolveManifestActivationPluginIds: typeof import("./activation-planner.js").resolveManifestActivationPluginIds; let resolveManifestActivationPlan: typeof import("./activation-planner.js").resolveManifestActivationPlan; diff --git a/src/plugins/activation-planner.ts b/src/plugins/activation-planner.ts index 2407f07195a..0bca2fef70d 100644 --- a/src/plugins/activation-planner.ts +++ b/src/plugins/activation-planner.ts @@ -1,10 +1,11 @@ import { normalizeProviderId } from "../agents/provider-id.js"; import type { OpenClawConfig } from "../config/types.js"; import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { loadPluginManifestRegistry, type PluginManifestRecord } from "./manifest-registry.js"; +import type { PluginManifestRecord } from "./manifest-registry.js"; import type { PluginDiagnostic } from "./manifest-types.js"; import type { PluginManifestActivationCapability } from "./manifest.js"; import type { PluginOrigin } from "./plugin-origin.types.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import { createPluginIdScopeSet, normalizePluginIdScope } from "./plugin-scope.js"; export type PluginActivationPlannerTrigger = @@ -65,11 +66,12 @@ export function resolveManifestActivationPlan( const onlyPluginIdSet = createPluginIdScopeSet(normalizePluginIdScope(params.onlyPluginIds)); const registry = params.manifestRecords ? { plugins: params.manifestRecords, diagnostics: [] } - : loadPluginManifestRegistry({ + : loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, env: params.env, cache: params.cache, + includeDisabled: true, }); const entries = registry.plugins .flatMap((plugin) => { diff --git a/src/plugins/bundle-commands.ts b/src/plugins/bundle-commands.ts index a342f7934da..df879522fc5 100644 --- a/src/plugins/bundle-commands.ts +++ b/src/plugins/bundle-commands.ts @@ -18,7 +18,7 @@ import { normalizePluginsConfig, resolveEffectivePluginActivationState, } from "./config-state.js"; -import { loadPluginManifestRegistry } from "./manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; export type ClaudeBundleCommandSpec = { pluginId: string; @@ -176,10 +176,11 @@ export function loadEnabledClaudeBundleCommands(params: { if (!hasExplicitPluginConfig(params.cfg?.plugins)) { return []; } - const registry = loadPluginManifestRegistry({ + const registry = loadPluginManifestRegistryForPluginRegistry({ workspaceDir: params.workspaceDir, config: params.cfg, cache: false, + includeDisabled: true, }); const normalizedPlugins = normalizePluginsConfig(params.cfg?.plugins); const commands: ClaudeBundleCommandSpec[] = []; diff --git a/src/plugins/bundle-config-shared.ts b/src/plugins/bundle-config-shared.ts index 6cf34bfe9eb..73f1cf188ab 100644 --- a/src/plugins/bundle-config-shared.ts +++ b/src/plugins/bundle-config-shared.ts @@ -5,8 +5,8 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { matchBoundaryFileOpenFailure, openBoundaryFileSync } from "../infra/boundary-file-read.js"; import { isRecord } from "../utils.js"; import { normalizePluginsConfig, resolveEffectivePluginActivationState } from "./config-state.js"; -import { loadPluginManifestRegistry } from "./manifest-registry.js"; import type { PluginBundleFormat } from "./manifest-types.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; type ReadBundleJsonResult = | { ok: true; raw: Record } @@ -107,9 +107,10 @@ export function loadEnabledBundleConfig(params: { return { config: params.createEmptyConfig(), diagnostics: [] }; } - const registry = loadPluginManifestRegistry({ + const registry = loadPluginManifestRegistryForPluginRegistry({ workspaceDir: params.workspaceDir, config: params.cfg, + includeDisabled: true, }); const diagnostics: TDiagnostic[] = []; let merged = params.createEmptyConfig(); diff --git a/src/plugins/capability-provider-runtime.test.ts b/src/plugins/capability-provider-runtime.test.ts index a5d1dd21ba9..f3fba0859bd 100644 --- a/src/plugins/capability-provider-runtime.test.ts +++ b/src/plugins/capability-provider-runtime.test.ts @@ -15,10 +15,10 @@ const mocks = vi.hoisted(() => ({ resolveRuntimePluginRegistry: vi.fn< (params?: unknown) => ReturnType | undefined >(() => undefined), - loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), - loadPluginManifestRegistry: vi.fn<() => MockManifestRegistry>(() => - createEmptyMockManifestRegistry(), + loadPluginManifestRegistry: vi.fn<(params?: Record) => MockManifestRegistry>( + () => createEmptyMockManifestRegistry(), ), + loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), withBundledPluginAllowlistCompat: vi.fn( ({ config, pluginIds }: { config?: OpenClawConfig; pluginIds: string[] }) => ({ @@ -41,9 +41,21 @@ vi.mock("./manifest-registry-installed.js", () => ({ loadPluginManifestRegistryForInstalledIndex: mocks.loadPluginManifestRegistry, })); -vi.mock("./plugin-registry.js", () => ({ - loadPluginRegistrySnapshot: mocks.loadPluginRegistrySnapshot, -})); +vi.mock("./plugin-registry.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + loadPluginRegistrySnapshot: mocks.loadPluginRegistrySnapshot, + loadPluginManifestRegistryForPluginRegistry: ( + ...args: Parameters + ) => { + const [{ includeDisabled: _includeDisabled, ...params } = {}] = args as [ + Record?, + ]; + return mocks.loadPluginManifestRegistry(params); + }, + }; +}); vi.mock("./bundled-compat.js", () => ({ withBundledPluginAllowlistCompat: mocks.withBundledPluginAllowlistCompat, @@ -73,10 +85,8 @@ function expectBundledCompatLoadPath(params: { }; }) { expect(mocks.loadPluginManifestRegistry).toHaveBeenCalledWith({ - index: expect.anything(), config: params.cfg, env: process.env, - includeDisabled: true, }); expect(mocks.withBundledPluginEnablementCompat).toHaveBeenCalledWith({ config: params.allowlistCompat, diff --git a/src/plugins/capability-provider-runtime.ts b/src/plugins/capability-provider-runtime.ts index 78fc73d13d9..364cf444e0d 100644 --- a/src/plugins/capability-provider-runtime.ts +++ b/src/plugins/capability-provider-runtime.ts @@ -6,8 +6,7 @@ import { } from "./bundled-compat.js"; import { hasExplicitPluginConfig } from "./config-policy.js"; import { resolveRuntimePluginRegistry } from "./loader.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import type { PluginRegistry } from "./registry-types.js"; type CapabilityProviderRegistryKey = @@ -50,12 +49,7 @@ function resolveBundledCapabilityCompatPluginIds(params: { providerId?: string; }): string[] { const contractKey = CAPABILITY_CONTRACT_KEY[params.key]; - const index = loadPluginRegistrySnapshot({ - config: params.cfg, - env: process.env, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, + return loadPluginManifestRegistryForPluginRegistry({ config: params.cfg, env: process.env, includeDisabled: true, diff --git a/src/plugins/channel-presence-policy.ts b/src/plugins/channel-presence-policy.ts index 14b9ef499ec..868cabca0e1 100644 --- a/src/plugins/channel-presence-policy.ts +++ b/src/plugins/channel-presence-policy.ts @@ -19,9 +19,8 @@ import { isBundledManifestOwner, passesManifestOwnerBasePolicy, } from "./manifest-owner-policy.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; const IGNORED_CHANNEL_CONFIG_KEYS = new Set(["defaults", "modelByChannel"]); @@ -348,17 +347,11 @@ function loadInstalledChannelManifestRecords(params: { env: NodeJS.ProcessEnv; cache?: boolean; }): readonly PluginManifestRecord[] { - const index = loadPluginRegistrySnapshot({ + return loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, env: params.env, cache: params.cache, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, includeDisabled: true, }).plugins; } diff --git a/src/plugins/config-contracts.test.ts b/src/plugins/config-contracts.test.ts index aa7c3e361a9..74dec84bd6f 100644 --- a/src/plugins/config-contracts.test.ts +++ b/src/plugins/config-contracts.test.ts @@ -1,11 +1,15 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import type { PluginManifestRegistry } from "./manifest-registry.js"; -const mocks = vi.hoisted(() => ({ - findBundledPluginMetadataById: vi.fn(), - loadPluginManifestRegistryForInstalledIndex: vi.fn(), - loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), -})); +const mocks = vi.hoisted(() => { + const loadManifestRegistry = vi.fn(); + return { + findBundledPluginMetadataById: vi.fn(), + loadPluginManifestRegistryForInstalledIndex: loadManifestRegistry, + loadPluginManifestRegistryForPluginRegistry: loadManifestRegistry, + loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), + }; +}); vi.mock("./bundled-plugin-metadata.js", () => ({ findBundledPluginMetadataById: mocks.findBundledPluginMetadataById, @@ -16,6 +20,7 @@ vi.mock("./manifest-registry-installed.js", () => ({ })); vi.mock("./plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: mocks.loadPluginManifestRegistryForPluginRegistry, loadPluginRegistrySnapshot: mocks.loadPluginRegistrySnapshot, })); diff --git a/src/plugins/config-contracts.ts b/src/plugins/config-contracts.ts index 35d76ef8e62..96e49f11496 100644 --- a/src/plugins/config-contracts.ts +++ b/src/plugins/config-contracts.ts @@ -1,10 +1,9 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isRecord } from "../utils.js"; import { findBundledPluginMetadataById } from "./bundled-plugin-metadata.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestConfigContracts } from "./manifest.js"; import type { PluginOrigin } from "./plugin-origin.types.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; export type PluginConfigContractMatch = { path: string; @@ -115,17 +114,11 @@ export function resolvePluginConfigContractsById(params: { } const resolvedPluginIds = new Set(); - const index = loadPluginRegistrySnapshot({ + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, env: params.env, cache: params.cache, - }); - const registry = loadPluginManifestRegistryForInstalledIndex({ - index, - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, includeDisabled: true, }); for (const plugin of registry.plugins) { diff --git a/src/plugins/doctor-contract-registry.ts b/src/plugins/doctor-contract-registry.ts index 615890ac247..522bb5199a5 100644 --- a/src/plugins/doctor-contract-registry.ts +++ b/src/plugins/doctor-contract-registry.ts @@ -4,10 +4,10 @@ import { fileURLToPath } from "node:url"; import type { LegacyConfigRule } from "../config/legacy.shared.js"; import type { OpenClawConfig } from "../config/types.js"; import { asNullableRecord } from "../shared/record-coerce.js"; -import { discoverOpenClawPlugins } from "./discovery.js"; import { getCachedPluginJitiLoader, type PluginJitiLoaderCache } from "./jiti-loader-cache.js"; -import { loadPluginManifestRegistry } from "./manifest-registry.js"; +import type { PluginManifestRegistry } from "./manifest-registry.js"; import { tryNativeRequireJavaScriptModule } from "./native-module-require.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import { resolvePluginCacheInputs, type PluginSourceRoots } from "./roots.js"; const CONTRACT_API_EXTENSIONS = [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"] as const; @@ -36,9 +36,7 @@ type PluginDoctorContractEntry = { normalizeCompatibilityConfig?: PluginDoctorCompatibilityNormalizer; }; -type PluginManifestRegistryRecord = ReturnType< - typeof loadPluginManifestRegistry ->["plugins"][number]; +type PluginManifestRegistryRecord = PluginManifestRegistry["plugins"][number]; const jitiLoaders: PluginJitiLoaderCache = new Map(); const doctorContractCache = new Map(); @@ -285,17 +283,11 @@ function resolvePluginDoctorContracts(params?: { return []; } - const discovery = discoverOpenClawPlugins({ + const manifestRegistry = loadPluginManifestRegistryForPluginRegistry({ workspaceDir: params?.workspaceDir, env, cache: true, - }); - const manifestRegistry = loadPluginManifestRegistry({ - workspaceDir: params?.workspaceDir, - env, - cache: true, - candidates: discovery.candidates, - diagnostics: discovery.diagnostics, + includeDisabled: true, }); const entries: PluginDoctorContractEntry[] = []; diff --git a/src/plugins/document-extractors.runtime.ts b/src/plugins/document-extractors.runtime.ts index d9259b83310..fd56e3c1c8f 100644 --- a/src/plugins/document-extractors.runtime.ts +++ b/src/plugins/document-extractors.runtime.ts @@ -7,9 +7,8 @@ import { } from "./config-state.js"; import { loadBundledDocumentExtractorEntriesFromDir } from "./document-extractor-public-artifacts.js"; import type { PluginDocumentExtractorEntry } from "./document-extractor-types.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; function compareExtractors( left: PluginDocumentExtractorEntry, @@ -31,13 +30,7 @@ function resolveBundledDocumentExtractorCompatPluginIds(params: { }): string[] { const onlyPluginIdSet = params.onlyPluginIds && params.onlyPluginIds.length > 0 ? new Set(params.onlyPluginIds) : null; - const index = loadPluginRegistrySnapshot({ - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, + return loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, env: params.env, @@ -82,13 +75,7 @@ function resolveEnabledBundledDocumentExtractorPlugins(params: { }); const onlyPluginIdSet = params.onlyPluginIds && params.onlyPluginIds.length > 0 ? new Set(params.onlyPluginIds) : null; - const index = loadPluginRegistrySnapshot({ - config: activation.config, - workspaceDir: params.workspaceDir, - env: params.env, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, + return loadPluginManifestRegistryForPluginRegistry({ config: activation.config, workspaceDir: params.workspaceDir, env: params.env, diff --git a/src/plugins/manifest-command-aliases.runtime.ts b/src/plugins/manifest-command-aliases.runtime.ts index 23f975fb092..d881761a4e5 100644 --- a/src/plugins/manifest-command-aliases.runtime.ts +++ b/src/plugins/manifest-command-aliases.runtime.ts @@ -4,8 +4,7 @@ import { type PluginManifestCommandAliasRegistry, type PluginManifestCommandAliasRecord, } from "./manifest-command-aliases.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; export function resolveManifestCommandAliasOwner(params: { command: string | undefined; @@ -16,20 +15,12 @@ export function resolveManifestCommandAliasOwner(params: { }): PluginManifestCommandAliasRecord | undefined { const registry = params.registry ?? - (() => { - const index = loadPluginRegistrySnapshot({ - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, - includeDisabled: true, - }); - })(); + loadPluginManifestRegistryForPluginRegistry({ + config: params.config, + workspaceDir: params.workspaceDir, + env: params.env, + includeDisabled: true, + }); return resolveManifestCommandAliasOwnerInRegistry({ command: params.command, registry, diff --git a/src/plugins/plugin-registry.ts b/src/plugins/plugin-registry.ts index 592c4945f55..bd236b10cbd 100644 --- a/src/plugins/plugin-registry.ts +++ b/src/plugins/plugin-registry.ts @@ -5,7 +5,9 @@ import { type NormalizedPluginsConfig, } from "./config-normalization-shared.js"; import { + inspectPersistedInstalledPluginIndex, readPersistedInstalledPluginIndexSync, + refreshPersistedInstalledPluginIndex, type InstalledPluginIndexStoreInspection, type InstalledPluginIndexStoreOptions, } from "./installed-plugin-index-store.js"; @@ -61,6 +63,11 @@ export type PluginRegistryContributionOptions = LoadPluginRegistryParams & { includeDisabled?: boolean; }; +export type LoadPluginRegistryManifestParams = LoadPluginRegistryParams & { + includeDisabled?: boolean; + pluginIds?: readonly string[]; +}; + export type GetPluginRecordParams = LoadPluginRegistryParams & { pluginId: string; }; @@ -190,6 +197,20 @@ function loadContributionManifestRegistry( }); } +export function loadPluginManifestRegistryForPluginRegistry( + params: LoadPluginRegistryManifestParams = {}, +): PluginManifestRegistry { + const index = resolveSnapshot(params); + return loadPluginManifestRegistryForInstalledIndex({ + index, + config: params.config, + workspaceDir: params.workspaceDir, + env: params.env, + pluginIds: params.pluginIds, + includeDisabled: params.includeDisabled, + }); +} + export function createPluginRegistryIdNormalizer( index: PluginRegistrySnapshot, ): (pluginId: string) => string { @@ -422,15 +443,11 @@ export function resolveSetupProviderOwners( export function inspectPluginRegistry( params: LoadInstalledPluginIndexParams & InstalledPluginIndexStoreOptions = {}, ): Promise { - return import("./installed-plugin-index-store.js").then((store) => - store.inspectPersistedInstalledPluginIndex(params), - ); + return inspectPersistedInstalledPluginIndex(params); } export function refreshPluginRegistry( params: RefreshInstalledPluginIndexParams & InstalledPluginIndexStoreOptions, ): Promise { - return import("./installed-plugin-index-store.js").then((store) => - store.refreshPersistedInstalledPluginIndex(params), - ); + return refreshPersistedInstalledPluginIndex(params); } diff --git a/src/plugins/provider-auth-choices.test.ts b/src/plugins/provider-auth-choices.test.ts index aba142d1f07..b8d8827fe01 100644 --- a/src/plugins/provider-auth-choices.test.ts +++ b/src/plugins/provider-auth-choices.test.ts @@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; const pluginRegistryMocks = vi.hoisted(() => ({ loadPluginManifestRegistryForInstalledIndex: vi.fn(), + loadPluginManifestRegistryForPluginRegistry: vi.fn(), loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), })); @@ -11,6 +12,8 @@ vi.mock("./manifest-registry-installed.js", () => ({ })); vi.mock("./plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: + pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry, loadPluginRegistrySnapshot: pluginRegistryMocks.loadPluginRegistrySnapshot, })); @@ -37,6 +40,9 @@ function setManifestPlugins(plugins: Array>) { pluginRegistryMocks.loadPluginManifestRegistryForInstalledIndex.mockReturnValue({ plugins, }); + pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry.mockReturnValue({ + plugins, + }); } function expectResolvedProviderAuthChoices(params: { @@ -66,6 +72,10 @@ describe("provider auth choice manifest helpers", () => { pluginRegistryMocks.loadPluginManifestRegistryForInstalledIndex.mockReturnValue({ plugins: [], }); + pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry.mockReset(); + pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry.mockReturnValue({ + plugins: [], + }); pluginRegistryMocks.loadPluginRegistrySnapshot.mockReset(); pluginRegistryMocks.loadPluginRegistrySnapshot.mockReturnValue({ plugins: [] }); }); diff --git a/src/plugins/provider-auth-choices.ts b/src/plugins/provider-auth-choices.ts index 405aee62c2d..0a7055d9e37 100644 --- a/src/plugins/provider-auth-choices.ts +++ b/src/plugins/provider-auth-choices.ts @@ -2,10 +2,9 @@ import { resolveProviderIdForAuth } from "../agents/provider-auth-aliases.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { sanitizeForLog } from "../terminal/ansi.js"; import { normalizePluginsConfig, resolveEffectiveEnableState } from "./config-state.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; import type { PluginOrigin } from "./plugin-origin.types.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; export type ProviderAuthChoiceMetadata = { pluginId: string; @@ -181,13 +180,7 @@ function resolveManifestProviderAuthChoiceCandidates(params?: { env?: NodeJS.ProcessEnv; includeUntrustedWorkspacePlugins?: boolean; }): ProviderAuthChoiceCandidate[] { - const index = loadPluginRegistrySnapshot({ - config: params?.config, - workspaceDir: params?.workspaceDir, - env: params?.env, - }); - const registry = loadPluginManifestRegistryForInstalledIndex({ - index, + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params?.config, workspaceDir: params?.workspaceDir, env: params?.env, diff --git a/src/plugins/provider-discovery.runtime.ts b/src/plugins/provider-discovery.runtime.ts index 000a91c0e11..872255b33b7 100644 --- a/src/plugins/provider-discovery.runtime.ts +++ b/src/plugins/provider-discovery.runtime.ts @@ -1,5 +1,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { loadPluginManifestRegistry, type PluginManifestRecord } from "./manifest-registry.js"; +import type { PluginManifestRecord } from "./manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import { resolveDiscoveredProviderPluginIds } from "./providers.js"; import { resolvePluginProviders } from "./providers.runtime.js"; import { createPluginSourceLoader } from "./source-loader.js"; @@ -77,9 +78,11 @@ function resolveProviderDiscoveryEntryPlugins(params: { }): ProviderDiscoveryEntryResult { const pluginIds = resolveDiscoveredProviderPluginIds(params); const pluginIdSet = new Set(pluginIds); - const pluginRecords = loadPluginManifestRegistry(params).plugins.filter((plugin) => - pluginIdSet.has(plugin.id), - ); + const pluginRecords = loadPluginManifestRegistryForPluginRegistry({ + ...params, + pluginIds, + includeDisabled: true, + }).plugins.filter((plugin) => pluginIdSet.has(plugin.id)); const entryRecords = pluginRecords.filter((plugin) => plugin.providerDiscoverySource); const entryPluginIds = new Set(entryRecords.map((plugin) => plugin.id)); if (entryRecords.length === 0) { diff --git a/src/plugins/setup-registry.ts b/src/plugins/setup-registry.ts index 58b2d36610e..5158a4d19c3 100644 --- a/src/plugins/setup-registry.ts +++ b/src/plugins/setup-registry.ts @@ -6,9 +6,8 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { buildPluginApi } from "./api-builder.js"; import { collectPluginConfigContractMatches } from "./config-contracts.js"; import { getCachedPluginJitiLoader, type PluginJitiLoaderCache } from "./jiti-loader-cache.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import { resolvePluginCacheInputs } from "./roots.js"; import type { PluginRuntime } from "./runtime/types.js"; import { listSetupCliBackendIds, listSetupProviderIds } from "./setup-descriptors.js"; @@ -252,6 +251,7 @@ function resolveRelevantSetupMigrationPluginIds(params: { }): string[] { const ids = new Set(collectConfiguredPluginEntryIds(params.config)); const registry = loadSetupManifestRegistry({ + config: params.config, workspaceDir: params.workspaceDir, env: params.env, }); @@ -376,15 +376,14 @@ function matchesProvider(provider: ProviderPlugin, providerId: string): boolean ); } -function loadSetupManifestRegistry(params?: { workspaceDir?: string; env?: NodeJS.ProcessEnv }) { +function loadSetupManifestRegistry(params?: { + config?: OpenClawConfig; + workspaceDir?: string; + env?: NodeJS.ProcessEnv; +}) { const env = params?.env ?? process.env; - const index = loadPluginRegistrySnapshot({ - workspaceDir: params?.workspaceDir, - env, - cache: true, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, + return loadPluginManifestRegistryForPluginRegistry({ + config: params?.config, workspaceDir: params?.workspaceDir, env, includeDisabled: true, diff --git a/src/plugins/synthetic-auth.runtime.ts b/src/plugins/synthetic-auth.runtime.ts index f1265489cca..efed10f1de3 100644 --- a/src/plugins/synthetic-auth.runtime.ts +++ b/src/plugins/synthetic-auth.runtime.ts @@ -1,6 +1,5 @@ import { normalizeProviderId } from "../agents/provider-id.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import { getPluginRegistryState } from "./runtime-state.js"; function uniqueProviderRefs(values: readonly string[]): string[] { @@ -19,12 +18,10 @@ function uniqueProviderRefs(values: readonly string[]): string[] { } function resolveManifestSyntheticAuthProviderRefs(): string[] { - const index = loadPluginRegistrySnapshot({ cache: true }); return uniqueProviderRefs( - loadPluginManifestRegistryForInstalledIndex({ - index, - includeDisabled: true, - }).plugins.flatMap((plugin) => plugin.syntheticAuthRefs ?? []), + loadPluginManifestRegistryForPluginRegistry({ includeDisabled: true }).plugins.flatMap( + (plugin) => plugin.syntheticAuthRefs ?? [], + ), ); } diff --git a/src/plugins/test-helpers/registry-jiti-mocks.ts b/src/plugins/test-helpers/registry-jiti-mocks.ts index bdf9c89a318..7608460fe5e 100644 --- a/src/plugins/test-helpers/registry-jiti-mocks.ts +++ b/src/plugins/test-helpers/registry-jiti-mocks.ts @@ -30,12 +30,18 @@ vi.mock("../manifest-registry-installed.js", () => ({ ) => registryJitiMocks.loadPluginManifestRegistry(...args), })); -vi.mock("../plugin-registry.js", () => ({ - loadPluginRegistrySnapshot: ( - ...args: Parameters - ) => registryJitiMocks.loadPluginRegistrySnapshot(...args), -})); - +vi.mock("../plugin-registry.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + loadPluginRegistrySnapshot: ( + ...args: Parameters + ) => registryJitiMocks.loadPluginRegistrySnapshot(...args), + loadPluginManifestRegistryForPluginRegistry: ( + ...args: Parameters + ) => registryJitiMocks.loadPluginManifestRegistry(...args), + }; +}); export function resetRegistryJitiMocks(): void { registryJitiMocks.createJiti.mockReset(); registryJitiMocks.discoverOpenClawPlugins.mockReset(); diff --git a/src/plugins/web-content-extractors.runtime.ts b/src/plugins/web-content-extractors.runtime.ts index 1975792cad8..08c131ef15e 100644 --- a/src/plugins/web-content-extractors.runtime.ts +++ b/src/plugins/web-content-extractors.runtime.ts @@ -5,9 +5,8 @@ import { normalizePluginsConfig, resolveEffectivePluginActivationState, } from "./config-state.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import { loadBundledWebContentExtractorEntriesFromDir } from "./web-content-extractor-public-artifacts.js"; import type { PluginWebContentExtractorEntry } from "./web-content-extractor-types.js"; @@ -31,13 +30,7 @@ function resolveBundledWebContentExtractorCompatPluginIds(params: { }): string[] { const onlyPluginIdSet = params.onlyPluginIds && params.onlyPluginIds.length > 0 ? new Set(params.onlyPluginIds) : null; - const index = loadPluginRegistrySnapshot({ - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, + return loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, env: params.env, @@ -82,13 +75,7 @@ function resolveEnabledBundledExtractorPlugins(params: { }); const onlyPluginIdSet = params.onlyPluginIds && params.onlyPluginIds.length > 0 ? new Set(params.onlyPluginIds) : null; - const index = loadPluginRegistrySnapshot({ - config: activation.config, - workspaceDir: params.workspaceDir, - env: params.env, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, + return loadPluginManifestRegistryForPluginRegistry({ config: activation.config, workspaceDir: params.workspaceDir, env: params.env, diff --git a/src/plugins/web-provider-public-artifacts.ts b/src/plugins/web-provider-public-artifacts.ts index e0a2f1572fd..24db1f7fe1f 100644 --- a/src/plugins/web-provider-public-artifacts.ts +++ b/src/plugins/web-provider-public-artifacts.ts @@ -1,7 +1,6 @@ import path from "node:path"; import type { PluginLoadOptions } from "./loader.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import type { PluginWebFetchProviderEntry, PluginWebSearchProviderEntry } from "./types.js"; import { resolveBundledWebFetchResolutionConfig } from "./web-fetch-providers.shared.js"; import { @@ -57,14 +56,8 @@ function resolveBundledManifestRecordsByPluginId(params: { onlyPluginIds: readonly string[]; }) { const allowedPluginIds = new Set(params.onlyPluginIds); - const index = loadPluginRegistrySnapshot({ - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, - }); return new Map( - loadPluginManifestRegistryForInstalledIndex({ - index, + loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, env: params.env, diff --git a/src/plugins/web-provider-resolution-shared.ts b/src/plugins/web-provider-resolution-shared.ts index c8b0ad17b08..93eee1232f9 100644 --- a/src/plugins/web-provider-resolution-shared.ts +++ b/src/plugins/web-provider-resolution-shared.ts @@ -1,8 +1,7 @@ import { resolveBundledPluginCompatibleLoadValues } from "./activation-context.js"; import type { PluginLoadOptions } from "./loader.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import { createPluginIdScopeSet, normalizePluginIdScope, @@ -65,13 +64,7 @@ function loadInstalledWebProviderManifestRecords(params: { workspaceDir?: string; env?: PluginLoadOptions["env"]; }): readonly PluginManifestRecord[] { - const index = loadPluginRegistrySnapshot({ - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, + return loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, env: params.env, diff --git a/src/plugins/web-search-credential-presence.ts b/src/plugins/web-search-credential-presence.ts index 30de22f60dd..c5bbb0b3f25 100644 --- a/src/plugins/web-search-credential-presence.ts +++ b/src/plugins/web-search-credential-presence.ts @@ -1,7 +1,6 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js"; import { resolvePluginWebSearchProviders } from "./web-search-providers.runtime.js"; function hasConfiguredCredentialValue(value: unknown): boolean { @@ -44,12 +43,7 @@ function hasManifestWebSearchEnvCredentialCandidate(params: { if (!env) { return false; } - const index = loadPluginRegistrySnapshot({ - config: params.config, - env, - }); - return loadPluginManifestRegistryForInstalledIndex({ - index, + return loadPluginManifestRegistryForPluginRegistry({ config: params.config, env, includeDisabled: true, diff --git a/src/secrets/channel-env-vars.dynamic.test.ts b/src/secrets/channel-env-vars.dynamic.test.ts index 7ff4711d688..fdac309be96 100644 --- a/src/secrets/channel-env-vars.dynamic.test.ts +++ b/src/secrets/channel-env-vars.dynamic.test.ts @@ -9,13 +9,17 @@ type MockManifestRegistry = { diagnostics: unknown[]; }; -const pluginRegistryMocks = vi.hoisted(() => ({ - loadPluginManifestRegistryForInstalledIndex: vi.fn<() => MockManifestRegistry>(() => ({ +const pluginRegistryMocks = vi.hoisted(() => { + const loadManifestRegistry = vi.fn<() => MockManifestRegistry>(() => ({ plugins: [], diagnostics: [], - })), - loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), -})); + })); + return { + loadPluginManifestRegistryForInstalledIndex: loadManifestRegistry, + loadPluginManifestRegistryForPluginRegistry: loadManifestRegistry, + loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), + }; +}); vi.mock("../plugins/manifest-registry-installed.js", () => ({ loadPluginManifestRegistryForInstalledIndex: @@ -23,6 +27,8 @@ vi.mock("../plugins/manifest-registry-installed.js", () => ({ })); vi.mock("../plugins/plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: + pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry, loadPluginRegistrySnapshot: pluginRegistryMocks.loadPluginRegistrySnapshot, })); diff --git a/src/secrets/channel-env-vars.ts b/src/secrets/channel-env-vars.ts index b199990e031..59b8a8983b4 100644 --- a/src/secrets/channel-env-vars.ts +++ b/src/secrets/channel-env-vars.ts @@ -1,6 +1,5 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js"; -import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; export { isSafeChannelEnvVarTriggerName } from "./channel-env-var-names.js"; type ChannelEnvVarLookupParams = { @@ -33,13 +32,7 @@ function appendUniqueEnvVarCandidates( export function resolveChannelEnvVars( params?: ChannelEnvVarLookupParams, ): Record { - const index = loadPluginRegistrySnapshot({ - config: params?.config, - workspaceDir: params?.workspaceDir, - env: params?.env, - }); - const registry = loadPluginManifestRegistryForInstalledIndex({ - index, + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params?.config, workspaceDir: params?.workspaceDir, env: params?.env, diff --git a/src/secrets/provider-env-vars.dynamic.test.ts b/src/secrets/provider-env-vars.dynamic.test.ts index d51caa8cc2d..9039c24f9f0 100644 --- a/src/secrets/provider-env-vars.dynamic.test.ts +++ b/src/secrets/provider-env-vars.dynamic.test.ts @@ -25,13 +25,17 @@ type MockManifestRegistry = { diagnostics: unknown[]; }; -const pluginRegistryMocks = vi.hoisted(() => ({ - loadPluginManifestRegistryForInstalledIndex: vi.fn<() => MockManifestRegistry>(() => ({ +const pluginRegistryMocks = vi.hoisted(() => { + const loadManifestRegistry = vi.fn<() => MockManifestRegistry>(() => ({ plugins: [], diagnostics: [], - })), - loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), -})); + })); + return { + loadPluginManifestRegistryForInstalledIndex: loadManifestRegistry, + loadPluginManifestRegistryForPluginRegistry: loadManifestRegistry, + loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), + }; +}); vi.mock("../plugins/manifest-registry-installed.js", () => ({ loadPluginManifestRegistryForInstalledIndex: @@ -39,6 +43,8 @@ vi.mock("../plugins/manifest-registry-installed.js", () => ({ })); vi.mock("../plugins/plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: + pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry, loadPluginRegistrySnapshot: pluginRegistryMocks.loadPluginRegistrySnapshot, })); diff --git a/src/secrets/provider-env-vars.ts b/src/secrets/provider-env-vars.ts index 46d249a35d4..a5c1f2250f0 100644 --- a/src/secrets/provider-env-vars.ts +++ b/src/secrets/provider-env-vars.ts @@ -1,12 +1,11 @@ import { resolveProviderAuthAliasMap } from "../agents/provider-auth-aliases.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; -import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js"; import type { PluginManifestRecord } from "../plugins/manifest-registry.js"; import { isWorkspacePluginAllowedByConfig, normalizePluginConfigId, } from "../plugins/plugin-config-trust.js"; -import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { hasKind } from "../plugins/slots.js"; const CORE_PROVIDER_AUTH_ENV_VAR_CANDIDATES = { @@ -77,13 +76,7 @@ function appendUniqueEnvVarCandidates( function resolveManifestProviderAuthEnvVarCandidates( params?: ProviderEnvVarLookupParams, ): Record { - const index = loadPluginRegistrySnapshot({ - config: params?.config, - workspaceDir: params?.workspaceDir, - env: params?.env, - }); - const registry = loadPluginManifestRegistryForInstalledIndex({ - index, + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params?.config, workspaceDir: params?.workspaceDir, env: params?.env, diff --git a/src/secrets/target-registry-data.ts b/src/secrets/target-registry-data.ts index 84ee403cb82..f9e275c2df4 100644 --- a/src/secrets/target-registry-data.ts +++ b/src/secrets/target-registry-data.ts @@ -1,6 +1,5 @@ -import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js"; import type { PluginManifestRecord } from "../plugins/manifest-registry.js"; -import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js"; import type { SecretTargetRegistryEntry } from "./target-registry-types.js"; @@ -50,11 +49,8 @@ function hasWebProviderContract( function listBundledWebProviderSecretTargetRegistryEntries(): SecretTargetRegistryEntry[] { const entries: SecretTargetRegistryEntry[] = []; - const index = loadPluginRegistrySnapshot({}); - for (const record of loadPluginManifestRegistryForInstalledIndex({ - index, - includeDisabled: true, - }).plugins) { + for (const record of loadPluginManifestRegistryForPluginRegistry({ includeDisabled: true }) + .plugins) { if (record.origin !== "bundled") { continue; } @@ -73,11 +69,8 @@ function listBundledWebProviderSecretTargetRegistryEntries(): SecretTargetRegist function listChannelSecretTargetRegistryEntries(): SecretTargetRegistryEntry[] { const entries: SecretTargetRegistryEntry[] = []; - const index = loadPluginRegistrySnapshot({}); - for (const record of loadPluginManifestRegistryForInstalledIndex({ - index, - includeDisabled: true, - }).plugins) { + for (const record of loadPluginManifestRegistryForPluginRegistry({ includeDisabled: true }) + .plugins) { if (record.origin !== "bundled") { continue; } diff --git a/src/trajectory/metadata.ts b/src/trajectory/metadata.ts index 40f8972fc2f..7a741e1eb95 100644 --- a/src/trajectory/metadata.ts +++ b/src/trajectory/metadata.ts @@ -10,7 +10,7 @@ import { sanitizeSupportSnapshotValue, type SupportRedactionContext, } from "../logging/diagnostic-support-redaction.js"; -import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js"; +import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { getActivePluginRegistry, listImportedRuntimePluginIds } from "../plugins/runtime.js"; import { VERSION } from "../version.js"; @@ -136,10 +136,11 @@ function buildPluginsFromManifest(params: { workspaceDir?: string; env?: NodeJS.ProcessEnv; }) { - const registry = loadPluginManifestRegistry({ + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, env: params.env, + includeDisabled: true, }); return { source: "manifest-registry", diff --git a/src/wizard/setup.plugin-config.ts b/src/wizard/setup.plugin-config.ts index 0d0ac2884f8..baf025a023c 100644 --- a/src/wizard/setup.plugin-config.ts +++ b/src/wizard/setup.plugin-config.ts @@ -16,13 +16,13 @@ export type ConfigurablePlugin = { jsonSchema?: JsonSchemaObject; }; -type ManifestRegistryModule = typeof import("../plugins/manifest-registry.js"); +type PluginRegistryModule = typeof import("../plugins/plugin-registry.js"); -let manifestRegistryModulePromise: Promise | undefined; +let pluginRegistryModulePromise: Promise | undefined; -function loadManifestRegistryModule(): Promise { - manifestRegistryModulePromise ??= import("../plugins/manifest-registry.js"); - return manifestRegistryModulePromise; +function loadPluginRegistryModule(): Promise { + pluginRegistryModulePromise ??= import("../plugins/plugin-registry.js"); + return pluginRegistryModulePromise; } type JsonSchemaProperty = { @@ -299,10 +299,11 @@ export async function setupPluginConfig(params: { prompter: WizardPrompter; workspaceDir?: string; }): Promise { - const { loadPluginManifestRegistry } = await loadManifestRegistryModule(); - const registry = loadPluginManifestRegistry({ + const { loadPluginManifestRegistryForPluginRegistry } = await loadPluginRegistryModule(); + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, + includeDisabled: true, }); const unconfigured = discoverUnconfiguredPlugins({ @@ -361,10 +362,11 @@ export async function configurePluginConfig(params: { prompter: WizardPrompter; workspaceDir?: string; }): Promise { - const { loadPluginManifestRegistry } = await loadManifestRegistryModule(); - const registry = loadPluginManifestRegistry({ + const { loadPluginManifestRegistryForPluginRegistry } = await loadPluginRegistryModule(); + const registry = loadPluginManifestRegistryForPluginRegistry({ config: params.config, workspaceDir: params.workspaceDir, + includeDisabled: true, }); const configurable = discoverConfigurablePlugins({