@openhands/agent-canvas 1.0.0-alpha.7 → 1.0.0-alpha.9

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 (745) hide show
  1. package/README.md +25 -23
  2. package/bin/agent-canvas.mjs +27 -1
  3. package/build/assets/{QueryClientProvider-DITRCGAK.js → QueryClientProvider-B7kl84Kj.js} +1 -1
  4. package/build/assets/{Trans-D43bd3yR.js → Trans-1j65oy9O.js} +1 -1
  5. package/build/assets/{acp-providers-SCPK1BIU.js → acp-providers-DauuOsW9.js} +1 -1
  6. package/build/assets/{acp-route-guard-IWlFmS6x.js → acp-route-guard-CQTmeJwM.js} +1 -1
  7. package/build/assets/{active-backend-context-CkP3ZEJs.js → active-backend-context-TVbjnvmP.js} +1 -1
  8. package/build/assets/add-backend-modal-FsnpTTgO.js +1 -0
  9. package/build/assets/{agent-server-client-options-8OJSXbm8.js → agent-server-client-options-DT2GP6VJ.js} +1 -1
  10. package/build/assets/{agent-server-compatibility-DvKtnXHw.js → agent-server-compatibility-2aOx5iWd.js} +1 -1
  11. package/build/assets/agent-server-conversation-service.api-BZmUqtiO.js +5 -0
  12. package/build/assets/{agent-settings-DdisD2Xx.js → agent-settings-B247S9G3.js} +2 -2
  13. package/build/assets/{alert-banner-CvTYN73l.js → alert-banner-BWoqueRw.js} +1 -1
  14. package/build/assets/{analytics-consent-form-modal-BKgT9i2w.js → analytics-consent-form-modal-C7sXfxRh.js} +1 -1
  15. package/build/assets/{app-settings-DcYXtxGP.js → app-settings-BVeSaty9.js} +1 -1
  16. package/build/assets/{automation-detail-D7GEU0vR.js → automation-detail-R-99FUce.js} +1 -1
  17. package/build/assets/{automations-list-CkVNsgzm.js → automations-list-Dfu2c-_D.js} +1 -1
  18. package/build/assets/backend-form-modal-DxYjqqAK.js +1 -0
  19. package/build/assets/{backend-synced-settings-badge-BFy2HylT.js → backend-synced-settings-badge-nAfiUWvM.js} +1 -1
  20. package/build/assets/{base-modal-B4HvlFHE.js → base-modal-CQRvRHu1.js} +1 -1
  21. package/build/assets/{brand-button-8fVVei4i.js → brand-button-C2nEKopC.js} +1 -1
  22. package/build/assets/browser-HrYc5Gce.js +5 -0
  23. package/build/assets/{browser-tab-DTM6RyoV.js → browser-tab-B_BuTvrO.js} +1 -1
  24. package/build/assets/{checkmark-BcvXE9bf.js → checkmark-BJJrZUF8.js} +1 -1
  25. package/build/assets/{chevron-left-small-BqSkXTeq.js → chevron-left-small-CSh-sE9L.js} +1 -1
  26. package/build/assets/{circle-plus-check-toggle-DRvuu-RD.js → circle-plus-check-toggle-qs8Va1cC.js} +1 -1
  27. package/build/assets/{clock-DfoVUZVq.js → clock-ZR4Kn-_Y.js} +1 -1
  28. package/build/assets/{close-SnIy2eLD.js → close-BdmyeRqS.js} +1 -1
  29. package/build/assets/{combobox-caret-BMsz5mQX.js → combobox-caret-B53O9Hsq.js} +1 -1
  30. package/build/assets/{condenser-settings-DduLQcpV.js → condenser-settings-A35V3yng.js} +1 -1
  31. package/build/assets/{confirmation-modal-B-DOYMUH.js → confirmation-modal-C9-La0h3.js} +1 -1
  32. package/build/assets/{context-menu-list-item-DzjPB8aC.js → context-menu-list-item-Buu9nc0q.js} +1 -1
  33. package/build/assets/conversation--ldUK72N.js +19 -0
  34. package/build/assets/conversation-eNrhH94O.js +1 -0
  35. package/build/assets/conversation-panel-B49Jpqpb.js +1 -0
  36. package/build/assets/{conversation-service.api-YTGTw0pz.js → conversation-service.api--f8WglOC.js} +1 -1
  37. package/build/assets/{conversation-tab-empty-state-BtFDbyTe.js → conversation-tab-empty-state-D8dNvo-V.js} +1 -1
  38. package/build/assets/conversation-websocket-context-BW68-J8o.js +3 -0
  39. package/build/assets/{copy-BxgbrjDT.js → copy-C7Ti2d8C.js} +1 -1
  40. package/build/assets/{custom-toast-handlers-BYxhSr3t.js → custom-toast-handlers-BOc3qeQ7.js} +1 -1
  41. package/build/assets/declaration-D378OjpZ.js +1 -0
  42. package/build/assets/{device-verify-CTbXX9CQ.js → device-verify-CMusn8nX.js} +1 -1
  43. package/build/assets/edit-automation-modal-Dnjxbjn7.js +1 -0
  44. package/build/assets/{ellipsis-button-BoU2-xlG.js → ellipsis-button-ugUATsNo.js} +1 -1
  45. package/build/assets/{entry.client-DU7-q4ZU.js → entry.client-CqqXOSvd.js} +2 -2
  46. package/build/assets/{enum-filter-dropdown-BJt-NplD.js → enum-filter-dropdown-1vpOGySB.js} +1 -1
  47. package/build/assets/{environment-switch-overlay-DQ1n6Iu6.js → environment-switch-overlay-CTCTQikP.js} +1 -1
  48. package/build/assets/{extensions-hub-BW1FAKFJ.js → extensions-hub-BSUseHVF.js} +1 -1
  49. package/build/assets/{extensions-navigation-CbPMhSML.js → extensions-navigation-CT1kc1u_.js} +1 -1
  50. package/build/assets/files-tab-CQHdWpQt.js +1 -0
  51. package/build/assets/{folder-CerIk8uG.js → folder-0WSMImNX.js} +1 -1
  52. package/build/assets/git-control-bar-branch-button-C8u5rzjc.js +27 -0
  53. package/build/assets/{git-provider-icon-D8RE4unY.js → git-provider-icon-D-a-rcLm.js} +1 -1
  54. package/build/assets/{home-DR11ejqB.js → home-DD0GroCu.js} +1 -1
  55. package/build/assets/{i18n-DkYgs32x.js → i18n-DjAGhTis.js} +1 -1
  56. package/build/assets/install-server-modal-z5VaHeXd.js +1 -0
  57. package/build/assets/{launch-DKCU9uJH.js → launch-B2mbfOSm.js} +1 -1
  58. package/build/assets/{lesson-plan-CmkRbe6Z.js → lesson-plan-DRYG5SLI.js} +1 -1
  59. package/build/assets/{link-external-CvxB0BmI.js → link-external-C9d6Fo3x.js} +1 -1
  60. package/build/assets/{llm-client-BpIfxETv.js → llm-client-ChQzg4wX.js} +1 -1
  61. package/build/assets/llm-settings-BEyqixPI.js +1 -0
  62. package/build/assets/{llm-settings-BOJC4vD-.js → llm-settings-BdiaGFbg.js} +1 -1
  63. package/build/assets/{loading-spinner-91b5FiMQ.js → loading-spinner-C04FGh14.js} +1 -1
  64. package/build/assets/{manage-backends-modal-DqpzcxdI.js → manage-backends-modal-s22zCdEW.js} +1 -1
  65. package/build/assets/{manage-workspaces-modal-eG6XgAvw.js → manage-workspaces-modal-C5EuW8m1.js} +1 -1
  66. package/build/assets/manifest-9d1c34fb.js +1 -0
  67. package/build/assets/{markdown-renderer-wZnLDbA1.js → markdown-renderer-CEX4Becj.js} +1 -1
  68. package/build/assets/mcp-C06YssEI.js +9 -0
  69. package/build/assets/messages-6aOyUu3r.js +36 -0
  70. package/build/assets/{modal-backdrop-B04pVYAD.js → modal-backdrop-DTYGVmOR.js} +1 -1
  71. package/build/assets/{modal-body-CgUoFQA1.js → modal-body-YElmM1dV.js} +1 -1
  72. package/build/assets/{modal-close-button-SM_WXzDY.js → modal-close-button-C_GpQt9F.js} +1 -1
  73. package/build/assets/{model-selector-7id-Uirf.js → model-selector-DeMmw-Xa.js} +1 -1
  74. package/build/assets/{navigation-context-BFjstyH6.js → navigation-context-DeIPtGPp.js} +1 -1
  75. package/build/assets/{navigation-link-DFQ7YcWq.js → navigation-link-C9JD4PYD.js} +1 -1
  76. package/build/assets/{openhands-logo-DkDp75rC.js → openhands-logo-CI5Fhn1W.js} +1 -1
  77. package/build/assets/{option-service.api-DN0ZcGjw.js → option-service.api-DsI1UW7N.js} +1 -1
  78. package/build/assets/{organization-service.api-Ct2dZF8M.js → organization-service.api-COwMPFg5.js} +1 -1
  79. package/build/assets/{path-utils-D1ZtqFC7.js → path-utils-BVbe598W.js} +1 -1
  80. package/build/assets/{plan-components-gOm-daR3.js → plan-components-DEjMuDDG.js} +1 -1
  81. package/build/assets/{planner-tab-yubfN-6U.js → planner-tab-bN6r1G-1.js} +1 -1
  82. package/build/assets/{profiles-client-D4twHRVf.js → profiles-client-BGkKEV9j.js} +1 -1
  83. package/build/assets/{providers-C2T07PM3.js → providers-DXvCAN_u.js} +1 -1
  84. package/build/assets/{proxy-BMZyC45G.js → proxy-CurRmrqf.js} +1 -1
  85. package/build/assets/{query-client-config-CiK0GJJO.js → query-client-config-Ba7qAAoO.js} +1 -1
  86. package/build/assets/recommended-automations-launcher-mJhK6Atl.js +52 -0
  87. package/build/assets/root-3t9rxEpE.js +2 -0
  88. package/build/assets/root-DHeCXo9N.css +1 -0
  89. package/build/assets/{root-layout-B4QioBS6.js → root-layout-BjVwHmta.js} +2 -2
  90. package/build/assets/{sdk-section-page-03k88tIR.js → sdk-section-page-CJW0G04-.js} +1 -1
  91. package/build/assets/{sdk-settings-schema-BY8dOy3a.js → sdk-settings-schema-QBYH-ONX.js} +1 -1
  92. package/build/assets/{search-BCAF9EDS.js → search-Cq_cFrDt.js} +1 -1
  93. package/build/assets/{secrets-service-Z3qtRb_G.js → secrets-service-Bwd5DeUs.js} +1 -1
  94. package/build/assets/{secrets-settings-BnlByuMZ.js → secrets-settings-MLXqOtX2.js} +1 -1
  95. package/build/assets/{server-client-CG1zHqph.js → server-client-C3mC8Hl3.js} +1 -1
  96. package/build/assets/{settings-DyzGLF_d.js → settings-D7E2U5tK.js} +1 -1
  97. package/build/assets/{settings-client-CkXDJwIY.js → settings-client-CwjfwoiB.js} +1 -1
  98. package/build/assets/{settings-dropdown-input-CAQWQgx-.js → settings-dropdown-input-VwAXNrOb.js} +1 -1
  99. package/build/assets/{settings-gear-D4ZkEDGb.js → settings-gear-BJwWR1ej.js} +1 -1
  100. package/build/assets/{settings-index-KtTw49xL.js → settings-index-J-3BNR0W.js} +1 -1
  101. package/build/assets/{settings-input-BWCZt9g2.js → settings-input-DBywAnA7.js} +1 -1
  102. package/build/assets/{settings-list-classes-xMleGkTC.js → settings-list-classes-BOS092DR.js} +1 -1
  103. package/build/assets/{settings-modal-Cv2YWSUY.js → settings-modal-B8vgWDTe.js} +1 -1
  104. package/build/assets/{settings-section-header-context-1wfkgjZZ.js → settings-section-header-context-32x6WTyL.js} +1 -1
  105. package/build/assets/settings-service.api-FvJGK45W.js +1 -0
  106. package/build/assets/{settings-switch-CGap2LtG.js → settings-switch-DTKmHC8F.js} +1 -1
  107. package/build/assets/{settings-utils-BBozxqqi.js → settings-utils-BsvSU3OM.js} +1 -1
  108. package/build/assets/{shared-conversation-DQlzwdpo.js → shared-conversation-EZV0FRIf.js} +1 -1
  109. package/build/assets/{sidebar-mobile-menu-toggle-DXplko7u.js → sidebar-mobile-menu-toggle-BnbzzpQl.js} +1 -1
  110. package/build/assets/{sidebar-nav-link-B4h8naZ7.js → sidebar-nav-link-CnWoZcwc.js} +1 -1
  111. package/build/assets/{skill-card-pill-row-D0oTWx-a.js → skill-card-pill-row-tZ599jli.js} +1 -1
  112. package/build/assets/{skills-BN8atjgW.js → skills-ZyAO5dyK.js} +1 -1
  113. package/build/assets/{skills-plugins-BTnp7QcQ.js → skills-plugins-BSRz041I.js} +1 -1
  114. package/build/assets/{skills-settings-CbOQvzkR.js → skills-settings-CG2hu34D.js} +2 -2
  115. package/build/assets/{status-DDL-ipIP.js → status-CsatcFbK.js} +1 -1
  116. package/build/assets/{styled-tooltip-Awq4HMw3.js → styled-tooltip-CS3mB_1X.js} +1 -1
  117. package/build/assets/{switch-skeleton-Bv21RGWd.js → switch-skeleton-C-CfhYYV.js} +1 -1
  118. package/build/assets/{task-list-tab-B45ktzHM.js → task-list-tab-465DDju0.js} +1 -1
  119. package/build/assets/{terminal-D5pzR9Ru.js → terminal-CcgBEVnC.js} +1 -1
  120. package/build/assets/{terminal-DGuR4559.js → terminal-LNa-iU5c.js} +1 -1
  121. package/build/assets/{toggle-switch-gj6T-wsU.js → toggle-switch-k-IZCDbt.js} +1 -1
  122. package/build/assets/{typography-BbaUAC4V.js → typography-vVUMoNUg.js} +1 -1
  123. package/build/assets/{u-check-circle-DHGiAi-w.js → u-check-circle-DplbarS5.js} +1 -1
  124. package/build/assets/{u-check-circle-half-BPcWtWwv.js → u-check-circle-half-yDuiSZHC.js} +1 -1
  125. package/build/assets/{u-circuit-B_nK9hOu.js → u-circuit-C9tYkpeK.js} +1 -1
  126. package/build/assets/{u-edit-BPFJBd34.js → u-edit-KAUlufD8.js} +1 -1
  127. package/build/assets/{use-active-conversation-Bu5J9iLy.js → use-active-conversation-DS5j9R4q.js} +1 -1
  128. package/build/assets/{use-agent-settings-schema-BbtOsR7P.js → use-agent-settings-schema-Bvp5UzV8.js} +1 -1
  129. package/build/assets/{use-agent-state-DN9Nc5pP.js → use-agent-state-D2C9SeGw.js} +1 -1
  130. package/build/assets/{use-cloud-current-user-id-B_rMUiu8.js → use-cloud-current-user-id-DWVar4st.js} +1 -1
  131. package/build/assets/{use-config-Bcz2JL2t.js → use-config-BSu_53GL.js} +1 -1
  132. package/build/assets/{use-conversation-id-BOaaZahn.js → use-conversation-id-DajhCn2A.js} +1 -1
  133. package/build/assets/{use-create-conversation-BWFA_FId.js → use-create-conversation-BEZg__Vv.js} +1 -1
  134. package/build/assets/{use-event-store-CQZCcVz-.js → use-event-store-BT_gV3ut.js} +1 -1
  135. package/build/assets/{use-handle-plan-click-CgrCGmT1.js → use-handle-plan-click-uOpew2LO.js} +1 -1
  136. package/build/assets/use-is-authed-hXC8vxgT.js +1 -0
  137. package/build/assets/{use-is-creating-conversation-DhoM7UAB.js → use-is-creating-conversation-DhDeeWfA.js} +1 -1
  138. package/build/assets/{use-launch-skill-in-chat-DOyQsXFO.js → use-launch-skill-in-chat-DVGPFrbI.js} +1 -1
  139. package/build/assets/{use-llm-profiles-CAIzHJDX.js → use-llm-profiles-O4a9V6RC.js} +1 -1
  140. package/build/assets/use-runtime-is-ready-pGSbPddC.js +1 -0
  141. package/build/assets/{use-save-settings-5m3w89Ph.js → use-save-settings-CEEKSTWG.js} +1 -1
  142. package/build/assets/{use-settings-DzG0C3vO.js → use-settings-DQ7Oo1Hj.js} +1 -1
  143. package/build/assets/{use-settings-nav-items-BIsKeX52.js → use-settings-nav-items-YmrXrjn9.js} +2 -2
  144. package/build/assets/use-skills-BIvlWblA.js +1 -0
  145. package/build/assets/{use-task-list-Bs90uF2N.js → use-task-list-DDeNHprj.js} +1 -1
  146. package/build/assets/{use-unified-vscode-url-C5iI-Z5A.js → use-unified-vscode-url-wAMzv8Sn.js} +1 -1
  147. package/build/assets/use-user-conversation-B_zDoSeh.js +1 -0
  148. package/build/assets/{useMutation-CRJwk4cR.js → useMutation-B4OUESdw.js} +1 -1
  149. package/build/assets/{useTranslation-01pF7z10.js → useTranslation-CpIcQBq6.js} +1 -1
  150. package/build/assets/{utils-Czcl6buL.js → utils-D-HX7JCe.js} +1 -1
  151. package/build/assets/{vendor~conversation-panel~conversation-CbjvWBSu.js → vendor~conversation-panel~conversation-BlCIz9XQ.js} +1 -1
  152. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CofhIDpd.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Ds9quNZ9.js} +1 -1
  153. package/build/assets/vendor~home~mcp~automations-list-C5PoHCy6.js +1 -0
  154. package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-BQPOygpY.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-CGlZoBKa.js} +1 -1
  155. package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-CyYIBiBk.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-DE11mPxp.js} +1 -1
  156. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-CuGq_cxH.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-8b8V5bfO.js} +1 -1
  157. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-CFpDeb9o.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-Dy7L6fMG.js} +1 -1
  158. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-C1p8-pMr.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-D40EXhZx.js} +1 -1
  159. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-CHrEOFl6.js +48 -0
  160. package/build/assets/{vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~kyz9p27j-DlKA6SoO.js → vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~kyz9p27j-CyUbhpbm.js} +1 -1
  161. package/build/assets/{verification-settings-DbziMp4K.js → verification-settings-BtlTiHP8.js} +1 -1
  162. package/build/assets/{vscode-tab-BVhQR2rt.js → vscode-tab-B0vdh9gU.js} +1 -1
  163. package/build/assets/{waiting-for-runtime-message-JotSOBdC.js → waiting-for-runtime-message-DWPl_Yby.js} +1 -1
  164. package/build/assets/{x-mark-CZ57VvRX.js → x-mark-CWI0f9yI.js} +1 -1
  165. package/build/favicon.svg +1 -0
  166. package/build/index.html +4 -4
  167. package/build/locales/ar/openhands.json +8 -0
  168. package/build/locales/ca/openhands.json +8 -0
  169. package/build/locales/de/openhands.json +8 -0
  170. package/build/locales/en/openhands.json +8 -0
  171. package/build/locales/es/openhands.json +8 -0
  172. package/build/locales/fr/openhands.json +8 -0
  173. package/build/locales/it/openhands.json +8 -0
  174. package/build/locales/ja/openhands.json +8 -0
  175. package/build/locales/ko-KR/openhands.json +8 -0
  176. package/build/locales/no/openhands.json +8 -0
  177. package/build/locales/pt/openhands.json +8 -0
  178. package/build/locales/tr/openhands.json +8 -0
  179. package/build/locales/uk/openhands.json +8 -0
  180. package/build/locales/zh-CN/openhands.json +8 -0
  181. package/build/locales/zh-TW/openhands.json +8 -0
  182. package/config/defaults.json +1 -1
  183. package/dist/api/agent-server-adapter.cjs +1 -1
  184. package/dist/api/agent-server-adapter.cjs.map +1 -1
  185. package/dist/api/agent-server-adapter.js +1 -0
  186. package/dist/api/agent-server-adapter.js.map +1 -1
  187. package/dist/api/agent-server-config.cjs +1 -1
  188. package/dist/api/agent-server-config.cjs.map +1 -1
  189. package/dist/api/agent-server-config.d.ts +1 -1
  190. package/dist/api/agent-server-config.js +1 -1
  191. package/dist/api/agent-server-config.js.map +1 -1
  192. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  193. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  194. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +12 -0
  195. package/dist/api/conversation-service/agent-server-conversation-service.api.js +4 -0
  196. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  197. package/dist/api/mcp-service/mcp-service.api.cjs +2 -0
  198. package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -0
  199. package/dist/api/mcp-service/mcp-service.api.d.ts +6 -0
  200. package/dist/api/mcp-service/mcp-service.api.js +36 -0
  201. package/dist/api/mcp-service/mcp-service.api.js.map +1 -0
  202. package/dist/api/settings-service/settings-service.api.cjs +1 -1
  203. package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
  204. package/dist/api/settings-service/settings-service.api.d.ts +1 -0
  205. package/dist/api/settings-service/settings-service.api.js +59 -41
  206. package/dist/api/settings-service/settings-service.api.js.map +1 -1
  207. package/dist/api/skills-service.cjs +1 -1
  208. package/dist/api/skills-service.cjs.map +1 -1
  209. package/dist/api/skills-service.d.ts +1 -1
  210. package/dist/api/skills-service.js +2 -2
  211. package/dist/api/skills-service.js.map +1 -1
  212. package/dist/components/features/automations/detail/activity-log-item.d.ts +1 -1
  213. package/dist/components/features/automations/recommended-automations-launcher.d.ts +1 -1
  214. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  215. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  216. package/dist/components/features/backends/backend-form-modal.js +149 -142
  217. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  218. package/dist/components/features/chat/change-agent-button.cjs +1 -1
  219. package/dist/components/features/chat/change-agent-button.cjs.map +1 -1
  220. package/dist/components/features/chat/change-agent-button.js +65 -59
  221. package/dist/components/features/chat/change-agent-button.js.map +1 -1
  222. package/dist/components/features/chat/chat-interface.cjs +2 -2
  223. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  224. package/dist/components/features/chat/chat-interface.js +15 -14
  225. package/dist/components/features/chat/chat-interface.js.map +1 -1
  226. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  227. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  228. package/dist/components/features/chat/components/chat-input-actions.js +127 -149
  229. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  230. package/dist/components/features/chat/components/chat-input-model.cjs +1 -1
  231. package/dist/components/features/chat/components/chat-input-model.cjs.map +1 -1
  232. package/dist/components/features/chat/components/chat-input-model.d.ts +10 -0
  233. package/dist/components/features/chat/components/chat-input-model.js +95 -60
  234. package/dist/components/features/chat/components/chat-input-model.js.map +1 -1
  235. package/dist/components/features/chat/git-control-bar.cjs +1 -1
  236. package/dist/components/features/chat/git-control-bar.cjs.map +1 -1
  237. package/dist/components/features/chat/git-control-bar.js +60 -59
  238. package/dist/components/features/chat/git-control-bar.js.map +1 -1
  239. package/dist/components/features/conversation/conversation-name-with-status.cjs +1 -1
  240. package/dist/components/features/conversation/conversation-name-with-status.cjs.map +1 -1
  241. package/dist/components/features/conversation/conversation-name-with-status.js +2 -2
  242. package/dist/components/features/conversation/conversation-name-with-status.js.map +1 -1
  243. package/dist/components/features/conversation/conversation-name.cjs +1 -1
  244. package/dist/components/features/conversation/conversation-name.cjs.map +1 -1
  245. package/dist/components/features/conversation/conversation-name.js +3 -3
  246. package/dist/components/features/conversation/conversation-name.js.map +1 -1
  247. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
  248. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
  249. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +1 -1
  250. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
  251. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
  252. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
  253. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +16 -16
  254. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
  255. package/dist/components/features/conversation-panel/skills-modal.cjs +1 -1
  256. package/dist/components/features/conversation-panel/skills-modal.cjs.map +1 -1
  257. package/dist/components/features/conversation-panel/skills-modal.js +1 -1
  258. package/dist/components/features/conversation-panel/skills-modal.js.map +1 -1
  259. package/dist/components/features/mcp-logo-badge.cjs +1 -1
  260. package/dist/components/features/mcp-logo-badge.cjs.map +1 -1
  261. package/dist/components/features/mcp-logo-badge.d.ts +2 -2
  262. package/dist/components/features/mcp-logo-badge.js +1 -1
  263. package/dist/components/features/mcp-logo-badge.js.map +1 -1
  264. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  265. package/dist/components/features/mcp-page/custom-server-editor.cjs.map +1 -1
  266. package/dist/components/features/mcp-page/custom-server-editor.js +64 -41
  267. package/dist/components/features/mcp-page/custom-server-editor.js.map +1 -1
  268. package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
  269. package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
  270. package/dist/components/features/mcp-page/install-server-modal.d.ts +1 -1
  271. package/dist/components/features/mcp-page/install-server-modal.js +126 -102
  272. package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
  273. package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
  274. package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
  275. package/dist/components/features/mcp-page/installed-server-card.js +1 -1
  276. package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
  277. package/dist/components/features/mcp-page/marketplace-card.cjs +1 -1
  278. package/dist/components/features/mcp-page/marketplace-card.cjs.map +1 -1
  279. package/dist/components/features/mcp-page/marketplace-card.d.ts +1 -1
  280. package/dist/components/features/mcp-page/marketplace-card.js +27 -25
  281. package/dist/components/features/mcp-page/marketplace-card.js.map +1 -1
  282. package/dist/components/features/mcp-page/marketplace-section.cjs +1 -1
  283. package/dist/components/features/mcp-page/marketplace-section.cjs.map +1 -1
  284. package/dist/components/features/mcp-page/marketplace-section.d.ts +1 -1
  285. package/dist/components/features/mcp-page/marketplace-section.js +1 -1
  286. package/dist/components/features/mcp-page/marketplace-section.js.map +1 -1
  287. package/dist/components/features/mcp-page/mcp-logo-stack-badge.d.ts +2 -2
  288. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +7 -7
  289. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
  290. package/dist/components/features/settings/mcp-settings/mcp-server-form.d.ts +8 -12
  291. package/dist/components/features/settings/mcp-settings/mcp-server-form.js +114 -87
  292. package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
  293. package/dist/context/scroll-context.cjs +1 -1
  294. package/dist/context/scroll-context.cjs.map +1 -1
  295. package/dist/context/scroll-context.d.ts +1 -0
  296. package/dist/context/scroll-context.js +4 -1
  297. package/dist/context/scroll-context.js.map +1 -1
  298. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  299. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  300. package/dist/contexts/conversation-websocket-context.js +97 -89
  301. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  302. package/dist/favicon.svg +1 -0
  303. package/dist/hooks/chat/use-slash-command.cjs +1 -1
  304. package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
  305. package/dist/hooks/chat/use-slash-command.js +1 -1
  306. package/dist/hooks/chat/use-slash-command.js.map +1 -1
  307. package/dist/hooks/mutation/use-switch-acp-model.cjs +2 -0
  308. package/dist/hooks/mutation/use-switch-acp-model.cjs.map +1 -0
  309. package/dist/hooks/mutation/use-switch-acp-model.d.ts +23 -0
  310. package/dist/hooks/mutation/use-switch-acp-model.js +26 -0
  311. package/dist/hooks/mutation/use-switch-acp-model.js.map +1 -0
  312. package/dist/hooks/mutation/use-test-mcp-server.cjs +2 -0
  313. package/dist/hooks/mutation/use-test-mcp-server.cjs.map +1 -0
  314. package/dist/hooks/mutation/use-test-mcp-server.d.ts +2 -0
  315. package/dist/hooks/mutation/use-test-mcp-server.js +10 -0
  316. package/dist/hooks/mutation/use-test-mcp-server.js.map +1 -0
  317. package/dist/hooks/query/use-automation-detail.d.ts +3 -2
  318. package/dist/hooks/query/use-conversation-skills.cjs +2 -0
  319. package/dist/hooks/query/use-conversation-skills.cjs.map +1 -0
  320. package/dist/hooks/query/use-conversation-skills.d.ts +7 -0
  321. package/dist/hooks/query/use-conversation-skills.js +8 -0
  322. package/dist/hooks/query/use-conversation-skills.js.map +1 -0
  323. package/dist/hooks/query/use-skills.cjs +1 -1
  324. package/dist/hooks/query/use-skills.cjs.map +1 -1
  325. package/dist/hooks/query/use-skills.d.ts +6 -1
  326. package/dist/hooks/query/use-skills.js +3 -3
  327. package/dist/hooks/query/use-skills.js.map +1 -1
  328. package/dist/hooks/use-acp-model-context.cjs.map +1 -1
  329. package/dist/hooks/use-acp-model-context.d.ts +3 -4
  330. package/dist/hooks/use-acp-model-context.js.map +1 -1
  331. package/dist/hooks/use-chat-input-model-state.cjs +2 -0
  332. package/dist/hooks/use-chat-input-model-state.cjs.map +1 -0
  333. package/dist/hooks/use-chat-input-model-state.d.ts +12 -0
  334. package/dist/hooks/use-chat-input-model-state.js +29 -0
  335. package/dist/hooks/use-chat-input-model-state.js.map +1 -0
  336. package/dist/i18n/declaration.cjs +1 -1
  337. package/dist/i18n/declaration.cjs.map +1 -1
  338. package/dist/i18n/declaration.d.ts +8 -0
  339. package/dist/i18n/declaration.js +1 -1
  340. package/dist/i18n/declaration.js.map +1 -1
  341. package/dist/i18n/translation.cjs +2 -2
  342. package/dist/i18n/translation.cjs.map +1 -1
  343. package/dist/i18n/translation.js +136 -0
  344. package/dist/i18n/translation.js.map +1 -1
  345. package/dist/locales/ar/openhands.json +8 -0
  346. package/dist/locales/ca/openhands.json +8 -0
  347. package/dist/locales/de/openhands.json +8 -0
  348. package/dist/locales/en/openhands.json +8 -0
  349. package/dist/locales/es/openhands.json +8 -0
  350. package/dist/locales/fr/openhands.json +8 -0
  351. package/dist/locales/it/openhands.json +8 -0
  352. package/dist/locales/ja/openhands.json +8 -0
  353. package/dist/locales/ko-KR/openhands.json +8 -0
  354. package/dist/locales/no/openhands.json +8 -0
  355. package/dist/locales/pt/openhands.json +8 -0
  356. package/dist/locales/tr/openhands.json +8 -0
  357. package/dist/locales/uk/openhands.json +8 -0
  358. package/dist/locales/zh-CN/openhands.json +8 -0
  359. package/dist/locales/zh-TW/openhands.json +8 -0
  360. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.cjs +2 -0
  361. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.cjs.map +1 -0
  362. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.js +37 -0
  363. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.js.map +1 -0
  364. package/dist/node_modules/@openhands/extensions/integrations/catalog/apify.cjs +2 -0
  365. package/dist/node_modules/@openhands/extensions/integrations/catalog/apify.cjs.map +1 -0
  366. package/dist/node_modules/@openhands/extensions/integrations/catalog/apify.js +36 -0
  367. package/dist/node_modules/@openhands/extensions/integrations/catalog/apify.js.map +1 -0
  368. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/atlassian.cjs +1 -1
  369. package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.cjs.map +1 -0
  370. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/atlassian.js +15 -5
  371. package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.js.map +1 -0
  372. package/dist/node_modules/@openhands/extensions/integrations/catalog/brave-search.cjs +2 -0
  373. package/dist/node_modules/@openhands/extensions/integrations/catalog/brave-search.cjs.map +1 -0
  374. package/dist/node_modules/@openhands/extensions/integrations/catalog/brave-search.js +36 -0
  375. package/dist/node_modules/@openhands/extensions/integrations/catalog/brave-search.js.map +1 -0
  376. package/dist/node_modules/@openhands/extensions/integrations/catalog/browser-mcp.cjs +2 -0
  377. package/dist/node_modules/@openhands/extensions/integrations/catalog/browser-mcp.cjs.map +1 -0
  378. package/dist/node_modules/@openhands/extensions/integrations/catalog/browser-mcp.js +31 -0
  379. package/dist/node_modules/@openhands/extensions/integrations/catalog/browser-mcp.js.map +1 -0
  380. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickhouse.cjs +2 -0
  381. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickhouse.cjs.map +1 -0
  382. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickhouse.js +52 -0
  383. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickhouse.js.map +1 -0
  384. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-bindings.cjs +1 -1
  385. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-bindings.cjs.map +1 -0
  386. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-bindings.js +15 -5
  387. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-bindings.js.map +1 -0
  388. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-browser-rendering.cjs +2 -0
  389. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-browser-rendering.cjs.map +1 -0
  390. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-browser-rendering.js +15 -5
  391. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-browser-rendering.js.map +1 -0
  392. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-builds.cjs +1 -1
  393. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-builds.cjs.map +1 -0
  394. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-builds.js +15 -5
  395. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-builds.js.map +1 -0
  396. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-docs.cjs +1 -1
  397. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-docs.cjs.map +1 -0
  398. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-docs.js +15 -5
  399. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-docs.js.map +1 -0
  400. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-observability.cjs +2 -0
  401. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-observability.cjs.map +1 -0
  402. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-observability.js +15 -5
  403. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-observability.js.map +1 -0
  404. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/deepwiki.cjs +1 -1
  405. package/dist/node_modules/@openhands/extensions/integrations/catalog/deepwiki.cjs.map +1 -0
  406. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/deepwiki.js +15 -5
  407. package/dist/node_modules/@openhands/extensions/integrations/catalog/deepwiki.js.map +1 -0
  408. package/dist/node_modules/@openhands/extensions/integrations/catalog/elevenlabs.cjs +2 -0
  409. package/dist/node_modules/@openhands/extensions/integrations/catalog/elevenlabs.cjs.map +1 -0
  410. package/dist/node_modules/@openhands/extensions/integrations/catalog/elevenlabs.js +36 -0
  411. package/dist/node_modules/@openhands/extensions/integrations/catalog/elevenlabs.js.map +1 -0
  412. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/everything.cjs +1 -1
  413. package/dist/node_modules/@openhands/extensions/integrations/catalog/everything.cjs.map +1 -0
  414. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/everything.js +13 -6
  415. package/dist/node_modules/@openhands/extensions/integrations/catalog/everything.js.map +1 -0
  416. package/dist/node_modules/@openhands/extensions/integrations/catalog/exa.cjs +2 -0
  417. package/dist/node_modules/@openhands/extensions/integrations/catalog/exa.cjs.map +1 -0
  418. package/dist/node_modules/@openhands/extensions/integrations/catalog/exa.js +36 -0
  419. package/dist/node_modules/@openhands/extensions/integrations/catalog/exa.js.map +1 -0
  420. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/fetch.cjs +1 -1
  421. package/dist/node_modules/@openhands/extensions/integrations/catalog/fetch.cjs.map +1 -0
  422. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/fetch.js +13 -6
  423. package/dist/node_modules/@openhands/extensions/integrations/catalog/fetch.js.map +1 -0
  424. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.cjs +2 -0
  425. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.cjs.map +1 -0
  426. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.js +40 -0
  427. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.js.map +1 -0
  428. package/dist/node_modules/@openhands/extensions/integrations/catalog/filesystem.cjs +2 -0
  429. package/dist/node_modules/@openhands/extensions/integrations/catalog/filesystem.cjs.map +1 -0
  430. package/dist/node_modules/@openhands/extensions/integrations/catalog/filesystem.js +39 -0
  431. package/dist/node_modules/@openhands/extensions/integrations/catalog/filesystem.js.map +1 -0
  432. package/dist/node_modules/@openhands/extensions/integrations/catalog/firecrawl.cjs +2 -0
  433. package/dist/node_modules/@openhands/extensions/integrations/catalog/firecrawl.cjs.map +1 -0
  434. package/dist/node_modules/@openhands/extensions/integrations/catalog/firecrawl.js +36 -0
  435. package/dist/node_modules/@openhands/extensions/integrations/catalog/firecrawl.js.map +1 -0
  436. package/dist/node_modules/@openhands/extensions/integrations/catalog/git.cjs +2 -0
  437. package/dist/node_modules/@openhands/extensions/integrations/catalog/git.cjs.map +1 -0
  438. package/dist/node_modules/@openhands/extensions/integrations/catalog/git.js +40 -0
  439. package/dist/node_modules/@openhands/extensions/integrations/catalog/git.js.map +1 -0
  440. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.cjs +2 -0
  441. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.cjs.map +1 -0
  442. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.js +47 -0
  443. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.js.map +1 -0
  444. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/huggingface.cjs +1 -1
  445. package/dist/node_modules/@openhands/extensions/integrations/catalog/huggingface.cjs.map +1 -0
  446. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/huggingface.js +15 -5
  447. package/dist/node_modules/@openhands/extensions/integrations/catalog/huggingface.js.map +1 -0
  448. package/dist/node_modules/@openhands/extensions/integrations/catalog/kagi.cjs +2 -0
  449. package/dist/node_modules/@openhands/extensions/integrations/catalog/kagi.cjs.map +1 -0
  450. package/dist/node_modules/@openhands/extensions/integrations/catalog/kagi.js +36 -0
  451. package/dist/node_modules/@openhands/extensions/integrations/catalog/kagi.js.map +1 -0
  452. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/linear.cjs +1 -1
  453. package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.cjs.map +1 -0
  454. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/linear.js +15 -5
  455. package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.js.map +1 -0
  456. package/dist/node_modules/@openhands/extensions/integrations/catalog/memory.cjs +2 -0
  457. package/dist/node_modules/@openhands/extensions/integrations/catalog/memory.cjs.map +1 -0
  458. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/memory.js +13 -6
  459. package/dist/node_modules/@openhands/extensions/integrations/catalog/memory.js.map +1 -0
  460. package/dist/node_modules/@openhands/extensions/integrations/catalog/mongodb.cjs +2 -0
  461. package/dist/node_modules/@openhands/extensions/integrations/catalog/mongodb.cjs.map +1 -0
  462. package/dist/node_modules/@openhands/extensions/integrations/catalog/mongodb.js +36 -0
  463. package/dist/node_modules/@openhands/extensions/integrations/catalog/mongodb.js.map +1 -0
  464. package/dist/node_modules/@openhands/extensions/integrations/catalog/neon.cjs +2 -0
  465. package/dist/node_modules/@openhands/extensions/integrations/catalog/neon.cjs.map +1 -0
  466. package/dist/node_modules/@openhands/extensions/integrations/catalog/neon.js +40 -0
  467. package/dist/node_modules/@openhands/extensions/integrations/catalog/neon.js.map +1 -0
  468. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs +2 -0
  469. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs.map +1 -0
  470. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js +39 -0
  471. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js.map +1 -0
  472. package/dist/node_modules/@openhands/extensions/integrations/catalog/obsidian.cjs +2 -0
  473. package/dist/node_modules/@openhands/extensions/integrations/catalog/obsidian.cjs.map +1 -0
  474. package/dist/node_modules/@openhands/extensions/integrations/catalog/obsidian.js +38 -0
  475. package/dist/node_modules/@openhands/extensions/integrations/catalog/obsidian.js.map +1 -0
  476. package/dist/node_modules/@openhands/extensions/integrations/catalog/paypal.cjs +2 -0
  477. package/dist/node_modules/@openhands/extensions/integrations/catalog/paypal.cjs.map +1 -0
  478. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/paypal.js +15 -5
  479. package/dist/node_modules/@openhands/extensions/integrations/catalog/paypal.js.map +1 -0
  480. package/dist/node_modules/@openhands/extensions/integrations/catalog/playwright.cjs +2 -0
  481. package/dist/node_modules/@openhands/extensions/integrations/catalog/playwright.cjs.map +1 -0
  482. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/playwright.js +13 -6
  483. package/dist/node_modules/@openhands/extensions/integrations/catalog/playwright.js.map +1 -0
  484. package/dist/node_modules/@openhands/extensions/integrations/catalog/redis.cjs +2 -0
  485. package/dist/node_modules/@openhands/extensions/integrations/catalog/redis.cjs.map +1 -0
  486. package/dist/node_modules/@openhands/extensions/integrations/catalog/redis.js +43 -0
  487. package/dist/node_modules/@openhands/extensions/integrations/catalog/redis.js.map +1 -0
  488. package/dist/node_modules/@openhands/extensions/integrations/catalog/resend.cjs +2 -0
  489. package/dist/node_modules/@openhands/extensions/integrations/catalog/resend.cjs.map +1 -0
  490. package/dist/node_modules/@openhands/extensions/integrations/catalog/resend.js +41 -0
  491. package/dist/node_modules/@openhands/extensions/integrations/catalog/resend.js.map +1 -0
  492. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.cjs +2 -0
  493. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.cjs.map +1 -0
  494. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/sentry.js +15 -5
  495. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.js.map +1 -0
  496. package/dist/node_modules/@openhands/extensions/integrations/catalog/sequential-thinking.cjs +2 -0
  497. package/dist/node_modules/@openhands/extensions/integrations/catalog/sequential-thinking.cjs.map +1 -0
  498. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/sequential-thinking.js +13 -6
  499. package/dist/node_modules/@openhands/extensions/integrations/catalog/sequential-thinking.js.map +1 -0
  500. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.cjs +2 -0
  501. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.cjs.map +1 -0
  502. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.js +45 -0
  503. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.js.map +1 -0
  504. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.cjs +2 -0
  505. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.cjs.map +1 -0
  506. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/stripe.js +15 -5
  507. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.js.map +1 -0
  508. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.cjs +2 -0
  509. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.cjs.map +1 -0
  510. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.js +37 -0
  511. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.js.map +1 -0
  512. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/tavily.cjs +1 -1
  513. package/dist/node_modules/@openhands/extensions/integrations/catalog/tavily.cjs.map +1 -0
  514. package/dist/node_modules/@openhands/extensions/integrations/catalog/tavily.js +39 -0
  515. package/dist/node_modules/@openhands/extensions/integrations/catalog/tavily.js.map +1 -0
  516. package/dist/node_modules/@openhands/extensions/integrations/catalog/time.cjs +2 -0
  517. package/dist/node_modules/@openhands/extensions/integrations/catalog/time.cjs.map +1 -0
  518. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/time.js +13 -6
  519. package/dist/node_modules/@openhands/extensions/integrations/catalog/time.js.map +1 -0
  520. package/dist/node_modules/@openhands/extensions/integrations/index.cjs +2 -0
  521. package/dist/node_modules/@openhands/extensions/integrations/index.cjs.map +1 -0
  522. package/dist/node_modules/@openhands/extensions/integrations/index.js +175 -0
  523. package/dist/node_modules/@openhands/extensions/integrations/index.js.map +1 -0
  524. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/logos.cjs +1 -1
  525. package/dist/node_modules/@openhands/extensions/integrations/logos.cjs.map +1 -0
  526. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/logos.js +2 -2
  527. package/dist/node_modules/@openhands/extensions/integrations/logos.js.map +1 -0
  528. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-catalog.cjs +2 -0
  529. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-catalog.cjs.map +1 -0
  530. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-catalog.js +548 -0
  531. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-catalog.js.map +1 -0
  532. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-registration-defaults.cjs +2 -0
  533. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-registration-defaults.cjs.map +1 -0
  534. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-registration-defaults.js +482 -0
  535. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-registration-defaults.js.map +1 -0
  536. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs +1 -1
  537. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs.map +1 -1
  538. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js +3 -0
  539. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js.map +1 -1
  540. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.cjs +2 -0
  541. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.cjs.map +1 -0
  542. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.js +22 -0
  543. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.js.map +1 -0
  544. package/dist/node_modules/@openhands/typescript-client/dist/index.cjs +1 -1
  545. package/dist/node_modules/@openhands/typescript-client/dist/index.js +1 -0
  546. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs +1 -1
  547. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs.map +1 -1
  548. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js +3 -0
  549. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js.map +1 -1
  550. package/dist/package.cjs +1 -1
  551. package/dist/package.cjs.map +1 -1
  552. package/dist/package.js +6 -4
  553. package/dist/package.js.map +1 -1
  554. package/dist/routes/conversation.cjs +1 -1
  555. package/dist/routes/conversation.cjs.map +1 -1
  556. package/dist/routes/conversation.js +61 -63
  557. package/dist/routes/conversation.js.map +1 -1
  558. package/dist/routes/mcp.cjs +1 -1
  559. package/dist/routes/mcp.cjs.map +1 -1
  560. package/dist/routes/mcp.js +1 -1
  561. package/dist/routes/mcp.js.map +1 -1
  562. package/dist/stores/use-event-store.cjs +1 -1
  563. package/dist/stores/use-event-store.cjs.map +1 -1
  564. package/dist/stores/use-event-store.d.ts +22 -0
  565. package/dist/stores/use-event-store.js +9 -1
  566. package/dist/stores/use-event-store.js.map +1 -1
  567. package/dist/ui/context-menu.d.ts +1 -1
  568. package/dist/ui/help-link.d.ts +1 -1
  569. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  570. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  571. package/dist/utils/mcp-marketplace-utils.d.ts +21 -1
  572. package/dist/utils/mcp-marketplace-utils.js +23 -13
  573. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  574. package/dist/utils/settings-utils.cjs.map +1 -1
  575. package/dist/utils/settings-utils.js.map +1 -1
  576. package/package.json +6 -4
  577. package/scripts/check-sdk-version-sync.mjs +6 -6
  578. package/scripts/dev-safe.mjs +60 -24
  579. package/scripts/dev-with-automation.mjs +30 -50
  580. package/tools/canvas_ui_tool.py +129 -0
  581. package/build/assets/add-backend-modal-CqjNjGqY.js +0 -1
  582. package/build/assets/agent-server-conversation-service.api-BdEre_71.js +0 -5
  583. package/build/assets/backend-form-modal-KudhWUX8.js +0 -1
  584. package/build/assets/browser-vYpdU3CR.js +0 -5
  585. package/build/assets/conversation-COZAKz_K.js +0 -1
  586. package/build/assets/conversation-DWcvnmds.js +0 -19
  587. package/build/assets/conversation-panel-CZDStT0b.js +0 -1
  588. package/build/assets/conversation-websocket-context-DulnrIHh.js +0 -3
  589. package/build/assets/declaration-C9nuq2Dj.js +0 -1
  590. package/build/assets/edit-automation-modal-C3bFxS2f.js +0 -1
  591. package/build/assets/files-tab-CbJ4s7Ik.js +0 -1
  592. package/build/assets/git-control-bar-branch-button-Bm6rzSpo.js +0 -27
  593. package/build/assets/install-server-modal-VB5hOBpW.js +0 -1
  594. package/build/assets/llm-settings-CIdxmimN.js +0 -1
  595. package/build/assets/manifest-f041e61a.js +0 -1
  596. package/build/assets/mcp-BdfyCW1l.js +0 -9
  597. package/build/assets/messages-v-q35ObG.js +0 -36
  598. package/build/assets/recommended-automations-launcher-Cx7svuGE.js +0 -52
  599. package/build/assets/root-D2PVd51i.js +0 -2
  600. package/build/assets/root-DEotKI6b.css +0 -1
  601. package/build/assets/settings-service.api-Z6x0l0GU.js +0 -1
  602. package/build/assets/use-is-authed-BFoh8Ogh.js +0 -1
  603. package/build/assets/use-runtime-is-ready-BQWLEyqa.js +0 -1
  604. package/build/assets/use-skills-Cn-78xP1.js +0 -1
  605. package/build/assets/use-user-conversation-BCYpbPT1.js +0 -1
  606. package/build/assets/vendor~home~mcp~automations-list-DRfWZRnF.js +0 -1
  607. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-BJm2mGIp.js +0 -48
  608. package/dist/node_modules/@openhands/extensions/mcps/catalog/airtable.cjs +0 -2
  609. package/dist/node_modules/@openhands/extensions/mcps/catalog/airtable.cjs.map +0 -1
  610. package/dist/node_modules/@openhands/extensions/mcps/catalog/airtable.js +0 -30
  611. package/dist/node_modules/@openhands/extensions/mcps/catalog/airtable.js.map +0 -1
  612. package/dist/node_modules/@openhands/extensions/mcps/catalog/apify.cjs +0 -2
  613. package/dist/node_modules/@openhands/extensions/mcps/catalog/apify.cjs.map +0 -1
  614. package/dist/node_modules/@openhands/extensions/mcps/catalog/apify.js +0 -29
  615. package/dist/node_modules/@openhands/extensions/mcps/catalog/apify.js.map +0 -1
  616. package/dist/node_modules/@openhands/extensions/mcps/catalog/atlassian.cjs.map +0 -1
  617. package/dist/node_modules/@openhands/extensions/mcps/catalog/atlassian.js.map +0 -1
  618. package/dist/node_modules/@openhands/extensions/mcps/catalog/brave-search.cjs +0 -2
  619. package/dist/node_modules/@openhands/extensions/mcps/catalog/brave-search.cjs.map +0 -1
  620. package/dist/node_modules/@openhands/extensions/mcps/catalog/brave-search.js +0 -29
  621. package/dist/node_modules/@openhands/extensions/mcps/catalog/brave-search.js.map +0 -1
  622. package/dist/node_modules/@openhands/extensions/mcps/catalog/browser-mcp.cjs +0 -2
  623. package/dist/node_modules/@openhands/extensions/mcps/catalog/browser-mcp.cjs.map +0 -1
  624. package/dist/node_modules/@openhands/extensions/mcps/catalog/browser-mcp.js +0 -24
  625. package/dist/node_modules/@openhands/extensions/mcps/catalog/browser-mcp.js.map +0 -1
  626. package/dist/node_modules/@openhands/extensions/mcps/catalog/clickhouse.cjs +0 -2
  627. package/dist/node_modules/@openhands/extensions/mcps/catalog/clickhouse.cjs.map +0 -1
  628. package/dist/node_modules/@openhands/extensions/mcps/catalog/clickhouse.js +0 -45
  629. package/dist/node_modules/@openhands/extensions/mcps/catalog/clickhouse.js.map +0 -1
  630. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-bindings.cjs.map +0 -1
  631. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-bindings.js.map +0 -1
  632. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-browser-rendering.cjs +0 -2
  633. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-browser-rendering.cjs.map +0 -1
  634. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-browser-rendering.js.map +0 -1
  635. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-builds.cjs.map +0 -1
  636. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-builds.js.map +0 -1
  637. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-docs.cjs.map +0 -1
  638. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-docs.js.map +0 -1
  639. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-observability.cjs +0 -2
  640. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-observability.cjs.map +0 -1
  641. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-observability.js.map +0 -1
  642. package/dist/node_modules/@openhands/extensions/mcps/catalog/deepwiki.cjs.map +0 -1
  643. package/dist/node_modules/@openhands/extensions/mcps/catalog/deepwiki.js.map +0 -1
  644. package/dist/node_modules/@openhands/extensions/mcps/catalog/elevenlabs.cjs +0 -2
  645. package/dist/node_modules/@openhands/extensions/mcps/catalog/elevenlabs.cjs.map +0 -1
  646. package/dist/node_modules/@openhands/extensions/mcps/catalog/elevenlabs.js +0 -29
  647. package/dist/node_modules/@openhands/extensions/mcps/catalog/elevenlabs.js.map +0 -1
  648. package/dist/node_modules/@openhands/extensions/mcps/catalog/everything.cjs.map +0 -1
  649. package/dist/node_modules/@openhands/extensions/mcps/catalog/everything.js.map +0 -1
  650. package/dist/node_modules/@openhands/extensions/mcps/catalog/exa.cjs +0 -2
  651. package/dist/node_modules/@openhands/extensions/mcps/catalog/exa.cjs.map +0 -1
  652. package/dist/node_modules/@openhands/extensions/mcps/catalog/exa.js +0 -29
  653. package/dist/node_modules/@openhands/extensions/mcps/catalog/exa.js.map +0 -1
  654. package/dist/node_modules/@openhands/extensions/mcps/catalog/fetch.cjs.map +0 -1
  655. package/dist/node_modules/@openhands/extensions/mcps/catalog/fetch.js.map +0 -1
  656. package/dist/node_modules/@openhands/extensions/mcps/catalog/figma.cjs +0 -2
  657. package/dist/node_modules/@openhands/extensions/mcps/catalog/figma.cjs.map +0 -1
  658. package/dist/node_modules/@openhands/extensions/mcps/catalog/figma.js +0 -33
  659. package/dist/node_modules/@openhands/extensions/mcps/catalog/figma.js.map +0 -1
  660. package/dist/node_modules/@openhands/extensions/mcps/catalog/filesystem.cjs +0 -2
  661. package/dist/node_modules/@openhands/extensions/mcps/catalog/filesystem.cjs.map +0 -1
  662. package/dist/node_modules/@openhands/extensions/mcps/catalog/filesystem.js +0 -32
  663. package/dist/node_modules/@openhands/extensions/mcps/catalog/filesystem.js.map +0 -1
  664. package/dist/node_modules/@openhands/extensions/mcps/catalog/firecrawl.cjs +0 -2
  665. package/dist/node_modules/@openhands/extensions/mcps/catalog/firecrawl.cjs.map +0 -1
  666. package/dist/node_modules/@openhands/extensions/mcps/catalog/firecrawl.js +0 -29
  667. package/dist/node_modules/@openhands/extensions/mcps/catalog/firecrawl.js.map +0 -1
  668. package/dist/node_modules/@openhands/extensions/mcps/catalog/git.cjs +0 -2
  669. package/dist/node_modules/@openhands/extensions/mcps/catalog/git.cjs.map +0 -1
  670. package/dist/node_modules/@openhands/extensions/mcps/catalog/git.js +0 -33
  671. package/dist/node_modules/@openhands/extensions/mcps/catalog/git.js.map +0 -1
  672. package/dist/node_modules/@openhands/extensions/mcps/catalog/github.cjs +0 -2
  673. package/dist/node_modules/@openhands/extensions/mcps/catalog/github.cjs.map +0 -1
  674. package/dist/node_modules/@openhands/extensions/mcps/catalog/github.js +0 -40
  675. package/dist/node_modules/@openhands/extensions/mcps/catalog/github.js.map +0 -1
  676. package/dist/node_modules/@openhands/extensions/mcps/catalog/huggingface.cjs.map +0 -1
  677. package/dist/node_modules/@openhands/extensions/mcps/catalog/huggingface.js.map +0 -1
  678. package/dist/node_modules/@openhands/extensions/mcps/catalog/kagi.cjs +0 -2
  679. package/dist/node_modules/@openhands/extensions/mcps/catalog/kagi.cjs.map +0 -1
  680. package/dist/node_modules/@openhands/extensions/mcps/catalog/kagi.js +0 -29
  681. package/dist/node_modules/@openhands/extensions/mcps/catalog/kagi.js.map +0 -1
  682. package/dist/node_modules/@openhands/extensions/mcps/catalog/linear.cjs.map +0 -1
  683. package/dist/node_modules/@openhands/extensions/mcps/catalog/linear.js.map +0 -1
  684. package/dist/node_modules/@openhands/extensions/mcps/catalog/memory.cjs +0 -2
  685. package/dist/node_modules/@openhands/extensions/mcps/catalog/memory.cjs.map +0 -1
  686. package/dist/node_modules/@openhands/extensions/mcps/catalog/memory.js.map +0 -1
  687. package/dist/node_modules/@openhands/extensions/mcps/catalog/mongodb.cjs +0 -2
  688. package/dist/node_modules/@openhands/extensions/mcps/catalog/mongodb.cjs.map +0 -1
  689. package/dist/node_modules/@openhands/extensions/mcps/catalog/mongodb.js +0 -29
  690. package/dist/node_modules/@openhands/extensions/mcps/catalog/mongodb.js.map +0 -1
  691. package/dist/node_modules/@openhands/extensions/mcps/catalog/neon.cjs +0 -2
  692. package/dist/node_modules/@openhands/extensions/mcps/catalog/neon.cjs.map +0 -1
  693. package/dist/node_modules/@openhands/extensions/mcps/catalog/neon.js +0 -33
  694. package/dist/node_modules/@openhands/extensions/mcps/catalog/neon.js.map +0 -1
  695. package/dist/node_modules/@openhands/extensions/mcps/catalog/notion.cjs +0 -2
  696. package/dist/node_modules/@openhands/extensions/mcps/catalog/notion.cjs.map +0 -1
  697. package/dist/node_modules/@openhands/extensions/mcps/catalog/notion.js +0 -32
  698. package/dist/node_modules/@openhands/extensions/mcps/catalog/notion.js.map +0 -1
  699. package/dist/node_modules/@openhands/extensions/mcps/catalog/obsidian.cjs +0 -2
  700. package/dist/node_modules/@openhands/extensions/mcps/catalog/obsidian.cjs.map +0 -1
  701. package/dist/node_modules/@openhands/extensions/mcps/catalog/obsidian.js +0 -31
  702. package/dist/node_modules/@openhands/extensions/mcps/catalog/obsidian.js.map +0 -1
  703. package/dist/node_modules/@openhands/extensions/mcps/catalog/paypal.cjs +0 -2
  704. package/dist/node_modules/@openhands/extensions/mcps/catalog/paypal.cjs.map +0 -1
  705. package/dist/node_modules/@openhands/extensions/mcps/catalog/paypal.js.map +0 -1
  706. package/dist/node_modules/@openhands/extensions/mcps/catalog/playwright.cjs +0 -2
  707. package/dist/node_modules/@openhands/extensions/mcps/catalog/playwright.cjs.map +0 -1
  708. package/dist/node_modules/@openhands/extensions/mcps/catalog/playwright.js.map +0 -1
  709. package/dist/node_modules/@openhands/extensions/mcps/catalog/redis.cjs +0 -2
  710. package/dist/node_modules/@openhands/extensions/mcps/catalog/redis.cjs.map +0 -1
  711. package/dist/node_modules/@openhands/extensions/mcps/catalog/redis.js +0 -36
  712. package/dist/node_modules/@openhands/extensions/mcps/catalog/redis.js.map +0 -1
  713. package/dist/node_modules/@openhands/extensions/mcps/catalog/resend.cjs +0 -2
  714. package/dist/node_modules/@openhands/extensions/mcps/catalog/resend.cjs.map +0 -1
  715. package/dist/node_modules/@openhands/extensions/mcps/catalog/resend.js +0 -34
  716. package/dist/node_modules/@openhands/extensions/mcps/catalog/resend.js.map +0 -1
  717. package/dist/node_modules/@openhands/extensions/mcps/catalog/sentry.cjs +0 -2
  718. package/dist/node_modules/@openhands/extensions/mcps/catalog/sentry.cjs.map +0 -1
  719. package/dist/node_modules/@openhands/extensions/mcps/catalog/sentry.js.map +0 -1
  720. package/dist/node_modules/@openhands/extensions/mcps/catalog/sequential-thinking.cjs +0 -2
  721. package/dist/node_modules/@openhands/extensions/mcps/catalog/sequential-thinking.cjs.map +0 -1
  722. package/dist/node_modules/@openhands/extensions/mcps/catalog/sequential-thinking.js.map +0 -1
  723. package/dist/node_modules/@openhands/extensions/mcps/catalog/slack.cjs +0 -2
  724. package/dist/node_modules/@openhands/extensions/mcps/catalog/slack.cjs.map +0 -1
  725. package/dist/node_modules/@openhands/extensions/mcps/catalog/slack.js +0 -38
  726. package/dist/node_modules/@openhands/extensions/mcps/catalog/slack.js.map +0 -1
  727. package/dist/node_modules/@openhands/extensions/mcps/catalog/stripe.cjs +0 -2
  728. package/dist/node_modules/@openhands/extensions/mcps/catalog/stripe.cjs.map +0 -1
  729. package/dist/node_modules/@openhands/extensions/mcps/catalog/stripe.js.map +0 -1
  730. package/dist/node_modules/@openhands/extensions/mcps/catalog/supabase.cjs +0 -2
  731. package/dist/node_modules/@openhands/extensions/mcps/catalog/supabase.cjs.map +0 -1
  732. package/dist/node_modules/@openhands/extensions/mcps/catalog/supabase.js +0 -30
  733. package/dist/node_modules/@openhands/extensions/mcps/catalog/supabase.js.map +0 -1
  734. package/dist/node_modules/@openhands/extensions/mcps/catalog/tavily.cjs.map +0 -1
  735. package/dist/node_modules/@openhands/extensions/mcps/catalog/tavily.js +0 -32
  736. package/dist/node_modules/@openhands/extensions/mcps/catalog/tavily.js.map +0 -1
  737. package/dist/node_modules/@openhands/extensions/mcps/catalog/time.cjs +0 -2
  738. package/dist/node_modules/@openhands/extensions/mcps/catalog/time.cjs.map +0 -1
  739. package/dist/node_modules/@openhands/extensions/mcps/catalog/time.js.map +0 -1
  740. package/dist/node_modules/@openhands/extensions/mcps/index.cjs +0 -2
  741. package/dist/node_modules/@openhands/extensions/mcps/index.cjs.map +0 -1
  742. package/dist/node_modules/@openhands/extensions/mcps/index.js +0 -87
  743. package/dist/node_modules/@openhands/extensions/mcps/index.js.map +0 -1
  744. package/dist/node_modules/@openhands/extensions/mcps/logos.cjs.map +0 -1
  745. package/dist/node_modules/@openhands/extensions/mcps/logos.js.map +0 -1
@@ -10,24 +10,24 @@ import { useAgentState as c } from "../../../../hooks/use-agent-state.js";
10
10
  import { mobileTopBarIconClassName as l } from "../../../../utils/mobile-top-bar-icon-button-classes.js";
11
11
  import { Typography as u } from "../../../../ui/typography.js";
12
12
  import d from "../../../../icons/lesson-plan.js";
13
- import ee from "../../../../icons/document.js";
14
- import { useHandleBuildPlanClick as te } from "../../../../hooks/use-handle-build-plan-click.js";
15
- import { useSelectConversationTab as ne } from "../../../../hooks/use-select-conversation-tab.js";
16
- import { EllipsisButton as f } from "../../conversation-panel/ellipsis-button.js";
17
- import { ChatActionTooltip as p } from "../../chat/chat-action-tooltip.js";
18
- import m from "../../../../icons/terminal.js";
13
+ import f from "../../../../icons/document.js";
14
+ import { useHandleBuildPlanClick as ee } from "../../../../hooks/use-handle-build-plan-click.js";
15
+ import { useSelectConversationTab as te } from "../../../../hooks/use-select-conversation-tab.js";
16
+ import { EllipsisButton as p } from "../../conversation-panel/ellipsis-button.js";
17
+ import { ChatActionTooltip as m } from "../../chat/chat-action-tooltip.js";
18
+ import ne from "../../../../icons/terminal.js";
19
19
  import h from "../../../../icons/globe.js";
20
20
  import g from "../../../../icons/vscode.js";
21
21
  import _ from "../../../../icons/double-check.js";
22
22
  import { ConversationTabNav as v } from "./conversation-tab-nav.js";
23
23
  import { VSCodeTooltipContent as y } from "./vscode-tooltip-content.js";
24
- import { useTaskList as re } from "../../../../hooks/use-task-list.js";
25
- import { ConversationTabsContextMenu as b } from "./conversation-tabs-context-menu.js";
24
+ import { useTaskList as b } from "../../../../hooks/use-task-list.js";
25
+ import { ConversationTabsContextMenu as re } from "./conversation-tabs-context-menu.js";
26
26
  import { useEffect as x, useLayoutEffect as S, useRef as C, useState as w } from "react";
27
27
  import { Fragment as ie, jsx as T, jsxs as E } from "react/jsx-runtime";
28
28
  //#region src/components/features/conversation/conversation-tabs/conversation-tabs.tsx
29
29
  function D({ variant: D = "default" }) {
30
- let { conversationId: O } = i(), { setSelectedTab: k, planContent: A } = o(), [j, M] = w(!1), { state: N } = a(O), { hasTaskList: P } = re(), { backend: F } = s(), { handleBuildPlanClick: I } = te(), { curAgentState: L } = c(), { selectTab: R, isTabActive: z, onTabChange: B, selectedTab: V, isRightPanelShown: H } = ne();
30
+ let { conversationId: O } = i(), { setSelectedTab: k, planContent: A } = o(), [j, M] = w(!1), { state: N } = a(O), { hasTaskList: P } = b(), { backend: F } = s(), { handleBuildPlanClick: I } = ee(), { curAgentState: L } = c(), { selectTab: R, isTabActive: z, onTabChange: B, selectedTab: V, isRightPanelShown: H } = te();
31
31
  x(() => {
32
32
  k(N.selectedTab);
33
33
  }, [k, N.selectedTab]), x(() => {
@@ -41,7 +41,7 @@ function D({ variant: D = "default" }) {
41
41
  {
42
42
  tabValue: "files",
43
43
  isActive: z("files"),
44
- icon: ee,
44
+ icon: f,
45
45
  onClick: () => R("files"),
46
46
  tooltipContent: U(t.COMMON$FILES),
47
47
  tooltipAriaLabel: U(t.COMMON$FILES),
@@ -68,7 +68,7 @@ function D({ variant: D = "default" }) {
68
68
  {
69
69
  tabValue: "terminal",
70
70
  isActive: z("terminal"),
71
- icon: m,
71
+ icon: ne,
72
72
  onClick: () => R("terminal"),
73
73
  tooltipContent: U(t.COMMON$TERMINAL),
74
74
  tooltipAriaLabel: U(t.COMMON$TERMINAL),
@@ -94,7 +94,7 @@ function D({ variant: D = "default" }) {
94
94
  tooltipAriaLabel: U(t.COMMON$TASK_LIST),
95
95
  label: U(t.COMMON$TASK_LIST)
96
96
  });
97
- let K = G.filter((e) => e.tabValue === "vscode" && F.kind !== "cloud" ? !1 : N.unpinnedTabs.includes(e.tabValue) ? V === e.tabValue : !0), q = N.unpinnedTabs.join(","), J = L === n.RUNNING || L === n.LOADING || !A, Y = C(null), X = C(null), Z = C(null), Q = C(null), [ae, $] = w(K.length);
97
+ let K = G.filter((e) => e.tabValue === "vscode" && F.kind !== "cloud" || e.tabValue === "planner" && F.kind !== "cloud" ? !1 : N.unpinnedTabs.includes(e.tabValue) ? V === e.tabValue : !0), q = N.unpinnedTabs.join(","), J = L === n.RUNNING || L === n.LOADING || !A, Y = C(null), X = C(null), Z = C(null), Q = C(null), [ae, $] = w(K.length);
98
98
  S(() => {
99
99
  let e = Y.current, t = X.current, n = Z.current;
100
100
  if (!e || !t || !n) return;
@@ -139,7 +139,7 @@ function D({ variant: D = "default" }) {
139
139
  ref: X,
140
140
  "aria-hidden": !0,
141
141
  className: "pointer-events-none absolute top-0 left-[-10000px] flex flex-nowrap items-center gap-1.5",
142
- children: K.map(({ tabValue: e, icon: t, isActive: n, tooltipContent: i, tooltipAriaLabel: a, label: o, className: s }, c) => /* @__PURE__ */ T(p, {
142
+ children: K.map(({ tabValue: e, icon: t, isActive: n, tooltipContent: i, tooltipAriaLabel: a, label: o, className: s }, c) => /* @__PURE__ */ T(m, {
143
143
  tooltip: i,
144
144
  ariaLabel: a,
145
145
  children: /* @__PURE__ */ T(v, {
@@ -159,7 +159,7 @@ function D({ variant: D = "default" }) {
159
159
  className: "flex w-fit max-w-full min-w-0 flex-nowrap items-center gap-1.5",
160
160
  children: [/* @__PURE__ */ T("div", {
161
161
  className: "flex min-w-0 flex-1 flex-nowrap items-center gap-1.5 overflow-x-hidden",
162
- children: K.slice(0, oe).map(({ tabValue: e, icon: t, onClick: n, isActive: i, tooltipContent: a, tooltipAriaLabel: o, label: s, className: c }, l) => /* @__PURE__ */ T(p, {
162
+ children: K.slice(0, oe).map(({ tabValue: e, icon: t, onClick: n, isActive: i, tooltipContent: a, tooltipAriaLabel: o, label: s, className: c }, l) => /* @__PURE__ */ T(m, {
163
163
  tooltip: a,
164
164
  ariaLabel: o,
165
165
  children: /* @__PURE__ */ T(v, {
@@ -174,12 +174,12 @@ function D({ variant: D = "default" }) {
174
174
  }), /* @__PURE__ */ E("div", {
175
175
  ref: Z,
176
176
  className: "relative shrink-0",
177
- children: [/* @__PURE__ */ T(f, {
177
+ children: [/* @__PURE__ */ T(p, {
178
178
  ref: Q,
179
179
  onClick: () => M(!j),
180
180
  ariaLabel: U(t.COMMON$MORE_OPTIONS),
181
181
  iconClassName: D === "compact" ? l : void 0
182
- }), /* @__PURE__ */ T(b, {
182
+ }), /* @__PURE__ */ T(re, {
183
183
  isOpen: j,
184
184
  onClose: () => M(!1),
185
185
  ignoreOutsideClickRef: Q
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-tabs.js","names":[],"sources":["../../../../../src/components/features/conversation/conversation-tabs/conversation-tabs.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport TerminalIcon from \"#/icons/terminal.svg?react\";\nimport GlobeIcon from \"#/icons/globe.svg?react\";\nimport DocumentIcon from \"#/icons/document.svg?react\";\nimport VSCodeIcon from \"#/icons/vscode.svg?react\";\nimport LessonPlanIcon from \"#/icons/lesson-plan.svg?react\";\nimport DoubleCheckIcon from \"#/icons/double-check.svg?react\";\nimport { EllipsisButton } from \"#/components/features/conversation-panel/ellipsis-button\";\nimport { cn } from \"#/utils/utils\";\nimport { useConversationLocalStorageState } from \"#/utils/conversation-local-storage\";\nimport { ConversationTabNav } from \"./conversation-tab-nav\";\nimport { ChatActionTooltip } from \"../../chat/chat-action-tooltip\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { VSCodeTooltipContent } from \"./vscode-tooltip-content\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { ConversationTabsContextMenu } from \"./conversation-tabs-context-menu\";\nimport { useConversationId } from \"#/hooks/use-conversation-id\";\nimport { useSelectConversationTab } from \"#/hooks/use-select-conversation-tab\";\nimport { useTaskList } from \"#/hooks/use-task-list\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useHandleBuildPlanClick } from \"#/hooks/use-handle-build-plan-click\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { AgentState } from \"#/types/agent-state\";\nimport { Typography } from \"#/ui/typography\";\nimport { mobileTopBarIconClassName } from \"#/utils/mobile-top-bar-icon-button-classes\";\n\nexport function ConversationTabs({\n variant = \"default\",\n}: {\n variant?: \"default\" | \"compact\";\n}) {\n const { conversationId } = useConversationId();\n const { setSelectedTab, planContent } = useConversationStore();\n\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n\n const { state: persistedState } =\n useConversationLocalStorageState(conversationId);\n\n const { hasTaskList } = useTaskList();\n const { backend } = useActiveBackend();\n\n const { handleBuildPlanClick } = useHandleBuildPlanClick();\n const { curAgentState } = useAgentState();\n\n const {\n selectTab,\n isTabActive,\n onTabChange,\n selectedTab,\n isRightPanelShown,\n } = useSelectConversationTab();\n\n // Restore the most-recently-used tab from localStorage so users don't\n // lose their tab selection across reloads.\n //\n // Note: we deliberately do NOT mirror `rightPanelShown` from\n // localStorage. The drawer's open/closed state is session-only — see\n // the comment in `useConversationStore` and the schema note in\n // `conversation-local-storage.ts` for the rationale.\n useEffect(() => {\n setSelectedTab(persistedState.selectedTab);\n }, [setSelectedTab, persistedState.selectedTab]);\n\n useEffect(() => {\n const handlePanelVisibilityChange = () => {\n if (isRightPanelShown) {\n // If no tab is selected, default to files tab\n if (!selectedTab) {\n onTabChange(\"files\");\n }\n }\n };\n\n handlePanelVisibilityChange();\n }, [isRightPanelShown, selectedTab, onTabChange]);\n\n const { t, i18n } = useTranslation(\"openhands\");\n\n // `files` is intentionally the leftmost tab — it's the primary entry\n // point for inspecting agent output (workspace files + git diff).\n const tabs = [\n {\n tabValue: \"files\",\n isActive: isTabActive(\"files\"),\n icon: DocumentIcon,\n onClick: () => selectTab(\"files\"),\n tooltipContent: t(I18nKey.COMMON$FILES),\n tooltipAriaLabel: t(I18nKey.COMMON$FILES),\n label: t(I18nKey.COMMON$FILES),\n },\n {\n tabValue: \"planner\",\n isActive: isTabActive(\"planner\"),\n icon: LessonPlanIcon,\n onClick: () => selectTab(\"planner\"),\n tooltipContent: t(I18nKey.COMMON$PLANNER),\n tooltipAriaLabel: t(I18nKey.COMMON$PLANNER),\n label: t(I18nKey.COMMON$PLANNER),\n },\n {\n tabValue: \"vscode\",\n isActive: isTabActive(\"vscode\"),\n icon: VSCodeIcon,\n onClick: () => selectTab(\"vscode\"),\n tooltipContent: <VSCodeTooltipContent />,\n tooltipAriaLabel: t(I18nKey.COMMON$CODE),\n label: t(I18nKey.COMMON$CODE),\n },\n {\n tabValue: \"terminal\",\n isActive: isTabActive(\"terminal\"),\n icon: TerminalIcon,\n onClick: () => selectTab(\"terminal\"),\n tooltipContent: t(I18nKey.COMMON$TERMINAL),\n tooltipAriaLabel: t(I18nKey.COMMON$TERMINAL),\n label: t(I18nKey.COMMON$TERMINAL),\n className: \"pl-2\",\n },\n {\n tabValue: \"browser\",\n isActive: isTabActive(\"browser\"),\n icon: GlobeIcon,\n onClick: () => selectTab(\"browser\"),\n tooltipContent: t(I18nKey.COMMON$BROWSER),\n tooltipAriaLabel: t(I18nKey.COMMON$BROWSER),\n label: t(I18nKey.COMMON$BROWSER),\n },\n ];\n\n if (hasTaskList) {\n // Insert after `files` so the leftmost slot stays Files.\n tabs.splice(1, 0, {\n tabValue: \"tasklist\",\n isActive: isTabActive(\"tasklist\"),\n icon: DoubleCheckIcon,\n onClick: () => selectTab(\"tasklist\"),\n tooltipContent: t(I18nKey.COMMON$TASK_LIST),\n tooltipAriaLabel: t(I18nKey.COMMON$TASK_LIST),\n label: t(I18nKey.COMMON$TASK_LIST),\n });\n }\n\n // Pinned tabs always show in the bar. Unpinned tabs stay hidden unless the\n // user has that tab selected — then it appears while active so the bar\n // matches the open panel. Hide VS Code on local backends (cloud-only URL).\n const visibleTabs = tabs.filter((tab) => {\n if (tab.tabValue === \"vscode\" && backend.kind !== \"cloud\") return false;\n if (!persistedState.unpinnedTabs.includes(tab.tabValue)) return true;\n return selectedTab === tab.tabValue;\n });\n\n const unpinnedSignature = persistedState.unpinnedTabs.join(\",\");\n\n const isAgentRunning =\n curAgentState === AgentState.RUNNING ||\n curAgentState === AgentState.LOADING;\n const isBuildDisabled = isAgentRunning || !planContent;\n\n const tabsRowInnerRef = useRef<HTMLDivElement>(null);\n const measureRowRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLButtonElement>(null);\n const [inlineTabCount, setInlineTabCount] = useState(visibleTabs.length);\n\n useLayoutEffect(() => {\n const rowInner = tabsRowInnerRef.current;\n const measureRow = measureRowRef.current;\n const menuEl = menuRef.current;\n if (!rowInner || !measureRow || !menuEl) return undefined;\n\n const measure = () => {\n const measureButtons = measureRow.querySelectorAll<HTMLButtonElement>(\n '[data-tab-measure=\"true\"]',\n );\n const tabCount = measureButtons.length;\n\n const rowWidth = rowInner.getBoundingClientRect().width;\n if (rowWidth === 0) {\n setInlineTabCount(tabCount);\n return;\n }\n\n const widths = Array.from(measureButtons).map(\n (button) => button.getBoundingClientRect().width,\n );\n\n if (widths.length !== tabCount || tabCount === 0) {\n setInlineTabCount(Math.max(0, tabCount));\n return;\n }\n\n const menuWidth = menuEl.getBoundingClientRect().width;\n const gapCss =\n getComputedStyle(rowInner).columnGap || getComputedStyle(rowInner).gap;\n const gapPx = parseFloat(gapCss) || 6;\n\n let nextCount = 0;\n for (let k = tabCount; k >= 0; k -= 1) {\n let total = menuWidth;\n for (let i = 0; i < k; i += 1) {\n total += widths[i] ?? 0;\n }\n if (k > 0) {\n total += k * gapPx;\n }\n if (total <= rowWidth + 0.5) {\n nextCount = k;\n break;\n }\n }\n\n setInlineTabCount((prev) => (prev === nextCount ? prev : nextCount));\n };\n\n measure();\n if (typeof ResizeObserver === \"undefined\") return undefined;\n const ro = new ResizeObserver(measure);\n ro.observe(rowInner);\n return () => ro.disconnect();\n }, [\n unpinnedSignature,\n visibleTabs.length,\n hasTaskList,\n backend.kind,\n selectedTab,\n isRightPanelShown,\n i18n.language,\n ]);\n\n const safeInlineTabCount = Math.min(inlineTabCount, visibleTabs.length);\n\n return (\n <>\n <div\n className={cn(\n \"relative w-full min-w-0\",\n variant === \"compact\"\n ? \"flex h-full min-h-0 items-center py-0 pl-0 pr-1\"\n : \"min-h-10 p-1\",\n )}\n >\n <div\n ref={measureRowRef}\n aria-hidden\n className=\"pointer-events-none absolute top-0 left-[-10000px] flex flex-nowrap items-center gap-1.5\"\n >\n {visibleTabs.map(\n (\n {\n tabValue,\n icon,\n isActive,\n tooltipContent,\n tooltipAriaLabel,\n label,\n className: tabClassName,\n },\n index,\n ) => (\n <ChatActionTooltip\n key={`measure-${tabValue}-${index}`}\n tooltip={tooltipContent}\n ariaLabel={tooltipAriaLabel}\n >\n <ConversationTabNav\n tabValue={tabValue}\n icon={icon}\n onClick={() => {}}\n isActive={isActive}\n label={label}\n className={cn(tabClassName, \"shrink-0\")}\n measureOnly\n />\n </ChatActionTooltip>\n ),\n )}\n </div>\n <div\n ref={tabsRowInnerRef}\n className=\"flex w-full min-w-0 flex-nowrap items-center justify-start\"\n >\n <div className=\"flex w-fit max-w-full min-w-0 flex-nowrap items-center gap-1.5\">\n <div className=\"flex min-w-0 flex-1 flex-nowrap items-center gap-1.5 overflow-x-hidden\">\n {visibleTabs\n .slice(0, safeInlineTabCount)\n .map(\n (\n {\n tabValue,\n icon,\n onClick,\n isActive,\n tooltipContent,\n tooltipAriaLabel,\n label,\n className: tabClassName,\n },\n index,\n ) => (\n <ChatActionTooltip\n key={`${tabValue}-${index}`}\n tooltip={tooltipContent}\n ariaLabel={tooltipAriaLabel}\n >\n <ConversationTabNav\n tabValue={tabValue}\n icon={icon}\n onClick={onClick}\n isActive={isActive}\n label={label}\n className={cn(tabClassName, \"shrink-0\")}\n />\n </ChatActionTooltip>\n ),\n )}\n </div>\n <div ref={menuRef} className=\"relative shrink-0\">\n <EllipsisButton\n ref={anchorRef}\n onClick={() => setIsMenuOpen(!isMenuOpen)}\n ariaLabel={t(I18nKey.COMMON$MORE_OPTIONS)}\n iconClassName={\n variant === \"compact\" ? mobileTopBarIconClassName : undefined\n }\n />\n <ConversationTabsContextMenu\n isOpen={isMenuOpen}\n onClose={() => setIsMenuOpen(false)}\n ignoreOutsideClickRef={anchorRef}\n />\n </div>\n </div>\n </div>\n </div>\n {isTabActive(\"planner\") && (\n <div\n className={cn(\n \"flex h-10 min-h-10 shrink-0 items-center border-t border-[var(--oh-border)] pl-[10px] pr-1\",\n )}\n >\n <button\n type=\"button\"\n onClick={handleBuildPlanClick}\n disabled={isBuildDisabled}\n className={cn(\n \"flex h-5 min-w-17 items-center justify-center rounded bg-white px-2 transition-opacity\",\n isBuildDisabled\n ? \"cursor-not-allowed opacity-50\"\n : \"cursor-pointer hover:opacity-90\",\n )}\n data-testid=\"planner-tab-build-button\"\n >\n <Typography.Text className=\"text-[11px] font-normal leading-5 text-black\">\n {/* eslint-disable-next-line i18next/no-literal-string */}\n {t(I18nKey.COMMON$BUILD)} ⌘↩\n </Typography.Text>\n </button>\n </div>\n )}\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"conversation-tabs.js","names":[],"sources":["../../../../../src/components/features/conversation/conversation-tabs/conversation-tabs.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport TerminalIcon from \"#/icons/terminal.svg?react\";\nimport GlobeIcon from \"#/icons/globe.svg?react\";\nimport DocumentIcon from \"#/icons/document.svg?react\";\nimport VSCodeIcon from \"#/icons/vscode.svg?react\";\nimport LessonPlanIcon from \"#/icons/lesson-plan.svg?react\";\nimport DoubleCheckIcon from \"#/icons/double-check.svg?react\";\nimport { EllipsisButton } from \"#/components/features/conversation-panel/ellipsis-button\";\nimport { cn } from \"#/utils/utils\";\nimport { useConversationLocalStorageState } from \"#/utils/conversation-local-storage\";\nimport { ConversationTabNav } from \"./conversation-tab-nav\";\nimport { ChatActionTooltip } from \"../../chat/chat-action-tooltip\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { VSCodeTooltipContent } from \"./vscode-tooltip-content\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { ConversationTabsContextMenu } from \"./conversation-tabs-context-menu\";\nimport { useConversationId } from \"#/hooks/use-conversation-id\";\nimport { useSelectConversationTab } from \"#/hooks/use-select-conversation-tab\";\nimport { useTaskList } from \"#/hooks/use-task-list\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useHandleBuildPlanClick } from \"#/hooks/use-handle-build-plan-click\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { AgentState } from \"#/types/agent-state\";\nimport { Typography } from \"#/ui/typography\";\nimport { mobileTopBarIconClassName } from \"#/utils/mobile-top-bar-icon-button-classes\";\n\nexport function ConversationTabs({\n variant = \"default\",\n}: {\n variant?: \"default\" | \"compact\";\n}) {\n const { conversationId } = useConversationId();\n const { setSelectedTab, planContent } = useConversationStore();\n\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n\n const { state: persistedState } =\n useConversationLocalStorageState(conversationId);\n\n const { hasTaskList } = useTaskList();\n const { backend } = useActiveBackend();\n\n const { handleBuildPlanClick } = useHandleBuildPlanClick();\n const { curAgentState } = useAgentState();\n\n const {\n selectTab,\n isTabActive,\n onTabChange,\n selectedTab,\n isRightPanelShown,\n } = useSelectConversationTab();\n\n // Restore the most-recently-used tab from localStorage so users don't\n // lose their tab selection across reloads.\n //\n // Note: we deliberately do NOT mirror `rightPanelShown` from\n // localStorage. The drawer's open/closed state is session-only — see\n // the comment in `useConversationStore` and the schema note in\n // `conversation-local-storage.ts` for the rationale.\n useEffect(() => {\n setSelectedTab(persistedState.selectedTab);\n }, [setSelectedTab, persistedState.selectedTab]);\n\n useEffect(() => {\n const handlePanelVisibilityChange = () => {\n if (isRightPanelShown) {\n // If no tab is selected, default to files tab\n if (!selectedTab) {\n onTabChange(\"files\");\n }\n }\n };\n\n handlePanelVisibilityChange();\n }, [isRightPanelShown, selectedTab, onTabChange]);\n\n const { t, i18n } = useTranslation(\"openhands\");\n\n // `files` is intentionally the leftmost tab — it's the primary entry\n // point for inspecting agent output (workspace files + git diff).\n const tabs = [\n {\n tabValue: \"files\",\n isActive: isTabActive(\"files\"),\n icon: DocumentIcon,\n onClick: () => selectTab(\"files\"),\n tooltipContent: t(I18nKey.COMMON$FILES),\n tooltipAriaLabel: t(I18nKey.COMMON$FILES),\n label: t(I18nKey.COMMON$FILES),\n },\n {\n tabValue: \"planner\",\n isActive: isTabActive(\"planner\"),\n icon: LessonPlanIcon,\n onClick: () => selectTab(\"planner\"),\n tooltipContent: t(I18nKey.COMMON$PLANNER),\n tooltipAriaLabel: t(I18nKey.COMMON$PLANNER),\n label: t(I18nKey.COMMON$PLANNER),\n },\n {\n tabValue: \"vscode\",\n isActive: isTabActive(\"vscode\"),\n icon: VSCodeIcon,\n onClick: () => selectTab(\"vscode\"),\n tooltipContent: <VSCodeTooltipContent />,\n tooltipAriaLabel: t(I18nKey.COMMON$CODE),\n label: t(I18nKey.COMMON$CODE),\n },\n {\n tabValue: \"terminal\",\n isActive: isTabActive(\"terminal\"),\n icon: TerminalIcon,\n onClick: () => selectTab(\"terminal\"),\n tooltipContent: t(I18nKey.COMMON$TERMINAL),\n tooltipAriaLabel: t(I18nKey.COMMON$TERMINAL),\n label: t(I18nKey.COMMON$TERMINAL),\n className: \"pl-2\",\n },\n {\n tabValue: \"browser\",\n isActive: isTabActive(\"browser\"),\n icon: GlobeIcon,\n onClick: () => selectTab(\"browser\"),\n tooltipContent: t(I18nKey.COMMON$BROWSER),\n tooltipAriaLabel: t(I18nKey.COMMON$BROWSER),\n label: t(I18nKey.COMMON$BROWSER),\n },\n ];\n\n if (hasTaskList) {\n // Insert after `files` so the leftmost slot stays Files.\n tabs.splice(1, 0, {\n tabValue: \"tasklist\",\n isActive: isTabActive(\"tasklist\"),\n icon: DoubleCheckIcon,\n onClick: () => selectTab(\"tasklist\"),\n tooltipContent: t(I18nKey.COMMON$TASK_LIST),\n tooltipAriaLabel: t(I18nKey.COMMON$TASK_LIST),\n label: t(I18nKey.COMMON$TASK_LIST),\n });\n }\n\n // Pinned tabs always show in the bar. Unpinned tabs stay hidden unless the\n // user has that tab selected — then it appears while active so the bar\n // matches the open panel. Hide VS Code and Planner on local backends —\n // both are cloud-only (the planning agent isn't supported locally).\n const visibleTabs = tabs.filter((tab) => {\n if (tab.tabValue === \"vscode\" && backend.kind !== \"cloud\") return false;\n if (tab.tabValue === \"planner\" && backend.kind !== \"cloud\") return false;\n if (!persistedState.unpinnedTabs.includes(tab.tabValue)) return true;\n return selectedTab === tab.tabValue;\n });\n\n const unpinnedSignature = persistedState.unpinnedTabs.join(\",\");\n\n const isAgentRunning =\n curAgentState === AgentState.RUNNING ||\n curAgentState === AgentState.LOADING;\n const isBuildDisabled = isAgentRunning || !planContent;\n\n const tabsRowInnerRef = useRef<HTMLDivElement>(null);\n const measureRowRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLButtonElement>(null);\n const [inlineTabCount, setInlineTabCount] = useState(visibleTabs.length);\n\n useLayoutEffect(() => {\n const rowInner = tabsRowInnerRef.current;\n const measureRow = measureRowRef.current;\n const menuEl = menuRef.current;\n if (!rowInner || !measureRow || !menuEl) return undefined;\n\n const measure = () => {\n const measureButtons = measureRow.querySelectorAll<HTMLButtonElement>(\n '[data-tab-measure=\"true\"]',\n );\n const tabCount = measureButtons.length;\n\n const rowWidth = rowInner.getBoundingClientRect().width;\n if (rowWidth === 0) {\n setInlineTabCount(tabCount);\n return;\n }\n\n const widths = Array.from(measureButtons).map(\n (button) => button.getBoundingClientRect().width,\n );\n\n if (widths.length !== tabCount || tabCount === 0) {\n setInlineTabCount(Math.max(0, tabCount));\n return;\n }\n\n const menuWidth = menuEl.getBoundingClientRect().width;\n const gapCss =\n getComputedStyle(rowInner).columnGap || getComputedStyle(rowInner).gap;\n const gapPx = parseFloat(gapCss) || 6;\n\n let nextCount = 0;\n for (let k = tabCount; k >= 0; k -= 1) {\n let total = menuWidth;\n for (let i = 0; i < k; i += 1) {\n total += widths[i] ?? 0;\n }\n if (k > 0) {\n total += k * gapPx;\n }\n if (total <= rowWidth + 0.5) {\n nextCount = k;\n break;\n }\n }\n\n setInlineTabCount((prev) => (prev === nextCount ? prev : nextCount));\n };\n\n measure();\n if (typeof ResizeObserver === \"undefined\") return undefined;\n const ro = new ResizeObserver(measure);\n ro.observe(rowInner);\n return () => ro.disconnect();\n }, [\n unpinnedSignature,\n visibleTabs.length,\n hasTaskList,\n backend.kind,\n selectedTab,\n isRightPanelShown,\n i18n.language,\n ]);\n\n const safeInlineTabCount = Math.min(inlineTabCount, visibleTabs.length);\n\n return (\n <>\n <div\n className={cn(\n \"relative w-full min-w-0\",\n variant === \"compact\"\n ? \"flex h-full min-h-0 items-center py-0 pl-0 pr-1\"\n : \"min-h-10 p-1\",\n )}\n >\n <div\n ref={measureRowRef}\n aria-hidden\n className=\"pointer-events-none absolute top-0 left-[-10000px] flex flex-nowrap items-center gap-1.5\"\n >\n {visibleTabs.map(\n (\n {\n tabValue,\n icon,\n isActive,\n tooltipContent,\n tooltipAriaLabel,\n label,\n className: tabClassName,\n },\n index,\n ) => (\n <ChatActionTooltip\n key={`measure-${tabValue}-${index}`}\n tooltip={tooltipContent}\n ariaLabel={tooltipAriaLabel}\n >\n <ConversationTabNav\n tabValue={tabValue}\n icon={icon}\n onClick={() => {}}\n isActive={isActive}\n label={label}\n className={cn(tabClassName, \"shrink-0\")}\n measureOnly\n />\n </ChatActionTooltip>\n ),\n )}\n </div>\n <div\n ref={tabsRowInnerRef}\n className=\"flex w-full min-w-0 flex-nowrap items-center justify-start\"\n >\n <div className=\"flex w-fit max-w-full min-w-0 flex-nowrap items-center gap-1.5\">\n <div className=\"flex min-w-0 flex-1 flex-nowrap items-center gap-1.5 overflow-x-hidden\">\n {visibleTabs\n .slice(0, safeInlineTabCount)\n .map(\n (\n {\n tabValue,\n icon,\n onClick,\n isActive,\n tooltipContent,\n tooltipAriaLabel,\n label,\n className: tabClassName,\n },\n index,\n ) => (\n <ChatActionTooltip\n key={`${tabValue}-${index}`}\n tooltip={tooltipContent}\n ariaLabel={tooltipAriaLabel}\n >\n <ConversationTabNav\n tabValue={tabValue}\n icon={icon}\n onClick={onClick}\n isActive={isActive}\n label={label}\n className={cn(tabClassName, \"shrink-0\")}\n />\n </ChatActionTooltip>\n ),\n )}\n </div>\n <div ref={menuRef} className=\"relative shrink-0\">\n <EllipsisButton\n ref={anchorRef}\n onClick={() => setIsMenuOpen(!isMenuOpen)}\n ariaLabel={t(I18nKey.COMMON$MORE_OPTIONS)}\n iconClassName={\n variant === \"compact\" ? mobileTopBarIconClassName : undefined\n }\n />\n <ConversationTabsContextMenu\n isOpen={isMenuOpen}\n onClose={() => setIsMenuOpen(false)}\n ignoreOutsideClickRef={anchorRef}\n />\n </div>\n </div>\n </div>\n </div>\n {isTabActive(\"planner\") && (\n <div\n className={cn(\n \"flex h-10 min-h-10 shrink-0 items-center border-t border-[var(--oh-border)] pl-[10px] pr-1\",\n )}\n >\n <button\n type=\"button\"\n onClick={handleBuildPlanClick}\n disabled={isBuildDisabled}\n className={cn(\n \"flex h-5 min-w-17 items-center justify-center rounded bg-white px-2 transition-opacity\",\n isBuildDisabled\n ? \"cursor-not-allowed opacity-50\"\n : \"cursor-pointer hover:opacity-90\",\n )}\n data-testid=\"planner-tab-build-button\"\n >\n <Typography.Text className=\"text-[11px] font-normal leading-5 text-black\">\n {/* eslint-disable-next-line i18next/no-literal-string */}\n {t(I18nKey.COMMON$BUILD)} ⌘↩\n </Typography.Text>\n </button>\n </div>\n )}\n </>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../types/agent-state.cjs`),r=require(`../../../api/agent-server-config.cjs`),i=require(`../../../hooks/use-agent-state.cjs`),a=require(`../../../hooks/query/use-skills.cjs`),o=require(`../../shared/modals/modal-backdrop.cjs`),s=require(`../../shared/modals/modal-body.cjs`),c=require(`../../../utils/skill-scope.cjs`),l=require(`./skills-modal-header.cjs`),u=require(`./skills-modal-section.cjs`),d=require(`./skills-runtime-waiting-state.cjs`),f=require(`./skills-loading-state.cjs`),p=require(`./skills-empty-state.cjs`),m=require(`./skill-item.cjs`);let h=require(`react`),g=require(`react/jsx-runtime`);var _={project:t.I18nKey.SKILLS_MODAL$SECTION_PROJECT,personal:t.I18nKey.SKILLS_MODAL$SECTION_USER,public:t.I18nKey.SKILLS_MODAL$SECTION_PUBLIC};function v({onClose:t}){let{t:v}=e.useTranslation(`openhands`),{curAgentState:y}=i.useAgentState(),b=r.getAgentServerWorkingDir(),[x,S]=(0,h.useState)({}),{data:C,isLoading:w,isError:T,refetch:E,isRefetching:D}=a.useSkills(),O=(0,h.useMemo)(()=>C?c.groupSkillsByScope(C,b):null,[C,b]),k=e=>{S(t=>({...t,[e]:!t[e]}))},A=![n.AgentState.LOADING,n.AgentState.INIT].includes(y);return(0,g.jsx)(o.ModalBackdrop,{onClose:t,children:(0,g.jsxs)(s.ModalBody,{width:`lg`,className:`relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]`,testID:`skills-modal`,children:[(0,g.jsx)(l.SkillsModalHeader,{isLoading:w,isRefetching:D,onRefresh:E,onClose:t}),(0,g.jsx)(`div`,{className:`w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always`,children:A?w?(0,g.jsx)(f.SkillsLoadingState,{}):T||!C||C.length===0?(0,g.jsx)(p.SkillsEmptyState,{isError:T}):O&&(0,g.jsx)(`div`,{className:`divide-y divide-[var(--oh-border)]`,children:c.SKILL_SCOPE_ORDER.map(e=>{let t=O[e];return t.length===0?null:(0,g.jsx)(u.SkillsModalSection,{title:v(_[e]),count:t.length,children:t.map(t=>(0,g.jsx)(m.SkillItem,{skill:t,isExpanded:x[t.name]||!1,onToggle:k},`${e}-${t.name}`))},e)})}):(0,g.jsx)(d.SkillsRuntimeWaitingState,{})})]})})}exports.SkillsModal=v;
1
+ require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../types/agent-state.cjs`),r=require(`../../../api/agent-server-config.cjs`),i=require(`../../../hooks/use-agent-state.cjs`),a=require(`../../../hooks/query/use-conversation-skills.cjs`),o=require(`../../shared/modals/modal-backdrop.cjs`),s=require(`../../shared/modals/modal-body.cjs`),c=require(`../../../utils/skill-scope.cjs`),l=require(`./skills-modal-header.cjs`),u=require(`./skills-modal-section.cjs`),d=require(`./skills-runtime-waiting-state.cjs`),f=require(`./skills-loading-state.cjs`),p=require(`./skills-empty-state.cjs`),m=require(`./skill-item.cjs`);let h=require(`react`),g=require(`react/jsx-runtime`);var _={project:t.I18nKey.SKILLS_MODAL$SECTION_PROJECT,personal:t.I18nKey.SKILLS_MODAL$SECTION_USER,public:t.I18nKey.SKILLS_MODAL$SECTION_PUBLIC};function v({onClose:t}){let{t:v}=e.useTranslation(`openhands`),{curAgentState:y}=i.useAgentState(),b=r.getAgentServerWorkingDir(),[x,S]=(0,h.useState)({}),{data:C,isLoading:w,isError:T,refetch:E,isRefetching:D}=a.useConversationSkills(),O=(0,h.useMemo)(()=>C?c.groupSkillsByScope(C,b):null,[C,b]),k=e=>{S(t=>({...t,[e]:!t[e]}))},A=![n.AgentState.LOADING,n.AgentState.INIT].includes(y);return(0,g.jsx)(o.ModalBackdrop,{onClose:t,children:(0,g.jsxs)(s.ModalBody,{width:`lg`,className:`relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]`,testID:`skills-modal`,children:[(0,g.jsx)(l.SkillsModalHeader,{isLoading:w,isRefetching:D,onRefresh:E,onClose:t}),(0,g.jsx)(`div`,{className:`w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always`,children:A?w?(0,g.jsx)(f.SkillsLoadingState,{}):T||!C||C.length===0?(0,g.jsx)(p.SkillsEmptyState,{isError:T}):O&&(0,g.jsx)(`div`,{className:`divide-y divide-[var(--oh-border)]`,children:c.SKILL_SCOPE_ORDER.map(e=>{let t=O[e];return t.length===0?null:(0,g.jsx)(u.SkillsModalSection,{title:v(_[e]),count:t.length,children:t.map(t=>(0,g.jsx)(m.SkillItem,{skill:t,isExpanded:x[t.name]||!1,onToggle:k},`${e}-${t.name}`))},e)})}):(0,g.jsx)(d.SkillsRuntimeWaitingState,{})})]})})}exports.SkillsModal=v;
2
2
  //# sourceMappingURL=skills-modal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"skills-modal.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useSkills } from \"#/hooks/query/use-skills\";\nimport { AgentState } from \"#/types/agent-state\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsRuntimeWaitingState } from \"./skills-runtime-waiting-state\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { curAgentState } = useAgentState();\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n const isAgentReady = ![AgentState.LOADING, AgentState.INIT].includes(\n curAgentState,\n );\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {!isAgentReady ? (\n <SkillsRuntimeWaitingState />\n ) : isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":"gyBAyBA,IAAM,EAAiD,CACrD,QAAS,EAAA,QAAQ,6BACjB,SAAU,EAAA,QAAQ,0BAClB,OAAQ,EAAA,QAAQ,4BACjB,CAED,SAAgB,EAAY,CAAE,WAA6B,CACzD,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAE,iBAAkB,EAAA,eAAe,CACnC,EAAa,EAAA,0BAA0B,CACvC,CAAC,EAAgB,IAAA,EAAA,EAAA,UACrB,EAAE,CACH,CACK,CACJ,KAAM,EACN,YACA,UACA,UACA,gBACE,EAAA,WAAW,CAET,GAAA,EAAA,EAAA,aACG,EAAS,EAAA,mBAAmB,EAAQ,EAAW,CAAG,KACzD,CAAC,EAAQ,EAAW,CACrB,CAEK,EAAe,GAAsB,CACzC,EAAmB,IAAU,CAC3B,GAAG,GACF,GAAY,CAAC,EAAK,GACpB,EAAE,EAGC,EAAe,CAAC,CAAC,EAAA,WAAW,QAAS,EAAA,WAAW,KAAK,CAAC,SAC1D,EACD,CAED,OACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAAwB,oBACtB,EAAA,EAAA,MAAC,EAAA,UAAD,CACE,MAAM,KACN,UAAU,mFACV,OAAO,wBAHT,EAKE,EAAA,EAAA,KAAC,EAAA,kBAAD,CACa,YACG,eACd,UAAW,EACF,UACT,CAAA,EAEF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+HACX,EAEE,GACF,EAAA,EAAA,KAAC,EAAA,mBAAD,EAAsB,CAAA,CACpB,GAAW,CAAC,GAAU,EAAO,SAAW,GAC1C,EAAA,EAAA,KAAC,EAAA,iBAAD,CAA2B,UAAW,CAAA,CAEtC,IACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8CACZ,EAAA,kBAAkB,IAAK,GAAU,CAChC,IAAM,EAAe,EAAc,GAKnC,OAJI,EAAa,SAAW,EACnB,MAIP,EAAA,EAAA,KAAC,EAAA,mBAAD,CAEE,MAAO,EAAE,EAAkB,GAAO,CAClC,MAAO,EAAa,gBAEnB,EAAa,IAAK,IAIf,EAAA,EAAA,KAAC,EAAA,UAAD,CAES,QACK,WANG,EAAe,EAAM,OAAS,GAO7C,SAAU,EACV,CAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ,CACiB,CAhBd,EAgBc,EAEvB,CACE,CAAA,EAnCR,EAAA,EAAA,KAAC,EAAA,0BAAD,EAA6B,CAAA,CAsC3B,CAAA,CACI,GACE,CAAA"}
1
+ {"version":3,"file":"skills-modal.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport { AgentState } from \"#/types/agent-state\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsRuntimeWaitingState } from \"./skills-runtime-waiting-state\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { curAgentState } = useAgentState();\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n // Scope the catalog to this conversation's attached workspace so the listed\n // skills match the project skills actually loaded into the conversation.\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useConversationSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n const isAgentReady = ![AgentState.LOADING, AgentState.INIT].includes(\n curAgentState,\n );\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {!isAgentReady ? (\n <SkillsRuntimeWaitingState />\n ) : isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":"6yBAyBA,IAAM,EAAiD,CACrD,QAAS,EAAA,QAAQ,6BACjB,SAAU,EAAA,QAAQ,0BAClB,OAAQ,EAAA,QAAQ,4BACjB,CAED,SAAgB,EAAY,CAAE,WAA6B,CACzD,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAE,iBAAkB,EAAA,eAAe,CACnC,EAAa,EAAA,0BAA0B,CACvC,CAAC,EAAgB,IAAA,EAAA,EAAA,UACrB,EAAE,CACH,CAGK,CACJ,KAAM,EACN,YACA,UACA,UACA,gBACE,EAAA,uBAAuB,CAErB,GAAA,EAAA,EAAA,aACG,EAAS,EAAA,mBAAmB,EAAQ,EAAW,CAAG,KACzD,CAAC,EAAQ,EAAW,CACrB,CAEK,EAAe,GAAsB,CACzC,EAAmB,IAAU,CAC3B,GAAG,GACF,GAAY,CAAC,EAAK,GACpB,EAAE,EAGC,EAAe,CAAC,CAAC,EAAA,WAAW,QAAS,EAAA,WAAW,KAAK,CAAC,SAC1D,EACD,CAED,OACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAAwB,oBACtB,EAAA,EAAA,MAAC,EAAA,UAAD,CACE,MAAM,KACN,UAAU,mFACV,OAAO,wBAHT,EAKE,EAAA,EAAA,KAAC,EAAA,kBAAD,CACa,YACG,eACd,UAAW,EACF,UACT,CAAA,EAEF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+HACX,EAEE,GACF,EAAA,EAAA,KAAC,EAAA,mBAAD,EAAsB,CAAA,CACpB,GAAW,CAAC,GAAU,EAAO,SAAW,GAC1C,EAAA,EAAA,KAAC,EAAA,iBAAD,CAA2B,UAAW,CAAA,CAEtC,IACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8CACZ,EAAA,kBAAkB,IAAK,GAAU,CAChC,IAAM,EAAe,EAAc,GAKnC,OAJI,EAAa,SAAW,EACnB,MAIP,EAAA,EAAA,KAAC,EAAA,mBAAD,CAEE,MAAO,EAAE,EAAkB,GAAO,CAClC,MAAO,EAAa,gBAEnB,EAAa,IAAK,IAIf,EAAA,EAAA,KAAC,EAAA,UAAD,CAES,QACK,WANG,EAAe,EAAM,OAAS,GAO7C,SAAU,EACV,CAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ,CACiB,CAhBd,EAgBc,EAEvB,CACE,CAAA,EAnCR,EAAA,EAAA,KAAC,EAAA,0BAAD,EAA6B,CAAA,CAsC3B,CAAA,CACI,GACE,CAAA"}
@@ -3,7 +3,7 @@ import { I18nKey as t } from "../../../i18n/declaration.js";
3
3
  import { AgentState as n } from "../../../types/agent-state.js";
4
4
  import { getAgentServerWorkingDir as r } from "../../../api/agent-server-config.js";
5
5
  import { useAgentState as i } from "../../../hooks/use-agent-state.js";
6
- import { useSkills as a } from "../../../hooks/query/use-skills.js";
6
+ import { useConversationSkills as a } from "../../../hooks/query/use-conversation-skills.js";
7
7
  import { ModalBackdrop as o } from "../../shared/modals/modal-backdrop.js";
8
8
  import { ModalBody as s } from "../../shared/modals/modal-body.js";
9
9
  import { SKILL_SCOPE_ORDER as c, groupSkillsByScope as l } from "../../../utils/skill-scope.js";
@@ -1 +1 @@
1
- {"version":3,"file":"skills-modal.js","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useSkills } from \"#/hooks/query/use-skills\";\nimport { AgentState } from \"#/types/agent-state\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsRuntimeWaitingState } from \"./skills-runtime-waiting-state\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { curAgentState } = useAgentState();\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n const isAgentReady = ![AgentState.LOADING, AgentState.INIT].includes(\n curAgentState,\n );\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {!isAgentReady ? (\n <SkillsRuntimeWaitingState />\n ) : isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,IAAM,IAAiD;CACrD,SAAS,EAAQ;CACjB,UAAU,EAAQ;CAClB,QAAQ,EAAQ;CACjB;AAED,SAAgB,EAAY,EAAE,cAA6B;CACzD,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,qBAAkB,GAAe,EACnC,IAAa,GAA0B,EACvC,CAAC,GAAgB,KAAqB,EAC1C,EAAE,CACH,EACK,EACJ,MAAM,GACN,cACA,YACA,YACA,oBACE,GAAW,EAET,IAAgB,QACb,IAAS,EAAmB,GAAQ,EAAW,GAAG,MACzD,CAAC,GAAQ,EAAW,CACrB,EAEK,KAAe,MAAsB;AACzC,KAAmB,OAAU;GAC3B,GAAG;IACF,IAAY,CAAC,EAAK;GACpB,EAAE;IAGC,IAAe,CAAC,CAAC,EAAW,SAAS,EAAW,KAAK,CAAC,SAC1D,EACD;AAED,QACE,kBAAC,GAAD;EAAwB;YACtB,kBAAC,GAAD;GACE,OAAM;GACN,WAAU;GACV,QAAO;aAHT,CAKE,kBAAC,GAAD;IACa;IACG;IACd,WAAW;IACF;IACT,CAAA,EAEF,kBAAC,OAAD;IAAK,WAAU;cACX,IAEE,IACF,kBAAC,GAAD,EAAsB,CAAA,GACpB,KAAW,CAAC,KAAU,EAAO,WAAW,IAC1C,kBAAC,GAAD,EAA2B,YAAW,CAAA,GAEtC,KACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAkB,KAAK,MAAU;MAChC,IAAM,IAAe,EAAc;AAKnC,aAJI,EAAa,WAAW,IACnB,OAIP,kBAAC,GAAD;OAEE,OAAO,EAAE,EAAkB,GAAO;OAClC,OAAO,EAAa;iBAEnB,EAAa,KAAK,MAIf,kBAAC,GAAD;QAES;QACK,YANG,EAAe,EAAM,SAAS;QAO7C,UAAU;QACV,EAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ;OACiB,EAhBd,EAgBc;OAEvB;KACE,CAAA,GAnCR,kBAAC,GAAD,EAA6B,CAAA;IAsC3B,CAAA,CACI;;EACE,CAAA"}
1
+ {"version":3,"file":"skills-modal.js","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport { AgentState } from \"#/types/agent-state\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsRuntimeWaitingState } from \"./skills-runtime-waiting-state\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { curAgentState } = useAgentState();\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n // Scope the catalog to this conversation's attached workspace so the listed\n // skills match the project skills actually loaded into the conversation.\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useConversationSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n const isAgentReady = ![AgentState.LOADING, AgentState.INIT].includes(\n curAgentState,\n );\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {!isAgentReady ? (\n <SkillsRuntimeWaitingState />\n ) : isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,IAAM,IAAiD;CACrD,SAAS,EAAQ;CACjB,UAAU,EAAQ;CAClB,QAAQ,EAAQ;CACjB;AAED,SAAgB,EAAY,EAAE,cAA6B;CACzD,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,qBAAkB,GAAe,EACnC,IAAa,GAA0B,EACvC,CAAC,GAAgB,KAAqB,EAC1C,EAAE,CACH,EAGK,EACJ,MAAM,GACN,cACA,YACA,YACA,oBACE,GAAuB,EAErB,IAAgB,QACb,IAAS,EAAmB,GAAQ,EAAW,GAAG,MACzD,CAAC,GAAQ,EAAW,CACrB,EAEK,KAAe,MAAsB;AACzC,KAAmB,OAAU;GAC3B,GAAG;IACF,IAAY,CAAC,EAAK;GACpB,EAAE;IAGC,IAAe,CAAC,CAAC,EAAW,SAAS,EAAW,KAAK,CAAC,SAC1D,EACD;AAED,QACE,kBAAC,GAAD;EAAwB;YACtB,kBAAC,GAAD;GACE,OAAM;GACN,WAAU;GACV,QAAO;aAHT,CAKE,kBAAC,GAAD;IACa;IACG;IACd,WAAW;IACF;IACT,CAAA,EAEF,kBAAC,OAAD;IAAK,WAAU;cACX,IAEE,IACF,kBAAC,GAAD,EAAsB,CAAA,GACpB,KAAW,CAAC,KAAU,EAAO,WAAW,IAC1C,kBAAC,GAAD,EAA2B,YAAW,CAAA,GAEtC,KACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAkB,KAAK,MAAU;MAChC,IAAM,IAAe,EAAc;AAKnC,aAJI,EAAa,WAAW,IACnB,OAIP,kBAAC,GAAD;OAEE,OAAO,EAAE,EAAkB,GAAO;OAClC,OAAO,EAAa;iBAEnB,EAAa,KAAK,MAIf,kBAAC,GAAD;QAES;QACK,YANG,EAAe,EAAM,SAAS;QAO7C,UAAU;QACV,EAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ;OACiB,EAhBd,EAgBc;OAEvB;KACE,CAAA,GAnCR,kBAAC,GAAD,EAA6B,CAAA;IAsC3B,CAAA,CACI;;EACE,CAAA"}
@@ -1,2 +1,2 @@
1
- require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../utils/utils.cjs`),t=require(`../../node_modules/@openhands/extensions/mcps/logos.cjs`);let n=require(`react/jsx-runtime`);var r={xs:`h-4 w-4 rounded [&>svg]:h-2.5 [&>svg]:w-2.5`,sm:`h-5 w-5 rounded-md [&>svg]:h-3 [&>svg]:w-3`,md:`h-10 w-10 rounded-lg [&>svg]:h-5 [&>svg]:w-5`};function i({entry:i,size:a=`md`,className:o,fallback:s,testId:c}){return(0,n.jsx)(`span`,{"aria-hidden":`true`,title:i?.name,"data-testid":c,className:e.cn(`inline-flex shrink-0 items-center justify-center overflow-hidden`,`border border-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]`,r[a],o),style:{backgroundColor:i?.iconBg??`var(--oh-color-tertiary)`,color:i?.iconColor??`#FFFFFF`},children:i?t.MCP_LOGOS[i.id]??s??t.MCP_FALLBACK_LOGO:s??t.MCP_FALLBACK_LOGO})}exports.McpLogoBadge=i;
1
+ require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../utils/utils.cjs`),t=require(`../../node_modules/@openhands/extensions/integrations/logos.cjs`);let n=require(`react/jsx-runtime`);var r={xs:`h-4 w-4 rounded [&>svg]:h-2.5 [&>svg]:w-2.5`,sm:`h-5 w-5 rounded-md [&>svg]:h-3 [&>svg]:w-3`,md:`h-10 w-10 rounded-lg [&>svg]:h-5 [&>svg]:w-5`};function i({entry:i,size:a=`md`,className:o,fallback:s,testId:c}){return(0,n.jsx)(`span`,{"aria-hidden":`true`,title:i?.name,"data-testid":c,className:e.cn(`inline-flex shrink-0 items-center justify-center overflow-hidden`,`border border-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]`,r[a],o),style:{backgroundColor:i?.iconBg??`var(--oh-color-tertiary)`,color:i?.iconColor??`#FFFFFF`},children:i?t.INTEGRATION_LOGOS[i.id]??s??t.INTEGRATION_FALLBACK_LOGO:s??t.INTEGRATION_FALLBACK_LOGO})}exports.McpLogoBadge=i;
2
2
  //# sourceMappingURL=mcp-logo-badge.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-logo-badge.cjs","names":[],"sources":["../../../src/components/features/mcp-logo-badge.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { McpCatalogEntry } from \"@openhands/extensions/mcps\";\nimport { MCP_FALLBACK_LOGO, MCP_LOGOS } from \"@openhands/extensions/mcps/logos\";\nimport { cn } from \"#/utils/utils\";\n\ntype McpLogoEntry = Pick<\n McpCatalogEntry,\n \"id\" | \"name\" | \"iconBg\" | \"iconColor\"\n>;\n\nexport type { McpLogoEntry };\n\ninterface McpLogoBadgeProps {\n entry?: McpLogoEntry | null;\n size?: \"xs\" | \"sm\" | \"md\";\n className?: string;\n fallback?: ReactNode;\n testId?: string;\n}\n\nconst sizeClassNames = {\n xs: \"h-4 w-4 rounded [&>svg]:h-2.5 [&>svg]:w-2.5\",\n sm: \"h-5 w-5 rounded-md [&>svg]:h-3 [&>svg]:w-3\",\n md: \"h-10 w-10 rounded-lg [&>svg]:h-5 [&>svg]:w-5\",\n};\n\nexport function McpLogoBadge({\n entry,\n size = \"md\",\n className,\n fallback,\n testId,\n}: McpLogoBadgeProps) {\n return (\n <span\n aria-hidden=\"true\"\n title={entry?.name}\n data-testid={testId}\n className={cn(\n \"inline-flex shrink-0 items-center justify-center overflow-hidden\",\n \"border border-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]\",\n sizeClassNames[size],\n className,\n )}\n style={{\n backgroundColor: entry?.iconBg ?? \"var(--oh-color-tertiary)\",\n color: entry?.iconColor ?? \"#FFFFFF\",\n }}\n >\n {entry\n ? (MCP_LOGOS[entry.id] ?? fallback ?? MCP_FALLBACK_LOGO)\n : (fallback ?? MCP_FALLBACK_LOGO)}\n </span>\n );\n}\n"],"mappings":"iMAoBA,IAAM,EAAiB,CACrB,GAAI,8CACJ,GAAI,6CACJ,GAAI,+CACL,CAED,SAAgB,EAAa,CAC3B,QACA,OAAO,KACP,YACA,WACA,UACoB,CACpB,OACE,EAAA,EAAA,KAAC,OAAD,CACE,cAAY,OACZ,MAAO,GAAO,KACd,cAAa,EACb,UAAW,EAAA,GACT,mEACA,uEACA,EAAe,GACf,EACD,CACD,MAAO,CACL,gBAAiB,GAAO,QAAU,2BAClC,MAAO,GAAO,WAAa,UAC5B,UAEA,EACI,EAAA,UAAU,EAAM,KAAO,GAAY,EAAA,kBACnC,GAAY,EAAA,kBACZ,CAAA"}
1
+ {"version":3,"file":"mcp-logo-badge.cjs","names":[],"sources":["../../../src/components/features/mcp-logo-badge.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { IntegrationCatalogEntry } from \"@openhands/extensions/integrations\";\nimport {\n INTEGRATION_FALLBACK_LOGO,\n INTEGRATION_LOGOS,\n} from \"@openhands/extensions/integrations/logos\";\nimport { cn } from \"#/utils/utils\";\n\ntype McpLogoEntry = Pick<\n IntegrationCatalogEntry,\n \"id\" | \"name\" | \"iconBg\" | \"iconColor\"\n>;\n\nexport type { McpLogoEntry };\n\ninterface McpLogoBadgeProps {\n entry?: McpLogoEntry | null;\n size?: \"xs\" | \"sm\" | \"md\";\n className?: string;\n fallback?: ReactNode;\n testId?: string;\n}\n\nconst sizeClassNames = {\n xs: \"h-4 w-4 rounded [&>svg]:h-2.5 [&>svg]:w-2.5\",\n sm: \"h-5 w-5 rounded-md [&>svg]:h-3 [&>svg]:w-3\",\n md: \"h-10 w-10 rounded-lg [&>svg]:h-5 [&>svg]:w-5\",\n};\n\nexport function McpLogoBadge({\n entry,\n size = \"md\",\n className,\n fallback,\n testId,\n}: McpLogoBadgeProps) {\n return (\n <span\n aria-hidden=\"true\"\n title={entry?.name}\n data-testid={testId}\n className={cn(\n \"inline-flex shrink-0 items-center justify-center overflow-hidden\",\n \"border border-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]\",\n sizeClassNames[size],\n className,\n )}\n style={{\n backgroundColor: entry?.iconBg ?? \"var(--oh-color-tertiary)\",\n color: entry?.iconColor ?? \"#FFFFFF\",\n }}\n >\n {entry\n ? (INTEGRATION_LOGOS[entry.id] ?? fallback ?? INTEGRATION_FALLBACK_LOGO)\n : (fallback ?? INTEGRATION_FALLBACK_LOGO)}\n </span>\n );\n}\n"],"mappings":"yMAuBA,IAAM,EAAiB,CACrB,GAAI,8CACJ,GAAI,6CACJ,GAAI,+CACL,CAED,SAAgB,EAAa,CAC3B,QACA,OAAO,KACP,YACA,WACA,UACoB,CACpB,OACE,EAAA,EAAA,KAAC,OAAD,CACE,cAAY,OACZ,MAAO,GAAO,KACd,cAAa,EACb,UAAW,EAAA,GACT,mEACA,uEACA,EAAe,GACf,EACD,CACD,MAAO,CACL,gBAAiB,GAAO,QAAU,2BAClC,MAAO,GAAO,WAAa,UAC5B,UAEA,EACI,EAAA,kBAAkB,EAAM,KAAO,GAAY,EAAA,0BAC3C,GAAY,EAAA,0BACZ,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
- import type { McpCatalogEntry } from "@openhands/extensions/mcps";
3
- type McpLogoEntry = Pick<McpCatalogEntry, "id" | "name" | "iconBg" | "iconColor">;
2
+ import type { IntegrationCatalogEntry } from "@openhands/extensions/integrations";
3
+ type McpLogoEntry = Pick<IntegrationCatalogEntry, "id" | "name" | "iconBg" | "iconColor">;
4
4
  export type { McpLogoEntry };
5
5
  interface McpLogoBadgeProps {
6
6
  entry?: McpLogoEntry | null;
@@ -1,5 +1,5 @@
1
1
  import { cn as e } from "../../utils/utils.js";
2
- import { MCP_FALLBACK_LOGO as t, MCP_LOGOS as n } from "../../node_modules/@openhands/extensions/mcps/logos.js";
2
+ import { INTEGRATION_FALLBACK_LOGO as t, INTEGRATION_LOGOS as n } from "../../node_modules/@openhands/extensions/integrations/logos.js";
3
3
  import { jsx as r } from "react/jsx-runtime";
4
4
  //#region src/components/features/mcp-logo-badge.tsx
5
5
  var i = {
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-logo-badge.js","names":[],"sources":["../../../src/components/features/mcp-logo-badge.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { McpCatalogEntry } from \"@openhands/extensions/mcps\";\nimport { MCP_FALLBACK_LOGO, MCP_LOGOS } from \"@openhands/extensions/mcps/logos\";\nimport { cn } from \"#/utils/utils\";\n\ntype McpLogoEntry = Pick<\n McpCatalogEntry,\n \"id\" | \"name\" | \"iconBg\" | \"iconColor\"\n>;\n\nexport type { McpLogoEntry };\n\ninterface McpLogoBadgeProps {\n entry?: McpLogoEntry | null;\n size?: \"xs\" | \"sm\" | \"md\";\n className?: string;\n fallback?: ReactNode;\n testId?: string;\n}\n\nconst sizeClassNames = {\n xs: \"h-4 w-4 rounded [&>svg]:h-2.5 [&>svg]:w-2.5\",\n sm: \"h-5 w-5 rounded-md [&>svg]:h-3 [&>svg]:w-3\",\n md: \"h-10 w-10 rounded-lg [&>svg]:h-5 [&>svg]:w-5\",\n};\n\nexport function McpLogoBadge({\n entry,\n size = \"md\",\n className,\n fallback,\n testId,\n}: McpLogoBadgeProps) {\n return (\n <span\n aria-hidden=\"true\"\n title={entry?.name}\n data-testid={testId}\n className={cn(\n \"inline-flex shrink-0 items-center justify-center overflow-hidden\",\n \"border border-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]\",\n sizeClassNames[size],\n className,\n )}\n style={{\n backgroundColor: entry?.iconBg ?? \"var(--oh-color-tertiary)\",\n color: entry?.iconColor ?? \"#FFFFFF\",\n }}\n >\n {entry\n ? (MCP_LOGOS[entry.id] ?? fallback ?? MCP_FALLBACK_LOGO)\n : (fallback ?? MCP_FALLBACK_LOGO)}\n </span>\n );\n}\n"],"mappings":";;;;AAoBA,IAAM,IAAiB;CACrB,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAED,SAAgB,EAAa,EAC3B,UACA,UAAO,MACP,cACA,aACA,aACoB;AACpB,QACE,kBAAC,QAAD;EACE,eAAY;EACZ,OAAO,GAAO;EACd,eAAa;EACb,WAAW,EACT,oEACA,wEACA,EAAe,IACf,EACD;EACD,OAAO;GACL,iBAAiB,GAAO,UAAU;GAClC,OAAO,GAAO,aAAa;GAC5B;YAEA,IACI,EAAU,EAAM,OAAO,KAAY,IACnC,KAAY;EACZ,CAAA"}
1
+ {"version":3,"file":"mcp-logo-badge.js","names":[],"sources":["../../../src/components/features/mcp-logo-badge.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { IntegrationCatalogEntry } from \"@openhands/extensions/integrations\";\nimport {\n INTEGRATION_FALLBACK_LOGO,\n INTEGRATION_LOGOS,\n} from \"@openhands/extensions/integrations/logos\";\nimport { cn } from \"#/utils/utils\";\n\ntype McpLogoEntry = Pick<\n IntegrationCatalogEntry,\n \"id\" | \"name\" | \"iconBg\" | \"iconColor\"\n>;\n\nexport type { McpLogoEntry };\n\ninterface McpLogoBadgeProps {\n entry?: McpLogoEntry | null;\n size?: \"xs\" | \"sm\" | \"md\";\n className?: string;\n fallback?: ReactNode;\n testId?: string;\n}\n\nconst sizeClassNames = {\n xs: \"h-4 w-4 rounded [&>svg]:h-2.5 [&>svg]:w-2.5\",\n sm: \"h-5 w-5 rounded-md [&>svg]:h-3 [&>svg]:w-3\",\n md: \"h-10 w-10 rounded-lg [&>svg]:h-5 [&>svg]:w-5\",\n};\n\nexport function McpLogoBadge({\n entry,\n size = \"md\",\n className,\n fallback,\n testId,\n}: McpLogoBadgeProps) {\n return (\n <span\n aria-hidden=\"true\"\n title={entry?.name}\n data-testid={testId}\n className={cn(\n \"inline-flex shrink-0 items-center justify-center overflow-hidden\",\n \"border border-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]\",\n sizeClassNames[size],\n className,\n )}\n style={{\n backgroundColor: entry?.iconBg ?? \"var(--oh-color-tertiary)\",\n color: entry?.iconColor ?? \"#FFFFFF\",\n }}\n >\n {entry\n ? (INTEGRATION_LOGOS[entry.id] ?? fallback ?? INTEGRATION_FALLBACK_LOGO)\n : (fallback ?? INTEGRATION_FALLBACK_LOGO)}\n </span>\n );\n}\n"],"mappings":";;;;AAuBA,IAAM,IAAiB;CACrB,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAED,SAAgB,EAAa,EAC3B,UACA,UAAO,MACP,cACA,aACA,aACoB;AACpB,QACE,kBAAC,QAAD;EACE,eAAY;EACZ,OAAO,GAAO;EACd,eAAa;EACb,WAAW,EACT,oEACA,wEACA,EAAe,IACf,EACD;EACD,OAAO;GACL,iBAAiB,GAAO,UAAU;GAClC,OAAO,GAAO,aAAa;GAC5B;YAEA,IACI,EAAkB,EAAM,OAAO,KAAY,IAC3C,KAAY;EACZ,CAAA"}
@@ -1,2 +1,2 @@
1
- const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/custom-toast-handlers.cjs`),i=require(`../../shared/modals/modal-backdrop.cjs`),a=require(`../../shared/modals/modal-close-button.cjs`),o=require(`../../../utils/retrieve-axios-error-message.cjs`),s=require(`../../shared/modals/confirmation-modal.cjs`),c=require(`../../../hooks/mutation/use-delete-mcp-server.cjs`),l=require(`../../../hooks/mutation/use-add-mcp-server.cjs`),u=require(`../settings/mcp-settings/mcp-server-form.cjs`),d=require(`../../../hooks/mutation/use-update-mcp-server.cjs`);let f=require(`react`);f=e.__toESM(f,1);let p=require(`react/jsx-runtime`);function m({server:e,existingServers:m,onClose:h}){let{t:g}=t.useTranslation(`openhands`),{mutate:_,isPending:v}=l.useAddMcpServer(),{mutate:y,isPending:b}=d.useUpdateMcpServer(),{mutate:x,isPending:S}=c.useDeleteMcpServer(),[C,w]=f.default.useState(!1),T=!!e.id,E=v||b||S,D=E||C,O=e=>{r.displayErrorToast(o.retrieveAxiosErrorMessage(e)||g(n.I18nKey.ERROR$GENERIC))};return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(i.ModalBackdrop,{onClose:D?void 0:h,closeOnEscape:!D,"aria-label":g(T?n.I18nKey.MCP$EDIT_CUSTOM_TITLE:n.I18nKey.MCP$ADD_CUSTOM_TITLE),children:(0,p.jsxs)(`div`,{"data-testid":`mcp-custom-editor`,className:`relative bg-base-secondary p-6 rounded-xl border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[90vh] overflow-y-auto custom-scrollbar`,children:[(0,p.jsx)(a.ModalCloseButton,{onClose:h,testId:`mcp-custom-editor-close`,disabled:D}),(0,p.jsx)(`h2`,{className:`mb-4 pr-6 text-lg font-semibold`,children:g(T?n.I18nKey.MCP$EDIT_CUSTOM_TITLE:n.I18nKey.MCP$ADD_CUSTOM_TITLE)}),(0,p.jsx)(u.MCPServerForm,{mode:T?`edit`:`add`,server:T?e:void 0,existingServers:m,onSubmit:t=>{T?y({serverId:e.id,server:t},{onSuccess:h,onError:O}):_(t,{onSuccess:h,onError:O})},onCancel:h,onDelete:T?()=>w(!0):void 0,isActionDisabled:E})]})}),C?(0,p.jsx)(s.ConfirmationModal,{text:g(n.I18nKey.SETTINGS$MCP_CONFIRM_DELETE),onCancel:()=>w(!1),onConfirm:()=>{x(e,{onSuccess:()=>{r.displaySuccessToast(g(n.I18nKey.MCP$REMOVE_SUCCESS)),w(!1),h()},onError:e=>{O(e),w(!1)}})},isConfirming:S}):null]})}exports.CustomServerEditor=m;
1
+ const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/custom-toast-handlers.cjs`),i=require(`../../shared/modals/modal-backdrop.cjs`),a=require(`../../shared/modals/modal-close-button.cjs`),o=require(`../../../utils/retrieve-axios-error-message.cjs`),s=require(`../../shared/modals/confirmation-modal.cjs`),c=require(`../../../hooks/mutation/use-delete-mcp-server.cjs`),l=require(`../../../hooks/mutation/use-add-mcp-server.cjs`),u=require(`../../../hooks/mutation/use-test-mcp-server.cjs`),d=require(`../settings/mcp-settings/mcp-server-form.cjs`),f=require(`../../../hooks/mutation/use-update-mcp-server.cjs`);let p=require(`react`);p=e.__toESM(p,1);let m=require(`react/jsx-runtime`);function h({server:e,existingServers:h,onClose:g}){let{t:_}=t.useTranslation(`openhands`),{mutate:v,isPending:y}=l.useAddMcpServer(),{mutate:b,isPending:x}=f.useUpdateMcpServer(),{mutate:S,isPending:C}=c.useDeleteMcpServer(),{mutate:w,isPending:T,data:E,reset:D}=u.useTestMcpServer(),[O,k]=p.default.useState(!1),A=!!e.id,j=y||x||C,M=j||T||O,N=e=>{switch(e.error_kind){case`timeout`:return _(n.I18nKey.MCP$TEST_ERROR_TIMEOUT);case`connection`:return _(n.I18nKey.MCP$TEST_ERROR_CONNECTION);default:return _(n.I18nKey.MCP$TEST_ERROR_UNKNOWN,{error:e.error})}},P=p.default.useMemo(()=>E?E.ok?{ok:!0,text:_(n.I18nKey.MCP$TEST_SUCCESS,{count:E.tools.length})}:{ok:!1,text:N(E)}:null,[E,_]),F=e=>{r.displayErrorToast(o.retrieveAxiosErrorMessage(e)||_(n.I18nKey.ERROR$GENERIC))};return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(i.ModalBackdrop,{onClose:M?void 0:g,closeOnEscape:!M,"aria-label":_(A?n.I18nKey.MCP$EDIT_CUSTOM_TITLE:n.I18nKey.MCP$ADD_CUSTOM_TITLE),children:(0,m.jsxs)(`div`,{"data-testid":`mcp-custom-editor`,className:`relative bg-base-secondary p-6 rounded-xl border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[90vh] overflow-y-auto custom-scrollbar`,children:[(0,m.jsx)(a.ModalCloseButton,{onClose:g,testId:`mcp-custom-editor-close`,disabled:M}),(0,m.jsx)(`h2`,{className:`mb-4 pr-6 text-lg font-semibold`,children:_(A?n.I18nKey.MCP$EDIT_CUSTOM_TITLE:n.I18nKey.MCP$ADD_CUSTOM_TITLE)}),(0,m.jsx)(d.MCPServerForm,{mode:A?`edit`:`add`,server:A?e:void 0,existingServers:h,onSubmit:t=>{D(),w(t,{onSuccess:n=>{n.ok&&(A?b({serverId:e.id,server:t},{onSuccess:g,onError:F}):v(t,{onSuccess:g,onError:F}))},onError:F})},onCancel:g,onDelete:A?()=>k(!0):void 0,isActionDisabled:j,onTest:e=>{w(e)},isTestPending:T,testMessage:P})]})}),O?(0,m.jsx)(s.ConfirmationModal,{text:_(n.I18nKey.SETTINGS$MCP_CONFIRM_DELETE),onCancel:()=>k(!1),onConfirm:()=>{S(e,{onSuccess:()=>{r.displaySuccessToast(_(n.I18nKey.MCP$REMOVE_SUCCESS)),k(!1),g()},onError:e=>{F(e),k(!1)}})},isConfirming:C}):null]})}exports.CustomServerEditor=h;
2
2
  //# sourceMappingURL=custom-server-editor.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-server-editor.cjs","names":[],"sources":["../../../../src/components/features/mcp-page/custom-server-editor.tsx"],"sourcesContent":["import React from \"react\";\nimport { AxiosError } from \"axios\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { ConfirmationModal } from \"#/components/shared/modals/confirmation-modal\";\nimport { MCPServerForm } from \"#/components/features/settings/mcp-settings/mcp-server-form\";\nimport { useAddMcpServer } from \"#/hooks/mutation/use-add-mcp-server\";\nimport { useUpdateMcpServer } from \"#/hooks/mutation/use-update-mcp-server\";\nimport { useDeleteMcpServer } from \"#/hooks/mutation/use-delete-mcp-server\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\n\ninterface CustomServerEditorProps {\n server: MCPServerConfig;\n existingServers: MCPServerConfig[];\n onClose: () => void;\n}\n\n/**\n * Modal wrapper around `MCPServerForm` so users can hand-author\n * arbitrary stdio / SSE / SHTTP entries without reaching for raw JSON.\n * An empty `server.id` means \"Add new\".\n */\nexport function CustomServerEditor({\n server,\n existingServers,\n onClose,\n}: CustomServerEditorProps) {\n const { t } = useTranslation(\"openhands\");\n const { mutate: addMcpServer, isPending: isAdding } = useAddMcpServer();\n const { mutate: updateMcpServer, isPending: isUpdating } =\n useUpdateMcpServer();\n const { mutate: deleteMcpServer, isPending: isDeleting } =\n useDeleteMcpServer();\n const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false);\n\n const isEditing = !!server.id;\n const isPending = isAdding || isUpdating || isDeleting;\n const isDismissBlocked = isPending || showDeleteConfirm;\n\n // Shared error handler so both add and update surface backend errors\n // as a toast instead of failing silently — previously these calls\n // had no `onError` and the modal closed even on a 4xx/5xx, leaving\n // the user to discover the failure on the next page load.\n const handleError = (err: unknown) => {\n const message = retrieveAxiosErrorMessage(err as AxiosError);\n displayErrorToast(message || t(I18nKey.ERROR$GENERIC));\n };\n\n const handleSubmit = (payload: MCPServerConfig) => {\n if (isEditing) {\n updateMcpServer(\n { serverId: server.id, server: payload },\n { onSuccess: onClose, onError: handleError },\n );\n } else {\n addMcpServer(payload, { onSuccess: onClose, onError: handleError });\n }\n };\n\n const handleConfirmDelete = () => {\n deleteMcpServer(server, {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.MCP$REMOVE_SUCCESS));\n setShowDeleteConfirm(false);\n onClose();\n },\n onError: (err) => {\n handleError(err);\n setShowDeleteConfirm(false);\n },\n });\n };\n\n return (\n <>\n <ModalBackdrop\n // Block backdrop-click / Escape from dismissing the modal while\n // a mutation is in flight — closing mid-request would orphan\n // the request and leave the user with no error feedback.\n onClose={isDismissBlocked ? undefined : onClose}\n closeOnEscape={!isDismissBlocked}\n aria-label={\n isEditing\n ? t(I18nKey.MCP$EDIT_CUSTOM_TITLE)\n : t(I18nKey.MCP$ADD_CUSTOM_TITLE)\n }\n >\n <div\n data-testid=\"mcp-custom-editor\"\n className=\"relative bg-base-secondary p-6 rounded-xl border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[90vh] overflow-y-auto custom-scrollbar\"\n >\n <ModalCloseButton\n onClose={onClose}\n testId=\"mcp-custom-editor-close\"\n disabled={isDismissBlocked}\n />\n <h2 className=\"mb-4 pr-6 text-lg font-semibold\">\n {isEditing\n ? t(I18nKey.MCP$EDIT_CUSTOM_TITLE)\n : t(I18nKey.MCP$ADD_CUSTOM_TITLE)}\n </h2>\n <MCPServerForm\n mode={isEditing ? \"edit\" : \"add\"}\n server={isEditing ? server : undefined}\n existingServers={existingServers}\n onSubmit={handleSubmit}\n onCancel={onClose}\n onDelete={isEditing ? () => setShowDeleteConfirm(true) : undefined}\n isActionDisabled={isPending}\n />\n </div>\n </ModalBackdrop>\n\n {showDeleteConfirm ? (\n <ConfirmationModal\n text={t(I18nKey.SETTINGS$MCP_CONFIRM_DELETE)}\n onCancel={() => setShowDeleteConfirm(false)}\n onConfirm={handleConfirmDelete}\n isConfirming={isDeleting}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"wwBA6BA,SAAgB,EAAmB,CACjC,SACA,kBACA,WAC0B,CAC1B,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAE,OAAQ,EAAc,UAAW,GAAa,EAAA,iBAAiB,CACjE,CAAE,OAAQ,EAAiB,UAAW,GAC1C,EAAA,oBAAoB,CAChB,CAAE,OAAQ,EAAiB,UAAW,GAC1C,EAAA,oBAAoB,CAChB,CAAC,EAAmB,GAAwB,EAAA,QAAM,SAAS,GAAM,CAEjE,EAAY,CAAC,CAAC,EAAO,GACrB,EAAY,GAAY,GAAc,EACtC,EAAmB,GAAa,EAMhC,EAAe,GAAiB,CAEpC,EAAA,kBADgB,EAAA,0BAA0B,EACxB,EAAW,EAAE,EAAA,QAAQ,cAAc,CAAC,EA4BxD,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAIE,QAAS,EAAmB,IAAA,GAAY,EACxC,cAAe,CAAC,EAChB,aAEM,EADJ,EACM,EAAA,QAAQ,sBACR,EAAA,QAAQ,qBAAqB,WAGrC,EAAA,EAAA,MAAC,MAAD,CACE,cAAY,oBACZ,UAAU,2JAFZ,EAIE,EAAA,EAAA,KAAC,EAAA,iBAAD,CACW,UACT,OAAO,0BACP,SAAU,EACV,CAAA,EACF,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,2CAER,EADH,EACK,EAAA,QAAQ,sBACR,EAAA,QAAQ,qBAAqB,CAChC,CAAA,EACL,EAAA,EAAA,KAAC,EAAA,cAAD,CACE,KAAM,EAAY,OAAS,MAC3B,OAAQ,EAAY,EAAS,IAAA,GACZ,kBACjB,SAzDY,GAA6B,CAC7C,EACF,EACE,CAAE,SAAU,EAAO,GAAI,OAAQ,EAAS,CACxC,CAAE,UAAW,EAAS,QAAS,EAAa,CAC7C,CAED,EAAa,EAAS,CAAE,UAAW,EAAS,QAAS,EAAa,CAAC,EAmD7D,SAAU,EACV,SAAU,MAAkB,EAAqB,GAAK,CAAG,IAAA,GACzD,iBAAkB,EAClB,CAAA,CACE,GACQ,CAAA,CAEf,GACC,EAAA,EAAA,KAAC,EAAA,kBAAD,CACE,KAAM,EAAE,EAAA,QAAQ,4BAA4B,CAC5C,aAAgB,EAAqB,GAAM,CAC3C,cA1D0B,CAChC,EAAgB,EAAQ,CACtB,cAAiB,CACf,EAAA,oBAAoB,EAAE,EAAA,QAAQ,mBAAmB,CAAC,CAClD,EAAqB,GAAM,CAC3B,GAAS,EAEX,QAAU,GAAQ,CAChB,EAAY,EAAI,CAChB,EAAqB,GAAM,EAE9B,CAAC,EAgDI,aAAc,EACd,CAAA,CACA,KACH,CAAA,CAAA"}
1
+ {"version":3,"file":"custom-server-editor.cjs","names":[],"sources":["../../../../src/components/features/mcp-page/custom-server-editor.tsx"],"sourcesContent":["import React from \"react\";\nimport { AxiosError } from \"axios\";\nimport { useTranslation } from \"react-i18next\";\nimport type { MCPTestFailure } from \"@openhands/typescript-client\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { ConfirmationModal } from \"#/components/shared/modals/confirmation-modal\";\nimport {\n MCPServerForm,\n type TestMessage,\n} from \"#/components/features/settings/mcp-settings/mcp-server-form\";\nimport { useAddMcpServer } from \"#/hooks/mutation/use-add-mcp-server\";\nimport { useUpdateMcpServer } from \"#/hooks/mutation/use-update-mcp-server\";\nimport { useDeleteMcpServer } from \"#/hooks/mutation/use-delete-mcp-server\";\nimport { useTestMcpServer } from \"#/hooks/mutation/use-test-mcp-server\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\n\ninterface CustomServerEditorProps {\n server: MCPServerConfig;\n existingServers: MCPServerConfig[];\n onClose: () => void;\n}\n\n/**\n * Modal wrapper around `MCPServerForm` so users can hand-author\n * arbitrary stdio / SSE / SHTTP entries without reaching for raw JSON.\n * An empty `server.id` means \"Add new\".\n */\nexport function CustomServerEditor({\n server,\n existingServers,\n onClose,\n}: CustomServerEditorProps) {\n const { t } = useTranslation(\"openhands\");\n const { mutate: addMcpServer, isPending: isAdding } = useAddMcpServer();\n const { mutate: updateMcpServer, isPending: isUpdating } =\n useUpdateMcpServer();\n const { mutate: deleteMcpServer, isPending: isDeleting } =\n useDeleteMcpServer();\n const {\n mutate: testServer,\n isPending: isTesting,\n data: testResult,\n reset: resetTest,\n } = useTestMcpServer();\n const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false);\n\n const isEditing = !!server.id;\n const isPending = isAdding || isUpdating || isDeleting;\n const isDismissBlocked = isPending || isTesting || showDeleteConfirm;\n\n const makeTestErrorMessage = (failure: MCPTestFailure): string => {\n switch (failure.error_kind) {\n case \"timeout\":\n return t(I18nKey.MCP$TEST_ERROR_TIMEOUT);\n case \"connection\":\n return t(I18nKey.MCP$TEST_ERROR_CONNECTION);\n default:\n return t(I18nKey.MCP$TEST_ERROR_UNKNOWN, { error: failure.error });\n }\n };\n\n const testMessage: TestMessage | null = React.useMemo(() => {\n if (!testResult) return null;\n if (testResult.ok) {\n return {\n ok: true,\n text: t(I18nKey.MCP$TEST_SUCCESS, { count: testResult.tools.length }),\n };\n }\n return { ok: false, text: makeTestErrorMessage(testResult) };\n }, [testResult, t]);\n\n // Shared error handler so both add and update surface backend errors\n // as a toast instead of failing silently — previously these calls\n // had no `onError` and the modal closed even on a 4xx/5xx, leaving\n // the user to discover the failure on the next page load.\n const handleError = (err: unknown) => {\n const message = retrieveAxiosErrorMessage(err as AxiosError);\n displayErrorToast(message || t(I18nKey.ERROR$GENERIC));\n };\n\n const handleSubmit = (payload: MCPServerConfig) => {\n resetTest();\n testServer(payload, {\n onSuccess: (result) => {\n if (!result.ok) {\n // Test failed — modal stays open, error shown via testMessage.\n return;\n }\n if (isEditing) {\n updateMcpServer(\n { serverId: server.id, server: payload },\n { onSuccess: onClose, onError: handleError },\n );\n } else {\n addMcpServer(payload, { onSuccess: onClose, onError: handleError });\n }\n },\n onError: handleError,\n });\n };\n\n const handleTestClick = (payload: MCPServerConfig) => {\n testServer(payload);\n };\n\n const handleConfirmDelete = () => {\n deleteMcpServer(server, {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.MCP$REMOVE_SUCCESS));\n setShowDeleteConfirm(false);\n onClose();\n },\n onError: (err) => {\n handleError(err);\n setShowDeleteConfirm(false);\n },\n });\n };\n\n return (\n <>\n <ModalBackdrop\n // Block backdrop-click / Escape from dismissing the modal while\n // a mutation is in flight — closing mid-request would orphan\n // the request and leave the user with no error feedback.\n onClose={isDismissBlocked ? undefined : onClose}\n closeOnEscape={!isDismissBlocked}\n aria-label={\n isEditing\n ? t(I18nKey.MCP$EDIT_CUSTOM_TITLE)\n : t(I18nKey.MCP$ADD_CUSTOM_TITLE)\n }\n >\n <div\n data-testid=\"mcp-custom-editor\"\n className=\"relative bg-base-secondary p-6 rounded-xl border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[90vh] overflow-y-auto custom-scrollbar\"\n >\n <ModalCloseButton\n onClose={onClose}\n testId=\"mcp-custom-editor-close\"\n disabled={isDismissBlocked}\n />\n <h2 className=\"mb-4 pr-6 text-lg font-semibold\">\n {isEditing\n ? t(I18nKey.MCP$EDIT_CUSTOM_TITLE)\n : t(I18nKey.MCP$ADD_CUSTOM_TITLE)}\n </h2>\n <MCPServerForm\n mode={isEditing ? \"edit\" : \"add\"}\n server={isEditing ? server : undefined}\n existingServers={existingServers}\n onSubmit={handleSubmit}\n onCancel={onClose}\n onDelete={isEditing ? () => setShowDeleteConfirm(true) : undefined}\n isActionDisabled={isPending}\n onTest={handleTestClick}\n isTestPending={isTesting}\n testMessage={testMessage}\n />\n </div>\n </ModalBackdrop>\n\n {showDeleteConfirm ? (\n <ConfirmationModal\n text={t(I18nKey.SETTINGS$MCP_CONFIRM_DELETE)}\n onCancel={() => setShowDeleteConfirm(false)}\n onConfirm={handleConfirmDelete}\n isConfirming={isDeleting}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"q0BAkCA,SAAgB,EAAmB,CACjC,SACA,kBACA,WAC0B,CAC1B,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAE,OAAQ,EAAc,UAAW,GAAa,EAAA,iBAAiB,CACjE,CAAE,OAAQ,EAAiB,UAAW,GAC1C,EAAA,oBAAoB,CAChB,CAAE,OAAQ,EAAiB,UAAW,GAC1C,EAAA,oBAAoB,CAChB,CACJ,OAAQ,EACR,UAAW,EACX,KAAM,EACN,MAAO,GACL,EAAA,kBAAkB,CAChB,CAAC,EAAmB,GAAwB,EAAA,QAAM,SAAS,GAAM,CAEjE,EAAY,CAAC,CAAC,EAAO,GACrB,EAAY,GAAY,GAAc,EACtC,EAAmB,GAAa,GAAa,EAE7C,EAAwB,GAAoC,CAChE,OAAQ,EAAQ,WAAhB,CACE,IAAK,UACH,OAAO,EAAE,EAAA,QAAQ,uBAAuB,CAC1C,IAAK,aACH,OAAO,EAAE,EAAA,QAAQ,0BAA0B,CAC7C,QACE,OAAO,EAAE,EAAA,QAAQ,uBAAwB,CAAE,MAAO,EAAQ,MAAO,CAAC,GAIlE,EAAkC,EAAA,QAAM,YACvC,EACD,EAAW,GACN,CACL,GAAI,GACJ,KAAM,EAAE,EAAA,QAAQ,iBAAkB,CAAE,MAAO,EAAW,MAAM,OAAQ,CAAC,CACtE,CAEI,CAAE,GAAI,GAAO,KAAM,EAAqB,EAAW,CAAE,CAPpC,KAQvB,CAAC,EAAY,EAAE,CAAC,CAMb,EAAe,GAAiB,CAEpC,EAAA,kBADgB,EAAA,0BAA0B,EACxB,EAAW,EAAE,EAAA,QAAQ,cAAc,CAAC,EA0CxD,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAIE,QAAS,EAAmB,IAAA,GAAY,EACxC,cAAe,CAAC,EAChB,aAEM,EADJ,EACM,EAAA,QAAQ,sBACR,EAAA,QAAQ,qBAAqB,WAGrC,EAAA,EAAA,MAAC,MAAD,CACE,cAAY,oBACZ,UAAU,2JAFZ,EAIE,EAAA,EAAA,KAAC,EAAA,iBAAD,CACW,UACT,OAAO,0BACP,SAAU,EACV,CAAA,EACF,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,2CAER,EADH,EACK,EAAA,QAAQ,sBACR,EAAA,QAAQ,qBAAqB,CAChC,CAAA,EACL,EAAA,EAAA,KAAC,EAAA,cAAD,CACE,KAAM,EAAY,OAAS,MAC3B,OAAQ,EAAY,EAAS,IAAA,GACZ,kBACjB,SAvEY,GAA6B,CACjD,GAAW,CACX,EAAW,EAAS,CAClB,UAAY,GAAW,CAChB,EAAO,KAIR,EACF,EACE,CAAE,SAAU,EAAO,GAAI,OAAQ,EAAS,CACxC,CAAE,UAAW,EAAS,QAAS,EAAa,CAC7C,CAED,EAAa,EAAS,CAAE,UAAW,EAAS,QAAS,EAAa,CAAC,GAGvE,QAAS,EACV,CAAC,EAsDM,SAAU,EACV,SAAU,MAAkB,EAAqB,GAAK,CAAG,IAAA,GACzD,iBAAkB,EAClB,OAtDe,GAA6B,CACpD,EAAW,EAAQ,EAsDX,cAAe,EACF,cACb,CAAA,CACE,GACQ,CAAA,CAEf,GACC,EAAA,EAAA,KAAC,EAAA,kBAAD,CACE,KAAM,EAAE,EAAA,QAAQ,4BAA4B,CAC5C,aAAgB,EAAqB,GAAM,CAC3C,cA7D0B,CAChC,EAAgB,EAAQ,CACtB,cAAiB,CACf,EAAA,oBAAoB,EAAE,EAAA,QAAQ,mBAAmB,CAAC,CAClD,EAAqB,GAAM,CAC3B,GAAS,EAEX,QAAU,GAAQ,CAChB,EAAY,EAAI,CAChB,EAAqB,GAAM,EAE9B,CAAC,EAmDI,aAAc,EACd,CAAA,CACA,KACH,CAAA,CAAA"}
@@ -7,71 +7,94 @@ import { retrieveAxiosErrorMessage as o } from "../../../utils/retrieve-axios-er
7
7
  import { ConfirmationModal as s } from "../../shared/modals/confirmation-modal.js";
8
8
  import { useDeleteMcpServer as c } from "../../../hooks/mutation/use-delete-mcp-server.js";
9
9
  import { useAddMcpServer as l } from "../../../hooks/mutation/use-add-mcp-server.js";
10
- import { MCPServerForm as u } from "../settings/mcp-settings/mcp-server-form.js";
11
- import { useUpdateMcpServer as d } from "../../../hooks/mutation/use-update-mcp-server.js";
12
- import f from "react";
13
- import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
10
+ import { useTestMcpServer as u } from "../../../hooks/mutation/use-test-mcp-server.js";
11
+ import { MCPServerForm as d } from "../settings/mcp-settings/mcp-server-form.js";
12
+ import { useUpdateMcpServer as f } from "../../../hooks/mutation/use-update-mcp-server.js";
13
+ import p from "react";
14
+ import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
14
15
  //#region src/components/features/mcp-page/custom-server-editor.tsx
15
- function g({ server: g, existingServers: _, onClose: v }) {
16
- let { t: y } = e("openhands"), { mutate: b, isPending: x } = l(), { mutate: S, isPending: C } = d(), { mutate: w, isPending: T } = c(), [E, D] = f.useState(!1), O = !!g.id, k = x || C || T, A = k || E, j = (e) => {
17
- n(o(e) || y(t.ERROR$GENERIC));
16
+ function _({ server: _, existingServers: v, onClose: y }) {
17
+ let { t: b } = e("openhands"), { mutate: x, isPending: S } = l(), { mutate: C, isPending: w } = f(), { mutate: T, isPending: E } = c(), { mutate: D, isPending: O, data: k, reset: A } = u(), [j, M] = p.useState(!1), N = !!_.id, P = S || w || E, F = P || O || j, I = (e) => {
18
+ switch (e.error_kind) {
19
+ case "timeout": return b(t.MCP$TEST_ERROR_TIMEOUT);
20
+ case "connection": return b(t.MCP$TEST_ERROR_CONNECTION);
21
+ default: return b(t.MCP$TEST_ERROR_UNKNOWN, { error: e.error });
22
+ }
23
+ }, L = p.useMemo(() => k ? k.ok ? {
24
+ ok: !0,
25
+ text: b(t.MCP$TEST_SUCCESS, { count: k.tools.length })
26
+ } : {
27
+ ok: !1,
28
+ text: I(k)
29
+ } : null, [k, b]), R = (e) => {
30
+ n(o(e) || b(t.ERROR$GENERIC));
18
31
  };
19
- return /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(i, {
20
- onClose: A ? void 0 : v,
21
- closeOnEscape: !A,
22
- "aria-label": y(O ? t.MCP$EDIT_CUSTOM_TITLE : t.MCP$ADD_CUSTOM_TITLE),
23
- children: /* @__PURE__ */ h("div", {
32
+ return /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(i, {
33
+ onClose: F ? void 0 : y,
34
+ closeOnEscape: !F,
35
+ "aria-label": b(N ? t.MCP$EDIT_CUSTOM_TITLE : t.MCP$ADD_CUSTOM_TITLE),
36
+ children: /* @__PURE__ */ g("div", {
24
37
  "data-testid": "mcp-custom-editor",
25
38
  className: "relative bg-base-secondary p-6 rounded-xl border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[90vh] overflow-y-auto custom-scrollbar",
26
39
  children: [
27
- /* @__PURE__ */ m(a, {
28
- onClose: v,
40
+ /* @__PURE__ */ h(a, {
41
+ onClose: y,
29
42
  testId: "mcp-custom-editor-close",
30
- disabled: A
43
+ disabled: F
31
44
  }),
32
- /* @__PURE__ */ m("h2", {
45
+ /* @__PURE__ */ h("h2", {
33
46
  className: "mb-4 pr-6 text-lg font-semibold",
34
- children: y(O ? t.MCP$EDIT_CUSTOM_TITLE : t.MCP$ADD_CUSTOM_TITLE)
47
+ children: b(N ? t.MCP$EDIT_CUSTOM_TITLE : t.MCP$ADD_CUSTOM_TITLE)
35
48
  }),
36
- /* @__PURE__ */ m(u, {
37
- mode: O ? "edit" : "add",
38
- server: O ? g : void 0,
39
- existingServers: _,
49
+ /* @__PURE__ */ h(d, {
50
+ mode: N ? "edit" : "add",
51
+ server: N ? _ : void 0,
52
+ existingServers: v,
40
53
  onSubmit: (e) => {
41
- O ? S({
42
- serverId: g.id,
43
- server: e
44
- }, {
45
- onSuccess: v,
46
- onError: j
47
- }) : b(e, {
48
- onSuccess: v,
49
- onError: j
54
+ A(), D(e, {
55
+ onSuccess: (t) => {
56
+ t.ok && (N ? C({
57
+ serverId: _.id,
58
+ server: e
59
+ }, {
60
+ onSuccess: y,
61
+ onError: R
62
+ }) : x(e, {
63
+ onSuccess: y,
64
+ onError: R
65
+ }));
66
+ },
67
+ onError: R
50
68
  });
51
69
  },
52
- onCancel: v,
53
- onDelete: O ? () => D(!0) : void 0,
54
- isActionDisabled: k
70
+ onCancel: y,
71
+ onDelete: N ? () => M(!0) : void 0,
72
+ isActionDisabled: P,
73
+ onTest: (e) => {
74
+ D(e);
75
+ },
76
+ isTestPending: O,
77
+ testMessage: L
55
78
  })
56
79
  ]
57
80
  })
58
- }), E ? /* @__PURE__ */ m(s, {
59
- text: y(t.SETTINGS$MCP_CONFIRM_DELETE),
60
- onCancel: () => D(!1),
81
+ }), j ? /* @__PURE__ */ h(s, {
82
+ text: b(t.SETTINGS$MCP_CONFIRM_DELETE),
83
+ onCancel: () => M(!1),
61
84
  onConfirm: () => {
62
- w(g, {
85
+ T(_, {
63
86
  onSuccess: () => {
64
- r(y(t.MCP$REMOVE_SUCCESS)), D(!1), v();
87
+ r(b(t.MCP$REMOVE_SUCCESS)), M(!1), y();
65
88
  },
66
89
  onError: (e) => {
67
- j(e), D(!1);
90
+ R(e), M(!1);
68
91
  }
69
92
  });
70
93
  },
71
- isConfirming: T
94
+ isConfirming: E
72
95
  }) : null] });
73
96
  }
74
97
  //#endregion
75
- export { g as CustomServerEditor };
98
+ export { _ as CustomServerEditor };
76
99
 
77
100
  //# sourceMappingURL=custom-server-editor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-server-editor.js","names":[],"sources":["../../../../src/components/features/mcp-page/custom-server-editor.tsx"],"sourcesContent":["import React from \"react\";\nimport { AxiosError } from \"axios\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { ConfirmationModal } from \"#/components/shared/modals/confirmation-modal\";\nimport { MCPServerForm } from \"#/components/features/settings/mcp-settings/mcp-server-form\";\nimport { useAddMcpServer } from \"#/hooks/mutation/use-add-mcp-server\";\nimport { useUpdateMcpServer } from \"#/hooks/mutation/use-update-mcp-server\";\nimport { useDeleteMcpServer } from \"#/hooks/mutation/use-delete-mcp-server\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\n\ninterface CustomServerEditorProps {\n server: MCPServerConfig;\n existingServers: MCPServerConfig[];\n onClose: () => void;\n}\n\n/**\n * Modal wrapper around `MCPServerForm` so users can hand-author\n * arbitrary stdio / SSE / SHTTP entries without reaching for raw JSON.\n * An empty `server.id` means \"Add new\".\n */\nexport function CustomServerEditor({\n server,\n existingServers,\n onClose,\n}: CustomServerEditorProps) {\n const { t } = useTranslation(\"openhands\");\n const { mutate: addMcpServer, isPending: isAdding } = useAddMcpServer();\n const { mutate: updateMcpServer, isPending: isUpdating } =\n useUpdateMcpServer();\n const { mutate: deleteMcpServer, isPending: isDeleting } =\n useDeleteMcpServer();\n const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false);\n\n const isEditing = !!server.id;\n const isPending = isAdding || isUpdating || isDeleting;\n const isDismissBlocked = isPending || showDeleteConfirm;\n\n // Shared error handler so both add and update surface backend errors\n // as a toast instead of failing silently — previously these calls\n // had no `onError` and the modal closed even on a 4xx/5xx, leaving\n // the user to discover the failure on the next page load.\n const handleError = (err: unknown) => {\n const message = retrieveAxiosErrorMessage(err as AxiosError);\n displayErrorToast(message || t(I18nKey.ERROR$GENERIC));\n };\n\n const handleSubmit = (payload: MCPServerConfig) => {\n if (isEditing) {\n updateMcpServer(\n { serverId: server.id, server: payload },\n { onSuccess: onClose, onError: handleError },\n );\n } else {\n addMcpServer(payload, { onSuccess: onClose, onError: handleError });\n }\n };\n\n const handleConfirmDelete = () => {\n deleteMcpServer(server, {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.MCP$REMOVE_SUCCESS));\n setShowDeleteConfirm(false);\n onClose();\n },\n onError: (err) => {\n handleError(err);\n setShowDeleteConfirm(false);\n },\n });\n };\n\n return (\n <>\n <ModalBackdrop\n // Block backdrop-click / Escape from dismissing the modal while\n // a mutation is in flight — closing mid-request would orphan\n // the request and leave the user with no error feedback.\n onClose={isDismissBlocked ? undefined : onClose}\n closeOnEscape={!isDismissBlocked}\n aria-label={\n isEditing\n ? t(I18nKey.MCP$EDIT_CUSTOM_TITLE)\n : t(I18nKey.MCP$ADD_CUSTOM_TITLE)\n }\n >\n <div\n data-testid=\"mcp-custom-editor\"\n className=\"relative bg-base-secondary p-6 rounded-xl border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[90vh] overflow-y-auto custom-scrollbar\"\n >\n <ModalCloseButton\n onClose={onClose}\n testId=\"mcp-custom-editor-close\"\n disabled={isDismissBlocked}\n />\n <h2 className=\"mb-4 pr-6 text-lg font-semibold\">\n {isEditing\n ? t(I18nKey.MCP$EDIT_CUSTOM_TITLE)\n : t(I18nKey.MCP$ADD_CUSTOM_TITLE)}\n </h2>\n <MCPServerForm\n mode={isEditing ? \"edit\" : \"add\"}\n server={isEditing ? server : undefined}\n existingServers={existingServers}\n onSubmit={handleSubmit}\n onCancel={onClose}\n onDelete={isEditing ? () => setShowDeleteConfirm(true) : undefined}\n isActionDisabled={isPending}\n />\n </div>\n </ModalBackdrop>\n\n {showDeleteConfirm ? (\n <ConfirmationModal\n text={t(I18nKey.SETTINGS$MCP_CONFIRM_DELETE)}\n onCancel={() => setShowDeleteConfirm(false)}\n onConfirm={handleConfirmDelete}\n isConfirming={isDeleting}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AA6BA,SAAgB,EAAmB,EACjC,WACA,oBACA,cAC0B;CAC1B,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,QAAQ,GAAc,WAAW,MAAa,GAAiB,EACjE,EAAE,QAAQ,GAAiB,WAAW,MAC1C,GAAoB,EAChB,EAAE,QAAQ,GAAiB,WAAW,MAC1C,GAAoB,EAChB,CAAC,GAAmB,KAAwB,EAAM,SAAS,GAAM,EAEjE,IAAY,CAAC,CAAC,EAAO,IACrB,IAAY,KAAY,KAAc,GACtC,IAAmB,KAAa,GAMhC,KAAe,MAAiB;AAEpC,IADgB,EAA0B,EACxB,IAAW,EAAE,EAAQ,cAAc,CAAC;;AA4BxD,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EAIE,SAAS,IAAmB,KAAA,IAAY;EACxC,eAAe,CAAC;EAChB,cAEM,EADJ,IACM,EAAQ,wBACR,EAAQ,qBAAqB;YAGrC,kBAAC,OAAD;GACE,eAAY;GACZ,WAAU;aAFZ;IAIE,kBAAC,GAAD;KACW;KACT,QAAO;KACP,UAAU;KACV,CAAA;IACF,kBAAC,MAAD;KAAI,WAAU;eAER,EADH,IACK,EAAQ,wBACR,EAAQ,qBAAqB;KAChC,CAAA;IACL,kBAAC,GAAD;KACE,MAAM,IAAY,SAAS;KAC3B,QAAQ,IAAY,IAAS,KAAA;KACZ;KACjB,WAzDY,MAA6B;AACjD,MAAI,IACF,EACE;OAAE,UAAU,EAAO;OAAI,QAAQ;OAAS,EACxC;OAAE,WAAW;OAAS,SAAS;OAAa,CAC7C,GAED,EAAa,GAAS;OAAE,WAAW;OAAS,SAAS;OAAa,CAAC;;KAmD7D,UAAU;KACV,UAAU,UAAkB,EAAqB,GAAK,GAAG,KAAA;KACzD,kBAAkB;KAClB,CAAA;IACE;;EACQ,CAAA,EAEf,IACC,kBAAC,GAAD;EACE,MAAM,EAAE,EAAQ,4BAA4B;EAC5C,gBAAgB,EAAqB,GAAM;EAC3C,iBA1D0B;AAChC,KAAgB,GAAQ;IACtB,iBAAiB;AAGf,KAFA,EAAoB,EAAE,EAAQ,mBAAmB,CAAC,EAClD,EAAqB,GAAM,EAC3B,GAAS;;IAEX,UAAU,MAAQ;AAEhB,KADA,EAAY,EAAI,EAChB,EAAqB,GAAM;;IAE9B,CAAC;;EAgDI,cAAc;EACd,CAAA,GACA,KACH,EAAA,CAAA"}
1
+ {"version":3,"file":"custom-server-editor.js","names":[],"sources":["../../../../src/components/features/mcp-page/custom-server-editor.tsx"],"sourcesContent":["import React from \"react\";\nimport { AxiosError } from \"axios\";\nimport { useTranslation } from \"react-i18next\";\nimport type { MCPTestFailure } from \"@openhands/typescript-client\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { ConfirmationModal } from \"#/components/shared/modals/confirmation-modal\";\nimport {\n MCPServerForm,\n type TestMessage,\n} from \"#/components/features/settings/mcp-settings/mcp-server-form\";\nimport { useAddMcpServer } from \"#/hooks/mutation/use-add-mcp-server\";\nimport { useUpdateMcpServer } from \"#/hooks/mutation/use-update-mcp-server\";\nimport { useDeleteMcpServer } from \"#/hooks/mutation/use-delete-mcp-server\";\nimport { useTestMcpServer } from \"#/hooks/mutation/use-test-mcp-server\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\n\ninterface CustomServerEditorProps {\n server: MCPServerConfig;\n existingServers: MCPServerConfig[];\n onClose: () => void;\n}\n\n/**\n * Modal wrapper around `MCPServerForm` so users can hand-author\n * arbitrary stdio / SSE / SHTTP entries without reaching for raw JSON.\n * An empty `server.id` means \"Add new\".\n */\nexport function CustomServerEditor({\n server,\n existingServers,\n onClose,\n}: CustomServerEditorProps) {\n const { t } = useTranslation(\"openhands\");\n const { mutate: addMcpServer, isPending: isAdding } = useAddMcpServer();\n const { mutate: updateMcpServer, isPending: isUpdating } =\n useUpdateMcpServer();\n const { mutate: deleteMcpServer, isPending: isDeleting } =\n useDeleteMcpServer();\n const {\n mutate: testServer,\n isPending: isTesting,\n data: testResult,\n reset: resetTest,\n } = useTestMcpServer();\n const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false);\n\n const isEditing = !!server.id;\n const isPending = isAdding || isUpdating || isDeleting;\n const isDismissBlocked = isPending || isTesting || showDeleteConfirm;\n\n const makeTestErrorMessage = (failure: MCPTestFailure): string => {\n switch (failure.error_kind) {\n case \"timeout\":\n return t(I18nKey.MCP$TEST_ERROR_TIMEOUT);\n case \"connection\":\n return t(I18nKey.MCP$TEST_ERROR_CONNECTION);\n default:\n return t(I18nKey.MCP$TEST_ERROR_UNKNOWN, { error: failure.error });\n }\n };\n\n const testMessage: TestMessage | null = React.useMemo(() => {\n if (!testResult) return null;\n if (testResult.ok) {\n return {\n ok: true,\n text: t(I18nKey.MCP$TEST_SUCCESS, { count: testResult.tools.length }),\n };\n }\n return { ok: false, text: makeTestErrorMessage(testResult) };\n }, [testResult, t]);\n\n // Shared error handler so both add and update surface backend errors\n // as a toast instead of failing silently — previously these calls\n // had no `onError` and the modal closed even on a 4xx/5xx, leaving\n // the user to discover the failure on the next page load.\n const handleError = (err: unknown) => {\n const message = retrieveAxiosErrorMessage(err as AxiosError);\n displayErrorToast(message || t(I18nKey.ERROR$GENERIC));\n };\n\n const handleSubmit = (payload: MCPServerConfig) => {\n resetTest();\n testServer(payload, {\n onSuccess: (result) => {\n if (!result.ok) {\n // Test failed — modal stays open, error shown via testMessage.\n return;\n }\n if (isEditing) {\n updateMcpServer(\n { serverId: server.id, server: payload },\n { onSuccess: onClose, onError: handleError },\n );\n } else {\n addMcpServer(payload, { onSuccess: onClose, onError: handleError });\n }\n },\n onError: handleError,\n });\n };\n\n const handleTestClick = (payload: MCPServerConfig) => {\n testServer(payload);\n };\n\n const handleConfirmDelete = () => {\n deleteMcpServer(server, {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.MCP$REMOVE_SUCCESS));\n setShowDeleteConfirm(false);\n onClose();\n },\n onError: (err) => {\n handleError(err);\n setShowDeleteConfirm(false);\n },\n });\n };\n\n return (\n <>\n <ModalBackdrop\n // Block backdrop-click / Escape from dismissing the modal while\n // a mutation is in flight — closing mid-request would orphan\n // the request and leave the user with no error feedback.\n onClose={isDismissBlocked ? undefined : onClose}\n closeOnEscape={!isDismissBlocked}\n aria-label={\n isEditing\n ? t(I18nKey.MCP$EDIT_CUSTOM_TITLE)\n : t(I18nKey.MCP$ADD_CUSTOM_TITLE)\n }\n >\n <div\n data-testid=\"mcp-custom-editor\"\n className=\"relative bg-base-secondary p-6 rounded-xl border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[90vh] overflow-y-auto custom-scrollbar\"\n >\n <ModalCloseButton\n onClose={onClose}\n testId=\"mcp-custom-editor-close\"\n disabled={isDismissBlocked}\n />\n <h2 className=\"mb-4 pr-6 text-lg font-semibold\">\n {isEditing\n ? t(I18nKey.MCP$EDIT_CUSTOM_TITLE)\n : t(I18nKey.MCP$ADD_CUSTOM_TITLE)}\n </h2>\n <MCPServerForm\n mode={isEditing ? \"edit\" : \"add\"}\n server={isEditing ? server : undefined}\n existingServers={existingServers}\n onSubmit={handleSubmit}\n onCancel={onClose}\n onDelete={isEditing ? () => setShowDeleteConfirm(true) : undefined}\n isActionDisabled={isPending}\n onTest={handleTestClick}\n isTestPending={isTesting}\n testMessage={testMessage}\n />\n </div>\n </ModalBackdrop>\n\n {showDeleteConfirm ? (\n <ConfirmationModal\n text={t(I18nKey.SETTINGS$MCP_CONFIRM_DELETE)}\n onCancel={() => setShowDeleteConfirm(false)}\n onConfirm={handleConfirmDelete}\n isConfirming={isDeleting}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkCA,SAAgB,EAAmB,EACjC,WACA,oBACA,cAC0B;CAC1B,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,QAAQ,GAAc,WAAW,MAAa,GAAiB,EACjE,EAAE,QAAQ,GAAiB,WAAW,MAC1C,GAAoB,EAChB,EAAE,QAAQ,GAAiB,WAAW,MAC1C,GAAoB,EAChB,EACJ,QAAQ,GACR,WAAW,GACX,MAAM,GACN,OAAO,MACL,GAAkB,EAChB,CAAC,GAAmB,KAAwB,EAAM,SAAS,GAAM,EAEjE,IAAY,CAAC,CAAC,EAAO,IACrB,IAAY,KAAY,KAAc,GACtC,IAAmB,KAAa,KAAa,GAE7C,KAAwB,MAAoC;AAChE,UAAQ,EAAQ,YAAhB;GACE,KAAK,UACH,QAAO,EAAE,EAAQ,uBAAuB;GAC1C,KAAK,aACH,QAAO,EAAE,EAAQ,0BAA0B;GAC7C,QACE,QAAO,EAAE,EAAQ,wBAAwB,EAAE,OAAO,EAAQ,OAAO,CAAC;;IAIlE,IAAkC,EAAM,cACvC,IACD,EAAW,KACN;EACL,IAAI;EACJ,MAAM,EAAE,EAAQ,kBAAkB,EAAE,OAAO,EAAW,MAAM,QAAQ,CAAC;EACtE,GAEI;EAAE,IAAI;EAAO,MAAM,EAAqB,EAAW;EAAE,GAPpC,MAQvB,CAAC,GAAY,EAAE,CAAC,EAMb,KAAe,MAAiB;AAEpC,IADgB,EAA0B,EACxB,IAAW,EAAE,EAAQ,cAAc,CAAC;;AA0CxD,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EAIE,SAAS,IAAmB,KAAA,IAAY;EACxC,eAAe,CAAC;EAChB,cAEM,EADJ,IACM,EAAQ,wBACR,EAAQ,qBAAqB;YAGrC,kBAAC,OAAD;GACE,eAAY;GACZ,WAAU;aAFZ;IAIE,kBAAC,GAAD;KACW;KACT,QAAO;KACP,UAAU;KACV,CAAA;IACF,kBAAC,MAAD;KAAI,WAAU;eAER,EADH,IACK,EAAQ,wBACR,EAAQ,qBAAqB;KAChC,CAAA;IACL,kBAAC,GAAD;KACE,MAAM,IAAY,SAAS;KAC3B,QAAQ,IAAY,IAAS,KAAA;KACZ;KACjB,WAvEY,MAA6B;AAEjD,MADA,GAAW,EACX,EAAW,GAAS;OAClB,YAAY,MAAW;AAChB,UAAO,OAIR,IACF,EACE;SAAE,UAAU,EAAO;SAAI,QAAQ;SAAS,EACxC;SAAE,WAAW;SAAS,SAAS;SAAa,CAC7C,GAED,EAAa,GAAS;SAAE,WAAW;SAAS,SAAS;SAAa,CAAC;;OAGvE,SAAS;OACV,CAAC;;KAsDM,UAAU;KACV,UAAU,UAAkB,EAAqB,GAAK,GAAG,KAAA;KACzD,kBAAkB;KAClB,SAtDe,MAA6B;AACpD,QAAW,EAAQ;;KAsDX,eAAe;KACF;KACb,CAAA;IACE;;EACQ,CAAA,EAEf,IACC,kBAAC,GAAD;EACE,MAAM,EAAE,EAAQ,4BAA4B;EAC5C,gBAAgB,EAAqB,GAAM;EAC3C,iBA7D0B;AAChC,KAAgB,GAAQ;IACtB,iBAAiB;AAGf,KAFA,EAAoB,EAAE,EAAQ,mBAAmB,CAAC,EAClD,EAAqB,GAAM,EAC3B,GAAS;;IAEX,UAAU,MAAQ;AAEhB,KADA,EAAY,EAAI,EAChB,EAAqB,GAAM;;IAE9B,CAAC;;EAmDI,cAAc;EACd,CAAA,GACA,KACH,EAAA,CAAA"}