136
137
constructor(
139
>
@ILabelService private readonly labelService: ILabelService,
140
>
@IModelService private readonly modelService: IModelService,
141
>
@IInstantiationService protected readonly instantiationService: IInstantiationService,
142
>
@IUserDataProfileService private readonly userDataService: IUserDataProfileService,
143
>
@IConfigurationService private readonly configurationService: IConfigurationService,
144
>
@IFileService protected readonly fileService: IFileService,
145
>
@IStorageService private readonly storageService: IStorageService,
146
>
@ITelemetryService private readonly telemetryService: ITelemetryService,
147
>
@IWorkspaceContextService private readonly workspaceService: IWorkspaceContextService,
148
>
@IPathService protected readonly pathService: IPathService,
149
>
@IAgentPluginService private readonly agentPluginService: IAgentPluginService,
150
>
@IWorkspaceTrustManagementService private readonly workspaceTrustService: IWorkspaceTrustManagementService,
151
>
) {
152
>
super();
153
>
154
>
this.fileLocator = this.createPromptFilesLocator();
155
>
156
>
this._register(this.modelService.onModelRemoved((model) => {
157
this.cachedParsedPromptFromModels.delete(model.uri);
159
>
160
>
this.extensionPromptFiles = this._register(this.instantiationService.createInstance(ExtensionPromptFileService));
161
>
const onDidChangeExtensionPromptFiles = this.extensionPromptFiles.onDidChange;
162
>
163
>
// Invalidate the cached file location list whenever an extension contribution
164
>
// or provider for the same type changes (or its `when` re-evaluates).
165
>
this._register(onDidChangeExtensionPromptFiles(e => {
166
this.cachedFileLocations[e.type] = undefined;
168
>
169
>
const modelChangeEvent = this._register(new ModelChangeTracker(this.modelService)).onDidPromptChange;
170
>
this.cachedCustomAgents = this._register(new CachedPromise(
171
>
(token) => this.computeAgentDiscoveryInfo(token),
172
>
() => Event.any(
173
>
this.getFileLocatorEvent(PromptsType.agent),
174
>
Event.filter(modelChangeEvent, e => e.promptType === PromptsType.agent),
175
>
Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration(PromptsConfig.USE_CHAT_HOOKS)),
176
>
Event.filter(onDidChangeExtensionPromptFiles, e => e.type === PromptsType.agent),
177
>
Event.filter(this._onDidPluginPromptFilesChange.event, t => t === PromptsType.agent),
178
>
this.workspaceTrustService.onDidChangeTrust,
179
>
)
180
>
));
181
>
182
>
this.cachedSlashCommands = this._register(new CachedPromise(
183
>
(token) => this.computeSlashCommandDiscoveryInfo(token),
184
>
() => Event.any(
185
>
this.getFileLocatorEvent(PromptsType.prompt),
186
>
this.getFileLocatorEvent(PromptsType.skill),
187
>
Event.filter(modelChangeEvent, e => e.promptType === PromptsType.prompt),
188
>
Event.filter(modelChangeEvent, e => e.promptType === PromptsType.skill),
189
>
Event.filter(onDidChangeExtensionPromptFiles, e => e.type === PromptsType.prompt || e.type === PromptsType.skill),
190
>
Event.filter(this._onDidPluginPromptFilesChange.event, t => t === PromptsType.prompt || t === PromptsType.skill)),
191
>
));
192
>
193
>
this.cachedSkills = this._register(new CachedPromise(
194
>
(token) => this.computeSkillDiscovery(token),
195
>
() => Event.any(
196
>
this.getFileLocatorEvent(PromptsType.skill),
197
>
Event.filter(modelChangeEvent, e => e.promptType === PromptsType.skill),
198
>
Event.filter(onDidChangeExtensionPromptFiles, e => e.type === PromptsType.skill),
199
>
Event.filter(this._onDidPluginPromptFilesChange.event, t => t === PromptsType.skill))
200
>
));
201
>
202
>
this.cachedHooks = this._register(new CachedPromise(
203
>
(token) => this.computeHooks(token),
204
>
() => Event.any(
205
>
this.getFileLocatorEvent(PromptsType.hook),
206
>
Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration(PromptsConfig.USE_CHAT_HOOKS) || e.affectsConfiguration(PromptsConfig.USE_CLAUDE_HOOKS)),
207
>
this._onDidPluginHooksChange.event,
208
>
this.workspaceTrustService.onDidChangeTrust,
209
>
)
210
>
));
211
>
212
>
this.cachedInstructions = this._register(new CachedPromise(
213
>
(token) => this.computeInstructionFiles(token),
214
>
() => Event.any(
215
>
this.getFileLocatorEvent(PromptsType.instructions),
216
>
Event.filter(onDidChangeExtensionPromptFiles, e => e.type === PromptsType.instructions),
217
>
Event.filter(this._onDidPluginPromptFilesChange.event, t => t === PromptsType.instructions),
218
>
)
219
>
));
220
>
221
>
this._register(this.watchPluginPromptFilesForType(
222
>
PromptsType.prompt,
223
>
(plugin, reader) => plugin.commands.read(reader),
224
>
));
225
>
this._register(this.watchPluginPromptFilesForType(
226
>
PromptsType.skill,
227
>
(plugin, reader) => plugin.skills.read(reader),
228
>
));
229
>
this._register(this.watchPluginPromptFilesForType(
230
>
PromptsType.agent,
231
>
(plugin, reader) => plugin.agents.read(reader),
232
>
));
233
>
this._register(this.watchPluginPromptFilesForType(
234
>
PromptsType.instructions,
235
>
(plugin, reader) => plugin.instructions.read(reader),
236
>
));
237
>
238
>
this._register(autorun(reader => {
239
>
const plugins = this.agentPluginService.plugins.read(reader);
240
>
const hookFiles: IPluginPromptPath[] = [];
241
>
for (const plugin of plugins) {
242
if (isContributionEnabled(plugin.enablement.read(reader))) {
243
for (const hook of plugin.hooks.read(reader)) {