@theia/ai-ide 1.75.0-next.8 → 1.75.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 (509) hide show
  1. package/lib/browser/ai-allow-all-mode-chat-banner.js +2 -20
  2. package/lib/browser/ai-allow-all-mode-chat-banner.js.map +1 -1
  3. package/lib/browser/ai-configuration/agent-icon.d.ts +16 -0
  4. package/lib/browser/ai-configuration/agent-icon.d.ts.map +1 -0
  5. package/lib/browser/ai-configuration/agent-icon.js +38 -0
  6. package/lib/browser/ai-configuration/agent-icon.js.map +1 -0
  7. package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.d.ts +36 -0
  8. package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.d.ts.map +1 -0
  9. package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.js +163 -0
  10. package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.js.map +1 -0
  11. package/lib/browser/ai-configuration/ai-configuration-detail-widget.d.ts +50 -0
  12. package/lib/browser/ai-configuration/ai-configuration-detail-widget.d.ts.map +1 -0
  13. package/lib/browser/ai-configuration/ai-configuration-detail-widget.js +208 -0
  14. package/lib/browser/ai-configuration/ai-configuration-detail-widget.js.map +1 -0
  15. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.d.ts +2 -0
  16. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.d.ts.map +1 -0
  17. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.js +139 -0
  18. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.js.map +1 -0
  19. package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.d.ts +13 -0
  20. package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.d.ts.map +1 -0
  21. package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.js +48 -0
  22. package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.js.map +1 -0
  23. package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.d.ts +22 -0
  24. package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.d.ts.map +1 -0
  25. package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.js +72 -0
  26. package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.js.map +1 -0
  27. package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.d.ts +2 -0
  28. package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.d.ts.map +1 -0
  29. package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.js +126 -0
  30. package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.js.map +1 -0
  31. package/lib/browser/ai-configuration/ai-configuration-resource.d.ts +10 -0
  32. package/lib/browser/ai-configuration/ai-configuration-resource.d.ts.map +1 -0
  33. package/lib/browser/ai-configuration/{components/configuration-section.js → ai-configuration-resource.js} +11 -11
  34. package/lib/browser/ai-configuration/ai-configuration-resource.js.map +1 -0
  35. package/lib/browser/ai-configuration/ai-configuration-search-widget.d.ts +29 -0
  36. package/lib/browser/ai-configuration/ai-configuration-search-widget.d.ts.map +1 -0
  37. package/lib/browser/ai-configuration/ai-configuration-search-widget.js +106 -0
  38. package/lib/browser/ai-configuration/ai-configuration-search-widget.js.map +1 -0
  39. package/lib/browser/ai-configuration/ai-configuration-search.d.ts +18 -0
  40. package/lib/browser/ai-configuration/ai-configuration-search.d.ts.map +1 -0
  41. package/lib/browser/ai-configuration/ai-configuration-search.js +45 -0
  42. package/lib/browser/ai-configuration/ai-configuration-search.js.map +1 -0
  43. package/lib/browser/ai-configuration/ai-configuration-search.spec.d.ts +2 -0
  44. package/lib/browser/ai-configuration/ai-configuration-search.spec.d.ts.map +1 -0
  45. package/lib/browser/ai-configuration/ai-configuration-search.spec.js +79 -0
  46. package/lib/browser/ai-configuration/ai-configuration-search.spec.js.map +1 -0
  47. package/lib/browser/ai-configuration/ai-configuration-tree-model.d.ts +8 -0
  48. package/lib/browser/ai-configuration/ai-configuration-tree-model.d.ts.map +1 -0
  49. package/lib/browser/ai-configuration/{base/ai-configuration-base-widget.js → ai-configuration-tree-model.js} +11 -14
  50. package/lib/browser/ai-configuration/ai-configuration-tree-model.js.map +1 -0
  51. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.d.ts +57 -0
  52. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.d.ts.map +1 -0
  53. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.js +134 -0
  54. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.js.map +1 -0
  55. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.d.ts +2 -0
  56. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.d.ts.map +1 -0
  57. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.js +134 -0
  58. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.js.map +1 -0
  59. package/lib/browser/ai-configuration/ai-configuration-tree-widget.d.ts +96 -0
  60. package/lib/browser/ai-configuration/ai-configuration-tree-widget.d.ts.map +1 -0
  61. package/lib/browser/ai-configuration/ai-configuration-tree-widget.js +407 -0
  62. package/lib/browser/ai-configuration/ai-configuration-tree-widget.js.map +1 -0
  63. package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts +38 -4
  64. package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts.map +1 -1
  65. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js +151 -19
  66. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js.map +1 -1
  67. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts +21 -23
  68. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts.map +1 -1
  69. package/lib/browser/ai-configuration/ai-configuration-widget.js +102 -70
  70. package/lib/browser/ai-configuration/ai-configuration-widget.js.map +1 -1
  71. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.d.ts +56 -0
  72. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.d.ts.map +1 -0
  73. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.js +195 -0
  74. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.js.map +1 -0
  75. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.d.ts +2 -0
  76. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.d.ts.map +1 -0
  77. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.js +140 -0
  78. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.js.map +1 -0
  79. package/lib/browser/ai-configuration/categories/agent-chips.d.ts +15 -0
  80. package/lib/browser/ai-configuration/categories/agent-chips.d.ts.map +1 -0
  81. package/lib/browser/ai-configuration/categories/agent-chips.js +19 -0
  82. package/lib/browser/ai-configuration/categories/agent-chips.js.map +1 -0
  83. package/lib/browser/ai-configuration/categories/agent-detail-model.d.ts +37 -0
  84. package/lib/browser/ai-configuration/categories/agent-detail-model.d.ts.map +1 -0
  85. package/lib/browser/ai-configuration/categories/agent-detail-model.js +99 -0
  86. package/lib/browser/ai-configuration/categories/agent-detail-model.js.map +1 -0
  87. package/lib/browser/ai-configuration/categories/agent-detail-view.d.ts +28 -0
  88. package/lib/browser/ai-configuration/categories/agent-detail-view.d.ts.map +1 -0
  89. package/lib/browser/ai-configuration/categories/agent-detail-view.js +135 -0
  90. package/lib/browser/ai-configuration/categories/agent-detail-view.js.map +1 -0
  91. package/lib/browser/ai-configuration/categories/agents-configuration-category.d.ts +78 -0
  92. package/lib/browser/ai-configuration/categories/agents-configuration-category.d.ts.map +1 -0
  93. package/lib/browser/ai-configuration/categories/agents-configuration-category.js +352 -0
  94. package/lib/browser/ai-configuration/categories/agents-configuration-category.js.map +1 -0
  95. package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.d.ts +2 -0
  96. package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.d.ts.map +1 -0
  97. package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.js +99 -0
  98. package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.js.map +1 -0
  99. package/lib/browser/ai-configuration/categories/general-configuration-category.d.ts +93 -0
  100. package/lib/browser/ai-configuration/categories/general-configuration-category.d.ts.map +1 -0
  101. package/lib/browser/ai-configuration/categories/general-configuration-category.js +313 -0
  102. package/lib/browser/ai-configuration/categories/general-configuration-category.js.map +1 -0
  103. package/lib/browser/ai-configuration/categories/general-configuration-category.spec.d.ts +2 -0
  104. package/lib/browser/ai-configuration/categories/general-configuration-category.spec.d.ts.map +1 -0
  105. package/lib/browser/ai-configuration/categories/general-configuration-category.spec.js +213 -0
  106. package/lib/browser/ai-configuration/categories/general-configuration-category.spec.js.map +1 -0
  107. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.d.ts +53 -0
  108. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.d.ts.map +1 -0
  109. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.js +241 -0
  110. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.js.map +1 -0
  111. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.d.ts +2 -0
  112. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.d.ts.map +1 -0
  113. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.js +75 -0
  114. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.js.map +1 -0
  115. package/lib/browser/ai-configuration/categories/models-configuration-category.d.ts +72 -0
  116. package/lib/browser/ai-configuration/categories/models-configuration-category.d.ts.map +1 -0
  117. package/lib/browser/ai-configuration/categories/models-configuration-category.js +227 -0
  118. package/lib/browser/ai-configuration/categories/models-configuration-category.js.map +1 -0
  119. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.d.ts +2 -0
  120. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.d.ts.map +1 -0
  121. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.js +145 -0
  122. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.js.map +1 -0
  123. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.d.ts +114 -0
  124. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.d.ts.map +1 -0
  125. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.js +341 -0
  126. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.js.map +1 -0
  127. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.d.ts +2 -0
  128. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.d.ts.map +1 -0
  129. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.js +199 -0
  130. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.js.map +1 -0
  131. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.d.ts +84 -0
  132. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.d.ts.map +1 -0
  133. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.js +341 -0
  134. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.js.map +1 -0
  135. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.d.ts +2 -0
  136. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.d.ts.map +1 -0
  137. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.js +184 -0
  138. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.js.map +1 -0
  139. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.d.ts +38 -0
  140. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.d.ts.map +1 -0
  141. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.js +130 -0
  142. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.js.map +1 -0
  143. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.d.ts +2 -0
  144. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.d.ts.map +1 -0
  145. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.js +51 -0
  146. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.js.map +1 -0
  147. package/lib/browser/ai-configuration/categories/tools-configuration-category.d.ts +60 -0
  148. package/lib/browser/ai-configuration/categories/tools-configuration-category.d.ts.map +1 -0
  149. package/lib/browser/ai-configuration/categories/tools-configuration-category.js +302 -0
  150. package/lib/browser/ai-configuration/categories/tools-configuration-category.js.map +1 -0
  151. package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.d.ts +2 -0
  152. package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.d.ts.map +1 -0
  153. package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.js +111 -0
  154. package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.js.map +1 -0
  155. package/lib/browser/ai-configuration/categories/variables-configuration-category.d.ts +72 -0
  156. package/lib/browser/ai-configuration/categories/variables-configuration-category.d.ts.map +1 -0
  157. package/lib/browser/ai-configuration/categories/variables-configuration-category.js +245 -0
  158. package/lib/browser/ai-configuration/categories/variables-configuration-category.js.map +1 -0
  159. package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.d.ts +2 -0
  160. package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.d.ts.map +1 -0
  161. package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.js +131 -0
  162. package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.js.map +1 -0
  163. package/lib/browser/ai-configuration/components/agent-notification-settings.d.ts +6 -2
  164. package/lib/browser/ai-configuration/components/agent-notification-settings.d.ts.map +1 -1
  165. package/lib/browser/ai-configuration/components/agent-notification-settings.js +15 -21
  166. package/lib/browser/ai-configuration/components/agent-notification-settings.js.map +1 -1
  167. package/lib/browser/ai-configuration/language-model-renderer.d.ts +25 -1
  168. package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +1 -1
  169. package/lib/browser/ai-configuration/language-model-renderer.js +159 -63
  170. package/lib/browser/ai-configuration/language-model-renderer.js.map +1 -1
  171. package/lib/browser/ai-configuration/language-model-renderer.spec.d.ts +2 -0
  172. package/lib/browser/ai-configuration/language-model-renderer.spec.d.ts.map +1 -0
  173. package/lib/browser/ai-configuration/language-model-renderer.spec.js +93 -0
  174. package/lib/browser/ai-configuration/language-model-renderer.spec.js.map +1 -0
  175. package/lib/browser/ai-sessions-widget.js +12 -16
  176. package/lib/browser/ai-sessions-widget.js.map +1 -1
  177. package/lib/browser/app-tester-chat-agent.d.ts +2 -0
  178. package/lib/browser/app-tester-chat-agent.d.ts.map +1 -1
  179. package/lib/browser/app-tester-chat-agent.js +5 -0
  180. package/lib/browser/app-tester-chat-agent.js.map +1 -1
  181. package/lib/browser/architect-agent.d.ts +2 -0
  182. package/lib/browser/architect-agent.d.ts.map +1 -1
  183. package/lib/browser/architect-agent.js +5 -0
  184. package/lib/browser/architect-agent.js.map +1 -1
  185. package/lib/browser/architect-prompt-template.d.ts.map +1 -1
  186. package/lib/browser/architect-prompt-template.js +7 -0
  187. package/lib/browser/architect-prompt-template.js.map +1 -1
  188. package/lib/browser/chat-session-item.d.ts.map +1 -1
  189. package/lib/browser/chat-session-item.js +17 -30
  190. package/lib/browser/chat-session-item.js.map +1 -1
  191. package/lib/browser/chat-session-list-components.js +7 -30
  192. package/lib/browser/chat-session-list-components.js.map +1 -1
  193. package/lib/browser/chat-session-list-service.d.ts +2 -1
  194. package/lib/browser/chat-session-list-service.d.ts.map +1 -1
  195. package/lib/browser/chat-session-list-service.js +6 -1
  196. package/lib/browser/chat-session-list-service.js.map +1 -1
  197. package/lib/browser/chat-sessions-welcome-message-provider.js +3 -21
  198. package/lib/browser/chat-sessions-welcome-message-provider.js.map +1 -1
  199. package/lib/browser/code-reviewer-agent.d.ts +2 -0
  200. package/lib/browser/code-reviewer-agent.d.ts.map +1 -1
  201. package/lib/browser/code-reviewer-agent.js +5 -0
  202. package/lib/browser/code-reviewer-agent.js.map +1 -1
  203. package/lib/browser/coder-agent.d.ts +2 -0
  204. package/lib/browser/coder-agent.d.ts.map +1 -1
  205. package/lib/browser/coder-agent.js +6 -1
  206. package/lib/browser/coder-agent.js.map +1 -1
  207. package/lib/browser/context-file-validation-service-impl.spec.js +2 -0
  208. package/lib/browser/context-file-validation-service-impl.spec.js.map +1 -1
  209. package/lib/browser/create-skill-agent.d.ts +2 -0
  210. package/lib/browser/create-skill-agent.d.ts.map +1 -1
  211. package/lib/browser/create-skill-agent.js +5 -0
  212. package/lib/browser/create-skill-agent.js.map +1 -1
  213. package/lib/browser/explore-agent.d.ts +2 -0
  214. package/lib/browser/explore-agent.d.ts.map +1 -1
  215. package/lib/browser/explore-agent.js +5 -0
  216. package/lib/browser/explore-agent.js.map +1 -1
  217. package/lib/browser/file-changeset-functions.d.ts +7 -1
  218. package/lib/browser/file-changeset-functions.d.ts.map +1 -1
  219. package/lib/browser/file-changeset-functions.js +62 -20
  220. package/lib/browser/file-changeset-functions.js.map +1 -1
  221. package/lib/browser/file-changeset-functions.spec.js +130 -1
  222. package/lib/browser/file-changeset-functions.spec.js.map +1 -1
  223. package/lib/browser/frontend-module.d.ts.map +1 -1
  224. package/lib/browser/frontend-module.js +65 -59
  225. package/lib/browser/frontend-module.js.map +1 -1
  226. package/lib/browser/github-chat-agent.d.ts +2 -1
  227. package/lib/browser/github-chat-agent.d.ts.map +1 -1
  228. package/lib/browser/github-chat-agent.js +5 -0
  229. package/lib/browser/github-chat-agent.js.map +1 -1
  230. package/lib/browser/github-repo-variable-contribution.d.ts +2 -1
  231. package/lib/browser/github-repo-variable-contribution.d.ts.map +1 -1
  232. package/lib/browser/github-repo-variable-contribution.js +6 -1
  233. package/lib/browser/github-repo-variable-contribution.js.map +1 -1
  234. package/lib/browser/ide-chat-welcome-message-provider.d.ts.map +1 -1
  235. package/lib/browser/ide-chat-welcome-message-provider.js +31 -118
  236. package/lib/browser/ide-chat-welcome-message-provider.js.map +1 -1
  237. package/lib/browser/memory-capability-contribution.d.ts +8 -0
  238. package/lib/browser/memory-capability-contribution.d.ts.map +1 -0
  239. package/lib/browser/memory-capability-contribution.js +88 -0
  240. package/lib/browser/memory-capability-contribution.js.map +1 -0
  241. package/lib/browser/memory-capability-contribution.spec.d.ts +2 -0
  242. package/lib/browser/memory-capability-contribution.spec.d.ts.map +1 -0
  243. package/lib/browser/memory-capability-contribution.spec.js +74 -0
  244. package/lib/browser/memory-capability-contribution.spec.js.map +1 -0
  245. package/lib/browser/memory-directory-variable-contribution.d.ts +41 -0
  246. package/lib/browser/memory-directory-variable-contribution.d.ts.map +1 -0
  247. package/lib/browser/memory-directory-variable-contribution.js +107 -0
  248. package/lib/browser/memory-directory-variable-contribution.js.map +1 -0
  249. package/lib/browser/memory-directory-variable-contribution.spec.d.ts +2 -0
  250. package/lib/browser/memory-directory-variable-contribution.spec.d.ts.map +1 -0
  251. package/lib/browser/memory-directory-variable-contribution.spec.js +98 -0
  252. package/lib/browser/memory-directory-variable-contribution.spec.js.map +1 -0
  253. package/lib/browser/open-editors-hint-contribution.d.ts +7 -0
  254. package/lib/browser/open-editors-hint-contribution.d.ts.map +1 -0
  255. package/lib/browser/open-editors-hint-contribution.js +43 -0
  256. package/lib/browser/open-editors-hint-contribution.js.map +1 -0
  257. package/lib/browser/project-info-agent.d.ts +2 -0
  258. package/lib/browser/project-info-agent.d.ts.map +1 -1
  259. package/lib/browser/project-info-agent.js +5 -0
  260. package/lib/browser/project-info-agent.js.map +1 -1
  261. package/lib/browser/review/pr-review-agent.d.ts +2 -0
  262. package/lib/browser/review/pr-review-agent.d.ts.map +1 -1
  263. package/lib/browser/review/pr-review-agent.js +5 -0
  264. package/lib/browser/review/pr-review-agent.js.map +1 -1
  265. package/lib/browser/summarize-session-command-contribution.d.ts +2 -1
  266. package/lib/browser/summarize-session-command-contribution.d.ts.map +1 -1
  267. package/lib/browser/summarize-session-command-contribution.js +6 -1
  268. package/lib/browser/summarize-session-command-contribution.js.map +1 -1
  269. package/lib/browser/task-context-file-storage-service.d.ts.map +1 -1
  270. package/lib/browser/task-context-file-storage-service.js +1 -0
  271. package/lib/browser/task-context-file-storage-service.js.map +1 -1
  272. package/lib/browser/todo-tool-renderer.js +11 -19
  273. package/lib/browser/todo-tool-renderer.js.map +1 -1
  274. package/lib/browser/user-interaction-tool-renderer.js +39 -83
  275. package/lib/browser/user-interaction-tool-renderer.js.map +1 -1
  276. package/lib/browser/user-interaction-tool.d.ts +2 -0
  277. package/lib/browser/user-interaction-tool.d.ts.map +1 -1
  278. package/lib/browser/user-interaction-tool.js +7 -1
  279. package/lib/browser/user-interaction-tool.js.map +1 -1
  280. package/lib/browser/user-interaction-tool.spec.js +4 -2
  281. package/lib/browser/user-interaction-tool.spec.js.map +1 -1
  282. package/lib/browser/workspace-functions.d.ts +45 -7
  283. package/lib/browser/workspace-functions.d.ts.map +1 -1
  284. package/lib/browser/workspace-functions.js +108 -70
  285. package/lib/browser/workspace-functions.js.map +1 -1
  286. package/lib/browser/workspace-functions.spec.js +139 -9
  287. package/lib/browser/workspace-functions.spec.js.map +1 -1
  288. package/lib/browser/workspace-launch-provider.spec.js +3 -0
  289. package/lib/browser/workspace-launch-provider.spec.js.map +1 -1
  290. package/lib/browser/workspace-search-provider.d.ts.map +1 -1
  291. package/lib/browser/workspace-search-provider.js +4 -7
  292. package/lib/browser/workspace-search-provider.js.map +1 -1
  293. package/lib/browser/workspace-search-provider.spec.js +1 -2
  294. package/lib/browser/workspace-search-provider.spec.js.map +1 -1
  295. package/lib/browser/workspace-task-provider.spec.js +4 -0
  296. package/lib/browser/workspace-task-provider.spec.js.map +1 -1
  297. package/lib/common/coder-replace-prompt-template.d.ts +0 -2
  298. package/lib/common/coder-replace-prompt-template.d.ts.map +1 -1
  299. package/lib/common/coder-replace-prompt-template.js +10 -11
  300. package/lib/common/coder-replace-prompt-template.js.map +1 -1
  301. package/lib/common/command-chat-agents.d.ts +2 -1
  302. package/lib/common/command-chat-agents.d.ts.map +1 -1
  303. package/lib/common/command-chat-agents.js +6 -1
  304. package/lib/common/command-chat-agents.js.map +1 -1
  305. package/lib/common/open-editors-hint-fragment-id.d.ts +2 -0
  306. package/lib/common/open-editors-hint-fragment-id.d.ts.map +1 -0
  307. package/lib/{browser/ai-configuration/components/empty-state.js → common/open-editors-hint-fragment-id.js} +5 -11
  308. package/lib/common/open-editors-hint-fragment-id.js.map +1 -0
  309. package/lib/common/orchestrator-chat-agent.d.ts +2 -1
  310. package/lib/common/orchestrator-chat-agent.d.ts.map +1 -1
  311. package/lib/common/orchestrator-chat-agent.js +5 -0
  312. package/lib/common/orchestrator-chat-agent.js.map +1 -1
  313. package/lib/common/universal-chat-agent.d.ts +2 -0
  314. package/lib/common/universal-chat-agent.d.ts.map +1 -1
  315. package/lib/common/universal-chat-agent.js +5 -0
  316. package/lib/common/universal-chat-agent.js.map +1 -1
  317. package/lib/common/universal-prompt-template.d.ts.map +1 -1
  318. package/lib/common/universal-prompt-template.js +3 -0
  319. package/lib/common/universal-prompt-template.js.map +1 -1
  320. package/lib/common/workspace-preferences.js +2 -2
  321. package/lib/common/workspace-preferences.js.map +1 -1
  322. package/lib/common/workspace-search-provider-util.d.ts +2 -1
  323. package/lib/common/workspace-search-provider-util.d.ts.map +1 -1
  324. package/lib/common/workspace-search-provider-util.js +3 -2
  325. package/lib/common/workspace-search-provider-util.js.map +1 -1
  326. package/lib/common/workspace-search-provider-util.spec.d.ts +2 -0
  327. package/lib/common/workspace-search-provider-util.spec.d.ts.map +1 -0
  328. package/lib/common/workspace-search-provider-util.spec.js +55 -0
  329. package/lib/common/workspace-search-provider-util.spec.js.map +1 -0
  330. package/lib/node/github-repo-service-impl.d.ts +2 -0
  331. package/lib/node/github-repo-service-impl.d.ts.map +1 -1
  332. package/lib/node/github-repo-service-impl.js +7 -1
  333. package/lib/node/github-repo-service-impl.js.map +1 -1
  334. package/package.json +26 -25
  335. package/src/browser/ai-configuration/agent-icon.ts +37 -0
  336. package/src/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.ts +164 -0
  337. package/src/browser/ai-configuration/ai-configuration-detail-widget.spec.ts +165 -0
  338. package/src/browser/ai-configuration/ai-configuration-detail-widget.tsx +237 -0
  339. package/src/browser/ai-configuration/ai-configuration-label-provider-contribution.ts +47 -0
  340. package/src/browser/ai-configuration/ai-configuration-open-preference-renderer.ts +64 -0
  341. package/src/browser/ai-configuration/ai-configuration-preference-ownership.spec.ts +135 -0
  342. package/src/browser/ai-configuration/{components/configuration-section.tsx → ai-configuration-resource.ts} +9 -19
  343. package/src/browser/ai-configuration/ai-configuration-search-widget.tsx +135 -0
  344. package/src/browser/ai-configuration/ai-configuration-search.spec.ts +91 -0
  345. package/src/browser/ai-configuration/ai-configuration-search.ts +43 -0
  346. package/src/browser/ai-configuration/{components/empty-state.tsx → ai-configuration-tree-model.ts} +7 -11
  347. package/src/browser/ai-configuration/ai-configuration-tree-nodes.spec.ts +150 -0
  348. package/src/browser/ai-configuration/ai-configuration-tree-nodes.ts +167 -0
  349. package/src/browser/ai-configuration/ai-configuration-tree-widget.tsx +457 -0
  350. package/src/browser/ai-configuration/ai-configuration-view-contribution.ts +156 -18
  351. package/src/browser/ai-configuration/ai-configuration-widget.tsx +107 -75
  352. package/src/browser/ai-configuration/categories/agent-capabilities-settings.spec.ts +161 -0
  353. package/src/browser/ai-configuration/categories/agent-capabilities-settings.tsx +340 -0
  354. package/src/browser/ai-configuration/categories/agent-chips.tsx +51 -0
  355. package/src/browser/ai-configuration/categories/agent-detail-model.ts +152 -0
  356. package/src/browser/ai-configuration/categories/agent-detail-view.tsx +329 -0
  357. package/src/browser/ai-configuration/categories/agents-configuration-category.spec.ts +119 -0
  358. package/src/browser/ai-configuration/categories/agents-configuration-category.tsx +431 -0
  359. package/src/browser/ai-configuration/categories/general-configuration-category.spec.ts +225 -0
  360. package/src/browser/ai-configuration/categories/general-configuration-category.tsx +465 -0
  361. package/src/browser/ai-configuration/categories/model-aliases-configuration-category.spec.ts +87 -0
  362. package/src/browser/ai-configuration/categories/model-aliases-configuration-category.tsx +286 -0
  363. package/src/browser/ai-configuration/categories/models-configuration-category.spec.ts +167 -0
  364. package/src/browser/ai-configuration/categories/models-configuration-category.tsx +264 -0
  365. package/src/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.ts +250 -0
  366. package/src/browser/ai-configuration/categories/prompt-snippets-configuration-category.tsx +438 -0
  367. package/src/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.ts +226 -0
  368. package/src/browser/ai-configuration/categories/prompts-and-skills-configuration-category.tsx +419 -0
  369. package/src/browser/ai-configuration/categories/token-usage-configuration-category.spec.ts +57 -0
  370. package/src/browser/ai-configuration/categories/token-usage-configuration-category.tsx +185 -0
  371. package/src/browser/ai-configuration/categories/tools-configuration-category.spec.ts +130 -0
  372. package/src/browser/ai-configuration/categories/tools-configuration-category.tsx +421 -0
  373. package/src/browser/ai-configuration/categories/variables-configuration-category.spec.ts +154 -0
  374. package/src/browser/ai-configuration/categories/variables-configuration-category.tsx +322 -0
  375. package/src/browser/ai-configuration/components/agent-notification-settings.tsx +38 -33
  376. package/src/browser/ai-configuration/language-model-renderer.spec.ts +100 -0
  377. package/src/browser/ai-configuration/language-model-renderer.tsx +244 -100
  378. package/src/browser/app-tester-chat-agent.ts +5 -2
  379. package/src/browser/architect-agent.ts +5 -2
  380. package/src/browser/architect-prompt-template.ts +7 -0
  381. package/src/browser/chat-session-item.tsx +2 -4
  382. package/src/browser/chat-session-list-service.ts +6 -3
  383. package/src/browser/code-reviewer-agent.ts +5 -2
  384. package/src/browser/coder-agent.ts +7 -5
  385. package/src/browser/context-file-validation-service-impl.spec.ts +3 -2
  386. package/src/browser/create-skill-agent.ts +5 -2
  387. package/src/browser/explore-agent.ts +5 -2
  388. package/src/browser/file-changeset-functions.spec.ts +158 -5
  389. package/src/browser/file-changeset-functions.ts +61 -23
  390. package/src/browser/frontend-module.ts +76 -63
  391. package/src/browser/github-chat-agent.ts +5 -2
  392. package/src/browser/github-repo-variable-contribution.ts +6 -3
  393. package/src/browser/ide-chat-welcome-message-provider.tsx +11 -11
  394. package/src/browser/memory-capability-contribution.spec.ts +85 -0
  395. package/src/browser/memory-capability-contribution.ts +86 -0
  396. package/src/browser/memory-directory-variable-contribution.spec.ts +113 -0
  397. package/src/browser/memory-directory-variable-contribution.ts +113 -0
  398. package/src/browser/open-editors-hint-contribution.ts +38 -0
  399. package/src/browser/project-info-agent.ts +5 -2
  400. package/src/browser/review/pr-review-agent.ts +5 -2
  401. package/src/browser/style/ai-configuration-base.css +0 -6
  402. package/src/browser/style/ai-configuration-shell.css +416 -0
  403. package/src/browser/style/ai-configuration-table.css +2 -15
  404. package/src/browser/style/index.css +220 -276
  405. package/src/browser/summarize-session-command-contribution.ts +6 -3
  406. package/src/browser/task-context-file-storage-service.ts +5 -2
  407. package/src/browser/user-interaction-tool.spec.ts +5 -2
  408. package/src/browser/user-interaction-tool.ts +6 -2
  409. package/src/browser/workspace-functions.spec.ts +163 -10
  410. package/src/browser/workspace-functions.ts +121 -72
  411. package/src/browser/workspace-launch-provider.spec.ts +4 -1
  412. package/src/browser/workspace-search-provider.spec.ts +1 -2
  413. package/src/browser/workspace-search-provider.ts +4 -7
  414. package/src/browser/workspace-task-provider.spec.ts +5 -1
  415. package/src/common/coder-replace-prompt-template.ts +9 -9
  416. package/src/common/command-chat-agents.ts +6 -2
  417. package/src/{browser/ai-configuration/base/ai-configuration-base-widget.tsx → common/open-editors-hint-fragment-id.ts} +2 -22
  418. package/src/common/orchestrator-chat-agent.ts +5 -2
  419. package/src/common/universal-chat-agent.ts +5 -2
  420. package/src/common/universal-prompt-template.ts +3 -0
  421. package/src/common/workspace-preferences.ts +2 -2
  422. package/src/common/workspace-search-provider-util.spec.ts +61 -0
  423. package/src/common/workspace-search-provider-util.ts +3 -2
  424. package/src/node/github-repo-service-impl.ts +6 -2
  425. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts +0 -72
  426. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +0 -1
  427. package/lib/browser/ai-configuration/agent-configuration-widget.js +0 -620
  428. package/lib/browser/ai-configuration/agent-configuration-widget.js.map +0 -1
  429. package/lib/browser/ai-configuration/agent-configuration-widget.spec.d.ts +0 -2
  430. package/lib/browser/ai-configuration/agent-configuration-widget.spec.d.ts.map +0 -1
  431. package/lib/browser/ai-configuration/agent-configuration-widget.spec.js +0 -56
  432. package/lib/browser/ai-configuration/agent-configuration-widget.spec.js.map +0 -1
  433. package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.d.ts +0 -31
  434. package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.d.ts.map +0 -1
  435. package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.js +0 -55
  436. package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.js.map +0 -1
  437. package/lib/browser/ai-configuration/base/ai-configuration-base-widget.d.ts +0 -13
  438. package/lib/browser/ai-configuration/base/ai-configuration-base-widget.d.ts.map +0 -1
  439. package/lib/browser/ai-configuration/base/ai-configuration-base-widget.js.map +0 -1
  440. package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.d.ts +0 -23
  441. package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.d.ts.map +0 -1
  442. package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.js +0 -60
  443. package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.js.map +0 -1
  444. package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.d.ts +0 -55
  445. package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.d.ts.map +0 -1
  446. package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.js +0 -96
  447. package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.js.map +0 -1
  448. package/lib/browser/ai-configuration/base/ai-table-configuration-widget.d.ts +0 -44
  449. package/lib/browser/ai-configuration/base/ai-table-configuration-widget.d.ts.map +0 -1
  450. package/lib/browser/ai-configuration/base/ai-table-configuration-widget.js +0 -66
  451. package/lib/browser/ai-configuration/base/ai-table-configuration-widget.js.map +0 -1
  452. package/lib/browser/ai-configuration/components/configuration-section.d.ts +0 -12
  453. package/lib/browser/ai-configuration/components/configuration-section.d.ts.map +0 -1
  454. package/lib/browser/ai-configuration/components/configuration-section.js.map +0 -1
  455. package/lib/browser/ai-configuration/components/empty-state.d.ts +0 -10
  456. package/lib/browser/ai-configuration/components/empty-state.d.ts.map +0 -1
  457. package/lib/browser/ai-configuration/components/empty-state.js.map +0 -1
  458. package/lib/browser/ai-configuration/components/expandable-section.d.ts +0 -13
  459. package/lib/browser/ai-configuration/components/expandable-section.d.ts.map +0 -1
  460. package/lib/browser/ai-configuration/components/expandable-section.js +0 -31
  461. package/lib/browser/ai-configuration/components/expandable-section.js.map +0 -1
  462. package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts +0 -26
  463. package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts.map +0 -1
  464. package/lib/browser/ai-configuration/model-aliases-configuration-widget.js +0 -198
  465. package/lib/browser/ai-configuration/model-aliases-configuration-widget.js.map +0 -1
  466. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts +0 -140
  467. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts.map +0 -1
  468. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js +0 -508
  469. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js.map +0 -1
  470. package/lib/browser/ai-configuration/skills-configuration-widget.d.ts +0 -29
  471. package/lib/browser/ai-configuration/skills-configuration-widget.d.ts.map +0 -1
  472. package/lib/browser/ai-configuration/skills-configuration-widget.js +0 -166
  473. package/lib/browser/ai-configuration/skills-configuration-widget.js.map +0 -1
  474. package/lib/browser/ai-configuration/skills-configuration-widget.spec.d.ts +0 -2
  475. package/lib/browser/ai-configuration/skills-configuration-widget.spec.d.ts.map +0 -1
  476. package/lib/browser/ai-configuration/skills-configuration-widget.spec.js +0 -191
  477. package/lib/browser/ai-configuration/skills-configuration-widget.spec.js.map +0 -1
  478. package/lib/browser/ai-configuration/template-settings-renderer.d.ts +0 -9
  479. package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +0 -1
  480. package/lib/browser/ai-configuration/template-settings-renderer.js +0 -78
  481. package/lib/browser/ai-configuration/template-settings-renderer.js.map +0 -1
  482. package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts +0 -20
  483. package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts.map +0 -1
  484. package/lib/browser/ai-configuration/token-usage-configuration-widget.js +0 -170
  485. package/lib/browser/ai-configuration/token-usage-configuration-widget.js.map +0 -1
  486. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts +0 -52
  487. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts.map +0 -1
  488. package/lib/browser/ai-configuration/tools-configuration-widget.js +0 -357
  489. package/lib/browser/ai-configuration/tools-configuration-widget.js.map +0 -1
  490. package/lib/browser/ai-configuration/variable-configuration-widget.d.ts +0 -22
  491. package/lib/browser/ai-configuration/variable-configuration-widget.d.ts.map +0 -1
  492. package/lib/browser/ai-configuration/variable-configuration-widget.js +0 -133
  493. package/lib/browser/ai-configuration/variable-configuration-widget.js.map +0 -1
  494. package/src/browser/ai-configuration/agent-configuration-widget.spec.ts +0 -71
  495. package/src/browser/ai-configuration/agent-configuration-widget.tsx +0 -928
  496. package/src/browser/ai-configuration/base/ai-card-grid-configuration-widget.tsx +0 -72
  497. package/src/browser/ai-configuration/base/ai-hierarchical-configuration-widget.tsx +0 -51
  498. package/src/browser/ai-configuration/base/ai-list-detail-configuration-widget.tsx +0 -140
  499. package/src/browser/ai-configuration/base/ai-table-configuration-widget.tsx +0 -107
  500. package/src/browser/ai-configuration/components/expandable-section.tsx +0 -51
  501. package/src/browser/ai-configuration/model-aliases-configuration-widget.tsx +0 -270
  502. package/src/browser/ai-configuration/prompt-fragments-configuration-widget.tsx +0 -736
  503. package/src/browser/ai-configuration/skills-configuration-widget.spec.ts +0 -248
  504. package/src/browser/ai-configuration/skills-configuration-widget.tsx +0 -229
  505. package/src/browser/ai-configuration/template-settings-renderer.tsx +0 -125
  506. package/src/browser/ai-configuration/token-usage-configuration-widget.tsx +0 -214
  507. package/src/browser/ai-configuration/tools-configuration-widget.tsx +0 -544
  508. package/src/browser/ai-configuration/variable-configuration-widget.tsx +0 -159
  509. package/src/browser/style/ai-configuration-cards.css +0 -60
@@ -0,0 +1,438 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { Agent, AgentService } from '@theia/ai-core';
18
+ import { CAPABILITY_TYPE_PROMPT_MAP, parseCapabilitiesFromTemplate } from '@theia/ai-core/lib/common';
19
+ import { isCustomizedPromptFragment, PromptFragment, PromptService } from '@theia/ai-core/lib/common/prompt-service';
20
+ import { Emitter, Event, nls } from '@theia/core';
21
+ import { codicon, ConfirmDialog } from '@theia/core/lib/browser';
22
+ import { DisposableCollection } from '@theia/core/lib/common';
23
+ import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
24
+ import * as React from '@theia/core/shared/react';
25
+ import {
26
+ AiConfigurationCategory,
27
+ AiConfigurationCategoryId,
28
+ AiConfigurationCategoryOrder,
29
+ AiConfigurationRenderContext,
30
+ AiConfigurationSearchItem,
31
+ AiConfigurationSearchProvider,
32
+ AiConfigurationSelection
33
+ } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
34
+ import { SinglePageCategoryRenderer } from '@theia/ai-core-ui/lib/browser/ai-configuration/renderers/single-page-category-renderer';
35
+ import {
36
+ CollapsibleGroup,
37
+ CollapsibleList,
38
+ CollapsibleRow,
39
+ CollapsibleRowAction
40
+ } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/collapsible-list';
41
+ import { PromptCustomizationDialogs } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/prompt-customization-dialogs';
42
+ import { AiConfigurationCallout } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-configuration-primitives';
43
+ import { AgentChips } from './agent-chips';
44
+
45
+ /**
46
+ * Fragments generated per running MCP server, named after `McpFrontendService.getPromptTemplateId`.
47
+ * Excluded from this page: they are rebuilt from the live tool list whenever a server starts, so a
48
+ * customization would silently diverge from the tools the server actually offers. The generated tool
49
+ * list is visible on the MCP Servers page instead.
50
+ */
51
+ const MCP_TOOL_LIST_FRAGMENT_PATTERN = /^mcp_.+_tools$/;
52
+
53
+ /** Which group a fragment belongs to, in the order the page renders them. */
54
+ export type PromptSnippetKind = 'snippet' | 'capability' | 'generic-capability';
55
+
56
+ /** One prompt fragment as this page shows it, resolved from the prompt service on load. */
57
+ export interface PromptSnippetEntry {
58
+ readonly id: string;
59
+ readonly kind: PromptSnippetKind;
60
+ /** Frontmatter `name`, when the fragment declares one. */
61
+ readonly name?: string;
62
+ /** Frontmatter `description`, when the fragment declares one. */
63
+ readonly description?: string;
64
+ /** A customization currently overrides (or, without a built-in, provides) the text. */
65
+ readonly customized: boolean;
66
+ /** `false` for a fragment that exists only as a user/workspace file, where reset has nothing to fall back to. */
67
+ readonly hasBuiltIn: boolean;
68
+ /** Agents whose selected prompt references this fragment as a capability; empty for plain snippets. */
69
+ readonly agentIds: string[];
70
+ }
71
+
72
+ export namespace PromptSnippetsConfiguration {
73
+ /**
74
+ * Prefix of the `data-ai-config-row-id` of every row on this page, regardless of its group, so that
75
+ * a deep link only needs the fragment id (an agent's capability list, for instance, does not know
76
+ * whether a fragment ends up under Capabilities or Generic Capabilities).
77
+ */
78
+ export const ROW_ID_PREFIX = 'fragment:';
79
+
80
+ /** Navigation target that scrolls to and flashes `fragmentId`'s row on this page. */
81
+ export function selectionFor(fragmentId: string): AiConfigurationSelection {
82
+ return {
83
+ categoryId: AiConfigurationCategoryId.PROMPT_SNIPPETS,
84
+ highlight: { rowId: ROW_ID_PREFIX + fragmentId }
85
+ };
86
+ }
87
+ }
88
+
89
+ /**
90
+ * The "Prompt Snippets" category: every prompt fragment that has no other home in this view, as a
91
+ * filterable list of expandable rows in three groups — user-authored snippets, agent capabilities and
92
+ * generic capabilities. Prompt variant sets live in the agent detail, skills and slash commands on the
93
+ * Skills page, so those are filtered out here; what remains would otherwise be uneditable, which is
94
+ * what this page fixes.
95
+ *
96
+ * Capability fragments are global: editing one affects every agent that references it, which is why
97
+ * each row lists the agents using it rather than pretending the text belongs to one of them.
98
+ */
99
+ @injectable()
100
+ export class PromptSnippetsConfigurationCategory extends SinglePageCategoryRenderer implements AiConfigurationCategory, AiConfigurationSearchProvider {
101
+
102
+ readonly id = AiConfigurationCategoryId.PROMPT_SNIPPETS;
103
+ readonly label = nls.localize('theia/ai/ide/promptSnippetsConfiguration/label', 'Prompt Snippets');
104
+ readonly description = nls.localize('theia/ai/ide/promptSnippetsConfiguration/description',
105
+ 'Reusable prompt text: your own snippets plus the capability snippets agents pull in. Editing a snippet affects every agent that uses it.');
106
+ readonly iconClass = codicon('file-code');
107
+ readonly order = AiConfigurationCategoryOrder.PROMPT_SNIPPETS;
108
+ readonly kind = 'single-page' as const;
109
+
110
+ @inject(PromptService)
111
+ protected readonly promptService: PromptService;
112
+
113
+ @inject(AgentService)
114
+ protected readonly agentService: AgentService;
115
+
116
+ protected readonly onDidChangeEmitter = new Emitter<void>();
117
+ readonly onDidChange: Event<void> = this.onDidChangeEmitter.event;
118
+ protected readonly toDispose = new DisposableCollection(this.onDidChangeEmitter);
119
+
120
+ protected entries: PromptSnippetEntry[] = [];
121
+ protected availableAgents: Agent[] = [];
122
+
123
+ get renderer(): this {
124
+ return this;
125
+ }
126
+
127
+ get search(): AiConfigurationSearchProvider {
128
+ return this;
129
+ }
130
+
131
+ @postConstruct()
132
+ protected init(): void {
133
+ this.reload();
134
+ this.toDispose.pushAll([
135
+ this.promptService.onPromptsChange(() => {
136
+ this.reload();
137
+ this.onDidChangeEmitter.fire();
138
+ }),
139
+ this.agentService.onDidChangeAgents(() => {
140
+ this.reload();
141
+ this.onDidChangeEmitter.fire();
142
+ })
143
+ ]);
144
+ }
145
+
146
+ dispose(): void {
147
+ this.toDispose.dispose();
148
+ }
149
+
150
+ protected reload(): void {
151
+ this.availableAgents = this.agentService.getAllAgents();
152
+ this.entries = this.loadEntries();
153
+ }
154
+
155
+ /**
156
+ * Classifies every registered fragment, dropping those another part of the view already owns.
157
+ * Grouped by {@link PromptSnippetKind} and sorted by display name within each group.
158
+ */
159
+ protected loadEntries(): PromptSnippetEntry[] {
160
+ const capabilityAgents = this.collectCapabilityReferences();
161
+ const genericCapabilityIds = new Set(CAPABILITY_TYPE_PROMPT_MAP.map(({ promptId }) => promptId));
162
+ const ownedElsewhere = this.collectFragmentIdsOwnedElsewhere();
163
+ const entries: PromptSnippetEntry[] = [];
164
+ for (const [id, fragments] of this.promptService.getAllPromptFragments()) {
165
+ if (ownedElsewhere.has(id) || MCP_TOOL_LIST_FRAGMENT_PATTERN.test(id)) {
166
+ continue;
167
+ }
168
+ const effective = this.promptService.getRawPromptFragment(id) ?? fragments[0];
169
+ // Slash commands (including the synthetic ones backing a skill) belong to the Skills page. Checking
170
+ // every fragment, not just the effective one, keeps a command hidden here even if a customization
171
+ // drops the `isCommand` frontmatter.
172
+ if (!effective || fragments.some(fragment => fragment.isCommand)) {
173
+ continue;
174
+ }
175
+ const agentIds = capabilityAgents.get(id) ?? [];
176
+ entries.push({
177
+ id,
178
+ kind: this.classify(id, effective, genericCapabilityIds, agentIds.length > 0),
179
+ name: effective.name,
180
+ description: effective.description,
181
+ customized: fragments.some(fragment => isCustomizedPromptFragment(fragment)),
182
+ hasBuiltIn: fragments.some(fragment => !isCustomizedPromptFragment(fragment)),
183
+ agentIds
184
+ });
185
+ }
186
+ return entries.sort((left, right) => this.displayName(left).localeCompare(this.displayName(right)));
187
+ }
188
+
189
+ /**
190
+ * A fragment is a *generic* capability when it is one of the fixed set the chat dropdowns inject
191
+ * (`CAPABILITY_TYPE_PROMPT_MAP` is that single source of truth), and a *capability* when an agent
192
+ * references it as `{{capability:id}}`. Declared frontmatter is accepted as a fallback so that a
193
+ * capability shipped by an extension still groups correctly before any agent template pulls it in.
194
+ */
195
+ protected classify(id: string, fragment: PromptFragment, genericCapabilityIds: Set<string>, referencedByAgent: boolean): PromptSnippetKind {
196
+ if (genericCapabilityIds.has(id)) {
197
+ return 'generic-capability';
198
+ }
199
+ if (referencedByAgent || fragment.name !== undefined || fragment.description !== undefined) {
200
+ return 'capability';
201
+ }
202
+ return 'snippet';
203
+ }
204
+
205
+ /**
206
+ * Maps capability fragment id -> ids of the agents referencing it. Mirrors the agent detail page,
207
+ * which parses `{{capability:...}}` out of each agent's selected prompt, so both agree on what
208
+ * counts as a capability. Uses the globally effective variant to stay synchronous; the agent detail
209
+ * additionally honours that agent's own variant selection.
210
+ */
211
+ protected collectCapabilityReferences(): Map<string, string[]> {
212
+ const references = new Map<string, string[]>();
213
+ for (const agent of this.availableAgents) {
214
+ for (const prompt of agent.prompts) {
215
+ const variantId = this.promptService.getEffectiveVariantId(prompt.id) ?? prompt.id;
216
+ const template = this.promptService.getRawPromptFragment(variantId)?.template;
217
+ if (!template) {
218
+ continue;
219
+ }
220
+ for (const capability of parseCapabilitiesFromTemplate(template)) {
221
+ const agents = references.get(capability.fragmentId) ?? [];
222
+ if (!agents.includes(agent.id)) {
223
+ agents.push(agent.id);
224
+ }
225
+ references.set(capability.fragmentId, agents);
226
+ }
227
+ }
228
+ }
229
+ return references;
230
+ }
231
+
232
+ /**
233
+ * Fragment ids another part of the view is responsible for: the prompt variant sets and their
234
+ * variants, which the agent detail owns as the single source of truth.
235
+ */
236
+ protected collectFragmentIdsOwnedElsewhere(): Set<string> {
237
+ const owned = new Set<string>();
238
+ for (const [variantSetId, variantIds] of this.promptService.getPromptVariantSets()) {
239
+ owned.add(variantSetId);
240
+ variantIds.forEach(variantId => owned.add(variantId));
241
+ }
242
+ return owned;
243
+ }
244
+
245
+ protected displayName(entry: PromptSnippetEntry): string {
246
+ return entry.name ?? entry.id;
247
+ }
248
+
249
+ protected renderSections(ctx: AiConfigurationRenderContext): React.ReactNode {
250
+ const onOpenAgent = (agentId: string): void => ctx.navigate({ categoryId: AiConfigurationCategoryId.AGENTS, itemId: agentId });
251
+ const groups: CollapsibleGroup[] = [
252
+ {
253
+ id: 'snippets',
254
+ title: nls.localizeByDefault('Snippets'),
255
+ description: nls.localize('theia/ai/ide/promptSnippetsConfiguration/snippetsGroupDescription',
256
+ 'Prompt text you maintain yourself, referenced from other prompts with {{prompt:id}}.'),
257
+ rows: this.buildRows('snippet', ctx, onOpenAgent)
258
+ },
259
+ {
260
+ id: 'capabilities',
261
+ title: nls.localizeByDefault('Capabilities'),
262
+ description: nls.localize('theia/ai/ide/promptSnippetsConfiguration/capabilitiesGroupDescription',
263
+ 'Instructions an agent adds to its prompt when enabled. They are shared, so an edit affects every agent using them.'),
264
+ rows: this.buildRows('capability', ctx, onOpenAgent)
265
+ },
266
+ {
267
+ id: 'generic-capabilities',
268
+ title: nls.localize('theia/ai/ide/promptSnippetsConfiguration/genericCapabilitiesGroup', 'Generic Capabilities'),
269
+ description: nls.localize('theia/ai/ide/promptSnippetsConfiguration/genericCapabilitiesGroupDescription',
270
+ 'Basic instructions to integrate the selected capabilities into the agent\'s prompt. They are shared, so an edit affects every agent using them.'),
271
+ rows: this.buildRows('generic-capability', ctx, onOpenAgent)
272
+ }
273
+ ];
274
+ return <>
275
+ {this.renderResetAllCallout(ctx)}
276
+ <CollapsibleList
277
+ groups={groups}
278
+ filterPlaceholder={nls.localize('theia/ai/ide/promptSnippetsConfiguration/filterPlaceholder', 'Filter prompt snippets by name, id or description')}
279
+ emptyMessage={nls.localize('theia/ai/ide/promptSnippetsConfiguration/empty', 'No prompt snippets are available.')}
280
+ filterEmptyMessage={query => nls.localize('theia/ai/ide/promptSnippetsConfiguration/noMatches', 'No prompt snippets match "{0}".', query)}
281
+ />
282
+ </>;
283
+ }
284
+
285
+ /**
286
+ * Page-level reset, as the prompt fragments page it replaces had. Shown only while something is
287
+ * customized, and explicit that it reverts *every* customization — including the agents' prompt
288
+ * variants, which live on their own pages.
289
+ */
290
+ protected renderResetAllCallout(ctx: AiConfigurationRenderContext): React.ReactNode {
291
+ if (!this.hasResettableCustomizations()) {
292
+ return undefined;
293
+ }
294
+ return <AiConfigurationCallout
295
+ message={nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetAllMessage',
296
+ 'Some prompt fragments are customized. Resetting reverts every one of them to its built-in version, '
297
+ + 'including the agents\' prompt templates. Snippets that have no built-in version are kept.')}
298
+ action={<button className='theia-button secondary' onClick={() => this.resetAllCustomizations(ctx)}>
299
+ {nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetAll', 'Reset All Customizations')}
300
+ </button>}
301
+ />;
302
+ }
303
+
304
+ /**
305
+ * Whether anything would actually be reset. Deliberately not limited to this page's entries: the action
306
+ * reverts every customized fragment that has a built-in, which includes the agents' prompt templates
307
+ * (listed on their own pages), so gating on the rows here would hide it exactly when it is needed.
308
+ */
309
+ protected hasResettableCustomizations(): boolean {
310
+ for (const fragments of this.promptService.getAllPromptFragments().values()) {
311
+ if (fragments.some(fragment => isCustomizedPromptFragment(fragment)) && fragments.some(fragment => !isCustomizedPromptFragment(fragment))) {
312
+ return true;
313
+ }
314
+ }
315
+ return false;
316
+ }
317
+
318
+ protected async resetAllCustomizations(ctx: AiConfigurationRenderContext): Promise<void> {
319
+ const dialog = new ConfirmDialog({
320
+ title: nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetAllDialogTitle', 'Reset All Customizations'),
321
+ msg: nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetAllDialogMsg',
322
+ 'Are you sure you want to reset every customized prompt fragment to its built-in version? '
323
+ + 'This includes the agents\' prompt templates, not only the snippets listed here. '
324
+ + 'Snippets that have no built-in version are kept.'),
325
+ ok: nls.localizeByDefault('Reset'),
326
+ cancel: nls.localizeByDefault('Cancel')
327
+ });
328
+ if (await dialog.open()) {
329
+ await this.promptService.resetAllToBuiltIn();
330
+ ctx.update();
331
+ }
332
+ }
333
+
334
+ protected buildRows(kind: PromptSnippetKind, ctx: AiConfigurationRenderContext, onOpenAgent: (agentId: string) => void): CollapsibleRow[] {
335
+ return this.entries.filter(entry => entry.kind === kind).map(entry => this.buildRow(entry, ctx, onOpenAgent));
336
+ }
337
+
338
+ protected buildRow(entry: PromptSnippetEntry, ctx: AiConfigurationRenderContext, onOpenAgent: (agentId: string) => void): CollapsibleRow {
339
+ const agents = this.availableAgents.filter(agent => entry.agentIds.includes(agent.id));
340
+ const pills: string[] = [];
341
+ if (entry.customized) {
342
+ pills.push(nls.localize('theia/ai/ide/promptSnippetsConfiguration/customized', 'Customized'));
343
+ }
344
+ if (agents.length > 0) {
345
+ pills.push(agents.length === 1 ? nls.localizeByDefault('1 agent') : nls.localizeByDefault('{0} agents', agents.length));
346
+ }
347
+ return {
348
+ id: PromptSnippetsConfiguration.ROW_ID_PREFIX + entry.id,
349
+ title: this.displayName(entry),
350
+ description: entry.description,
351
+ pills,
352
+ filterText: `${entry.id} ${entry.name ?? ''} ${entry.description ?? ''}`.toLocaleLowerCase(),
353
+ actions: <>
354
+ <CollapsibleRowAction
355
+ iconClass={codicon('edit')}
356
+ label={nls.localize('theia/ai/ide/promptSnippetsConfiguration/editSnippet', 'Edit snippet')}
357
+ onActivate={() => this.editEntry(entry)}
358
+ />
359
+ {/* A customization of a built-in can be reverted; a snippet that only exists as a file has
360
+ nothing to revert to, so it offers deletion instead. */}
361
+ {entry.customized && entry.hasBuiltIn && <CollapsibleRowAction
362
+ iconClass={codicon('discard')}
363
+ label={nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetSnippet', 'Reset snippet to built-in')}
364
+ onActivate={() => this.resetEntry(entry, ctx)}
365
+ />}
366
+ {entry.customized && !entry.hasBuiltIn && <CollapsibleRowAction
367
+ iconClass={codicon('trash')}
368
+ label={nls.localize('theia/ai/ide/promptSnippetsConfiguration/removeSnippet', 'Remove snippet')}
369
+ onActivate={() => this.removeEntry(entry, ctx)}
370
+ />}
371
+ </>,
372
+ body: <>
373
+ <div className='ai-variable-id-row'>
374
+ <span className='ai-variable-id-label'>{nls.localizeByDefault('ID')}</span>
375
+ <code className='ai-variable-id-value'>{entry.id}</code>
376
+ </div>
377
+ {agents.length > 0 && <div className='ai-variable-section'>
378
+ <div className='ai-variable-section-label'>
379
+ {nls.localize('theia/ai/ide/promptSnippetsConfiguration/usedByAgents', 'Used by Agents')}
380
+ </div>
381
+ <AgentChips agents={agents} onOpenAgent={onOpenAgent} />
382
+ </div>}
383
+ </>
384
+ };
385
+ }
386
+
387
+ /** Opens the effective text: the customization if there is one, otherwise a fresh copy of the built-in. */
388
+ protected editEntry(entry: PromptSnippetEntry): void {
389
+ const fragment = this.promptService.getRawPromptFragment(entry.id);
390
+ if (fragment && isCustomizedPromptFragment(fragment)) {
391
+ this.promptService.editCustomization(fragment.id, fragment.customizationId);
392
+ } else {
393
+ this.promptService.editBuiltInCustomization(entry.id);
394
+ }
395
+ }
396
+
397
+ /** Drops all customizations so the built-in text applies again. */
398
+ protected async resetEntry(entry: PromptSnippetEntry, ctx: AiConfigurationRenderContext): Promise<void> {
399
+ await PromptCustomizationDialogs.confirmAndReset(
400
+ this.promptService,
401
+ entry.id,
402
+ nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetDialogTitle', 'Reset Snippet to Built-in'),
403
+ nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetDialogMsg',
404
+ 'Are you sure you want to reset the snippet "{0}" to its built-in version? This will remove all customizations.', entry.id)
405
+ );
406
+ ctx.update();
407
+ }
408
+
409
+ /** Deletes a snippet that has no built-in behind it, naming the file, since it is gone afterwards. */
410
+ protected async removeEntry(entry: PromptSnippetEntry, ctx: AiConfigurationRenderContext): Promise<void> {
411
+ await PromptCustomizationDialogs.confirmAndRemove(this.promptService, entry.id, {
412
+ title: nls.localize('theia/ai/ide/promptSnippetsConfiguration/removeDialogTitle', 'Remove Snippet'),
413
+ message: ({ type, description }) => description
414
+ ? nls.localize('theia/ai/ide/promptSnippetsConfiguration/removeWithDescDialogMsg',
415
+ 'Are you sure you want to remove the {0} customization for snippet "{1}" ({2})? It has no built-in version, so it will be gone entirely.',
416
+ type ?? '', entry.id, description)
417
+ : nls.localize('theia/ai/ide/promptSnippetsConfiguration/removeDialogMsg',
418
+ 'Are you sure you want to remove the {0} customization for snippet "{1}"? It has no built-in version, so it will be gone entirely.',
419
+ type ?? '', entry.id)
420
+ });
421
+ ctx.update();
422
+ }
423
+
424
+ getSearchItems(): AiConfigurationSearchItem[] {
425
+ const typeLabels: Record<PromptSnippetKind, string> = {
426
+ 'snippet': nls.localizeByDefault('Snippet'),
427
+ 'capability': nls.localize('theia/ai/ide/promptSnippetsConfiguration/capabilityTypeLabel', 'Capability'),
428
+ 'generic-capability': nls.localize('theia/ai/ide/promptSnippetsConfiguration/genericCapabilityTypeLabel', 'Generic capability')
429
+ };
430
+ return this.entries.map(entry => ({
431
+ label: this.displayName(entry),
432
+ typeLabel: typeLabels[entry.kind],
433
+ categoryId: this.id,
434
+ target: PromptSnippetsConfiguration.selectionFor(entry.id),
435
+ keywords: `${entry.id} ${entry.description ?? ''}`
436
+ }));
437
+ }
438
+ }
@@ -0,0 +1,226 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
18
+ let disableJSDOM = enableJSDOM();
19
+
20
+ import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
21
+ FrontendApplicationConfigProvider.set({});
22
+
23
+ import { expect } from 'chai';
24
+ import { Event } from '@theia/core';
25
+ import { PromptFragment } from '@theia/ai-core/lib/common/prompt-service';
26
+ import { Skill } from '@theia/ai-core/lib/common/skill';
27
+ import { AgentPluginUiBridge, InstalledAgentPluginInfo } from '@theia/ai-core/lib/browser/agent-plugin-ui-bridge';
28
+ import { SkillRegistryUiBridge } from '@theia/ai-core/lib/browser/skill-registry-ui-bridge';
29
+ import { AiConfigurationCategoryId } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
30
+ import { CollapsibleRow } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/collapsible-list';
31
+ import { PromptsAndSkillsConfigurationCategory } from './prompts-and-skills-configuration-category';
32
+
33
+ disableJSDOM();
34
+
35
+ /** A plugin as the bridge knows it, plus the qualifier its contributed skill root carries. */
36
+ type InstalledPlugin = InstalledAgentPluginInfo & { qualifier: string };
37
+
38
+ describe('PromptsAndSkillsConfigurationCategory', () => {
39
+
40
+ before(() => disableJSDOM = enableJSDOM());
41
+ after(() => disableJSDOM());
42
+
43
+ function categoryWith(skills: Skill[], slashCommands: PromptFragment[]): PromptsAndSkillsConfigurationCategory {
44
+ const category = new PromptsAndSkillsConfigurationCategory();
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ (category as any).skills = skills;
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ (category as any).slashCommands = slashCommands;
49
+ return category;
50
+ }
51
+
52
+ /** Leaves the bridge unbound when `installedPlugins` is omitted, i.e. a product without `@theia/ai-registry`. */
53
+ function categoryWithPlugins(skills: Skill[], installedPlugins: InstalledPlugin[] | undefined, revealed: string[] = []): PromptsAndSkillsConfigurationCategory {
54
+ const category = categoryWith(skills, []);
55
+ if (installedPlugins) {
56
+ const bridge: AgentPluginUiBridge = {
57
+ getPlugin: pluginId => installedPlugins.find(plugin => plugin.pluginId === pluginId),
58
+ getPluginByQualifier: qualifier => installedPlugins.find(plugin => plugin.qualifier === qualifier),
59
+ revealPlugin: pluginId => { revealed.push(pluginId); },
60
+ onDidChange: Event.None
61
+ };
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ (category as any).agentPluginUiBridge = bridge;
64
+ }
65
+ return category;
66
+ }
67
+
68
+ /**
69
+ * Leaves the bridge unbound when `managed` is omitted. `managed` maps a skill location to the
70
+ * registry entry it was installed from, which is how the real bridge keys them.
71
+ */
72
+ function categoryWithRegistrySkills(
73
+ skills: Skill[], managed: Record<string, string> | undefined, revealed: string[] = []
74
+ ): PromptsAndSkillsConfigurationCategory {
75
+ const category = categoryWith(skills, []);
76
+ if (managed) {
77
+ const bridge: SkillRegistryUiBridge = {
78
+ getRegistryEntryId: forSkill => managed[forSkill.location],
79
+ revealSkill: skillId => { revealed.push(skillId); },
80
+ onDidChange: Event.None
81
+ };
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ (category as any).skillRegistryUiBridge = bridge;
84
+ }
85
+ return category;
86
+ }
87
+
88
+ function skillRow(category: PromptsAndSkillsConfigurationCategory, forSkill: Skill): CollapsibleRow {
89
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
+ return (category as any).buildSkillRow(forSkill) as CollapsibleRow;
91
+ }
92
+
93
+ function skill(overrides: Partial<Skill>): Skill {
94
+ return { name: 'query-builder', qualifiedName: 'query-builder', description: 'Build SQL', location: '/skills/query-builder/SKILL.md', ...overrides } as Skill;
95
+ }
96
+
97
+ it('declares the skills and slash commands single-page metadata', () => {
98
+ const category = new PromptsAndSkillsConfigurationCategory();
99
+ expect(category.id).to.equal(AiConfigurationCategoryId.PROMPTS_AND_SKILLS);
100
+ expect(category.kind).to.equal('single-page');
101
+ });
102
+
103
+ it('indexes skills and slash commands for search, highlighting their rows', () => {
104
+ const category = categoryWith(
105
+ [{ name: 'refactor', qualifiedName: 'refactor', description: 'do it', location: '/s' } as unknown as Skill],
106
+ [{ id: 'cmd', commandName: 'go', commandDescription: 'run' } as unknown as PromptFragment]
107
+ );
108
+ const items = category.getSearchItems();
109
+ const byType = (typeIncludes: string) => items.filter(i => i.typeLabel.toLowerCase().includes(typeIncludes));
110
+
111
+ expect(byType('skill')).to.have.lengthOf(1);
112
+ expect(byType('slash')).to.have.lengthOf(1);
113
+ expect(items.find(i => i.label === 'refactor')?.target.highlight?.rowId).to.equal('skill:refactor');
114
+ expect(items.find(i => i.label === '/go')?.target.highlight?.rowId).to.equal('cmd:cmd');
115
+ expect(items.every(i => i.target.categoryId === AiConfigurationCategoryId.PROMPTS_AND_SKILLS)).to.equal(true);
116
+ });
117
+
118
+ it('does not list skill-backed synthetic commands as slash commands', () => {
119
+ const category = new PromptsAndSkillsConfigurationCategory();
120
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
121
+ (category as any).promptService = {
122
+ getCommands: () => [
123
+ { id: 'skill-command-refactor', commandName: 'refactor', isCommand: true },
124
+ { id: 'remember', commandName: 'remember', isCommand: true }
125
+ ] as unknown as PromptFragment[]
126
+ };
127
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
+ (category as any).loadSlashCommands();
129
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
+ const commands = (category as any).slashCommands as PromptFragment[];
131
+ expect(commands.map(command => command.id)).to.deep.equal(['remember']);
132
+ });
133
+
134
+ describe('Agent Plugin provenance', () => {
135
+
136
+ const bigquery: InstalledPlugin = { pluginId: 'io.example/bq', name: 'BigQuery Data Analytics', qualifier: 'bigquery' };
137
+ const contributed = skill({ qualifiedName: 'bigquery:query-builder', location: '/plugins/bigquery/skills/query-builder/SKILL.md' });
138
+
139
+ it('keys and titles a skill row by its qualified name, which is what the model addresses', () => {
140
+ const row = skillRow(categoryWithPlugins([contributed], [bigquery]), contributed);
141
+ expect(row.id).to.equal('skill:bigquery:query-builder');
142
+ expect(row.title).to.equal('bigquery:query-builder');
143
+ });
144
+
145
+ it('labels a contributed skill with the shared origin badge naming the plugin that supplied it', () => {
146
+ const row = skillRow(categoryWithPlugins([contributed], [bigquery]), contributed);
147
+ // The same descriptor the MCP page builds, so both pages render one badge rather than two designs.
148
+ expect(row.origins?.map(origin => origin.label)).to.deep.equal(['via BigQuery Data Analytics']);
149
+ // Filterable by the plugin name too, so a plugin's skills can be listed together.
150
+ expect(row.filterText).to.contain('bigquery data analytics');
151
+ });
152
+
153
+ it('reveals the owning plugin when the origin badge is activated', () => {
154
+ const revealed: string[] = [];
155
+ const row = skillRow(categoryWithPlugins([contributed], [bigquery], revealed), contributed);
156
+ // Activated directly: rendering the badge as a button is `AiConfigurationOriginBadge`'s
157
+ // contract, tested where it lives; what belongs here is where this page's badge leads.
158
+ row.origins![0].activate!();
159
+ expect(revealed).to.deep.equal([bigquery.pluginId]);
160
+ });
161
+
162
+ it('keeps the provenance out of the pills, which state what the skill is rather than where it came from', () => {
163
+ const row = skillRow(categoryWithPlugins([contributed], [bigquery]), contributed);
164
+ expect(row.pills?.some(pill => pill.startsWith('via '))).to.not.equal(true);
165
+ });
166
+
167
+ it('labels nothing for a skill from a built-in root, which is the common case', () => {
168
+ const own = skill({});
169
+ expect(skillRow(categoryWithPlugins([own], [bigquery]), own).origins).to.equal(undefined);
170
+ });
171
+
172
+ it('labels nothing rather than a bare qualifier when the qualifier belongs to no installed plugin', () => {
173
+ const row = skillRow(categoryWithPlugins([contributed], []), contributed);
174
+ expect(row.origins).to.equal(undefined);
175
+ expect(row.title).to.equal('bigquery:query-builder');
176
+ });
177
+
178
+ it('labels nothing when no bridge is bound, i.e. without `@theia/ai-registry`', () => {
179
+ expect(skillRow(categoryWithPlugins([contributed], undefined), contributed).origins).to.equal(undefined);
180
+ });
181
+ });
182
+
183
+ describe('AI registry provenance', () => {
184
+
185
+ const installed = skill({ location: '/home/alex/.agents/skills/query-builder/SKILL.md' });
186
+ const entryId = 'io.github.acme/query-builder';
187
+
188
+ it('labels a registry-installed skill with the shared "From registry" badge', () => {
189
+ const row = skillRow(categoryWithRegistrySkills([installed], { [installed.location]: entryId }), installed);
190
+ expect(row.origins?.map(origin => origin.label)).to.deep.equal(['From registry']);
191
+ expect(row.origins![0].tooltip).to.contain(entryId);
192
+ });
193
+
194
+ it('reveals the registry entry when the badge is activated', () => {
195
+ const revealed: string[] = [];
196
+ const row = skillRow(categoryWithRegistrySkills([installed], { [installed.location]: entryId }, revealed), installed);
197
+ row.origins![0].activate!();
198
+ expect(revealed).to.deep.equal([entryId]);
199
+ });
200
+
201
+ it('labels nothing for a skill in a directory the user controls', () => {
202
+ const own = skill({ location: '/workspace/.agents/skills/query-builder/SKILL.md' });
203
+ expect(skillRow(categoryWithRegistrySkills([own], { [installed.location]: entryId }), own).origins).to.equal(undefined);
204
+ });
205
+
206
+ it('labels nothing when no bridge is bound, i.e. without `@theia/ai-registry`', () => {
207
+ expect(skillRow(categoryWithRegistrySkills([installed], undefined), installed).origins).to.equal(undefined);
208
+ });
209
+
210
+ it('credits the plugin, not the registry, for a skill a plugin contributed', () => {
211
+ // A plugin ships its skills inside the plugin, so the two origins cannot both apply; were the
212
+ // registry consulted anyway, a stale name collision would show a skill as coming from both.
213
+ const bigquery: InstalledPlugin = { pluginId: 'io.example/bq', name: 'BigQuery', qualifier: 'bigquery' };
214
+ const contributed = skill({ qualifiedName: 'bigquery:query-builder', location: '/plugins/bigquery/skills/query-builder/SKILL.md' });
215
+ const category = categoryWithPlugins([contributed], [bigquery]);
216
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
217
+ (category as any).skillRegistryUiBridge = {
218
+ getRegistryEntryId: () => entryId,
219
+ revealSkill: () => { },
220
+ onDidChange: Event.None
221
+ } satisfies SkillRegistryUiBridge;
222
+
223
+ expect(skillRow(category, contributed).origins?.map(origin => origin.label)).to.deep.equal(['via BigQuery']);
224
+ });
225
+ });
226
+ });