@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,457 @@
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 * as React from '@theia/core/shared/react';
18
+ import { Emitter, Event } from '@theia/core';
19
+ import { Container, inject, injectable, interfaces, postConstruct } from '@theia/core/shared/inversify';
20
+ import {
21
+ codicon, CompositeTreeNode, ContextMenuRenderer, createTreeContainer, ExpandableTreeNode, NodeProps, SelectableTreeNode,
22
+ TreeModel, TreeNode, TreeProps, TreeWidget
23
+ } from '@theia/core/lib/browser';
24
+ import { AIActivationService } from '@theia/ai-core/lib/browser/ai-activation-service';
25
+ import { AiConfigurationCategoryRegistry } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category-registry';
26
+ import { AiConfigurationSelectionModel } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-selection-model';
27
+ import {
28
+ AiConfigurationAddDescriptor,
29
+ AiConfigurationCategory,
30
+ AiConfigurationCategoryId,
31
+ AiConfigurationSelection
32
+ } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
33
+ import { AiConfigurationTreeModel } from './ai-configuration-tree-model';
34
+ import { AiConfigurationCategoryNode, AiConfigurationItemNode, AiConfigurationSeparatorNode, AiConfigurationTree } from './ai-configuration-tree-nodes';
35
+ import { AiConfigurationSearch } from './ai-configuration-search';
36
+
37
+ @injectable()
38
+ export class AiConfigurationTreeWidget extends TreeWidget {
39
+
40
+ static readonly ID = 'ai-configuration-tree';
41
+
42
+ @inject(AiConfigurationCategoryRegistry)
43
+ protected readonly registry: AiConfigurationCategoryRegistry;
44
+
45
+ @inject(AiConfigurationSelectionModel)
46
+ protected readonly selectionModel: AiConfigurationSelectionModel;
47
+
48
+ @inject(AIActivationService)
49
+ protected readonly activationService: AIActivationService;
50
+
51
+ /** Guards the tree ↔ selection-model round trip against re-entrant updates. */
52
+ protected updatingSelection = false;
53
+ /** Set while a rebuild is in flight, so selection is restored once the tree is refreshed. */
54
+ protected pendingSelectionRestore = false;
55
+ protected expansionState = new Map<string, boolean>();
56
+
57
+ /** Active live-filter terms (empty => no filtering). */
58
+ protected filterTerms: string[] = [];
59
+ /** Expansion snapshot captured when filtering starts, restored when it ends. */
60
+ protected preFilterExpansion: Map<string, boolean> | undefined;
61
+
62
+ protected readonly onDidChangeExpansionEmitter = new Emitter<void>();
63
+ /** Fires when a category's expansion changes or the tree rebuilds, so the toolbar toggle can update. */
64
+ readonly onDidChangeExpansion: Event<void> = this.onDidChangeExpansionEmitter.event;
65
+
66
+ constructor(
67
+ @inject(TreeProps) props: TreeProps,
68
+ @inject(TreeModel) model: TreeModel,
69
+ @inject(ContextMenuRenderer) contextMenuRenderer: ContextMenuRenderer
70
+ ) {
71
+ super(props, model, contextMenuRenderer);
72
+ }
73
+
74
+ @postConstruct()
75
+ protected override init(): void {
76
+ super.init();
77
+ this.id = AiConfigurationTreeWidget.ID;
78
+ this.addClass('ai-configuration-tree');
79
+ this.toDispose.push(this.onDidChangeExpansionEmitter);
80
+ this.toDispose.push(this.registry.onDidChange(() => this.buildTree()));
81
+ this.toDispose.push(this.model.onChanged(() => this.onModelChanged()));
82
+ // The toolbar toggle mirrors the tree: rebuilds (onChanged) and expand/collapse both re-sync it.
83
+ this.toDispose.push(this.model.onChanged(() => this.onDidChangeExpansionEmitter.fire()));
84
+ this.toDispose.push(this.model.onExpansionChanged(() => this.onDidChangeExpansionEmitter.fire()));
85
+ this.toDispose.push(this.model.onSelectionChanged(() => this.handleTreeSelectionChanged()));
86
+ this.toDispose.push(this.selectionModel.onDidChangeSelection(selection => this.reflectSelection(selection)));
87
+ // When AI features are toggled off, hide the other categories and fall back to the General page
88
+ // (the only place to re-enable them); rebuild to bring them back once AI is on again.
89
+ this.toDispose.push(this.activationService.onDidChangeActiveStatus(() => {
90
+ this.buildTree();
91
+ if (!this.activationService.isActive) {
92
+ this.selectionModel.select({ categoryId: AiConfigurationCategoryId.GENERAL });
93
+ }
94
+ }));
95
+ this.buildTree();
96
+ }
97
+
98
+ protected buildTree(): void {
99
+ this.expansionState = this.captureExpansion();
100
+ this.pendingSelectionRestore = true;
101
+ this.model.root = AiConfigurationTree.buildRoot(this.visibleCategories(), {
102
+ isExpanded: categoryId => this.expansionState.get(categoryId)
103
+ });
104
+ }
105
+
106
+ /**
107
+ * The categories shown in the tree. While AI features are disabled only General is shown, so the
108
+ * view focuses on re-enabling them (mirroring how the General page disables its dependent settings).
109
+ */
110
+ protected visibleCategories(): AiConfigurationCategory[] {
111
+ const categories = this.registry.getCategories();
112
+ if (this.activationService.isActive) {
113
+ return categories;
114
+ }
115
+ return categories.filter(category => category.id === AiConfigurationCategoryId.GENERAL);
116
+ }
117
+
118
+ protected captureExpansion(): Map<string, boolean> {
119
+ const state = new Map<string, boolean>();
120
+ const root = this.model.root;
121
+ if (CompositeTreeNode.is(root)) {
122
+ for (const child of root.children) {
123
+ if (AiConfigurationCategoryNode.is(child) && ExpandableTreeNode.is(child)) {
124
+ state.set(child.categoryId, child.expanded);
125
+ }
126
+ }
127
+ }
128
+ return state;
129
+ }
130
+
131
+ /** Restores the selection after a rebuild once the target node has been indexed. */
132
+ protected onModelChanged(): void {
133
+ if (!this.pendingSelectionRestore) {
134
+ return;
135
+ }
136
+ const selection = this.selectionModel.getSelection();
137
+ if (!selection) {
138
+ this.pendingSelectionRestore = false;
139
+ return;
140
+ }
141
+ // Expand the owning category so an item child gets indexed on the next refresh.
142
+ if (selection.itemId) {
143
+ const categoryNode = this.model.getNode(AiConfigurationTree.categoryNodeId(selection.categoryId));
144
+ if (ExpandableTreeNode.is(categoryNode) && !categoryNode.expanded) {
145
+ this.model.expandNode(categoryNode);
146
+ }
147
+ }
148
+ const node = this.model.getNode(this.selectionNodeId(selection));
149
+ if (SelectableTreeNode.is(node)) {
150
+ this.pendingSelectionRestore = false;
151
+ this.applyTreeSelection(node);
152
+ }
153
+ }
154
+
155
+ /** Selection model → tree. */
156
+ protected reflectSelection(selection: AiConfigurationSelection | undefined): void {
157
+ if (!selection) {
158
+ return;
159
+ }
160
+ const node = this.model.getNode(this.selectionNodeId(selection));
161
+ if (SelectableTreeNode.is(node)) {
162
+ if (!node.selected) {
163
+ this.applyTreeSelection(node);
164
+ }
165
+ } else {
166
+ // The node is not indexed yet (e.g. during a rebuild); restore on the next refresh.
167
+ this.pendingSelectionRestore = true;
168
+ }
169
+ }
170
+
171
+ /** Tree → selection model. */
172
+ protected handleTreeSelectionChanged(): void {
173
+ if (this.updatingSelection) {
174
+ return;
175
+ }
176
+ const node = this.model.selectedNodes[0];
177
+ if (AiConfigurationItemNode.is(node)) {
178
+ // While filtering, jump to and flash the child's own matching setting (e.g. a provider setting);
179
+ // otherwise just open the child page.
180
+ this.selectionModel.select(this.matchingSettingTarget(node.categoryId, node.itemId) ?? { categoryId: node.categoryId, itemId: node.itemId });
181
+ } else if (AiConfigurationCategoryNode.is(node)) {
182
+ // While filtering, if the category was matched by one of its own (page-level) settings, jump to and
183
+ // flash that setting's row rather than just opening the category — useful on the General page, which
184
+ // gathers many settings across sub-sections. Settings that live in a child are reached via that child.
185
+ this.selectionModel.select(this.matchingSettingTarget(node.categoryId) ?? { categoryId: node.categoryId });
186
+ }
187
+ }
188
+
189
+ /**
190
+ * When a live filter is active and a category's own label does not match, returns the navigation target of
191
+ * the first setting that matches and lives at the requested location (with a `highlight` so the detail pane
192
+ * scrolls to and flashes the row): page-level settings when `itemId` is omitted, the given child's settings
193
+ * otherwise. Returns `undefined` otherwise, so selecting the node opens its overview as usual.
194
+ */
195
+ protected matchingSettingTarget(categoryId: string, itemId?: string): AiConfigurationSelection | undefined {
196
+ if (this.filterTerms.length === 0) {
197
+ return undefined;
198
+ }
199
+ const category = this.registry.getCategory(categoryId);
200
+ if (!category || this.labelMatches(category.label)) {
201
+ return undefined;
202
+ }
203
+ const match = (category.search?.getSearchItems() ?? []).find(item =>
204
+ item.target.highlight
205
+ && item.target.itemId === itemId
206
+ && AiConfigurationSearch.matchesTerms(AiConfigurationSearch.matchKey(item), this.filterTerms));
207
+ return match?.target;
208
+ }
209
+
210
+ protected applyTreeSelection(node: SelectableTreeNode): void {
211
+ this.updatingSelection = true;
212
+ try {
213
+ if (AiConfigurationItemNode.is(node) && ExpandableTreeNode.is(node.parent) && !node.parent.expanded) {
214
+ this.model.expandNode(node.parent);
215
+ }
216
+ this.model.selectNode(node);
217
+ } finally {
218
+ this.updatingSelection = false;
219
+ }
220
+ }
221
+
222
+ protected selectionNodeId(selection: AiConfigurationSelection): string {
223
+ return selection.itemId
224
+ ? AiConfigurationTree.itemNodeId(selection.categoryId, selection.itemId)
225
+ : AiConfigurationTree.categoryNodeId(selection.categoryId);
226
+ }
227
+
228
+ /** Expands every collapsible category (used by the Expand All toolbar action). */
229
+ expandAll(): void {
230
+ this.forEachCategory(node => {
231
+ if (!node.expanded) {
232
+ this.model.expandNode(node);
233
+ }
234
+ });
235
+ }
236
+
237
+ /** Collapses every collapsible category (used by the Collapse All toolbar action). */
238
+ collapseAll(): void {
239
+ this.forEachCategory(node => {
240
+ if (node.expanded) {
241
+ this.model.collapseNode(node);
242
+ }
243
+ });
244
+ }
245
+
246
+ /**
247
+ * Summarises the tree's expansion for the toolbar toggle: `'none'` when no category can be expanded,
248
+ * `'all-expanded'` when every expandable category is expanded, otherwise `'partially-collapsed'`.
249
+ */
250
+ getExpansionSummary(): 'none' | 'all-expanded' | 'partially-collapsed' {
251
+ let expandable = 0;
252
+ let expanded = 0;
253
+ this.forEachCategory(node => {
254
+ expandable++;
255
+ if (node.expanded) {
256
+ expanded++;
257
+ }
258
+ });
259
+ if (expandable === 0) {
260
+ return 'none';
261
+ }
262
+ return expanded === expandable ? 'all-expanded' : 'partially-collapsed';
263
+ }
264
+
265
+ protected forEachCategory(callback: (node: AiConfigurationCategoryNode & ExpandableTreeNode) => void): void {
266
+ const root = this.model.root;
267
+ if (!CompositeTreeNode.is(root)) {
268
+ return;
269
+ }
270
+ for (const child of root.children) {
271
+ if (AiConfigurationCategoryNode.is(child) && ExpandableTreeNode.is(child)) {
272
+ callback(child);
273
+ }
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Live tree filter driven by the search box: hides non-matching category/item
279
+ * nodes and the separator, and (un)expands categories so matches stay visible.
280
+ */
281
+ setFilter(text: string): void {
282
+ const terms = AiConfigurationSearch.terms(text);
283
+ const wasFiltering = this.filterTerms.length > 0;
284
+ const nowFiltering = terms.length > 0;
285
+ this.filterTerms = terms;
286
+ if (nowFiltering) {
287
+ if (!wasFiltering) {
288
+ this.preFilterExpansion = this.captureExpansion();
289
+ }
290
+ this.expandMatchingCategories();
291
+ } else if (wasFiltering) {
292
+ this.restoreExpansion();
293
+ }
294
+ this.updateRows();
295
+ }
296
+
297
+ protected expandMatchingCategories(): void {
298
+ const root = this.model.root;
299
+ if (!CompositeTreeNode.is(root)) {
300
+ return;
301
+ }
302
+ for (const child of root.children) {
303
+ if (AiConfigurationCategoryNode.is(child) && ExpandableTreeNode.is(child) && !child.expanded && this.matchesFilter(child)) {
304
+ this.model.expandNode(child);
305
+ }
306
+ }
307
+ }
308
+
309
+ protected restoreExpansion(): void {
310
+ const state = this.preFilterExpansion;
311
+ this.preFilterExpansion = undefined;
312
+ const root = this.model.root;
313
+ if (!state || !CompositeTreeNode.is(root)) {
314
+ return;
315
+ }
316
+ for (const child of root.children) {
317
+ if (AiConfigurationCategoryNode.is(child) && ExpandableTreeNode.is(child)) {
318
+ const wasExpanded = state.get(child.categoryId) ?? false;
319
+ if (wasExpanded && !child.expanded) {
320
+ this.model.expandNode(child);
321
+ } else if (!wasExpanded && child.expanded) {
322
+ this.model.collapseNode(child);
323
+ }
324
+ }
325
+ }
326
+ }
327
+
328
+ protected override shouldDisplayNode(node: TreeNode): boolean {
329
+ if (!super.shouldDisplayNode(node)) {
330
+ return false;
331
+ }
332
+ if (this.filterTerms.length === 0) {
333
+ return true;
334
+ }
335
+ if (AiConfigurationSeparatorNode.is(node)) {
336
+ return false;
337
+ }
338
+ return this.matchesFilter(node);
339
+ }
340
+
341
+ /**
342
+ * A category matches if its own label, any child, or any of its settings match; an item matches if its
343
+ * label or its category's label matches. Matching a category's settings means their names AND ids are
344
+ * searchable (via the deep-search index), so typing a setting id/name reveals its owning category.
345
+ */
346
+ protected matchesFilter(node: TreeNode): boolean {
347
+ if (AiConfigurationCategoryNode.is(node)) {
348
+ return this.labelMatches(node.name)
349
+ || node.children.some(child => this.labelMatches(child.name))
350
+ || this.settingsMatch(node.categoryId);
351
+ }
352
+ if (AiConfigurationItemNode.is(node)) {
353
+ // Reveal the specific child (e.g. an `anthropic` provider) whose own settings match, so searching a
354
+ // setting id like `ai-features.anthropic.serverSideCompaction` surfaces exactly where it lives —
355
+ // not just the parent category. The same setting may live under several children; each is revealed.
356
+ return this.labelMatches(node.name)
357
+ || (AiConfigurationCategoryNode.is(node.parent) && this.labelMatches(node.parent.name))
358
+ || this.settingsMatch(node.categoryId, node.itemId);
359
+ }
360
+ return false;
361
+ }
362
+
363
+ /**
364
+ * Whether a category's deep-search items (setting names, ids/keywords) match the active terms. With `itemId`
365
+ * only settings that live in that child node are considered; without it, every setting of the category.
366
+ */
367
+ protected settingsMatch(categoryId: string, itemId?: string): boolean {
368
+ const items = this.registry.getCategory(categoryId)?.search?.getSearchItems() ?? [];
369
+ return items.some(item =>
370
+ (itemId === undefined || item.target.itemId === itemId)
371
+ && AiConfigurationSearch.matchesTerms(AiConfigurationSearch.matchKey(item), this.filterTerms));
372
+ }
373
+
374
+ protected labelMatches(label: string | undefined): boolean {
375
+ if (!label) {
376
+ return false;
377
+ }
378
+ return AiConfigurationSearch.matchesTerms(label.toLowerCase(), this.filterTerms);
379
+ }
380
+
381
+ protected override renderIcon(node: TreeNode, props: NodeProps): React.ReactNode {
382
+ if (AiConfigurationCategoryNode.is(node) || AiConfigurationItemNode.is(node)) {
383
+ return <div className={`ai-configuration-tree-node-icon ${node.iconClass}`}></div>;
384
+ }
385
+ return super.renderIcon(node, props);
386
+ }
387
+
388
+ /**
389
+ * Trailing decorations: an item's state as a colored dot (e.g. whether an MCP server is running), and a
390
+ * category's "create item" action, so adding an agent or a server does not require opening the page
391
+ * first. The action button is revealed on hover/focus of the row, like the Settings UI's gear.
392
+ */
393
+ protected override renderTailDecorations(node: TreeNode, props: NodeProps): React.ReactNode {
394
+ if (AiConfigurationItemNode.is(node) && node.status) {
395
+ // Boxed in the same trailing slot as a category's action button so the dot and the `+` line up.
396
+ return <span className='ai-configuration-tree-node-decoration' title={node.status.tooltip ?? node.status.label}>
397
+ <span
398
+ className={`ai-configuration-status ai-configuration-status-${node.status.kind}`}
399
+ // The dot repeats what the detail page states in words, so it is decorative for screen readers.
400
+ aria-hidden={true}
401
+ ></span>
402
+ </span>;
403
+ }
404
+ if (AiConfigurationCategoryNode.is(node)) {
405
+ const add = this.getAddAction(node.categoryId);
406
+ if (add) {
407
+ return <button
408
+ type='button'
409
+ className='ai-configuration-tree-node-decoration ai-configuration-tree-node-action'
410
+ title={add.label}
411
+ aria-label={add.label}
412
+ onClick={event => {
413
+ // Without this the click also selects (or expands) the row behind the button.
414
+ event.stopPropagation();
415
+ add.run();
416
+ }}
417
+ >
418
+ <span aria-hidden='true' className={add.iconClass ?? codicon('add')}></span>
419
+ </button>;
420
+ }
421
+ }
422
+ return super.renderTailDecorations(node, props);
423
+ }
424
+
425
+ /**
426
+ * The category's add action, if it offers one. Navigation goes through the selection model, so running the
427
+ * action from the tree behaves like running it from the category's own page.
428
+ */
429
+ protected getAddAction(categoryId: string): AiConfigurationAddDescriptor | undefined {
430
+ const renderer = this.registry.getCategory(categoryId)?.renderer;
431
+ return renderer?.getAddAction?.({
432
+ scope: 'user',
433
+ navigate: selection => this.selectionModel.select(selection),
434
+ update: () => { }
435
+ });
436
+ }
437
+
438
+ protected override createNodeClassNames(node: TreeNode, props: NodeProps): string[] {
439
+ const classNames = super.createNodeClassNames(node, props);
440
+ if (AiConfigurationSeparatorNode.is(node)) {
441
+ classNames.push('ai-configuration-tree-separator');
442
+ }
443
+ return classNames;
444
+ }
445
+ }
446
+
447
+ export function createAiConfigurationTreeContainer(parent: interfaces.Container): Container {
448
+ return createTreeContainer(parent, {
449
+ model: AiConfigurationTreeModel,
450
+ widget: AiConfigurationTreeWidget,
451
+ props: {
452
+ virtualized: false,
453
+ search: false,
454
+ leftPadding: 8
455
+ }
456
+ });
457
+ }
@@ -13,15 +13,22 @@
13
13
  //
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
- import { Command, CommandRegistry, nls } from '@theia/core';
16
+ import { Command, CommandRegistry, MenuModelRegistry, nls } from '@theia/core';
17
17
  import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
18
- import { AIViewContribution } from '@theia/ai-core/lib/browser';
18
+ import { AI_SHOW_SETTINGS_COMMAND, AIViewContribution } from '@theia/ai-core/lib/browser';
19
19
  import { ChatViewWidget } from '@theia/ai-chat-ui/lib/browser/chat-view-widget';
20
- import { FrontendApplication } from '@theia/core/lib/browser';
20
+ import { codicon, CommonCommands, CommonMenus, KeybindingRegistry } from '@theia/core/lib/browser';
21
21
  import { inject, injectable } from '@theia/core/shared/inversify';
22
22
  import { AIConfigurationContainerWidget } from './ai-configuration-widget';
23
23
  import { AIConfigurationSelectionService } from './ai-configuration-service';
24
- import { AIToolsConfigurationWidget } from './tools-configuration-widget';
24
+ import {
25
+ AiConfigurationCategoryId, AiConfigurationSearchProvider, AiConfigurationSelection
26
+ } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
27
+ import { AiConfigurationCategoryRegistry } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category-registry';
28
+ import { AiConfigurationSelectionModel } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-selection-model';
29
+
30
+ /** Preference key prefix under which all AI features register their preferences. */
31
+ const AI_PREFERENCE_PREFIX = 'ai-features.';
25
32
 
26
33
  export const AI_CONFIGURATION_TOGGLE_COMMAND_ID = 'aiConfiguration:toggle';
27
34
  export const OPEN_AI_CONFIG_VIEW = Command.toLocalizedCommand({
@@ -35,11 +42,17 @@ export const OPEN_AI_CONFIG_VIEW_TOOLS = Command.toLocalizedCommand({
35
42
  });
36
43
 
37
44
  @injectable()
38
- export class AIAgentConfigurationViewContribution extends AIViewContribution<AIConfigurationContainerWidget> implements TabBarToolbarContribution {
45
+ export class AIConfigurationViewContribution extends AIViewContribution<AIConfigurationContainerWidget> implements TabBarToolbarContribution {
39
46
 
40
47
  @inject(AIConfigurationSelectionService)
41
48
  protected readonly aiConfigurationSelectionService: AIConfigurationSelectionService;
42
49
 
50
+ @inject(AiConfigurationCategoryRegistry)
51
+ protected readonly categoryRegistry: AiConfigurationCategoryRegistry;
52
+
53
+ @inject(AiConfigurationSelectionModel)
54
+ protected readonly selectionModel: AiConfigurationSelectionModel;
55
+
43
56
  constructor() {
44
57
  super({
45
58
  widgetId: AIConfigurationContainerWidget.ID,
@@ -52,31 +65,140 @@ export class AIAgentConfigurationViewContribution extends AIViewContribution<AIC
52
65
  });
53
66
  }
54
67
 
55
- async initializeLayout(_app: FrontendApplication): Promise<void> {
56
- await this.openView();
68
+ /**
69
+ * Overrides {@link AIViewContribution.init}, which closes the view when AI features are disabled.
70
+ * The AI Configuration view must instead stay open, so that turning AI off does not close the very
71
+ * view holding the toggle that turns it back on. It stays reachable either way via the Manage (gear)
72
+ * menu and `alt+a`, both of which are ungated. See eclipsesource/theia#316.
73
+ */
74
+ protected override init(): void {
75
+ // Intentionally left blank: do not register the deactivate-closes-view listener.
57
76
  }
58
77
 
59
78
  override registerCommands(commands: CommandRegistry): void {
60
- super.registerCommands(commands);
79
+ // Register the view toggle command as {@link AIViewContribution} would, but intentionally omit the
80
+ // "Open View..." quick-pick item it registers. The AI Configuration view is reachable only from the
81
+ // bottom-left Manage (gear) menu and the alt+a keybinding, mirroring the Settings UI.
82
+ if (this.toggleCommand) {
83
+ commands.registerCommand(this.toggleCommand, this.commandHandlerFactory({
84
+ execute: () => this.toggleView()
85
+ }));
86
+ }
61
87
  commands.registerCommand(OPEN_AI_CONFIG_VIEW, {
62
- execute: async (tabId?: string) => {
63
- // Only open/reveal the view if it isn't already visible; switching tabs on an
64
- // already-visible view doesn't need a (re-)activation of the whole view.
65
- const widget = this.tryGetWidget();
66
- if (!widget?.isVisible) {
67
- await this.openView({ activate: true });
68
- }
69
- if (typeof tabId === 'string') {
70
- this.aiConfigurationSelectionService.selectConfigurationTab(tabId);
88
+ execute: async (target?: unknown) => {
89
+ // The Manage-menu entry and the alt+a keybinding invoke this with no argument; the chat
90
+ // toolbar passes the active widget. Only an explicit string target (a category or preference
91
+ // id) navigates - anything else just opens the view, so every entry point behaves the same
92
+ // as the Manage-menu entry.
93
+ const explicitTarget = typeof target === 'string' ? target.trim() || undefined : undefined;
94
+ // Whether the view already existed (open in some tab) before this call.
95
+ const alreadyOpen = !!this.tryGetWidget();
96
+ await this.openView({ activate: true });
97
+ if (explicitTarget) {
98
+ // An explicit category/preference target always navigates.
99
+ this.navigateTo(explicitTarget);
100
+ } else if (!alreadyOpen) {
101
+ // A fresh open with no target lands on General; an already-open view is only
102
+ // (re-)activated and keeps its current selection.
103
+ this.navigateTo(undefined);
71
104
  }
72
105
  },
73
106
  });
74
107
  commands.registerCommand(OPEN_AI_CONFIG_VIEW_TOOLS, {
75
- execute: () => commands.executeCommand(OPEN_AI_CONFIG_VIEW.id, AIToolsConfigurationWidget.ID),
108
+ execute: () => commands.executeCommand(OPEN_AI_CONFIG_VIEW.id, AiConfigurationCategoryId.TOOLS),
109
+ });
110
+ // "Show AI Settings" (contributed by @theia/ai-core, e.g. the chat toolbar gear) opens the AI
111
+ // features settings. Those now live in this view rather than the Settings UI, so route the command
112
+ // straight here. Registered from @theia/ai-ide, this handler takes precedence over the core one
113
+ // (which falls back to `preferences:open` for apps without this view). No `isEnabled` gate, so the
114
+ // view stays reachable while AI is disabled — that is where AI features are re-enabled.
115
+ commands.registerHandler(AI_SHOW_SETTINGS_COMMAND.id, {
116
+ // Forwarded so callers can deep-link to a preference row; OPEN_AI_CONFIG_VIEW ignores any
117
+ // argument that is not a string, so the widget the chat toolbar passes just opens the view.
118
+ execute: (target?: unknown) => commands.executeCommand(OPEN_AI_CONFIG_VIEW.id, target)
119
+ });
120
+ }
121
+
122
+ /** Whether a `preferences:open` argument targets the AI features preference section or a preference in it. */
123
+ protected isAiConfigurationPreference(query: unknown): boolean {
124
+ return typeof query === 'string' && (query === 'ai-features' || query.startsWith(AI_PREFERENCE_PREFIX));
125
+ }
126
+
127
+ /**
128
+ * Navigates the (already-open) view to `target`. An `ai-features.*` preference id (or the `ai-features`
129
+ * section) opens the owning category focused on that row; any other value is treated as a category/tab
130
+ * id; no target lands on General. This lets every AI-settings entry point go through
131
+ * {@link OPEN_AI_CONFIG_VIEW} instead of `preferences:open`.
132
+ */
133
+ protected navigateTo(target?: string): void {
134
+ const value = target?.trim();
135
+ // An AI preference id (or the `ai-features` section) → focus the owning category and row.
136
+ if (value && this.isAiConfigurationPreference(value)) {
137
+ this.selectionModel.select(
138
+ this.resolvePreferenceTarget(value) ?? { categoryId: AiConfigurationCategoryId.GENERAL, highlight: { rowId: value } }
139
+ );
140
+ return;
141
+ }
142
+ // A known category id → select it directly (deterministic, no dependency on the legacy bridge).
143
+ if (value && this.categoryRegistry.getCategory(value)) {
144
+ this.selectionModel.select({ categoryId: value });
145
+ return;
146
+ }
147
+ // A legacy per-tab widget id → let the container bridge map it onto a category.
148
+ if (value) {
149
+ this.aiConfigurationSelectionService.selectConfigurationTab(value);
150
+ return;
151
+ }
152
+ // No/empty target → General, so the detail never stays on the empty "select a category" placeholder.
153
+ this.selectionModel.select({ categoryId: AiConfigurationCategoryId.GENERAL });
154
+ }
155
+
156
+ /**
157
+ * Finds the navigation target for a preference by scanning the categories' deep-search index for the
158
+ * setting row that anchors it (rows use the preference id as their `highlight.rowId`). Returns
159
+ * `undefined` when no category surfaces the preference.
160
+ */
161
+ protected resolvePreferenceTarget(preferenceId: string): AiConfigurationSelection | undefined {
162
+ for (const category of this.categoryRegistry.getCategories()) {
163
+ const searchProvider = category as Partial<AiConfigurationSearchProvider>;
164
+ for (const item of searchProvider.getSearchItems?.() ?? []) {
165
+ if (item.target.highlight?.rowId === preferenceId) {
166
+ return item.target;
167
+ }
168
+ }
169
+ }
170
+ return undefined;
171
+ }
172
+
173
+ /**
174
+ * Overrides {@link AIViewContribution.registerMenus} so the AI Configuration view is offered only from
175
+ * the bottom-left Manage (gear) menu, mirroring the Settings UI. It is intentionally not added to the
176
+ * View menu's "Views" submenu. The Manage entry (and the alt+a keybinding) keep it reachable even while
177
+ * AI is disabled, which is where AI gets re-enabled. See eclipsesource/theia#316.
178
+ */
179
+ override registerMenus(menus: MenuModelRegistry): void {
180
+ // Bottom-left Manage menu, directly below "Settings" (order 'a10').
181
+ menus.registerMenuAction(CommonMenus.MANAGE_SETTINGS, {
182
+ commandId: OPEN_AI_CONFIG_VIEW.id,
183
+ label: nls.localize('theia/ai/ide/aiConfiguration/manageMenu', 'AI Configuration'),
184
+ order: 'a11'
185
+ });
186
+ }
187
+
188
+ override registerKeybindings(keybindings: KeybindingRegistry): void {
189
+ super.registerKeybindings(keybindings);
190
+ keybindings.registerKeybinding({
191
+ command: OPEN_AI_CONFIG_VIEW.id,
192
+ keybinding: 'alt+a'
76
193
  });
77
194
  }
78
195
 
79
196
  registerToolbarItems(registry: TabBarToolbarRegistry): void {
197
+ // The IDE offers "Open AI Configuration" (below) as the single chat-toolbar entry into AI settings,
198
+ // so drop the generic "Open AI Settings" button that @theia/ai-chat-ui contributes for base apps
199
+ // (AI_SHOW_SETTINGS_COMMAND). @theia/ai-ide depends on @theia/ai-chat-ui, so that item is already
200
+ // registered by the time this runs.
201
+ registry.unregisterItem('chat-view.' + AI_SHOW_SETTINGS_COMMAND.id);
80
202
  registry.registerItem({
81
203
  id: 'chat-view.' + OPEN_AI_CONFIG_VIEW.id,
82
204
  command: OPEN_AI_CONFIG_VIEW.id,
@@ -85,5 +207,21 @@ export class AIAgentConfigurationViewContribution extends AIViewContribution<AIC
85
207
  priority: 2,
86
208
  isVisible: widget => this.activationService.isActive && widget instanceof ChatViewWidget
87
209
  });
210
+ // Escape hatch from the AI Configuration view to the regular Settings UI. OPEN_PREFERENCES ignores
211
+ // the widget argument the toolbar passes (it only acts on a string search term), and this view's
212
+ // `ai-features.*` interceptor does not claim it (the argument is not an AI preference id).
213
+ registry.registerItem({
214
+ id: 'ai-configuration.open-settings-ui',
215
+ command: CommonCommands.OPEN_PREFERENCES.id,
216
+ icon: codicon('settings'),
217
+ tooltip: nls.localizeByDefault('Open Settings (UI)'),
218
+ isVisible: widget => widget instanceof AIConfigurationContainerWidget
219
+ });
220
+ // Expand/Collapse All are a single contextual toggle below the search box, owned by the search
221
+ // widget and wired straight to the tree (see `AIConfigurationContainerWidget.initListeners`).
222
+ // Deliberately not commands: they act on this view's own category tree, so "Expand All" would not
223
+ // say in the command palette what it expands. The Outline and Problems views keep theirs out of the
224
+ // palette the same way, by declaring the command without a `label` (`QuickCommandService.normalize`
225
+ // filters those out) on top of gating it on the widget.
88
226
  }
89
227
  }