1
>
/*---------------------------------------------------------------------------------------------
agentPluginService.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 { IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js';
7
>
import { IObservable } from '../../../../../base/common/observable.js';
8
>
import { basename } from '../../../../../base/common/resources.js';
9
>
import { URI } from '../../../../../base/common/uri.js';
10
>
import { SyncDescriptor0 } from '../../../../../platform/instantiation/common/descriptors.js';
11
>
import { createDecorator } from '../../../../../platform/instantiation/common/instantiation.js';
12
>
import { type INamedPluginResource, type IMcpServerDefinition, type IParsedHookCommand, type PluginFormat } from '../../../../../platform/agentPlugins/common/pluginParsers.js';
13
>
import { ContributionEnablementState, IEnablementModel } from '../enablement.js';
14
>
import { HookType } from '../promptSyntax/hookTypes.js';
15
>
import { IMarketplacePlugin } from './pluginMarketplaceService.js';
16
>
17
>
export const IAgentPluginService = createDecorator<IAgentPluginService>('agentPluginService');
18
>
19
>
export interface IAgentPluginHook {
20
>
readonly type: HookType;
21
>
readonly hooks: readonly IParsedHookCommand[];
22
>
/** URI where this hook is defined -- not unique, multiple hooks may be in a manifest */
23
>
readonly uri: URI;
24
>
readonly originalId: string;
25
>
}
26
>
27
>
export type IAgentPluginCommand = INamedPluginResource;
28
>
export type IAgentPluginSkill = INamedPluginResource;
29
>
export type IAgentPluginAgent = INamedPluginResource;
30
>
export type IAgentPluginInstruction = INamedPluginResource;
31
>
export type IAgentPluginMcpServerDefinition = IMcpServerDefinition;
32
>
33
>
export interface IAgentPlugin {
34
>
readonly uri: URI;
35
>
readonly format: PluginFormat;
36
>
/** Human-readable display name for the plugin. */
37
>
readonly label: string;
38
>
readonly enablement: IObservable<ContributionEnablementState>;
39
>
/**
40
>
* When `true`, the plugin is blocked by enterprise policy. It remains
41
>
* visible (shown as disabled) but its contributions are inactive and the
42
>
* user cannot re-enable it. Folded into {@link enablement} so all gating
43
>
* consumers honor it automatically.
44
>
*/
45
>
readonly policyBlocked?: IObservable<boolean>;
46
>
/** Removes this plugin from its discovery source (config or installed storage). Undefined for policy-managed plugins that cannot be removed by the user. */
47
>
remove?(): void;
48
>
readonly hooks: IObservable<readonly IAgentPluginHook[]>;
49
>
readonly commands: IObservable<readonly IAgentPluginCommand[]>;
50
>
readonly skills: IObservable<readonly IAgentPluginSkill[]>;
51
>
readonly agents: IObservable<readonly IAgentPluginAgent[]>;
52
>
readonly instructions: IObservable<readonly IAgentPluginInstruction[]>;
53
>
readonly mcpServerDefinitions: IObservable<readonly IAgentPluginMcpServerDefinition[]>;
54
>
/** Set when the plugin was installed from a marketplace repository. */
55
>
readonly fromMarketplace?: IMarketplacePlugin;
56
>
}
57
>
58
>
export interface IAgentPluginService {
59
>
readonly _serviceBrand: undefined;
60
>
readonly plugins: IObservable<readonly IAgentPlugin[]>;
61
>
readonly enablementModel: IEnablementModel;
62
>
}
63
>
64
>
export interface IAgentPluginDiscovery extends IDisposable {
65
>
readonly plugins: IObservable<readonly IAgentPlugin[] | undefined>;
66
>
start(enablementModel: IEnablementModel): void;
67
>
}
68
>
69
>
export const enum AgentPluginDiscoveryPriority {
70
>
Configured = 10,
71
>
Marketplace = 20,
72
>
Extension = 30,
73
>
CopilotCli = 40,
74
>
}
75
>
76
>
export function getCanonicalPluginCommandId(plugin: { readonly uri: URI; readonly label?: string }, commandName: string): string {
77
const prefix = (plugin.label ? normalizePluginToken(plugin.label) : '') || normalizePluginToken(basename(plugin.uri));
78
const normalizedCommand = normalizePluginToken(commandName);