@openhands/agent-canvas 1.14.0 → 1.15.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 (1590) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/acp-providers-BKvmTf82.js +1 -0
  4. package/build/assets/active-backend-context-DKFSMbn3.js +2 -0
  5. package/build/assets/agent-context-settings-D3PjSTU1.js +1 -0
  6. package/build/assets/agent-profiles-settings-D4cY5U2T.js +1 -0
  7. package/build/assets/agent-server-conversation-service.api-DozDKIW_.js +86 -0
  8. package/build/assets/agent-settings-351vXWc9.js +2 -0
  9. package/build/assets/agent-settings-Ce7BDZ6I.js +1 -0
  10. package/build/assets/alert-banner-Kyy1YWZU.js +1 -0
  11. package/build/assets/api-error-message-BJyfWp6p.js +1 -0
  12. package/build/assets/api-key-entry-screen-INIxqAMs.js +1 -0
  13. package/build/assets/app-settings-CbHqzQus.js +1 -0
  14. package/build/assets/automation-detail-DXDhUwPq.js +3 -0
  15. package/build/assets/automation-export-BRopEHMu.js +2 -0
  16. package/build/assets/automation-git-sync-CzyS4cn1.js +1 -0
  17. package/build/assets/automation-setup-route-FRr05f_g.js +1 -0
  18. package/build/assets/automation-templates-C_0FZgLG.js +1 -0
  19. package/build/assets/automations-list-CERuQWE6.js +1 -0
  20. package/build/assets/back-nav-button-Dm9tIjVf.js +1 -0
  21. package/build/assets/backend-form-modal-DK78-jn1.js +1 -0
  22. package/build/assets/backend-synced-settings-badge-3fOwg6Bd.js +1 -0
  23. package/build/assets/badge-D4SqUCsR.js +1 -0
  24. package/build/assets/base-modal-C7_BDl_U.js +1 -0
  25. package/build/assets/bot-C-0Wu7vQ.js +1 -0
  26. package/build/assets/brand-button-Dxv6PDeN.js +1 -0
  27. package/build/assets/browser-11etCQ04.js +7 -0
  28. package/build/assets/browser-tab-BAl4ckJE.js +1 -0
  29. package/build/assets/chat-send-button-DWwR2cgI.js +1 -0
  30. package/build/assets/check-Cf2YoT90.js +1 -0
  31. package/build/assets/chevron-down-C3OQ-ehx.js +1 -0
  32. package/build/assets/chevron-right-CN1uUiJ1.js +1 -0
  33. package/build/assets/circle-check-g5yeGMd-.js +1 -0
  34. package/build/assets/circle-plus-check-toggle-CBh_qomE.js +1 -0
  35. package/build/assets/cloud-funnel-analytics-287iIERo.js +1 -0
  36. package/build/assets/cog-C4rrw-ZK.js +1 -0
  37. package/build/assets/command-menu-BZQ8S3Ke.js +1 -0
  38. package/build/assets/commits-tab-DZtJgaDM.js +1 -0
  39. package/build/assets/condenser-settings-BcNmYR4s.js +1 -0
  40. package/build/assets/confirmation-modal-Bk4JRcCM.js +1 -0
  41. package/build/assets/context-menu-list-item-lVYETtY5.js +1 -0
  42. package/build/assets/conversation-CchMzpGl.js +1 -0
  43. package/build/assets/conversation-Dpzftz57.js +93 -0
  44. package/build/assets/conversation-panel-CchMzpGl.js +1 -0
  45. package/build/assets/conversation-state-store-a9d2fxRc.js +1 -0
  46. package/build/assets/conversation-store-Ca3ghXap.js +6 -0
  47. package/build/assets/conversation-tab-empty-state-HJtkmHZj.js +1 -0
  48. package/build/assets/copy-to-clipboard-button-Cjkswvnj.js +1 -0
  49. package/build/assets/device-verify-EZhHhBT7.js +1 -0
  50. package/build/assets/dropdown-classes-DJe-E6MC.js +1 -0
  51. package/build/assets/edit-automation-modal-D-urtv8n.js +1 -0
  52. package/build/assets/empty-state-CvaVahVr.js +1 -0
  53. package/build/assets/entry.client-C7Bi2tkU.js +2 -0
  54. package/build/assets/enum-filter-dropdown-DliX_Lo0.js +1 -0
  55. package/build/assets/environment-switch-overlay-CEKrFiMw.js +1 -0
  56. package/build/assets/error-state-BALXiBNy.js +1 -0
  57. package/build/assets/extension-module-card-classes-DpeaYhYo.js +1 -0
  58. package/build/assets/extensions-hub-CFduxBnk.js +1 -0
  59. package/build/assets/extensions-navigation-BeC224yX.js +1 -0
  60. package/build/assets/external-link-DFpYunfj.js +1 -0
  61. package/build/assets/files-tab-CL3J9b3p.js +1 -0
  62. package/build/assets/form-control-classes-CGw40z5h.js +1 -0
  63. package/build/assets/get-git-path-DlAJa_i6.js +1 -0
  64. package/build/assets/git-repo-dropdown-DGMEhz7d.js +1 -0
  65. package/build/assets/git-repo-dropdown-ai8qaNkD.js +1 -0
  66. package/build/assets/highlighted-source-view-C3sxykQi.js +1 -0
  67. package/build/assets/home-BCGlNJCA.js +1 -0
  68. package/build/assets/home-DB1pRqTC.js +1 -0
  69. package/build/assets/home-automation-run-tooltip-CooFQRIG.js +1 -0
  70. package/build/assets/home-store-Dl1dPE58.js +1 -0
  71. package/build/assets/index-home-DB1pRqTC.js +1 -0
  72. package/build/assets/info-uYSVzX86.js +1 -0
  73. package/build/assets/install-server-modal-BbJdhzet.js +1 -0
  74. package/build/assets/kebab-menu-item-content-BYokkRHi.js +1 -0
  75. package/build/assets/key-Cn5za3rg.js +1 -0
  76. package/build/assets/launch-C1ieiOGe.js +1 -0
  77. package/build/assets/list-filter-OFkpRrmi.js +1 -0
  78. package/build/assets/list-todo-Cuu-STFc.js +1 -0
  79. package/build/assets/llm-not-configured-banner-BqqYnJ1t.js +27 -0
  80. package/build/assets/llm-settings-CnDbbmVW.js +1 -0
  81. package/build/assets/llm-settings-S8Yjg__1.js +1 -0
  82. package/build/assets/llm-subscription-service-BpPfzW4x.js +1 -0
  83. package/build/assets/loader-circle-nvrwthvj.js +1 -0
  84. package/build/assets/loading-spinner-0L3ZTToZ.js +1 -0
  85. package/build/assets/manage-backends-modal-BCUPswyl.js +1 -0
  86. package/build/assets/manifest-58597dde.js +1 -0
  87. package/build/assets/manifest-subpage-layout-BGhiUQbA.js +1 -0
  88. package/build/assets/map-provider-B9LTm23I.js +1 -0
  89. package/build/assets/markdown-renderer-Cb2sBWtV.js +8 -0
  90. package/build/assets/mcp-CKbR4Vft.js +1 -0
  91. package/build/assets/mcp-marketplace-utils-C13fFccR.js +1 -0
  92. package/build/assets/mcp-page-Bm4K2NQq.js +9 -0
  93. package/build/assets/messages-BTN5thLe.js +40 -0
  94. package/build/assets/modal-body-CMOc2tLl.js +1 -0
  95. package/build/assets/modal-classes-BAb4Y_BG.js +1 -0
  96. package/build/assets/modal-close-button-CkJ0Ktjj.js +1 -0
  97. package/build/assets/mouse-pointer-click-CsgRs_-r.js +1 -0
  98. package/build/assets/onboarding-Cx_kaiD1.js +1 -0
  99. package/build/assets/onboarding-modal-vMwn7ihv.js +1 -0
  100. package/build/assets/organization-service.api-C8XpQ0pM.js +1 -0
  101. package/build/assets/parse-git-remote-url-DpDM9bK6.js +1 -0
  102. package/build/assets/pencil-Clh1Wjvh.js +1 -0
  103. package/build/assets/planner-tab-DQvDU3ap.js +1 -0
  104. package/build/assets/plug-BuQhHSSG.js +1 -0
  105. package/build/assets/plugins-management-service-BjYeF0b0.js +1 -0
  106. package/build/assets/plus-CEKne-Yp.js +1 -0
  107. package/build/assets/profiles-service.api-QB-T_u-g.js +1 -0
  108. package/build/assets/providers-FfSZ5TXP.js +1 -0
  109. package/build/assets/proxy-tcFL2yTQ.js +1 -0
  110. package/build/assets/puzzle-A9pGxxai.js +1 -0
  111. package/build/assets/recommended-automations-launcher-Bw8uC4V6.js +1 -0
  112. package/build/assets/refresh-cw-Bh69DyYO.js +1 -0
  113. package/build/assets/root-BLeQfBEq.css +1 -0
  114. package/build/assets/root-ZKKYPR1Z.js +2 -0
  115. package/build/assets/root-layout-luJoE9IG.js +2 -0
  116. package/build/assets/schema-field-Csw5fhtN.js +1 -0
  117. package/build/assets/scroll-fade-state-Dw-i4SGq.js +1 -0
  118. package/build/assets/sdk-section-page-HTffvm7Q.js +1 -0
  119. package/build/assets/secret-form-HTUbYw5o.js +1 -0
  120. package/build/assets/secrets-service-BTor9uAU.js +1 -0
  121. package/build/assets/secrets-settings-BizaTEr1.js +1 -0
  122. package/build/assets/server-process-C9RKzd1x.js +1 -0
  123. package/build/assets/settings-BlmrkwRi.js +1 -0
  124. package/build/assets/settings-dropdown-input-tM0A0ipy.js +1 -0
  125. package/build/assets/settings-index-CKq0b0Vg.js +1 -0
  126. package/build/assets/settings-input-C03KUoSC.js +1 -0
  127. package/build/assets/settings-list-classes-BJ0g8rWj.js +1 -0
  128. package/build/assets/settings-modal-AzEF1QPP.js +1 -0
  129. package/build/assets/settings-service.api-B2agVfjL.js +1 -0
  130. package/build/assets/settings-switch-CQE0EGC-.js +1 -0
  131. package/build/assets/settings-utils-ClYOkbbI.js +1 -0
  132. package/build/assets/shared-conversation-B55pCyBG.js +1 -0
  133. package/build/assets/shield-check-CFDViW82.js +1 -0
  134. package/build/assets/sidebar-layout-D3hE08wK.js +1 -0
  135. package/build/assets/sidebar-mobile-menu-toggle-BOtyJHwE.js +1 -0
  136. package/build/assets/sidebar-nav-link-CPzhyHQg.js +1 -0
  137. package/build/assets/sidebar-onboarding-checklist-storage-3qYflszY.js +1 -0
  138. package/build/assets/sidebar-store-DtpU7zaI.js +1 -0
  139. package/build/assets/skill-card-pill-row-CFxjoqxn.js +1 -0
  140. package/build/assets/skill-filter-CWZ5kjcg.js +2 -0
  141. package/build/assets/skill-icon-badge-CPQJ6A-I.js +1 -0
  142. package/build/assets/skill-scope-CV1dkAbW.js +1 -0
  143. package/build/assets/skills-plugins-DGHULTq6.js +1 -0
  144. package/build/assets/skills-settings-CM1lFv3e.js +1 -0
  145. package/build/assets/styled-tooltip-Dl06rkpY.js +1 -0
  146. package/build/assets/task-list-tab-04GNQuii.js +1 -0
  147. package/build/assets/terminal-Cj0iHIW7.js +3 -0
  148. package/build/assets/toggle-switch-Fd_QGz0r.js +1 -0
  149. package/build/assets/trash-2-Dl8_RGz0.js +1 -0
  150. package/build/assets/trash-_RMt7Ayc.js +1 -0
  151. package/build/assets/triangle-alert-SM-q4NU_.js +1 -0
  152. package/build/assets/typography-SgFy466J.js +1 -0
  153. package/build/assets/usage-tab-BcfWV6db.js +1 -0
  154. package/build/assets/use-acp-credential-form-BsSW5NHG.js +1 -0
  155. package/build/assets/use-activate-agent-profile-B2NS8nA5.js +1 -0
  156. package/build/assets/use-agent-profiles-DWBPC0Si.js +1 -0
  157. package/build/assets/use-automation-health-BxXdzZMP.js +1 -0
  158. package/build/assets/use-automations-zYb0dUny.js +1 -0
  159. package/build/assets/use-can-manage-org-profiles-BWMahtUh.js +1 -0
  160. package/build/assets/use-cloud-current-user-id-CPHMDG-C.js +1 -0
  161. package/build/assets/use-config-Bft35DOK.js +1 -0
  162. package/build/assets/use-create-conversation-DwN5vv2f.js +1 -0
  163. package/build/assets/use-create-secret-BSxJMxHp.js +1 -0
  164. package/build/assets/use-get-secrets-BT4ihRwj.js +1 -0
  165. package/build/assets/use-has-permission-B3C8rQmR.js +1 -0
  166. package/build/assets/use-is-authed-CFGkY3-Z.js +1 -0
  167. package/build/assets/use-launch-skill-in-chat-BYjYihBP.js +1 -0
  168. package/build/assets/use-llm-configured-BI6obxsc.js +1 -0
  169. package/build/assets/use-llm-profiles-djGAhTWL.js +1 -0
  170. package/build/assets/use-manifest-capabilities-3z0-1G59.js +1 -0
  171. package/build/assets/use-onboarding-completion-BXpyUSsJ.js +1 -0
  172. package/build/assets/use-plugins-marketplace-DI4_pK56.js +1 -0
  173. package/build/assets/use-save-agent-profile-DdBSTdpN.js +1 -0
  174. package/build/assets/use-save-settings-CUZW6yXP.js +1 -0
  175. package/build/assets/use-settings-C5VhGpqd.js +1 -0
  176. package/build/assets/use-settings-nav-items-DHaUu1Dg.js +16 -0
  177. package/build/assets/use-tracking-D5t9otIF.js +3 -0
  178. package/build/assets/use-user-conversation-DT0_QCnL.js +1 -0
  179. package/build/assets/useInfiniteQuery-CgeUQPfs.js +1 -0
  180. package/build/assets/useMutation-DFnzkf6f.js +1 -0
  181. package/build/assets/useQueries-BhbrGEf1.js +1 -0
  182. package/build/assets/useQuery-BXWbZBZl.js +1 -0
  183. package/build/assets/utils-DaCIEEQP.js +1 -0
  184. package/build/assets/vendor~browser-hbU4u2Ag.js +47 -0
  185. package/build/assets/vendor~commits-tab-BaO2Ce3e.js +11 -0
  186. package/build/assets/vendor~conversation-panel~conversation-CTvDDiXg.js +1 -0
  187. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kepq2zme-ZixYGy6E.js +186 -0
  188. package/build/assets/vendor~index-home~home~conversation-panel~conversation-BTyukeM-.js +13 -0
  189. package/build/assets/vendor~root-layout-BlUaZ18v.js +1 -0
  190. package/build/assets/vendor~root-layout~conversation-panel~conversation-BYAWJwQX.js +1 -0
  191. package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-CHaLEBVR.js +1 -0
  192. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-B2OLKL7N.js +1 -0
  193. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-DXqM7vqB.js +1 -0
  194. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-Dtu7BpYk.js +48 -0
  195. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iw7io29p-Dz-MAyNb.js +1 -0
  196. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-DonTKfQD.js +4949 -0
  197. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~jz4f6vo2-BgxDvUcf.js +8420 -0
  198. package/build/assets/verification-settings-Bj6bo097.js +1 -0
  199. package/build/assets/wrench-hi7Q13dF.js +1 -0
  200. package/build/assets/x-DkgltWa0.js +1 -0
  201. package/build/index.html +4 -4
  202. package/build/locales/ar/openhands.json +124 -43
  203. package/build/locales/ca/openhands.json +124 -43
  204. package/build/locales/de/openhands.json +124 -43
  205. package/build/locales/en/openhands.json +124 -43
  206. package/build/locales/es/openhands.json +124 -43
  207. package/build/locales/fr/openhands.json +124 -43
  208. package/build/locales/it/openhands.json +124 -43
  209. package/build/locales/ja/openhands.json +124 -43
  210. package/build/locales/ko-KR/openhands.json +124 -43
  211. package/build/locales/no/openhands.json +124 -43
  212. package/build/locales/pt/openhands.json +124 -43
  213. package/build/locales/tr/openhands.json +124 -43
  214. package/build/locales/uk/openhands.json +124 -43
  215. package/build/locales/zh-CN/openhands.json +124 -43
  216. package/build/locales/zh-TW/openhands.json +124 -43
  217. package/config/defaults.json +2 -2
  218. package/dist/api/agent-server-adapter.cjs +3 -3
  219. package/dist/api/agent-server-adapter.cjs.map +1 -1
  220. package/dist/api/agent-server-adapter.d.ts +10 -1
  221. package/dist/api/agent-server-adapter.js +115 -110
  222. package/dist/api/agent-server-adapter.js.map +1 -1
  223. package/dist/api/automation-service/automation-service.api.cjs +1 -1
  224. package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
  225. package/dist/api/automation-service/automation-service.api.d.ts +13 -2
  226. package/dist/api/automation-service/automation-service.api.js +99 -84
  227. package/dist/api/automation-service/automation-service.api.js.map +1 -1
  228. package/dist/api/backend-registry/url-selection.cjs +1 -1
  229. package/dist/api/backend-registry/url-selection.cjs.map +1 -1
  230. package/dist/api/backend-registry/url-selection.d.ts +2 -1
  231. package/dist/api/backend-registry/url-selection.js +2 -2
  232. package/dist/api/backend-registry/url-selection.js.map +1 -1
  233. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  234. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  235. package/dist/api/conversation-service/agent-server-conversation-service.api.js +29 -24
  236. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  237. package/dist/api/git-provider-items-service.cjs +2 -0
  238. package/dist/api/git-provider-items-service.cjs.map +1 -0
  239. package/dist/api/git-provider-items-service.d.ts +25 -0
  240. package/dist/api/git-provider-items-service.js +127 -0
  241. package/dist/api/git-provider-items-service.js.map +1 -0
  242. package/dist/api/mcp-health/probe-mcp-server-health.cjs +1 -1
  243. package/dist/api/mcp-health/probe-mcp-server-health.js +31 -31
  244. package/dist/api/open-hands.types.d.ts +0 -19
  245. package/dist/api/profiles-service/profiles-service.api.cjs.map +1 -1
  246. package/dist/api/profiles-service/profiles-service.api.d.ts +16 -2
  247. package/dist/api/profiles-service/profiles-service.api.js.map +1 -1
  248. package/dist/api/provider-connections-service/provider-connections-service.api.cjs +2 -0
  249. package/dist/api/provider-connections-service/provider-connections-service.api.cjs.map +1 -0
  250. package/dist/api/provider-connections-service/provider-connections-service.api.d.ts +34 -0
  251. package/dist/api/provider-connections-service/provider-connections-service.api.js +50 -0
  252. package/dist/api/provider-connections-service/provider-connections-service.api.js.map +1 -0
  253. package/dist/components/conversation-events/chat/event-content-helpers/create-skill-ready-event.cjs +1 -1
  254. package/dist/components/conversation-events/chat/event-content-helpers/create-skill-ready-event.cjs.map +1 -1
  255. package/dist/components/conversation-events/chat/event-content-helpers/create-skill-ready-event.js +1 -1
  256. package/dist/components/conversation-events/chat/event-content-helpers/create-skill-ready-event.js.map +1 -1
  257. package/dist/components/conversation-events/chat/event-message.cjs +1 -1
  258. package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
  259. package/dist/components/conversation-events/chat/event-message.js +1 -1
  260. package/dist/components/conversation-events/chat/event-message.js.map +1 -1
  261. package/dist/components/conversation-events/chat/messages.cjs.map +1 -1
  262. package/dist/components/conversation-events/chat/messages.js.map +1 -1
  263. package/dist/components/features/automations/add-automation-menu.d.ts +7 -0
  264. package/dist/components/features/automations/add-automation-modal.cjs +2 -0
  265. package/dist/components/features/automations/add-automation-modal.cjs.map +1 -0
  266. package/dist/components/features/automations/add-automation-modal.js +42 -0
  267. package/dist/components/features/automations/add-automation-modal.js.map +1 -0
  268. package/dist/components/features/automations/automation-action-button-classes.cjs +2 -0
  269. package/dist/components/features/automations/automation-action-button-classes.cjs.map +1 -0
  270. package/dist/components/features/automations/automation-action-button-classes.d.ts +0 -2
  271. package/dist/components/features/automations/automation-action-button-classes.js +8 -0
  272. package/dist/components/features/automations/automation-action-button-classes.js.map +1 -0
  273. package/dist/components/features/automations/automation-card-skeleton.cjs +2 -0
  274. package/dist/components/features/automations/automation-card-skeleton.cjs.map +1 -0
  275. package/dist/components/features/automations/automation-card-skeleton.js +33 -0
  276. package/dist/components/features/automations/automation-card-skeleton.js.map +1 -0
  277. package/dist/components/features/automations/automation-card.cjs +2 -0
  278. package/dist/components/features/automations/automation-card.cjs.map +1 -0
  279. package/dist/components/features/automations/automation-card.d.ts +1 -1
  280. package/dist/components/features/automations/automation-card.js +160 -0
  281. package/dist/components/features/automations/automation-card.js.map +1 -0
  282. package/dist/components/features/automations/automation-group.cjs +2 -0
  283. package/dist/components/features/automations/automation-group.cjs.map +1 -0
  284. package/dist/components/features/automations/automation-group.js +54 -0
  285. package/dist/components/features/automations/automation-group.js.map +1 -0
  286. package/dist/components/features/automations/automation-list-row.cjs +2 -0
  287. package/dist/components/features/automations/automation-list-row.cjs.map +1 -0
  288. package/dist/components/features/automations/automation-list-row.js +152 -0
  289. package/dist/components/features/automations/automation-list-row.js.map +1 -0
  290. package/dist/components/features/automations/automation-run-insights.cjs +2 -0
  291. package/dist/components/features/automations/automation-run-insights.cjs.map +1 -0
  292. package/dist/components/features/automations/automation-run-insights.js +46 -0
  293. package/dist/components/features/automations/automation-run-insights.js.map +1 -0
  294. package/dist/components/features/automations/automation-view-mode.cjs +2 -0
  295. package/dist/components/features/automations/automation-view-mode.cjs.map +1 -0
  296. package/dist/components/features/automations/automation-view-mode.d.ts +5 -1
  297. package/dist/components/features/automations/automation-view-mode.js +6 -0
  298. package/dist/components/features/automations/automation-view-mode.js.map +1 -0
  299. package/dist/components/features/automations/backend-not-configured.cjs +2 -0
  300. package/dist/components/features/automations/backend-not-configured.cjs.map +1 -0
  301. package/dist/components/features/automations/backend-not-configured.js +34 -0
  302. package/dist/components/features/automations/backend-not-configured.js.map +1 -0
  303. package/dist/components/features/automations/build-automation-menu-items.cjs +2 -0
  304. package/dist/components/features/automations/build-automation-menu-items.cjs.map +1 -0
  305. package/dist/components/features/automations/build-automation-menu-items.js +53 -0
  306. package/dist/components/features/automations/build-automation-menu-items.js.map +1 -0
  307. package/dist/components/features/automations/build-automation-pills.cjs +2 -0
  308. package/dist/components/features/automations/build-automation-pills.cjs.map +1 -0
  309. package/dist/components/features/automations/build-automation-pills.js +71 -0
  310. package/dist/components/features/automations/build-automation-pills.js.map +1 -0
  311. package/dist/components/features/automations/create-instructions.cjs +2 -0
  312. package/dist/components/features/automations/create-instructions.cjs.map +1 -0
  313. package/dist/components/features/automations/create-instructions.js +102 -0
  314. package/dist/components/features/automations/create-instructions.js.map +1 -0
  315. package/dist/components/features/automations/dashboard/automations-dashboard-controls.d.ts +4 -3
  316. package/dist/components/features/automations/detail/run-status-badge.cjs +2 -0
  317. package/dist/components/features/automations/detail/run-status-badge.cjs.map +1 -0
  318. package/dist/components/features/automations/detail/run-status-badge.js +102 -0
  319. package/dist/components/features/automations/detail/run-status-badge.js.map +1 -0
  320. package/dist/components/features/automations/empty-state.cjs +2 -0
  321. package/dist/components/features/automations/empty-state.cjs.map +1 -0
  322. package/dist/components/features/automations/empty-state.js +35 -0
  323. package/dist/components/features/automations/empty-state.js.map +1 -0
  324. package/dist/components/features/automations/error-state.cjs +2 -0
  325. package/dist/components/features/automations/error-state.cjs.map +1 -0
  326. package/dist/components/features/automations/error-state.js +28 -0
  327. package/dist/components/features/automations/error-state.js.map +1 -0
  328. package/dist/components/features/automations/import-automation-modal.d.ts +2 -1
  329. package/dist/components/features/automations/kebab-menu-item-content.cjs +2 -0
  330. package/dist/components/features/automations/kebab-menu-item-content.cjs.map +1 -0
  331. package/dist/components/features/automations/kebab-menu-item-content.js +21 -0
  332. package/dist/components/features/automations/kebab-menu-item-content.js.map +1 -0
  333. package/dist/components/features/automations/kebab-menu.cjs +2 -0
  334. package/dist/components/features/automations/kebab-menu.cjs.map +1 -0
  335. package/dist/components/features/automations/kebab-menu.d.ts +2 -1
  336. package/dist/components/features/automations/kebab-menu.js +76 -0
  337. package/dist/components/features/automations/kebab-menu.js.map +1 -0
  338. package/dist/components/features/automations/recommended-automations-launcher.cjs +2 -0
  339. package/dist/components/features/automations/recommended-automations-launcher.cjs.map +1 -0
  340. package/dist/components/features/automations/recommended-automations-launcher.d.ts +7 -1
  341. package/dist/components/features/automations/recommended-automations-launcher.js +134 -0
  342. package/dist/components/features/automations/recommended-automations-launcher.js.map +1 -0
  343. package/dist/components/features/automations/recommended-automations-rail.cjs +2 -0
  344. package/dist/components/features/automations/recommended-automations-rail.cjs.map +1 -0
  345. package/dist/components/features/automations/recommended-automations-rail.d.ts +9 -0
  346. package/dist/components/features/automations/recommended-automations-rail.js +127 -0
  347. package/dist/components/features/automations/recommended-automations-rail.js.map +1 -0
  348. package/dist/components/features/automations/recommended-automations-section.cjs +2 -0
  349. package/dist/components/features/automations/recommended-automations-section.cjs.map +1 -0
  350. package/dist/components/features/automations/recommended-automations-section.d.ts +2 -2
  351. package/dist/components/features/automations/recommended-automations-section.js +198 -0
  352. package/dist/components/features/automations/recommended-automations-section.js.map +1 -0
  353. package/dist/components/features/automations/responder-deployment-modal.cjs +2 -0
  354. package/dist/components/features/automations/responder-deployment-modal.cjs.map +1 -0
  355. package/dist/components/features/automations/responder-deployment-modal.js +75 -0
  356. package/dist/components/features/automations/responder-deployment-modal.js.map +1 -0
  357. package/dist/components/features/automations/status-badge.cjs +2 -0
  358. package/dist/components/features/automations/status-badge.cjs.map +1 -0
  359. package/dist/components/features/automations/status-badge.js +12 -0
  360. package/dist/components/features/automations/status-badge.js.map +1 -0
  361. package/dist/components/features/automations/to-latest-run-state.cjs +2 -0
  362. package/dist/components/features/automations/to-latest-run-state.cjs.map +1 -0
  363. package/dist/components/features/automations/to-latest-run-state.d.ts +6 -0
  364. package/dist/components/features/automations/to-latest-run-state.js +21 -0
  365. package/dist/components/features/automations/to-latest-run-state.js.map +1 -0
  366. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  367. package/dist/components/features/backends/backend-form-modal.js +10 -10
  368. package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
  369. package/dist/components/features/backends/manage-backends-modal.js +5 -5
  370. package/dist/components/features/chat/chat-interface.cjs +2 -2
  371. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  372. package/dist/components/features/chat/chat-interface.js +179 -177
  373. package/dist/components/features/chat/chat-interface.js.map +1 -1
  374. package/dist/components/features/command-menu/command-menu-items.d.ts +10 -4
  375. package/dist/components/features/conversation/conversation-git-actions-menu.cjs +2 -0
  376. package/dist/components/features/conversation/conversation-git-actions-menu.cjs.map +1 -0
  377. package/dist/components/features/conversation/conversation-git-actions-menu.d.ts +15 -0
  378. package/dist/components/features/conversation/conversation-git-actions-menu.js +123 -0
  379. package/dist/components/features/conversation/conversation-git-actions-menu.js.map +1 -0
  380. package/dist/components/features/conversation/conversation-git-actions-toggle.cjs +2 -0
  381. package/dist/components/features/conversation/conversation-git-actions-toggle.cjs.map +1 -0
  382. package/dist/components/features/conversation/conversation-git-actions-toggle.d.ts +10 -0
  383. package/dist/components/features/conversation/conversation-git-actions-toggle.js +60 -0
  384. package/dist/components/features/conversation/conversation-git-actions-toggle.js.map +1 -0
  385. package/dist/components/features/conversation/conversation-main/chat-interface-wrapper.cjs +1 -1
  386. package/dist/components/features/conversation/conversation-main/chat-interface-wrapper.cjs.map +1 -1
  387. package/dist/components/features/conversation/conversation-main/chat-interface-wrapper.js +46 -10
  388. package/dist/components/features/conversation/conversation-main/chat-interface-wrapper.js.map +1 -1
  389. package/dist/components/features/conversation/conversation-main/conversation-main.cjs +1 -1
  390. package/dist/components/features/conversation/conversation-main/conversation-main.cjs.map +1 -1
  391. package/dist/components/features/conversation/conversation-main/conversation-main.js +49 -43
  392. package/dist/components/features/conversation/conversation-main/conversation-main.js.map +1 -1
  393. package/dist/components/features/conversation/conversation-name-with-status.cjs +1 -1
  394. package/dist/components/features/conversation/conversation-name-with-status.cjs.map +1 -1
  395. package/dist/components/features/conversation/conversation-name-with-status.js +49 -40
  396. package/dist/components/features/conversation/conversation-name-with-status.js.map +1 -1
  397. package/dist/components/features/conversation/conversation-name.cjs +1 -1
  398. package/dist/components/features/conversation/conversation-name.js +4 -4
  399. package/dist/components/features/conversation/conversation-overview-automations-panel.cjs +2 -0
  400. package/dist/components/features/conversation/conversation-overview-automations-panel.cjs.map +1 -0
  401. package/dist/components/features/conversation/conversation-overview-automations-panel.d.ts +6 -0
  402. package/dist/components/features/conversation/conversation-overview-automations-panel.js +48 -0
  403. package/dist/components/features/conversation/conversation-overview-automations-panel.js.map +1 -0
  404. package/dist/components/features/conversation/conversation-overview-context-menu.cjs +2 -0
  405. package/dist/components/features/conversation/conversation-overview-context-menu.cjs.map +1 -0
  406. package/dist/components/features/conversation/conversation-overview-context-menu.d.ts +10 -0
  407. package/dist/components/features/conversation/conversation-overview-context-menu.js +221 -0
  408. package/dist/components/features/conversation/conversation-overview-context-menu.js.map +1 -0
  409. package/dist/components/features/conversation/conversation-overview-diffs-row.cjs +2 -0
  410. package/dist/components/features/conversation/conversation-overview-diffs-row.cjs.map +1 -0
  411. package/dist/components/features/conversation/conversation-overview-diffs-row.d.ts +2 -0
  412. package/dist/components/features/conversation/conversation-overview-diffs-row.js +88 -0
  413. package/dist/components/features/conversation/conversation-overview-diffs-row.js.map +1 -0
  414. package/dist/components/features/conversation/conversation-overview-drawer-content.cjs +2 -0
  415. package/dist/components/features/conversation/conversation-overview-drawer-content.cjs.map +1 -0
  416. package/dist/components/features/conversation/conversation-overview-drawer-content.d.ts +6 -0
  417. package/dist/components/features/conversation/conversation-overview-drawer-content.js +138 -0
  418. package/dist/components/features/conversation/conversation-overview-drawer-content.js.map +1 -0
  419. package/dist/components/features/conversation/conversation-overview-drawer-context.cjs +2 -0
  420. package/dist/components/features/conversation/conversation-overview-drawer-context.cjs.map +1 -0
  421. package/dist/components/features/conversation/conversation-overview-drawer-context.d.ts +17 -0
  422. package/dist/components/features/conversation/conversation-overview-drawer-context.js +43 -0
  423. package/dist/components/features/conversation/conversation-overview-drawer-context.js.map +1 -0
  424. package/dist/components/features/conversation/conversation-overview-drawer.cjs +2 -0
  425. package/dist/components/features/conversation/conversation-overview-drawer.cjs.map +1 -0
  426. package/dist/components/features/conversation/conversation-overview-drawer.constants.cjs +2 -0
  427. package/dist/components/features/conversation/conversation-overview-drawer.constants.cjs.map +1 -0
  428. package/dist/components/features/conversation/conversation-overview-drawer.constants.d.ts +6 -0
  429. package/dist/components/features/conversation/conversation-overview-drawer.constants.js +6 -0
  430. package/dist/components/features/conversation/conversation-overview-drawer.constants.js.map +1 -0
  431. package/dist/components/features/conversation/conversation-overview-drawer.d.ts +7 -0
  432. package/dist/components/features/conversation/conversation-overview-drawer.js +45 -0
  433. package/dist/components/features/conversation/conversation-overview-drawer.js.map +1 -0
  434. package/dist/components/features/conversation/conversation-overview-drawer.types.cjs +2 -0
  435. package/dist/components/features/conversation/conversation-overview-drawer.types.cjs.map +1 -0
  436. package/dist/components/features/conversation/conversation-overview-drawer.types.d.ts +12 -0
  437. package/dist/components/features/conversation/conversation-overview-drawer.types.js +13 -0
  438. package/dist/components/features/conversation/conversation-overview-drawer.types.js.map +1 -0
  439. package/dist/components/features/conversation/conversation-overview-git-items-panel.cjs +2 -0
  440. package/dist/components/features/conversation/conversation-overview-git-items-panel.cjs.map +1 -0
  441. package/dist/components/features/conversation/conversation-overview-git-items-panel.d.ts +7 -0
  442. package/dist/components/features/conversation/conversation-overview-git-items-panel.js +81 -0
  443. package/dist/components/features/conversation/conversation-overview-git-items-panel.js.map +1 -0
  444. package/dist/components/features/conversation/conversation-overview-git-section.cjs +2 -0
  445. package/dist/components/features/conversation/conversation-overview-git-section.cjs.map +1 -0
  446. package/dist/components/features/conversation/conversation-overview-git-section.d.ts +6 -0
  447. package/dist/components/features/conversation/conversation-overview-git-section.js +143 -0
  448. package/dist/components/features/conversation/conversation-overview-git-section.js.map +1 -0
  449. package/dist/components/features/conversation/conversation-overview-mcp-panel.cjs +2 -0
  450. package/dist/components/features/conversation/conversation-overview-mcp-panel.cjs.map +1 -0
  451. package/dist/components/features/conversation/conversation-overview-mcp-panel.d.ts +6 -0
  452. package/dist/components/features/conversation/conversation-overview-mcp-panel.js +108 -0
  453. package/dist/components/features/conversation/conversation-overview-mcp-panel.js.map +1 -0
  454. package/dist/components/features/conversation/conversation-overview-panel.cjs +2 -0
  455. package/dist/components/features/conversation/conversation-overview-panel.cjs.map +1 -0
  456. package/dist/components/features/conversation/conversation-overview-panel.constants.cjs +2 -0
  457. package/dist/components/features/conversation/conversation-overview-panel.constants.cjs.map +1 -0
  458. package/dist/components/features/conversation/conversation-overview-panel.constants.d.ts +24 -0
  459. package/dist/components/features/conversation/conversation-overview-panel.constants.js +12 -0
  460. package/dist/components/features/conversation/conversation-overview-panel.constants.js.map +1 -0
  461. package/dist/components/features/conversation/conversation-overview-panel.d.ts +2 -0
  462. package/dist/components/features/conversation/conversation-overview-panel.js +102 -0
  463. package/dist/components/features/conversation/conversation-overview-panel.js.map +1 -0
  464. package/dist/components/features/conversation/conversation-overview-project-scope-toggle.cjs +2 -0
  465. package/dist/components/features/conversation/conversation-overview-project-scope-toggle.cjs.map +1 -0
  466. package/dist/components/features/conversation/conversation-overview-project-scope-toggle.d.ts +8 -0
  467. package/dist/components/features/conversation/conversation-overview-project-scope-toggle.js +29 -0
  468. package/dist/components/features/conversation/conversation-overview-project-scope-toggle.js.map +1 -0
  469. package/dist/components/features/conversation/conversation-overview-secrets-panel.cjs +2 -0
  470. package/dist/components/features/conversation/conversation-overview-secrets-panel.cjs.map +1 -0
  471. package/dist/components/features/conversation/conversation-overview-secrets-panel.d.ts +6 -0
  472. package/dist/components/features/conversation/conversation-overview-secrets-panel.js +89 -0
  473. package/dist/components/features/conversation/conversation-overview-secrets-panel.js.map +1 -0
  474. package/dist/components/features/conversation/conversation-overview-sections.cjs +2 -0
  475. package/dist/components/features/conversation/conversation-overview-sections.cjs.map +1 -0
  476. package/dist/components/features/conversation/conversation-overview-sections.d.ts +43 -0
  477. package/dist/components/features/conversation/conversation-overview-sections.js +27 -0
  478. package/dist/components/features/conversation/conversation-overview-sections.js.map +1 -0
  479. package/dist/components/features/conversation/conversation-overview-skills-panel.cjs +2 -0
  480. package/dist/components/features/conversation/conversation-overview-skills-panel.cjs.map +1 -0
  481. package/dist/components/features/conversation/conversation-overview-skills-panel.d.ts +6 -0
  482. package/dist/components/features/conversation/conversation-overview-skills-panel.js +138 -0
  483. package/dist/components/features/conversation/conversation-overview-skills-panel.js.map +1 -0
  484. package/dist/components/features/conversation/conversation-overview-toggle.cjs +2 -0
  485. package/dist/components/features/conversation/conversation-overview-toggle.cjs.map +1 -0
  486. package/dist/components/features/conversation/conversation-overview-toggle.d.ts +11 -0
  487. package/dist/components/features/conversation/conversation-overview-toggle.js +99 -0
  488. package/dist/components/features/conversation/conversation-overview-toggle.js.map +1 -0
  489. package/dist/components/features/conversation/conversation-secondary-drawer.classes.cjs +2 -0
  490. package/dist/components/features/conversation/conversation-secondary-drawer.classes.cjs.map +1 -0
  491. package/dist/components/features/conversation/conversation-secondary-drawer.classes.d.ts +4 -0
  492. package/dist/components/features/conversation/conversation-secondary-drawer.classes.js +7 -0
  493. package/dist/components/features/conversation/conversation-secondary-drawer.classes.js.map +1 -0
  494. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.cjs +1 -1
  495. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.cjs.map +1 -1
  496. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.js +10 -9
  497. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.js.map +1 -1
  498. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
  499. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
  500. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +68 -62
  501. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
  502. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
  503. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
  504. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +98 -88
  505. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
  506. package/dist/components/features/conversation/right-panel-toggle.cjs +1 -1
  507. package/dist/components/features/conversation/right-panel-toggle.cjs.map +1 -1
  508. package/dist/components/features/conversation/right-panel-toggle.d.ts +3 -2
  509. package/dist/components/features/conversation/right-panel-toggle.js +34 -33
  510. package/dist/components/features/conversation/right-panel-toggle.js.map +1 -1
  511. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs +1 -1
  512. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs.map +1 -1
  513. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.d.ts +2 -1
  514. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js +14 -7
  515. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js.map +1 -1
  516. package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
  517. package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
  518. package/dist/components/features/conversation-panel/conversation-panel.js +252 -225
  519. package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
  520. package/dist/components/features/conversation-panel/local-new-conversation-menu.cjs +1 -1
  521. package/dist/components/features/conversation-panel/local-new-conversation-menu.cjs.map +1 -1
  522. package/dist/components/features/conversation-panel/local-new-conversation-menu.js +4 -4
  523. package/dist/components/features/conversation-panel/local-new-conversation-menu.js.map +1 -1
  524. package/dist/components/features/diff-viewer/accordion-panel.cjs +2 -0
  525. package/dist/components/features/diff-viewer/accordion-panel.cjs.map +1 -0
  526. package/dist/components/features/diff-viewer/accordion-panel.d.ts +13 -0
  527. package/dist/components/features/diff-viewer/accordion-panel.js +41 -0
  528. package/dist/components/features/diff-viewer/accordion-panel.js.map +1 -0
  529. package/dist/components/features/diff-viewer/commit-list.cjs +1 -1
  530. package/dist/components/features/diff-viewer/commit-list.cjs.map +1 -1
  531. package/dist/components/features/diff-viewer/commit-list.d.ts +5 -1
  532. package/dist/components/features/diff-viewer/commit-list.js +30 -16
  533. package/dist/components/features/diff-viewer/commit-list.js.map +1 -1
  534. package/dist/components/features/diff-viewer/commit-row.cjs +1 -1
  535. package/dist/components/features/diff-viewer/commit-row.cjs.map +1 -1
  536. package/dist/components/features/diff-viewer/commit-row.d.ts +1 -2
  537. package/dist/components/features/diff-viewer/commit-row.js +38 -34
  538. package/dist/components/features/diff-viewer/commit-row.js.map +1 -1
  539. package/dist/components/features/diff-viewer/diff-change-list.cjs +2 -0
  540. package/dist/components/features/diff-viewer/diff-change-list.cjs.map +1 -0
  541. package/dist/components/features/diff-viewer/diff-change-list.d.ts +18 -0
  542. package/dist/components/features/diff-viewer/diff-change-list.js +22 -0
  543. package/dist/components/features/diff-viewer/diff-change-list.js.map +1 -0
  544. package/dist/components/features/diff-viewer/editor-container.cjs +1 -1
  545. package/dist/components/features/diff-viewer/editor-container.cjs.map +1 -1
  546. package/dist/components/features/diff-viewer/editor-container.d.ts +2 -1
  547. package/dist/components/features/diff-viewer/editor-container.js +8 -7
  548. package/dist/components/features/diff-viewer/editor-container.js.map +1 -1
  549. package/dist/components/features/diff-viewer/file-diff-viewer.cjs +1 -1
  550. package/dist/components/features/diff-viewer/file-diff-viewer.cjs.map +1 -1
  551. package/dist/components/features/diff-viewer/file-diff-viewer.d.ts +10 -1
  552. package/dist/components/features/diff-viewer/file-diff-viewer.js +138 -112
  553. package/dist/components/features/diff-viewer/file-diff-viewer.js.map +1 -1
  554. package/dist/components/features/diff-viewer/uncommitted-changes-row.cjs +2 -0
  555. package/dist/components/features/diff-viewer/uncommitted-changes-row.cjs.map +1 -0
  556. package/dist/components/features/diff-viewer/uncommitted-changes-row.d.ts +12 -0
  557. package/dist/components/features/diff-viewer/uncommitted-changes-row.js +51 -0
  558. package/dist/components/features/diff-viewer/uncommitted-changes-row.js.map +1 -0
  559. package/dist/components/features/files-tab/file-content-viewer.cjs +1 -1
  560. package/dist/components/features/files-tab/file-content-viewer.cjs.map +1 -1
  561. package/dist/components/features/files-tab/file-content-viewer.js +0 -1
  562. package/dist/components/features/files-tab/file-content-viewer.js.map +1 -1
  563. package/dist/components/features/files-tab/file-quick-row.cjs +1 -1
  564. package/dist/components/features/files-tab/file-quick-row.cjs.map +1 -1
  565. package/dist/components/features/files-tab/file-quick-row.d.ts +9 -7
  566. package/dist/components/features/files-tab/file-quick-row.js +63 -34
  567. package/dist/components/features/files-tab/file-quick-row.js.map +1 -1
  568. package/dist/components/features/files-tab/files-tab-tree.constants.cjs +2 -0
  569. package/dist/components/features/files-tab/files-tab-tree.constants.cjs.map +1 -0
  570. package/dist/components/features/files-tab/files-tab-tree.constants.d.ts +7 -0
  571. package/dist/components/features/files-tab/files-tab-tree.constants.js +6 -0
  572. package/dist/components/features/files-tab/files-tab-tree.constants.js.map +1 -0
  573. package/dist/components/features/files-tab/segmented-toggle.cjs +1 -1
  574. package/dist/components/features/files-tab/segmented-toggle.cjs.map +1 -1
  575. package/dist/components/features/files-tab/segmented-toggle.d.ts +5 -3
  576. package/dist/components/features/files-tab/segmented-toggle.js +10 -13
  577. package/dist/components/features/files-tab/segmented-toggle.js.map +1 -1
  578. package/dist/components/features/files-tab/tree-node.cjs +1 -1
  579. package/dist/components/features/files-tab/tree-node.cjs.map +1 -1
  580. package/dist/components/features/files-tab/tree-node.js +34 -32
  581. package/dist/components/features/files-tab/tree-node.js.map +1 -1
  582. package/dist/components/features/files-tab/workspace-path.cjs +2 -0
  583. package/dist/components/features/files-tab/workspace-path.cjs.map +1 -0
  584. package/dist/components/features/files-tab/workspace-path.d.ts +6 -0
  585. package/dist/components/features/files-tab/workspace-path.js +41 -0
  586. package/dist/components/features/files-tab/workspace-path.js.map +1 -0
  587. package/dist/components/features/home/featured-automations/automation-health-indicator.cjs +2 -0
  588. package/dist/components/features/home/featured-automations/automation-health-indicator.cjs.map +1 -0
  589. package/dist/components/features/home/featured-automations/automation-health-indicator.js +22 -0
  590. package/dist/components/features/home/featured-automations/automation-health-indicator.js.map +1 -0
  591. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.cjs +2 -0
  592. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.cjs.map +1 -0
  593. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.js +45 -0
  594. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.js.map +1 -0
  595. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.cjs +2 -0
  596. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.cjs.map +1 -0
  597. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.js +108 -0
  598. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.js.map +1 -0
  599. package/dist/components/features/home/featured-automations/automation-run-health.cjs +2 -0
  600. package/dist/components/features/home/featured-automations/automation-run-health.cjs.map +1 -0
  601. package/dist/components/features/home/featured-automations/automation-run-health.js +75 -0
  602. package/dist/components/features/home/featured-automations/automation-run-health.js.map +1 -0
  603. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs +2 -0
  604. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs.map +1 -0
  605. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js +74 -0
  606. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js.map +1 -0
  607. package/dist/components/features/home/featured-automations/pinned-automation-card.d.ts +3 -3
  608. package/dist/components/features/home/git-repo-dropdown/use-url-search.cjs +1 -1
  609. package/dist/components/features/home/git-repo-dropdown/use-url-search.cjs.map +1 -1
  610. package/dist/components/features/home/git-repo-dropdown/use-url-search.js +1 -1
  611. package/dist/components/features/home/git-repo-dropdown/use-url-search.js.map +1 -1
  612. package/dist/components/features/home/workspace-dropdown/folder-browser-modal.cjs +1 -1
  613. package/dist/components/features/home/workspace-dropdown/folder-browser-modal.js +6 -6
  614. package/dist/components/features/home/workspace-dropdown/manage-workspaces-modal.cjs +1 -1
  615. package/dist/components/features/home/workspace-dropdown/manage-workspaces-modal.js +6 -6
  616. package/dist/components/features/manifest/manifest-form-field.d.ts +4 -3
  617. package/dist/components/features/manifest/manifest-icons.cjs +2 -0
  618. package/dist/components/features/manifest/manifest-icons.cjs.map +1 -0
  619. package/dist/components/features/manifest/manifest-icons.d.ts +1 -0
  620. package/dist/components/features/manifest/manifest-icons.js +21 -0
  621. package/dist/components/features/manifest/manifest-icons.js.map +1 -0
  622. package/dist/components/features/manifest/manifest-repository-list.d.ts +25 -0
  623. package/dist/components/features/markdown/markdown-table-scroll.cjs +1 -1
  624. package/dist/components/features/markdown/markdown-table-scroll.cjs.map +1 -1
  625. package/dist/components/features/markdown/markdown-table-scroll.d.ts +2 -6
  626. package/dist/components/features/markdown/markdown-table-scroll.js +15 -21
  627. package/dist/components/features/markdown/markdown-table-scroll.js.map +1 -1
  628. package/dist/components/features/mcp-logo-badge.cjs +1 -1
  629. package/dist/components/features/mcp-logo-badge.cjs.map +1 -1
  630. package/dist/components/features/mcp-logo-badge.d.ts +1 -1
  631. package/dist/components/features/mcp-logo-badge.js +1 -0
  632. package/dist/components/features/mcp-logo-badge.js.map +1 -1
  633. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  634. package/dist/components/features/mcp-page/custom-server-editor.js +16 -16
  635. package/dist/components/features/mcp-page/index.cjs +1 -1
  636. package/dist/components/features/mcp-page/index.js +2 -2
  637. package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
  638. package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
  639. package/dist/components/features/mcp-page/install-server-modal.js +25 -25
  640. package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
  641. package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
  642. package/dist/components/features/mcp-page/installed-server-card.js +5 -5
  643. package/dist/components/features/mcp-page/marketplace-card.cjs +1 -1
  644. package/dist/components/features/mcp-page/marketplace-card.js +4 -4
  645. package/dist/components/features/mcp-page/marketplace-section.cjs +1 -1
  646. package/dist/components/features/mcp-page/marketplace-section.js +3 -3
  647. package/dist/components/features/mcp-page/mcp-logo-stack-badge.cjs +2 -0
  648. package/dist/components/features/mcp-page/mcp-logo-stack-badge.cjs.map +1 -0
  649. package/dist/components/features/mcp-page/mcp-logo-stack-badge.js +60 -0
  650. package/dist/components/features/mcp-page/mcp-logo-stack-badge.js.map +1 -0
  651. package/dist/components/features/mcp-page/mcp-server-health.cjs +1 -1
  652. package/dist/components/features/mcp-page/mcp-server-health.js +18 -18
  653. package/dist/components/features/onboarding/use-onboarding-completion.cjs +2 -0
  654. package/dist/components/features/onboarding/use-onboarding-completion.cjs.map +1 -0
  655. package/dist/components/features/onboarding/use-onboarding-completion.js +32 -0
  656. package/dist/components/features/onboarding/use-onboarding-completion.js.map +1 -0
  657. package/dist/components/features/settings/app-settings/getting-started-checklist-switch.cjs +2 -0
  658. package/dist/components/features/settings/app-settings/getting-started-checklist-switch.cjs.map +1 -0
  659. package/dist/components/features/settings/app-settings/getting-started-checklist-switch.d.ts +1 -0
  660. package/dist/components/features/settings/app-settings/getting-started-checklist-switch.js +22 -0
  661. package/dist/components/features/settings/app-settings/getting-started-checklist-switch.js.map +1 -0
  662. package/dist/components/features/settings/brand-button.cjs +1 -1
  663. package/dist/components/features/settings/brand-button.cjs.map +1 -1
  664. package/dist/components/features/settings/brand-button.d.ts +2 -0
  665. package/dist/components/features/settings/brand-button.js +4 -2
  666. package/dist/components/features/settings/brand-button.js.map +1 -1
  667. package/dist/components/features/settings/llm-profiles/delete-provider-connection-modal.cjs +1 -0
  668. package/dist/components/features/settings/llm-profiles/delete-provider-connection-modal.d.ts +7 -0
  669. package/dist/components/features/settings/llm-profiles/delete-provider-connection-modal.js +7 -0
  670. package/dist/components/features/settings/llm-profiles/llm-profiles-manager.cjs +1 -1
  671. package/dist/components/features/settings/llm-profiles/llm-profiles-manager.js +3 -0
  672. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
  673. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +1 -0
  674. package/dist/components/features/settings/llm-profiles/profiles-body.d.ts +20 -1
  675. package/dist/components/features/settings/llm-profiles/provider-connection-modal.cjs +1 -0
  676. package/dist/components/features/settings/llm-profiles/provider-connection-modal.d.ts +19 -0
  677. package/dist/components/features/settings/llm-profiles/provider-connection-modal.js +10 -0
  678. package/dist/components/features/settings/llm-profiles/provider-connection-row.cjs +1 -0
  679. package/dist/components/features/settings/llm-profiles/provider-connection-row.d.ts +10 -0
  680. package/dist/components/features/settings/llm-profiles/provider-connection-row.js +6 -0
  681. package/dist/components/features/settings/llm-profiles/provider-connections-manager.cjs +1 -0
  682. package/dist/components/features/settings/llm-profiles/provider-connections-manager.d.ts +15 -0
  683. package/dist/components/features/settings/llm-profiles/provider-connections-manager.js +8 -0
  684. package/dist/components/features/settings/sdk-settings/schema-field.cjs +1 -1
  685. package/dist/components/features/settings/sdk-settings/schema-field.js +6 -6
  686. package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs +1 -1
  687. package/dist/components/features/settings/sdk-settings/sdk-section-page.js +7 -7
  688. package/dist/components/features/settings/sdk-settings/sdk-section-page.js.map +1 -1
  689. package/dist/components/features/settings/secrets-settings/secret-form.cjs +1 -1
  690. package/dist/components/features/settings/secrets-settings/secret-form.js +7 -7
  691. package/dist/components/features/settings/settings-input.cjs +1 -1
  692. package/dist/components/features/settings/settings-input.cjs.map +1 -1
  693. package/dist/components/features/settings/settings-input.d.ts +6 -0
  694. package/dist/components/features/settings/settings-input.js +14 -13
  695. package/dist/components/features/settings/settings-input.js.map +1 -1
  696. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-icon.cjs +2 -0
  697. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-icon.cjs.map +1 -0
  698. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-icon.d.ts +7 -0
  699. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-icon.js +102 -0
  700. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-icon.js.map +1 -0
  701. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-preview.cjs +2 -0
  702. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-preview.cjs.map +1 -0
  703. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-preview.d.ts +8 -0
  704. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-preview.js +66 -0
  705. package/dist/components/features/sidebar/sidebar-onboarding-checklist-item-preview.js.map +1 -0
  706. package/dist/components/features/sidebar/sidebar-onboarding-checklist-llm-complete.cjs +2 -0
  707. package/dist/components/features/sidebar/sidebar-onboarding-checklist-llm-complete.cjs.map +1 -0
  708. package/dist/components/features/sidebar/sidebar-onboarding-checklist-llm-complete.d.ts +3 -0
  709. package/dist/components/features/sidebar/sidebar-onboarding-checklist-llm-complete.js +15 -0
  710. package/dist/components/features/sidebar/sidebar-onboarding-checklist-llm-complete.js.map +1 -0
  711. package/dist/components/features/sidebar/sidebar-onboarding-checklist-storage.cjs +2 -0
  712. package/dist/components/features/sidebar/sidebar-onboarding-checklist-storage.cjs.map +1 -0
  713. package/dist/components/features/sidebar/sidebar-onboarding-checklist-storage.d.ts +10 -0
  714. package/dist/components/features/sidebar/sidebar-onboarding-checklist-storage.js +39 -0
  715. package/dist/components/features/sidebar/sidebar-onboarding-checklist-storage.js.map +1 -0
  716. package/dist/components/features/sidebar/sidebar-onboarding-checklist.cjs +2 -0
  717. package/dist/components/features/sidebar/sidebar-onboarding-checklist.cjs.map +1 -0
  718. package/dist/components/features/sidebar/sidebar-onboarding-checklist.constants.cjs +2 -0
  719. package/dist/components/features/sidebar/sidebar-onboarding-checklist.constants.cjs.map +1 -0
  720. package/dist/components/features/sidebar/sidebar-onboarding-checklist.constants.d.ts +26 -0
  721. package/dist/components/features/sidebar/sidebar-onboarding-checklist.constants.js +78 -0
  722. package/dist/components/features/sidebar/sidebar-onboarding-checklist.constants.js.map +1 -0
  723. package/dist/components/features/sidebar/sidebar-onboarding-checklist.d.ts +5 -0
  724. package/dist/components/features/sidebar/sidebar-onboarding-checklist.js +127 -0
  725. package/dist/components/features/sidebar/sidebar-onboarding-checklist.js.map +1 -0
  726. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  727. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  728. package/dist/components/features/sidebar/sidebar-rail-body.js +115 -111
  729. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  730. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist-dismissed.cjs +2 -0
  731. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist-dismissed.cjs.map +1 -0
  732. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist-dismissed.d.ts +1 -0
  733. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist-dismissed.js +10 -0
  734. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist-dismissed.js.map +1 -0
  735. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.cjs +2 -0
  736. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.cjs.map +1 -0
  737. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.d.ts +15 -0
  738. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.js +75 -0
  739. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.js.map +1 -0
  740. package/dist/components/features/skills/add-skill-modal.cjs +2 -0
  741. package/dist/components/features/skills/add-skill-modal.cjs.map +1 -0
  742. package/dist/components/features/skills/add-skill-modal.js +164 -0
  743. package/dist/components/features/skills/add-skill-modal.js.map +1 -0
  744. package/dist/components/features/skills/build-skill-pills.cjs +2 -0
  745. package/dist/components/features/skills/build-skill-pills.cjs.map +1 -0
  746. package/dist/components/features/skills/build-skill-pills.js +88 -0
  747. package/dist/components/features/skills/build-skill-pills.js.map +1 -0
  748. package/dist/components/features/skills/get-skill-card-description.cjs +2 -0
  749. package/dist/components/features/skills/get-skill-card-description.cjs.map +1 -0
  750. package/dist/components/features/skills/get-skill-card-description.js +34 -0
  751. package/dist/components/features/skills/get-skill-card-description.js.map +1 -0
  752. package/dist/components/features/skills/get-skill-chat-launch-message.cjs +2 -0
  753. package/dist/components/features/skills/get-skill-chat-launch-message.cjs.map +1 -0
  754. package/dist/components/features/skills/get-skill-chat-launch-message.js +9 -0
  755. package/dist/components/features/skills/get-skill-chat-launch-message.js.map +1 -0
  756. package/dist/components/features/skills/is-copyable-skill-source.cjs +2 -0
  757. package/dist/components/features/skills/is-copyable-skill-source.cjs.map +1 -0
  758. package/dist/components/features/skills/is-copyable-skill-source.js +9 -0
  759. package/dist/components/features/skills/is-copyable-skill-source.js.map +1 -0
  760. package/dist/components/features/skills/skill-card-pill-row.cjs +2 -0
  761. package/dist/components/features/skills/skill-card-pill-row.cjs.map +1 -0
  762. package/dist/components/features/skills/skill-card-pill-row.d.ts +1 -1
  763. package/dist/components/features/skills/skill-card-pill-row.js +137 -0
  764. package/dist/components/features/skills/skill-card-pill-row.js.map +1 -0
  765. package/dist/components/features/skills/skill-card.cjs +2 -0
  766. package/dist/components/features/skills/skill-card.cjs.map +1 -0
  767. package/dist/components/features/skills/skill-card.js +93 -0
  768. package/dist/components/features/skills/skill-card.js.map +1 -0
  769. package/dist/components/features/skills/skill-detail-modal.cjs +3 -0
  770. package/dist/components/features/skills/skill-detail-modal.cjs.map +1 -0
  771. package/dist/components/features/skills/skill-detail-modal.js +150 -0
  772. package/dist/components/features/skills/skill-detail-modal.js.map +1 -0
  773. package/dist/components/features/skills/skill-facet-rail.cjs +2 -0
  774. package/dist/components/features/skills/skill-facet-rail.cjs.map +1 -0
  775. package/dist/components/features/skills/skill-facet-rail.js +42 -0
  776. package/dist/components/features/skills/skill-facet-rail.js.map +1 -0
  777. package/dist/components/features/skills/skill-facet-row.cjs +2 -0
  778. package/dist/components/features/skills/skill-facet-row.cjs.map +1 -0
  779. package/dist/components/features/skills/skill-facet-row.js +44 -0
  780. package/dist/components/features/skills/skill-facet-row.js.map +1 -0
  781. package/dist/components/features/skills/skill-filter.cjs +2 -0
  782. package/dist/components/features/skills/skill-filter.cjs.map +1 -0
  783. package/dist/components/features/skills/skill-filter.js +166 -0
  784. package/dist/components/features/skills/skill-filter.js.map +1 -0
  785. package/dist/components/features/skills/skill-filters-modal.cjs +2 -0
  786. package/dist/components/features/skills/skill-filters-modal.cjs.map +1 -0
  787. package/dist/components/features/skills/skill-filters-modal.js +53 -0
  788. package/dist/components/features/skills/skill-filters-modal.js.map +1 -0
  789. package/dist/components/features/skills/skill-icon-badge.cjs +2 -0
  790. package/dist/components/features/skills/skill-icon-badge.cjs.map +1 -0
  791. package/dist/components/features/skills/skill-icon-badge.js +17 -0
  792. package/dist/components/features/skills/skill-icon-badge.js.map +1 -0
  793. package/dist/components/features/skills/skill-type-badge.cjs +2 -0
  794. package/dist/components/features/skills/skill-type-badge.cjs.map +1 -0
  795. package/dist/components/features/skills/skill-type-badge.js +21 -0
  796. package/dist/components/features/skills/skill-type-badge.js.map +1 -0
  797. package/dist/components/features/skills/skills-toolbar.cjs +2 -0
  798. package/dist/components/features/skills/skills-toolbar.cjs.map +1 -0
  799. package/dist/components/features/skills/skills-toolbar.js +63 -0
  800. package/dist/components/features/skills/skills-toolbar.js.map +1 -0
  801. package/dist/components/shared/buttons/circle-plus-check-toggle.cjs +1 -1
  802. package/dist/components/shared/buttons/circle-plus-check-toggle.cjs.map +1 -1
  803. package/dist/components/shared/buttons/circle-plus-check-toggle.js +19 -6
  804. package/dist/components/shared/buttons/circle-plus-check-toggle.js.map +1 -1
  805. package/dist/components/shared/filters/enum-filter-dropdown.cjs +1 -1
  806. package/dist/components/shared/filters/enum-filter-dropdown.cjs.map +1 -1
  807. package/dist/components/shared/filters/enum-filter-dropdown.d.ts +4 -1
  808. package/dist/components/shared/filters/enum-filter-dropdown.js +14 -14
  809. package/dist/components/shared/filters/enum-filter-dropdown.js.map +1 -1
  810. package/dist/components/shared/modals/settings/settings-form.cjs +1 -1
  811. package/dist/components/shared/modals/settings/settings-form.js +4 -4
  812. package/dist/components/ui/resize-handle.cjs +1 -1
  813. package/dist/components/ui/resize-handle.cjs.map +1 -1
  814. package/dist/components/ui/resize-handle.d.ts +2 -1
  815. package/dist/components/ui/resize-handle.js +6 -5
  816. package/dist/components/ui/resize-handle.js.map +1 -1
  817. package/dist/config/defaults.cjs +1 -1
  818. package/dist/config/defaults.cjs.map +1 -1
  819. package/dist/config/defaults.js +2 -2
  820. package/dist/config/defaults.js.map +1 -1
  821. package/dist/constants/skills-docs.cjs +2 -0
  822. package/dist/constants/skills-docs.cjs.map +1 -0
  823. package/dist/constants/skills-docs.js +6 -0
  824. package/dist/constants/skills-docs.js.map +1 -0
  825. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  826. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  827. package/dist/contexts/conversation-websocket-context.js +174 -149
  828. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  829. package/dist/fixtures/home-automations-demo.cjs +2 -0
  830. package/dist/fixtures/home-automations-demo.cjs.map +1 -0
  831. package/dist/fixtures/home-automations-demo.d.ts +1 -3
  832. package/dist/fixtures/home-automations-demo.js +384 -0
  833. package/dist/fixtures/home-automations-demo.js.map +1 -0
  834. package/dist/hooks/chat/use-slash-command.cjs +1 -1
  835. package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
  836. package/dist/hooks/chat/use-slash-command.d.ts +1 -2
  837. package/dist/hooks/chat/use-slash-command.js +1 -0
  838. package/dist/hooks/chat/use-slash-command.js.map +1 -1
  839. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  840. package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
  841. package/dist/hooks/mutation/use-create-conversation.js +27 -30
  842. package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
  843. package/dist/hooks/mutation/use-create-provider-connection.cjs +1 -0
  844. package/dist/hooks/mutation/use-create-provider-connection.d.ts +2 -0
  845. package/dist/hooks/mutation/use-create-provider-connection.js +1 -0
  846. package/dist/hooks/mutation/use-delete-mcp-server.cjs +1 -1
  847. package/dist/hooks/mutation/use-delete-mcp-server.js +3 -3
  848. package/dist/hooks/mutation/use-delete-provider-connection.cjs +1 -0
  849. package/dist/hooks/mutation/use-delete-provider-connection.d.ts +1 -0
  850. package/dist/hooks/mutation/use-delete-provider-connection.js +1 -0
  851. package/dist/hooks/mutation/use-switch-acp-model.cjs +1 -1
  852. package/dist/hooks/mutation/use-switch-acp-model.cjs.map +1 -1
  853. package/dist/hooks/mutation/use-switch-acp-model.d.ts +5 -3
  854. package/dist/hooks/mutation/use-switch-acp-model.js +9 -13
  855. package/dist/hooks/mutation/use-switch-acp-model.js.map +1 -1
  856. package/dist/hooks/mutation/use-update-mcp-server.cjs +1 -1
  857. package/dist/hooks/mutation/use-update-mcp-server.js +6 -6
  858. package/dist/hooks/mutation/use-update-provider-connection.cjs +1 -0
  859. package/dist/hooks/mutation/use-update-provider-connection.d.ts +7 -0
  860. package/dist/hooks/mutation/use-update-provider-connection.js +1 -0
  861. package/dist/hooks/query/query-keys.cjs +1 -1
  862. package/dist/hooks/query/query-keys.cjs.map +1 -1
  863. package/dist/hooks/query/query-keys.d.ts +3 -0
  864. package/dist/hooks/query/query-keys.js +4 -4
  865. package/dist/hooks/query/query-keys.js.map +1 -1
  866. package/dist/hooks/query/use-automation-detail.cjs +1 -0
  867. package/dist/hooks/query/use-automation-detail.js +2 -0
  868. package/dist/hooks/query/use-automation-health.cjs +2 -0
  869. package/dist/hooks/query/use-automation-health.cjs.map +1 -0
  870. package/dist/hooks/query/use-automation-health.js +22 -0
  871. package/dist/hooks/query/use-automation-health.js.map +1 -0
  872. package/dist/hooks/query/use-automations.cjs +2 -0
  873. package/dist/hooks/query/use-automations.cjs.map +1 -0
  874. package/dist/hooks/query/use-automations.js +28 -0
  875. package/dist/hooks/query/use-automations.js.map +1 -0
  876. package/dist/hooks/query/use-backends-health.cjs +1 -1
  877. package/dist/hooks/query/use-backends-health.cjs.map +1 -1
  878. package/dist/hooks/query/use-backends-health.js +1 -1
  879. package/dist/hooks/query/use-backends-health.js.map +1 -1
  880. package/dist/hooks/query/use-commit-changes.cjs +1 -1
  881. package/dist/hooks/query/use-commit-changes.js +4 -4
  882. package/dist/hooks/query/use-conversation-history.cjs +1 -1
  883. package/dist/hooks/query/use-conversation-history.cjs.map +1 -1
  884. package/dist/hooks/query/use-conversation-history.js +3 -1
  885. package/dist/hooks/query/use-conversation-history.js.map +1 -1
  886. package/dist/hooks/query/use-conversation-metrics.cjs +1 -1
  887. package/dist/hooks/query/use-conversation-metrics.js +3 -3
  888. package/dist/hooks/query/use-latest-automation-runs.cjs +1 -0
  889. package/dist/hooks/query/use-latest-automation-runs.d.ts +2 -0
  890. package/dist/hooks/query/use-latest-automation-runs.js +3 -0
  891. package/dist/hooks/query/use-llm-profiles.d.ts +1 -1
  892. package/dist/hooks/query/use-paginated-conversations.cjs +1 -1
  893. package/dist/hooks/query/use-paginated-conversations.cjs.map +1 -1
  894. package/dist/hooks/query/use-paginated-conversations.js +1 -1
  895. package/dist/hooks/query/use-paginated-conversations.js.map +1 -1
  896. package/dist/hooks/query/use-provider-connections.cjs +2 -0
  897. package/dist/hooks/query/use-provider-connections.cjs.map +1 -0
  898. package/dist/hooks/query/use-provider-connections.d.ts +8 -0
  899. package/dist/hooks/query/use-provider-connections.js +19 -0
  900. package/dist/hooks/query/use-provider-connections.js.map +1 -0
  901. package/dist/hooks/query/use-repository-git-items.cjs +2 -0
  902. package/dist/hooks/query/use-repository-git-items.cjs.map +1 -0
  903. package/dist/hooks/query/use-repository-git-items.d.ts +3 -0
  904. package/dist/hooks/query/use-repository-git-items.js +33 -0
  905. package/dist/hooks/query/use-repository-git-items.js.map +1 -0
  906. package/dist/hooks/query/use-unified-get-git-changes.cjs +1 -1
  907. package/dist/hooks/query/use-unified-get-git-changes.js +4 -4
  908. package/dist/hooks/query/use-unified-git-commits.cjs +1 -1
  909. package/dist/hooks/query/use-unified-git-commits.js +4 -4
  910. package/dist/hooks/query/use-unified-git-diff.cjs +1 -1
  911. package/dist/hooks/query/use-unified-git-diff.js +4 -4
  912. package/dist/hooks/query/use-workspace-files.cjs +1 -1
  913. package/dist/hooks/query/use-workspace-files.js +6 -6
  914. package/dist/hooks/use-bash-command-runner.cjs +1 -1
  915. package/dist/hooks/use-bash-command-runner.cjs.map +1 -1
  916. package/dist/hooks/use-bash-command-runner.js +45 -42
  917. package/dist/hooks/use-bash-command-runner.js.map +1 -1
  918. package/dist/hooks/use-conversation-overview-column-space.cjs +2 -0
  919. package/dist/hooks/use-conversation-overview-column-space.cjs.map +1 -0
  920. package/dist/hooks/use-conversation-overview-column-space.d.ts +2 -0
  921. package/dist/hooks/use-conversation-overview-column-space.js +25 -0
  922. package/dist/hooks/use-conversation-overview-column-space.js.map +1 -0
  923. package/dist/hooks/use-conversation-overview-git-diff-stats.cjs +2 -0
  924. package/dist/hooks/use-conversation-overview-git-diff-stats.cjs.map +1 -0
  925. package/dist/hooks/use-conversation-overview-git-diff-stats.d.ts +7 -0
  926. package/dist/hooks/use-conversation-overview-git-diff-stats.js +37 -0
  927. package/dist/hooks/use-conversation-overview-git-diff-stats.js.map +1 -0
  928. package/dist/hooks/use-conversation-overview-panel-peek.cjs +2 -0
  929. package/dist/hooks/use-conversation-overview-panel-peek.cjs.map +1 -0
  930. package/dist/hooks/use-conversation-overview-panel-peek.d.ts +9 -0
  931. package/dist/hooks/use-conversation-overview-panel-peek.js +32 -0
  932. package/dist/hooks/use-conversation-overview-panel-peek.js.map +1 -0
  933. package/dist/hooks/use-conversation-overview-stats.cjs +2 -0
  934. package/dist/hooks/use-conversation-overview-stats.cjs.map +1 -0
  935. package/dist/hooks/use-conversation-overview-stats.d.ts +4 -0
  936. package/dist/hooks/use-conversation-overview-stats.js +15 -0
  937. package/dist/hooks/use-conversation-overview-stats.js.map +1 -0
  938. package/dist/hooks/use-conversation-primary-repository.cjs +2 -0
  939. package/dist/hooks/use-conversation-primary-repository.cjs.map +1 -0
  940. package/dist/hooks/use-conversation-primary-repository.d.ts +11 -0
  941. package/dist/hooks/use-conversation-primary-repository.js +17 -0
  942. package/dist/hooks/use-conversation-primary-repository.js.map +1 -0
  943. package/dist/hooks/use-drag-scroll.cjs +2 -0
  944. package/dist/hooks/use-drag-scroll.cjs.map +1 -0
  945. package/dist/hooks/use-drag-scroll.d.ts +12 -0
  946. package/dist/hooks/use-drag-scroll.js +41 -0
  947. package/dist/hooks/use-drag-scroll.js.map +1 -0
  948. package/dist/hooks/use-has-permission.cjs +2 -0
  949. package/dist/hooks/use-has-permission.cjs.map +1 -0
  950. package/dist/hooks/use-has-permission.js +8 -0
  951. package/dist/hooks/use-has-permission.js.map +1 -0
  952. package/dist/hooks/use-home-automation-actions.cjs +2 -0
  953. package/dist/hooks/use-home-automation-actions.cjs.map +1 -0
  954. package/dist/hooks/use-home-automation-actions.js +15 -0
  955. package/dist/hooks/use-home-automation-actions.js.map +1 -0
  956. package/dist/hooks/use-launch-skill-in-chat.cjs +2 -0
  957. package/dist/hooks/use-launch-skill-in-chat.cjs.map +1 -0
  958. package/dist/hooks/use-launch-skill-in-chat.js +16 -0
  959. package/dist/hooks/use-launch-skill-in-chat.js.map +1 -0
  960. package/dist/hooks/use-mcp-server-health.cjs +1 -1
  961. package/dist/hooks/use-mcp-server-health.js +3 -3
  962. package/dist/hooks/use-resizable-drawer-width.cjs +2 -0
  963. package/dist/hooks/use-resizable-drawer-width.cjs.map +1 -0
  964. package/dist/hooks/use-resizable-drawer-width.d.ts +22 -0
  965. package/dist/hooks/use-resizable-drawer-width.js +46 -0
  966. package/dist/hooks/use-resizable-drawer-width.js.map +1 -0
  967. package/dist/hooks/use-responder-url-secret.cjs +2 -0
  968. package/dist/hooks/use-responder-url-secret.cjs.map +1 -0
  969. package/dist/hooks/use-responder-url-secret.js +51 -0
  970. package/dist/hooks/use-responder-url-secret.js.map +1 -0
  971. package/dist/hooks/use-select-conversation-tab.cjs +1 -1
  972. package/dist/hooks/use-select-conversation-tab.cjs.map +1 -1
  973. package/dist/hooks/use-select-conversation-tab.d.ts +2 -0
  974. package/dist/hooks/use-select-conversation-tab.js +15 -7
  975. package/dist/hooks/use-select-conversation-tab.js.map +1 -1
  976. package/dist/hooks/use-tracking.cjs +1 -1
  977. package/dist/hooks/use-tracking.cjs.map +1 -1
  978. package/dist/hooks/use-tracking.d.ts +17 -0
  979. package/dist/hooks/use-tracking.js +10 -0
  980. package/dist/hooks/use-tracking.js.map +1 -1
  981. package/dist/hooks/use-websocket.cjs +1 -1
  982. package/dist/hooks/use-websocket.cjs.map +1 -1
  983. package/dist/hooks/use-websocket.d.ts +1 -2
  984. package/dist/hooks/use-websocket.js +58 -51
  985. package/dist/hooks/use-websocket.js.map +1 -1
  986. package/dist/i18n/declaration.cjs +1 -1
  987. package/dist/i18n/declaration.cjs.map +1 -1
  988. package/dist/i18n/declaration.d.ts +124 -43
  989. package/dist/i18n/declaration.js +1 -1
  990. package/dist/i18n/declaration.js.map +1 -1
  991. package/dist/i18n/translation.cjs +3 -3
  992. package/dist/i18n/translation.cjs.map +1 -1
  993. package/dist/i18n/translation.js +2091 -714
  994. package/dist/i18n/translation.js.map +1 -1
  995. package/dist/icons/check-circle.cjs +2 -0
  996. package/dist/icons/check-circle.cjs.map +1 -0
  997. package/dist/icons/check-circle.js +20 -0
  998. package/dist/icons/check-circle.js.map +1 -0
  999. package/dist/icons/chevron-down.cjs +2 -0
  1000. package/dist/icons/chevron-down.cjs.map +1 -0
  1001. package/dist/icons/chevron-down.js +20 -0
  1002. package/dist/icons/chevron-down.js.map +1 -0
  1003. package/dist/icons/clock.cjs +2 -0
  1004. package/dist/icons/clock.cjs.map +1 -0
  1005. package/dist/icons/clock.js +20 -0
  1006. package/dist/icons/clock.js.map +1 -0
  1007. package/dist/icons/exclamation-circle.cjs +2 -0
  1008. package/dist/icons/exclamation-circle.cjs.map +1 -0
  1009. package/dist/icons/exclamation-circle.js +20 -0
  1010. package/dist/icons/exclamation-circle.js.map +1 -0
  1011. package/dist/icons/kebab-vertical.cjs +2 -0
  1012. package/dist/icons/kebab-vertical.cjs.map +1 -0
  1013. package/dist/icons/kebab-vertical.js +14 -0
  1014. package/dist/icons/kebab-vertical.js.map +1 -0
  1015. package/dist/icons/key.cjs +2 -0
  1016. package/dist/icons/key.cjs.map +1 -0
  1017. package/dist/icons/key.js +21 -0
  1018. package/dist/icons/key.js.map +1 -0
  1019. package/dist/icons/message-square-share.cjs +2 -0
  1020. package/dist/icons/message-square-share.cjs.map +1 -0
  1021. package/dist/icons/message-square-share.js +22 -0
  1022. package/dist/icons/message-square-share.js.map +1 -0
  1023. package/dist/icons/play.cjs +2 -0
  1024. package/dist/icons/play.cjs.map +1 -0
  1025. package/dist/icons/play.js +19 -0
  1026. package/dist/icons/play.js.map +1 -0
  1027. package/dist/icons/power.cjs +2 -0
  1028. package/dist/icons/power.cjs.map +1 -0
  1029. package/dist/icons/power.js +20 -0
  1030. package/dist/icons/power.js.map +1 -0
  1031. package/dist/icons/sparkle.cjs +2 -0
  1032. package/dist/icons/sparkle.cjs.map +1 -0
  1033. package/dist/icons/sparkle.js +20 -0
  1034. package/dist/icons/sparkle.js.map +1 -0
  1035. package/dist/icons/trash.cjs +2 -0
  1036. package/dist/icons/trash.cjs.map +1 -0
  1037. package/dist/icons/trash.js +20 -0
  1038. package/dist/icons/trash.js.map +1 -0
  1039. package/dist/icons/x-circle.cjs +2 -0
  1040. package/dist/icons/x-circle.cjs.map +1 -0
  1041. package/dist/icons/x-circle.js +20 -0
  1042. package/dist/icons/x-circle.js.map +1 -0
  1043. package/dist/locales/ar/openhands.json +124 -43
  1044. package/dist/locales/ca/openhands.json +124 -43
  1045. package/dist/locales/de/openhands.json +124 -43
  1046. package/dist/locales/en/openhands.json +124 -43
  1047. package/dist/locales/es/openhands.json +124 -43
  1048. package/dist/locales/fr/openhands.json +124 -43
  1049. package/dist/locales/it/openhands.json +124 -43
  1050. package/dist/locales/ja/openhands.json +124 -43
  1051. package/dist/locales/ko-KR/openhands.json +124 -43
  1052. package/dist/locales/no/openhands.json +124 -43
  1053. package/dist/locales/pt/openhands.json +124 -43
  1054. package/dist/locales/tr/openhands.json +124 -43
  1055. package/dist/locales/uk/openhands.json +124 -43
  1056. package/dist/locales/zh-CN/openhands.json +124 -43
  1057. package/dist/locales/zh-TW/openhands.json +124 -43
  1058. package/dist/manifests/automation-insights.cjs +2 -0
  1059. package/dist/manifests/automation-insights.cjs.map +1 -0
  1060. package/dist/manifests/automation-insights.d.ts +2 -0
  1061. package/dist/manifests/automation-insights.js +9 -0
  1062. package/dist/manifests/automation-insights.js.map +1 -0
  1063. package/dist/manifests/automation-interface.cjs +1 -1
  1064. package/dist/manifests/automation-interface.cjs.map +1 -1
  1065. package/dist/manifests/automation-interface.d.ts +47 -31
  1066. package/dist/manifests/automation-interface.js +48 -54
  1067. package/dist/manifests/automation-interface.js.map +1 -1
  1068. package/dist/manifests/automation-setup.cjs +1 -1
  1069. package/dist/manifests/automation-setup.cjs.map +1 -1
  1070. package/dist/manifests/automation-setup.d.ts +37 -3
  1071. package/dist/manifests/automation-setup.js +16 -2
  1072. package/dist/manifests/automation-setup.js.map +1 -1
  1073. package/dist/manifests/interface-validation.cjs +1 -1
  1074. package/dist/manifests/interface-validation.cjs.map +1 -1
  1075. package/dist/manifests/interface-validation.js +56 -52
  1076. package/dist/manifests/interface-validation.js.map +1 -1
  1077. package/dist/manifests/manifest-actions.d.ts +5 -0
  1078. package/dist/manifests/manifest-bundle.d.ts +30 -0
  1079. package/dist/manifests/manifest-local-validation.d.ts +10 -1
  1080. package/dist/manifests/manifest-sources.cjs +1 -1
  1081. package/dist/manifests/manifest-sources.cjs.map +1 -1
  1082. package/dist/manifests/manifest-sources.js +3 -3
  1083. package/dist/manifests/manifest-sources.js.map +1 -1
  1084. package/dist/manifests/manifest-template.d.ts +14 -0
  1085. package/dist/manifests/manifest-validation.cjs +1 -1
  1086. package/dist/manifests/manifest-validation.cjs.map +1 -1
  1087. package/dist/manifests/manifest-validation.js +78 -45
  1088. package/dist/manifests/manifest-validation.js.map +1 -1
  1089. package/dist/manifests/types.cjs +1 -1
  1090. package/dist/manifests/types.cjs.map +1 -1
  1091. package/dist/manifests/types.d.ts +64 -3
  1092. package/dist/manifests/types.js +7 -6
  1093. package/dist/manifests/types.js.map +1 -1
  1094. package/dist/node_modules/@heroui/popover/dist/chunk-NW7HJLND.cjs +1 -1
  1095. package/dist/node_modules/@heroui/popover/dist/chunk-NW7HJLND.js +10 -10
  1096. package/dist/node_modules/@heroui/ripple/dist/chunk-UIQI3AYJ.cjs +1 -1
  1097. package/dist/node_modules/@heroui/ripple/dist/chunk-UIQI3AYJ.js +8 -8
  1098. package/dist/node_modules/@heroui/tooltip/dist/chunk-AUA5GDXN.cjs +1 -1
  1099. package/dist/node_modules/@heroui/tooltip/dist/chunk-AUA5GDXN.js +9 -9
  1100. package/dist/node_modules/@openhands/extensions/automations/bundle-index.cjs +4843 -0
  1101. package/dist/node_modules/@openhands/extensions/automations/bundle-index.cjs.map +1 -0
  1102. package/dist/node_modules/@openhands/extensions/automations/bundle-index.js +11 -0
  1103. package/dist/node_modules/@openhands/extensions/automations/bundle-index.js.map +1 -0
  1104. package/dist/node_modules/@openhands/extensions/automations/catalog/github-agents-md-maintainer/manifest.cjs +13 -0
  1105. package/dist/node_modules/@openhands/extensions/automations/catalog/github-agents-md-maintainer/manifest.cjs.map +1 -0
  1106. package/dist/node_modules/@openhands/extensions/automations/catalog/github-agents-md-maintainer/manifest.js +87 -0
  1107. package/dist/node_modules/@openhands/extensions/automations/catalog/github-agents-md-maintainer/manifest.js.map +1 -0
  1108. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs +12 -0
  1109. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs.map +1 -0
  1110. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js +98 -0
  1111. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js.map +1 -0
  1112. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +9 -7
  1113. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -1
  1114. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +32 -13
  1115. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -1
  1116. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs +2 -2
  1117. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs.map +1 -1
  1118. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js +29 -34
  1119. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js.map +1 -1
  1120. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs +3 -3
  1121. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs.map +1 -1
  1122. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js +2 -2
  1123. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js.map +1 -1
  1124. package/dist/node_modules/@openhands/extensions/automations/catalog/news-digest/manifest.cjs +14 -0
  1125. package/dist/node_modules/@openhands/extensions/automations/catalog/news-digest/manifest.cjs.map +1 -0
  1126. package/dist/node_modules/@openhands/extensions/automations/catalog/news-digest/manifest.js +72 -0
  1127. package/dist/node_modules/@openhands/extensions/automations/catalog/news-digest/manifest.js.map +1 -0
  1128. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +1 -1
  1129. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -1
  1130. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +16 -10
  1131. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -1
  1132. package/dist/node_modules/@openhands/extensions/automations/index.cjs +1 -1
  1133. package/dist/node_modules/@openhands/extensions/automations/index.cjs.map +1 -1
  1134. package/dist/node_modules/@openhands/extensions/automations/index.js +18 -13
  1135. package/dist/node_modules/@openhands/extensions/automations/index.js.map +1 -1
  1136. package/dist/node_modules/@openhands/extensions/automations/interface.cjs +1 -1
  1137. package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -1
  1138. package/dist/node_modules/@openhands/extensions/automations/interface.js +6 -2
  1139. package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -1
  1140. package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.cjs +1 -1
  1141. package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.cjs.map +1 -1
  1142. package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.js +36 -3
  1143. package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.js.map +1 -1
  1144. package/dist/node_modules/@openhands/extensions/integrations/catalog/sonarqube.cjs +2 -0
  1145. package/dist/node_modules/@openhands/extensions/integrations/catalog/sonarqube.cjs.map +1 -0
  1146. package/dist/node_modules/@openhands/extensions/integrations/catalog/sonarqube.js +75 -0
  1147. package/dist/node_modules/@openhands/extensions/integrations/catalog/sonarqube.js.map +1 -0
  1148. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs +1 -1
  1149. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs.map +1 -1
  1150. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js +68 -66
  1151. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js.map +1 -1
  1152. package/dist/node_modules/@openhands/extensions/skills/index.cjs +1002 -47
  1153. package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
  1154. package/dist/node_modules/@openhands/extensions/skills/index.js +59 -17
  1155. package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
  1156. package/dist/node_modules/lucide-react/dist/esm/icons/activity.cjs +2 -0
  1157. package/dist/node_modules/lucide-react/dist/esm/icons/activity.cjs.map +1 -0
  1158. package/dist/node_modules/lucide-react/dist/esm/icons/activity.js +9 -0
  1159. package/dist/node_modules/lucide-react/dist/esm/icons/activity.js.map +1 -0
  1160. package/dist/node_modules/lucide-react/dist/esm/icons/book-open.cjs +2 -0
  1161. package/dist/node_modules/lucide-react/dist/esm/icons/book-open.cjs.map +1 -0
  1162. package/dist/node_modules/lucide-react/dist/esm/icons/book-open.js +12 -0
  1163. package/dist/node_modules/lucide-react/dist/esm/icons/book-open.js.map +1 -0
  1164. package/dist/node_modules/lucide-react/dist/esm/icons/download.cjs +2 -0
  1165. package/dist/node_modules/lucide-react/dist/esm/icons/download.cjs.map +1 -0
  1166. package/dist/node_modules/lucide-react/dist/esm/icons/download.js +19 -0
  1167. package/dist/node_modules/lucide-react/dist/esm/icons/download.js.map +1 -0
  1168. package/dist/node_modules/lucide-react/dist/esm/icons/file-text.cjs +2 -0
  1169. package/dist/node_modules/lucide-react/dist/esm/icons/file-text.cjs.map +1 -0
  1170. package/dist/node_modules/lucide-react/dist/esm/icons/file-text.js +27 -0
  1171. package/dist/node_modules/lucide-react/dist/esm/icons/file-text.js.map +1 -0
  1172. package/dist/node_modules/lucide-react/dist/esm/icons/git-commit-horizontal.cjs +2 -0
  1173. package/dist/node_modules/lucide-react/dist/esm/icons/git-commit-horizontal.cjs.map +1 -0
  1174. package/dist/node_modules/lucide-react/dist/esm/icons/git-commit-horizontal.js +27 -0
  1175. package/dist/node_modules/lucide-react/dist/esm/icons/git-commit-horizontal.js.map +1 -0
  1176. package/dist/node_modules/lucide-react/dist/esm/icons/laptop.cjs +2 -0
  1177. package/dist/node_modules/lucide-react/dist/esm/icons/laptop.cjs.map +1 -0
  1178. package/dist/node_modules/lucide-react/dist/esm/icons/laptop.js +12 -0
  1179. package/dist/node_modules/lucide-react/dist/esm/icons/laptop.js.map +1 -0
  1180. package/dist/node_modules/lucide-react/dist/esm/icons/layout-dashboard.cjs +2 -0
  1181. package/dist/node_modules/lucide-react/dist/esm/icons/layout-dashboard.cjs.map +1 -0
  1182. package/dist/node_modules/lucide-react/dist/esm/icons/layout-dashboard.js +39 -0
  1183. package/dist/node_modules/lucide-react/dist/esm/icons/layout-dashboard.js.map +1 -0
  1184. package/dist/node_modules/lucide-react/dist/esm/icons/library.cjs +2 -0
  1185. package/dist/node_modules/lucide-react/dist/esm/icons/library.cjs.map +1 -0
  1186. package/dist/node_modules/lucide-react/dist/esm/icons/library.js +23 -0
  1187. package/dist/node_modules/lucide-react/dist/esm/icons/library.js.map +1 -0
  1188. package/dist/node_modules/lucide-react/dist/esm/icons/package.cjs +2 -0
  1189. package/dist/node_modules/lucide-react/dist/esm/icons/package.cjs.map +1 -0
  1190. package/dist/node_modules/lucide-react/dist/esm/icons/package.js +23 -0
  1191. package/dist/node_modules/lucide-react/dist/esm/icons/package.js.map +1 -0
  1192. package/dist/node_modules/lucide-react/dist/esm/icons/palette.cjs +2 -0
  1193. package/dist/node_modules/lucide-react/dist/esm/icons/palette.cjs.map +1 -0
  1194. package/dist/node_modules/lucide-react/dist/esm/icons/palette.js +39 -0
  1195. package/dist/node_modules/lucide-react/dist/esm/icons/palette.js.map +1 -0
  1196. package/dist/node_modules/lucide-react/dist/esm/icons/pen-line.cjs +2 -0
  1197. package/dist/node_modules/lucide-react/dist/esm/icons/pen-line.cjs.map +1 -0
  1198. package/dist/node_modules/lucide-react/dist/esm/icons/pen-line.js +12 -0
  1199. package/dist/node_modules/lucide-react/dist/esm/icons/pen-line.js.map +1 -0
  1200. package/dist/node_modules/lucide-react/dist/esm/icons/shield-check.cjs +2 -0
  1201. package/dist/node_modules/lucide-react/dist/esm/icons/shield-check.cjs.map +1 -0
  1202. package/dist/node_modules/lucide-react/dist/esm/icons/shield-check.js +12 -0
  1203. package/dist/node_modules/lucide-react/dist/esm/icons/shield-check.js.map +1 -0
  1204. package/dist/node_modules/lucide-react/dist/esm/icons/sparkles.cjs +2 -0
  1205. package/dist/node_modules/lucide-react/dist/esm/icons/sparkles.cjs.map +1 -0
  1206. package/dist/node_modules/lucide-react/dist/esm/icons/sparkles.js +25 -0
  1207. package/dist/node_modules/lucide-react/dist/esm/icons/sparkles.js.map +1 -0
  1208. package/dist/node_modules/lucide-react/dist/esm/icons/timer.cjs +2 -0
  1209. package/dist/node_modules/lucide-react/dist/esm/icons/timer.cjs.map +1 -0
  1210. package/dist/node_modules/lucide-react/dist/esm/icons/timer.js +27 -0
  1211. package/dist/node_modules/lucide-react/dist/esm/icons/timer.js.map +1 -0
  1212. package/dist/package.cjs +1 -1
  1213. package/dist/package.cjs.map +1 -1
  1214. package/dist/package.js +3 -3
  1215. package/dist/package.js.map +1 -1
  1216. package/dist/routes/app-settings.cjs +1 -1
  1217. package/dist/routes/app-settings.cjs.map +1 -1
  1218. package/dist/routes/app-settings.js +87 -85
  1219. package/dist/routes/app-settings.js.map +1 -1
  1220. package/dist/routes/commits-tab.cjs +1 -1
  1221. package/dist/routes/commits-tab.cjs.map +1 -1
  1222. package/dist/routes/commits-tab.js +27 -21
  1223. package/dist/routes/commits-tab.js.map +1 -1
  1224. package/dist/routes/conversation.cjs +1 -1
  1225. package/dist/routes/conversation.cjs.map +1 -1
  1226. package/dist/routes/conversation.js +56 -55
  1227. package/dist/routes/conversation.js.map +1 -1
  1228. package/dist/routes/files-tab.cjs +1 -1
  1229. package/dist/routes/files-tab.cjs.map +1 -1
  1230. package/dist/routes/files-tab.d.ts +4 -0
  1231. package/dist/routes/files-tab.js +121 -151
  1232. package/dist/routes/files-tab.js.map +1 -1
  1233. package/dist/routes/llm-settings.cjs +1 -1
  1234. package/dist/routes/llm-settings.cjs.map +1 -1
  1235. package/dist/routes/llm-settings.d.ts +9 -1
  1236. package/dist/routes/llm-settings.js +137 -107
  1237. package/dist/routes/llm-settings.js.map +1 -1
  1238. package/dist/routes/mcp.cjs +1 -1
  1239. package/dist/routes/mcp.cjs.map +1 -1
  1240. package/dist/routes/mcp.js +20 -20
  1241. package/dist/routes/secrets-settings.cjs +1 -1
  1242. package/dist/routes/secrets-settings.js +15 -15
  1243. package/dist/stores/conversation-store.cjs +1 -1
  1244. package/dist/stores/conversation-store.cjs.map +1 -1
  1245. package/dist/stores/conversation-store.d.ts +8 -1
  1246. package/dist/stores/conversation-store.js +9 -0
  1247. package/dist/stores/conversation-store.js.map +1 -1
  1248. package/dist/stores/files-tab-store.cjs +1 -1
  1249. package/dist/stores/files-tab-store.cjs.map +1 -1
  1250. package/dist/stores/files-tab-store.d.ts +13 -0
  1251. package/dist/stores/files-tab-store.js +49 -5
  1252. package/dist/stores/files-tab-store.js.map +1 -1
  1253. package/dist/stores/use-event-store.cjs +1 -1
  1254. package/dist/stores/use-event-store.cjs.map +1 -1
  1255. package/dist/stores/use-event-store.js +11 -11
  1256. package/dist/stores/use-event-store.js.map +1 -1
  1257. package/dist/types/agent-server/core/events/message-event.d.ts +2 -2
  1258. package/dist/types/automation.cjs +2 -0
  1259. package/dist/types/automation.cjs.map +1 -0
  1260. package/dist/types/automation.js +8 -0
  1261. package/dist/types/automation.js.map +1 -0
  1262. package/dist/utils/automation-catalog.cjs +1 -1
  1263. package/dist/utils/automation-catalog.cjs.map +1 -1
  1264. package/dist/utils/automation-catalog.d.ts +12 -0
  1265. package/dist/utils/automation-catalog.js +20 -1
  1266. package/dist/utils/automation-catalog.js.map +1 -1
  1267. package/dist/utils/automation-schedule.cjs +2 -0
  1268. package/dist/utils/automation-schedule.cjs.map +1 -0
  1269. package/dist/utils/automation-schedule.js +8 -0
  1270. package/dist/utils/automation-schedule.js.map +1 -0
  1271. package/dist/utils/automation-stack-section.cjs +2 -0
  1272. package/dist/utils/automation-stack-section.cjs.map +1 -0
  1273. package/dist/utils/automation-stack-section.d.ts +2 -0
  1274. package/dist/utils/automation-stack-section.js +6 -0
  1275. package/dist/utils/automation-stack-section.js.map +1 -0
  1276. package/dist/utils/constants.cjs +1 -1
  1277. package/dist/utils/constants.cjs.map +1 -1
  1278. package/dist/utils/constants.js +4 -0
  1279. package/dist/utils/constants.js.map +1 -1
  1280. package/dist/utils/conversation-local-storage.cjs +1 -1
  1281. package/dist/utils/conversation-local-storage.cjs.map +1 -1
  1282. package/dist/utils/conversation-local-storage.d.ts +17 -4
  1283. package/dist/utils/conversation-local-storage.js +111 -63
  1284. package/dist/utils/conversation-local-storage.js.map +1 -1
  1285. package/dist/utils/conversation-metrics.cjs +1 -1
  1286. package/dist/utils/conversation-metrics.cjs.map +1 -1
  1287. package/dist/utils/conversation-metrics.d.ts +3 -2
  1288. package/dist/utils/conversation-metrics.js +16 -14
  1289. package/dist/utils/conversation-metrics.js.map +1 -1
  1290. package/dist/utils/conversation-overview-project-scope.cjs +2 -0
  1291. package/dist/utils/conversation-overview-project-scope.cjs.map +1 -0
  1292. package/dist/utils/conversation-overview-project-scope.d.ts +16 -0
  1293. package/dist/utils/conversation-overview-project-scope.js +22 -0
  1294. package/dist/utils/conversation-overview-project-scope.js.map +1 -0
  1295. package/dist/utils/extension-module-card-classes.cjs +1 -1
  1296. package/dist/utils/extension-module-card-classes.cjs.map +1 -1
  1297. package/dist/utils/extension-module-card-classes.d.ts +1 -1
  1298. package/dist/utils/extension-module-card-classes.js +2 -2
  1299. package/dist/utils/extension-module-card-classes.js.map +1 -1
  1300. package/dist/utils/format-relative-time.cjs +2 -0
  1301. package/dist/utils/format-relative-time.cjs.map +1 -0
  1302. package/dist/utils/format-relative-time.js +17 -0
  1303. package/dist/utils/format-relative-time.js.map +1 -0
  1304. package/dist/utils/git-diff-stats.cjs +5 -0
  1305. package/dist/utils/git-diff-stats.cjs.map +1 -0
  1306. package/dist/utils/git-diff-stats.d.ts +9 -0
  1307. package/dist/utils/git-diff-stats.js +53 -0
  1308. package/dist/utils/git-diff-stats.js.map +1 -0
  1309. package/dist/utils/handle-event-for-ui.cjs +1 -1
  1310. package/dist/utils/handle-event-for-ui.cjs.map +1 -1
  1311. package/dist/utils/handle-event-for-ui.js +13 -11
  1312. package/dist/utils/handle-event-for-ui.js.map +1 -1
  1313. package/dist/utils/mcp-credential-validation.cjs +1 -1
  1314. package/dist/utils/mcp-credential-validation.js +3 -3
  1315. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  1316. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  1317. package/dist/utils/mcp-marketplace-utils.js +22 -9
  1318. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  1319. package/dist/utils/parse-git-remote-url.cjs +1 -1
  1320. package/dist/utils/parse-git-remote-url.cjs.map +1 -1
  1321. package/dist/utils/parse-git-remote-url.js +6 -7
  1322. package/dist/utils/parse-git-remote-url.js.map +1 -1
  1323. package/dist/utils/recommended-automation-rail.cjs +2 -0
  1324. package/dist/utils/recommended-automation-rail.cjs.map +1 -0
  1325. package/dist/utils/recommended-automation-rail.d.ts +22 -0
  1326. package/dist/utils/recommended-automation-rail.js +44 -0
  1327. package/dist/utils/recommended-automation-rail.js.map +1 -0
  1328. package/dist/utils/responder-deployment.cjs +2 -0
  1329. package/dist/utils/responder-deployment.cjs.map +1 -0
  1330. package/dist/utils/responder-deployment.js +42 -0
  1331. package/dist/utils/responder-deployment.js.map +1 -0
  1332. package/dist/utils/scroll-fade-state.cjs +2 -0
  1333. package/dist/utils/scroll-fade-state.cjs.map +1 -0
  1334. package/dist/utils/scroll-fade-state.d.ts +6 -0
  1335. package/dist/utils/scroll-fade-state.js +13 -0
  1336. package/dist/utils/scroll-fade-state.js.map +1 -0
  1337. package/dist/utils/skill-category.cjs +2 -0
  1338. package/dist/utils/skill-category.cjs.map +1 -0
  1339. package/dist/utils/skill-category.js +51 -0
  1340. package/dist/utils/skill-category.js.map +1 -0
  1341. package/dist/utils/skill-scope.cjs +1 -1
  1342. package/dist/utils/skill-scope.cjs.map +1 -1
  1343. package/dist/utils/skill-scope.js +1 -1
  1344. package/dist/utils/skill-scope.js.map +1 -1
  1345. package/dist/utils/streaming-delta-batcher.cjs +2 -0
  1346. package/dist/utils/streaming-delta-batcher.cjs.map +1 -0
  1347. package/dist/utils/streaming-delta-batcher.d.ts +21 -0
  1348. package/dist/utils/streaming-delta-batcher.js +31 -0
  1349. package/dist/utils/streaming-delta-batcher.js.map +1 -0
  1350. package/dist/utils/tar-gzip.d.ts +26 -0
  1351. package/dist/utils/utils.cjs +1 -1
  1352. package/dist/utils/utils.cjs.map +1 -1
  1353. package/dist/utils/utils.d.ts +1 -41
  1354. package/dist/utils/utils.js +27 -6
  1355. package/dist/utils/utils.js.map +1 -1
  1356. package/dist/utils/websocket-handshake.cjs +2 -0
  1357. package/dist/utils/websocket-handshake.cjs.map +1 -0
  1358. package/dist/utils/websocket-handshake.d.ts +11 -0
  1359. package/dist/utils/websocket-handshake.js +12 -0
  1360. package/dist/utils/websocket-handshake.js.map +1 -0
  1361. package/package.json +3 -3
  1362. package/scripts/check-translation-completeness.cjs +4 -0
  1363. package/scripts/dev-static.mjs +49 -43
  1364. package/scripts/dev-with-automation.mjs +13 -5
  1365. package/scripts/seed-automation-ux-data.mjs +810 -0
  1366. package/build/assets/acp-providers-CYy8qA2z.js +0 -1
  1367. package/build/assets/active-backend-context-BZDG15C0.js +0 -2
  1368. package/build/assets/agent-context-settings-DGWBBbcp.js +0 -1
  1369. package/build/assets/agent-profiles-settings-DrkGdf4_.js +0 -1
  1370. package/build/assets/agent-server-conversation-service.api-DK56YPTs.js +0 -86
  1371. package/build/assets/agent-settings-DfcSgkLD.js +0 -2
  1372. package/build/assets/agent-settings-Lrc5-twS.js +0 -1
  1373. package/build/assets/alert-banner-BgDHhL7b.js +0 -1
  1374. package/build/assets/api-error-message-BEIE_yD1.js +0 -1
  1375. package/build/assets/api-key-entry-screen-DaZnOlVo.js +0 -1
  1376. package/build/assets/app-settings-BG5NAUbC.js +0 -1
  1377. package/build/assets/automation-detail-D4Hs831Z.js +0 -3
  1378. package/build/assets/automation-export-n0X6FB0C.js +0 -2
  1379. package/build/assets/automation-git-sync-CDrm8WV7.js +0 -1
  1380. package/build/assets/automation-setup-route-CZCl4ONs.js +0 -1
  1381. package/build/assets/automation-templates-DFF96AdL.js +0 -1
  1382. package/build/assets/automations-list-Bl-oGOrV.js +0 -1
  1383. package/build/assets/back-nav-button-H_ThtDA0.js +0 -1
  1384. package/build/assets/backend-form-modal-CbCemvHt.js +0 -1
  1385. package/build/assets/backend-not-configured-DP8KLNq_.js +0 -1
  1386. package/build/assets/backend-synced-settings-badge-BBASWqsb.js +0 -1
  1387. package/build/assets/badge-B-51h-SW.js +0 -1
  1388. package/build/assets/base-modal-BbjycA8X.js +0 -1
  1389. package/build/assets/bot-CGPCg03p.js +0 -1
  1390. package/build/assets/brand-button-Blxv5nww.js +0 -1
  1391. package/build/assets/browser-CuW0nWvh.js +0 -7
  1392. package/build/assets/browser-tab-D5G0ORwt.js +0 -1
  1393. package/build/assets/chat-send-button-BD2tii1r.js +0 -1
  1394. package/build/assets/check-DSuS-lyr.js +0 -1
  1395. package/build/assets/chevron-down-CgGcmtE2.js +0 -1
  1396. package/build/assets/circle-check-CG5-NPw7.js +0 -1
  1397. package/build/assets/circle-plus-check-toggle-ASbpB8vN.js +0 -1
  1398. package/build/assets/cloud-funnel-analytics-GlCUG0gk.js +0 -1
  1399. package/build/assets/cog-CZiR80uT.js +0 -1
  1400. package/build/assets/combobox-caret-DvpEsh2O.js +0 -1
  1401. package/build/assets/command-menu-DwUQzjYP.js +0 -1
  1402. package/build/assets/condenser-settings-BptcoiLA.js +0 -1
  1403. package/build/assets/confirmation-modal-CiEwxZAA.js +0 -1
  1404. package/build/assets/context-menu-list-item-CdcamfM1.js +0 -1
  1405. package/build/assets/conversation-DREHj4nT.js +0 -1
  1406. package/build/assets/conversation-DotRfiDz.js +0 -90
  1407. package/build/assets/conversation-panel-DREHj4nT.js +0 -1
  1408. package/build/assets/conversation-state-store-DMLtlHbE.js +0 -1
  1409. package/build/assets/conversation-store-Blc5xysY.js +0 -6
  1410. package/build/assets/conversation-tab-empty-state-D-puECpY.js +0 -1
  1411. package/build/assets/copy-to-clipboard-button-BGxcUbgy.js +0 -1
  1412. package/build/assets/device-verify-CZJfWaJf.js +0 -1
  1413. package/build/assets/dropdown-classes-tLhpwtxS.js +0 -1
  1414. package/build/assets/entry.client-D8GnI6GZ.js +0 -2
  1415. package/build/assets/enum-filter-dropdown-Fk8k60nk.js +0 -1
  1416. package/build/assets/environment-switch-overlay-DeztVYuL.js +0 -1
  1417. package/build/assets/extension-module-card-classes-Bo43vY5V.js +0 -1
  1418. package/build/assets/extensions-hub-Cd6GCYzq.js +0 -1
  1419. package/build/assets/extensions-navigation-C4sgZg-y.js +0 -1
  1420. package/build/assets/external-link-C0UpBgsE.js +0 -1
  1421. package/build/assets/file-text-C6WYtNdV.js +0 -1
  1422. package/build/assets/files-tab-BW_qzyAm.js +0 -1
  1423. package/build/assets/form-control-classes-CGXBLcn1.js +0 -1
  1424. package/build/assets/format-relative-time-ZhQD4rsl.js +0 -1
  1425. package/build/assets/git-provider-icon-CaQ1yLPi.js +0 -1
  1426. package/build/assets/git-repo-dropdown-CgXR6M_E.js +0 -1
  1427. package/build/assets/git-repo-dropdown-D2Uei3CO.js +0 -1
  1428. package/build/assets/highlighted-source-view-C_YOp8Fo.js +0 -1
  1429. package/build/assets/home-DNzzJcMP.js +0 -1
  1430. package/build/assets/home-aCos-5vc.js +0 -1
  1431. package/build/assets/home-store-DgzViC3f.js +0 -1
  1432. package/build/assets/index-home-DNzzJcMP.js +0 -1
  1433. package/build/assets/info-CLoC1LRo.js +0 -1
  1434. package/build/assets/install-server-modal-D7zIqNKz.js +0 -1
  1435. package/build/assets/kebab-menu-item-content-DERMdnDv.js +0 -1
  1436. package/build/assets/launch-5PjKeLak.js +0 -1
  1437. package/build/assets/list-todo-BF049YaY.js +0 -1
  1438. package/build/assets/llm-not-configured-banner-BK9z5eS0.js +0 -27
  1439. package/build/assets/llm-settings-BLAMK2tR.js +0 -1
  1440. package/build/assets/llm-settings-BWsbarGM.js +0 -1
  1441. package/build/assets/llm-subscription-service-SfnEV9Uc.js +0 -1
  1442. package/build/assets/loader-circle-D7IagAyF.js +0 -1
  1443. package/build/assets/loading-spinner-DBgXgra0.js +0 -1
  1444. package/build/assets/manage-backends-modal-BTqNPhzc.js +0 -1
  1445. package/build/assets/manifest-abebca3c.js +0 -1
  1446. package/build/assets/manifest-subpage-layout-Rn-glaxV.js +0 -1
  1447. package/build/assets/map-provider-BK4HnqYz.js +0 -1
  1448. package/build/assets/markdown-renderer-Cp6DlHQN.js +0 -8
  1449. package/build/assets/mcp-BC-Ixn4T.js +0 -9
  1450. package/build/assets/mcp-marketplace-utils-BJWJgbB6.js +0 -1
  1451. package/build/assets/messages-CzFKrzPG.js +0 -40
  1452. package/build/assets/modal-body-BdKfD3Hl.js +0 -1
  1453. package/build/assets/modal-classes-D5_b5vMi.js +0 -1
  1454. package/build/assets/modal-close-button-objukxk_.js +0 -1
  1455. package/build/assets/mouse-pointer-click-C_gXyLyD.js +0 -1
  1456. package/build/assets/npm-CHVHV1MC.js +0 -1
  1457. package/build/assets/onboarding-Diw0V51A.js +0 -1
  1458. package/build/assets/onboarding-modal-Da4yHzsA.js +0 -1
  1459. package/build/assets/organization-service.api-BztSy69u.js +0 -1
  1460. package/build/assets/parse-git-remote-url-BkXN9jzl.js +0 -1
  1461. package/build/assets/pencil-49avMHlD.js +0 -1
  1462. package/build/assets/planner-tab-CJiSpNax.js +0 -1
  1463. package/build/assets/plugins-management-service-lHdNKWNU.js +0 -1
  1464. package/build/assets/plus-C0BagBpV.js +0 -1
  1465. package/build/assets/profiles-service.api-BLr7FXec.js +0 -1
  1466. package/build/assets/providers-CWXnb7S3.js +0 -1
  1467. package/build/assets/proxy-DYDXxtje.js +0 -1
  1468. package/build/assets/puzzle-Bt2B1rzf.js +0 -1
  1469. package/build/assets/recommended-automations-launcher-CcFMfJRR.js +0 -1
  1470. package/build/assets/refresh-cw-nmcesifB.js +0 -1
  1471. package/build/assets/root-CT4t7apy.css +0 -1
  1472. package/build/assets/root-DnRgLKpU.js +0 -2
  1473. package/build/assets/root-layout-2L9tr-BN.js +0 -2
  1474. package/build/assets/schema-field-C59lVZTA.js +0 -1
  1475. package/build/assets/sdk-section-page-BbBEQQjq.js +0 -1
  1476. package/build/assets/search-CYSDBczG.js +0 -1
  1477. package/build/assets/secrets-service-BtsgYSlj.js +0 -1
  1478. package/build/assets/secrets-settings-DJ0OKa4_.js +0 -1
  1479. package/build/assets/segmented-toggle-DiVfTZuN.js +0 -1
  1480. package/build/assets/settings-CDqL_Uqh.js +0 -1
  1481. package/build/assets/settings-dropdown-input-Ba1UN5Du.js +0 -1
  1482. package/build/assets/settings-index-Cz2cKt2K.js +0 -1
  1483. package/build/assets/settings-input-CWUEHHvS.js +0 -1
  1484. package/build/assets/settings-list-classes-DdcLXDGn.js +0 -1
  1485. package/build/assets/settings-modal-nEEK1Kh1.js +0 -1
  1486. package/build/assets/settings-service.api-3yAUFcaP.js +0 -1
  1487. package/build/assets/settings-switch-Dk9hChx1.js +0 -1
  1488. package/build/assets/settings-utils-CxjtCSB3.js +0 -1
  1489. package/build/assets/shared-conversation-DbAcrx3s.js +0 -1
  1490. package/build/assets/shield-check-CiOTXxV2.js +0 -1
  1491. package/build/assets/sidebar-layout-lrfPooIB.js +0 -1
  1492. package/build/assets/sidebar-mobile-menu-toggle-KERXfNu1.js +0 -1
  1493. package/build/assets/sidebar-nav-link-B8lFD6Cb.js +0 -1
  1494. package/build/assets/sidebar-store-u6pUpxJ7.js +0 -1
  1495. package/build/assets/skill-card-pill-row-dGIUzr_b.js +0 -1
  1496. package/build/assets/skill-icon-badge-kkOWZ89w.js +0 -1
  1497. package/build/assets/skill-scope-DWN1PBPH.js +0 -1
  1498. package/build/assets/skills-plugins-DFjH2Nq6.js +0 -1
  1499. package/build/assets/skills-settings-DIHpl3ol.js +0 -2
  1500. package/build/assets/sparkles-ntyMLnbj.js +0 -1
  1501. package/build/assets/styled-tooltip-B6JXcsmL.js +0 -1
  1502. package/build/assets/task-list-tab-aEJzEcHD.js +0 -1
  1503. package/build/assets/terminal-Dch7Ty5K.js +0 -3
  1504. package/build/assets/toggle-switch-B2MLKsgt.js +0 -1
  1505. package/build/assets/trash-2-yZnDM4Ji.js +0 -1
  1506. package/build/assets/typography-DB5HoCk0.js +0 -1
  1507. package/build/assets/usage-tab-DrEtBmBT.js +0 -1
  1508. package/build/assets/use-acp-credential-form-c8KXAa8A.js +0 -1
  1509. package/build/assets/use-activate-agent-profile-B0p34N3q.js +0 -1
  1510. package/build/assets/use-agent-profiles-CPIc6wLH.js +0 -1
  1511. package/build/assets/use-can-manage-org-profiles-Dz_8Eqkv.js +0 -1
  1512. package/build/assets/use-cloud-current-user-id-DvUVqCle.js +0 -1
  1513. package/build/assets/use-config-C3PO4TBw.js +0 -1
  1514. package/build/assets/use-create-conversation-DVrA_uLD.js +0 -1
  1515. package/build/assets/use-create-secret-DbBIpaCR.js +0 -1
  1516. package/build/assets/use-get-secrets-6PBitf54.js +0 -1
  1517. package/build/assets/use-has-permission-CQ31Cl8j.js +0 -1
  1518. package/build/assets/use-is-authed-2UrDIziV.js +0 -1
  1519. package/build/assets/use-is-creating-conversation-BvYpmb3v.js +0 -1
  1520. package/build/assets/use-launch-skill-in-chat-COnDpxCQ.js +0 -1
  1521. package/build/assets/use-llm-profiles-diZS4FiN.js +0 -1
  1522. package/build/assets/use-manifest-capabilities-HIWCtIUm.js +0 -1
  1523. package/build/assets/use-onboarding-completion-Bs8PcXik.js +0 -1
  1524. package/build/assets/use-plugins-marketplace-BCuNLFsr.js +0 -1
  1525. package/build/assets/use-save-agent-profile-BaMNSpBV.js +0 -1
  1526. package/build/assets/use-save-settings-BahvC2Gw.js +0 -1
  1527. package/build/assets/use-settings-C6ZxpBDX.js +0 -1
  1528. package/build/assets/use-settings-nav-items-Bqn69Ggw.js +0 -16
  1529. package/build/assets/use-tracking-Bhu7gk2y.js +0 -3
  1530. package/build/assets/use-user-conversation-BkNXpXrd.js +0 -1
  1531. package/build/assets/useInfiniteQuery-c_OmS3lK.js +0 -1
  1532. package/build/assets/useMutation-6ZsQCqAn.js +0 -1
  1533. package/build/assets/useQueries-xDrGlTO_.js +0 -1
  1534. package/build/assets/useQuery-Bs5NFz2s.js +0 -1
  1535. package/build/assets/utils-DUD5ScdA.js +0 -1
  1536. package/build/assets/vendor~browser-B-fae1JU.js +0 -47
  1537. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kepq2zme-D87mAf6K.js +0 -186
  1538. package/build/assets/vendor~files-tab-B6POTS66.js +0 -11
  1539. package/build/assets/vendor~index-home~home~conversation-panel~conversation-53Q_U6uP.js +0 -13
  1540. package/build/assets/vendor~root-layout-DeQACFVA.js +0 -1
  1541. package/build/assets/vendor~root-layout~conversation-panel~conversation-bv7ooVgH.js +0 -1
  1542. package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-e8pX05xf.js +0 -1
  1543. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-BvS6PCK2.js +0 -1
  1544. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~automation-templates~automation-set~bxsimjx0-D7IDevqN.js +0 -1
  1545. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-DOPLJMH9.js +0 -48
  1546. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iw7io29p-Dz8NQve5.js +0 -1
  1547. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-BOVIFA_g.js +0 -73
  1548. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~jz4f6vo2-C0JXQb_q.js +0 -7465
  1549. package/build/assets/verification-settings-COueVXmM.js +0 -1
  1550. package/build/assets/wrench-C95ujnYo.js +0 -1
  1551. package/build/assets/x-86ZCfxKY.js +0 -1
  1552. package/build/assets/zap-DRa-r-Tf.js +0 -1
  1553. package/dist/components/features/diff-viewer/empty-changes-message.cjs +0 -2
  1554. package/dist/components/features/diff-viewer/empty-changes-message.cjs.map +0 -1
  1555. package/dist/components/features/diff-viewer/empty-changes-message.js +0 -17
  1556. package/dist/components/features/diff-viewer/empty-changes-message.js.map +0 -1
  1557. package/dist/components/features/tips/random-tip.cjs +0 -2
  1558. package/dist/components/features/tips/random-tip.cjs.map +0 -1
  1559. package/dist/components/features/tips/random-tip.js +0 -41
  1560. package/dist/components/features/tips/random-tip.js.map +0 -1
  1561. package/dist/hooks/query/use-has-git-commits.cjs +0 -2
  1562. package/dist/hooks/query/use-has-git-commits.cjs.map +0 -1
  1563. package/dist/hooks/query/use-has-git-commits.d.ts +0 -25
  1564. package/dist/hooks/query/use-has-git-commits.js +0 -31
  1565. package/dist/hooks/query/use-has-git-commits.js.map +0 -1
  1566. package/dist/hooks/use-has-attached-source.cjs +0 -2
  1567. package/dist/hooks/use-has-attached-source.cjs.map +0 -1
  1568. package/dist/hooks/use-has-attached-source.d.ts +0 -18
  1569. package/dist/hooks/use-has-attached-source.js +0 -14
  1570. package/dist/hooks/use-has-attached-source.js.map +0 -1
  1571. package/dist/icons/chveron-up.cjs +0 -2
  1572. package/dist/icons/chveron-up.cjs.map +0 -1
  1573. package/dist/icons/chveron-up.js +0 -21
  1574. package/dist/icons/chveron-up.js.map +0 -1
  1575. package/dist/routes/changes-tab.cjs +0 -2
  1576. package/dist/routes/changes-tab.cjs.map +0 -1
  1577. package/dist/routes/changes-tab.d.ts +0 -3
  1578. package/dist/routes/changes-tab.js +0 -64
  1579. package/dist/routes/changes-tab.js.map +0 -1
  1580. package/dist/utils/file-priority.cjs +0 -2
  1581. package/dist/utils/file-priority.cjs.map +0 -1
  1582. package/dist/utils/file-priority.d.ts +0 -27
  1583. package/dist/utils/file-priority.js +0 -61
  1584. package/dist/utils/file-priority.js.map +0 -1
  1585. package/dist/utils/table-row-classes.d.ts +0 -9
  1586. package/dist/utils/tips.cjs +0 -2
  1587. package/dist/utils/tips.cjs.map +0 -1
  1588. package/dist/utils/tips.js +0 -45
  1589. package/dist/utils/tips.js.map +0 -1
  1590. /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dcc51rps-rfV8mQ9m.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew3u153i-rfV8mQ9m.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"handle-event-for-ui.js","names":[],"sources":["../../src/utils/handle-event-for-ui.ts"],"sourcesContent":["import {\n ActionEvent,\n ImageContent,\n OpenHandsEvent,\n TextContent,\n} from \"#/types/agent-server/core\";\nimport {\n isACPToolCallEvent,\n isActionEvent,\n isMessageEvent,\n isObservationEvent,\n isStreamingDeltaEvent,\n} from \"#/types/agent-server/type-guards\";\nimport { StreamingDeltaEvent } from \"#/types/agent-server/core/events/streaming-delta-event\";\nimport {\n getReasoningContent,\n splitInlineThink,\n} from \"#/components/conversation-events/chat/event-thought-helpers\";\n\nexport const mergeStreamingDeltaEvent = (\n incoming: StreamingDeltaEvent,\n existing: StreamingDeltaEvent,\n): StreamingDeltaEvent => ({\n ...existing,\n content: `${existing.content ?? \"\"}${incoming.content ?? \"\"}` || null,\n reasoning_content:\n `${existing.reasoning_content ?? \"\"}${incoming.reasoning_content ?? \"\"}` ||\n null,\n});\n\n// Deltas only merge into one bubble when they share a sender; the planning flag\n// is the only discriminator (every delta has `source: \"agent\"`). Prevents a\n// planning-agent delta concatenating onto a main-agent one, misattributed (#1656).\nexport const isSameStreamingSender = (\n a: OpenHandsEvent & { isFromPlanningAgent?: boolean },\n b: OpenHandsEvent & { isFromPlanningAgent?: boolean },\n): boolean => Boolean(a.isFromPlanningAgent) === Boolean(b.isFromPlanningAgent);\n\nconst findLastUserMessageIndex = (events: OpenHandsEvent[]): number => {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index];\n if (isMessageEvent(event) && event.source === \"user\") {\n return index;\n }\n }\n return -1;\n};\n\n// Join text blocks WITHOUT a separator: streaming deltas concatenate content\n// tokens directly with no separator between LLM content blocks, so using \"\\n\"\n// here would cause startsWith/findTextSegmentsInOrder to miss when reconciling\n// a multi-block message/thought against the already-rendered streaming delta.\nconst joinTextBlocks = (blocks: (TextContent | ImageContent)[]): string =>\n blocks\n .filter((block) => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n\nconst findTextSegmentsInOrder = (\n text: string,\n segments: string[],\n): { matched: boolean; lastMatchEnd: number } => {\n let searchStart = 0;\n let lastMatchEnd = 0;\n\n for (const segment of segments) {\n const index = text.indexOf(segment, searchStart);\n if (index === -1) {\n return { matched: false, lastMatchEnd };\n }\n lastMatchEnd = index + segment.length;\n searchStart = lastMatchEnd;\n }\n\n return { matched: true, lastMatchEnd };\n};\n\n// Content-bearing streaming deltas of the current turn (after the last user\n// message) that share the final event's sender. Reasoning-only deltas are\n// excluded: reasoning renders in its own collapsed bubble and never overlaps\n// the message text being reconciled. Sender scoping matters because the main\n// and planning sockets share this event store — without it, one agent's final\n// event would strip the other agent's still-live streamed deltas (#1656).\nconst getCurrentTurnContentDeltas = (\n uiEvents: OpenHandsEvent[],\n finalEvent: OpenHandsEvent,\n): { event: StreamingDeltaEvent; index: number }[] => {\n const lastUserMessageIndex = findLastUserMessageIndex(uiEvents);\n return uiEvents\n .map((event, index) => ({ event, index }))\n .filter(\n (item): item is { event: StreamingDeltaEvent; index: number } =>\n item.index > lastUserMessageIndex &&\n isStreamingDeltaEvent(item.event) &&\n (item.event.content?.length ?? 0) > 0 &&\n isSameStreamingSender(finalEvent, item.event),\n );\n};\n\n// The current step's streaming delta(s): the trailing run at the end of\n// `uiEvents`. Earlier steps' deltas are separated by their observations, so\n// this never folds an earlier step's delta into the current one.\nconst getTrailingDeltas = (\n uiEvents: OpenHandsEvent[],\n selects: (event: StreamingDeltaEvent) => boolean,\n): { event: StreamingDeltaEvent; index: number }[] => {\n const deltas: { event: StreamingDeltaEvent; index: number }[] = [];\n for (let index = uiEvents.length - 1; index >= 0; index -= 1) {\n const event = uiEvents[index];\n if (!isStreamingDeltaEvent(event)) {\n break;\n }\n if (selects(event)) {\n deltas.unshift({ event, index });\n }\n }\n return deltas;\n};\n\nconst getTrailingContentDeltas = (uiEvents: OpenHandsEvent[]) =>\n getTrailingDeltas(uiEvents, (event) => (event.content?.length ?? 0) > 0);\n\n// Sender-scoped: the main and planning sockets share this event store, so a\n// main-agent action must not strip the planning agent's live reasoning (#1656).\nconst getTrailingReasoningDeltas = (\n uiEvents: OpenHandsEvent[],\n finalEvent: OpenHandsEvent,\n) =>\n getTrailingDeltas(\n uiEvents,\n (event) =>\n Boolean(event.reasoning_content) &&\n isSameStreamingSender(finalEvent, event),\n );\n\n// Strip the streamed content deltas, keeping a delta only when it carries\n// reasoning the replacement itself won't render (many models stream reasoning\n// solely through the delta). Shared by the finalize and intermediate-action\n// reconciliation paths.\nconst supersedeStreamingContent = (\n uiEvents: OpenHandsEvent[],\n contentDeltas: { event: StreamingDeltaEvent; index: number }[],\n replacementRendersReasoning: boolean,\n): OpenHandsEvent[] => {\n const indexesToStrip = new Set(contentDeltas.map(({ index }) => index));\n const nextUiEvents: OpenHandsEvent[] = [];\n uiEvents.forEach((event, index) => {\n if (!indexesToStrip.has(index) || !isStreamingDeltaEvent(event)) {\n nextUiEvents.push(event);\n return;\n }\n\n // Keep the delta only to render reasoning the replacement itself lacks.\n if (!replacementRendersReasoning && event.reasoning_content) {\n nextUiEvents.push({ ...event, content: null });\n }\n });\n return nextUiEvents;\n};\n\n// Whether the streamed `segments` (in order) reconcile against `targetText`.\n// `lastMatchEnd` is the offset past the matched text, so callers can recover\n// any not-yet-streamed suffix. The SDK strips the finalized text, so tolerate\n// leading and trailing whitespace that appeared only in the stream.\nconst matchStreamedSegments = (\n targetText: string,\n segments: string[],\n): { matched: boolean; lastMatchEnd: number } => {\n const streamedText = segments.join(\"\");\n const candidates = new Set([\n streamedText,\n streamedText.trimEnd(),\n streamedText.trimStart(),\n streamedText.trim(),\n ]);\n for (const candidate of candidates) {\n if (candidate && targetText.startsWith(candidate)) {\n return { matched: true, lastMatchEnd: candidate.length };\n }\n }\n // Segments may be interleaved with not-yet-streamed text; locate them in\n // order, trimming the last segment's trailing whitespace.\n const lastIndex = segments.length - 1;\n const searchSegments = segments.map((segment, index) =>\n index === lastIndex ? segment.trimEnd() : segment,\n );\n return findTextSegmentsInOrder(targetText, searchSegments);\n};\n\n// Whether the finalized event renders its own reasoning: an ActionEvent via\n// reasoning_content/thinking_blocks, an agent MessageEvent via an inline\n// <think> block in its content. Decides if a replaced delta's reasoning must\n// be preserved separately.\nconst eventRendersReasoning = (event: OpenHandsEvent): boolean => {\n if (isActionEvent(event)) {\n return getReasoningContent(event).trim().length > 0;\n }\n\n if (isMessageEvent(event) && event.source === \"agent\") {\n return (\n splitInlineThink(joinTextBlocks(event.llm_message.content)).reasoning\n .length > 0\n );\n }\n\n return false;\n};\n\n// The final MessageEvent/FinishAction is authoritative for the turn's text. Drop\n// the provisional streamed deltas and render the canonical final event instead,\n// so the message is rendered exactly once (never holey or duplicated) and its\n// metadata — critic_result, activated_microagents — renders too. Stream-only\n// reasoning is preserved. Returns null when there is no streamed content to\n// reconcile, leaving the caller to append the final event normally.\nconst finalizeStreamingDeltasInPlace = (\n finalEvent: OpenHandsEvent,\n uiEvents: OpenHandsEvent[],\n): OpenHandsEvent[] | null => {\n const contentStreamingDeltas = getCurrentTurnContentDeltas(\n uiEvents,\n finalEvent,\n );\n if (contentStreamingDeltas.length === 0) {\n return null;\n }\n\n const nextUiEvents = supersedeStreamingContent(\n uiEvents,\n contentStreamingDeltas,\n eventRendersReasoning(finalEvent),\n );\n nextUiEvents.push(finalEvent);\n return nextUiEvents;\n};\n\n/**\n * Reconcile the current turn's streaming delta when an intermediate\n * (tool-calling) `ActionEvent` arrives. With `stream=true` the step's\n * pre-tool-call text is streamed as delta `content`, then the action's\n * `thought` repeats it and the chat hoists that into its own message (see\n * `group-events.ts`), so the text would render twice (issue #1534).\n *\n * The action must stay because it owns the tool call. The streamed text is\n * cleared from the delta, and the delta is kept only to carry reasoning the\n * action itself lacks (for many models the delta is the sole reasoning\n * carrier), otherwise dropped.\n *\n * Only the current step's trailing delta run is considered. Returns the updated\n * array, or `null` when there is nothing to reconcile.\n */\nconst supersedeStreamedThoughtWithAction = (\n action: ActionEvent,\n uiEvents: OpenHandsEvent[],\n): OpenHandsEvent[] | null => {\n const thoughtText = joinTextBlocks(action.thought);\n if (!thoughtText) {\n return null;\n }\n\n const contentDeltas = getTrailingContentDeltas(uiEvents);\n if (contentDeltas.length === 0) {\n return null;\n }\n\n const streamingSegments = contentDeltas.map(\n ({ event }) => event.content ?? \"\",\n );\n\n // Only strip when the streamed text is the action's rendered thought.\n if (!matchStreamedSegments(thoughtText, streamingSegments).matched) {\n return null;\n }\n\n // Keeping the delta's reasoning would duplicate the action's own \"Thinking\".\n return supersedeStreamingContent(\n uiEvents,\n contentDeltas,\n getReasoningContent(action).trim().length > 0,\n );\n};\n\n// Drop the current step's streamed reasoning when the action renders that\n// reasoning itself, so \"Thinking\" renders once. Unlike\n// `supersedeStreamedThoughtWithAction` this does not require the streamed text\n// to match the thought, which models streaming reasoning-only deltas never do.\nconst supersedeStreamedReasoningWithAction = (\n action: ActionEvent,\n uiEvents: OpenHandsEvent[],\n): OpenHandsEvent[] | null => {\n if (getReasoningContent(action).trim().length === 0) {\n return null;\n }\n\n const reasoningDeltas = getTrailingReasoningDeltas(uiEvents, action);\n if (reasoningDeltas.length === 0) {\n return null;\n }\n\n const indexesToStrip = new Set(reasoningDeltas.map(({ index }) => index));\n const nextUiEvents: OpenHandsEvent[] = [];\n uiEvents.forEach((event, index) => {\n if (!indexesToStrip.has(index) || !isStreamingDeltaEvent(event)) {\n nextUiEvents.push(event);\n return;\n }\n\n // Keep the delta only for streamed text the action itself lacks.\n if (event.content) {\n nextUiEvents.push({ ...event, reasoning_content: null });\n }\n });\n return nextUiEvents;\n};\n\n/**\n * Handles adding an event to the UI events array\n * Replaces actions with observations when they arrive (so UI shows observation instead of action)\n * Exception: ThinkAction is NOT replaced because the thought content is in the action, not in the observation\n *\n * ACPToolCallEvent merge: the SDK emits two events per ``tool_call_id`` — an\n * early ``started`` event (``pending`` / ``in_progress``) and one terminal\n * (completed / failed) event, the action->observation pair for a tool call.\n * Replace the started entry in place with the terminal one so a single card\n * updates from running to its result, exactly like an observation superseding\n * its action below.\n */\nexport const handleEventForUI = (\n event: OpenHandsEvent,\n uiEvents: OpenHandsEvent[],\n): OpenHandsEvent[] => {\n const newUiEvents = [...uiEvents];\n\n if (isStreamingDeltaEvent(event)) {\n if (event.content === null && event.reasoning_content === null) {\n return newUiEvents;\n }\n\n const lastIndex = newUiEvents.length - 1;\n const lastEvent = newUiEvents[lastIndex];\n if (\n lastEvent &&\n isStreamingDeltaEvent(lastEvent) &&\n isSameStreamingSender(event, lastEvent)\n ) {\n newUiEvents[lastIndex] = mergeStreamingDeltaEvent(event, lastEvent);\n return newUiEvents;\n }\n\n newUiEvents.push(event);\n return newUiEvents;\n }\n\n if (\n (isActionEvent(event) && event.action.kind === \"FinishAction\") ||\n (isMessageEvent(event) && event.source === \"agent\")\n ) {\n const finalizedUiEvents = finalizeStreamingDeltasInPlace(\n event,\n newUiEvents,\n );\n if (finalizedUiEvents) {\n return finalizedUiEvents;\n }\n }\n\n // Intermediate tool-calling action whose thought was streamed: clear the\n // duplicated text from the delta (issue #1534). ThinkAction is excluded — its\n // thought renders through its own collapsible, not a hoisted thought.\n if (\n isActionEvent(event) &&\n event.action.kind !== \"FinishAction\" &&\n event.action.kind !== \"ThinkAction\"\n ) {\n const reconciledUiEvents =\n supersedeStreamedThoughtWithAction(event, newUiEvents) ??\n supersedeStreamedReasoningWithAction(event, newUiEvents);\n if (reconciledUiEvents) {\n reconciledUiEvents.push(event);\n return reconciledUiEvents;\n }\n }\n\n if (isACPToolCallEvent(event)) {\n const existingIndex = newUiEvents.findIndex(\n (uiEvent) =>\n isACPToolCallEvent(uiEvent) &&\n uiEvent.tool_call_id === event.tool_call_id,\n );\n if (existingIndex !== -1) {\n newUiEvents[existingIndex] = event;\n } else {\n newUiEvents.push(event);\n }\n return newUiEvents;\n }\n\n if (isObservationEvent(event)) {\n // Don't add ThinkObservation at all - we keep the ThinkAction instead\n // The thought content is in the action, not the observation\n if (event.observation.kind === \"ThinkObservation\") {\n return newUiEvents;\n }\n\n // Don't add FinishObservation at all - we keep the FinishAction instead\n // Both contain the same message content, so we only need to display one\n // This also prevents duplicate messages when events arrive out of order due to React batching\n if (event.observation.kind === \"FinishObservation\") {\n return newUiEvents;\n }\n\n // Find and replace the corresponding action from uiEvents\n const actionIndex = newUiEvents.findIndex(\n (uiEvent) => uiEvent.id === event.action_id,\n );\n if (actionIndex !== -1) {\n newUiEvents[actionIndex] = event;\n } else {\n // Action not found in uiEvents, just add the observation\n newUiEvents.push(event);\n }\n } else {\n // For non-observation events, just add them to uiEvents\n newUiEvents.push(event);\n }\n\n return newUiEvents;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"handle-event-for-ui.js","names":[],"sources":["../../src/utils/handle-event-for-ui.ts"],"sourcesContent":["import {\n ActionEvent,\n ImageContent,\n OpenHandsEvent,\n TextContent,\n} from \"#/types/agent-server/core\";\nimport {\n isACPToolCallEvent,\n isActionEvent,\n isMessageEvent,\n isObservationEvent,\n isStreamingDeltaEvent,\n} from \"#/types/agent-server/type-guards\";\nimport { StreamingDeltaEvent } from \"#/types/agent-server/core/events/streaming-delta-event\";\nimport {\n getReasoningContent,\n splitInlineThink,\n} from \"#/components/conversation-events/chat/event-thought-helpers\";\n\nexport const mergeStreamingDeltaEvent = (\n incoming: StreamingDeltaEvent,\n existing: StreamingDeltaEvent,\n): StreamingDeltaEvent => ({\n ...existing,\n content: `${existing.content ?? \"\"}${incoming.content ?? \"\"}` || null,\n reasoning_content:\n `${existing.reasoning_content ?? \"\"}${incoming.reasoning_content ?? \"\"}` ||\n null,\n});\n\n// Deltas only merge into one bubble when they share a sender; the planning flag\n// is the only discriminator (every delta has `source: \"agent\"`). Prevents a\n// planning-agent delta concatenating onto a main-agent one, misattributed (#1656).\nexport const isSameStreamingSender = (\n a: OpenHandsEvent & { isFromPlanningAgent?: boolean },\n b: OpenHandsEvent & { isFromPlanningAgent?: boolean },\n): boolean => Boolean(a.isFromPlanningAgent) === Boolean(b.isFromPlanningAgent);\n\nconst findLastUserMessageIndex = (events: OpenHandsEvent[]): number => {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index];\n if (isMessageEvent(event) && event.source === \"user\") {\n return index;\n }\n }\n return -1;\n};\n\n// Join text blocks WITHOUT a separator: streaming deltas concatenate content\n// tokens directly with no separator between LLM content blocks, so using \"\\n\"\n// here would cause startsWith/findTextSegmentsInOrder to miss when reconciling\n// a multi-block message/thought against the already-rendered streaming delta.\nconst joinTextBlocks = (blocks: (TextContent | ImageContent)[]): string =>\n blocks\n .filter((block) => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n\nconst findTextSegmentsInOrder = (\n text: string,\n segments: string[],\n): { matched: boolean; lastMatchEnd: number } => {\n let searchStart = 0;\n let lastMatchEnd = 0;\n\n for (const segment of segments) {\n const index = text.indexOf(segment, searchStart);\n if (index === -1) {\n return { matched: false, lastMatchEnd };\n }\n lastMatchEnd = index + segment.length;\n searchStart = lastMatchEnd;\n }\n\n return { matched: true, lastMatchEnd };\n};\n\n// Content-bearing streaming deltas of the current turn (after the last user\n// message) that share the final event's sender. Reasoning-only deltas are\n// excluded: reasoning renders in its own collapsed bubble and never overlaps\n// the message text being reconciled. Sender scoping matters because the main\n// and planning sockets share this event store — without it, one agent's final\n// event would strip the other agent's still-live streamed deltas (#1656).\nconst getCurrentTurnContentDeltas = (\n uiEvents: OpenHandsEvent[],\n finalEvent: OpenHandsEvent,\n): { event: StreamingDeltaEvent; index: number }[] => {\n const lastUserMessageIndex = findLastUserMessageIndex(uiEvents);\n return uiEvents\n .map((event, index) => ({ event, index }))\n .filter(\n (item): item is { event: StreamingDeltaEvent; index: number } =>\n item.index > lastUserMessageIndex &&\n isStreamingDeltaEvent(item.event) &&\n (item.event.content?.length ?? 0) > 0 &&\n isSameStreamingSender(finalEvent, item.event),\n );\n};\n\n// The current step's streaming delta(s): the trailing run at the end of\n// `uiEvents`. Earlier steps' deltas are separated by their observations, so\n// this never folds an earlier step's delta into the current one.\nconst getTrailingDeltas = (\n uiEvents: OpenHandsEvent[],\n selects: (event: StreamingDeltaEvent) => boolean,\n): { event: StreamingDeltaEvent; index: number }[] => {\n const deltas: { event: StreamingDeltaEvent; index: number }[] = [];\n for (let index = uiEvents.length - 1; index >= 0; index -= 1) {\n const event = uiEvents[index];\n if (!isStreamingDeltaEvent(event)) {\n break;\n }\n if (selects(event)) {\n deltas.unshift({ event, index });\n }\n }\n return deltas;\n};\n\n// Sender-scoped for the same reason as `getTrailingReasoningDeltas` (#1656):\n// a main-agent action must not strip the planning agent's live content.\nconst getTrailingContentDeltas = (\n uiEvents: OpenHandsEvent[],\n finalEvent: OpenHandsEvent,\n) =>\n getTrailingDeltas(\n uiEvents,\n (event) =>\n (event.content?.length ?? 0) > 0 &&\n isSameStreamingSender(finalEvent, event),\n );\n\n// Sender-scoped: the main and planning sockets share this event store, so a\n// main-agent action must not strip the planning agent's live reasoning (#1656).\nconst getTrailingReasoningDeltas = (\n uiEvents: OpenHandsEvent[],\n finalEvent: OpenHandsEvent,\n) =>\n getTrailingDeltas(\n uiEvents,\n (event) =>\n Boolean(event.reasoning_content) &&\n isSameStreamingSender(finalEvent, event),\n );\n\n// Strip the streamed content deltas, keeping a delta only when it carries\n// reasoning the replacement itself won't render (many models stream reasoning\n// solely through the delta). Shared by the finalize and intermediate-action\n// reconciliation paths.\nconst supersedeStreamingContent = (\n uiEvents: OpenHandsEvent[],\n contentDeltas: { event: StreamingDeltaEvent; index: number }[],\n replacementRendersReasoning: boolean,\n): OpenHandsEvent[] => {\n const indexesToStrip = new Set(contentDeltas.map(({ index }) => index));\n const nextUiEvents: OpenHandsEvent[] = [];\n uiEvents.forEach((event, index) => {\n if (!indexesToStrip.has(index) || !isStreamingDeltaEvent(event)) {\n nextUiEvents.push(event);\n return;\n }\n\n // Keep the delta only to render reasoning the replacement itself lacks.\n if (!replacementRendersReasoning && event.reasoning_content) {\n nextUiEvents.push({ ...event, content: null });\n }\n });\n return nextUiEvents;\n};\n\n// Whether the streamed `segments` (in order) reconcile against `targetText`.\n// `lastMatchEnd` is the offset past the matched text, so callers can recover\n// any not-yet-streamed suffix. The SDK strips the finalized text, so tolerate\n// leading and trailing whitespace that appeared only in the stream.\nconst matchStreamedSegments = (\n targetText: string,\n segments: string[],\n): { matched: boolean; lastMatchEnd: number } => {\n const streamedText = segments.join(\"\");\n const candidates = new Set([\n streamedText,\n streamedText.trimEnd(),\n streamedText.trimStart(),\n streamedText.trim(),\n ]);\n for (const candidate of candidates) {\n if (candidate && targetText.startsWith(candidate)) {\n return { matched: true, lastMatchEnd: candidate.length };\n }\n }\n // Segments may be interleaved with not-yet-streamed text; locate them in\n // order, trimming the last segment's trailing whitespace.\n const lastIndex = segments.length - 1;\n const searchSegments = segments.map((segment, index) =>\n index === lastIndex ? segment.trimEnd() : segment,\n );\n return findTextSegmentsInOrder(targetText, searchSegments);\n};\n\n// A `<function=` marker means the delta still holds the raw prompted-tool-call\n// XML the SDK strips only after the response completes, so the streamed text is\n// a superset of the action's `thought` that `matchStreamedSegments` can't match.\nconst hasUnstrippedFunctionCallMarker = (segments: string[]): boolean =>\n segments.some((segment) => segment.includes(\"<function=\"));\n\n// Whether the finalized event renders its own reasoning: an ActionEvent via\n// reasoning_content/thinking_blocks, an agent MessageEvent via an inline\n// <think> block in its content. Decides if a replaced delta's reasoning must\n// be preserved separately.\nconst eventRendersReasoning = (event: OpenHandsEvent): boolean => {\n if (isActionEvent(event)) {\n return getReasoningContent(event).trim().length > 0;\n }\n\n if (isMessageEvent(event) && event.source === \"agent\") {\n return (\n splitInlineThink(joinTextBlocks(event.llm_message.content)).reasoning\n .length > 0\n );\n }\n\n return false;\n};\n\n// The final MessageEvent/FinishAction is authoritative for the turn's text. Drop\n// the provisional streamed deltas and render the canonical final event instead,\n// so the message is rendered exactly once (never holey or duplicated) and its\n// metadata — critic_result, activated_skills — renders too. Stream-only\n// reasoning is preserved. Returns null when there is no streamed content to\n// reconcile, leaving the caller to append the final event normally.\nconst finalizeStreamingDeltasInPlace = (\n finalEvent: OpenHandsEvent,\n uiEvents: OpenHandsEvent[],\n): OpenHandsEvent[] | null => {\n const contentStreamingDeltas = getCurrentTurnContentDeltas(\n uiEvents,\n finalEvent,\n );\n if (contentStreamingDeltas.length === 0) {\n return null;\n }\n\n const nextUiEvents = supersedeStreamingContent(\n uiEvents,\n contentStreamingDeltas,\n eventRendersReasoning(finalEvent),\n );\n nextUiEvents.push(finalEvent);\n return nextUiEvents;\n};\n\n/**\n * Reconcile the current turn's streaming delta when an intermediate\n * (tool-calling) `ActionEvent` arrives. With `stream=true` the step's\n * pre-tool-call text is streamed as delta `content`, then the action's\n * `thought` repeats it and the chat hoists that into its own message (see\n * `group-events.ts`), so the text would render twice (issue #1534).\n *\n * The action must stay because it owns the tool call. The streamed text is\n * cleared from the delta, and the delta is kept only to carry reasoning the\n * action itself lacks (for many models the delta is the sole reasoning\n * carrier), otherwise dropped.\n *\n * Only the current step's trailing delta run is considered. Returns the updated\n * array, or `null` when there is nothing to reconcile.\n */\nconst supersedeStreamedThoughtWithAction = (\n action: ActionEvent,\n uiEvents: OpenHandsEvent[],\n): OpenHandsEvent[] | null => {\n const thoughtText = joinTextBlocks(action.thought);\n if (!thoughtText) {\n return null;\n }\n\n const contentDeltas = getTrailingContentDeltas(uiEvents, action);\n if (contentDeltas.length === 0) {\n return null;\n }\n\n const streamingSegments = contentDeltas.map(\n ({ event }) => event.content ?? \"\",\n );\n\n // Strip on a thought match, or on an unstripped `<function=...>` marker whose\n // streamed text is a superset of `thought` that the match can't reconcile.\n const matchedThought = matchStreamedSegments(\n thoughtText,\n streamingSegments,\n ).matched;\n if (!matchedThought && !hasUnstrippedFunctionCallMarker(streamingSegments)) {\n return null;\n }\n\n // Keeping the delta's reasoning would duplicate the action's own \"Thinking\".\n return supersedeStreamingContent(\n uiEvents,\n contentDeltas,\n getReasoningContent(action).trim().length > 0,\n );\n};\n\n// Drop the current step's streamed reasoning when the action renders that\n// reasoning itself, so \"Thinking\" renders once. Unlike\n// `supersedeStreamedThoughtWithAction` this does not require the streamed text\n// to match the thought, which models streaming reasoning-only deltas never do.\nconst supersedeStreamedReasoningWithAction = (\n action: ActionEvent,\n uiEvents: OpenHandsEvent[],\n): OpenHandsEvent[] | null => {\n if (getReasoningContent(action).trim().length === 0) {\n return null;\n }\n\n const reasoningDeltas = getTrailingReasoningDeltas(uiEvents, action);\n if (reasoningDeltas.length === 0) {\n return null;\n }\n\n const indexesToStrip = new Set(reasoningDeltas.map(({ index }) => index));\n const nextUiEvents: OpenHandsEvent[] = [];\n uiEvents.forEach((event, index) => {\n if (!indexesToStrip.has(index) || !isStreamingDeltaEvent(event)) {\n nextUiEvents.push(event);\n return;\n }\n\n // Keep the delta only for streamed text the action itself lacks.\n if (event.content) {\n nextUiEvents.push({ ...event, reasoning_content: null });\n }\n });\n return nextUiEvents;\n};\n\n/**\n * Handles adding an event to the UI events array\n * Replaces actions with observations when they arrive (so UI shows observation instead of action)\n * Exception: ThinkAction is NOT replaced because the thought content is in the action, not in the observation\n *\n * ACPToolCallEvent merge: the SDK emits two events per ``tool_call_id`` — an\n * early ``started`` event (``pending`` / ``in_progress``) and one terminal\n * (completed / failed) event, the action->observation pair for a tool call.\n * Replace the started entry in place with the terminal one so a single card\n * updates from running to its result, exactly like an observation superseding\n * its action below.\n */\nexport const handleEventForUI = (\n event: OpenHandsEvent,\n uiEvents: OpenHandsEvent[],\n): OpenHandsEvent[] => {\n const newUiEvents = [...uiEvents];\n\n if (isStreamingDeltaEvent(event)) {\n if (event.content === null && event.reasoning_content === null) {\n return newUiEvents;\n }\n\n const lastIndex = newUiEvents.length - 1;\n const lastEvent = newUiEvents[lastIndex];\n if (\n lastEvent &&\n isStreamingDeltaEvent(lastEvent) &&\n isSameStreamingSender(event, lastEvent)\n ) {\n newUiEvents[lastIndex] = mergeStreamingDeltaEvent(event, lastEvent);\n return newUiEvents;\n }\n\n newUiEvents.push(event);\n return newUiEvents;\n }\n\n if (\n (isActionEvent(event) && event.action.kind === \"FinishAction\") ||\n (isMessageEvent(event) && event.source === \"agent\")\n ) {\n const finalizedUiEvents = finalizeStreamingDeltasInPlace(\n event,\n newUiEvents,\n );\n if (finalizedUiEvents) {\n return finalizedUiEvents;\n }\n }\n\n // Intermediate tool-calling action whose thought was streamed: clear the\n // duplicated text from the delta (issue #1534). ThinkAction is excluded — its\n // thought renders through its own collapsible, not a hoisted thought.\n if (\n isActionEvent(event) &&\n event.action.kind !== \"FinishAction\" &&\n event.action.kind !== \"ThinkAction\"\n ) {\n const reconciledUiEvents =\n supersedeStreamedThoughtWithAction(event, newUiEvents) ??\n supersedeStreamedReasoningWithAction(event, newUiEvents);\n if (reconciledUiEvents) {\n reconciledUiEvents.push(event);\n return reconciledUiEvents;\n }\n }\n\n if (isACPToolCallEvent(event)) {\n const existingIndex = newUiEvents.findIndex(\n (uiEvent) =>\n isACPToolCallEvent(uiEvent) &&\n uiEvent.tool_call_id === event.tool_call_id,\n );\n if (existingIndex !== -1) {\n newUiEvents[existingIndex] = event;\n } else {\n newUiEvents.push(event);\n }\n return newUiEvents;\n }\n\n if (isObservationEvent(event)) {\n // Don't add ThinkObservation at all - we keep the ThinkAction instead\n // The thought content is in the action, not the observation\n if (event.observation.kind === \"ThinkObservation\") {\n return newUiEvents;\n }\n\n // Don't add FinishObservation at all - we keep the FinishAction instead\n // Both contain the same message content, so we only need to display one\n // This also prevents duplicate messages when events arrive out of order due to React batching\n if (event.observation.kind === \"FinishObservation\") {\n return newUiEvents;\n }\n\n // Find and replace the corresponding action from uiEvents\n const actionIndex = newUiEvents.findIndex(\n (uiEvent) => uiEvent.id === event.action_id,\n );\n if (actionIndex !== -1) {\n newUiEvents[actionIndex] = event;\n } else {\n // Action not found in uiEvents, just add the observation\n newUiEvents.push(event);\n }\n } else {\n // For non-observation events, just add them to uiEvents\n newUiEvents.push(event);\n }\n\n return newUiEvents;\n};\n"],"mappings":";;;AAmBA,IAAa,KACX,GACA,OACyB;CACzB,GAAG;CACH,SAAS,GAAG,EAAS,WAAW,KAAK,EAAS,WAAW,QAAQ;CACjE,mBACE,GAAG,EAAS,qBAAqB,KAAK,EAAS,qBAAqB,QACpE;AACJ,IAKa,KACX,GACA,MACY,EAAQ,EAAE,uBAAyB,EAAQ,EAAE,qBAErD,KAA4B,MAAqC;CACrE,KAAK,IAAI,IAAQ,EAAO,SAAS,GAAG,KAAS,GAAG,KAAY;EAC1D,IAAM,IAAQ,EAAO;EACrB,IAAI,EAAe,CAAK,KAAK,EAAM,WAAW,QAC5C,OAAO;CAEX;CACA,OAAO;AACT,GAMM,KAAkB,MACtB,EACG,QAAQ,MAAU,EAAM,SAAS,MAAM,EACvC,KAAK,MAAU,EAAM,IAAI,EACzB,KAAK,EAAE,GAEN,KACJ,GACA,MAC+C;CAC/C,IAAI,IAAc,GACd,IAAe;CAEnB,KAAK,IAAM,KAAW,GAAU;EAC9B,IAAM,IAAQ,EAAK,QAAQ,GAAS,CAAW;EAC/C,IAAI,MAAU,IACZ,OAAO;GAAE,SAAS;GAAO;EAAa;EAGxC,AADA,IAAe,IAAQ,EAAQ,QAC/B,IAAc;CAChB;CAEA,OAAO;EAAE,SAAS;EAAM;CAAa;AACvC,GAQM,KACJ,GACA,MACoD;CACpD,IAAM,IAAuB,EAAyB,CAAQ;CAC9D,OAAO,EACJ,KAAK,GAAO,OAAW;EAAE;EAAO;CAAM,EAAE,EACxC,QACE,MACC,EAAK,QAAQ,KACb,EAAsB,EAAK,KAAK,MAC/B,EAAK,MAAM,SAAS,UAAU,KAAK,KACpC,EAAsB,GAAY,EAAK,KAAK,CAChD;AACJ,GAKM,KACJ,GACA,MACoD;CACpD,IAAM,IAA0D,CAAC;CACjE,KAAK,IAAI,IAAQ,EAAS,SAAS,GAAG,KAAS,GAAG,KAAY;EAC5D,IAAM,IAAQ,EAAS;EACvB,IAAI,CAAC,EAAsB,CAAK,GAC9B;EAEF,AAAI,EAAQ,CAAK,KACf,EAAO,QAAQ;GAAE;GAAO;EAAM,CAAC;CAEnC;CACA,OAAO;AACT,GAIM,KACJ,GACA,MAEA,EACE,IACC,OACE,EAAM,SAAS,UAAU,KAAK,KAC/B,EAAsB,GAAY,CAAK,CAC3C,GAII,KACJ,GACA,MAEA,EACE,IACC,MACC,EAAQ,EAAM,qBACd,EAAsB,GAAY,CAAK,CAC3C,GAMI,KACJ,GACA,GACA,MACqB;CACrB,IAAM,IAAiB,IAAI,IAAI,EAAc,KAAK,EAAE,eAAY,CAAK,CAAC,GAChE,IAAiC,CAAC;CAYxC,OAXA,EAAS,SAAS,GAAO,MAAU;EACjC,IAAI,CAAC,EAAe,IAAI,CAAK,KAAK,CAAC,EAAsB,CAAK,GAAG;GAC/D,EAAa,KAAK,CAAK;GACvB;EACF;EAGA,AAAI,CAAC,KAA+B,EAAM,qBACxC,EAAa,KAAK;GAAE,GAAG;GAAO,SAAS;EAAK,CAAC;CAEjD,CAAC,GACM;AACT,GAMM,KACJ,GACA,MAC+C;CAC/C,IAAM,IAAe,EAAS,KAAK,EAAE,GAC/B,IAAa,IAAI,IAAI;EACzB;EACA,EAAa,QAAQ;EACrB,EAAa,UAAU;EACvB,EAAa,KAAK;CACpB,CAAC;CACD,KAAK,IAAM,KAAa,GACtB,IAAI,KAAa,EAAW,WAAW,CAAS,GAC9C,OAAO;EAAE,SAAS;EAAM,cAAc,EAAU;CAAO;CAK3D,IAAM,IAAY,EAAS,SAAS;CAIpC,OAAO,EAAwB,GAHR,EAAS,KAAK,GAAS,MAC5C,MAAU,IAAY,EAAQ,QAAQ,IAAI,CAED,CAAc;AAC3D,GAKM,KAAmC,MACvC,EAAS,MAAM,MAAY,EAAQ,SAAS,YAAY,CAAC,GAMrD,KAAyB,MACzB,EAAc,CAAK,IACd,EAAoB,CAAK,EAAE,KAAK,EAAE,SAAS,IAGhD,EAAe,CAAK,KAAK,EAAM,WAAW,UAE1C,EAAiB,EAAe,EAAM,YAAY,OAAO,CAAC,EAAE,UACzD,SAAS,IAIT,IASH,KACJ,GACA,MAC4B;CAC5B,IAAM,IAAyB,EAC7B,GACA,CACF;CACA,IAAI,EAAuB,WAAW,GACpC,OAAO;CAGT,IAAM,IAAe,EACnB,GACA,GACA,EAAsB,CAAU,CAClC;CAEA,OADA,EAAa,KAAK,CAAU,GACrB;AACT,GAiBM,KACJ,GACA,MAC4B;CAC5B,IAAM,IAAc,EAAe,EAAO,OAAO;CACjD,IAAI,CAAC,GACH,OAAO;CAGT,IAAM,IAAgB,EAAyB,GAAU,CAAM;CAC/D,IAAI,EAAc,WAAW,GAC3B,OAAO;CAGT,IAAM,IAAoB,EAAc,KACrC,EAAE,eAAY,EAAM,WAAW,EAClC;CAaA,OALI,CAJmB,EACrB,GACA,CACF,EAAE,WACqB,CAAC,EAAgC,CAAiB,IAChE,OAIF,EACL,GACA,GACA,EAAoB,CAAM,EAAE,KAAK,EAAE,SAAS,CAC9C;AACF,GAMM,KACJ,GACA,MAC4B;CAC5B,IAAI,EAAoB,CAAM,EAAE,KAAK,EAAE,WAAW,GAChD,OAAO;CAGT,IAAM,IAAkB,EAA2B,GAAU,CAAM;CACnE,IAAI,EAAgB,WAAW,GAC7B,OAAO;CAGT,IAAM,IAAiB,IAAI,IAAI,EAAgB,KAAK,EAAE,eAAY,CAAK,CAAC,GAClE,IAAiC,CAAC;CAYxC,OAXA,EAAS,SAAS,GAAO,MAAU;EACjC,IAAI,CAAC,EAAe,IAAI,CAAK,KAAK,CAAC,EAAsB,CAAK,GAAG;GAC/D,EAAa,KAAK,CAAK;GACvB;EACF;EAGA,AAAI,EAAM,WACR,EAAa,KAAK;GAAE,GAAG;GAAO,mBAAmB;EAAK,CAAC;CAE3D,CAAC,GACM;AACT,GAca,KACX,GACA,MACqB;CACrB,IAAM,IAAc,CAAC,GAAG,CAAQ;CAEhC,IAAI,EAAsB,CAAK,GAAG;EAChC,IAAI,EAAM,YAAY,QAAQ,EAAM,sBAAsB,MACxD,OAAO;EAGT,IAAM,IAAY,EAAY,SAAS,GACjC,IAAY,EAAY;EAW9B,OATE,KACA,EAAsB,CAAS,KAC/B,EAAsB,GAAO,CAAS,KAEtC,EAAY,KAAa,EAAyB,GAAO,CAAS,GAC3D,MAGT,EAAY,KAAK,CAAK,GACf;CACT;CAEA,IACG,EAAc,CAAK,KAAK,EAAM,OAAO,SAAS,kBAC9C,EAAe,CAAK,KAAK,EAAM,WAAW,SAC3C;EACA,IAAM,IAAoB,EACxB,GACA,CACF;EACA,IAAI,GACF,OAAO;CAEX;CAKA,IACE,EAAc,CAAK,KACnB,EAAM,OAAO,SAAS,kBACtB,EAAM,OAAO,SAAS,eACtB;EACA,IAAM,IACJ,EAAmC,GAAO,CAAW,KACrD,EAAqC,GAAO,CAAW;EACzD,IAAI,GAEF,OADA,EAAmB,KAAK,CAAK,GACtB;CAEX;CAEA,IAAI,EAAmB,CAAK,GAAG;EAC7B,IAAM,IAAgB,EAAY,WAC/B,MACC,EAAmB,CAAO,KAC1B,EAAQ,iBAAiB,EAAM,YACnC;EAMA,OALI,MAAkB,KAGpB,EAAY,KAAK,CAAK,IAFtB,EAAY,KAAiB,GAIxB;CACT;CAEA,IAAI,EAAmB,CAAK,GAAG;EAU7B,IAPI,EAAM,YAAY,SAAS,sBAO3B,EAAM,YAAY,SAAS,qBAC7B,OAAO;EAIT,IAAM,IAAc,EAAY,WAC7B,MAAY,EAAQ,OAAO,EAAM,SACpC;EACA,AAAI,MAAgB,KAIlB,EAAY,KAAK,CAAK,IAHtB,EAAY,KAAe;CAK/B,OAEE,EAAY,KAAK,CAAK;CAGxB,OAAO;AACT"}
@@ -1,2 +1,2 @@
1
- require("../_virtual/_rolldown/runtime.cjs");const e=require("./mcp-marketplace-utils.cjs"),t=require("../node_modules/@openhands/extensions/integrations/index.cjs");var n=new Set([`invalid_auth`,`not_authed`,`account_inactive`,`token_revoked`,`token_expired`]),r=e=>e.is_error?e.text||`tool call failed`:null,i={github:{toolCall:{name:`get_me`,arguments:{}},interpret:r},linear:{toolCall:{name:`list_teams`,arguments:{}},interpret:r},slack:{toolCall:{name:`slack_list_channels`,arguments:{limit:1}},interpret:e=>{if(e.is_error)return e.text||`tool call failed`;try{let t=JSON.parse(e.text);if(t?.ok===!1&&n.has(t.error))return String(t.error)}catch{}return null}}};function a(n){let r=e.findCatalogEntryForServer(n,e.getMcpMarketplaceCatalog(t.default));return r?i[r.id]:void 0}exports.getCredentialValidationForServer=a;
1
+ require("../_virtual/_rolldown/runtime.cjs");const e=require("../node_modules/@openhands/extensions/integrations/index.cjs"),t=require("./mcp-marketplace-utils.cjs");var n=new Set([`invalid_auth`,`not_authed`,`account_inactive`,`token_revoked`,`token_expired`]),r=e=>e.is_error?e.text||`tool call failed`:null,i={github:{toolCall:{name:`get_me`,arguments:{}},interpret:r},linear:{toolCall:{name:`list_teams`,arguments:{}},interpret:r},slack:{toolCall:{name:`slack_list_channels`,arguments:{limit:1}},interpret:e=>{if(e.is_error)return e.text||`tool call failed`;try{let t=JSON.parse(e.text);if(t?.ok===!1&&n.has(t.error))return String(t.error)}catch{}return null}}};function a(n){let r=t.findCatalogEntryForServer(n,t.getMcpMarketplaceCatalog(e.default));return r?i[r.id]:void 0}exports.getCredentialValidationForServer=a;
2
2
  //# sourceMappingURL=mcp-credential-validation.cjs.map
@@ -1,5 +1,5 @@
1
- import { findCatalogEntryForServer as e, getMcpMarketplaceCatalog as t } from "./mcp-marketplace-utils.js";
2
- import n from "../node_modules/@openhands/extensions/integrations/index.js";
1
+ import e from "../node_modules/@openhands/extensions/integrations/index.js";
2
+ import { findCatalogEntryForServer as t, getMcpMarketplaceCatalog as n } from "./mcp-marketplace-utils.js";
3
3
  //#region src/utils/mcp-credential-validation.ts
4
4
  var r = new Set([
5
5
  "invalid_auth",
@@ -38,7 +38,7 @@ var r = new Set([
38
38
  }
39
39
  };
40
40
  function o(r) {
41
- let i = e(r, t(n));
41
+ let i = t(r, n(e));
42
42
  return i ? a[i.id] : void 0;
43
43
  }
44
44
  //#endregion
@@ -1,2 +1,2 @@
1
- require("../_virtual/_rolldown/runtime.cjs");function e(e){return e.connectionOptions.filter(e=>e.provider===`mcp`&&!!e.transport)}function t(t){return e(t)[0]}function n(e){if(e.auth.strategy!==`oauth2`)return!0;let t=e.auth.oauth;return t?!t.authorizationUrl&&!t.tokenUrl&&!t.registrationUrl&&!t.additionalAuthorizationParams&&!t.additionalTokenParams:!1}function r(t){return e(t).find(n)}function i(e){return t(e)?.transport}function a(e){switch(e){case`none`:return`none`;case`body`:return`client_secret_post`;case`basic`:return`client_secret_basic`;default:return}}function o(e){if(e.auth.strategy!==`oauth2`)return;let t={type:`oauth`},n=a(e.auth.oauth?.clientAuthentication);return n&&(t.client_auth_method=n),e.auth.oauth?.scopes?.length&&(t.scopes=e.auth.oauth.scopes),Object.keys(t).length>1?t:void 0}function s(e){return e.filter(c)}function c(e){return!!t(e)}var l=e=>{try{return new URL(e)}catch{return null}};function u(e,t){let n=typeof e==`string`?e:``,r=typeof t==`string`?t:``;if(!n||!r)return!1;let i=l(n),a=l(r);return!i||!a?n.replace(/\/+$/,``)===r.replace(/\/+$/,``):i.protocol===a.protocol&&i.host===a.host&&i.pathname.replace(/\/+$/,``)===a.pathname.replace(/\/+$/,``)}function d(e,t){if(e.kind===`shttp`){let n=e.url;return t.type===`shttp`&&!!t.url&&u(t.url,n)}if(e.kind===`sse`){let n=e.url;return t.type===`sse`&&!!t.url&&u(t.url,n)}return t.type===`stdio`&&t.name===e.serverName}function f(e){return e.trim().toLowerCase()}function p(e){return e.map((e,t)=>({entry:e,index:t})).sort((e,t)=>(t.entry.popularityRank??0)-(e.entry.popularityRank??0)||e.index-t.index).map(({entry:e})=>e)}function m(e,t){let n=f(t);return n?[e.name,e.description,e.id,...e.keywords??[]].join(` `).toLowerCase().includes(n):!0}function h(e,t,n){let r=f(n);return r?[e.type,`name`in e?e.name:void 0,`command`in e?e.command:void 0,`args`in e?e.args?.join(` `):void 0,`url`in e?e.url:void 0,t?.name,t?.description,t?.id,...t?.keywords??[]].filter(Boolean).join(` `).toLowerCase().includes(r):!0}function g(t,n){return n.find(n=>e(n).some(e=>d(e.transport,t)))}exports.findCatalogEntryForServer=g,exports.getDefaultMcpTransport=i,exports.getInstallableMcpConnectionOption=r,exports.getMarketplaceEntriesByPopularity=p,exports.getMcpMarketplaceCatalog=s,exports.getMcpOAuthAuthenticationConfig=o,exports.installedServerMatchesQuery=h,exports.marketplaceEntryMatchesQuery=m;
1
+ require("../_virtual/_rolldown/runtime.cjs");function e(e){return e.connectionOptions.filter(e=>e.provider===`mcp`&&!!e.transport)}function t(t){return e(t)[0]}function n(e){if(e.auth.strategy!==`oauth2`)return!0;let t=e.auth.oauth;return t?!t.authorizationUrl&&!t.tokenUrl&&!t.registrationUrl&&!t.additionalAuthorizationParams&&!t.additionalTokenParams:!1}function r(t){return e(t).find(n)}function i(e){return t(e)?.transport}function a(e){switch(e){case`none`:return`none`;case`body`:return`client_secret_post`;case`basic`:return`client_secret_basic`;default:return}}function o(e){if(e.auth.strategy!==`oauth2`)return;let t={type:`oauth`},n=a(e.auth.oauth?.clientAuthentication);return n&&(t.client_auth_method=n),e.auth.oauth?.scopes?.length&&(t.scopes=e.auth.oauth.scopes),Object.keys(t).length>1?t:void 0}function s(e){return e.filter(c)}function c(e){return!!t(e)}var l=e=>{try{return new URL(e)}catch{return null}};function u(e,t){let n=typeof e==`string`?e:``,r=typeof t==`string`?t:``;if(!n||!r)return!1;let i=l(n),a=l(r);return!i||!a?n.replace(/\/+$/,``)===r.replace(/\/+$/,``):i.protocol===a.protocol&&i.host===a.host&&i.pathname.replace(/\/+$/,``)===a.pathname.replace(/\/+$/,``)}function d(e,t){return t.find(t=>p(e,t))??null}function f(t,n){for(let r of e(t)){let e=d(r.transport,n);if(e)return e}return null}function p(e,t){if(e.kind===`shttp`){let n=e.url;return t.type===`shttp`&&!!t.url&&u(t.url,n)}if(e.kind===`sse`){let n=e.url;return t.type===`sse`&&!!t.url&&u(t.url,n)}return t.type===`stdio`&&t.name===e.serverName}function m(e){return e.trim().toLowerCase()}function h(e){return e.map((e,t)=>({entry:e,index:t})).sort((e,t)=>(t.entry.popularityRank??0)-(e.entry.popularityRank??0)||e.index-t.index).map(({entry:e})=>e)}function g(e,t){return t.find(t=>t.id===e)}function _(e,t){let n=m(t);return n?[e.name,e.description,e.id,...e.keywords??[]].join(` `).toLowerCase().includes(n):!0}function v(e,t,n){let r=m(n);return r?[e.type,`name`in e?e.name:void 0,`command`in e?e.command:void 0,`args`in e?e.args?.join(` `):void 0,`url`in e?e.url:void 0,t?.name,t?.description,t?.id,...t?.keywords??[]].filter(Boolean).join(` `).toLowerCase().includes(r):!0}function y(t,n){return n.find(n=>e(n).some(e=>p(e.transport,t)))}exports.findCatalogEntryForServer=y,exports.findInstalledEntryMatch=f,exports.getDefaultMcpTransport=i,exports.getInstallableMcpConnectionOption=r,exports.getMarketplaceEntriesByPopularity=h,exports.getMarketplaceEntryById=g,exports.getMcpMarketplaceCatalog=s,exports.getMcpOAuthAuthenticationConfig=o,exports.installedServerMatchesQuery=v,exports.isMcpInstallableEntry=c,exports.marketplaceEntryMatchesQuery=_;
2
2
  //# sourceMappingURL=mcp-marketplace-utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-marketplace-utils.cjs","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type {\n IntegrationAuthConfig,\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationOAuthConfig,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\ntype McpIntegrationAuthConfig = IntegrationAuthConfig & {\n credentialSecretName?: string;\n saveCredentialAsSecretByDefault?: boolean;\n};\n\nexport type McpMarketplaceConnectionOption = Omit<\n IntegrationConnectionOption,\n \"auth\" | \"provider\" | \"transport\"\n> & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n auth: McpIntegrationAuthConfig;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry)[0];\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n if (option.auth.strategy !== \"oauth2\") return true;\n\n const oauth = option.auth.oauth;\n if (!oauth) return false;\n\n // Local agent-server installs only support OAuth flows initiated by the MCP\n // server itself through fastmcp. Catalog entries that specify provider OAuth\n // endpoints still need the hosted integration-auth flow and should not be\n // exposed as locally installable static MCP configs.\n return (\n !oauth.authorizationUrl &&\n !oauth.tokenUrl &&\n !oauth.registrationUrl &&\n !oauth.additionalAuthorizationParams &&\n !oauth.additionalTokenParams\n );\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry).find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nfunction toMcpOAuthClientAuthMethod(\n value: IntegrationOAuthConfig[\"clientAuthentication\"] | undefined,\n): MCPOAuthClientAuthMethod | undefined {\n switch (value) {\n case \"none\":\n return \"none\";\n case \"body\":\n return \"client_secret_post\";\n case \"basic\":\n return \"client_secret_basic\";\n default:\n return undefined;\n }\n}\n\nexport function getMcpOAuthAuthenticationConfig(\n option: McpMarketplaceConnectionOption,\n): MCPAuthenticationConfig | undefined {\n if (option.auth.strategy !== \"oauth2\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n const clientAuthMethod = toMcpOAuthClientAuthMethod(\n option.auth.oauth?.clientAuthentication,\n );\n if (clientAuthMethod) {\n authentication.client_auth_method = clientAuthMethod;\n }\n if (option.auth.oauth?.scopes?.length) {\n authentication.scopes = option.auth.oauth.scopes;\n }\n return Object.keys(authentication).length > 1 ? authentication : undefined;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter(isMcpInstallableEntry);\n}\n\n/**\n * Whether this backend can install/configure the entry as an MCP server.\n * Entries whose only connection options use another provider or transport\n * (e.g. Jira's HTTP/OpenAPI option) exist in the catalog but cannot go\n * through the local MCP install flow.\n */\nexport function isMcpInstallableEntry(entry: MarketplaceEntry): boolean {\n return !!getDefaultMcpConnectionOption(entry);\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp-marketplace-utils.cjs","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type {\n IntegrationAuthConfig,\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationOAuthConfig,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\ntype McpIntegrationAuthConfig = IntegrationAuthConfig & {\n credentialSecretName?: string;\n saveCredentialAsSecretByDefault?: boolean;\n};\n\nexport type McpMarketplaceConnectionOption = Omit<\n IntegrationConnectionOption,\n \"auth\" | \"provider\" | \"transport\"\n> & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n auth: McpIntegrationAuthConfig;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry)[0];\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n if (option.auth.strategy !== \"oauth2\") return true;\n\n const oauth = option.auth.oauth;\n if (!oauth) return false;\n\n // Local agent-server installs only support OAuth flows initiated by the MCP\n // server itself through fastmcp. Catalog entries that specify provider OAuth\n // endpoints still need the hosted integration-auth flow and should not be\n // exposed as locally installable static MCP configs.\n return (\n !oauth.authorizationUrl &&\n !oauth.tokenUrl &&\n !oauth.registrationUrl &&\n !oauth.additionalAuthorizationParams &&\n !oauth.additionalTokenParams\n );\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry).find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nfunction toMcpOAuthClientAuthMethod(\n value: IntegrationOAuthConfig[\"clientAuthentication\"] | undefined,\n): MCPOAuthClientAuthMethod | undefined {\n switch (value) {\n case \"none\":\n return \"none\";\n case \"body\":\n return \"client_secret_post\";\n case \"basic\":\n return \"client_secret_basic\";\n default:\n return undefined;\n }\n}\n\nexport function getMcpOAuthAuthenticationConfig(\n option: McpMarketplaceConnectionOption,\n): MCPAuthenticationConfig | undefined {\n if (option.auth.strategy !== \"oauth2\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n const clientAuthMethod = toMcpOAuthClientAuthMethod(\n option.auth.oauth?.clientAuthentication,\n );\n if (clientAuthMethod) {\n authentication.client_auth_method = clientAuthMethod;\n }\n if (option.auth.oauth?.scopes?.length) {\n authentication.scopes = option.auth.oauth.scopes;\n }\n return Object.keys(authentication).length > 1 ? authentication : undefined;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter(isMcpInstallableEntry);\n}\n\n/**\n * Whether this backend can install/configure the entry as an MCP server.\n * Entries whose only connection options use another provider or transport\n * (e.g. Jira's HTTP/OpenAPI option) exist in the catalog but cannot go\n * through the local MCP install flow.\n */\nexport function isMcpInstallableEntry(entry: MarketplaceEntry): boolean {\n return !!getDefaultMcpConnectionOption(entry);\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"6CA6BA,SAAgB,EACd,EACkC,CAClC,OAAO,EAAM,kBAAkB,OAC5B,GACC,EAAO,WAAa,OAAS,CAAC,CAAC,EAAO,SAC1C,CACF,CAEA,SAAgB,EACd,EAC4C,CAC5C,OAAO,EAAwB,CAAK,EAAE,EACxC,CAEA,SAAS,EACP,EACS,CACT,GAAI,EAAO,KAAK,WAAa,SAAU,MAAO,GAE9C,IAAM,EAAQ,EAAO,KAAK,MAO1B,OANK,EAOH,CAAC,EAAM,kBACP,CAAC,EAAM,UACP,CAAC,EAAM,iBACP,CAAC,EAAM,+BACP,CAAC,EAAM,sBAXU,EAarB,CAEA,SAAgB,EACd,EAC4C,CAC5C,OAAO,EAAwB,CAAK,EAAE,KAAK,CAA6B,CAC1E,CAEA,SAAgB,EACd,EACkC,CAClC,OAAO,EAA8B,CAAK,GAAG,SAC/C,CAEA,SAAS,EACP,EACsC,CACtC,OAAQ,EAAR,CACE,IAAK,OACH,MAAO,OACT,IAAK,OACH,MAAO,qBACT,IAAK,QACH,MAAO,sBACT,QACE,MACJ,CACF,CAEA,SAAgB,EACd,EACqC,CACrC,GAAI,EAAO,KAAK,WAAa,SAAU,OACvC,IAAM,EAA0C,CAAE,KAAM,OAAQ,EAC1D,EAAmB,EACvB,EAAO,KAAK,OAAO,oBACrB,EAOA,OANI,IACF,EAAe,mBAAqB,GAElC,EAAO,KAAK,OAAO,QAAQ,SAC7B,EAAe,OAAS,EAAO,KAAK,MAAM,QAErC,OAAO,KAAK,CAAc,EAAE,OAAS,EAAI,EAAiB,IAAA,EACnE,CAEA,SAAgB,EACd,EACoB,CACpB,OAAO,EAAQ,OAAO,CAAqB,CAC7C,CAQA,SAAgB,EAAsB,EAAkC,CACtE,MAAO,CAAC,CAAC,EAA8B,CAAK,CAC9C,CAEA,IAAM,EAAU,GAA4B,CAC1C,GAAI,CACF,OAAO,IAAI,IAAI,CAAG,CACpB,MAAQ,CACN,OAAO,IACT,CACF,EAaA,SAAgB,EAAU,EAAY,EAAqB,CACzD,IAAM,EAAO,OAAO,GAAM,SAAW,EAAI,GACnC,EAAO,OAAO,GAAM,SAAW,EAAI,GACzC,GAAI,CAAC,GAAQ,CAAC,EAAM,MAAO,GAC3B,IAAM,EAAO,EAAO,CAAI,EAClB,EAAQ,EAAO,CAAI,EAIzB,MAHI,CAAC,GAAQ,CAAC,EACL,EAAK,QAAQ,OAAQ,EAAE,IAAM,EAAK,QAAQ,OAAQ,EAAE,EAG3D,EAAK,WAAa,EAAM,UACxB,EAAK,OAAS,EAAM,MACpB,EAAK,SAAS,QAAQ,OAAQ,EAAE,IAAM,EAAM,SAAS,QAAQ,OAAQ,EAAE,CAE3E,CAOA,SAAgB,EACd,EACA,EACwB,CACxB,OACE,EAAQ,KAAM,GAAW,EAAuB,EAAW,CAAM,CAAC,GAAK,IAE3E,CAEA,SAAgB,EACd,EACA,EACwB,CACxB,IAAK,IAAM,KAAU,EAAwB,CAAK,EAAG,CACnD,IAAM,EAAQ,EAAmB,EAAO,UAAW,CAAO,EAC1D,GAAI,EAAO,OAAO,CACpB,CACA,OAAO,IACT,CAEA,SAAS,EACP,EACA,EACS,CACT,GAAI,EAAU,OAAS,QAAS,CAC9B,IAAM,EAAS,EAAU,IACzB,OACE,EAAO,OAAS,SAAW,CAAC,CAAC,EAAO,KAAO,EAAU,EAAO,IAAK,CAAM,CAE3E,CAEA,GAAI,EAAU,OAAS,MAAO,CAC5B,IAAM,EAAS,EAAU,IACzB,OACE,EAAO,OAAS,OAAS,CAAC,CAAC,EAAO,KAAO,EAAU,EAAO,IAAK,CAAM,CAEzE,CAGA,OAAO,EAAO,OAAS,SAAW,EAAO,OAAS,EAAU,UAC9D,CAEA,SAAS,EAAU,EAAuB,CACxC,OAAO,EAAM,KAAK,EAAE,YAAY,CAClC,CAOA,SAAgB,EACd,EACoB,CACpB,OAAO,EACJ,KAAK,EAAO,KAAW,CAAE,QAAO,OAAM,EAAE,EACxC,MAAM,EAAG,KAEL,EAAE,MAAM,gBAAkB,IAAM,EAAE,MAAM,gBAAkB,IACtC,EAAE,MAAQ,EAAE,KACpC,EACA,KAAK,CAAE,WAAY,CAAK,CAC7B,CAEA,SAAgB,EACd,EACA,EAC8B,CAC9B,OAAO,EAAQ,KAAM,GAAU,EAAM,KAAO,CAAE,CAChD,CAEA,SAAgB,EACd,EACA,EACS,CACT,IAAM,EAAI,EAAU,CAAQ,EAU5B,OATK,EACY,CACf,EAAM,KACN,EAAM,YACN,EAAM,GACN,GAAI,EAAM,UAAY,CAAC,CACzB,EACG,KAAK,GAAG,EACR,YACI,EAAS,SAAS,CAAC,EATX,EAUjB,CASA,SAAgB,EACd,EACA,EACA,EACS,CACT,IAAM,EAAI,EAAU,CAAQ,EAgB5B,OAfK,EACY,CACf,EAAO,KACP,SAAU,EAAS,EAAO,KAAO,IAAA,GACjC,YAAa,EAAS,EAAO,QAAU,IAAA,GACvC,SAAU,EAAS,EAAO,MAAM,KAAK,GAAG,EAAI,IAAA,GAC5C,QAAS,EAAS,EAAO,IAAM,IAAA,GAC/B,GAAc,KACd,GAAc,YACd,GAAc,GACd,GAAI,GAAc,UAAY,CAAC,CACjC,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EACR,YACI,EAAS,SAAS,CAAC,EAfX,EAgBjB,CAOA,SAAgB,EACd,EACA,EAC8B,CAC9B,OAAO,EAAQ,KAAM,GAIZ,EAAwB,CAAK,EAAE,KAAM,GAC1C,EAAuB,EAAO,UAAW,CAAM,CACjD,CACD,CACH"}
@@ -49,6 +49,16 @@ function u(e, t) {
49
49
  return !i || !a ? n.replace(/\/+$/, "") === r.replace(/\/+$/, "") : i.protocol === a.protocol && i.host === a.host && i.pathname.replace(/\/+$/, "") === a.pathname.replace(/\/+$/, "");
50
50
  }
51
51
  function d(e, t) {
52
+ return t.find((t) => p(e, t)) ?? null;
53
+ }
54
+ function f(t, n) {
55
+ for (let r of e(t)) {
56
+ let e = d(r.transport, n);
57
+ if (e) return e;
58
+ }
59
+ return null;
60
+ }
61
+ function p(e, t) {
52
62
  if (e.kind === "shttp") {
53
63
  let n = e.url;
54
64
  return t.type === "shttp" && !!t.url && u(t.url, n);
@@ -59,17 +69,20 @@ function d(e, t) {
59
69
  }
60
70
  return t.type === "stdio" && t.name === e.serverName;
61
71
  }
62
- function f(e) {
72
+ function m(e) {
63
73
  return e.trim().toLowerCase();
64
74
  }
65
- function p(e) {
75
+ function h(e) {
66
76
  return e.map((e, t) => ({
67
77
  entry: e,
68
78
  index: t
69
79
  })).sort((e, t) => (t.entry.popularityRank ?? 0) - (e.entry.popularityRank ?? 0) || e.index - t.index).map(({ entry: e }) => e);
70
80
  }
71
- function m(e, t) {
72
- let n = f(t);
81
+ function g(e, t) {
82
+ return t.find((t) => t.id === e);
83
+ }
84
+ function _(e, t) {
85
+ let n = m(t);
73
86
  return n ? [
74
87
  e.name,
75
88
  e.description,
@@ -77,8 +90,8 @@ function m(e, t) {
77
90
  ...e.keywords ?? []
78
91
  ].join(" ").toLowerCase().includes(n) : !0;
79
92
  }
80
- function h(e, t, n) {
81
- let r = f(n);
93
+ function v(e, t, n) {
94
+ let r = m(n);
82
95
  return r ? [
83
96
  e.type,
84
97
  "name" in e ? e.name : void 0,
@@ -91,10 +104,10 @@ function h(e, t, n) {
91
104
  ...t?.keywords ?? []
92
105
  ].filter(Boolean).join(" ").toLowerCase().includes(r) : !0;
93
106
  }
94
- function g(t, n) {
95
- return n.find((n) => e(n).some((e) => d(e.transport, t)));
107
+ function y(t, n) {
108
+ return n.find((n) => e(n).some((e) => p(e.transport, t)));
96
109
  }
97
110
  //#endregion
98
- export { g as findCatalogEntryForServer, i as getDefaultMcpTransport, r as getInstallableMcpConnectionOption, p as getMarketplaceEntriesByPopularity, s as getMcpMarketplaceCatalog, o as getMcpOAuthAuthenticationConfig, h as installedServerMatchesQuery, m as marketplaceEntryMatchesQuery };
111
+ export { y as findCatalogEntryForServer, f as findInstalledEntryMatch, i as getDefaultMcpTransport, r as getInstallableMcpConnectionOption, h as getMarketplaceEntriesByPopularity, g as getMarketplaceEntryById, s as getMcpMarketplaceCatalog, o as getMcpOAuthAuthenticationConfig, v as installedServerMatchesQuery, c as isMcpInstallableEntry, _ as marketplaceEntryMatchesQuery };
99
112
 
100
113
  //# sourceMappingURL=mcp-marketplace-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-marketplace-utils.js","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type {\n IntegrationAuthConfig,\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationOAuthConfig,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\ntype McpIntegrationAuthConfig = IntegrationAuthConfig & {\n credentialSecretName?: string;\n saveCredentialAsSecretByDefault?: boolean;\n};\n\nexport type McpMarketplaceConnectionOption = Omit<\n IntegrationConnectionOption,\n \"auth\" | \"provider\" | \"transport\"\n> & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n auth: McpIntegrationAuthConfig;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry)[0];\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n if (option.auth.strategy !== \"oauth2\") return true;\n\n const oauth = option.auth.oauth;\n if (!oauth) return false;\n\n // Local agent-server installs only support OAuth flows initiated by the MCP\n // server itself through fastmcp. Catalog entries that specify provider OAuth\n // endpoints still need the hosted integration-auth flow and should not be\n // exposed as locally installable static MCP configs.\n return (\n !oauth.authorizationUrl &&\n !oauth.tokenUrl &&\n !oauth.registrationUrl &&\n !oauth.additionalAuthorizationParams &&\n !oauth.additionalTokenParams\n );\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry).find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nfunction toMcpOAuthClientAuthMethod(\n value: IntegrationOAuthConfig[\"clientAuthentication\"] | undefined,\n): MCPOAuthClientAuthMethod | undefined {\n switch (value) {\n case \"none\":\n return \"none\";\n case \"body\":\n return \"client_secret_post\";\n case \"basic\":\n return \"client_secret_basic\";\n default:\n return undefined;\n }\n}\n\nexport function getMcpOAuthAuthenticationConfig(\n option: McpMarketplaceConnectionOption,\n): MCPAuthenticationConfig | undefined {\n if (option.auth.strategy !== \"oauth2\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n const clientAuthMethod = toMcpOAuthClientAuthMethod(\n option.auth.oauth?.clientAuthentication,\n );\n if (clientAuthMethod) {\n authentication.client_auth_method = clientAuthMethod;\n }\n if (option.auth.oauth?.scopes?.length) {\n authentication.scopes = option.auth.oauth.scopes;\n }\n return Object.keys(authentication).length > 1 ? authentication : undefined;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter(isMcpInstallableEntry);\n}\n\n/**\n * Whether this backend can install/configure the entry as an MCP server.\n * Entries whose only connection options use another provider or transport\n * (e.g. Jira's HTTP/OpenAPI option) exist in the catalog but cannot go\n * through the local MCP install flow.\n */\nexport function isMcpInstallableEntry(entry: MarketplaceEntry): boolean {\n return !!getDefaultMcpConnectionOption(entry);\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp-marketplace-utils.js","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type {\n IntegrationAuthConfig,\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationOAuthConfig,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\ntype McpIntegrationAuthConfig = IntegrationAuthConfig & {\n credentialSecretName?: string;\n saveCredentialAsSecretByDefault?: boolean;\n};\n\nexport type McpMarketplaceConnectionOption = Omit<\n IntegrationConnectionOption,\n \"auth\" | \"provider\" | \"transport\"\n> & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n auth: McpIntegrationAuthConfig;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry)[0];\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n if (option.auth.strategy !== \"oauth2\") return true;\n\n const oauth = option.auth.oauth;\n if (!oauth) return false;\n\n // Local agent-server installs only support OAuth flows initiated by the MCP\n // server itself through fastmcp. Catalog entries that specify provider OAuth\n // endpoints still need the hosted integration-auth flow and should not be\n // exposed as locally installable static MCP configs.\n return (\n !oauth.authorizationUrl &&\n !oauth.tokenUrl &&\n !oauth.registrationUrl &&\n !oauth.additionalAuthorizationParams &&\n !oauth.additionalTokenParams\n );\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry).find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nfunction toMcpOAuthClientAuthMethod(\n value: IntegrationOAuthConfig[\"clientAuthentication\"] | undefined,\n): MCPOAuthClientAuthMethod | undefined {\n switch (value) {\n case \"none\":\n return \"none\";\n case \"body\":\n return \"client_secret_post\";\n case \"basic\":\n return \"client_secret_basic\";\n default:\n return undefined;\n }\n}\n\nexport function getMcpOAuthAuthenticationConfig(\n option: McpMarketplaceConnectionOption,\n): MCPAuthenticationConfig | undefined {\n if (option.auth.strategy !== \"oauth2\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n const clientAuthMethod = toMcpOAuthClientAuthMethod(\n option.auth.oauth?.clientAuthentication,\n );\n if (clientAuthMethod) {\n authentication.client_auth_method = clientAuthMethod;\n }\n if (option.auth.oauth?.scopes?.length) {\n authentication.scopes = option.auth.oauth.scopes;\n }\n return Object.keys(authentication).length > 1 ? authentication : undefined;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter(isMcpInstallableEntry);\n}\n\n/**\n * Whether this backend can install/configure the entry as an MCP server.\n * Entries whose only connection options use another provider or transport\n * (e.g. Jira's HTTP/OpenAPI option) exist in the catalog but cannot go\n * through the local MCP install flow.\n */\nexport function isMcpInstallableEntry(entry: MarketplaceEntry): boolean {\n return !!getDefaultMcpConnectionOption(entry);\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- require("../_virtual/_rolldown/runtime.cjs");var e={"github.com":`github`,"gitlab.com":`gitlab`,"bitbucket.org":`bitbucket`,"dev.azure.com":`azure_devops`};function t(e){return e.replace(/\.git$/,``)}function n(t){return t?e[t.toLowerCase()]??null:null}function r(e){let t=e.split(`/`).filter(Boolean),n=t.indexOf(`_git`);return n===-1?t.join(`/`):[...t.slice(0,n),...t.slice(n+1)].join(`/`)}function i(e,i,a){let o=t(a.replace(/^\/+/,``)),s=n(i);return{url:e,host:i,repository:(s===`azure_devops`?r(o):o)||null,provider:s}}function a(e){let t=e?.trim();if(!t)return null;let n=t.match(/^[^@\s]+@([^:\s]+):(.+)$/);if(n){let e=n[1];return i(t,e,n[2])}try{let e=new URL(t);return i(t,e.hostname||null,e.pathname)}catch{return null}}exports.parseGitRemoteUrl=a;
1
+ require("../_virtual/_rolldown/runtime.cjs");var e={"github.com":`github`,"gitlab.com":`gitlab`,"bitbucket.org":`bitbucket`,"dev.azure.com":`azure_devops`};function t(e){return e.replace(/\.git$/,``)}function n(t){return t?e[t.toLowerCase()]??null:null}function r(e){let t=e.split(`/`).filter(Boolean),n=t.indexOf(`_git`);return n===-1?t.join(`/`):[...t.slice(0,n),...t.slice(n+1)].join(`/`)}function i(e,i,a){let o=t(a.replace(/^\/+|\/+$/g,``)),s=n(i);return{url:e,host:i,repository:(s===`azure_devops`?r(o):o)||null,provider:s}}function a(e){let t=e?.trim();if(!t)return null;try{let e=new URL(t);if(e.hostname)return i(t,e.hostname,e.pathname)}catch{}let n=t.match(/^[^@\s]+@([^:\s]+):(.+)$/);if(n){let e=n[1];return i(t,e,n[2])}return null}exports.parseGitRemoteUrl=a;
2
2
  //# sourceMappingURL=parse-git-remote-url.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-git-remote-url.cjs","names":[],"sources":["../../src/utils/parse-git-remote-url.ts"],"sourcesContent":["import { Provider } from \"#/types/settings\";\n\nexport interface ParsedGitRemoteUrl {\n /** Original URL, trimmed. */\n url: string;\n /** Hostname of the remote (e.g. `github.com`, `git.example.com`). */\n host: string | null;\n /** Path-style identifier, normalized to `owner/repo` (no leading slash, no `.git` suffix). */\n repository: string | null;\n /** Best-effort provider detection from the host. `null` for unrecognized/self-hosted hosts. */\n provider: Provider | null;\n}\n\nconst KNOWN_HOSTS: Record<string, Provider> = {\n \"github.com\": \"github\",\n \"gitlab.com\": \"gitlab\",\n \"bitbucket.org\": \"bitbucket\",\n \"dev.azure.com\": \"azure_devops\",\n};\n\nfunction stripGitSuffix(path: string): string {\n return path.replace(/\\.git$/, \"\");\n}\n\nfunction detectProvider(host: string | null): Provider | null {\n if (!host) return null;\n return KNOWN_HOSTS[host.toLowerCase()] ?? null;\n}\n\nfunction normalizeAzureDevOpsPath(path: string): string {\n // Azure paths look like `org/project/_git/repo` or `org/_git/repo`.\n // Normalize to `org/project/repo` (or `org/repo`) so it lines up with\n // constructBranchUrl's expectations.\n const segments = path.split(\"/\").filter(Boolean);\n const gitIndex = segments.indexOf(\"_git\");\n if (gitIndex === -1) return segments.join(\"/\");\n return [...segments.slice(0, gitIndex), ...segments.slice(gitIndex + 1)].join(\n \"/\",\n );\n}\n\nfunction buildParsedGitRemoteUrl(\n url: string,\n host: string | null,\n rawPath: string,\n): ParsedGitRemoteUrl {\n const path = stripGitSuffix(rawPath.replace(/^\\/+/, \"\"));\n const provider = detectProvider(host);\n const repository =\n provider === \"azure_devops\" ? normalizeAzureDevOpsPath(path) : path;\n\n return {\n url,\n host,\n repository: repository || null,\n provider,\n };\n}\n\n/**\n * Parse a git remote URL (HTTPS, SSH, or `git@host:path` shorthand) into its\n * host, repository (`owner/repo`), and best-effort provider.\n *\n * Returns `null` if the URL is empty or unparseable. Unknown hosts still\n * resolve `host` and `repository`; only `provider` is left `null`.\n */\nexport function parseGitRemoteUrl(\n remoteUrl: string | null | undefined,\n): ParsedGitRemoteUrl | null {\n const url = remoteUrl?.trim();\n if (!url) return null;\n\n // git@host:owner/repo(.git)\n const scpMatch = url.match(/^[^@\\s]+@([^:\\s]+):(.+)$/);\n if (scpMatch) {\n const host = scpMatch[1];\n return buildParsedGitRemoteUrl(url, host, scpMatch[2]);\n }\n\n // ssh://, https://, http://, git://\n try {\n const parsed = new URL(url);\n return buildParsedGitRemoteUrl(\n url,\n parsed.hostname || null,\n parsed.pathname,\n );\n } catch {\n return null;\n }\n}\n"],"mappings":"6CAaA,IAAM,EAAwC,CAC5C,aAAc,SACd,aAAc,SACd,gBAAiB,YACjB,gBAAiB,cACnB,EAEA,SAAS,EAAe,EAAsB,CAC5C,OAAO,EAAK,QAAQ,SAAU,EAAE,CAClC,CAEA,SAAS,EAAe,EAAsC,CAE5D,OADK,EACE,EAAY,EAAK,YAAY,IAAM,KADxB,IAEpB,CAEA,SAAS,EAAyB,EAAsB,CAItD,IAAM,EAAW,EAAK,MAAM,GAAG,EAAE,OAAO,OAAO,EACzC,EAAW,EAAS,QAAQ,MAAM,EAExC,OADI,IAAa,GAAW,EAAS,KAAK,GAAG,EACtC,CAAC,GAAG,EAAS,MAAM,EAAG,CAAQ,EAAG,GAAG,EAAS,MAAM,EAAW,CAAC,CAAC,EAAE,KACvE,GACF,CACF,CAEA,SAAS,EACP,EACA,EACA,EACoB,CACpB,IAAM,EAAO,EAAe,EAAQ,QAAQ,OAAQ,EAAE,CAAC,EACjD,EAAW,EAAe,CAAI,EAIpC,MAAO,CACL,MACA,OACA,YALA,IAAa,eAAiB,EAAyB,CAAI,EAAI,IAKrC,KAC1B,UACF,CACF,CASA,SAAgB,EACd,EAC2B,CAC3B,IAAM,EAAM,GAAW,KAAK,EAC5B,GAAI,CAAC,EAAK,OAAO,KAGjB,IAAM,EAAW,EAAI,MAAM,0BAA0B,EACrD,GAAI,EAAU,CACZ,IAAM,EAAO,EAAS,GACtB,OAAO,EAAwB,EAAK,EAAM,EAAS,EAAE,CACvD,CAGA,GAAI,CACF,IAAM,EAAS,IAAI,IAAI,CAAG,EAC1B,OAAO,EACL,EACA,EAAO,UAAY,KACnB,EAAO,QACT,CACF,MAAQ,CACN,OAAO,IACT,CACF"}
1
+ {"version":3,"file":"parse-git-remote-url.cjs","names":[],"sources":["../../src/utils/parse-git-remote-url.ts"],"sourcesContent":["import { Provider } from \"#/types/settings\";\n\nexport interface ParsedGitRemoteUrl {\n /** Original URL, trimmed. */\n url: string;\n /** Hostname of the remote (e.g. `github.com`, `git.example.com`). */\n host: string | null;\n /** Path-style identifier, normalized to `owner/repo` (no leading slash, no `.git` suffix). */\n repository: string | null;\n /** Best-effort provider detection from the host. `null` for unrecognized/self-hosted hosts. */\n provider: Provider | null;\n}\n\nconst KNOWN_HOSTS: Record<string, Provider> = {\n \"github.com\": \"github\",\n \"gitlab.com\": \"gitlab\",\n \"bitbucket.org\": \"bitbucket\",\n \"dev.azure.com\": \"azure_devops\",\n};\n\nfunction stripGitSuffix(path: string): string {\n return path.replace(/\\.git$/, \"\");\n}\n\nfunction detectProvider(host: string | null): Provider | null {\n if (!host) return null;\n return KNOWN_HOSTS[host.toLowerCase()] ?? null;\n}\n\nfunction normalizeAzureDevOpsPath(path: string): string {\n // Azure paths look like `org/project/_git/repo` or `org/_git/repo`.\n // Normalize to `org/project/repo` (or `org/repo`) so it lines up with\n // constructBranchUrl's expectations.\n const segments = path.split(\"/\").filter(Boolean);\n const gitIndex = segments.indexOf(\"_git\");\n if (gitIndex === -1) return segments.join(\"/\");\n return [...segments.slice(0, gitIndex), ...segments.slice(gitIndex + 1)].join(\n \"/\",\n );\n}\n\nfunction buildParsedGitRemoteUrl(\n url: string,\n host: string | null,\n rawPath: string,\n): ParsedGitRemoteUrl {\n const path = stripGitSuffix(rawPath.replace(/^\\/+|\\/+$/g, \"\"));\n const provider = detectProvider(host);\n const repository =\n provider === \"azure_devops\" ? normalizeAzureDevOpsPath(path) : path;\n\n return {\n url,\n host,\n repository: repository || null,\n provider,\n };\n}\n\n/**\n * Parse a git remote URL (HTTPS, SSH, or `git@host:path` shorthand) into its\n * host, repository (`owner/repo`), and best-effort provider.\n *\n * Returns `null` if the URL is empty or unparseable. Unknown hosts still\n * resolve `host` and `repository`; only `provider` is left `null`.\n */\nexport function parseGitRemoteUrl(\n remoteUrl: string | null | undefined,\n): ParsedGitRemoteUrl | null {\n const url = remoteUrl?.trim();\n if (!url) return null;\n\n // ssh://, https://, http://, git://. Tried before the shorthand match\n // below, whose `[^@\\s]+` would otherwise swallow `ssh://git` and read the\n // port in `ssh://git@host:2222/owner/repo` as the first path segment.\n try {\n const parsed = new URL(url);\n // A bare Windows path (`C:/src/repo`) parses as a `c:` scheme with an\n // empty host, so it is left to the shorthand match below.\n if (parsed.hostname) {\n return buildParsedGitRemoteUrl(url, parsed.hostname, parsed.pathname);\n }\n } catch {\n // Not a URL the WHATWG parser accepts, so try the shorthand form.\n }\n\n // git@host:owner/repo(.git)\n const scpMatch = url.match(/^[^@\\s]+@([^:\\s]+):(.+)$/);\n if (scpMatch) {\n const host = scpMatch[1];\n return buildParsedGitRemoteUrl(url, host, scpMatch[2]);\n }\n\n return null;\n}\n"],"mappings":"6CAaA,IAAM,EAAwC,CAC5C,aAAc,SACd,aAAc,SACd,gBAAiB,YACjB,gBAAiB,cACnB,EAEA,SAAS,EAAe,EAAsB,CAC5C,OAAO,EAAK,QAAQ,SAAU,EAAE,CAClC,CAEA,SAAS,EAAe,EAAsC,CAE5D,OADK,EACE,EAAY,EAAK,YAAY,IAAM,KADxB,IAEpB,CAEA,SAAS,EAAyB,EAAsB,CAItD,IAAM,EAAW,EAAK,MAAM,GAAG,EAAE,OAAO,OAAO,EACzC,EAAW,EAAS,QAAQ,MAAM,EAExC,OADI,IAAa,GAAW,EAAS,KAAK,GAAG,EACtC,CAAC,GAAG,EAAS,MAAM,EAAG,CAAQ,EAAG,GAAG,EAAS,MAAM,EAAW,CAAC,CAAC,EAAE,KACvE,GACF,CACF,CAEA,SAAS,EACP,EACA,EACA,EACoB,CACpB,IAAM,EAAO,EAAe,EAAQ,QAAQ,aAAc,EAAE,CAAC,EACvD,EAAW,EAAe,CAAI,EAIpC,MAAO,CACL,MACA,OACA,YALA,IAAa,eAAiB,EAAyB,CAAI,EAAI,IAKrC,KAC1B,UACF,CACF,CASA,SAAgB,EACd,EAC2B,CAC3B,IAAM,EAAM,GAAW,KAAK,EAC5B,GAAI,CAAC,EAAK,OAAO,KAKjB,GAAI,CACF,IAAM,EAAS,IAAI,IAAI,CAAG,EAG1B,GAAI,EAAO,SACT,OAAO,EAAwB,EAAK,EAAO,SAAU,EAAO,QAAQ,CAExE,MAAQ,CAER,CAGA,IAAM,EAAW,EAAI,MAAM,0BAA0B,EACrD,GAAI,EAAU,CACZ,IAAM,EAAO,EAAS,GACtB,OAAO,EAAwB,EAAK,EAAM,EAAS,EAAE,CACvD,CAEA,OAAO,IACT"}
@@ -16,7 +16,7 @@ function r(e) {
16
16
  return n === -1 ? t.join("/") : [...t.slice(0, n), ...t.slice(n + 1)].join("/");
17
17
  }
18
18
  function i(e, i, a) {
19
- let o = t(a.replace(/^\/+/, "")), s = n(i);
19
+ let o = t(a.replace(/^\/+|\/+$/g, "")), s = n(i);
20
20
  return {
21
21
  url: e,
22
22
  host: i,
@@ -27,17 +27,16 @@ function i(e, i, a) {
27
27
  function a(e) {
28
28
  let t = e?.trim();
29
29
  if (!t) return null;
30
+ try {
31
+ let e = new URL(t);
32
+ if (e.hostname) return i(t, e.hostname, e.pathname);
33
+ } catch {}
30
34
  let n = t.match(/^[^@\s]+@([^:\s]+):(.+)$/);
31
35
  if (n) {
32
36
  let e = n[1];
33
37
  return i(t, e, n[2]);
34
38
  }
35
- try {
36
- let e = new URL(t);
37
- return i(t, e.hostname || null, e.pathname);
38
- } catch {
39
- return null;
40
- }
39
+ return null;
41
40
  }
42
41
  //#endregion
43
42
  export { a as parseGitRemoteUrl };
@@ -1 +1 @@
1
- {"version":3,"file":"parse-git-remote-url.js","names":[],"sources":["../../src/utils/parse-git-remote-url.ts"],"sourcesContent":["import { Provider } from \"#/types/settings\";\n\nexport interface ParsedGitRemoteUrl {\n /** Original URL, trimmed. */\n url: string;\n /** Hostname of the remote (e.g. `github.com`, `git.example.com`). */\n host: string | null;\n /** Path-style identifier, normalized to `owner/repo` (no leading slash, no `.git` suffix). */\n repository: string | null;\n /** Best-effort provider detection from the host. `null` for unrecognized/self-hosted hosts. */\n provider: Provider | null;\n}\n\nconst KNOWN_HOSTS: Record<string, Provider> = {\n \"github.com\": \"github\",\n \"gitlab.com\": \"gitlab\",\n \"bitbucket.org\": \"bitbucket\",\n \"dev.azure.com\": \"azure_devops\",\n};\n\nfunction stripGitSuffix(path: string): string {\n return path.replace(/\\.git$/, \"\");\n}\n\nfunction detectProvider(host: string | null): Provider | null {\n if (!host) return null;\n return KNOWN_HOSTS[host.toLowerCase()] ?? null;\n}\n\nfunction normalizeAzureDevOpsPath(path: string): string {\n // Azure paths look like `org/project/_git/repo` or `org/_git/repo`.\n // Normalize to `org/project/repo` (or `org/repo`) so it lines up with\n // constructBranchUrl's expectations.\n const segments = path.split(\"/\").filter(Boolean);\n const gitIndex = segments.indexOf(\"_git\");\n if (gitIndex === -1) return segments.join(\"/\");\n return [...segments.slice(0, gitIndex), ...segments.slice(gitIndex + 1)].join(\n \"/\",\n );\n}\n\nfunction buildParsedGitRemoteUrl(\n url: string,\n host: string | null,\n rawPath: string,\n): ParsedGitRemoteUrl {\n const path = stripGitSuffix(rawPath.replace(/^\\/+/, \"\"));\n const provider = detectProvider(host);\n const repository =\n provider === \"azure_devops\" ? normalizeAzureDevOpsPath(path) : path;\n\n return {\n url,\n host,\n repository: repository || null,\n provider,\n };\n}\n\n/**\n * Parse a git remote URL (HTTPS, SSH, or `git@host:path` shorthand) into its\n * host, repository (`owner/repo`), and best-effort provider.\n *\n * Returns `null` if the URL is empty or unparseable. Unknown hosts still\n * resolve `host` and `repository`; only `provider` is left `null`.\n */\nexport function parseGitRemoteUrl(\n remoteUrl: string | null | undefined,\n): ParsedGitRemoteUrl | null {\n const url = remoteUrl?.trim();\n if (!url) return null;\n\n // git@host:owner/repo(.git)\n const scpMatch = url.match(/^[^@\\s]+@([^:\\s]+):(.+)$/);\n if (scpMatch) {\n const host = scpMatch[1];\n return buildParsedGitRemoteUrl(url, host, scpMatch[2]);\n }\n\n // ssh://, https://, http://, git://\n try {\n const parsed = new URL(url);\n return buildParsedGitRemoteUrl(\n url,\n parsed.hostname || null,\n parsed.pathname,\n );\n } catch {\n return null;\n }\n}\n"],"mappings":";AAaA,IAAM,IAAwC;CAC5C,cAAc;CACd,cAAc;CACd,iBAAiB;CACjB,iBAAiB;AACnB;AAEA,SAAS,EAAe,GAAsB;CAC5C,OAAO,EAAK,QAAQ,UAAU,EAAE;AAClC;AAEA,SAAS,EAAe,GAAsC;CAE5D,OADK,IACE,EAAY,EAAK,YAAY,MAAM,OADxB;AAEpB;AAEA,SAAS,EAAyB,GAAsB;CAItD,IAAM,IAAW,EAAK,MAAM,GAAG,EAAE,OAAO,OAAO,GACzC,IAAW,EAAS,QAAQ,MAAM;CAExC,OADI,MAAa,KAAW,EAAS,KAAK,GAAG,IACtC,CAAC,GAAG,EAAS,MAAM,GAAG,CAAQ,GAAG,GAAG,EAAS,MAAM,IAAW,CAAC,CAAC,EAAE,KACvE,GACF;AACF;AAEA,SAAS,EACP,GACA,GACA,GACoB;CACpB,IAAM,IAAO,EAAe,EAAQ,QAAQ,QAAQ,EAAE,CAAC,GACjD,IAAW,EAAe,CAAI;CAIpC,OAAO;EACL;EACA;EACA,aALA,MAAa,iBAAiB,EAAyB,CAAI,IAAI,MAKrC;EAC1B;CACF;AACF;AASA,SAAgB,EACd,GAC2B;CAC3B,IAAM,IAAM,GAAW,KAAK;CAC5B,IAAI,CAAC,GAAK,OAAO;CAGjB,IAAM,IAAW,EAAI,MAAM,0BAA0B;CACrD,IAAI,GAAU;EACZ,IAAM,IAAO,EAAS;EACtB,OAAO,EAAwB,GAAK,GAAM,EAAS,EAAE;CACvD;CAGA,IAAI;EACF,IAAM,IAAS,IAAI,IAAI,CAAG;EAC1B,OAAO,EACL,GACA,EAAO,YAAY,MACnB,EAAO,QACT;CACF,QAAQ;EACN,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"parse-git-remote-url.js","names":[],"sources":["../../src/utils/parse-git-remote-url.ts"],"sourcesContent":["import { Provider } from \"#/types/settings\";\n\nexport interface ParsedGitRemoteUrl {\n /** Original URL, trimmed. */\n url: string;\n /** Hostname of the remote (e.g. `github.com`, `git.example.com`). */\n host: string | null;\n /** Path-style identifier, normalized to `owner/repo` (no leading slash, no `.git` suffix). */\n repository: string | null;\n /** Best-effort provider detection from the host. `null` for unrecognized/self-hosted hosts. */\n provider: Provider | null;\n}\n\nconst KNOWN_HOSTS: Record<string, Provider> = {\n \"github.com\": \"github\",\n \"gitlab.com\": \"gitlab\",\n \"bitbucket.org\": \"bitbucket\",\n \"dev.azure.com\": \"azure_devops\",\n};\n\nfunction stripGitSuffix(path: string): string {\n return path.replace(/\\.git$/, \"\");\n}\n\nfunction detectProvider(host: string | null): Provider | null {\n if (!host) return null;\n return KNOWN_HOSTS[host.toLowerCase()] ?? null;\n}\n\nfunction normalizeAzureDevOpsPath(path: string): string {\n // Azure paths look like `org/project/_git/repo` or `org/_git/repo`.\n // Normalize to `org/project/repo` (or `org/repo`) so it lines up with\n // constructBranchUrl's expectations.\n const segments = path.split(\"/\").filter(Boolean);\n const gitIndex = segments.indexOf(\"_git\");\n if (gitIndex === -1) return segments.join(\"/\");\n return [...segments.slice(0, gitIndex), ...segments.slice(gitIndex + 1)].join(\n \"/\",\n );\n}\n\nfunction buildParsedGitRemoteUrl(\n url: string,\n host: string | null,\n rawPath: string,\n): ParsedGitRemoteUrl {\n const path = stripGitSuffix(rawPath.replace(/^\\/+|\\/+$/g, \"\"));\n const provider = detectProvider(host);\n const repository =\n provider === \"azure_devops\" ? normalizeAzureDevOpsPath(path) : path;\n\n return {\n url,\n host,\n repository: repository || null,\n provider,\n };\n}\n\n/**\n * Parse a git remote URL (HTTPS, SSH, or `git@host:path` shorthand) into its\n * host, repository (`owner/repo`), and best-effort provider.\n *\n * Returns `null` if the URL is empty or unparseable. Unknown hosts still\n * resolve `host` and `repository`; only `provider` is left `null`.\n */\nexport function parseGitRemoteUrl(\n remoteUrl: string | null | undefined,\n): ParsedGitRemoteUrl | null {\n const url = remoteUrl?.trim();\n if (!url) return null;\n\n // ssh://, https://, http://, git://. Tried before the shorthand match\n // below, whose `[^@\\s]+` would otherwise swallow `ssh://git` and read the\n // port in `ssh://git@host:2222/owner/repo` as the first path segment.\n try {\n const parsed = new URL(url);\n // A bare Windows path (`C:/src/repo`) parses as a `c:` scheme with an\n // empty host, so it is left to the shorthand match below.\n if (parsed.hostname) {\n return buildParsedGitRemoteUrl(url, parsed.hostname, parsed.pathname);\n }\n } catch {\n // Not a URL the WHATWG parser accepts, so try the shorthand form.\n }\n\n // git@host:owner/repo(.git)\n const scpMatch = url.match(/^[^@\\s]+@([^:\\s]+):(.+)$/);\n if (scpMatch) {\n const host = scpMatch[1];\n return buildParsedGitRemoteUrl(url, host, scpMatch[2]);\n }\n\n return null;\n}\n"],"mappings":";AAaA,IAAM,IAAwC;CAC5C,cAAc;CACd,cAAc;CACd,iBAAiB;CACjB,iBAAiB;AACnB;AAEA,SAAS,EAAe,GAAsB;CAC5C,OAAO,EAAK,QAAQ,UAAU,EAAE;AAClC;AAEA,SAAS,EAAe,GAAsC;CAE5D,OADK,IACE,EAAY,EAAK,YAAY,MAAM,OADxB;AAEpB;AAEA,SAAS,EAAyB,GAAsB;CAItD,IAAM,IAAW,EAAK,MAAM,GAAG,EAAE,OAAO,OAAO,GACzC,IAAW,EAAS,QAAQ,MAAM;CAExC,OADI,MAAa,KAAW,EAAS,KAAK,GAAG,IACtC,CAAC,GAAG,EAAS,MAAM,GAAG,CAAQ,GAAG,GAAG,EAAS,MAAM,IAAW,CAAC,CAAC,EAAE,KACvE,GACF;AACF;AAEA,SAAS,EACP,GACA,GACA,GACoB;CACpB,IAAM,IAAO,EAAe,EAAQ,QAAQ,cAAc,EAAE,CAAC,GACvD,IAAW,EAAe,CAAI;CAIpC,OAAO;EACL;EACA;EACA,aALA,MAAa,iBAAiB,EAAyB,CAAI,IAAI,MAKrC;EAC1B;CACF;AACF;AASA,SAAgB,EACd,GAC2B;CAC3B,IAAM,IAAM,GAAW,KAAK;CAC5B,IAAI,CAAC,GAAK,OAAO;CAKjB,IAAI;EACF,IAAM,IAAS,IAAI,IAAI,CAAG;EAG1B,IAAI,EAAO,UACT,OAAO,EAAwB,GAAK,EAAO,UAAU,EAAO,QAAQ;CAExE,QAAQ,CAER;CAGA,IAAM,IAAW,EAAI,MAAM,0BAA0B;CACrD,IAAI,GAAU;EACZ,IAAM,IAAO,EAAS;EACtB,OAAO,EAAwB,GAAK,GAAM,EAAS,EAAE;CACvD;CAEA,OAAO;AACT"}
@@ -0,0 +1,2 @@
1
+ require("../_virtual/_rolldown/runtime.cjs");const e=require("../node_modules/@openhands/extensions/automations/index.cjs"),t=require("../manifests/manifest-sources.cjs"),n=require("../manifests/automation-interface.cjs");function r(e){return e.map((e,t)=>({automation:e,index:t})).sort((e,t)=>(t.automation.popularityRank??0)-(e.automation.popularityRank??0)||e.index-t.index).map(({automation:e})=>e)}function i(e){return e.trim().toLowerCase().replace(/&/g,`and`).replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)}function a(e){return[e.id,e.name,e.skill].filter(e=>!!e).map(i)}function o(e,t){let n=new Set(t.map(e=>i(e.name)));return a(e).some(e=>n.has(e))}function s(e){return n.getFeaturedAutomationIds().includes(e.id)}function c(e){return t.SETUP_REGISTRY.findById(e.id)==null}function l(t){let n=r(e.default).filter(e=>!o(e,t));return{proven:n.filter(s),conversation:n.filter(e=>!s(e)&&c(e))}}function u(e){return[...e.proven,...e.conversation]}exports.flattenRecommendedRailGroups=u,exports.getAutomationsByPopularity=r,exports.getRecommendedRailGroups=l;
2
+ //# sourceMappingURL=recommended-automation-rail.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommended-automation-rail.cjs","names":[],"sources":["../../src/utils/recommended-automation-rail.ts"],"sourcesContent":["import {\n AUTOMATION_CATALOG,\n type RecommendedAutomation,\n} from \"@openhands/extensions/automations\";\nimport { getFeaturedAutomationIds } from \"#/manifests/automation-interface\";\nimport { SETUP_REGISTRY } from \"#/manifests/manifest-sources\";\nimport type { Automation } from \"#/types/automation\";\n\nexport function getAutomationsByPopularity(\n catalog: RecommendedAutomation[],\n): RecommendedAutomation[] {\n return catalog\n .map((automation, index) => ({ automation, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.automation.popularityRank ?? 0) - (a.automation.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ automation }) => automation);\n}\n\n/**\n * Slug used to match a catalog entry against an installed automation name.\n * Catalog ids are already kebab-case; installed names are human titles.\n */\nexport function normalizeAutomationKey(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/&/g, \"and\")\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction catalogMatchKeys(entry: RecommendedAutomation): string[] {\n return [entry.id, entry.name, entry.skill]\n .filter((value): value is string => Boolean(value))\n .map(normalizeAutomationKey);\n}\n\nexport function isCatalogAutomationAdded(\n entry: RecommendedAutomation,\n installed: readonly Pick<Automation, \"name\">[],\n): boolean {\n const installedKeys = new Set(\n installed.map((automation) => normalizeAutomationKey(automation.name)),\n );\n return catalogMatchKeys(entry).some((key) => installedKeys.has(key));\n}\n\nfunction isProvenAutomation(entry: RecommendedAutomation): boolean {\n return getFeaturedAutomationIds().includes(entry.id);\n}\n\n/** Catalog cards that launch a conversation instead of a host setup form. */\nexport function isConversationLaunchAutomation(\n entry: RecommendedAutomation,\n): boolean {\n return SETUP_REGISTRY.findById(entry.id) == null;\n}\n\nexport interface RecommendedRailGroups {\n proven: RecommendedAutomation[];\n conversation: RecommendedAutomation[];\n}\n\n/**\n * Home / dashboard rail: remaining proven workflows, then other useful\n * automations that open in a new conversation. Already-created automations\n * are dropped from both groups.\n */\nexport function getRecommendedRailGroups(\n installed: readonly Pick<Automation, \"name\">[],\n): RecommendedRailGroups {\n // Every catalog entry is offerable: one that declares no integration needs\n // nothing connected, and one that names an integration this host cannot\n // resolve stays visible so the drift is actionable rather than hidden.\n const available = getAutomationsByPopularity(AUTOMATION_CATALOG).filter(\n (entry) => !isCatalogAutomationAdded(entry, installed),\n );\n\n return {\n proven: available.filter(isProvenAutomation),\n conversation: available.filter(\n (entry) =>\n !isProvenAutomation(entry) && isConversationLaunchAutomation(entry),\n ),\n };\n}\n\nexport function flattenRecommendedRailGroups(\n groups: RecommendedRailGroups,\n): RecommendedAutomation[] {\n return [...groups.proven, ...groups.conversation];\n}\n"],"mappings":"8NAQA,SAAgB,EACd,EACyB,CACzB,OAAO,EACJ,KAAK,EAAY,KAAW,CAAE,aAAY,OAAM,EAAE,EAClD,MAAM,EAAG,KAEL,EAAE,WAAW,gBAAkB,IAAM,EAAE,WAAW,gBAAkB,IAChD,EAAE,MAAQ,EAAE,KACpC,EACA,KAAK,CAAE,gBAAiB,CAAU,CACvC,CAMA,SAAgB,EAAuB,EAAuB,CAC5D,OAAO,EACJ,KAAK,EACL,YAAY,EACZ,QAAQ,KAAM,KAAK,EACnB,QAAQ,cAAe,GAAG,EAC1B,QAAQ,WAAY,EAAE,CAC3B,CAEA,SAAS,EAAiB,EAAwC,CAChE,MAAO,CAAC,EAAM,GAAI,EAAM,KAAM,EAAM,KAAK,EACtC,OAAQ,GAA2B,EAAQ,CAAM,EACjD,IAAI,CAAsB,CAC/B,CAEA,SAAgB,EACd,EACA,EACS,CACT,IAAM,EAAgB,IAAI,IACxB,EAAU,IAAK,GAAe,EAAuB,EAAW,IAAI,CAAC,CACvE,EACA,OAAO,EAAiB,CAAK,EAAE,KAAM,GAAQ,EAAc,IAAI,CAAG,CAAC,CACrE,CAEA,SAAS,EAAmB,EAAuC,CACjE,OAAO,EAAA,yBAAyB,EAAE,SAAS,EAAM,EAAE,CACrD,CAGA,SAAgB,EACd,EACS,CACT,OAAO,EAAA,eAAe,SAAS,EAAM,EAAE,GAAK,IAC9C,CAYA,SAAgB,EACd,EACuB,CAIvB,IAAM,EAAY,EAA2B,EAAA,OAAkB,EAAE,OAC9D,GAAU,CAAC,EAAyB,EAAO,CAAS,CACvD,EAEA,MAAO,CACL,OAAQ,EAAU,OAAO,CAAkB,EAC3C,aAAc,EAAU,OACrB,GACC,CAAC,EAAmB,CAAK,GAAK,EAA+B,CAAK,CACtE,CACF,CACF,CAEA,SAAgB,EACd,EACyB,CACzB,MAAO,CAAC,GAAG,EAAO,OAAQ,GAAG,EAAO,YAAY,CAClD"}
@@ -0,0 +1,22 @@
1
+ import { type RecommendedAutomation } from "@openhands/extensions/automations";
2
+ import type { Automation } from "#/types/automation";
3
+ export declare function getAutomationsByPopularity(catalog: RecommendedAutomation[]): RecommendedAutomation[];
4
+ /**
5
+ * Slug used to match a catalog entry against an installed automation name.
6
+ * Catalog ids are already kebab-case; installed names are human titles.
7
+ */
8
+ export declare function normalizeAutomationKey(value: string): string;
9
+ export declare function isCatalogAutomationAdded(entry: RecommendedAutomation, installed: readonly Pick<Automation, "name">[]): boolean;
10
+ /** Catalog cards that launch a conversation instead of a host setup form. */
11
+ export declare function isConversationLaunchAutomation(entry: RecommendedAutomation): boolean;
12
+ export interface RecommendedRailGroups {
13
+ proven: RecommendedAutomation[];
14
+ conversation: RecommendedAutomation[];
15
+ }
16
+ /**
17
+ * Home / dashboard rail: remaining proven workflows, then other useful
18
+ * automations that open in a new conversation. Already-created automations
19
+ * are dropped from both groups.
20
+ */
21
+ export declare function getRecommendedRailGroups(installed: readonly Pick<Automation, "name">[]): RecommendedRailGroups;
22
+ export declare function flattenRecommendedRailGroups(groups: RecommendedRailGroups): RecommendedAutomation[];
@@ -0,0 +1,44 @@
1
+ import e from "../node_modules/@openhands/extensions/automations/index.js";
2
+ import { SETUP_REGISTRY as t } from "../manifests/manifest-sources.js";
3
+ import { getFeaturedAutomationIds as n } from "../manifests/automation-interface.js";
4
+ //#region src/utils/recommended-automation-rail.ts
5
+ function r(e) {
6
+ return e.map((e, t) => ({
7
+ automation: e,
8
+ index: t
9
+ })).sort((e, t) => (t.automation.popularityRank ?? 0) - (e.automation.popularityRank ?? 0) || e.index - t.index).map(({ automation: e }) => e);
10
+ }
11
+ function i(e) {
12
+ return e.trim().toLowerCase().replace(/&/g, "and").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
13
+ }
14
+ function a(e) {
15
+ return [
16
+ e.id,
17
+ e.name,
18
+ e.skill
19
+ ].filter((e) => !!e).map(i);
20
+ }
21
+ function o(e, t) {
22
+ let n = new Set(t.map((e) => i(e.name)));
23
+ return a(e).some((e) => n.has(e));
24
+ }
25
+ function s(e) {
26
+ return n().includes(e.id);
27
+ }
28
+ function c(e) {
29
+ return t.findById(e.id) == null;
30
+ }
31
+ function l(t) {
32
+ let n = r(e).filter((e) => !o(e, t));
33
+ return {
34
+ proven: n.filter(s),
35
+ conversation: n.filter((e) => !s(e) && c(e))
36
+ };
37
+ }
38
+ function u(e) {
39
+ return [...e.proven, ...e.conversation];
40
+ }
41
+ //#endregion
42
+ export { u as flattenRecommendedRailGroups, r as getAutomationsByPopularity, l as getRecommendedRailGroups };
43
+
44
+ //# sourceMappingURL=recommended-automation-rail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommended-automation-rail.js","names":[],"sources":["../../src/utils/recommended-automation-rail.ts"],"sourcesContent":["import {\n AUTOMATION_CATALOG,\n type RecommendedAutomation,\n} from \"@openhands/extensions/automations\";\nimport { getFeaturedAutomationIds } from \"#/manifests/automation-interface\";\nimport { SETUP_REGISTRY } from \"#/manifests/manifest-sources\";\nimport type { Automation } from \"#/types/automation\";\n\nexport function getAutomationsByPopularity(\n catalog: RecommendedAutomation[],\n): RecommendedAutomation[] {\n return catalog\n .map((automation, index) => ({ automation, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.automation.popularityRank ?? 0) - (a.automation.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ automation }) => automation);\n}\n\n/**\n * Slug used to match a catalog entry against an installed automation name.\n * Catalog ids are already kebab-case; installed names are human titles.\n */\nexport function normalizeAutomationKey(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/&/g, \"and\")\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction catalogMatchKeys(entry: RecommendedAutomation): string[] {\n return [entry.id, entry.name, entry.skill]\n .filter((value): value is string => Boolean(value))\n .map(normalizeAutomationKey);\n}\n\nexport function isCatalogAutomationAdded(\n entry: RecommendedAutomation,\n installed: readonly Pick<Automation, \"name\">[],\n): boolean {\n const installedKeys = new Set(\n installed.map((automation) => normalizeAutomationKey(automation.name)),\n );\n return catalogMatchKeys(entry).some((key) => installedKeys.has(key));\n}\n\nfunction isProvenAutomation(entry: RecommendedAutomation): boolean {\n return getFeaturedAutomationIds().includes(entry.id);\n}\n\n/** Catalog cards that launch a conversation instead of a host setup form. */\nexport function isConversationLaunchAutomation(\n entry: RecommendedAutomation,\n): boolean {\n return SETUP_REGISTRY.findById(entry.id) == null;\n}\n\nexport interface RecommendedRailGroups {\n proven: RecommendedAutomation[];\n conversation: RecommendedAutomation[];\n}\n\n/**\n * Home / dashboard rail: remaining proven workflows, then other useful\n * automations that open in a new conversation. Already-created automations\n * are dropped from both groups.\n */\nexport function getRecommendedRailGroups(\n installed: readonly Pick<Automation, \"name\">[],\n): RecommendedRailGroups {\n // Every catalog entry is offerable: one that declares no integration needs\n // nothing connected, and one that names an integration this host cannot\n // resolve stays visible so the drift is actionable rather than hidden.\n const available = getAutomationsByPopularity(AUTOMATION_CATALOG).filter(\n (entry) => !isCatalogAutomationAdded(entry, installed),\n );\n\n return {\n proven: available.filter(isProvenAutomation),\n conversation: available.filter(\n (entry) =>\n !isProvenAutomation(entry) && isConversationLaunchAutomation(entry),\n ),\n };\n}\n\nexport function flattenRecommendedRailGroups(\n groups: RecommendedRailGroups,\n): RecommendedAutomation[] {\n return [...groups.proven, ...groups.conversation];\n}\n"],"mappings":";;;;AAQA,SAAgB,EACd,GACyB;CACzB,OAAO,EACJ,KAAK,GAAY,OAAW;EAAE;EAAY;CAAM,EAAE,EAClD,MAAM,GAAG,OAEL,EAAE,WAAW,kBAAkB,MAAM,EAAE,WAAW,kBAAkB,MAChD,EAAE,QAAQ,EAAE,KACpC,EACA,KAAK,EAAE,oBAAiB,CAAU;AACvC;AAMA,SAAgB,EAAuB,GAAuB;CAC5D,OAAO,EACJ,KAAK,EACL,YAAY,EACZ,QAAQ,MAAM,KAAK,EACnB,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AAC3B;AAEA,SAAS,EAAiB,GAAwC;CAChE,OAAO;EAAC,EAAM;EAAI,EAAM;EAAM,EAAM;CAAK,EACtC,QAAQ,MAA2B,EAAQ,CAAM,EACjD,IAAI,CAAsB;AAC/B;AAEA,SAAgB,EACd,GACA,GACS;CACT,IAAM,IAAgB,IAAI,IACxB,EAAU,KAAK,MAAe,EAAuB,EAAW,IAAI,CAAC,CACvE;CACA,OAAO,EAAiB,CAAK,EAAE,MAAM,MAAQ,EAAc,IAAI,CAAG,CAAC;AACrE;AAEA,SAAS,EAAmB,GAAuC;CACjE,OAAO,EAAyB,EAAE,SAAS,EAAM,EAAE;AACrD;AAGA,SAAgB,EACd,GACS;CACT,OAAO,EAAe,SAAS,EAAM,EAAE,KAAK;AAC9C;AAYA,SAAgB,EACd,GACuB;CAIvB,IAAM,IAAY,EAA2B,CAAkB,EAAE,QAC9D,MAAU,CAAC,EAAyB,GAAO,CAAS,CACvD;CAEA,OAAO;EACL,QAAQ,EAAU,OAAO,CAAkB;EAC3C,cAAc,EAAU,QACrB,MACC,CAAC,EAAmB,CAAK,KAAK,EAA+B,CAAK,CACtE;CACF;AACF;AAEA,SAAgB,EACd,GACyB;CACzB,OAAO,CAAC,GAAG,EAAO,QAAQ,GAAG,EAAO,YAAY;AAClD"}
@@ -0,0 +1,2 @@
1
+ require("../_virtual/_rolldown/runtime.cjs");const e=require("../i18n/declaration.cjs"),t=require("./constants.cjs"),n=require("./automation-catalog.cjs"),r=require("../manifests/automation-interface.cjs");var i=`${t.PRODUCT_URL.PRODUCTION}/settings/integrations`;function a(e){let t=r.getResponderIntegrationIds(),i=n.getRequiredIntegrationIds(e);return i.length>0&&i.every(e=>t.includes(e))}function o(t){switch(t){case`local`:return{target:t,testId:`responder-deployment-option-local`,titleKey:e.I18nKey.RESPONDER_DEPLOYMENT$LOCAL_TITLE,descriptionKey:e.I18nKey.RESPONDER_DEPLOYMENT$LOCAL_DESCRIPTION,primaryActionKey:e.I18nKey.RESPONDER_DEPLOYMENT$LOCAL_ACTION,primaryActionTestId:`responder-deployment-continue-local`,action:{kind:`launch-local`}};case`openhands-cloud`:return{target:t,testId:`responder-deployment-option-openhands-cloud`,titleKey:e.I18nKey.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_TITLE,descriptionKey:e.I18nKey.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_DESCRIPTION,primaryActionKey:e.I18nKey.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_ACTION,primaryActionTestId:`responder-deployment-open-openhands-cloud`,action:{kind:`open-url`,url:i}};case`user-cloud`:throw Error(`User Cloud responder deployment is not yet supported`);default:return t}}var s=[`local`,`openhands-cloud`];exports.VISIBLE_RESPONDER_DEPLOYMENT_TARGETS=s,exports.isResponderAutomation=a,exports.resolveResponderDeploymentOption=o;
2
+ //# sourceMappingURL=responder-deployment.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responder-deployment.cjs","names":[],"sources":["../../src/utils/responder-deployment.ts"],"sourcesContent":["import type { RecommendedAutomation } from \"@openhands/extensions/automations\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getResponderIntegrationIds } from \"#/manifests/automation-interface\";\nimport { getRequiredIntegrationIds } from \"#/utils/automation-catalog\";\nimport { PRODUCT_URL } from \"#/utils/constants\";\n\n/** OpenHands Cloud integrations page — where always-on responders are set up. */\nexport const OPENHANDS_CLOUD_INTEGRATIONS_URL = `${PRODUCT_URL.PRODUCTION}/settings/integrations`;\n\n/**\n * Single source of truth for \"does this automation get the deployment-choice\n * modal?\" — true only for automations whose required integrations are\n * exclusively responder ones (owned by the interface manifest, GitHub/Slack by\n * default), so multi-tool digests (e.g. slack + linear + notion) are not\n * treated as Slack responders. An integration the automation can start without\n * does not decide where it runs, so only the required ones are classified.\n */\nexport function isResponderAutomation(\n automation: RecommendedAutomation,\n): boolean {\n const responderIds = getResponderIntegrationIds();\n const ids = getRequiredIntegrationIds(automation);\n return ids.length > 0 && ids.every((id) => responderIds.includes(id));\n}\n\n/**\n * Where a responder runs. Only `local` and `openhands-cloud` are wired today;\n * `user-cloud` is reserved for a future remote-deployment target.\n */\nexport type ResponderDeploymentTarget =\n | \"local\"\n | \"user-cloud\"\n | \"openhands-cloud\";\n\n/** What the launcher should do when an option's primary action fires. */\nexport type ResponderDeploymentAction =\n | { kind: \"launch-local\" }\n | { kind: \"open-url\"; url: string };\n\n/** Presentational + behavioral descriptor for one deployment option. */\nexport interface ResponderDeploymentOption {\n target: ResponderDeploymentTarget;\n testId: string;\n titleKey: I18nKey;\n descriptionKey: I18nKey;\n primaryActionKey: I18nKey;\n primaryActionTestId: string;\n action: ResponderDeploymentAction;\n}\n\n/**\n * Centralized runtime-selection mechanism. Returns a descriptor (data) rather\n * than executing behavior, so the side effects stay with the launcher that owns\n * the relevant state. Adding a target later means adding a `case` here and an\n * entry to {@link VISIBLE_RESPONDER_DEPLOYMENT_TARGETS}; the `never` check makes\n * an unhandled target a compile error.\n */\nexport function resolveResponderDeploymentOption(\n target: ResponderDeploymentTarget,\n): ResponderDeploymentOption {\n switch (target) {\n case \"local\":\n return {\n target,\n testId: \"responder-deployment-option-local\",\n titleKey: I18nKey.RESPONDER_DEPLOYMENT$LOCAL_TITLE,\n descriptionKey: I18nKey.RESPONDER_DEPLOYMENT$LOCAL_DESCRIPTION,\n primaryActionKey: I18nKey.RESPONDER_DEPLOYMENT$LOCAL_ACTION,\n primaryActionTestId: \"responder-deployment-continue-local\",\n action: { kind: \"launch-local\" },\n };\n case \"openhands-cloud\":\n return {\n target,\n testId: \"responder-deployment-option-openhands-cloud\",\n titleKey: I18nKey.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_TITLE,\n descriptionKey:\n I18nKey.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_DESCRIPTION,\n primaryActionKey: I18nKey.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_ACTION,\n primaryActionTestId: \"responder-deployment-open-openhands-cloud\",\n action: { kind: \"open-url\", url: OPENHANDS_CLOUD_INTEGRATIONS_URL },\n };\n case \"user-cloud\":\n throw new Error(\"User Cloud responder deployment is not yet supported\");\n default: {\n const exhaustive: never = target;\n return exhaustive;\n }\n }\n}\n\n/** Targets the modal renders today, in display order (excludes `user-cloud`). */\nexport const VISIBLE_RESPONDER_DEPLOYMENT_TARGETS: ResponderDeploymentTarget[] =\n [\"local\", \"openhands-cloud\"];\n"],"mappings":"8MAOA,IAAa,EAAmC,GAAG,EAAA,YAAY,WAAW,wBAU1E,SAAgB,EACd,EACS,CACT,IAAM,EAAe,EAAA,2BAA2B,EAC1C,EAAM,EAAA,0BAA0B,CAAU,EAChD,OAAO,EAAI,OAAS,GAAK,EAAI,MAAO,GAAO,EAAa,SAAS,CAAE,CAAC,CACtE,CAkCA,SAAgB,EACd,EAC2B,CAC3B,OAAQ,EAAR,CACE,IAAK,QACH,MAAO,CACL,SACA,OAAQ,oCACR,SAAU,EAAA,QAAQ,iCAClB,eAAgB,EAAA,QAAQ,uCACxB,iBAAkB,EAAA,QAAQ,kCAC1B,oBAAqB,sCACrB,OAAQ,CAAE,KAAM,cAAe,CACjC,EACF,IAAK,kBACH,MAAO,CACL,SACA,OAAQ,8CACR,SAAU,EAAA,QAAQ,2CAClB,eACE,EAAA,QAAQ,iDACV,iBAAkB,EAAA,QAAQ,4CAC1B,oBAAqB,4CACrB,OAAQ,CAAE,KAAM,WAAY,IAAK,CAAiC,CACpE,EACF,IAAK,aACH,MAAU,MAAM,sDAAsD,EACxE,QAEE,OAAO,CAEX,CACF,CAGA,IAAa,EACX,CAAC,QAAS,iBAAiB"}
@@ -0,0 +1,42 @@
1
+ import { I18nKey as e } from "../i18n/declaration.js";
2
+ import { PRODUCT_URL as t } from "./constants.js";
3
+ import { getRequiredIntegrationIds as n } from "./automation-catalog.js";
4
+ import { getResponderIntegrationIds as r } from "../manifests/automation-interface.js";
5
+ //#region src/utils/responder-deployment.ts
6
+ var i = `${t.PRODUCTION}/settings/integrations`;
7
+ function a(e) {
8
+ let t = r(), i = n(e);
9
+ return i.length > 0 && i.every((e) => t.includes(e));
10
+ }
11
+ function o(t) {
12
+ switch (t) {
13
+ case "local": return {
14
+ target: t,
15
+ testId: "responder-deployment-option-local",
16
+ titleKey: e.RESPONDER_DEPLOYMENT$LOCAL_TITLE,
17
+ descriptionKey: e.RESPONDER_DEPLOYMENT$LOCAL_DESCRIPTION,
18
+ primaryActionKey: e.RESPONDER_DEPLOYMENT$LOCAL_ACTION,
19
+ primaryActionTestId: "responder-deployment-continue-local",
20
+ action: { kind: "launch-local" }
21
+ };
22
+ case "openhands-cloud": return {
23
+ target: t,
24
+ testId: "responder-deployment-option-openhands-cloud",
25
+ titleKey: e.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_TITLE,
26
+ descriptionKey: e.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_DESCRIPTION,
27
+ primaryActionKey: e.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_ACTION,
28
+ primaryActionTestId: "responder-deployment-open-openhands-cloud",
29
+ action: {
30
+ kind: "open-url",
31
+ url: i
32
+ }
33
+ };
34
+ case "user-cloud": throw Error("User Cloud responder deployment is not yet supported");
35
+ default: return t;
36
+ }
37
+ }
38
+ var s = ["local", "openhands-cloud"];
39
+ //#endregion
40
+ export { s as VISIBLE_RESPONDER_DEPLOYMENT_TARGETS, a as isResponderAutomation, o as resolveResponderDeploymentOption };
41
+
42
+ //# sourceMappingURL=responder-deployment.js.map