agentPluginEnablement.ts ×12

Frontier kind: Code frontier

unlabeled · c_ea788809b635

95 tests · 36666 LOC · 172 files · introduces 0 tests · 64 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
12 ranges64 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
2989 ranges36666 lines · 172 files · Browse complete extent
All tests (intent)
95 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 64 introduced LOC across 12 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/workbench/contrib/chat/common/plugins/agentPluginEnablement.ts 64 introduced LOC · 12 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- agentPluginEnablement.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { IObservable } from '../../../../../base/common/observable.js';
7 > import { AgentPluginDiscoveryPriority, IAgentPlugin } from './agentPluginService.js';
8 > import { IGitHubPluginSource, IGitUrlPluginSource, IMarketplacePlugin, INpmPluginSource, IPipPluginSource, PluginSourceKind } from './pluginMarketplaceService.js';
9 > import { type IMarketplaceReference } from './marketplaceReference.js';
10 > import { CollisionEnablementModel, IEnablementModel } from '../enablement.js';
11 >
12 > export interface IDiscoveredAgentPlugins {
13 > readonly plugins: readonly IAgentPlugin[];
14 > readonly priority: AgentPluginDiscoveryPriority;
15 > readonly order: number;
16 > }
17 >
18 > interface IAgentPluginCandidate {
19 > readonly plugin: IAgentPlugin;
20 > readonly priority: AgentPluginDiscoveryPriority;
21 > readonly order: number;
22 > readonly pluginOrder: number;
23 > readonly canonicalKey: string;
24 > }
25 >
26 > /**
27 > * Path fragment that identifies a Copilot-CLI-installed plugin. Mirrored by
28 > * `ConfiguredAgentPluginDiscovery._resolveEnterprisePluginId`.
29 > */
30 > const COPILOT_CLI_INSTALL_PATH_FRAGMENT = '/.copilot/installed-plugins/';
31 >
32 > export class AgentPluginCollisionEnablementModel extends CollisionEnablementModel {
33 > constructor(base: IEnablementModel, collisionGroups: IObservable<ReadonlyMap<string, readonly string[]>>) {
34 super(base, collisionGroups);
35 }
37 >
38 > export function getSortedAgentPlugins(discoveries: readonly IDiscoveredAgentPlugins[]): readonly IAgentPlugin[] {
39 return getUniqueAgentPluginCandidates(discoveries)
40 .map(candidate => candidate.plugin)
41 .sort((a, b) => a.uri.toString().localeCompare(b.uri.toString()));
42 }
44 > export function getCanonicalAgentPluginCollisionGroups(discoveries: readonly IDiscoveredAgentPlugins[], isBlocked?: (plugin: IAgentPlugin) => boolean): ReadonlyMap<string, readonly string[]> {
45 const candidates = getUniqueAgentPluginCandidates(discoveries);
46 const byCanonicalKey = new Map<string, string[]>();
68 return groups;
69 }
71 > /**
72 > * Whether the `ChatEnabledPlugins` enterprise policy explicitly blocks this plugin.
73 > *
74 > * The policy is a **deny list**, not an allowlist: enterprise-managed `enabledPlugins` entries
75 > * add to (never replace) the plugins a user has installed. A plugin is blocked only when its
76 > * policy id is mapped to `false`; entries mapped to `true` enable the plugin, and a plugin the
77 > * policy never mentions is left to the user's own enablement. This keeps a customer's existing
78 > * plugins working when their enterprise deploys `enabledPlugins` for a different plugin.
79 > */
80 > export function isAgentPluginBlockedByPolicy(
81 plugin: IAgentPlugin,
82 enabledPluginsPolicy: Record<string, boolean> | undefined,
85 return pluginId !== undefined && enabledPluginsPolicy?.[pluginId] === false;
86 }
88 > export function getAgentPluginPolicyId(plugin: IAgentPlugin): string | undefined {
89 const identity = getPolicyIdentity(plugin);
90 return identity ? `${identity.name}@${identity.marketplace}` : undefined;
91 }
93 function getAgentPluginCandidates(discoveries: readonly IDiscoveredAgentPlugins[]): IAgentPluginCandidate[] {
94 const candidates: IAgentPluginCandidate[] = [];
113 );
114 }
116 function getUniqueAgentPluginCandidates(discoveries: readonly IDiscoveredAgentPlugins[]): IAgentPluginCandidate[] {
117 const unique: IAgentPluginCandidate[] = [];
127 return unique;
128 }
130 function getCanonicalPluginIdentity(plugin: IAgentPlugin): string {
131 return getMarketplaceCanonicalIdentity(plugin.fromMarketplace)
133 ?? `uri:${plugin.uri.toString()}`;
134 }
136 function getMarketplaceCanonicalIdentity(plugin: IMarketplacePlugin | undefined): string | undefined {
137 if (!plugin) {
166 }
167 }
169 function getCopilotCliInstallCanonicalIdentity(plugin: IAgentPlugin): string | undefined {
170 if (plugin.uri.scheme !== 'file') {
196 return `github:${groups.owner.toLowerCase()}/${groups.repo.toLowerCase()}|${normalizePluginIdentitySegment(groups.plugin)}`;
197 }
199 function normalizePluginIdentitySegment(value: string): string {
200 return value
206 .replace(/^[-:.]+|[-:.]+$/g, '');
207 }
209 > interface IPolicyIdentity {
210 > readonly name: string;
211 > readonly marketplace: string;
212 > readonly marketplaceReference?: IMarketplaceReference;
213 > }
214 >
215 function getPolicyIdentity(plugin: IAgentPlugin): IPolicyIdentity | undefined {
216 const m = plugin.fromMarketplace;