From eaf1f53d60fb6f32c57c0f0030c81de59539a321 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 2 May 2026 07:27:19 +0100 Subject: [PATCH] fix: stabilize plugin metadata release checks --- src/plugins/capability-provider-runtime.test.ts | 7 ++++++- src/plugins/install.ts | 5 ++++- src/plugins/plugin-metadata-snapshot.ts | 8 ++++---- src/plugins/plugin-registry-id-normalizer.ts | 6 +++--- src/plugins/tools.optional.test.ts | 9 ++++++++- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/plugins/capability-provider-runtime.test.ts b/src/plugins/capability-provider-runtime.test.ts index a9cffe56e9f..09c694f7031 100644 --- a/src/plugins/capability-provider-runtime.test.ts +++ b/src/plugins/capability-provider-runtime.test.ts @@ -70,6 +70,11 @@ vi.mock("./plugin-registry.js", async (importOriginal) => { return { ...actual, loadPluginRegistrySnapshot: mocks.loadPluginRegistrySnapshot, + loadPluginRegistrySnapshotWithMetadata: (params?: { index?: unknown }) => ({ + snapshot: params?.index ?? mocks.loadPluginRegistrySnapshot(), + source: params?.index ? "provided" : "derived", + diagnostics: [], + }), loadPluginManifestRegistryForPluginRegistry: ( ...args: Parameters ) => { @@ -1078,7 +1083,7 @@ describe("resolvePluginCapabilityProviders", () => { expectResolvedCapabilityProviderIds(providers, ["google"]); expect(mocks.loadPluginManifestRegistry).toHaveBeenCalledWith( expect.objectContaining({ - config: undefined, + config: {}, env: process.env, includeDisabled: true, index: expect.any(Object), diff --git a/src/plugins/install.ts b/src/plugins/install.ts index 4bf4b06bc3a..165d62d6e59 100644 --- a/src/plugins/install.ts +++ b/src/plugins/install.ts @@ -850,6 +850,7 @@ async function installPluginFromPackageDir( const { plugin } = validated; preparedTarget = await resolvePreparedTargetForPluginId(plugin.pluginId); + const hasBundleManifest = Boolean(runtime.detectBundleManifestFormat(params.packageDir)); return await installPluginDirectoryIntoExtensions({ sourceDir: params.packageDir, @@ -865,7 +866,9 @@ async function installPluginFromPackageDir( dryRun, copyErrorPrefix: "failed to copy plugin", hasDeps: - plugin.hasRuntimeDependencies && params.installPolicyRequest?.kind === "plugin-archive", + plugin.hasRuntimeDependencies && + !hasBundleManifest && + params.installPolicyRequest?.kind === "plugin-archive", depsLogMessage: "Installing plugin dependencies…", nameEncoder: encodePluginInstallDirName, afterInstall: async (installedDir) => { diff --git a/src/plugins/plugin-metadata-snapshot.ts b/src/plugins/plugin-metadata-snapshot.ts index 6e003a00fc6..62e9bb97e8d 100644 --- a/src/plugins/plugin-metadata-snapshot.ts +++ b/src/plugins/plugin-metadata-snapshot.ts @@ -14,7 +14,7 @@ import type { PluginMetadataSnapshotOwnerMaps, } from "./plugin-metadata-snapshot.types.js"; import { createPluginRegistryIdNormalizer } from "./plugin-registry-id-normalizer.js"; -import { loadPluginRegistrySnapshotWithMetadata } from "./plugin-registry-snapshot.js"; +import { loadPluginRegistrySnapshotWithMetadata } from "./plugin-registry.js"; export type { LoadPluginMetadataSnapshotParams, PluginMetadataManifestView, @@ -102,13 +102,13 @@ function buildPluginMetadataOwnerMaps( const contracts = new Map(); for (const plugin of plugins) { - for (const channelId of plugin.channels) { + for (const channelId of plugin.channels ?? []) { appendOwner(channels, channelId, plugin.id); } for (const channelId of Object.keys(plugin.channelConfigs ?? {})) { appendOwner(channelConfigs, channelId, plugin.id); } - for (const providerId of plugin.providers) { + for (const providerId of plugin.providers ?? []) { appendOwner(providers, providerId, plugin.id); } for (const providerId of Object.keys(plugin.modelCatalog?.providers ?? {})) { @@ -117,7 +117,7 @@ function buildPluginMetadataOwnerMaps( for (const providerId of Object.keys(plugin.modelCatalog?.aliases ?? {})) { appendOwner(modelCatalogProviders, providerId, plugin.id); } - for (const cliBackendId of plugin.cliBackends) { + for (const cliBackendId of plugin.cliBackends ?? []) { appendOwner(cliBackends, cliBackendId, plugin.id); } for (const cliBackendId of plugin.setup?.cliBackends ?? []) { diff --git a/src/plugins/plugin-registry-id-normalizer.ts b/src/plugins/plugin-registry-id-normalizer.ts index 15fb5fd3e9e..1d7d9dfd8e0 100644 --- a/src/plugins/plugin-registry-id-normalizer.ts +++ b/src/plugins/plugin-registry-id-normalizer.ts @@ -22,10 +22,10 @@ function collectObjectKeys(value: Record | undefined): readonly function listPluginRegistryNormalizerAliases(plugin: PluginManifestRecord): readonly string[] { return [ plugin.id, - ...plugin.providers, - ...plugin.channels, + ...(plugin.providers ?? []), + ...(plugin.channels ?? []), ...(plugin.setup?.providers?.map((provider) => provider.id) ?? []), - ...plugin.cliBackends, + ...(plugin.cliBackends ?? []), ...(plugin.setup?.cliBackends ?? []), ...collectObjectKeys(plugin.modelCatalog?.providers), ...collectObjectKeys(plugin.modelCatalog?.aliases), diff --git a/src/plugins/tools.optional.test.ts b/src/plugins/tools.optional.test.ts index ad8d0aa1bbf..76c4f67f084 100644 --- a/src/plugins/tools.optional.test.ts +++ b/src/plugins/tools.optional.test.ts @@ -234,16 +234,19 @@ function createOptionalDemoActiveRegistry() { function installToolManifestSnapshot(params: { config: ReturnType["config"]; + env?: NodeJS.ProcessEnv; plugin: Record; }) { installToolManifestSnapshots({ config: params.config, + env: params.env, plugins: [params.plugin], }); } function installToolManifestSnapshots(params: { config: ReturnType["config"]; + env?: NodeJS.ProcessEnv; plugins: Record[]; }) { const plugins = params.plugins; @@ -287,7 +290,7 @@ function installToolManifestSnapshots(params: { manifestPluginCount: plugins.length, }, } as never, - { config: params.config, env: process.env, workspaceDir: "/tmp" }, + { config: params.config, env: params.env ?? process.env, workspaceDir: "/tmp" }, ); } @@ -392,6 +395,7 @@ describe("resolvePluginTools optional tools", () => { const config = createContext().config; installToolManifestSnapshot({ config, + env: {}, plugin: createXaiToolManifest(), }); const factory = vi.fn(() => makeTool("x_search")); @@ -434,6 +438,7 @@ describe("resolvePluginTools optional tools", () => { const config = createContext().config; installToolManifestSnapshot({ config, + env: {}, plugin: createXaiToolManifest(), }); const factory = vi.fn(() => makeTool("x_search")); @@ -474,6 +479,7 @@ describe("resolvePluginTools optional tools", () => { const config = createContext().config; installToolManifestSnapshot({ config, + env: { XAI_API_KEY: "test-key" }, plugin: createXaiToolManifest(), }); const factory = vi.fn(() => makeTool("x_search")); @@ -541,6 +547,7 @@ describe("resolvePluginTools optional tools", () => { } as const; installToolManifestSnapshot({ config, + env: {}, plugin: createXaiToolManifest(), }); const factory = vi.fn(() => makeTool("x_search"));