@codingame/monaco-vscode-chat-service-override 37.1.0 → 37.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/index.js +15 -5
  2. package/package.json +5 -5
  3. package/vscode/src/vs/platform/agentHost/browser/agentHostEnablementService.js +1 -1
  4. package/vscode/src/vs/workbench/api/browser/mainThreadChatAgents2.d.ts +104 -0
  5. package/vscode/src/vs/workbench/api/browser/mainThreadChatAgents2.js +827 -0
  6. package/vscode/src/vs/workbench/api/browser/mainThreadChatCodeMapper.d.ts +15 -0
  7. package/vscode/src/vs/workbench/api/browser/mainThreadChatCodeMapper.js +71 -0
  8. package/vscode/src/vs/workbench/api/browser/mainThreadChatContext.d.ts +16 -0
  9. package/vscode/src/vs/workbench/api/browser/mainThreadChatContext.js +95 -0
  10. package/vscode/src/vs/workbench/api/browser/mainThreadChatDebug.d.ts +22 -0
  11. package/vscode/src/vs/workbench/api/browser/mainThreadChatDebug.js +286 -0
  12. package/vscode/src/vs/workbench/api/browser/mainThreadChatInputNotification.d.ts +10 -0
  13. package/vscode/src/vs/workbench/api/browser/mainThreadChatInputNotification.js +38 -0
  14. package/vscode/src/vs/workbench/api/browser/mainThreadChatQuota.d.ts +9 -0
  15. package/vscode/src/vs/workbench/api/browser/mainThreadChatQuota.js +22 -0
  16. package/vscode/src/vs/workbench/api/browser/mainThreadChatSessions.d.ts +130 -0
  17. package/vscode/src/vs/workbench/api/browser/mainThreadChatSessions.js +907 -0
  18. package/vscode/src/vs/workbench/api/browser/mainThreadChatStatus.d.ts +10 -0
  19. package/vscode/src/vs/workbench/api/browser/mainThreadChatStatus.js +28 -0
  20. package/vscode/src/vs/workbench/api/browser/mainThreadLanguageModelTools.d.ts +27 -0
  21. package/vscode/src/vs/workbench/api/browser/mainThreadLanguageModelTools.js +167 -0
  22. package/vscode/src/vs/workbench/api/browser/mainThreadLanguageModels.d.ts +46 -0
  23. package/vscode/src/vs/workbench/api/browser/mainThreadLanguageModels.js +356 -0
  24. package/vscode/src/vs/workbench/contrib/agentsVoice/browser/agentsVoiceWidgetBinding.js +1 -1
  25. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatOpenAgentDebugPanelAction.js +1 -1
  26. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatPluginActions.js +2 -2
  27. package/vscode/src/vs/workbench/contrib/chat/browser/actions/exportAgentHostDebugLogsAction.js +1 -1
  28. package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginEditor/agentPluginEditor.js +1 -1
  29. package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginEditor/agentPluginItems.d.ts +2 -2
  30. package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginRepositoryService.d.ts +1 -1
  31. package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginRepositoryService.js +2 -2
  32. package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginsView.js +1 -1
  33. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentCustomizationContentExpander.d.ts +1 -1
  34. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentCustomizationItemProvider.d.ts +1 -1
  35. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentCustomizationSyncProvider.d.ts +1 -1
  36. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostActiveClientService.d.ts +1 -1
  37. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostExistingSessionHarnessPickerEnablement.js +1 -1
  38. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostLocalCustomizations.d.ts +1 -1
  39. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostPermissionUiContribution.js +1 -1
  40. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostPromptCacheNotification.js +1 -1
  41. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.js +5 -3
  42. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSettings.contribution.js +1 -1
  43. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSignedOutModelsNotification.js +2 -2
  44. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentSessionSettings.contribution.js +2 -2
  45. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/openSessionLinkOpener.contribution.js +1 -1
  46. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.d.ts +1 -1
  47. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.js +1 -1
  48. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.d.ts +1 -1
  49. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.js +1 -1
  50. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsService.d.ts +1 -1
  51. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsService.js +1 -1
  52. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionProjectionActions.d.ts +1 -1
  53. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionProjectionActions.js +1 -1
  54. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionProjectionService.d.ts +1 -1
  55. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionProjectionService.js +1 -1
  56. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionsExperiments.contribution.js +1 -1
  57. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentTitleBarStatusWidget.js +1 -1
  58. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/localAgentSessionsController.js +2 -2
  59. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationItemSource.d.ts +1 -1
  60. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationItemSource.js +1 -1
  61. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationItemsModel.js +3 -3
  62. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagementEditor.js +1 -1
  63. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationPresentation.d.ts +1 -1
  64. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationHarnessService.d.ts +1 -1
  65. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationHarnessService.js +1 -1
  66. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigration.d.ts +1 -1
  67. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationCategories.js +1 -1
  68. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/embeddedAgentPluginDetail.d.ts +1 -1
  69. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/mcpListWidget.js +1 -1
  70. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/pluginListWidget.d.ts +1 -1
  71. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/pluginListWidget.js +1 -1
  72. package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/promptsServiceCustomizationItemProvider.d.ts +1 -1
  73. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentResolveService.js +1 -1
  74. package/vscode/src/vs/workbench/contrib/chat/browser/chat.shared.contribution.js +12 -12
  75. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/agentHostChatDebugProvider.d.ts +1 -1
  76. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/agentHostChatDebugProvider.js +1 -1
  77. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatCustomizationDiscoveryRenderer.d.ts +1 -1
  78. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugCacheExplorerView.d.ts +1 -1
  79. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugDetailPanel.d.ts +1 -1
  80. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEventDetailRenderer.d.ts +1 -1
  81. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEventList.d.ts +1 -1
  82. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEventList.js +1 -1
  83. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugFlowGraph.d.ts +1 -1
  84. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugHookContentRenderer.d.ts +1 -1
  85. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugHookContentRenderer.js +1 -1
  86. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugLogsView.d.ts +1 -1
  87. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugMessageContentRenderer.d.ts +1 -1
  88. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugModelTurnContentRenderer.d.ts +1 -1
  89. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugOverviewView.js +1 -1
  90. package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugToolCallContentRenderer.d.ts +1 -1
  91. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedNotebookEntry.d.ts +1 -1
  92. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/notebook/chatEditingModifiedNotebookSnapshot.js +1 -1
  93. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/notebook/chatEditingNotebookCellEntry.d.ts +1 -1
  94. package/vscode/src/vs/workbench/contrib/chat/browser/chatImageCarouselService.js +1 -1
  95. package/vscode/src/vs/workbench/contrib/chat/browser/chatPromoNotification.js +1 -1
  96. package/vscode/src/vs/workbench/contrib/chat/browser/chatQuotaNotification.js +2 -2
  97. package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionDescription.d.ts +2 -0
  98. package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionDescription.js +57 -0
  99. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupContributions.js +2 -2
  100. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupController.d.ts +1 -1
  101. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupController.js +1 -1
  102. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupGrowthSession.d.ts +1 -1
  103. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupProviders.js +1 -1
  104. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupRunner.d.ts +1 -1
  105. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupRunner.js +1 -1
  106. package/vscode/src/vs/workbench/contrib/chat/browser/chatTipService.js +1 -1
  107. package/vscode/src/vs/workbench/contrib/chat/browser/expNotification/chatExpNotificationConfig.d.ts +1 -1
  108. package/vscode/src/vs/workbench/contrib/chat/browser/expNotification/chatExpNotificationConfig.js +1 -1
  109. package/vscode/src/vs/workbench/contrib/chat/browser/expNotification/chatExpNotificationContribution.js +1 -1
  110. package/vscode/src/vs/workbench/contrib/chat/browser/pluginInstallService.d.ts +1 -1
  111. package/vscode/src/vs/workbench/contrib/chat/browser/pluginInstallService.js +2 -2
  112. package/vscode/src/vs/workbench/contrib/chat/browser/pluginSources.d.ts +1 -1
  113. package/vscode/src/vs/workbench/contrib/chat/browser/pluginSources.js +1 -1
  114. package/vscode/src/vs/workbench/contrib/chat/browser/pluginUrlHandler.js +1 -1
  115. package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/hookActions.js +3 -3
  116. package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/hookUtils.js +1 -1
  117. package/vscode/src/vs/workbench/contrib/chat/browser/promptsDebugContribution.js +1 -1
  118. package/vscode/src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.js +1 -1
  119. package/vscode/src/vs/workbench/contrib/chat/browser/tools/renameTool.js +1 -1
  120. package/vscode/src/vs/workbench/contrib/chat/browser/tools/toolHelpers.js +1 -1
  121. package/vscode/src/vs/workbench/contrib/chat/browser/tools/usagesTool.js +1 -1
  122. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/agentHostInputCompletions.js +1 -1
  123. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCommandArgumentHint.js +1 -1
  124. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCompletions.js +2 -2
  125. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputEditorContrib.js +1 -1
  126. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputEditorHover.js +10 -2
  127. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputReferenceDecorations.js +1 -1
  128. package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewPane.d.ts +1 -1
  129. package/vscode/src/vs/workbench/contrib/chat/common/chatDebugEvents.d.ts +1 -1
  130. package/vscode/src/vs/workbench/contrib/chat/common/chatDebugService.d.ts +253 -0
  131. package/vscode/src/vs/workbench/contrib/chat/common/chatDebugService.js +20 -0
  132. package/vscode/src/vs/workbench/contrib/chat/common/chatDebugServiceImpl.d.ts +1 -1
  133. package/vscode/src/vs/workbench/contrib/chat/common/chatDebugServiceImpl.js +1 -1
  134. package/vscode/src/vs/workbench/contrib/chat/common/chatService/chatServiceImpl.js +2 -2
  135. package/vscode/src/vs/workbench/contrib/chat/common/customizationHarnessService.d.ts +300 -0
  136. package/vscode/src/vs/workbench/contrib/chat/common/customizationHarnessService.js +272 -0
  137. package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginEnablement.d.ts +25 -0
  138. package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginEnablement.js +178 -0
  139. package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginService.d.ts +78 -0
  140. package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginService.js +51 -0
  141. package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginServiceImpl.d.ts +2 -2
  142. package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginServiceImpl.js +2 -2
  143. package/vscode/src/vs/workbench/contrib/chat/common/plugins/fileBackedInstalledPluginsStore.d.ts +67 -0
  144. package/vscode/src/vs/workbench/contrib/chat/common/plugins/fileBackedInstalledPluginsStore.js +195 -0
  145. package/vscode/src/vs/workbench/contrib/chat/common/plugins/marketplaceReference.d.ts +67 -0
  146. package/vscode/src/vs/workbench/contrib/chat/common/plugins/marketplaceReference.js +294 -0
  147. package/vscode/src/vs/workbench/contrib/chat/common/plugins/pluginMarketplaceService.d.ts +212 -0
  148. package/vscode/src/vs/workbench/contrib/chat/common/plugins/pluginMarketplaceService.js +955 -0
  149. package/vscode/src/vs/workbench/contrib/chat/common/plugins/strictKnownMarketplaces.d.ts +31 -0
  150. package/vscode/src/vs/workbench/contrib/chat/common/plugins/strictKnownMarketplaces.js +122 -0
  151. package/vscode/src/vs/workbench/contrib/chat/common/plugins/workspacePluginSettingsService.d.ts +1 -1
  152. package/vscode/src/vs/workbench/contrib/chat/common/plugins/workspacePluginSettingsService.js +1 -1
  153. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/computeAutomaticInstructions.d.ts +65 -0
  154. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/computeAutomaticInstructions.js +698 -0
  155. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/hookClaudeCompat.d.ts +50 -0
  156. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/hookClaudeCompat.js +78 -0
  157. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/hookCompatibility.d.ts +77 -0
  158. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/hookCompatibility.js +120 -0
  159. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/hookCopilotCliCompat.d.ts +10 -0
  160. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/hookCopilotCliCompat.js +23 -0
  161. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/service/extensionPromptFileService.d.ts +92 -0
  162. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/service/extensionPromptFileService.js +335 -0
  163. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.d.ts +235 -0
  164. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.js +1673 -0
  165. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/utils/promptFilesLocator.d.ts +202 -0
  166. package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/utils/promptFilesLocator.js +872 -0
  167. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/confirmationTool.d.ts +36 -0
  168. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/confirmationTool.js +239 -0
  169. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/editFileTool.d.ts +21 -0
  170. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/editFileTool.js +143 -0
  171. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/manageTodoListTool.d.ts +24 -0
  172. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/manageTodoListTool.js +298 -0
  173. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/reviewPlanTool.d.ts +25 -0
  174. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/reviewPlanTool.js +177 -0
  175. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/runSubagentTool.d.ts +73 -0
  176. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/runSubagentTool.js +577 -0
  177. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/setArtifactRulesTool.d.ts +11 -0
  178. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/setArtifactRulesTool.js +90 -0
  179. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/setArtifactsTool.d.ts +16 -0
  180. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/setArtifactsTool.js +130 -0
  181. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/taskCompleteTool.d.ts +12 -0
  182. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/taskCompleteTool.js +53 -0
  183. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/toolHelpers.d.ts +5 -0
  184. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/toolHelpers.js +12 -0
  185. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/tools.d.ts +10 -0
  186. package/vscode/src/vs/workbench/contrib/chat/common/tools/builtinTools/tools.js +91 -0
  187. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.d.ts +38 -0
  188. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.js +518 -0
  189. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsParametersSchema.d.ts +6 -0
  190. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsParametersSchema.js +231 -0
  191. package/vscode/src/vs/workbench/contrib/notebook/browser/controller/chat/cellChatActions.js +1 -1
  192. package/vscode/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.js +4 -4
  193. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/getTerminalLastCommandTool.js +1 -1
  194. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/getTerminalOutputTool.js +1 -1
  195. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/getTerminalSelectionTool.js +1 -1
  196. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/killTerminalTool.js +1 -1
  197. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalConfirmationTool.js +1 -1
  198. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.js +1 -1
  199. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/sendToTerminalTool.js +1 -1
  200. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/createAndRunTaskTool.js +1 -1
  201. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/getTaskOutputTool.js +1 -1
  202. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/runTaskTool.js +1 -1
  203. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalOutputCache.d.ts +1 -1
  204. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalOutputCache.js +1 -1
  205. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalOutputCompressor.js +1 -1
@@ -0,0 +1,1673 @@
1
+
2
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
+ import { CancellationToken, CancellationTokenPool } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
4
+ import { isCancellationError, CancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
5
+ import { Emitter, Event } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
6
+ import { parse } from '@codingame/monaco-vscode-api/vscode/vs/base/common/json';
7
+ import { getParseErrorMessage } from '@codingame/monaco-vscode-api/vscode/vs/base/common/jsonErrorMessages';
8
+ import { Disposable, MutableDisposable, DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
9
+ import { StopWatch } from '@codingame/monaco-vscode-api/vscode/vs/base/common/stopwatch';
10
+ import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
11
+ import { ResourceMap, ResourceSet } from '@codingame/monaco-vscode-api/vscode/vs/base/common/map';
12
+ import { isEqual, dirname, joinPath, basename } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
13
+ import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
14
+ import { OffsetRange } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/core/ranges/offsetRange';
15
+ import { IModelService } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/services/model.service';
16
+ import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
17
+ import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
18
+ import { isAgentBuiltinCustomizationUri } from '@codingame/monaco-vscode-api/vscode/vs/platform/agentHost/common/agentHostCustomizationUri';
19
+ import { FileOperationError, FileOperationResult } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files';
20
+ import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
21
+ import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
22
+ import { ILabelService } from '@codingame/monaco-vscode-api/vscode/vs/platform/label/common/label.service';
23
+ import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
24
+ import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
25
+ import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
26
+ import { ITelemetryService } from '@codingame/monaco-vscode-api/vscode/vs/platform/telemetry/common/telemetry.service';
27
+ import { IUserDataProfileService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/userDataProfile/common/userDataProfile.service';
28
+ import { PromptsConfig } from '@codingame/monaco-vscode-katex-common/vscode/vs/workbench/contrib/chat/common/promptSyntax/config/config';
29
+ import { getSkillFolderName, getCleanPromptName, AGENT_MD_FILENAME, CLAUDE_MD_FILENAME, CLAUDE_LOCAL_MD_FILENAME, CLAUDE_CONFIG_FOLDER, COPILOT_CUSTOM_INSTRUCTIONS_FILENAME, GITHUB_CONFIG_FOLDER, COPILOT_CONFIG_FOLDER, VOICE_INSTRUCTIONS_FILENAME, DICTATION_INSTRUCTIONS_FILENAME, isInClaudeRulesFolder } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/config/promptFileLocations';
30
+ import { PromptsType, PromptFileSource, PROMPT_LANGUAGE_ID, getPromptsTypeForLanguageId, Target } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/promptTypes';
31
+ import { PromptFilesLocator } from '../utils/promptFilesLocator.js';
32
+ import { PromptFileParser, evaluateApplyToPattern, PromptHeaderAttributes } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/promptFileParser';
33
+ import { PromptsStorage, matchesSessionType, IAgentSource, AgentInstructionFileType } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/service/promptsService';
34
+ import { Limiter, Delayer, raceCancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
35
+ import { Schemas } from '@codingame/monaco-vscode-api/vscode/vs/base/common/network';
36
+ import { parseSubagentHooksFromYaml } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/hookSchema';
37
+ import { parseHooksFromFile, HookSourceFormat } from '../hookCompatibility.js';
38
+ import { IWorkspaceContextService } from '@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspace.service';
39
+ import { IWorkspaceTrustManagementService } from '@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspaceTrust.service';
40
+ import { IPathService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/path/common/pathService.service';
41
+ import { getTarget, mapClaudeModels, mapClaudeTools } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptFileAttributes';
42
+ import { getCanonicalPluginCommandId } from '../../plugins/agentPluginService.js';
43
+ import { IAgentPluginService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/plugins/agentPluginService.service';
44
+ import { isContributionEnabled } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/enablement';
45
+ import { assertNever } from '@codingame/monaco-vscode-api/vscode/vs/base/common/assert';
46
+ import { ExtensionPromptFileService } from './extensionPromptFileService.js';
47
+ import { COPILOT_STRICT_PLUGIN_ONLY_CUSTOMIZATION_CONFIG, COPILOT_ALLOW_MANAGED_HOOKS_ONLY_CONFIG } from '@codingame/monaco-vscode-api/vscode/vs/platform/policy/common/copilotManagedSettings';
48
+ import { isPromptTypeBlocked } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/customizationLockdown';
49
+ import { isAgentPluginForceEnabledByPolicy } from '../../plugins/agentPluginEnablement.js';
50
+ import { ChatConfiguration } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/constants';
51
+ import { observableFromEvent } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableFromEvent';
52
+ import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
53
+
54
+ const PROMPT_FILE_DISCOVERY_CONCURRENCY = 10;
55
+ let PromptsService = class PromptsService extends Disposable {
56
+ queueDiscoveryRead(task) {
57
+ return this._discoveryLimiter.queue(task);
58
+ }
59
+ constructor(
60
+ logger,
61
+ labelService,
62
+ modelService,
63
+ instantiationService,
64
+ userDataService,
65
+ configurationService,
66
+ fileService,
67
+ storageService,
68
+ telemetryService,
69
+ workspaceService,
70
+ pathService,
71
+ agentPluginService,
72
+ workspaceTrustService
73
+ ) {
74
+ super();
75
+ this.logger = logger;
76
+ this.labelService = labelService;
77
+ this.modelService = modelService;
78
+ this.instantiationService = instantiationService;
79
+ this.userDataService = userDataService;
80
+ this.configurationService = configurationService;
81
+ this.fileService = fileService;
82
+ this.storageService = storageService;
83
+ this.telemetryService = telemetryService;
84
+ this.workspaceService = workspaceService;
85
+ this.pathService = pathService;
86
+ this.agentPluginService = agentPluginService;
87
+ this.workspaceTrustService = workspaceTrustService;
88
+ this._discoveryLimiter = this._register(( new Limiter(PROMPT_FILE_DISCOVERY_CONCURRENCY)));
89
+ this.agentInstructionsWatcher = this._register(( new MutableDisposable()));
90
+ this._onDidChangeAgentInstructions = this._register(( new Emitter({
91
+ onWillAddFirstListener: () => {
92
+ const store = ( new DisposableStore());
93
+ const agentInstructionsUpdatedEvent = this.fileLocator.createAgentInstructionsUpdatedEvent();
94
+ store.add(agentInstructionsUpdatedEvent);
95
+ store.add(
96
+ agentInstructionsUpdatedEvent.event(() => this._onDidChangeAgentInstructions.fire())
97
+ );
98
+ this.agentInstructionsWatcher.value = store;
99
+ },
100
+ onDidRemoveLastListener: () => {
101
+ this.agentInstructionsWatcher.clear();
102
+ }
103
+ })));
104
+ this.knownPromptSlashCommandNames = ( new Set());
105
+ this.cachedParsedPromptFromModels = ( new ResourceMap());
106
+ this.cachedFileLocations = {};
107
+ this.fileLocatorEvents = {};
108
+ this._onDidPluginPromptFilesChange = this._register(( new Emitter()));
109
+ this._onDidPluginHooksChange = this._register(( new Emitter()));
110
+ this._pluginPromptFilesByType = ( new Map());
111
+ this.knownPromptSlashCommandsHydrationStarted = false;
112
+ this.disabledPromptsStorageKeyPrefix = "chat.disabledPromptFiles.";
113
+ this.fileLocator = this.createPromptFilesLocator();
114
+ this._register(this.modelService.onModelRemoved(model => {
115
+ this.cachedParsedPromptFromModels.delete(model.uri);
116
+ }));
117
+ this.extensionPromptFiles = this._register(this.instantiationService.createInstance(ExtensionPromptFileService));
118
+ const onDidChangeExtensionPromptFiles = this.extensionPromptFiles.onDidChange;
119
+ const onDidChangeCustomizationLockdown = Event.filter(
120
+ this.configurationService.onDidChangeConfiguration,
121
+ e => e.affectsConfiguration(COPILOT_STRICT_PLUGIN_ONLY_CUSTOMIZATION_CONFIG) || e.affectsConfiguration(COPILOT_ALLOW_MANAGED_HOOKS_ONLY_CONFIG)
122
+ );
123
+ this._register(onDidChangeCustomizationLockdown(() => {
124
+ this.cachedFileLocations[PromptsType.agent] = undefined;
125
+ this.cachedFileLocations[PromptsType.skill] = undefined;
126
+ this.cachedFileLocations[PromptsType.hook] = undefined;
127
+ this.cachedFileLocations[PromptsType.instructions] = undefined;
128
+ this._onDidChangeAgentInstructions.fire();
129
+ }));
130
+ this._register(onDidChangeExtensionPromptFiles(e => {
131
+ this.cachedFileLocations[e.type] = undefined;
132
+ }));
133
+ const modelChangeEvent = this._register(( new ModelChangeTracker(this.modelService))).onDidPromptChange;
134
+ this.cachedCustomAgents = this._register(( new CachedPromise(token => this.computeAgentDiscoveryInfo(token), () => Event.any(
135
+ this.getFileLocatorEvent(PromptsType.agent),
136
+ Event.filter(modelChangeEvent, e => e.promptType === PromptsType.agent),
137
+ Event.filter(
138
+ this.configurationService.onDidChangeConfiguration,
139
+ e => e.affectsConfiguration(PromptsConfig.USE_CHAT_HOOKS)
140
+ ),
141
+ Event.filter(onDidChangeExtensionPromptFiles, e => e.type === PromptsType.agent),
142
+ Event.filter(this._onDidPluginPromptFilesChange.event, t => t === PromptsType.agent),
143
+ onDidChangeCustomizationLockdown,
144
+ this.workspaceTrustService.onDidChangeTrust
145
+ ))));
146
+ this.cachedSlashCommands = this._register(( new CachedPromise(token => this.computeSlashCommandDiscoveryInfo(token), () => Event.any(
147
+ this.getFileLocatorEvent(PromptsType.prompt),
148
+ this.getFileLocatorEvent(PromptsType.skill),
149
+ Event.filter(modelChangeEvent, e => e.promptType === PromptsType.prompt),
150
+ Event.filter(modelChangeEvent, e => e.promptType === PromptsType.skill),
151
+ Event.filter(
152
+ onDidChangeExtensionPromptFiles,
153
+ e => e.type === PromptsType.prompt || e.type === PromptsType.skill
154
+ ),
155
+ Event.filter(
156
+ this._onDidPluginPromptFilesChange.event,
157
+ t => t === PromptsType.prompt || t === PromptsType.skill
158
+ ),
159
+ onDidChangeCustomizationLockdown
160
+ ))));
161
+ this.cachedSkills = this._register(( new CachedPromise(token => this.computeSkillDiscovery(token), () => Event.any(
162
+ this.getFileLocatorEvent(PromptsType.skill),
163
+ Event.filter(modelChangeEvent, e => e.promptType === PromptsType.skill),
164
+ Event.filter(onDidChangeExtensionPromptFiles, e => e.type === PromptsType.skill),
165
+ Event.filter(this._onDidPluginPromptFilesChange.event, t => t === PromptsType.skill),
166
+ onDidChangeCustomizationLockdown
167
+ ))));
168
+ this.cachedHooks = this._register(( new CachedPromise(
169
+ token => this.computeHooks(token),
170
+ () => Event.any(this.getFileLocatorEvent(PromptsType.hook), Event.filter(
171
+ this.configurationService.onDidChangeConfiguration,
172
+ e => e.affectsConfiguration(PromptsConfig.USE_CHAT_HOOKS) || e.affectsConfiguration(PromptsConfig.USE_CLAUDE_HOOKS)
173
+ ), onDidChangeCustomizationLockdown, this._onDidPluginHooksChange.event, this.workspaceTrustService.onDidChangeTrust)
174
+ )));
175
+ this.cachedInstructions = this._register(( new CachedPromise(token => this.computeInstructionFiles(token), () => Event.any(
176
+ this.getFileLocatorEvent(PromptsType.instructions),
177
+ Event.filter(onDidChangeExtensionPromptFiles, e => e.type === PromptsType.instructions),
178
+ Event.filter(
179
+ this._onDidPluginPromptFilesChange.event,
180
+ t => t === PromptsType.instructions
181
+ ),
182
+ onDidChangeCustomizationLockdown
183
+ ))));
184
+ this._register(
185
+ this.watchPluginPromptFilesForType(PromptsType.prompt, (plugin, reader) => plugin.commands.read(reader))
186
+ );
187
+ this._register(
188
+ this.watchPluginPromptFilesForType(PromptsType.skill, (plugin, reader) => plugin.skills.read(reader))
189
+ );
190
+ this._register(
191
+ this.watchPluginPromptFilesForType(PromptsType.agent, (plugin, reader) => plugin.agents.read(reader))
192
+ );
193
+ this._register(this.watchPluginPromptFilesForType(
194
+ PromptsType.instructions,
195
+ (plugin, reader) => plugin.instructions.read(reader)
196
+ ));
197
+ const managedHooksOnly = observableFromEvent(
198
+ this,
199
+ onDidChangeCustomizationLockdown,
200
+ () => this.configurationService.getValue(COPILOT_ALLOW_MANAGED_HOOKS_ONLY_CONFIG) === true
201
+ );
202
+ const enabledPluginsPolicy = observableFromEvent(this, Event.filter(
203
+ this.configurationService.onDidChangeConfiguration,
204
+ e => e.affectsConfiguration(ChatConfiguration.EnabledPlugins)
205
+ ), () => this.configurationService.inspect(ChatConfiguration.EnabledPlugins).policyValue);
206
+ this._register(autorun(reader => {
207
+ const plugins = this.agentPluginService.plugins.read(reader);
208
+ const managedHooksOnlyValue = managedHooksOnly.read(reader);
209
+ const enabledPluginsPolicyValue = enabledPluginsPolicy.read(reader);
210
+ const hookFiles = [];
211
+ for (const plugin of plugins) {
212
+ if (isContributionEnabled(plugin.enablement.read(reader)) && (!managedHooksOnlyValue || isAgentPluginForceEnabledByPolicy(plugin, enabledPluginsPolicyValue))) {
213
+ for (const hook of plugin.hooks.read(reader)) {
214
+ hookFiles.push({
215
+ uri: hook.uri,
216
+ storage: PromptsStorage.plugin,
217
+ type: PromptsType.hook,
218
+ name: getCanonicalPluginCommandId(plugin, hook.originalId),
219
+ pluginUri: plugin.uri,
220
+ pluginLabel: plugin.label,
221
+ source: PromptFileSource.Plugin
222
+ });
223
+ }
224
+ }
225
+ }
226
+ this._pluginPromptFilesByType.set(PromptsType.hook, hookFiles);
227
+ this.cachedFileLocations[PromptsType.hook] = undefined;
228
+ this._onDidPluginHooksChange.fire();
229
+ }));
230
+ }
231
+ watchPluginPromptFilesForType(type, getItems) {
232
+ return autorun(reader => {
233
+ const plugins = this.agentPluginService.plugins.read(reader);
234
+ const nextFiles = [];
235
+ for (const plugin of plugins) {
236
+ if (!isContributionEnabled(plugin.enablement.read(reader))) {
237
+ continue;
238
+ }
239
+ for (const item of getItems(plugin, reader)) {
240
+ nextFiles.push({
241
+ uri: item.uri,
242
+ storage: PromptsStorage.plugin,
243
+ type,
244
+ name: getCanonicalPluginCommandId(plugin, item.name),
245
+ pluginUri: plugin.uri,
246
+ pluginLabel: plugin.label,
247
+ source: PromptFileSource.Plugin
248
+ });
249
+ }
250
+ }
251
+ nextFiles.sort((a, b) => `${a.name ?? ""}|${( a.uri.toString())}`.localeCompare(`${b.name ?? ""}|${( b.uri.toString())}`));
252
+ this._pluginPromptFilesByType.set(type, nextFiles);
253
+ this.cachedFileLocations[type] = undefined;
254
+ this._onDidPluginPromptFilesChange.fire(type);
255
+ });
256
+ }
257
+ createPromptFilesLocator() {
258
+ return this.instantiationService.createInstance(PromptFilesLocator);
259
+ }
260
+ getFileLocatorEvent(type) {
261
+ let event = this.fileLocatorEvents[type];
262
+ if (!event) {
263
+ event = this.fileLocatorEvents[type] = this._register(this.fileLocator.createFilesUpdatedEvent(type)).event;
264
+ this._register(event(() => {
265
+ this.cachedFileLocations[type] = undefined;
266
+ }));
267
+ }
268
+ return event;
269
+ }
270
+ getParsedPromptFile(textModel) {
271
+ const cached = this.cachedParsedPromptFromModels.get(textModel.uri);
272
+ if (cached && cached[0] === textModel.getVersionId()) {
273
+ return cached[1];
274
+ }
275
+ const ast = ( new PromptFileParser()).parse(textModel.uri, textModel.getValue());
276
+ if (!cached || cached[0] < textModel.getVersionId()) {
277
+ this.cachedParsedPromptFromModels.set(textModel.uri, [textModel.getVersionId(), ast]);
278
+ }
279
+ return ast;
280
+ }
281
+ async listPromptFiles(type, token) {
282
+ let listPromise = this.cachedFileLocations[type];
283
+ if (!listPromise) {
284
+ listPromise = this.computeListPromptFiles(type, token);
285
+ if (!this.fileLocatorEvents[type]) {
286
+ return listPromise;
287
+ }
288
+ this.cachedFileLocations[type] = listPromise;
289
+ return listPromise;
290
+ }
291
+ return listPromise;
292
+ }
293
+ async computeListPromptFiles(type, token) {
294
+ const allowStandalone = !this.areStandalonePromptFilesBlocked(type);
295
+ const prompts = await Promise.all([
296
+ allowStandalone ? this.fileLocator.listFilesWithSource(type, PromptsStorage.user, token).then(files => ( files.map(file => ({
297
+ ...file,
298
+ storage: PromptsStorage.user,
299
+ type
300
+ })))) : [],
301
+ allowStandalone ? this.fileLocator.listFilesWithSource(type, PromptsStorage.local, token).then(files => ( files.map(file => ({
302
+ ...file,
303
+ storage: PromptsStorage.local,
304
+ type
305
+ })))) : [],
306
+ this.getExtensionPromptFiles(type, token),
307
+ this._pluginPromptFilesByType.get(type) ?? [],
308
+ this.getBuiltinPromptFiles(type, token)
309
+ ]);
310
+ return prompts.flat();
311
+ }
312
+ async _collectSourceFolderDiagnostics(type) {
313
+ if (this.areStandalonePromptFilesBlocked(type)) {
314
+ return [];
315
+ }
316
+ const resolvedFolders = await this.fileLocator.getSourceFoldersInDiscoveryOrder(type);
317
+ return ( resolvedFolders.map(folder => ({
318
+ uri: folder.uri,
319
+ storage: folder.storage
320
+ })));
321
+ }
322
+ registerPromptFileProvider(extension, type, provider) {
323
+ return this.extensionPromptFiles.registerPromptFileProvider(extension, type, provider);
324
+ }
325
+ async listPromptFilesForStorage(type, storage, token, root) {
326
+ let promptPaths;
327
+ switch (storage) {
328
+ case PromptsStorage.extension:
329
+ promptPaths = await this.getExtensionPromptFiles(type, token);
330
+ break;
331
+ case PromptsStorage.local:
332
+ promptPaths = this.areStandalonePromptFilesBlocked(type) ? [] : await this.fileLocator.listFilesWithSource(type, PromptsStorage.local, token, root).then(files => ( files.map(file => ({
333
+ ...file,
334
+ storage: PromptsStorage.local,
335
+ type
336
+ }))));
337
+ break;
338
+ case PromptsStorage.user:
339
+ promptPaths = this.areStandalonePromptFilesBlocked(type) ? [] : await this.fileLocator.listFilesWithSource(type, PromptsStorage.user, token).then(files => ( files.map(file => ({
340
+ ...file,
341
+ storage: PromptsStorage.user,
342
+ type
343
+ }))));
344
+ break;
345
+ case PromptsStorage.plugin:
346
+ promptPaths = this._pluginPromptFilesByType.get(type) ?? [];
347
+ break;
348
+ case PromptsStorage.builtIn:
349
+ promptPaths = await this.getBuiltinPromptFiles(type, token);
350
+ break;
351
+ default:
352
+ throw ( new Error(`[listPromptFilesForStorage] Unsupported prompt storage type: ${storage}`));
353
+ }
354
+ return promptPaths;
355
+ }
356
+ getExtensionPromptFiles(type, token) {
357
+ return this.extensionPromptFiles.getExtensionPromptFiles(type, token);
358
+ }
359
+ async getBuiltinPromptFiles(type, token) {
360
+ return [];
361
+ }
362
+ async getSourceFolders(type) {
363
+ if (this.areStandalonePromptFilesBlocked(type)) {
364
+ return [];
365
+ }
366
+ const result = [];
367
+ if (type === PromptsType.hook) {
368
+ const hooksFolders = await this.fileLocator.getHookSourceFolders();
369
+ for (const folder of hooksFolders) {
370
+ result.push({
371
+ uri: folder.uri,
372
+ storage: folder.storage,
373
+ type,
374
+ source: folder.source
375
+ });
376
+ }
377
+ return result;
378
+ }
379
+ if (type === PromptsType.skill) {
380
+ const resolvedFolders = await this.fileLocator.getResolvedSourceFolders(type);
381
+ for (const folder of resolvedFolders) {
382
+ result.push({
383
+ uri: folder.searchRoot,
384
+ storage: folder.storage,
385
+ type,
386
+ source: folder.source
387
+ });
388
+ }
389
+ return result;
390
+ }
391
+ for (const uri of await this.fileLocator.getConfigBasedSourceFolders(type)) {
392
+ result.push({
393
+ uri,
394
+ storage: PromptsStorage.local,
395
+ type
396
+ });
397
+ }
398
+ const userHome = this.userDataService.currentProfile.promptsHome;
399
+ result.push({
400
+ uri: userHome,
401
+ storage: PromptsStorage.user,
402
+ type
403
+ });
404
+ return result;
405
+ }
406
+ async getResolvedSourceFolders(type) {
407
+ if (this.areStandalonePromptFilesBlocked(type)) {
408
+ return [];
409
+ }
410
+ return this.fileLocator.getResolvedSourceFolders(type);
411
+ }
412
+ areStandalonePromptFilesBlocked(type) {
413
+ const strictPluginOnly = this.configurationService.getValue(COPILOT_STRICT_PLUGIN_ONLY_CUSTOMIZATION_CONFIG);
414
+ return isPromptTypeBlocked(strictPluginOnly, type) || (type === PromptsType.hook && this.configurationService.getValue(COPILOT_ALLOW_MANAGED_HOOKS_ONLY_CONFIG) === true);
415
+ }
416
+ areAgentHooksAllowed(promptPath) {
417
+ if (this.configurationService.getValue(COPILOT_ALLOW_MANAGED_HOOKS_ONLY_CONFIG) === true) {
418
+ if (promptPath.storage !== PromptsStorage.plugin || !promptPath.pluginUri) {
419
+ return false;
420
+ }
421
+ const plugin = this.agentPluginService.plugins.get().find(candidate => isEqual(candidate.uri, promptPath.pluginUri));
422
+ const enabledPluginsPolicy = this.configurationService.inspect(ChatConfiguration.EnabledPlugins).policyValue;
423
+ return plugin !== undefined && isAgentPluginForceEnabledByPolicy(plugin, enabledPluginsPolicy);
424
+ }
425
+ const strictPluginOnly = this.configurationService.getValue(COPILOT_STRICT_PLUGIN_ONLY_CUSTOMIZATION_CONFIG);
426
+ return !isPromptTypeBlocked(strictPluginOnly, PromptsType.hook) || (promptPath.storage !== PromptsStorage.local && promptPath.storage !== PromptsStorage.user);
427
+ }
428
+ get onDidChangeSlashCommands() {
429
+ return this.cachedSlashCommands.onDidChangePromise;
430
+ }
431
+ async getPromptSlashCommands(token) {
432
+ const discoveryInfo = await this.cachedSlashCommands.get(token);
433
+ const result = this.slashCommandsFromDiscoveryInfo(discoveryInfo);
434
+ return result;
435
+ }
436
+ async computeSlashCommandDiscoveryInfo(token) {
437
+ const stopWatch = StopWatch.create(true);
438
+ const promptFiles = await this.listPromptFiles(PromptsType.prompt, token);
439
+ const useAgentSkills = this.configurationService.getValue(PromptsConfig.USE_AGENT_SKILLS);
440
+ const skills = useAgentSkills ? await this.listPromptFiles(PromptsType.skill, token) : [];
441
+ const disabledSkills = this.getDisabledPromptFiles(PromptsType.skill);
442
+ const enabledSkills = skills.filter(s => !( disabledSkills.has(s.uri))).sort((a, b) => this.getSkillPriority(a) - this.getSkillPriority(b));
443
+ const slashCommandFiles = [...promptFiles, ...enabledSkills];
444
+ const parseResults = await Promise.all(( slashCommandFiles.map(promptPath => this.queueDiscoveryRead(async () => {
445
+ try {
446
+ const parsedPromptFile = await this.parseNew(promptPath.uri, token);
447
+ let rawName;
448
+ if (promptPath.type === PromptsType.skill) {
449
+ rawName = getSkillFolderName(promptPath.uri);
450
+ } else {
451
+ rawName = parsedPromptFile?.header?.name ?? promptPath.name ?? getCleanPromptName(promptPath.uri);
452
+ }
453
+ const name = promptPath.source === PromptFileSource.Plugin && promptPath.pluginUri ? getCanonicalPluginCommandId({
454
+ uri: promptPath.pluginUri,
455
+ label: promptPath.pluginLabel
456
+ }, rawName) : rawName;
457
+ const description = parsedPromptFile?.header?.description ?? promptPath.description;
458
+ const argumentHint = parsedPromptFile?.header?.argumentHint;
459
+ const userInvocable = parsedPromptFile?.header?.userInvocable;
460
+ return {
461
+ status: "loaded",
462
+ promptPath: this.withPromptPathMetadata(promptPath, name, description),
463
+ argumentHint,
464
+ userInvocable
465
+ };
466
+ } catch (e) {
467
+ if (!isCancellationError(e)) {
468
+ this.logger.error(
469
+ `[computeSlashCommandDiscoveryInfo] Failed to parse prompt file for slash command: ${promptPath.uri}`,
470
+ e instanceof Error ? e.message : String(e)
471
+ );
472
+ }
473
+ return {
474
+ status: "skipped",
475
+ skipReason: "parse-error",
476
+ errorMessage: e instanceof Error ? e.message : String(e),
477
+ promptPath
478
+ };
479
+ }
480
+ }))));
481
+ const seenSkillNames = ( new Set());
482
+ const files = [];
483
+ for (const result of parseResults) {
484
+ if (result.status === "loaded" && result.promptPath.type === PromptsType.skill) {
485
+ const name = result.promptPath.name;
486
+ if (name !== undefined) {
487
+ if (( seenSkillNames.has(name))) {
488
+ files.push({
489
+ status: "skipped",
490
+ skipReason: "duplicate-name",
491
+ promptPath: result.promptPath
492
+ });
493
+ continue;
494
+ }
495
+ seenSkillNames.add(name);
496
+ }
497
+ }
498
+ files.push(result);
499
+ }
500
+ const promptSourceFolders = await this._collectSourceFolderDiagnostics(PromptsType.prompt);
501
+ const sourceFolders = [...promptSourceFolders];
502
+ if (useAgentSkills) {
503
+ const skillSourceFolders = await this._collectSourceFolderDiagnostics(PromptsType.skill);
504
+ sourceFolders.push(...skillSourceFolders);
505
+ }
506
+ return {
507
+ type: PromptsType.prompt,
508
+ files,
509
+ sourceFolders,
510
+ durationInMillis: stopWatch.elapsed()
511
+ };
512
+ }
513
+ slashCommandsFromDiscoveryInfo(discoveryInfo) {
514
+ const result = [];
515
+ const seen = ( new ResourceSet());
516
+ for (const file of discoveryInfo.files) {
517
+ if (file.status === "loaded") {
518
+ result.push(
519
+ this.asChatPromptSlashCommand(file.argumentHint, file.userInvocable, file.promptPath)
520
+ );
521
+ seen.add(file.promptPath.uri);
522
+ }
523
+ }
524
+ for (const model of this.modelService.getModels()) {
525
+ if (model.getLanguageId() === PROMPT_LANGUAGE_ID && model.uri.scheme === Schemas.untitled && !( seen.has(model.uri))) {
526
+ const parsedPromptFile = this.getParsedPromptFile(model);
527
+ const name = parsedPromptFile?.header?.name ?? getCleanPromptName(model.uri);
528
+ const description = parsedPromptFile?.header?.description;
529
+ result.push(this.asChatPromptSlashCommand(
530
+ parsedPromptFile?.header?.argumentHint,
531
+ parsedPromptFile?.header?.userInvocable,
532
+ {
533
+ uri: model.uri,
534
+ storage: PromptsStorage.local,
535
+ type: PromptsType.prompt,
536
+ name,
537
+ description
538
+ }
539
+ ));
540
+ }
541
+ }
542
+ return result;
543
+ }
544
+ isValidSlashCommandName(command) {
545
+ return command.match(/^[\p{L}\d_\-\.:]+$/u) !== null;
546
+ }
547
+ hasPromptSlashCommand(name) {
548
+ if (!this.knownPromptSlashCommandsHydrationStarted) {
549
+ this.knownPromptSlashCommandsHydrationStarted = true;
550
+ this.refreshKnownPromptSlashCommandNames();
551
+ this._register(
552
+ this.onDidChangeSlashCommands(() => this.refreshKnownPromptSlashCommandNames())
553
+ );
554
+ }
555
+ return ( this.knownPromptSlashCommandNames.has(name));
556
+ }
557
+ refreshKnownPromptSlashCommandNames() {
558
+ this.getPromptSlashCommands(CancellationToken.None).then(commands => {
559
+ this.knownPromptSlashCommandNames.clear();
560
+ for (const cmd of commands) {
561
+ this.knownPromptSlashCommandNames.add(cmd.name);
562
+ }
563
+ }, () => {});
564
+ }
565
+ async resolvePromptSlashCommand(name, sessionType, token) {
566
+ const commands = await this.getPromptSlashCommands(token);
567
+ const command = commands.find(
568
+ cmd => cmd.name === name && matchesSessionType(cmd.sessionTypes, sessionType)
569
+ );
570
+ if (command) {
571
+ if (isAgentBuiltinCustomizationUri(command.uri)) {
572
+ return command;
573
+ }
574
+ return {
575
+ ...command,
576
+ parsedPromptFile: await this.parseNew(command.uri, token)
577
+ };
578
+ }
579
+ return undefined;
580
+ }
581
+ asChatPromptSlashCommand(argumentHint, userInvocable, promptPath) {
582
+ let name = promptPath.name ?? getCleanPromptName(promptPath.uri);
583
+ name = name.replace(/[^\p{L}\d_\-\.:]+/gu, "-");
584
+ return {
585
+ uri: promptPath.uri,
586
+ name: name,
587
+ source: promptPath.source,
588
+ storage: promptPath.storage,
589
+ type: promptPath.type,
590
+ extension: promptPath.extension,
591
+ pluginUri: promptPath.pluginUri,
592
+ pluginLabel: promptPath.pluginLabel,
593
+ description: promptPath.description,
594
+ argumentHint: argumentHint,
595
+ userInvocable: userInvocable ?? true,
596
+ sessionTypes: promptPath.sessionTypes
597
+ };
598
+ }
599
+ async getPromptSlashCommandName(uri, token) {
600
+ const slashCommands = await this.getPromptSlashCommands(token);
601
+ const slashCommand = slashCommands.find(c => isEqual(c.uri, uri));
602
+ if (!slashCommand) {
603
+ return getCleanPromptName(uri);
604
+ }
605
+ return slashCommand.name;
606
+ }
607
+ get onDidChangeCustomAgents() {
608
+ return this.cachedCustomAgents.onDidChangePromise;
609
+ }
610
+ get onDidChangeInstructions() {
611
+ return this.cachedInstructions.onDidChangePromise;
612
+ }
613
+ get onDidChangeAgentInstructions() {
614
+ return this._onDidChangeAgentInstructions.event;
615
+ }
616
+ async getCustomAgents(token) {
617
+ const discoveryInfo = await this.cachedCustomAgents.get(token);
618
+ const result = this.agentsFromDiscoveryInfo(discoveryInfo);
619
+ return result;
620
+ }
621
+ agentsFromDiscoveryInfo(discoveryInfo) {
622
+ const result = [];
623
+ for (const file of discoveryInfo.files) {
624
+ if (file.agent) {
625
+ result.push(file.agent);
626
+ }
627
+ }
628
+ return result;
629
+ }
630
+ async computeAgentDiscoveryInfo(token) {
631
+ const stopWatch = StopWatch.create(true);
632
+ const allAgentFiles = await this.listPromptFiles(PromptsType.agent, token);
633
+ const disabledAgents = this.getDisabledPromptFiles(PromptsType.agent);
634
+ const useChatHooks = this.configurationService.getValue(PromptsConfig.USE_CHAT_HOOKS);
635
+ const isWorkspaceTrusted = this.workspaceTrustService.isWorkspaceTrusted();
636
+ const userHomeUri = await this.pathService.userHome();
637
+ const userHome = userHomeUri.scheme === Schemas.file ? userHomeUri.fsPath : userHomeUri.path;
638
+ const defaultFolder = this.workspaceService.getWorkspace().folders[0];
639
+ const files = await Promise.all(( allAgentFiles.map(promptPath => this.queueDiscoveryRead(async () => {
640
+ const uri = promptPath.uri;
641
+ const isEnabled = !( disabledAgents.has(uri));
642
+ try {
643
+ const ast = await this.parseNew(uri, token);
644
+ let hooks;
645
+ const hooksRaw = ast.header?.hooksRaw;
646
+ if (useChatHooks && isWorkspaceTrusted && hooksRaw && this.areAgentHooksAllowed(promptPath)) {
647
+ const hookWorkspaceFolder = this.workspaceService.getWorkspaceFolder(uri) ?? defaultFolder;
648
+ const workspaceRootUri = hookWorkspaceFolder?.uri;
649
+ const target = getTarget(PromptsType.agent, ast.header ?? promptPath.uri);
650
+ hooks = parseSubagentHooksFromYaml(hooksRaw, workspaceRootUri, userHome, target);
651
+ }
652
+ const extra = {
653
+ sessionTypes: promptPath.sessionTypes,
654
+ hooks,
655
+ name: promptPath.name,
656
+ description: promptPath.description,
657
+ source: IAgentSource.fromPromptPath(promptPath),
658
+ enabled: isEnabled
659
+ };
660
+ const agent = CustomAgent.fromParsedPromptFile(ast, extra);
661
+ const status = isEnabled ? "loaded" : "skipped";
662
+ const skipReason = isEnabled ? undefined : "disabled";
663
+ return {
664
+ status,
665
+ skipReason,
666
+ promptPath: this.withPromptPathMetadata(promptPath, agent.name, agent.description),
667
+ agent
668
+ };
669
+ } catch (e) {
670
+ if (isCancellationError(e)) {
671
+ throw e;
672
+ }
673
+ const error = e instanceof Error ? e : ( new Error(String(e)));
674
+ if (error instanceof FileOperationError && error.fileOperationResult === FileOperationResult.FILE_NOT_FOUND) {
675
+ this.logger.warn(
676
+ `[computeAgentDiscoveryInfo] Skipping agent file that does not exist: ${uri}`,
677
+ error.message
678
+ );
679
+ } else {
680
+ this.logger.error(`[computeAgentDiscoveryInfo] Failed to parse agent file: ${uri}`, error);
681
+ }
682
+ return {
683
+ status: "skipped",
684
+ skipReason: "parse-error",
685
+ errorMessage: error.message,
686
+ promptPath
687
+ };
688
+ }
689
+ }))));
690
+ const sourceFolders = await this._collectSourceFolderDiagnostics(PromptsType.agent);
691
+ return {
692
+ type: PromptsType.agent,
693
+ files,
694
+ sourceFolders,
695
+ durationInMillis: stopWatch.elapsed()
696
+ };
697
+ }
698
+ async parseNew(uri, token) {
699
+ const model = this.modelService.getModel(uri);
700
+ if (model) {
701
+ return this.getParsedPromptFile(model);
702
+ }
703
+ const fileContent = await this.fileService.readFile(uri);
704
+ if (token.isCancellationRequested) {
705
+ throw ( new CancellationError());
706
+ }
707
+ return ( new PromptFileParser()).parse(uri, ( fileContent.value.toString()));
708
+ }
709
+ registerContributedFile(type, uri, extension, name, description, when, sessionTypes) {
710
+ return this.extensionPromptFiles.registerContributedFile(type, uri, extension, name, description, when, sessionTypes);
711
+ }
712
+ getPromptLocationLabel(promptPath) {
713
+ switch (promptPath.storage) {
714
+ case PromptsStorage.local:
715
+ return this.labelService.getUriLabel(dirname(promptPath.uri), {
716
+ relative: true
717
+ });
718
+ case PromptsStorage.user:
719
+ return localize(10853, "User Data");
720
+ case PromptsStorage.extension:
721
+ {
722
+ return localize(
723
+ 10854,
724
+ "Extension: {0}",
725
+ promptPath.extension.displayName ?? promptPath.extension.id
726
+ );
727
+ }
728
+ case PromptsStorage.plugin:
729
+ return localize(10855, "Plugin");
730
+ case PromptsStorage.builtIn:
731
+ return localize(10856, "Built-in");
732
+ default:
733
+ assertNever(promptPath, "Unknown prompt storage type");
734
+ }
735
+ }
736
+ async listNestedAgentMDs(token) {
737
+ if (this.areStandalonePromptFilesBlocked(PromptsType.instructions)) {
738
+ return [];
739
+ }
740
+ const useAgentMD = this.configurationService.getValue(PromptsConfig.USE_AGENT_MD);
741
+ if (!useAgentMD) {
742
+ return [];
743
+ }
744
+ const useNestedAgentMD = this.configurationService.getValue(PromptsConfig.USE_NESTED_AGENT_MD);
745
+ if (useNestedAgentMD) {
746
+ return await this.fileLocator.findAgentMDsInWorkspace(token);
747
+ }
748
+ return [];
749
+ }
750
+ async listAgentInstructions(token, logger) {
751
+ if (this.areStandalonePromptFilesBlocked(PromptsType.instructions)) {
752
+ return [];
753
+ }
754
+ const resolvedAgentFiles = [];
755
+ const promises = [];
756
+ const includeParents = this.configurationService.getValue(PromptsConfig.USE_CUSTOMIZATIONS_IN_PARENT_REPOS) === true;
757
+ const rootFolders = await this.fileLocator.getWorkspaceFolderRoots(includeParents, logger);
758
+ const rootFiles = [];
759
+ const useAgentMD = this.configurationService.getValue(PromptsConfig.USE_AGENT_MD);
760
+ if (!useAgentMD) {
761
+ logger?.logInfo("Agent MD files are disabled via configuration.");
762
+ } else {
763
+ rootFiles.push({
764
+ fileName: AGENT_MD_FILENAME,
765
+ type: AgentInstructionFileType.agentsMd
766
+ });
767
+ }
768
+ const useClaudeMD = this.configurationService.getValue(PromptsConfig.USE_CLAUDE_MD);
769
+ if (!useClaudeMD) {
770
+ logger?.logInfo("Claude MD files are disabled via configuration.");
771
+ } else {
772
+ const claudeMdFile = {
773
+ fileName: CLAUDE_MD_FILENAME,
774
+ type: AgentInstructionFileType.claudeMd
775
+ };
776
+ rootFiles.push(claudeMdFile);
777
+ rootFiles.push({
778
+ fileName: CLAUDE_LOCAL_MD_FILENAME,
779
+ type: AgentInstructionFileType.claudeMd
780
+ });
781
+ promises.push(this.fileLocator.findFilesInRoots(
782
+ rootFolders,
783
+ CLAUDE_CONFIG_FOLDER,
784
+ [claudeMdFile],
785
+ token,
786
+ resolvedAgentFiles
787
+ ));
788
+ promises.push(this.fileLocator.findFilesInRoots(
789
+ [await this.pathService.userHome()],
790
+ CLAUDE_CONFIG_FOLDER,
791
+ [claudeMdFile],
792
+ token,
793
+ resolvedAgentFiles
794
+ ));
795
+ }
796
+ const useCopilotInstructionsFiles = this.configurationService.getValue(PromptsConfig.USE_COPILOT_INSTRUCTION_FILES);
797
+ if (!useCopilotInstructionsFiles) {
798
+ logger?.logInfo("Copilot instructions files are disabled via configuration.");
799
+ } else {
800
+ const copilotInstructionsFile = {
801
+ fileName: COPILOT_CUSTOM_INSTRUCTIONS_FILENAME,
802
+ type: AgentInstructionFileType.copilotInstructionsMd
803
+ };
804
+ promises.push(this.fileLocator.findFilesInRoots(
805
+ rootFolders,
806
+ GITHUB_CONFIG_FOLDER,
807
+ [copilotInstructionsFile],
808
+ token,
809
+ resolvedAgentFiles
810
+ ));
811
+ promises.push(this.fileLocator.findFilesInRoots(
812
+ [await this.pathService.userHome()],
813
+ COPILOT_CONFIG_FOLDER,
814
+ [copilotInstructionsFile],
815
+ token,
816
+ resolvedAgentFiles
817
+ ));
818
+ }
819
+ promises.push(
820
+ this.fileLocator.findFilesInRoots(rootFolders, undefined, rootFiles, token, resolvedAgentFiles)
821
+ );
822
+ await Promise.all(promises);
823
+ if (token.isCancellationRequested) {
824
+ return [];
825
+ }
826
+ const seenFileURI = ( new ResourceSet());
827
+ const symlinks = [];
828
+ const result = [];
829
+ const add = file => {
830
+ if (file.realPath) {
831
+ symlinks.push(file);
832
+ } else {
833
+ result.push(file);
834
+ seenFileURI.add(file.uri);
835
+ }
836
+ return true;
837
+ };
838
+ resolvedAgentFiles.forEach(add);
839
+ for (const symlink of symlinks) {
840
+ if (( seenFileURI.has(symlink.realPath))) {
841
+ logger?.logInfo(
842
+ `Skipping symlinked agent instructions file ${symlink.uri} as target already included: ${symlink.realPath}`
843
+ );
844
+ } else {
845
+ result.push(symlink);
846
+ seenFileURI.add(symlink.realPath);
847
+ }
848
+ }
849
+ return result.sort((a, b) => ( a.uri.toString()).localeCompare(( b.uri.toString())));
850
+ }
851
+ async getVoiceInstructions(token) {
852
+ return this.getSpeechInstructions(VOICE_INSTRUCTIONS_FILENAME, "voice", token);
853
+ }
854
+ async getDictationInstructions(token) {
855
+ return this.getSpeechInstructions(DICTATION_INSTRUCTIONS_FILENAME, "dictation", token);
856
+ }
857
+ async getSpeechInstructions(fileName, kind, token) {
858
+ const userHome = await this.pathService.userHome();
859
+ if (token.isCancellationRequested) {
860
+ return undefined;
861
+ }
862
+ const candidates = [joinPath(userHome, COPILOT_CONFIG_FOLDER, fileName)];
863
+ if (this.workspaceTrustService.isWorkspaceTrusted()) {
864
+ const workspaceRoots = await this.fileLocator.getWorkspaceFolderRoots(false);
865
+ if (token.isCancellationRequested) {
866
+ return undefined;
867
+ }
868
+ candidates.push(...( workspaceRoots.map(root => joinPath(root, GITHUB_CONFIG_FOLDER, fileName))));
869
+ }
870
+ const contents = [];
871
+ for (const candidate of candidates) {
872
+ if (token.isCancellationRequested) {
873
+ return undefined;
874
+ }
875
+ try {
876
+ const content = ( (await this.fileService.readFile(candidate, undefined, token)).value.toString()).trim();
877
+ if (token.isCancellationRequested) {
878
+ return undefined;
879
+ }
880
+ if (content) {
881
+ contents.push(content);
882
+ }
883
+ } catch (error) {
884
+ if (token.isCancellationRequested || isCancellationError(error)) {
885
+ return undefined;
886
+ }
887
+ if (!(error instanceof FileOperationError && error.fileOperationResult === FileOperationResult.FILE_NOT_FOUND)) {
888
+ this.logger.warn(
889
+ `[PromptsService] Failed to read ${kind} instructions from ${( candidate.toString())}: ${error}`
890
+ );
891
+ }
892
+ }
893
+ }
894
+ return contents.length > 0 ? contents.join("\n\n") : undefined;
895
+ }
896
+ getAgentFileURIFromModeFile(oldURI) {
897
+ return this.fileLocator.getAgentFileURIFromModeFile(oldURI);
898
+ }
899
+ getDisabledPromptFiles(type) {
900
+ const disabledKey = this.disabledPromptsStorageKeyPrefix + type;
901
+ const value = this.storageService.get(disabledKey, StorageScope.PROFILE, "[]");
902
+ const result = ( new ResourceSet());
903
+ try {
904
+ const arr = JSON.parse(value);
905
+ if (Array.isArray(arr)) {
906
+ for (const s of arr) {
907
+ try {
908
+ result.add(URI.revive(s));
909
+ } catch {}
910
+ }
911
+ }
912
+ } catch {}
913
+ return result;
914
+ }
915
+ setDisabledPromptFiles(type, uris) {
916
+ const disabled = ( Array.from(uris).map(uri => uri.toJSON()));
917
+ this.storageService.store(
918
+ this.disabledPromptsStorageKeyPrefix + type,
919
+ JSON.stringify(disabled),
920
+ StorageScope.PROFILE,
921
+ StorageTarget.USER
922
+ );
923
+ if (type === PromptsType.agent) {
924
+ this.cachedCustomAgents.refresh();
925
+ } else if (type === PromptsType.skill) {
926
+ this.cachedSkills.refresh();
927
+ this.cachedSlashCommands.refresh();
928
+ }
929
+ }
930
+ sanitizeAgentSkillText(text) {
931
+ return text.replace(/<[^>]+>/g, "");
932
+ }
933
+ truncateAgentSkillName(name, uri) {
934
+ const MAX_NAME_LENGTH = 64;
935
+ const sanitized = this.sanitizeAgentSkillText(name);
936
+ if (sanitized !== name) {
937
+ this.logger.debug(`[findAgentSkills] Agent skill name contains XML tags, removed: ${uri}`);
938
+ }
939
+ if (sanitized.length > MAX_NAME_LENGTH) {
940
+ this.logger.debug(
941
+ `[findAgentSkills] Agent skill name exceeds ${MAX_NAME_LENGTH} characters, truncated: ${uri}`
942
+ );
943
+ return sanitized.substring(0, MAX_NAME_LENGTH);
944
+ }
945
+ return sanitized;
946
+ }
947
+ truncateAgentSkillDescription(description, uri) {
948
+ if (!description) {
949
+ return undefined;
950
+ }
951
+ const MAX_DESCRIPTION_LENGTH = 1024;
952
+ const sanitized = this.sanitizeAgentSkillText(description);
953
+ if (sanitized !== description) {
954
+ this.logger.debug(
955
+ `[findAgentSkills] Agent skill description contains XML tags, removed: ${uri}`
956
+ );
957
+ }
958
+ if (sanitized.length > MAX_DESCRIPTION_LENGTH) {
959
+ this.logger.debug(
960
+ `[findAgentSkills] Agent skill description exceeds ${MAX_DESCRIPTION_LENGTH} characters, truncated: ${uri}`
961
+ );
962
+ return sanitized.substring(0, MAX_DESCRIPTION_LENGTH);
963
+ }
964
+ return sanitized;
965
+ }
966
+ get onDidChangeSkills() {
967
+ return this.cachedSkills.onDidChangePromise;
968
+ }
969
+ get onDidChangeHooks() {
970
+ return this.cachedHooks.onDidChangePromise;
971
+ }
972
+ async findAgentSkills(token) {
973
+ const useAgentSkills = this.configurationService.getValue(PromptsConfig.USE_AGENT_SKILLS);
974
+ if (!useAgentSkills) {
975
+ return undefined;
976
+ }
977
+ const discoveryInfo = await this.cachedSkills.get(token);
978
+ const result = this.skillsFromDiscoveryInfo(discoveryInfo);
979
+ return result;
980
+ }
981
+ skillsFromDiscoveryInfo(discoveryInfo) {
982
+ const result = [];
983
+ for (const file of discoveryInfo.files) {
984
+ if (file.status === "loaded" && file.promptPath.name) {
985
+ const sanitizedDescription = this.truncateAgentSkillDescription(file.promptPath.description, file.promptPath.uri);
986
+ result.push({
987
+ uri: file.promptPath.uri,
988
+ storage: file.promptPath.storage,
989
+ name: file.promptPath.name,
990
+ description: sanitizedDescription,
991
+ disableModelInvocation: file.disableModelInvocation ?? false,
992
+ userInvocable: file.userInvocable ?? true,
993
+ pluginUri: file.promptPath.pluginUri,
994
+ pluginLabel: file.promptPath.pluginLabel,
995
+ extension: file.promptPath.extension,
996
+ sessionTypes: file.promptPath.sessionTypes
997
+ });
998
+ }
999
+ }
1000
+ return result;
1001
+ }
1002
+ async computeSkillDiscovery(token) {
1003
+ const stopWatch = StopWatch.create(true);
1004
+ const files = await this.computeSkillDiscoveryInfo(token);
1005
+ const sourceFolders = await this._collectSourceFolderDiagnostics(PromptsType.skill);
1006
+ const skillsBySource = ( new Map());
1007
+ for (const file of files) {
1008
+ if (file.status === "loaded" && file.promptPath.name) {
1009
+ const source = file.promptPath.source;
1010
+ if (source) {
1011
+ skillsBySource.set(source, (skillsBySource.get(source) || 0) + 1);
1012
+ }
1013
+ }
1014
+ }
1015
+ let skippedMissingName = 0;
1016
+ let skippedMissingDescription = 0;
1017
+ let skippedDuplicateName = 0;
1018
+ let skippedParseFailed = 0;
1019
+ let skippedNameMismatch = 0;
1020
+ for (const file of files) {
1021
+ if (file.status === "skipped") {
1022
+ switch (file.skipReason) {
1023
+ case "missing-name":
1024
+ skippedMissingName++;
1025
+ break;
1026
+ case "missing-description":
1027
+ skippedMissingDescription++;
1028
+ break;
1029
+ case "duplicate-name":
1030
+ skippedDuplicateName++;
1031
+ break;
1032
+ case "name-mismatch":
1033
+ skippedNameMismatch++;
1034
+ break;
1035
+ case "parse-error":
1036
+ skippedParseFailed++;
1037
+ break;
1038
+ }
1039
+ }
1040
+ }
1041
+ const totalSkillsFound = files.filter(f => f.status === "loaded" && f.promptPath.name).length;
1042
+ this.telemetryService.publicLog2("agentSkillsFound", {
1043
+ totalSkillsFound,
1044
+ claudePersonal: skillsBySource.get(PromptFileSource.ClaudePersonal) ?? 0,
1045
+ claudeWorkspace: skillsBySource.get(PromptFileSource.ClaudeWorkspace) ?? 0,
1046
+ copilotPersonal: skillsBySource.get(PromptFileSource.CopilotPersonal) ?? 0,
1047
+ githubWorkspace: skillsBySource.get(PromptFileSource.GitHubWorkspace) ?? 0,
1048
+ agentsPersonal: skillsBySource.get(PromptFileSource.AgentsPersonal) ?? 0,
1049
+ agentsWorkspace: skillsBySource.get(PromptFileSource.AgentsWorkspace) ?? 0,
1050
+ configWorkspace: skillsBySource.get(PromptFileSource.ConfigWorkspace) ?? 0,
1051
+ configPersonal: skillsBySource.get(PromptFileSource.ConfigPersonal) ?? 0,
1052
+ extensionContribution: skillsBySource.get(PromptFileSource.ExtensionContribution) ?? 0,
1053
+ extensionAPI: skillsBySource.get(PromptFileSource.ExtensionAPI) ?? 0,
1054
+ plugin: skillsBySource.get(PromptFileSource.Plugin) ?? 0,
1055
+ skippedDuplicateName,
1056
+ skippedMissingName,
1057
+ skippedMissingDescription,
1058
+ skippedNameMismatch,
1059
+ skippedParseFailed
1060
+ });
1061
+ return {
1062
+ type: PromptsType.skill,
1063
+ files,
1064
+ sourceFolders,
1065
+ durationInMillis: stopWatch.elapsed()
1066
+ };
1067
+ }
1068
+ async getHooks(token) {
1069
+ const discoveryInfo = await this.cachedHooks.get(token);
1070
+ const result = discoveryInfo.hooksInfo;
1071
+ return result;
1072
+ }
1073
+ async getDiscoveryInfo(type, token) {
1074
+ switch (type) {
1075
+ case PromptsType.instructions:
1076
+ return this.cachedInstructions.get(token);
1077
+ case PromptsType.prompt:
1078
+ return this.cachedSlashCommands.get(token);
1079
+ case PromptsType.agent:
1080
+ return this.cachedCustomAgents.get(token);
1081
+ case PromptsType.skill:
1082
+ return this.cachedSkills.get(token);
1083
+ case PromptsType.hook:
1084
+ return this.cachedHooks.get(token);
1085
+ }
1086
+ }
1087
+ async getInstructionFiles(token) {
1088
+ const discoveryInfo = await this.cachedInstructions.get(token);
1089
+ const result = this.instructionsFromDiscoveryInfo(discoveryInfo);
1090
+ return result;
1091
+ }
1092
+ instructionsFromDiscoveryInfo(discoveryInfo) {
1093
+ const result = [];
1094
+ for (const file of discoveryInfo.files) {
1095
+ if (file.status === "loaded" && file.promptPath.name) {
1096
+ result.push({
1097
+ uri: file.promptPath.uri,
1098
+ storage: file.promptPath.storage,
1099
+ extension: file.promptPath.extension,
1100
+ pluginUri: file.promptPath.pluginUri,
1101
+ source: file.promptPath.source,
1102
+ name: file.promptPath.name,
1103
+ description: file.promptPath.description,
1104
+ pattern: file.pattern,
1105
+ sessionTypes: file.promptPath.sessionTypes
1106
+ });
1107
+ }
1108
+ }
1109
+ return result;
1110
+ }
1111
+ withPromptPathMetadata(promptPath, name, description) {
1112
+ return {
1113
+ ...promptPath,
1114
+ name,
1115
+ description
1116
+ };
1117
+ }
1118
+ async computeInstructionFiles(token) {
1119
+ return await this.getInstructionsDiscoveryInfo(token);
1120
+ }
1121
+ async computeHooks(token) {
1122
+ const stopWatch = StopWatch.create(true);
1123
+ const useChatHooks = this.configurationService.getValue(PromptsConfig.USE_CHAT_HOOKS);
1124
+ if (!useChatHooks || !this.workspaceTrustService.isWorkspaceTrusted()) {
1125
+ const hookFiles = await this.listPromptFiles(PromptsType.hook, token);
1126
+ const skipReason = !useChatHooks ? "disabled" : "workspace-untrusted";
1127
+ const files = ( hookFiles.map(promptPath => ({
1128
+ status: "skipped",
1129
+ skipReason,
1130
+ promptPath: this.withPromptPathMetadata(promptPath, basename(promptPath.uri), promptPath.description)
1131
+ })));
1132
+ const sourceFolders = await this._collectSourceFolderDiagnostics(PromptsType.hook);
1133
+ return {
1134
+ type: PromptsType.hook,
1135
+ files,
1136
+ sourceFolders,
1137
+ hooksInfo: undefined,
1138
+ durationInMillis: stopWatch.elapsed()
1139
+ };
1140
+ }
1141
+ const useClaudeHooks = this.configurationService.getValue(PromptsConfig.USE_CLAUDE_HOOKS);
1142
+ const hookFiles = await this.listPromptFiles(PromptsType.hook, token);
1143
+ this.logger.trace(`[PromptsService] Found ${hookFiles.length} hook file(s).`);
1144
+ const userHomeUri = await this.pathService.userHome();
1145
+ const userHome = userHomeUri.scheme === Schemas.file ? userHomeUri.fsPath : userHomeUri.path;
1146
+ const defaultFolder = this.workspaceService.getWorkspace().folders[0];
1147
+ const fileResults = await Promise.all(( hookFiles.map(hookFile => this.queueDiscoveryRead(async () => {
1148
+ const name = basename(hookFile.uri);
1149
+ if (hookFile.storage === PromptsStorage.plugin) {
1150
+ return {
1151
+ file: {
1152
+ status: "loaded",
1153
+ promptPath: this.withPromptPathMetadata(hookFile, name, hookFile.description)
1154
+ }
1155
+ };
1156
+ }
1157
+ try {
1158
+ const content = await this.fileService.readFile(hookFile.uri);
1159
+ const parseErrors = [];
1160
+ const json = parse(( content.value.toString()), parseErrors);
1161
+ if (parseErrors.length > 0) {
1162
+ const first = parseErrors[0];
1163
+ const message = getParseErrorMessage(first.error) || "Invalid JSON";
1164
+ return {
1165
+ file: {
1166
+ status: "skipped",
1167
+ skipReason: "parse-error",
1168
+ errorMessage: `${message} at offset ${first.offset}`,
1169
+ promptPath: this.withPromptPathMetadata(hookFile, name, hookFile.description)
1170
+ }
1171
+ };
1172
+ }
1173
+ if (!json || typeof json !== "object") {
1174
+ return {
1175
+ file: {
1176
+ status: "skipped",
1177
+ skipReason: "parse-error",
1178
+ errorMessage: "Invalid hooks file: must be a JSON object",
1179
+ promptPath: this.withPromptPathMetadata(hookFile, name, hookFile.description)
1180
+ }
1181
+ };
1182
+ }
1183
+ const hookWorkspaceFolder = this.workspaceService.getWorkspaceFolder(hookFile.uri) ?? defaultFolder;
1184
+ const workspaceRootUri = hookWorkspaceFolder?.uri;
1185
+ const {
1186
+ format,
1187
+ hooks: parsedHooks,
1188
+ disabledAllHooks
1189
+ } = parseHooksFromFile(hookFile.uri, json, workspaceRootUri, userHome);
1190
+ if (disabledAllHooks) {
1191
+ this.logger.trace(
1192
+ `[PromptsService] Skipping hook file with disableAllHooks: ${hookFile.uri}`
1193
+ );
1194
+ return {
1195
+ file: {
1196
+ status: "skipped",
1197
+ skipReason: "all-hooks-disabled",
1198
+ promptPath: this.withPromptPathMetadata(hookFile, name, hookFile.description)
1199
+ }
1200
+ };
1201
+ }
1202
+ if (format === HookSourceFormat.Claude && useClaudeHooks === false) {
1203
+ const hasAnyCommands = ( [...( parsedHooks.values())].some((
1204
+ {
1205
+ hooks: cmds
1206
+ }
1207
+ ) => cmds.length > 0));
1208
+ this.logger.trace(
1209
+ `[PromptsService] Skipping Claude hook file (disabled via setting): ${hookFile.uri}`
1210
+ );
1211
+ return {
1212
+ file: {
1213
+ status: "skipped",
1214
+ skipReason: "claude-hooks-disabled",
1215
+ promptPath: this.withPromptPathMetadata(hookFile, name, hookFile.description)
1216
+ },
1217
+ hasDisabledClaudeHooks: hasAnyCommands
1218
+ };
1219
+ }
1220
+ const hooks = ( new Map());
1221
+ for (const [hookType, {
1222
+ hooks: commands
1223
+ }] of parsedHooks) {
1224
+ for (const command of commands) {
1225
+ let bucket = hooks.get(hookType);
1226
+ if (!bucket) {
1227
+ bucket = [];
1228
+ hooks.set(hookType, bucket);
1229
+ }
1230
+ bucket.push(command);
1231
+ this.logger.trace(
1232
+ `[PromptsService] Collected ${hookType} hook from ${hookFile.uri} (format: ${format})`
1233
+ );
1234
+ }
1235
+ }
1236
+ return {
1237
+ file: {
1238
+ status: "loaded",
1239
+ promptPath: this.withPromptPathMetadata(hookFile, name, hookFile.description)
1240
+ },
1241
+ hooks,
1242
+ sourceUri: hookFile.uri
1243
+ };
1244
+ } catch (error) {
1245
+ const msg = error instanceof Error ? error.message : String(error);
1246
+ this.logger.warn(`[PromptsService] Failed to parse hook file: ${hookFile.uri}`, error);
1247
+ return {
1248
+ file: {
1249
+ status: "skipped",
1250
+ skipReason: "parse-error",
1251
+ errorMessage: msg,
1252
+ promptPath: this.withPromptPathMetadata(hookFile, name, hookFile.description)
1253
+ }
1254
+ };
1255
+ }
1256
+ }))));
1257
+ const files = [];
1258
+ let hasDisabledClaudeHooks = false;
1259
+ const collectedHooks = ( new Map());
1260
+ for (const {
1261
+ file,
1262
+ hooks,
1263
+ sourceUri,
1264
+ hasDisabledClaudeHooks: disabled
1265
+ } of fileResults) {
1266
+ if (file) {
1267
+ files.push(file);
1268
+ }
1269
+ if (disabled) {
1270
+ hasDisabledClaudeHooks = true;
1271
+ }
1272
+ if (hooks && sourceUri) {
1273
+ for (const [hookType, commands] of hooks) {
1274
+ let bucket = collectedHooks.get(hookType);
1275
+ if (!bucket) {
1276
+ bucket = [];
1277
+ collectedHooks.set(hookType, bucket);
1278
+ }
1279
+ for (const command of commands) {
1280
+ bucket.push({
1281
+ ...command,
1282
+ sourceUri
1283
+ });
1284
+ }
1285
+ }
1286
+ }
1287
+ }
1288
+ const plugins = this.agentPluginService.plugins.get();
1289
+ const managedHooksOnlyValue = this.configurationService.getValue(COPILOT_ALLOW_MANAGED_HOOKS_ONLY_CONFIG) === true;
1290
+ const enabledPluginsPolicyValue = this.configurationService.inspect(ChatConfiguration.EnabledPlugins).policyValue;
1291
+ for (const plugin of plugins) {
1292
+ if (!isContributionEnabled(plugin.enablement.get()) || (managedHooksOnlyValue && !isAgentPluginForceEnabledByPolicy(plugin, enabledPluginsPolicyValue))) {
1293
+ continue;
1294
+ }
1295
+ for (const hook of plugin.hooks.get()) {
1296
+ let bucket = collectedHooks.get(hook.type);
1297
+ if (!bucket) {
1298
+ bucket = [];
1299
+ collectedHooks.set(hook.type, bucket);
1300
+ }
1301
+ for (const command of hook.hooks) {
1302
+ bucket.push({
1303
+ ...command,
1304
+ sourceUri: hook.uri
1305
+ });
1306
+ }
1307
+ }
1308
+ }
1309
+ const sourceFolders = await this._collectSourceFolderDiagnostics(PromptsType.hook);
1310
+ if (collectedHooks.size === 0) {
1311
+ this.logger.trace("[PromptsService] No valid hooks collected.");
1312
+ return {
1313
+ type: PromptsType.hook,
1314
+ files,
1315
+ sourceFolders,
1316
+ hooksInfo: undefined,
1317
+ durationInMillis: stopWatch.elapsed()
1318
+ };
1319
+ }
1320
+ const result = Object.fromEntries(collectedHooks);
1321
+ this.logger.trace(`[PromptsService] Collected hooks: ${JSON.stringify(( Object.keys(result)))}`);
1322
+ return {
1323
+ type: PromptsType.hook,
1324
+ files,
1325
+ sourceFolders,
1326
+ hooksInfo: {
1327
+ hooks: result,
1328
+ hasDisabledClaudeHooks
1329
+ },
1330
+ durationInMillis: stopWatch.elapsed()
1331
+ };
1332
+ }
1333
+ getSkillPriority(skill) {
1334
+ if (skill.storage === PromptsStorage.local) {
1335
+ return 0;
1336
+ }
1337
+ if (skill.storage === PromptsStorage.user) {
1338
+ return 1;
1339
+ }
1340
+ if (skill.storage === PromptsStorage.plugin) {
1341
+ return 2;
1342
+ }
1343
+ if (skill.source === PromptFileSource.ExtensionAPI) {
1344
+ return 3;
1345
+ }
1346
+ if (skill.source === PromptFileSource.ExtensionContribution) {
1347
+ return 4;
1348
+ }
1349
+ return 5;
1350
+ }
1351
+ async computeSkillDiscoveryInfo(token) {
1352
+ const files = [];
1353
+ const seenNames = ( new Set());
1354
+ const nameToUri = ( new Map());
1355
+ const allSkills = [];
1356
+ const standaloneSkills = this.areStandalonePromptFilesBlocked(PromptsType.skill) ? [] : await this.fileLocator.findAgentSkills(token);
1357
+ const skills = await Promise.all([
1358
+ Promise.resolve(standaloneSkills),
1359
+ this.getExtensionPromptFiles(PromptsType.skill, token),
1360
+ Promise.resolve(this._pluginPromptFilesByType.get(PromptsType.skill) ?? []),
1361
+ this.getBuiltinPromptFiles(PromptsType.skill, token)
1362
+ ]);
1363
+ for (const skillList of skills) {
1364
+ allSkills.push(...skillList);
1365
+ }
1366
+ allSkills.sort((a, b) => this.getSkillPriority(a) - this.getSkillPriority(b));
1367
+ for (const skill of allSkills) {
1368
+ const uri = skill.uri;
1369
+ const promptPath = skill;
1370
+ try {
1371
+ const parsedFile = await this.parseNew(uri, token);
1372
+ const folderName = getSkillFolderName(uri);
1373
+ let name = parsedFile.header?.name;
1374
+ const description = parsedFile.header?.description;
1375
+ if (!name) {
1376
+ this.logger.debug(
1377
+ `[computeSkillDiscoveryInfo] Agent skill file missing name attribute, using folder name "${folderName}": ${uri}`
1378
+ );
1379
+ name = folderName;
1380
+ }
1381
+ let sanitizedName = this.truncateAgentSkillName(name, uri);
1382
+ if (sanitizedName !== folderName) {
1383
+ this.logger.debug(
1384
+ `[computeSkillDiscoveryInfo] Agent skill name "${sanitizedName}" does not match folder name "${folderName}", using folder name: ${uri}`
1385
+ );
1386
+ sanitizedName = folderName;
1387
+ }
1388
+ if (( seenNames.has(sanitizedName))) {
1389
+ this.logger.debug(
1390
+ `[computeSkillDiscoveryInfo] Skipping duplicate agent skill name: ${sanitizedName} at ${uri}`
1391
+ );
1392
+ files.push({
1393
+ status: "skipped",
1394
+ skipReason: "duplicate-name",
1395
+ duplicateOf: nameToUri.get(sanitizedName),
1396
+ promptPath: this.withPromptPathMetadata(promptPath, sanitizedName, description)
1397
+ });
1398
+ continue;
1399
+ }
1400
+ seenNames.add(sanitizedName);
1401
+ nameToUri.set(sanitizedName, uri);
1402
+ const disableModelInvocation = parsedFile.header?.disableModelInvocation === true;
1403
+ const userInvocable = parsedFile.header?.userInvocable !== false;
1404
+ files.push({
1405
+ status: "loaded",
1406
+ promptPath: this.withPromptPathMetadata(promptPath, sanitizedName, description),
1407
+ disableModelInvocation,
1408
+ userInvocable
1409
+ });
1410
+ } catch (e) {
1411
+ const msg = e instanceof Error ? e.message : String(e);
1412
+ this.logger.error(
1413
+ `[computeSkillDiscoveryInfo] Failed to validate Agent skill file: ${uri}`,
1414
+ msg
1415
+ );
1416
+ files.push({
1417
+ status: "skipped",
1418
+ skipReason: "parse-error",
1419
+ errorMessage: msg,
1420
+ promptPath
1421
+ });
1422
+ }
1423
+ }
1424
+ return files;
1425
+ }
1426
+ async getInstructionsDiscoveryInfo(token) {
1427
+ const stopWatch = StopWatch.create(true);
1428
+ const files = [];
1429
+ const instructionsFiles = await this.listPromptFiles(PromptsType.instructions, token);
1430
+ for (const promptPath of instructionsFiles) {
1431
+ const uri = promptPath.uri;
1432
+ try {
1433
+ const parsedPromptFile = await this.parseNew(uri, token);
1434
+ const name = parsedPromptFile?.header?.name ?? promptPath.name ?? getCleanPromptName(uri);
1435
+ const description = parsedPromptFile?.header?.description ?? promptPath.description;
1436
+ const pattern = evaluateApplyToPattern(parsedPromptFile.header, isInClaudeRulesFolder(uri));
1437
+ files.push({
1438
+ status: "loaded",
1439
+ pattern,
1440
+ promptPath: this.withPromptPathMetadata(promptPath, name, description)
1441
+ });
1442
+ } catch (e) {
1443
+ files.push({
1444
+ status: "skipped",
1445
+ skipReason: "parse-error",
1446
+ errorMessage: e instanceof Error ? e.message : String(e),
1447
+ promptPath
1448
+ });
1449
+ }
1450
+ }
1451
+ const sourceFolders = await this._collectSourceFolderDiagnostics(PromptsType.instructions);
1452
+ return {
1453
+ type: PromptsType.instructions,
1454
+ files,
1455
+ sourceFolders,
1456
+ durationInMillis: stopWatch.elapsed()
1457
+ };
1458
+ }
1459
+ };
1460
+ PromptsService = ( __decorate([( __param(0, ILogService)), ( __param(1, ILabelService)), ( __param(2, IModelService)), ( __param(3, IInstantiationService)), ( __param(4, IUserDataProfileService)), ( __param(5, IConfigurationService)), ( __param(6, IFileService)), ( __param(7, IStorageService)), ( __param(8, ITelemetryService)), ( __param(9, IWorkspaceContextService)), ( __param(10, IPathService)), ( __param(11, IAgentPluginService)), ( __param(12, IWorkspaceTrustManagementService))], PromptsService));
1461
+ class CachedPromise extends Disposable {
1462
+ constructor(computeFn, getEvent, delay = 0) {
1463
+ super();
1464
+ this.computeFn = computeFn;
1465
+ this.getEvent = getEvent;
1466
+ this.delay = delay;
1467
+ this.cachedPromise = undefined;
1468
+ this.cachedPool = undefined;
1469
+ this.onDidUpdatePromiseEmitter = this._register(( new Emitter()));
1470
+ const delayer = this._register(( new Delayer(this.delay)));
1471
+ this._register(this.getEvent()(() => {
1472
+ this.cachedPromise = undefined;
1473
+ delayer.trigger(() => this.onDidUpdatePromiseEmitter.fire());
1474
+ }));
1475
+ }
1476
+ get onDidChangePromise() {
1477
+ return this.onDidUpdatePromiseEmitter.event;
1478
+ }
1479
+ get(token) {
1480
+ if (this.cachedPool?.token.isCancellationRequested) {
1481
+ this.cachedPromise = undefined;
1482
+ this.cachedPool = undefined;
1483
+ }
1484
+ let pool = this.cachedPool;
1485
+ if (this.cachedPromise === undefined) {
1486
+ pool = ( new CancellationTokenPool());
1487
+ const promise = this.computeFn(pool.token).catch(err => {
1488
+ if (this.cachedPromise === promise) {
1489
+ this.cachedPromise = undefined;
1490
+ }
1491
+ throw err;
1492
+ });
1493
+ const disposePool = () => {
1494
+ if (this.cachedPool === pool) {
1495
+ this.cachedPool = undefined;
1496
+ }
1497
+ pool.dispose();
1498
+ };
1499
+ promise.then(disposePool, disposePool);
1500
+ this.cachedPromise = promise;
1501
+ this.cachedPool = pool;
1502
+ }
1503
+ pool?.add(token);
1504
+ return raceCancellationError(this.cachedPromise, token);
1505
+ }
1506
+ refresh() {
1507
+ this.cachedPromise = undefined;
1508
+ this.onDidUpdatePromiseEmitter?.fire();
1509
+ }
1510
+ }
1511
+ class ModelChangeTracker extends Disposable {
1512
+ get onDidPromptChange() {
1513
+ return this.onDidPromptModelChange.event;
1514
+ }
1515
+ constructor(modelService) {
1516
+ super();
1517
+ this.listeners = ( new ResourceMap());
1518
+ this.onDidPromptModelChange = this._register(( new Emitter()));
1519
+ const onAdd = model => {
1520
+ const promptType = getPromptsTypeForLanguageId(model.getLanguageId());
1521
+ if (promptType !== undefined) {
1522
+ this.listeners.set(
1523
+ model.uri,
1524
+ model.onDidChangeContent(() => this.onDidPromptModelChange.fire({
1525
+ uri: model.uri,
1526
+ promptType
1527
+ }))
1528
+ );
1529
+ }
1530
+ return promptType;
1531
+ };
1532
+ const onRemove = (languageId, uri) => {
1533
+ const promptType = getPromptsTypeForLanguageId(languageId);
1534
+ if (promptType !== undefined) {
1535
+ this.listeners.get(uri)?.dispose();
1536
+ this.listeners.delete(uri);
1537
+ }
1538
+ return promptType;
1539
+ };
1540
+ this._register(modelService.onModelAdded(model => onAdd(model)));
1541
+ this._register(modelService.onModelLanguageChanged(e => {
1542
+ const removedPromptType = onRemove(e.oldLanguageId, e.model.uri);
1543
+ const addedPromptType = onAdd(e.model);
1544
+ if (removedPromptType !== addedPromptType) {
1545
+ if (removedPromptType) {
1546
+ this.onDidPromptModelChange.fire({
1547
+ uri: e.model.uri,
1548
+ promptType: removedPromptType
1549
+ });
1550
+ }
1551
+ if (addedPromptType) {
1552
+ this.onDidPromptModelChange.fire({
1553
+ uri: e.model.uri,
1554
+ promptType: addedPromptType
1555
+ });
1556
+ }
1557
+ }
1558
+ }));
1559
+ this._register(
1560
+ modelService.onModelRemoved(model => onRemove(model.getLanguageId(), model.uri))
1561
+ );
1562
+ }
1563
+ dispose() {
1564
+ super.dispose();
1565
+ this.listeners.forEach(listener => listener.dispose());
1566
+ this.listeners.clear();
1567
+ }
1568
+ }
1569
+ var CustomAgent;
1570
+ (function(CustomAgent) {
1571
+ function fromParsedPromptFile(ast, extra) {
1572
+ const uri = ast.uri;
1573
+ const {
1574
+ hooks,
1575
+ sessionTypes,
1576
+ enabled
1577
+ } = extra;
1578
+ let metadata;
1579
+ if (ast.header) {
1580
+ const advanced = ast.header.getAttribute(PromptHeaderAttributes.advancedOptions);
1581
+ if (advanced && advanced.value.type === "map") {
1582
+ metadata = {};
1583
+ for (const [key, value] of Object.entries(advanced.value)) {
1584
+ if (value.type === "scalar") {
1585
+ metadata[key] = value;
1586
+ }
1587
+ }
1588
+ }
1589
+ }
1590
+ const toolReferences = [];
1591
+ if (ast.body) {
1592
+ const bodyOffset = ast.body.offset;
1593
+ const bodyVarRefs = ast.body.variableReferences;
1594
+ for (let i = bodyVarRefs.length - 1; i >= 0; i--) {
1595
+ const {
1596
+ name,
1597
+ offset,
1598
+ fullLength
1599
+ } = bodyVarRefs[i];
1600
+ const range = ( new OffsetRange(offset - bodyOffset, offset - bodyOffset + fullLength));
1601
+ toolReferences.push({
1602
+ name,
1603
+ range
1604
+ });
1605
+ }
1606
+ }
1607
+ const agentInstructions = {
1608
+ content: ast.body?.getContent() ?? "",
1609
+ toolReferences,
1610
+ metadata
1611
+ };
1612
+ const name = ast.header?.name ?? extra.name ?? getCleanPromptName(uri);
1613
+ const description = ast.header?.description ?? extra.description;
1614
+ const target = getTarget(PromptsType.agent, ast.header ?? uri);
1615
+ const id = ( uri.toString());
1616
+ const source = extra.source;
1617
+ if (!ast.header) {
1618
+ return {
1619
+ id,
1620
+ uri,
1621
+ name,
1622
+ agentInstructions,
1623
+ source,
1624
+ target,
1625
+ visibility: {
1626
+ userInvocable: true,
1627
+ agentInvocable: true
1628
+ },
1629
+ sessionTypes,
1630
+ hooks,
1631
+ enabled
1632
+ };
1633
+ }
1634
+ const visibility = {
1635
+ userInvocable: ast.header.userInvocable !== false,
1636
+ agentInvocable: ast.header.infer !== undefined ? ast.header.infer === true : ast.header.disableModelInvocation !== true
1637
+ };
1638
+ let model = ast.header.model;
1639
+ if (target === Target.Claude && model) {
1640
+ model = mapClaudeModels(model);
1641
+ }
1642
+ let {
1643
+ tools,
1644
+ handOffs,
1645
+ argumentHint,
1646
+ agents
1647
+ } = ast.header;
1648
+ if (target === Target.Claude && tools) {
1649
+ tools = mapClaudeTools(tools);
1650
+ }
1651
+ return {
1652
+ id,
1653
+ uri,
1654
+ name,
1655
+ description,
1656
+ model,
1657
+ tools,
1658
+ handOffs,
1659
+ argumentHint,
1660
+ target,
1661
+ visibility,
1662
+ agents,
1663
+ agentInstructions,
1664
+ source,
1665
+ sessionTypes,
1666
+ hooks,
1667
+ enabled
1668
+ };
1669
+ }
1670
+ CustomAgent.fromParsedPromptFile = fromParsedPromptFile;
1671
+ })(CustomAgent || (CustomAgent = {}));
1672
+
1673
+ export { CustomAgent, PromptsService };