Skip to content

Commit c6d811e

Browse files
committed
fix(plugins): preserve bundled allowlist edges
1 parent 494857e commit c6d811e

5 files changed

Lines changed: 65 additions & 6 deletions
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
02987f4cecb64a98170b61c925fd7b16a22b276abfb261f9281b42f613ded923 config-baseline.json
2-
de5a6f65ef09dc23453a2e12512e41c133c941519e0ebef7f2946e4a24265d17 config-baseline.core.json
1+
2566cb33c48abf3884d44cc605e3fe23ee3dc3e998c29fe86dfe773faf58cb52 config-baseline.json
2+
eab2f8a9af31910e26874209330d10ca46afd910cba88beda8a48fe6b9831159 config-baseline.core.json
33
cd7c0c7fb1435bc7e59099e9ac334462d5ad444016e9ab4512aae63a238f78dc config-baseline.channel.json
44
9832b30a696930a3da7efccf38073137571e1b66cae84e54d747b733fdafcc54 config-baseline.plugin.json

src/agents/models-config.providers.plugin-allowlist-compat.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,27 @@ describe("implicit provider plugin allowlist compatibility", () => {
132132
).toEqual(["openrouter"]);
133133
});
134134

135+
it("does not re-enable plugins when allowlist mode rejects every compat plugin", () => {
136+
const config = withBundledPluginEnablementCompat({
137+
config: {
138+
plugins: {
139+
enabled: false,
140+
allow: ["openrouter"],
141+
bundledDiscovery: "allowlist",
142+
},
143+
},
144+
pluginIds: ["kilocode", "moonshot"],
145+
});
146+
147+
expect(config).toEqual({
148+
plugins: {
149+
enabled: false,
150+
allow: ["openrouter"],
151+
bundledDiscovery: "allowlist",
152+
},
153+
});
154+
});
155+
135156
it("still honors explicit plugin denies over compat allowlist injection", () => {
136157
const config = withBundledPluginEnablementCompat({
137158
config: withBundledPluginAllowlistCompat({

src/plugins/bundled-compat.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,24 @@ export function withBundledPluginEnablementCompat(params: {
4646
const allow = params.config?.plugins?.allow;
4747
const allowSet =
4848
!useCompatDiscovery && Array.isArray(allow) && allow.length > 0 ? new Set(allow) : undefined;
49+
let hasEligiblePlugin = false;
4950
let changed = false;
5051
const nextEntries: Record<string, PluginEntryConfig> = { ...existingEntries };
5152

5253
for (const pluginId of params.pluginIds) {
53-
if (existingEntries[pluginId] !== undefined) {
54+
if (allowSet && !allowSet.has(pluginId)) {
5455
continue;
5556
}
56-
if (allowSet && !allowSet.has(pluginId)) {
57+
hasEligiblePlugin = true;
58+
if (existingEntries[pluginId] !== undefined) {
5759
continue;
5860
}
5961
nextEntries[pluginId] = { enabled: true };
6062
changed = true;
6163
}
6264

6365
if (!changed) {
64-
if (!forcePluginsEnabled) {
66+
if (!forcePluginsEnabled || !hasEligiblePlugin) {
6567
return params.config;
6668
}
6769
}

src/plugins/web-provider-public-artifacts.fallback.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,37 @@ describe("web provider public artifact manifest fallback", () => {
152152
pluginId: "fallback-fetch",
153153
});
154154
});
155+
156+
it("matches bundled web-search candidates through provider alias allowlist entries", () => {
157+
mocks.resolveBundledExplicitWebSearchProvidersFromPublicArtifacts.mockReturnValueOnce(null);
158+
mocks.loadPluginMetadataSnapshot.mockReturnValueOnce({
159+
diagnostics: [],
160+
plugins: [
161+
{
162+
id: "google",
163+
origin: "bundled",
164+
rootDir: "/tmp/google",
165+
contracts: { webSearchProviders: ["gemini"] },
166+
},
167+
],
168+
});
169+
mocks.loadBundledWebSearchProviderEntriesFromDir.mockReturnValueOnce([
170+
{ id: "gemini", pluginId: "google" },
171+
]);
172+
173+
const providers = resolveBundledWebSearchProvidersFromPublicArtifacts({
174+
config: {
175+
plugins: {
176+
allow: ["google-gemini-cli"],
177+
bundledDiscovery: "allowlist",
178+
},
179+
},
180+
});
181+
182+
expect(providers).toEqual([{ id: "gemini", pluginId: "google" }]);
183+
expect(mocks.loadBundledWebSearchProviderEntriesFromDir).toHaveBeenCalledWith({
184+
dirName: "google",
185+
pluginId: "google",
186+
});
187+
});
155188
});

src/plugins/web-provider-public-artifacts.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from "node:path";
2+
import { normalizePluginId } from "./config-state.js";
23
import type { PluginLoadOptions } from "./loader.js";
34
import { loadManifestMetadataSnapshot } from "./manifest-contract-eligibility.js";
45
import type { PluginManifestRecord } from "./manifest-registry.js";
@@ -38,7 +39,9 @@ function filterAllowlistedBundledPluginIds(
3839
) {
3940
return [...pluginIds];
4041
}
41-
const allowedPluginIds = new Set(allow.map((pluginId) => pluginId.trim()).filter(Boolean));
42+
const allowedPluginIds = new Set(
43+
allow.map((pluginId) => normalizePluginId(pluginId)).filter(Boolean),
44+
);
4245
return pluginIds.filter((pluginId) => allowedPluginIds.has(pluginId));
4346
}
4447

0 commit comments

Comments
 (0)