@openhands/agent-canvas 1.0.0-alpha.9 → 1.0.0-beta.2

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 (370) hide show
  1. package/README.md +2 -2
  2. package/bin/agent-canvas.mjs +22 -2
  3. package/build/assets/{QueryClientProvider-B7kl84Kj.js → QueryClientProvider-CkGuhXg-.js} +1 -1
  4. package/build/assets/{Trans-1j65oy9O.js → Trans-Cvm_-SMi.js} +1 -1
  5. package/build/assets/acp-providers-CbiRekh9.js +1 -0
  6. package/build/assets/{acp-route-guard-CQTmeJwM.js → acp-route-guard-B2yoBZ_4.js} +1 -1
  7. package/build/assets/{active-backend-context-TVbjnvmP.js → active-backend-context-cCM1vYYZ.js} +1 -1
  8. package/build/assets/add-backend-modal-DIUQzMPa.js +1 -0
  9. package/build/assets/agent-server-client-options-Bc5ZorQZ.js +1 -0
  10. package/build/assets/agent-server-compatibility-BlkUsrX2.js +1 -0
  11. package/build/assets/agent-server-conversation-service.api-DFvqqEDo.js +5 -0
  12. package/build/assets/{agent-settings-B247S9G3.js → agent-settings-CnGSCmK8.js} +1 -1
  13. package/build/assets/{alert-banner-BWoqueRw.js → alert-banner-DtzAX654.js} +1 -1
  14. package/build/assets/{analytics-consent-form-modal-C7sXfxRh.js → analytics-consent-form-modal-CHZ3I37v.js} +1 -1
  15. package/build/assets/api-key-entry-screen-B2gynaCp.js +1 -0
  16. package/build/assets/{app-settings-BVeSaty9.js → app-settings-Db9ITeJH.js} +1 -1
  17. package/build/assets/{automation-detail-R-99FUce.js → automation-detail-Di7EOIZD.js} +1 -1
  18. package/build/assets/{automations-list-Dfu2c-_D.js → automations-list-IsIWdDiw.js} +1 -1
  19. package/build/assets/{backend-form-modal-DxYjqqAK.js → backend-form-modal-Dnk33xA_.js} +1 -1
  20. package/build/assets/{backend-synced-settings-badge-nAfiUWvM.js → backend-synced-settings-badge-Dc6c7GT4.js} +1 -1
  21. package/build/assets/{base-modal-CQRvRHu1.js → base-modal-_dYTw1ri.js} +1 -1
  22. package/build/assets/{brand-button-C2nEKopC.js → brand-button-Br7f0kZJ.js} +1 -1
  23. package/build/assets/{browser-HrYc5Gce.js → browser-D810xUYt.js} +2 -2
  24. package/build/assets/browser-store-Couc4S5D.js +1 -0
  25. package/build/assets/browser-tab-B-aIqXRl.js +1 -0
  26. package/build/assets/{checkmark-BJJrZUF8.js → checkmark-DL7acQA7.js} +1 -1
  27. package/build/assets/{chevron-left-small-CSh-sE9L.js → chevron-left-small-CVWf8TI6.js} +1 -1
  28. package/build/assets/{circle-plus-check-toggle-qs8Va1cC.js → circle-plus-check-toggle-P7ZZToV4.js} +1 -1
  29. package/build/assets/{clock-ZR4Kn-_Y.js → clock-BRjCgHTc.js} +1 -1
  30. package/build/assets/{close-BdmyeRqS.js → close-B5LROHR3.js} +1 -1
  31. package/build/assets/{combobox-caret-B53O9Hsq.js → combobox-caret-to1O8irE.js} +1 -1
  32. package/build/assets/{condenser-settings-A35V3yng.js → condenser-settings-wnEKhBof.js} +1 -1
  33. package/build/assets/{confirmation-modal-C9-La0h3.js → confirmation-modal-Dau3w_sa.js} +1 -1
  34. package/build/assets/{context-menu-list-item-Buu9nc0q.js → context-menu-list-item-CWNFpuiC.js} +1 -1
  35. package/build/assets/conversation-HlncOV7n.js +19 -0
  36. package/build/assets/conversation-MtnkpqA9.js +1 -0
  37. package/build/assets/conversation-panel-DxnM6tRe.js +1 -0
  38. package/build/assets/{conversation-service.api--f8WglOC.js → conversation-service.api-nb5W1PqR.js} +1 -1
  39. package/build/assets/{conversation-tab-empty-state-D8dNvo-V.js → conversation-tab-empty-state-DyssnnWa.js} +1 -1
  40. package/build/assets/conversation-websocket-context-C8_PkGLi.js +3 -0
  41. package/build/assets/{copy-C7Ti2d8C.js → copy-DYgmUdIw.js} +1 -1
  42. package/build/assets/{custom-toast-handlers-BOc3qeQ7.js → custom-toast-handlers-C-SZFmto.js} +1 -1
  43. package/build/assets/declaration-BNMqORFE.js +1 -0
  44. package/build/assets/{device-verify-CMusn8nX.js → device-verify-DqDlphsG.js} +1 -1
  45. package/build/assets/{dist-DZHSA2e6.js → dist-C6t0EXL7.js} +1 -1
  46. package/build/assets/{edit-automation-modal-Dnjxbjn7.js → edit-automation-modal-BGzR3nfZ.js} +1 -1
  47. package/build/assets/{ellipsis-button-ugUATsNo.js → ellipsis-button-ZyLMPURn.js} +1 -1
  48. package/build/assets/{entry.client-CqqXOSvd.js → entry.client-1VMHpktY.js} +2 -2
  49. package/build/assets/{enum-filter-dropdown-1vpOGySB.js → enum-filter-dropdown-CEgCdu4A.js} +1 -1
  50. package/build/assets/{environment-switch-overlay-CTCTQikP.js → environment-switch-overlay-XL8yCGP6.js} +1 -1
  51. package/build/assets/{extensions-hub-BSUseHVF.js → extensions-hub-C651jsVh.js} +1 -1
  52. package/build/assets/{extensions-navigation-CT1kc1u_.js → extensions-navigation-BYR8Giqq.js} +1 -1
  53. package/build/assets/files-tab-BhnLgimi.js +1 -0
  54. package/build/assets/{folder-0WSMImNX.js → folder-ZZJVGgd7.js} +1 -1
  55. package/build/assets/{git-control-bar-branch-button-C8u5rzjc.js → git-control-bar-branch-button-M34A5_vX.js} +2 -2
  56. package/build/assets/{git-provider-icon-D-a-rcLm.js → git-provider-icon-D5dCNy-k.js} +1 -1
  57. package/build/assets/home-CYQv7yc_.js +1 -0
  58. package/build/assets/{i18n-DjAGhTis.js → i18n-CTohRuoO.js} +1 -1
  59. package/build/assets/install-server-modal-f31_CLrW.js +1 -0
  60. package/build/assets/{launch-B2mbfOSm.js → launch-DHEUYn2A.js} +1 -1
  61. package/build/assets/{lesson-plan-DRYG5SLI.js → lesson-plan-dH5Bj0pN.js} +1 -1
  62. package/build/assets/{link-external-C9d6Fo3x.js → link-external-D2POYx4c.js} +1 -1
  63. package/build/assets/{llm-client-ChQzg4wX.js → llm-client-DaH1TuyR.js} +1 -1
  64. package/build/assets/llm-settings-Bql-vydt.js +1 -0
  65. package/build/assets/llm-settings-C_tal6Ds.js +1 -0
  66. package/build/assets/{loading-spinner-C04FGh14.js → loading-spinner-BPtYORNK.js} +1 -1
  67. package/build/assets/{manage-backends-modal-s22zCdEW.js → manage-backends-modal-l7RkKfwX.js} +1 -1
  68. package/build/assets/{manage-workspaces-modal-C5EuW8m1.js → manage-workspaces-modal-DhKF_8z3.js} +1 -1
  69. package/build/assets/manifest-6b31008e.js +1 -0
  70. package/build/assets/{markdown-renderer-CEX4Becj.js → markdown-renderer-DMzf2i4x.js} +1 -1
  71. package/build/assets/mcp-D2onbwVk.js +9 -0
  72. package/build/assets/{messages-6aOyUu3r.js → messages-BMzyOW2V.js} +1 -1
  73. package/build/assets/{modal-backdrop-DTYGVmOR.js → modal-backdrop-BAbgYsqB.js} +1 -1
  74. package/build/assets/{modal-body-YElmM1dV.js → modal-body-BI6Ru2Qr.js} +1 -1
  75. package/build/assets/{modal-close-button-C_GpQt9F.js → modal-close-button-t1Gh3qmL.js} +1 -1
  76. package/build/assets/{model-selector-DeMmw-Xa.js → model-selector-SM9IUz-q.js} +1 -1
  77. package/build/assets/{mutation-Cz7N4XAo.js → mutation-D0OogFCz.js} +1 -1
  78. package/build/assets/{navigation-context-DeIPtGPp.js → navigation-context-D0YWpT8d.js} +1 -1
  79. package/build/assets/{navigation-link-C9JD4PYD.js → navigation-link-Cn7KP3c5.js} +1 -1
  80. package/build/assets/{openhands-logo-CI5Fhn1W.js → openhands-logo-CnrF6LKb.js} +1 -1
  81. package/build/assets/{option-service.api-DsI1UW7N.js → option-service.api-KvY_mZMY.js} +1 -1
  82. package/build/assets/{organization-service.api-COwMPFg5.js → organization-service.api-DzYTHTYC.js} +1 -1
  83. package/build/assets/{path-utils-BVbe598W.js → path-utils-YohAYyMv.js} +1 -1
  84. package/build/assets/{plan-components-DEjMuDDG.js → plan-components-atxXCF0R.js} +1 -1
  85. package/build/assets/{planner-tab-bN6r1G-1.js → planner-tab-CFc-hV07.js} +1 -1
  86. package/build/assets/{profiles-client-BGkKEV9j.js → profiles-client-D6IkTJof.js} +1 -1
  87. package/build/assets/{providers-DXvCAN_u.js → providers-Bx6EfrzZ.js} +1 -1
  88. package/build/assets/{proxy-CurRmrqf.js → proxy-CxydCnis.js} +1 -1
  89. package/build/assets/{query-client-config-Ba7qAAoO.js → query-client-config-B7u9asM0.js} +1 -1
  90. package/build/assets/{recommended-automations-launcher-mJhK6Atl.js → recommended-automations-launcher-sgvfU62c.js} +3 -3
  91. package/build/assets/root-E6pcRIYp.js +2 -0
  92. package/build/assets/{root-layout-BjVwHmta.js → root-layout-DVepR4To.js} +2 -2
  93. package/build/assets/sdk-section-page-DOIKvwSL.js +1 -0
  94. package/build/assets/{sdk-settings-schema-QBYH-ONX.js → sdk-settings-schema-DsUf9wu1.js} +1 -1
  95. package/build/assets/{search-Cq_cFrDt.js → search-27Owlc3A.js} +1 -1
  96. package/build/assets/{secrets-service-Bwd5DeUs.js → secrets-service-BsnKFc2x.js} +1 -1
  97. package/build/assets/secrets-settings-Bz_UohPJ.js +1 -0
  98. package/build/assets/{server-client-C3mC8Hl3.js → server-client-DyAQ3NZ_.js} +1 -1
  99. package/build/assets/{settings-D7E2U5tK.js → settings-BYkVX7vW.js} +1 -1
  100. package/build/assets/{settings-client-CwjfwoiB.js → settings-client-C73C7IgV.js} +1 -1
  101. package/build/assets/{settings-dropdown-input-VwAXNrOb.js → settings-dropdown-input-BJYvGdg-.js} +1 -1
  102. package/build/assets/{settings-gear-BJwWR1ej.js → settings-gear-C77PgE_O.js} +1 -1
  103. package/build/assets/{settings-index-J-3BNR0W.js → settings-index-Dz0BmdJD.js} +1 -1
  104. package/build/assets/{settings-input-DBywAnA7.js → settings-input-Bn7F5C75.js} +1 -1
  105. package/build/assets/{settings-list-classes-BOS092DR.js → settings-list-classes-Bf80tWtc.js} +1 -1
  106. package/build/assets/{settings-modal-B8vgWDTe.js → settings-modal-Brzgh5Yw.js} +1 -1
  107. package/build/assets/{settings-section-header-context-32x6WTyL.js → settings-section-header-context-BgZe5YkE.js} +1 -1
  108. package/build/assets/{settings-service.api-FvJGK45W.js → settings-service.api-CZ3uWx4v.js} +1 -1
  109. package/build/assets/{settings-switch-DTKmHC8F.js → settings-switch-BeIKrWms.js} +1 -1
  110. package/build/assets/{shared-conversation-EZV0FRIf.js → shared-conversation-DChOdb0t.js} +1 -1
  111. package/build/assets/{sidebar-mobile-menu-toggle-BnbzzpQl.js → sidebar-mobile-menu-toggle-BWuf4PRH.js} +1 -1
  112. package/build/assets/{sidebar-nav-link-CnWoZcwc.js → sidebar-nav-link-BGjiJq-4.js} +1 -1
  113. package/build/assets/{skill-card-pill-row-tZ599jli.js → skill-card-pill-row-DF1axQCG.js} +1 -1
  114. package/build/assets/{skills-ZyAO5dyK.js → skills-ChIKZPK4.js} +1 -1
  115. package/build/assets/{skills-plugins-BSRz041I.js → skills-plugins-CcI_19lM.js} +1 -1
  116. package/build/assets/{skills-settings-CG2hu34D.js → skills-settings-DlA5hlXw.js} +1 -1
  117. package/build/assets/{status-CsatcFbK.js → status-hp6M6E7E.js} +1 -1
  118. package/build/assets/{styled-tooltip-CS3mB_1X.js → styled-tooltip-CBzrri6o.js} +1 -1
  119. package/build/assets/{switch-skeleton-C-CfhYYV.js → switch-skeleton-DnC9wLp7.js} +1 -1
  120. package/build/assets/{task-list-tab-465DDju0.js → task-list-tab-DUJn1sgz.js} +1 -1
  121. package/build/assets/{terminal-CcgBEVnC.js → terminal-CRf9S0Z2.js} +1 -1
  122. package/build/assets/{terminal-LNa-iU5c.js → terminal-RmuaSdhJ.js} +1 -1
  123. package/build/assets/{toggle-switch-k-IZCDbt.js → toggle-switch-Pvyp2RAN.js} +1 -1
  124. package/build/assets/{typography-vVUMoNUg.js → typography-gpuWmrQO.js} +1 -1
  125. package/build/assets/{u-check-circle-DplbarS5.js → u-check-circle-IUIfACQQ.js} +1 -1
  126. package/build/assets/{u-check-circle-half-yDuiSZHC.js → u-check-circle-half-C1YxB6py.js} +1 -1
  127. package/build/assets/{u-circuit-C9tYkpeK.js → u-circuit-BmVikJHu.js} +1 -1
  128. package/build/assets/{u-edit-KAUlufD8.js → u-edit-CFvXHqZk.js} +1 -1
  129. package/build/assets/use-active-conversation-Db3IWSPK.js +1 -0
  130. package/build/assets/{use-agent-settings-schema-Bvp5UzV8.js → use-agent-settings-schema-33Un7UF2.js} +1 -1
  131. package/build/assets/{use-agent-state-D2C9SeGw.js → use-agent-state-Bn8vS5sY.js} +1 -1
  132. package/build/assets/{use-cloud-current-user-id-DWVar4st.js → use-cloud-current-user-id-CvkXFnTT.js} +1 -1
  133. package/build/assets/use-config-Co1O8-Ey.js +1 -0
  134. package/build/assets/{use-create-conversation-BEZg__Vv.js → use-create-conversation-CKS3EAHu.js} +1 -1
  135. package/build/assets/use-get-secrets-DuhdIA59.js +1 -0
  136. package/build/assets/{use-handle-plan-click-uOpew2LO.js → use-handle-plan-click-C9zJpK8A.js} +1 -1
  137. package/build/assets/use-is-authed-BggE5wPj.js +1 -0
  138. package/build/assets/{use-is-creating-conversation-DhDeeWfA.js → use-is-creating-conversation-BZ5hB_Bg.js} +1 -1
  139. package/build/assets/{use-launch-skill-in-chat-DVGPFrbI.js → use-launch-skill-in-chat-fNN_xGZG.js} +1 -1
  140. package/build/assets/{use-llm-profiles-O4a9V6RC.js → use-llm-profiles-DDOol3gK.js} +1 -1
  141. package/build/assets/use-runtime-is-ready-CQCE3xZC.js +1 -0
  142. package/build/assets/{use-save-settings-CEEKSTWG.js → use-save-settings-VUrj_QNG.js} +1 -1
  143. package/build/assets/{use-settings-DQ7Oo1Hj.js → use-settings-DQIZmIov.js} +1 -1
  144. package/build/assets/{use-settings-nav-items-YmrXrjn9.js → use-settings-nav-items-1ZvovKSr.js} +1 -1
  145. package/build/assets/{use-skills-BIvlWblA.js → use-skills-DAMLFjKU.js} +1 -1
  146. package/build/assets/use-unified-vscode-url-sZt29HrC.js +1 -0
  147. package/build/assets/use-user-conversation-DfgEB6RW.js +1 -0
  148. package/build/assets/{useMutation-B4OUESdw.js → useMutation-DqrumCWD.js} +1 -1
  149. package/build/assets/{useTranslation-CpIcQBq6.js → useTranslation-DCOdSSMl.js} +1 -1
  150. package/build/assets/{utils-D-HX7JCe.js → utils-i18rdUj2.js} +1 -1
  151. package/build/assets/v4-CNn21NXa.js +1 -0
  152. package/build/assets/{vendor~browser-Dr71AdrG.js → vendor~browser-BNjNhjFU.js} +1 -1
  153. package/build/assets/{vendor~browser-tab-BiVxfjJo.js → vendor~browser-tab-BgwV1mxF.js} +1 -1
  154. package/build/assets/{vendor~conversation-panel~conversation-BlCIz9XQ.js → vendor~conversation-panel~conversation-a9SyrrhV.js} +1 -1
  155. package/build/assets/{vendor~files-tab-DtLR-QD9.js → vendor~files-tab-BGKayPiK.js} +1 -1
  156. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Ds9quNZ9.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-smY2r837.js} +1 -1
  157. package/build/assets/{vendor~home~mcp~automations-list-C5PoHCy6.js → vendor~home~mcp~automations-list-Ccy2I0KU.js} +1 -1
  158. package/build/assets/{vendor~home~mcp~automations-list-BUBGGGYz.js → vendor~home~mcp~automations-list-DoPfwaXj.js} +1 -1
  159. package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-CGlZoBKa.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-DbfELDJu.js} +2 -2
  160. package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-DE11mPxp.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-Z3nsiNNq.js} +1 -1
  161. package/build/assets/{vendor~launch-Dg--Ssk6.js → vendor~launch-vdeRTWFu.js} +1 -1
  162. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-DrXgiSCq.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-DW31UyBp.js} +1 -1
  163. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-8b8V5bfO.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-BkQGKpye.js} +1 -1
  164. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-Dy7L6fMG.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-DzIXV3Ui.js} +1 -1
  165. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-D40EXhZx.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-Bbs7UJ5U.js} +2 -2
  166. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-CHrEOFl6.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-DTwbEEcX.js} +1 -1
  167. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-BP1SKG0F.js → vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-d2oallMa.js} +1 -1
  168. package/build/assets/{vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~kyz9p27j-CyUbhpbm.js → vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~f2l2lr17-CDXvdvb2.js} +1 -1
  169. package/build/assets/{verification-settings-BtlTiHP8.js → verification-settings-CsbvQcYS.js} +1 -1
  170. package/build/assets/{vscode-tab-B0vdh9gU.js → vscode-tab-Zb-QbTuV.js} +1 -1
  171. package/build/assets/{waiting-for-runtime-message-DWPl_Yby.js → waiting-for-runtime-message-CntjExbU.js} +1 -1
  172. package/build/assets/{x-mark-CWI0f9yI.js → x-mark-CrpjscNc.js} +1 -1
  173. package/build/index.html +4 -4
  174. package/build/locales/ar/openhands.json +7 -0
  175. package/build/locales/ca/openhands.json +7 -0
  176. package/build/locales/de/openhands.json +7 -0
  177. package/build/locales/en/openhands.json +7 -0
  178. package/build/locales/es/openhands.json +7 -0
  179. package/build/locales/fr/openhands.json +7 -0
  180. package/build/locales/it/openhands.json +7 -0
  181. package/build/locales/ja/openhands.json +7 -0
  182. package/build/locales/ko-KR/openhands.json +7 -0
  183. package/build/locales/no/openhands.json +7 -0
  184. package/build/locales/pt/openhands.json +7 -0
  185. package/build/locales/tr/openhands.json +7 -0
  186. package/build/locales/uk/openhands.json +7 -0
  187. package/build/locales/zh-CN/openhands.json +7 -0
  188. package/build/locales/zh-TW/openhands.json +7 -0
  189. package/config/defaults.json +0 -4
  190. package/dist/api/agent-server-adapter.cjs +1 -1
  191. package/dist/api/agent-server-adapter.cjs.map +1 -1
  192. package/dist/api/agent-server-adapter.js +1 -1
  193. package/dist/api/agent-server-adapter.js.map +1 -1
  194. package/dist/api/agent-server-compatibility.cjs +1 -1
  195. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  196. package/dist/api/agent-server-compatibility.d.ts +16 -0
  197. package/dist/api/agent-server-compatibility.js +31 -20
  198. package/dist/api/agent-server-compatibility.js.map +1 -1
  199. package/dist/api/agent-server-config.cjs +1 -1
  200. package/dist/api/agent-server-config.cjs.map +1 -1
  201. package/dist/api/agent-server-config.d.ts +45 -0
  202. package/dist/api/agent-server-config.js +49 -21
  203. package/dist/api/agent-server-config.js.map +1 -1
  204. package/dist/api/backend-registry/storage.cjs +1 -1
  205. package/dist/api/backend-registry/storage.cjs.map +1 -1
  206. package/dist/api/backend-registry/storage.js +34 -32
  207. package/dist/api/backend-registry/storage.js.map +1 -1
  208. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  209. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  210. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +5 -4
  211. package/dist/api/conversation-service/agent-server-conversation-service.api.js +70 -76
  212. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  213. package/dist/components/features/backends/api-key-entry-screen.d.ts +10 -0
  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.d.ts +23 -2
  217. package/dist/components/features/backends/backend-form-modal.js +43 -38
  218. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  219. package/dist/components/features/browser/browser.cjs +1 -1
  220. package/dist/components/features/browser/browser.cjs.map +1 -1
  221. package/dist/components/features/browser/browser.js +10 -16
  222. package/dist/components/features/browser/browser.js.map +1 -1
  223. package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
  224. package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
  225. package/dist/components/features/mcp-page/install-server-modal.js +123 -116
  226. package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
  227. package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
  228. package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
  229. package/dist/components/features/mcp-page/installed-server-card.js +40 -40
  230. package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
  231. package/dist/components/features/mcp-page/marketplace-card.cjs +1 -1
  232. package/dist/components/features/mcp-page/marketplace-card.cjs.map +1 -1
  233. package/dist/components/features/mcp-page/marketplace-card.js +2 -3
  234. package/dist/components/features/mcp-page/marketplace-card.js.map +1 -1
  235. package/dist/components/features/mcp-page/marketplace-section.cjs +1 -1
  236. package/dist/components/features/mcp-page/marketplace-section.cjs.map +1 -1
  237. package/dist/components/features/mcp-page/marketplace-section.js +21 -21
  238. package/dist/components/features/mcp-page/marketplace-section.js.map +1 -1
  239. package/dist/components/features/onboarding/steps/setup-acp-secrets-step.d.ts +27 -0
  240. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
  241. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +2 -0
  242. package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs +1 -1
  243. package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs.map +1 -1
  244. package/dist/components/features/settings/sdk-settings/sdk-section-page.d.ts +10 -1
  245. package/dist/components/features/settings/sdk-settings/sdk-section-page.js +87 -84
  246. package/dist/components/features/settings/sdk-settings/sdk-section-page.js.map +1 -1
  247. package/dist/constants/acp-providers.cjs +1 -1
  248. package/dist/constants/acp-providers.cjs.map +1 -1
  249. package/dist/constants/acp-providers.d.ts +25 -0
  250. package/dist/constants/acp-providers.js +1 -0
  251. package/dist/constants/acp-providers.js.map +1 -1
  252. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  253. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  254. package/dist/contexts/conversation-websocket-context.js +136 -132
  255. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  256. package/dist/hooks/chat/use-model-interceptor.cjs.map +1 -1
  257. package/dist/hooks/chat/use-model-interceptor.js.map +1 -1
  258. package/dist/hooks/mutation/use-switch-llm-profile.cjs.map +1 -1
  259. package/dist/hooks/mutation/use-switch-llm-profile.d.ts +1 -1
  260. package/dist/hooks/mutation/use-switch-llm-profile.js.map +1 -1
  261. package/dist/hooks/query/use-config.cjs +1 -1
  262. package/dist/hooks/query/use-config.cjs.map +1 -1
  263. package/dist/hooks/query/use-config.js +10 -10
  264. package/dist/hooks/query/use-config.js.map +1 -1
  265. package/dist/hooks/query/use-local-git-info.cjs +3 -3
  266. package/dist/hooks/query/use-local-git-info.cjs.map +1 -1
  267. package/dist/hooks/query/use-local-git-info.js +24 -25
  268. package/dist/hooks/query/use-local-git-info.js.map +1 -1
  269. package/dist/i18n/declaration.cjs +1 -1
  270. package/dist/i18n/declaration.cjs.map +1 -1
  271. package/dist/i18n/declaration.d.ts +7 -0
  272. package/dist/i18n/declaration.js +1 -1
  273. package/dist/i18n/declaration.js.map +1 -1
  274. package/dist/i18n/translation.cjs +2 -2
  275. package/dist/i18n/translation.cjs.map +1 -1
  276. package/dist/i18n/translation.js +119 -0
  277. package/dist/i18n/translation.js.map +1 -1
  278. package/dist/locales/ar/openhands.json +7 -0
  279. package/dist/locales/ca/openhands.json +7 -0
  280. package/dist/locales/de/openhands.json +7 -0
  281. package/dist/locales/en/openhands.json +7 -0
  282. package/dist/locales/es/openhands.json +7 -0
  283. package/dist/locales/fr/openhands.json +7 -0
  284. package/dist/locales/it/openhands.json +7 -0
  285. package/dist/locales/ja/openhands.json +7 -0
  286. package/dist/locales/ko-KR/openhands.json +7 -0
  287. package/dist/locales/no/openhands.json +7 -0
  288. package/dist/locales/pt/openhands.json +7 -0
  289. package/dist/locales/tr/openhands.json +7 -0
  290. package/dist/locales/uk/openhands.json +7 -0
  291. package/dist/locales/zh-CN/openhands.json +7 -0
  292. package/dist/locales/zh-TW/openhands.json +7 -0
  293. package/dist/package.cjs +1 -1
  294. package/dist/package.cjs.map +1 -1
  295. package/dist/package.js +1 -1
  296. package/dist/package.js.map +1 -1
  297. package/dist/routes/mcp.cjs +1 -1
  298. package/dist/routes/mcp.cjs.map +1 -1
  299. package/dist/routes/mcp.js +64 -64
  300. package/dist/routes/mcp.js.map +1 -1
  301. package/dist/stores/browser-store.cjs +1 -1
  302. package/dist/stores/browser-store.cjs.map +1 -1
  303. package/dist/stores/browser-store.js +1 -1
  304. package/dist/stores/browser-store.js.map +1 -1
  305. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  306. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  307. package/dist/utils/mcp-marketplace-utils.d.ts +13 -22
  308. package/dist/utils/mcp-marketplace-utils.js +46 -28
  309. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  310. package/dist/utils/sdk-settings-schema.cjs +1 -1
  311. package/dist/utils/sdk-settings-schema.cjs.map +1 -1
  312. package/dist/utils/sdk-settings-schema.d.ts +1 -0
  313. package/dist/utils/sdk-settings-schema.js +1 -1
  314. package/dist/utils/sdk-settings-schema.js.map +1 -1
  315. package/package.json +1 -1
  316. package/scripts/dev-safe.mjs +59 -40
  317. package/scripts/dev-static.mjs +2 -3
  318. package/scripts/dev-with-automation.mjs +75 -19
  319. package/scripts/static-server.mjs +77 -35
  320. package/tools/canvas_ui_tool.py +4 -0
  321. package/build/assets/acp-providers-DauuOsW9.js +0 -1
  322. package/build/assets/add-backend-modal-FsnpTTgO.js +0 -1
  323. package/build/assets/agent-server-client-options-DT2GP6VJ.js +0 -1
  324. package/build/assets/agent-server-compatibility-2aOx5iWd.js +0 -1
  325. package/build/assets/agent-server-conversation-service.api-BZmUqtiO.js +0 -5
  326. package/build/assets/browser-store-C3AqxAO7.js +0 -1
  327. package/build/assets/browser-tab-B_BuTvrO.js +0 -1
  328. package/build/assets/conversation--ldUK72N.js +0 -19
  329. package/build/assets/conversation-eNrhH94O.js +0 -1
  330. package/build/assets/conversation-panel-B49Jpqpb.js +0 -1
  331. package/build/assets/conversation-websocket-context-BW68-J8o.js +0 -3
  332. package/build/assets/declaration-D378OjpZ.js +0 -1
  333. package/build/assets/files-tab-CQHdWpQt.js +0 -1
  334. package/build/assets/home-DD0GroCu.js +0 -1
  335. package/build/assets/install-server-modal-z5VaHeXd.js +0 -1
  336. package/build/assets/llm-settings-BEyqixPI.js +0 -1
  337. package/build/assets/llm-settings-BdiaGFbg.js +0 -1
  338. package/build/assets/manifest-9d1c34fb.js +0 -1
  339. package/build/assets/mcp-C06YssEI.js +0 -9
  340. package/build/assets/root-3t9rxEpE.js +0 -2
  341. package/build/assets/sdk-section-page-CJW0G04-.js +0 -1
  342. package/build/assets/secrets-settings-MLXqOtX2.js +0 -1
  343. package/build/assets/use-active-conversation-DS5j9R4q.js +0 -1
  344. package/build/assets/use-config-BSu_53GL.js +0 -1
  345. package/build/assets/use-conversation-id-DajhCn2A.js +0 -1
  346. package/build/assets/use-is-authed-hXC8vxgT.js +0 -1
  347. package/build/assets/use-runtime-is-ready-pGSbPddC.js +0 -1
  348. package/build/assets/use-unified-vscode-url-wAMzv8Sn.js +0 -1
  349. package/build/assets/use-user-conversation-B_zDoSeh.js +0 -1
  350. /package/build/assets/{automation-XLxhq3I8.js → automation-IdgZq6ZK.js} +0 -0
  351. /package/build/assets/{common-SMkEaBSr.js → common-DR1t-EeP.js} +0 -0
  352. /package/build/assets/{conversation-state-store-Bc0slAjL.js → conversation-state-store-u5jepov0.js} +0 -0
  353. /package/build/assets/{dist-yMQV8IUk.js → dist-BxBP7tFD.js} +0 -0
  354. /package/build/assets/{git-status-mapper-BI8FyUVp.js → git-status-mapper-DnL9OC8_.js} +0 -0
  355. /package/build/assets/{handle-capture-consent-BfZATzpI.js → handle-capture-consent-3XrjZ8wi.js} +0 -0
  356. /package/build/assets/{iconBase-C7N9pPOs.js → iconBase-DE30Zj_-.js} +0 -0
  357. /package/build/assets/{settings-D5am1n6X.js → settings-D_H-qsRm.js} +0 -0
  358. /package/build/assets/{settings-like-page-layout-classes-Bn-M9oOa.js → settings-like-page-layout-classes-I0BDBEoq.js} +0 -0
  359. /package/build/assets/{settings-utils-BsvSU3OM.js → settings-utils-B6Nl07io.js} +0 -0
  360. /package/build/assets/{sidebar-store-cOeaKmIm.js → sidebar-store-Uy3v0AOV.js} +0 -0
  361. /package/build/assets/{use-breakpoint-B86yKT9n.js → use-breakpoint-DbJ6FkQ-.js} +0 -0
  362. /package/build/assets/{use-click-outside-element-835W9pC6.js → use-click-outside-element-DffgWWoZ.js} +0 -0
  363. /package/build/assets/{use-task-list-DDeNHprj.js → use-task-list-CLJbuJgM.js} +0 -0
  364. /package/build/assets/{vendor~browser-BpdPBhgZ.js → vendor~browser-DDiZgqD3.js} +0 -0
  365. /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-Df7_G0zR.js → vendor~conversation-panel~conversation~alert-banner-DbvX3OcM.js} +0 -0
  366. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~b4cctr4k-B7YVdv1X.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~g56ukk6u-DsSvIDZQ.js} +0 -0
  367. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~i9dbt75i-CI82Did1.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~hkqzh1hb-BZ0HXuHD.js} +0 -0
  368. /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~pfbaerbd-zhv9fooy.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~ninslayh-D9P8e98a.js} +0 -0
  369. /package/build/assets/{vendor~terminal-BUxzHKcC.js → vendor~terminal-DUrOWGFE.js} +0 -0
  370. /package/build/assets/{vscode-url-helper-jesbpos5.js → vscode-url-helper-Cwy1A62q.js} +0 -0
@@ -1,36 +1,43 @@
1
1
  import { useTranslation as e } from "../../../node_modules/react-i18next/dist/es/useTranslation.js";
2
2
  import { I18nKey as t } from "../../../i18n/declaration.js";
3
3
  import { displaySuccessToast as n } from "../../../utils/custom-toast-handlers.js";
4
- import { ModalBackdrop as r } from "../../shared/modals/modal-backdrop.js";
5
- import { ModalCloseButton as i } from "../../shared/modals/modal-close-button.js";
6
- import { BrandButton as a } from "../settings/brand-button.js";
7
- import { SettingsInput as o } from "../settings/settings-input.js";
8
- import { retrieveAxiosErrorMessage as s } from "../../../utils/retrieve-axios-error-message.js";
9
- import { getInstallableTemplate as c } from "../../../utils/mcp-marketplace-utils.js";
10
- import { McpLogoBadge as l } from "../mcp-logo-badge.js";
11
- import { useAddMcpServer as u } from "../../../hooks/mutation/use-add-mcp-server.js";
12
- import { useTestMcpServer as d } from "../../../hooks/mutation/use-test-mcp-server.js";
13
- import f, { useId as p } from "react";
4
+ import r from "../../../node_modules/uuid/dist/v4.js";
5
+ import { ModalBackdrop as i } from "../../shared/modals/modal-backdrop.js";
6
+ import { ModalCloseButton as a } from "../../shared/modals/modal-close-button.js";
7
+ import { BrandButton as o } from "../settings/brand-button.js";
8
+ import { SettingsInput as s } from "../settings/settings-input.js";
9
+ import { retrieveAxiosErrorMessage as c } from "../../../utils/retrieve-axios-error-message.js";
10
+ import { getInstallableMcpConnectionOption as l } from "../../../utils/mcp-marketplace-utils.js";
11
+ import { McpLogoBadge as u } from "../mcp-logo-badge.js";
12
+ import { useAddMcpServer as d } from "../../../hooks/mutation/use-add-mcp-server.js";
13
+ import { useTestMcpServer as f } from "../../../hooks/mutation/use-test-mcp-server.js";
14
+ import p from "react";
14
15
  import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
15
16
  //#region src/components/features/mcp-page/install-server-modal.tsx
16
17
  function _(e) {
17
- let t = {}, n = c(e);
18
- if (!n) return {
19
- values: t,
20
- errors: {}
21
- };
22
- if (n.kind === "stdio") {
23
- for (let e of n.envFields ?? []) t[e.key] = "";
24
- for (let e of n.argFields ?? []) t[e.key] = "";
25
- } else (n.kind === "shttp" || n.kind === "sse") && (t.api_key = "");
18
+ return e?.transport.kind !== "shttp" && e?.transport.kind !== "sse" ? !1 : [
19
+ "api_key",
20
+ "bearer",
21
+ "basic"
22
+ ].includes(e.auth.strategy);
23
+ }
24
+ function v(e) {
25
+ return e.transport.kind === "stdio" ? e.auth.apiKeyOptional ?? !1 : e.auth.apiKeyOptional ?? e.transport.apiKeyOptional ?? !1;
26
+ }
27
+ function y(e) {
28
+ let t = {}, n = l(e), r = n?.transport;
29
+ if (r?.kind === "stdio") {
30
+ for (let e of r.envFields ?? []) t[e.key] = "";
31
+ for (let e of r.argFields ?? []) t[e.key] = "";
32
+ } else _(n) && (t.api_key = "");
26
33
  return {
27
34
  values: t,
28
35
  errors: {}
29
36
  };
30
37
  }
31
- function v({ entry: v, onClose: y, onSuccess: b }) {
32
- let { t: x } = e("openhands"), { mutate: S, isPending: C } = u(), { mutate: w, isPending: T } = d(), E = p(), [D, O] = f.useState(() => _(v)), [k, A] = f.useState(null), j = T || C, M = (e, t) => {
33
- O((n) => ({
38
+ function b({ entry: b, onClose: x, onSuccess: S }) {
39
+ let { t: C } = e("openhands"), { mutate: w, isPending: T } = d(), { mutate: E, isPending: D } = f(), [O, k] = p.useState(() => y(b)), [A, j] = p.useState(null), M = l(b), N = M?.transport, P = D || T, F = (e, t) => {
40
+ k((n) => ({
34
41
  values: {
35
42
  ...n.values,
36
43
  [e]: t
@@ -39,159 +46,159 @@ function v({ entry: v, onClose: y, onSuccess: b }) {
39
46
  ...n.errors,
40
47
  [e]: null
41
48
  }
42
- })), A(null);
43
- }, N = (e) => {
49
+ })), j(null);
50
+ }, I = (e) => {
44
51
  switch (e.error_kind) {
45
- case "timeout": return x(t.MCP$TEST_ERROR_TIMEOUT);
46
- case "connection": return x(t.MCP$TEST_ERROR_CONNECTION);
47
- default: return x(t.MCP$TEST_ERROR_UNKNOWN, { error: e.error });
52
+ case "timeout": return C(t.MCP$TEST_ERROR_TIMEOUT);
53
+ case "connection": return C(t.MCP$TEST_ERROR_CONNECTION);
54
+ default: return C(t.MCP$TEST_ERROR_UNKNOWN, { error: e.error });
48
55
  }
49
- }, P = (e) => {
50
- w(e, {
56
+ }, L = (e) => {
57
+ E(e, {
51
58
  onSuccess: (r) => {
52
59
  if (!r.ok) {
53
- A(N(r));
60
+ j(I(r));
54
61
  return;
55
62
  }
56
- S(e, {
63
+ w(e, {
57
64
  onSuccess: () => {
58
- n(x(t.MCP$INSTALL_SUCCESS)), b?.(v), y();
65
+ n(C(t.MCP$INSTALL_SUCCESS)), S?.(b), x();
59
66
  },
60
67
  onError: (e) => {
61
- A(s(e) || x(t.ERROR$GENERIC));
68
+ j(c(e) || C(t.ERROR$GENERIC));
62
69
  }
63
70
  });
64
71
  },
65
72
  onError: (e) => {
66
- A(s(e) || x(t.ERROR$GENERIC));
73
+ j(c(e) || C(t.ERROR$GENERIC));
67
74
  }
68
75
  });
69
- }, F = c(v), I = () => {
70
- if (!F || F.kind !== "shttp" && F.kind !== "sse") return;
71
- let e = D.values.api_key?.trim() ?? "";
72
- if (!F.apiKeyOptional && !e) {
73
- O((e) => ({
76
+ }, R = () => {
77
+ if (N?.kind !== "shttp" && N?.kind !== "sse" || !M) return;
78
+ let e = O.values.api_key?.trim() ?? "", n = _(M);
79
+ if (n && !v(M) && !e) {
80
+ k((e) => ({
74
81
  ...e,
75
- errors: { api_key: x(t.MCP$ERROR_FIELD_REQUIRED) }
82
+ errors: { api_key: C(t.MCP$ERROR_FIELD_REQUIRED) }
76
83
  }));
77
84
  return;
78
85
  }
79
- P({
80
- id: `${F.kind}-${E}`,
81
- type: F.kind,
82
- url: F.url,
83
- ...e && { api_key: e }
86
+ L({
87
+ id: `${N.kind}-${r()}`,
88
+ type: N.kind,
89
+ url: N.url,
90
+ ...n && e && { api_key: e }
84
91
  });
85
- }, L = () => {
86
- if (F?.kind !== "stdio") return;
87
- let e = F, n = {};
88
- for (let r of e.envFields ?? []) r.required && !(D.values[r.key] ?? "").trim() && (n[r.key] = x(t.MCP$ERROR_FIELD_REQUIRED));
89
- for (let r of e.argFields ?? []) r.required && !(D.values[r.key] ?? "").trim() && (n[r.key] = x(t.MCP$ERROR_FIELD_REQUIRED));
92
+ }, z = () => {
93
+ if (N?.kind !== "stdio") return;
94
+ let e = N, n = {};
95
+ for (let r of e.envFields ?? []) r.required && !(O.values[r.key] ?? "").trim() && (n[r.key] = C(t.MCP$ERROR_FIELD_REQUIRED));
96
+ for (let r of e.argFields ?? []) r.required && !(O.values[r.key] ?? "").trim() && (n[r.key] = C(t.MCP$ERROR_FIELD_REQUIRED));
90
97
  if (Object.values(n).some(Boolean)) {
91
- O((e) => ({
98
+ k((e) => ({
92
99
  ...e,
93
100
  errors: n
94
101
  }));
95
102
  return;
96
103
  }
97
- let r = {};
104
+ let i = {};
98
105
  for (let t of e.envFields ?? []) {
99
- let e = D.values[t.key]?.trim();
100
- e && (r[t.key] = e);
106
+ let e = O.values[t.key]?.trim();
107
+ e && (i[t.key] = e);
101
108
  }
102
- let i = [];
109
+ let a = [];
103
110
  for (let t of e.argFields ?? []) {
104
- let e = D.values[t.key]?.trim();
105
- if (e) for (let t of e.split(/\s+/)) t && i.push(t);
111
+ let e = O.values[t.key]?.trim();
112
+ if (e) for (let t of e.split(/\s+/)) t && a.push(t);
106
113
  }
107
- P({
108
- id: `stdio-${E}`,
114
+ L({
115
+ id: `stdio-${r()}`,
109
116
  type: "stdio",
110
117
  name: e.serverName,
111
118
  command: e.command,
112
- args: [...e.args, ...i],
113
- ...Object.keys(r).length > 0 && { env: r }
119
+ args: [...e.args, ...a],
120
+ ...Object.keys(i).length > 0 && { env: i }
114
121
  });
115
122
  };
116
- return /* @__PURE__ */ h(r, {
117
- onClose: y,
118
- "aria-label": v.name,
123
+ return /* @__PURE__ */ h(i, {
124
+ onClose: x,
125
+ "aria-label": b.name,
119
126
  children: /* @__PURE__ */ g("form", {
120
127
  "data-testid": "mcp-install-modal",
121
- "data-marketplace-id": v.id,
122
- onSubmit: (e) => (e.preventDefault(), A(null), F?.kind === "shttp" || F?.kind === "sse" ? I() : L()),
128
+ "data-marketplace-id": b.id,
129
+ onSubmit: (e) => (e.preventDefault(), j(null), N?.kind === "shttp" || N?.kind === "sse" ? R() : z()),
123
130
  className: "relative bg-base-secondary p-6 rounded-xl flex flex-col gap-4 border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[85vh] overflow-y-auto custom-scrollbar",
124
131
  children: [
125
- /* @__PURE__ */ h(i, {
126
- onClose: y,
132
+ /* @__PURE__ */ h(a, {
133
+ onClose: x,
127
134
  testId: "mcp-install-modal-close",
128
- disabled: j
135
+ disabled: P
129
136
  }),
130
137
  /* @__PURE__ */ g("div", {
131
138
  className: "flex items-start gap-3 pr-6",
132
- children: [/* @__PURE__ */ h(l, { entry: v }), /* @__PURE__ */ g("div", {
139
+ children: [/* @__PURE__ */ h(u, { entry: b }), /* @__PURE__ */ g("div", {
133
140
  className: "flex flex-col flex-1",
134
141
  children: [/* @__PURE__ */ h("h2", {
135
142
  className: "text-lg font-semibold",
136
- children: v.name
143
+ children: b.name
137
144
  }), /* @__PURE__ */ h("p", {
138
145
  className: "text-xs text-tertiary-light",
139
- children: v.description
146
+ children: b.description
140
147
  })]
141
148
  })]
142
149
  }),
143
- v.installHint && /* @__PURE__ */ h("p", {
150
+ b.installHint && /* @__PURE__ */ h("p", {
144
151
  className: "text-xs text-tertiary-light",
145
- children: v.installHint
152
+ children: b.installHint
146
153
  }),
147
- v.docsUrl && /* @__PURE__ */ h("a", {
148
- href: v.docsUrl,
154
+ b.docsUrl && /* @__PURE__ */ h("a", {
155
+ href: b.docsUrl,
149
156
  target: "_blank",
150
157
  rel: "noreferrer",
151
158
  className: "text-xs text-[var(--oh-muted)] hover:text-white hover:underline self-start transition-colors",
152
- children: x(t.MCP$VIEW_DOCS)
159
+ children: C(t.MCP$VIEW_DOCS)
153
160
  }),
154
161
  /* @__PURE__ */ h("div", {
155
162
  className: "flex flex-col gap-3",
156
163
  children: (() => {
157
- if (!F) return null;
158
- if (F.kind === "shttp" || F.kind === "sse") {
159
- let e = F.apiKeyOptional ?? !1;
160
- return /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(o, {
164
+ if (N?.kind === "shttp" || N?.kind === "sse") {
165
+ let e = _(M), n = M ? v(M) : !1;
166
+ return /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(s, {
161
167
  testId: "mcp-install-field-url",
162
168
  name: "url",
163
169
  type: "url",
164
- label: x(t.SETTINGS$MCP_URL),
165
- value: F.url,
170
+ label: C(t.SETTINGS$MCP_URL),
171
+ value: N.url,
166
172
  onChange: () => {},
167
173
  isDisabled: !0,
168
174
  className: "w-full"
169
- }), /* @__PURE__ */ g("div", {
175
+ }), e ? /* @__PURE__ */ g("div", {
170
176
  className: "flex flex-col gap-1",
171
- children: [/* @__PURE__ */ h(o, {
177
+ children: [/* @__PURE__ */ h(s, {
172
178
  testId: "mcp-install-field-api_key",
173
179
  name: "api_key",
174
180
  type: "password",
175
- label: x(t.SETTINGS$MCP_API_KEY),
176
- value: D.values.api_key ?? "",
177
- onChange: (e) => M("api_key", e),
178
- placeholder: x(t.SETTINGS$MCP_API_KEY_PLACEHOLDER),
179
- showOptionalTag: e,
180
- required: !e,
181
+ label: C(t.SETTINGS$MCP_API_KEY),
182
+ value: O.values.api_key ?? "",
183
+ onChange: (e) => F("api_key", e),
184
+ placeholder: C(t.SETTINGS$MCP_API_KEY_PLACEHOLDER),
185
+ showOptionalTag: n,
186
+ required: !n,
181
187
  className: "w-full"
182
- }), D.errors.api_key && /* @__PURE__ */ h("p", {
188
+ }), O.errors.api_key && /* @__PURE__ */ h("p", {
183
189
  className: "text-xs text-red-500",
184
- children: D.errors.api_key
190
+ children: O.errors.api_key
185
191
  })]
186
- })] });
192
+ }) : null] });
187
193
  }
188
- let e = F;
194
+ if (N?.kind !== "stdio") return null;
195
+ let e = N;
189
196
  return /* @__PURE__ */ g(m, { children: [
190
- /* @__PURE__ */ h(o, {
197
+ /* @__PURE__ */ h(s, {
191
198
  testId: "mcp-install-field-command-readonly",
192
199
  name: "command-readonly",
193
200
  type: "text",
194
- label: x(t.MCP$COMMAND_LABEL),
201
+ label: C(t.MCP$COMMAND_LABEL),
195
202
  value: `${e.command} ${e.args.join(" ")}`.trim(),
196
203
  onChange: () => {},
197
204
  isDisabled: !0,
@@ -200,13 +207,13 @@ function v({ entry: v, onClose: y, onSuccess: b }) {
200
207
  (e.envFields ?? []).map((e) => /* @__PURE__ */ g("div", {
201
208
  className: "flex flex-col gap-1",
202
209
  children: [
203
- /* @__PURE__ */ h(o, {
210
+ /* @__PURE__ */ h(s, {
204
211
  testId: `mcp-install-field-${e.key}`,
205
212
  name: e.key,
206
213
  type: e.type === "password" ? "password" : "text",
207
214
  label: e.label,
208
- value: D.values[e.key] ?? "",
209
- onChange: (t) => M(e.key, t),
215
+ value: O.values[e.key] ?? "",
216
+ onChange: (t) => F(e.key, t),
210
217
  placeholder: e.placeholder,
211
218
  required: e.required,
212
219
  showOptionalTag: !e.required,
@@ -216,22 +223,22 @@ function v({ entry: v, onClose: y, onSuccess: b }) {
216
223
  className: "text-xs text-tertiary-alt",
217
224
  children: e.helperText
218
225
  }),
219
- D.errors[e.key] && /* @__PURE__ */ h("p", {
226
+ O.errors[e.key] && /* @__PURE__ */ h("p", {
220
227
  className: "text-xs text-red-500",
221
- children: D.errors[e.key]
228
+ children: O.errors[e.key]
222
229
  })
223
230
  ]
224
231
  }, e.key)),
225
232
  (e.argFields ?? []).map((e) => /* @__PURE__ */ g("div", {
226
233
  className: "flex flex-col gap-1",
227
234
  children: [
228
- /* @__PURE__ */ h(o, {
235
+ /* @__PURE__ */ h(s, {
229
236
  testId: `mcp-install-field-${e.key}`,
230
237
  name: e.key,
231
238
  type: e.type === "password" ? "password" : "text",
232
239
  label: e.label,
233
- value: D.values[e.key] ?? "",
234
- onChange: (t) => M(e.key, t),
240
+ value: O.values[e.key] ?? "",
241
+ onChange: (t) => F(e.key, t),
235
242
  placeholder: e.placeholder,
236
243
  required: e.required,
237
244
  showOptionalTag: !e.required,
@@ -241,34 +248,34 @@ function v({ entry: v, onClose: y, onSuccess: b }) {
241
248
  className: "text-xs text-tertiary-alt",
242
249
  children: e.helperText
243
250
  }),
244
- D.errors[e.key] && /* @__PURE__ */ h("p", {
251
+ O.errors[e.key] && /* @__PURE__ */ h("p", {
245
252
  className: "text-xs text-red-500",
246
- children: D.errors[e.key]
253
+ children: O.errors[e.key]
247
254
  })
248
255
  ]
249
256
  }, e.key))
250
257
  ] });
251
258
  })()
252
259
  }),
253
- k && /* @__PURE__ */ h("p", {
260
+ A && /* @__PURE__ */ h("p", {
254
261
  "data-testid": "mcp-install-modal-error",
255
262
  className: "text-sm text-red-500 whitespace-pre-wrap",
256
- children: k
263
+ children: A
257
264
  }),
258
265
  /* @__PURE__ */ g("div", {
259
266
  className: "flex justify-end gap-2 mt-2",
260
- children: [/* @__PURE__ */ h(a, {
267
+ children: [/* @__PURE__ */ h(o, {
261
268
  type: "button",
262
269
  variant: "secondary",
263
- onClick: y,
270
+ onClick: x,
264
271
  testId: "mcp-install-cancel",
265
- children: x(t.BUTTON$CANCEL)
266
- }), /* @__PURE__ */ h(a, {
272
+ children: C(t.BUTTON$CANCEL)
273
+ }), /* @__PURE__ */ h(o, {
267
274
  type: "submit",
268
275
  variant: "primary",
269
- isDisabled: j,
276
+ isDisabled: P,
270
277
  testId: "mcp-install-submit",
271
- children: x(T ? t.MCP$VERIFYING : C ? t.SETTINGS$SAVING : t.MCP$INSTALL_BUTTON)
278
+ children: C(D ? t.MCP$VERIFYING : T ? t.SETTINGS$SAVING : t.MCP$INSTALL_BUTTON)
272
279
  })]
273
280
  })
274
281
  ]
@@ -276,6 +283,6 @@ function v({ entry: v, onClose: y, onSuccess: b }) {
276
283
  });
277
284
  }
278
285
  //#endregion
279
- export { v as InstallServerModal };
286
+ export { b as InstallServerModal };
280
287
 
281
288
  //# sourceMappingURL=install-server-modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install-server-modal.js","names":[],"sources":["../../../../src/components/features/mcp-page/install-server-modal.tsx"],"sourcesContent":["import React, { useId } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { AxiosError } from \"axios\";\nimport type { MCPTestFailure } from \"@openhands/typescript-client\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { IntegrationCatalogEntry as MarketplaceEntry } from \"@openhands/extensions/integrations\";\nimport { McpLogoBadge } from \"#/components/features/mcp-logo-badge\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport { useAddMcpServer } from \"#/hooks/mutation/use-add-mcp-server\";\nimport { useTestMcpServer } from \"#/hooks/mutation/use-test-mcp-server\";\nimport { displaySuccessToast } from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\nimport { getInstallableTemplate } from \"#/utils/mcp-marketplace-utils\";\n\ninterface InstallServerModalProps {\n entry: MarketplaceEntry;\n onClose: () => void;\n onSuccess?: (entry: MarketplaceEntry) => void;\n}\n\ninterface FieldState {\n values: Record<string, string>;\n errors: Record<string, string | null>;\n}\n\nfunction makeInitialState(entry: MarketplaceEntry): FieldState {\n const values: Record<string, string> = {};\n const template = getInstallableTemplate(entry);\n if (!template) return { values, errors: {} };\n if (template.kind === \"stdio\") {\n for (const field of template.envFields ?? []) {\n values[field.key] = \"\";\n }\n for (const field of template.argFields ?? []) {\n values[field.key] = \"\";\n }\n } else if (template.kind === \"shttp\" || template.kind === \"sse\") {\n values.api_key = \"\";\n }\n return { values, errors: {} };\n}\n\n// The marketplace install modal is intentionally add-only: clicking\n// a catalog tile always appends a new server (the user might want\n// two Slack workspaces, two Postgres connections, etc.) even when\n// one of the same template kind is already installed. Editing an\n// existing server is reached via the installed-server-card's edit\n// button, which opens `CustomServerEditor` instead.\nexport function InstallServerModal({\n entry,\n onClose,\n onSuccess,\n}: InstallServerModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { mutate: addMcpServer, isPending: isAdding } = useAddMcpServer();\n const { mutate: testMcpServer, isPending: isTesting } = useTestMcpServer();\n const instanceId = useId();\n\n const [state, setState] = React.useState<FieldState>(() =>\n makeInitialState(entry),\n );\n const [globalError, setGlobalError] = React.useState<string | null>(null);\n\n const isPending = isTesting || isAdding;\n\n const setValue = (key: string, value: string) => {\n setState((prev) => ({\n values: { ...prev.values, [key]: value },\n errors: { ...prev.errors, [key]: null },\n }));\n setGlobalError(null);\n };\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 submitServer = (payload: MCPServerConfig) => {\n testMcpServer(payload, {\n onSuccess: (result) => {\n if (!result.ok) {\n setGlobalError(makeTestErrorMessage(result));\n // Modal stays open — do NOT call onClose.\n return;\n }\n addMcpServer(payload, {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.MCP$INSTALL_SUCCESS));\n onSuccess?.(entry);\n onClose();\n },\n onError: (err: unknown) => {\n const message = retrieveAxiosErrorMessage(err as AxiosError);\n setGlobalError(message || t(I18nKey.ERROR$GENERIC));\n },\n });\n },\n onError: (err: unknown) => {\n const message = retrieveAxiosErrorMessage(err as AxiosError);\n setGlobalError(message || t(I18nKey.ERROR$GENERIC));\n },\n });\n };\n\n const template = getInstallableTemplate(entry);\n\n // ------------------------------------------------------------------\n // Per-template submit handlers. Each is small and self-contained:\n // validate user input, build the payload, then hand off to\n // submitServer.\n // ------------------------------------------------------------------\n const handleHttpServerSubmit = () => {\n // TS narrows this branch to shttp|sse; the equality guard is a\n // runtime/defensive belt to make the helper safe in isolation.\n if (!template || (template.kind !== \"shttp\" && template.kind !== \"sse\")) {\n return;\n }\n const apiKey = state.values.api_key?.trim() ?? \"\";\n if (!template.apiKeyOptional && !apiKey) {\n setState((prev) => ({\n ...prev,\n errors: { api_key: t(I18nKey.MCP$ERROR_FIELD_REQUIRED) },\n }));\n return;\n }\n const payload: MCPServerConfig = {\n id: `${template.kind}-${instanceId}`,\n type: template.kind,\n url: template.url,\n ...(apiKey && { api_key: apiKey }),\n };\n submitServer(payload);\n };\n\n const handleStdioSubmit = () => {\n if (template?.kind !== \"stdio\") return;\n const stdio = template;\n const errors: Record<string, string | null> = {};\n\n for (const field of stdio.envFields ?? []) {\n if (field.required && !(state.values[field.key] ?? \"\").trim()) {\n errors[field.key] = t(I18nKey.MCP$ERROR_FIELD_REQUIRED);\n }\n }\n for (const field of stdio.argFields ?? []) {\n if (field.required && !(state.values[field.key] ?? \"\").trim()) {\n errors[field.key] = t(I18nKey.MCP$ERROR_FIELD_REQUIRED);\n }\n }\n if (Object.values(errors).some(Boolean)) {\n setState((prev) => ({ ...prev, errors }));\n return;\n }\n\n const env: Record<string, string> = {};\n for (const field of stdio.envFields ?? []) {\n const v = state.values[field.key]?.trim();\n if (v) env[field.key] = v;\n }\n const extraArgs: string[] = [];\n for (const field of stdio.argFields ?? []) {\n const v = state.values[field.key]?.trim();\n if (v) {\n // Filesystem-style multi-token input: split on whitespace.\n for (const token of v.split(/\\s+/)) {\n if (token) extraArgs.push(token);\n }\n }\n }\n\n const payload: MCPServerConfig = {\n id: `stdio-${instanceId}`,\n type: \"stdio\",\n name: stdio.serverName,\n command: stdio.command,\n args: [...stdio.args, ...extraArgs],\n ...(Object.keys(env).length > 0 && { env }),\n };\n submitServer(payload);\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setGlobalError(null);\n if (template?.kind === \"shttp\" || template?.kind === \"sse\") {\n return handleHttpServerSubmit();\n }\n return handleStdioSubmit();\n };\n\n const renderFields = () => {\n if (!template) return null;\n if (template.kind === \"shttp\" || template.kind === \"sse\") {\n const apiKeyOptional = template.apiKeyOptional ?? false;\n return (\n <>\n <SettingsInput\n testId=\"mcp-install-field-url\"\n name=\"url\"\n type=\"url\"\n label={t(I18nKey.SETTINGS$MCP_URL)}\n value={template.url}\n onChange={() => {}}\n isDisabled\n className=\"w-full\"\n />\n <div className=\"flex flex-col gap-1\">\n <SettingsInput\n testId=\"mcp-install-field-api_key\"\n name=\"api_key\"\n type=\"password\"\n label={t(I18nKey.SETTINGS$MCP_API_KEY)}\n value={state.values.api_key ?? \"\"}\n onChange={(v) => setValue(\"api_key\", v)}\n placeholder={t(I18nKey.SETTINGS$MCP_API_KEY_PLACEHOLDER)}\n showOptionalTag={apiKeyOptional}\n required={!apiKeyOptional}\n className=\"w-full\"\n />\n {state.errors.api_key && (\n <p className=\"text-xs text-red-500\">{state.errors.api_key}</p>\n )}\n </div>\n </>\n );\n }\n\n const stdio = template;\n return (\n <>\n <SettingsInput\n testId=\"mcp-install-field-command-readonly\"\n name=\"command-readonly\"\n type=\"text\"\n label={t(I18nKey.MCP$COMMAND_LABEL)}\n value={`${stdio.command} ${stdio.args.join(\" \")}`.trim()}\n onChange={() => {}}\n isDisabled\n className=\"w-full\"\n />\n {(stdio.envFields ?? []).map((field) => (\n <div key={field.key} className=\"flex flex-col gap-1\">\n <SettingsInput\n testId={`mcp-install-field-${field.key}`}\n name={field.key}\n type={field.type === \"password\" ? \"password\" : \"text\"}\n label={field.label}\n value={state.values[field.key] ?? \"\"}\n onChange={(v) => setValue(field.key, v)}\n placeholder={field.placeholder}\n required={field.required}\n showOptionalTag={!field.required}\n className=\"w-full\"\n />\n {field.helperText && (\n <p className=\"text-xs text-tertiary-alt\">{field.helperText}</p>\n )}\n {state.errors[field.key] && (\n <p className=\"text-xs text-red-500\">{state.errors[field.key]}</p>\n )}\n </div>\n ))}\n {(stdio.argFields ?? []).map((field) => (\n <div key={field.key} className=\"flex flex-col gap-1\">\n <SettingsInput\n testId={`mcp-install-field-${field.key}`}\n name={field.key}\n type={field.type === \"password\" ? \"password\" : \"text\"}\n label={field.label}\n value={state.values[field.key] ?? \"\"}\n onChange={(v) => setValue(field.key, v)}\n placeholder={field.placeholder}\n required={field.required}\n showOptionalTag={!field.required}\n className=\"w-full\"\n />\n {field.helperText && (\n <p className=\"text-xs text-tertiary-alt\">{field.helperText}</p>\n )}\n {state.errors[field.key] && (\n <p className=\"text-xs text-red-500\">{state.errors[field.key]}</p>\n )}\n </div>\n ))}\n </>\n );\n };\n\n return (\n <ModalBackdrop onClose={onClose} aria-label={entry.name}>\n <form\n data-testid=\"mcp-install-modal\"\n data-marketplace-id={entry.id}\n onSubmit={handleSubmit}\n className=\"relative bg-base-secondary p-6 rounded-xl flex flex-col gap-4 border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[85vh] overflow-y-auto custom-scrollbar\"\n >\n <ModalCloseButton\n onClose={onClose}\n testId=\"mcp-install-modal-close\"\n disabled={isPending}\n />\n <div className=\"flex items-start gap-3 pr-6\">\n <McpLogoBadge entry={entry} />\n <div className=\"flex flex-col flex-1\">\n <h2 className=\"text-lg font-semibold\">{entry.name}</h2>\n <p className=\"text-xs text-tertiary-light\">{entry.description}</p>\n </div>\n </div>\n\n {entry.installHint && (\n <p className=\"text-xs text-tertiary-light\">{entry.installHint}</p>\n )}\n\n {entry.docsUrl && (\n <a\n href={entry.docsUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-xs text-[var(--oh-muted)] hover:text-white hover:underline self-start transition-colors\"\n >\n {t(I18nKey.MCP$VIEW_DOCS)}\n </a>\n )}\n\n <div className=\"flex flex-col gap-3\">{renderFields()}</div>\n\n {globalError && (\n <p\n data-testid=\"mcp-install-modal-error\"\n className=\"text-sm text-red-500 whitespace-pre-wrap\"\n >\n {globalError}\n </p>\n )}\n\n <div className=\"flex justify-end gap-2 mt-2\">\n <BrandButton\n type=\"button\"\n variant=\"secondary\"\n onClick={onClose}\n testId=\"mcp-install-cancel\"\n >\n {t(I18nKey.BUTTON$CANCEL)}\n </BrandButton>\n <BrandButton\n type=\"submit\"\n variant=\"primary\"\n isDisabled={isPending}\n testId=\"mcp-install-submit\"\n >\n {isTesting\n ? t(I18nKey.MCP$VERIFYING)\n : isAdding\n ? t(I18nKey.SETTINGS$SAVING)\n : t(I18nKey.MCP$INSTALL_BUTTON)}\n </BrandButton>\n </div>\n </form>\n </ModalBackdrop>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"install-server-modal.js","names":[],"sources":["../../../../src/components/features/mcp-page/install-server-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { AxiosError } from \"axios\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { MCPTestFailure } from \"@openhands/typescript-client\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { IntegrationCatalogEntry as MarketplaceEntry } from \"@openhands/extensions/integrations\";\nimport { McpLogoBadge } from \"#/components/features/mcp-logo-badge\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport { useAddMcpServer } from \"#/hooks/mutation/use-add-mcp-server\";\nimport { useTestMcpServer } from \"#/hooks/mutation/use-test-mcp-server\";\nimport { displaySuccessToast } from \"#/utils/custom-toast-handlers\";\nimport {\n getInstallableMcpConnectionOption,\n type McpMarketplaceConnectionOption,\n} from \"#/utils/mcp-marketplace-utils\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\n\ninterface InstallServerModalProps {\n entry: MarketplaceEntry;\n onClose: () => void;\n onSuccess?: (entry: MarketplaceEntry) => void;\n}\n\ninterface FieldState {\n values: Record<string, string>;\n errors: Record<string, string | null>;\n}\n\nfunction optionNeedsCredentialField(\n option: McpMarketplaceConnectionOption | undefined,\n): boolean {\n if (option?.transport.kind !== \"shttp\" && option?.transport.kind !== \"sse\") {\n return false;\n }\n return [\"api_key\", \"bearer\", \"basic\"].includes(option.auth.strategy);\n}\n\nfunction isCredentialOptional(option: McpMarketplaceConnectionOption): boolean {\n if (option.transport.kind === \"stdio\") {\n return option.auth.apiKeyOptional ?? false;\n }\n return option.auth.apiKeyOptional ?? option.transport.apiKeyOptional ?? false;\n}\n\nfunction makeInitialState(entry: MarketplaceEntry): FieldState {\n const values: Record<string, string> = {};\n const option = getInstallableMcpConnectionOption(entry);\n const template = option?.transport;\n if (template?.kind === \"stdio\") {\n for (const field of template.envFields ?? []) {\n values[field.key] = \"\";\n }\n for (const field of template.argFields ?? []) {\n values[field.key] = \"\";\n }\n } else if (optionNeedsCredentialField(option)) {\n values.api_key = \"\";\n }\n return { values, errors: {} };\n}\n\n// The marketplace install modal is intentionally add-only: clicking\n// a catalog tile always appends a new server (the user might want\n// two Slack workspaces, two Postgres connections, etc.) even when\n// one of the same template kind is already installed. Editing an\n// existing server is reached via the installed-server-card's edit\n// button, which opens `CustomServerEditor` instead.\nexport function InstallServerModal({\n entry,\n onClose,\n onSuccess,\n}: InstallServerModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { mutate: addMcpServer, isPending: isAdding } = useAddMcpServer();\n const { mutate: testMcpServer, isPending: isTesting } = useTestMcpServer();\n\n const [state, setState] = React.useState<FieldState>(() =>\n makeInitialState(entry),\n );\n const [globalError, setGlobalError] = React.useState<string | null>(null);\n const option = getInstallableMcpConnectionOption(entry);\n const template = option?.transport;\n\n const isPending = isTesting || isAdding;\n\n const setValue = (key: string, value: string) => {\n setState((prev) => ({\n values: { ...prev.values, [key]: value },\n errors: { ...prev.errors, [key]: null },\n }));\n setGlobalError(null);\n };\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 submitServer = (payload: MCPServerConfig) => {\n testMcpServer(payload, {\n onSuccess: (result) => {\n if (!result.ok) {\n setGlobalError(makeTestErrorMessage(result));\n // Modal stays open — do NOT call onClose.\n return;\n }\n addMcpServer(payload, {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.MCP$INSTALL_SUCCESS));\n onSuccess?.(entry);\n onClose();\n },\n onError: (err: unknown) => {\n const message = retrieveAxiosErrorMessage(err as AxiosError);\n setGlobalError(message || t(I18nKey.ERROR$GENERIC));\n },\n });\n },\n onError: (err: unknown) => {\n const message = retrieveAxiosErrorMessage(err as AxiosError);\n setGlobalError(message || t(I18nKey.ERROR$GENERIC));\n },\n });\n };\n\n // ------------------------------------------------------------------\n // Per-template submit handlers. Each is small and self-contained:\n // validate user input, build the payload, then hand off to\n // submitServer.\n // ------------------------------------------------------------------\n const handleHttpServerSubmit = () => {\n // TS narrows this branch to shttp|sse; the equality guard is a\n // runtime/defensive belt to make the helper safe in isolation.\n if (template?.kind !== \"shttp\" && template?.kind !== \"sse\") {\n return;\n }\n if (!option) return;\n const apiKey = state.values.api_key?.trim() ?? \"\";\n const needsCredential = optionNeedsCredentialField(option);\n if (needsCredential && !isCredentialOptional(option) && !apiKey) {\n setState((prev) => ({\n ...prev,\n errors: { api_key: t(I18nKey.MCP$ERROR_FIELD_REQUIRED) },\n }));\n return;\n }\n const payload: MCPServerConfig = {\n id: `${template.kind}-${uuidv4()}`,\n type: template.kind,\n url: template.url,\n ...(needsCredential && apiKey && { api_key: apiKey }),\n };\n submitServer(payload);\n };\n\n const handleStdioSubmit = () => {\n if (template?.kind !== \"stdio\") return;\n const stdio = template;\n const errors: Record<string, string | null> = {};\n\n for (const field of stdio.envFields ?? []) {\n if (field.required && !(state.values[field.key] ?? \"\").trim()) {\n errors[field.key] = t(I18nKey.MCP$ERROR_FIELD_REQUIRED);\n }\n }\n for (const field of stdio.argFields ?? []) {\n if (field.required && !(state.values[field.key] ?? \"\").trim()) {\n errors[field.key] = t(I18nKey.MCP$ERROR_FIELD_REQUIRED);\n }\n }\n if (Object.values(errors).some(Boolean)) {\n setState((prev) => ({ ...prev, errors }));\n return;\n }\n\n const env: Record<string, string> = {};\n for (const field of stdio.envFields ?? []) {\n const v = state.values[field.key]?.trim();\n if (v) env[field.key] = v;\n }\n const extraArgs: string[] = [];\n for (const field of stdio.argFields ?? []) {\n const v = state.values[field.key]?.trim();\n if (v) {\n // Filesystem-style multi-token input: split on whitespace.\n for (const token of v.split(/\\s+/)) {\n if (token) extraArgs.push(token);\n }\n }\n }\n\n const payload: MCPServerConfig = {\n id: `stdio-${uuidv4()}`,\n type: \"stdio\",\n name: stdio.serverName,\n command: stdio.command,\n args: [...stdio.args, ...extraArgs],\n ...(Object.keys(env).length > 0 && { env }),\n };\n submitServer(payload);\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setGlobalError(null);\n if (template?.kind === \"shttp\" || template?.kind === \"sse\") {\n return handleHttpServerSubmit();\n }\n return handleStdioSubmit();\n };\n\n const renderFields = () => {\n if (template?.kind === \"shttp\" || template?.kind === \"sse\") {\n const shouldRenderCredential = optionNeedsCredentialField(option);\n const apiKeyOptional = option ? isCredentialOptional(option) : false;\n return (\n <>\n <SettingsInput\n testId=\"mcp-install-field-url\"\n name=\"url\"\n type=\"url\"\n label={t(I18nKey.SETTINGS$MCP_URL)}\n value={template.url}\n onChange={() => {}}\n isDisabled\n className=\"w-full\"\n />\n {shouldRenderCredential ? (\n <div className=\"flex flex-col gap-1\">\n <SettingsInput\n testId=\"mcp-install-field-api_key\"\n name=\"api_key\"\n type=\"password\"\n label={t(I18nKey.SETTINGS$MCP_API_KEY)}\n value={state.values.api_key ?? \"\"}\n onChange={(v) => setValue(\"api_key\", v)}\n placeholder={t(I18nKey.SETTINGS$MCP_API_KEY_PLACEHOLDER)}\n showOptionalTag={apiKeyOptional}\n required={!apiKeyOptional}\n className=\"w-full\"\n />\n {state.errors.api_key && (\n <p className=\"text-xs text-red-500\">{state.errors.api_key}</p>\n )}\n </div>\n ) : null}\n </>\n );\n }\n\n if (template?.kind !== \"stdio\") return null;\n const stdio = template;\n return (\n <>\n <SettingsInput\n testId=\"mcp-install-field-command-readonly\"\n name=\"command-readonly\"\n type=\"text\"\n label={t(I18nKey.MCP$COMMAND_LABEL)}\n value={`${stdio.command} ${stdio.args.join(\" \")}`.trim()}\n onChange={() => {}}\n isDisabled\n className=\"w-full\"\n />\n {(stdio.envFields ?? []).map((field) => (\n <div key={field.key} className=\"flex flex-col gap-1\">\n <SettingsInput\n testId={`mcp-install-field-${field.key}`}\n name={field.key}\n type={field.type === \"password\" ? \"password\" : \"text\"}\n label={field.label}\n value={state.values[field.key] ?? \"\"}\n onChange={(v) => setValue(field.key, v)}\n placeholder={field.placeholder}\n required={field.required}\n showOptionalTag={!field.required}\n className=\"w-full\"\n />\n {field.helperText && (\n <p className=\"text-xs text-tertiary-alt\">{field.helperText}</p>\n )}\n {state.errors[field.key] && (\n <p className=\"text-xs text-red-500\">{state.errors[field.key]}</p>\n )}\n </div>\n ))}\n {(stdio.argFields ?? []).map((field) => (\n <div key={field.key} className=\"flex flex-col gap-1\">\n <SettingsInput\n testId={`mcp-install-field-${field.key}`}\n name={field.key}\n type={field.type === \"password\" ? \"password\" : \"text\"}\n label={field.label}\n value={state.values[field.key] ?? \"\"}\n onChange={(v) => setValue(field.key, v)}\n placeholder={field.placeholder}\n required={field.required}\n showOptionalTag={!field.required}\n className=\"w-full\"\n />\n {field.helperText && (\n <p className=\"text-xs text-tertiary-alt\">{field.helperText}</p>\n )}\n {state.errors[field.key] && (\n <p className=\"text-xs text-red-500\">{state.errors[field.key]}</p>\n )}\n </div>\n ))}\n </>\n );\n };\n\n return (\n <ModalBackdrop onClose={onClose} aria-label={entry.name}>\n <form\n data-testid=\"mcp-install-modal\"\n data-marketplace-id={entry.id}\n onSubmit={handleSubmit}\n className=\"relative bg-base-secondary p-6 rounded-xl flex flex-col gap-4 border border-[var(--oh-border)] w-[520px] max-w-[90vw] max-h-[85vh] overflow-y-auto custom-scrollbar\"\n >\n <ModalCloseButton\n onClose={onClose}\n testId=\"mcp-install-modal-close\"\n disabled={isPending}\n />\n <div className=\"flex items-start gap-3 pr-6\">\n <McpLogoBadge entry={entry} />\n <div className=\"flex flex-col flex-1\">\n <h2 className=\"text-lg font-semibold\">{entry.name}</h2>\n <p className=\"text-xs text-tertiary-light\">{entry.description}</p>\n </div>\n </div>\n\n {entry.installHint && (\n <p className=\"text-xs text-tertiary-light\">{entry.installHint}</p>\n )}\n\n {entry.docsUrl && (\n <a\n href={entry.docsUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-xs text-[var(--oh-muted)] hover:text-white hover:underline self-start transition-colors\"\n >\n {t(I18nKey.MCP$VIEW_DOCS)}\n </a>\n )}\n\n <div className=\"flex flex-col gap-3\">{renderFields()}</div>\n\n {globalError && (\n <p\n data-testid=\"mcp-install-modal-error\"\n className=\"text-sm text-red-500 whitespace-pre-wrap\"\n >\n {globalError}\n </p>\n )}\n\n <div className=\"flex justify-end gap-2 mt-2\">\n <BrandButton\n type=\"button\"\n variant=\"secondary\"\n onClick={onClose}\n testId=\"mcp-install-cancel\"\n >\n {t(I18nKey.BUTTON$CANCEL)}\n </BrandButton>\n <BrandButton\n type=\"submit\"\n variant=\"primary\"\n isDisabled={isPending}\n testId=\"mcp-install-submit\"\n >\n {isTesting\n ? t(I18nKey.MCP$VERIFYING)\n : isAdding\n ? t(I18nKey.SETTINGS$SAVING)\n : t(I18nKey.MCP$INSTALL_BUTTON)}\n </BrandButton>\n </div>\n </form>\n </ModalBackdrop>\n );\n}\n"],"mappings":"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"}
@@ -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/utils.cjs`),i=require(`../../../node_modules/lucide-react/dist/esm/icons/puzzle.cjs`),a=require(`../../../utils/mcp-marketplace-utils.cjs`),o=require(`../../../node_modules/@openhands/extensions/integrations/index.cjs`),s=require(`../mcp-logo-badge.cjs`),c=require(`../../shared/buttons/circle-plus-check-toggle.cjs`),l=require(`../../../utils/extension-module-card-classes.cjs`);let u=require(`react`);u=e.__toESM(u,1);let d=require(`react/jsx-runtime`);function f(e){switch(e){case`sse`:return`SSE`;case`shttp`:return`HTTP`;case`stdio`:return`STDIO`;default:return e}}function p(e){return e.type===`stdio`?e.name??e.command??``:e.url??``}function m(e){if(e.type===`stdio`){let t=e.args&&e.args.length>0?` ${e.args.join(` `)}`:``;return`${e.command??``}${t}`.trim()}return e.url??``}function h({server:e,onEdit:u,onDelete:h}){let{t:g}=t.useTranslation(`openhands`),_=a.findCatalogEntryForServer(e,o.default),v=_?.name??p(e),y=m(e),b=f(e.type);return(0,d.jsx)(`div`,{"data-testid":`mcp-server-item`,"data-server-id":e.id,role:`button`,tabIndex:0,onClick:u,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),u())},"aria-label":g(n.I18nKey.MCP$EDIT_SERVER_ARIA,{name:v}),className:r.cn(`flex min-h-[132px] flex-col overflow-hidden p-4 text-left`,l.extensionModuleCardSurfaceClassName,l.extensionModuleCardInteractiveClassName),children:(0,d.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,d.jsx)(s.McpLogoBadge,{entry:_,fallback:(0,d.jsx)(i.Puzzle,{strokeWidth:2.25})}),(0,d.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-3`,children:[(0,d.jsxs)(`header`,{className:`flex items-start justify-between gap-3`,children:[(0,d.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,d.jsx)(`h3`,{className:`truncate text-sm font-semibold`,title:v,children:v}),(0,d.jsx)(`p`,{className:`mt-0.5 text-xs text-tertiary-alt`,children:b})]}),(0,d.jsx)(c.CirclePlusCheckToggle,{testId:`mcp-installed-toggle-${e.id}`,isSelected:!0,onToggle:e=>{e||h()},enableLabelKey:n.I18nKey.MCP$TOGGLE_ADD_SERVER,disableLabelKey:n.I18nKey.MCP$TOGGLE_REMOVE_SERVER})]}),_?.description?(0,d.jsx)(`p`,{"data-testid":`mcp-server-description-${e.id}`,className:`line-clamp-2 break-words text-xs leading-relaxed text-tertiary-light`,children:_.description}):null,y?(0,d.jsx)(`p`,{"data-testid":`mcp-server-detail-${e.id}`,className:`truncate text-xs text-tertiary-alt`,title:y,children:y}):null]})]})})}exports.InstalledServerCard=h;
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/utils.cjs`),i=require(`../../../node_modules/lucide-react/dist/esm/icons/puzzle.cjs`),a=require(`../../../utils/mcp-marketplace-utils.cjs`),o=require(`../../../node_modules/@openhands/extensions/integrations/index.cjs`),s=require(`../mcp-logo-badge.cjs`),c=require(`../../shared/buttons/circle-plus-check-toggle.cjs`),l=require(`../../../utils/extension-module-card-classes.cjs`);let u=require(`react`);u=e.__toESM(u,1);let d=require(`react/jsx-runtime`);function f(e){switch(e){case`sse`:return`SSE`;case`shttp`:return`HTTP`;case`stdio`:return`STDIO`;default:return e}}function p(e){return e.type===`stdio`?e.name??e.command??``:e.url??``}function m(e){if(e.type===`stdio`){let t=e.args&&e.args.length>0?` ${e.args.join(` `)}`:``;return`${e.command??``}${t}`.trim()}return e.url??``}function h({server:e,onEdit:u,onDelete:h}){let{t:g}=t.useTranslation(`openhands`),_=a.findCatalogEntryForServer(e,a.getMcpMarketplaceCatalog(o.default)),v=_?.name??p(e),y=m(e),b=f(e.type);return(0,d.jsx)(`div`,{"data-testid":`mcp-server-item`,"data-server-id":e.id,role:`button`,tabIndex:0,onClick:u,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),u())},"aria-label":g(n.I18nKey.MCP$EDIT_SERVER_ARIA,{name:v}),className:r.cn(`flex min-h-[132px] flex-col overflow-hidden p-4 text-left`,l.extensionModuleCardSurfaceClassName,l.extensionModuleCardInteractiveClassName),children:(0,d.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,d.jsx)(s.McpLogoBadge,{entry:_,fallback:(0,d.jsx)(i.Puzzle,{strokeWidth:2.25})}),(0,d.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-3`,children:[(0,d.jsxs)(`header`,{className:`flex items-start justify-between gap-3`,children:[(0,d.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,d.jsx)(`h3`,{className:`truncate text-sm font-semibold`,title:v,children:v}),(0,d.jsx)(`p`,{className:`mt-0.5 text-xs text-tertiary-alt`,children:b})]}),(0,d.jsx)(c.CirclePlusCheckToggle,{testId:`mcp-installed-toggle-${e.id}`,isSelected:!0,onToggle:e=>{e||h()},enableLabelKey:n.I18nKey.MCP$TOGGLE_ADD_SERVER,disableLabelKey:n.I18nKey.MCP$TOGGLE_REMOVE_SERVER})]}),_?.description?(0,d.jsx)(`p`,{"data-testid":`mcp-server-description-${e.id}`,className:`line-clamp-2 break-words text-xs leading-relaxed text-tertiary-light`,children:_.description}):null,y?(0,d.jsx)(`p`,{"data-testid":`mcp-server-detail-${e.id}`,className:`truncate text-xs text-tertiary-alt`,title:y,children:y}):null]})]})})}exports.InstalledServerCard=h;
2
2
  //# sourceMappingURL=installed-server-card.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"installed-server-card.cjs","names":[],"sources":["../../../../src/components/features/mcp-page/installed-server-card.tsx"],"sourcesContent":["import React from \"react\";\nimport { Puzzle } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { McpLogoBadge } from \"#/components/features/mcp-logo-badge\";\nimport { CirclePlusCheckToggle } from \"#/components/shared/buttons/circle-plus-check-toggle\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport { INTEGRATION_CATALOG as INTEGRATION_MARKETPLACE } from \"@openhands/extensions/integrations\";\nimport { findCatalogEntryForServer } from \"#/utils/mcp-marketplace-utils\";\nimport { cn } from \"#/utils/utils\";\nimport {\n extensionModuleCardInteractiveClassName,\n extensionModuleCardSurfaceClassName,\n} from \"#/utils/extension-module-card-classes\";\n\ninterface InstalledServerCardProps {\n server: MCPServerConfig;\n onEdit: () => void;\n onDelete: () => void;\n}\n\nfunction getServerTransportLabel(type: MCPServerConfig[\"type\"]) {\n switch (type) {\n case \"sse\":\n return \"SSE\";\n case \"shttp\":\n return \"HTTP\";\n case \"stdio\":\n return \"STDIO\";\n default:\n return type;\n }\n}\n\nfunction getServerTitle(server: MCPServerConfig): string {\n if (server.type === \"stdio\") return server.name ?? server.command ?? \"\";\n return server.url ?? \"\";\n}\n\nfunction getServerDetailLine(server: MCPServerConfig): string {\n if (server.type === \"stdio\") {\n const args =\n server.args && server.args.length > 0 ? ` ${server.args.join(\" \")}` : \"\";\n return `${server.command ?? \"\"}${args}`.trim();\n }\n return server.url ?? \"\";\n}\n\nexport function InstalledServerCard({\n server,\n onEdit,\n onDelete,\n}: InstalledServerCardProps) {\n const { t } = useTranslation(\"openhands\");\n const catalog = findCatalogEntryForServer(server, INTEGRATION_MARKETPLACE);\n\n const title = catalog?.name ?? getServerTitle(server);\n const detailLine = getServerDetailLine(server);\n const transport = getServerTransportLabel(server.type);\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onEdit();\n }\n };\n\n return (\n <div\n data-testid=\"mcp-server-item\"\n data-server-id={server.id}\n role=\"button\"\n tabIndex={0}\n onClick={onEdit}\n onKeyDown={handleKeyDown}\n aria-label={t(I18nKey.MCP$EDIT_SERVER_ARIA, { name: title })}\n className={cn(\n \"flex min-h-[132px] flex-col overflow-hidden p-4 text-left\",\n extensionModuleCardSurfaceClassName,\n extensionModuleCardInteractiveClassName,\n )}\n >\n <div className=\"flex items-start gap-3\">\n <McpLogoBadge\n entry={catalog}\n fallback={<Puzzle strokeWidth={2.25} />}\n />\n\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n <header className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-sm font-semibold\" title={title}>\n {title}\n </h3>\n <p className=\"mt-0.5 text-xs text-tertiary-alt\">{transport}</p>\n </div>\n <CirclePlusCheckToggle\n testId={`mcp-installed-toggle-${server.id}`}\n isSelected\n onToggle={(selected) => {\n if (!selected) {\n onDelete();\n }\n }}\n enableLabelKey={I18nKey.MCP$TOGGLE_ADD_SERVER}\n disableLabelKey={I18nKey.MCP$TOGGLE_REMOVE_SERVER}\n />\n </header>\n\n {catalog?.description ? (\n <p\n data-testid={`mcp-server-description-${server.id}`}\n className=\"line-clamp-2 break-words text-xs leading-relaxed text-tertiary-light\"\n >\n {catalog.description}\n </p>\n ) : null}\n\n {detailLine ? (\n <p\n data-testid={`mcp-server-detail-${server.id}`}\n className=\"truncate text-xs text-tertiary-alt\"\n title={detailLine}\n >\n {detailLine}\n </p>\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"mpBAqBA,SAAS,EAAwB,EAA+B,CAC9D,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,MACT,IAAK,QACH,MAAO,OACT,IAAK,QACH,MAAO,QACT,QACE,OAAO,GAIb,SAAS,EAAe,EAAiC,CAEvD,OADI,EAAO,OAAS,QAAgB,EAAO,MAAQ,EAAO,SAAW,GAC9D,EAAO,KAAO,GAGvB,SAAS,EAAoB,EAAiC,CAC5D,GAAI,EAAO,OAAS,QAAS,CAC3B,IAAM,EACJ,EAAO,MAAQ,EAAO,KAAK,OAAS,EAAI,IAAI,EAAO,KAAK,KAAK,IAAI,GAAK,GACxE,MAAO,GAAG,EAAO,SAAW,KAAK,IAAO,MAAM,CAEhD,OAAO,EAAO,KAAO,GAGvB,SAAgB,EAAoB,CAClC,SACA,SACA,YAC2B,CAC3B,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,EAAU,EAAA,0BAA0B,EAAQ,EAAA,QAAwB,CAEpE,EAAQ,GAAS,MAAQ,EAAe,EAAO,CAC/C,EAAa,EAAoB,EAAO,CACxC,EAAY,EAAwB,EAAO,KAAK,CAStD,OACE,EAAA,EAAA,KAAC,MAAD,CACE,cAAY,kBACZ,iBAAgB,EAAO,GACvB,KAAK,SACL,SAAU,EACV,QAAS,EACT,UAdmB,GAA+B,EAChD,EAAM,MAAQ,SAAW,EAAM,MAAQ,OACzC,EAAM,gBAAgB,CACtB,GAAQ,GAYR,aAAY,EAAE,EAAA,QAAQ,qBAAsB,CAAE,KAAM,EAAO,CAAC,CAC5D,UAAW,EAAA,GACT,4DACA,EAAA,oCACA,EAAA,wCACD,WAED,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kCAAf,EACE,EAAA,EAAA,KAAC,EAAA,aAAD,CACE,MAAO,EACP,UAAU,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,YAAa,KAAQ,CAAA,CACvC,CAAA,EAEF,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,8CAAf,EACE,EAAA,EAAA,MAAC,SAAD,CAAQ,UAAU,kDAAlB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0BAAf,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCAAwC,iBACnD,EACE,CAAA,EACL,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,4CAAoC,EAAc,CAAA,CAC3D,IACN,EAAA,EAAA,KAAC,EAAA,sBAAD,CACE,OAAQ,wBAAwB,EAAO,KACvC,WAAA,GACA,SAAW,GAAa,CACjB,GACH,GAAU,EAGd,eAAgB,EAAA,QAAQ,sBACxB,gBAAiB,EAAA,QAAQ,yBACzB,CAAA,CACK,GAER,GAAS,aACR,EAAA,EAAA,KAAC,IAAD,CACE,cAAa,0BAA0B,EAAO,KAC9C,UAAU,gFAET,EAAQ,YACP,CAAA,CACF,KAEH,GACC,EAAA,EAAA,KAAC,IAAD,CACE,cAAa,qBAAqB,EAAO,KACzC,UAAU,qCACV,MAAO,WAEN,EACC,CAAA,CACF,KACA,GACF,GACF,CAAA"}
1
+ {"version":3,"file":"installed-server-card.cjs","names":[],"sources":["../../../../src/components/features/mcp-page/installed-server-card.tsx"],"sourcesContent":["import React from \"react\";\nimport { Puzzle } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { McpLogoBadge } from \"#/components/features/mcp-logo-badge\";\nimport { CirclePlusCheckToggle } from \"#/components/shared/buttons/circle-plus-check-toggle\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport { INTEGRATION_CATALOG as MCP_MARKETPLACE } from \"@openhands/extensions/integrations\";\nimport {\n findCatalogEntryForServer,\n getMcpMarketplaceCatalog,\n} from \"#/utils/mcp-marketplace-utils\";\nimport { cn } from \"#/utils/utils\";\nimport {\n extensionModuleCardInteractiveClassName,\n extensionModuleCardSurfaceClassName,\n} from \"#/utils/extension-module-card-classes\";\n\ninterface InstalledServerCardProps {\n server: MCPServerConfig;\n onEdit: () => void;\n onDelete: () => void;\n}\n\nfunction getServerTransportLabel(type: MCPServerConfig[\"type\"]) {\n switch (type) {\n case \"sse\":\n return \"SSE\";\n case \"shttp\":\n return \"HTTP\";\n case \"stdio\":\n return \"STDIO\";\n default:\n return type;\n }\n}\n\nfunction getServerTitle(server: MCPServerConfig): string {\n if (server.type === \"stdio\") return server.name ?? server.command ?? \"\";\n return server.url ?? \"\";\n}\n\nfunction getServerDetailLine(server: MCPServerConfig): string {\n if (server.type === \"stdio\") {\n const args =\n server.args && server.args.length > 0 ? ` ${server.args.join(\" \")}` : \"\";\n return `${server.command ?? \"\"}${args}`.trim();\n }\n return server.url ?? \"\";\n}\n\nexport function InstalledServerCard({\n server,\n onEdit,\n onDelete,\n}: InstalledServerCardProps) {\n const { t } = useTranslation(\"openhands\");\n const catalog = findCatalogEntryForServer(\n server,\n getMcpMarketplaceCatalog(MCP_MARKETPLACE),\n );\n\n const title = catalog?.name ?? getServerTitle(server);\n const detailLine = getServerDetailLine(server);\n const transport = getServerTransportLabel(server.type);\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onEdit();\n }\n };\n\n return (\n <div\n data-testid=\"mcp-server-item\"\n data-server-id={server.id}\n role=\"button\"\n tabIndex={0}\n onClick={onEdit}\n onKeyDown={handleKeyDown}\n aria-label={t(I18nKey.MCP$EDIT_SERVER_ARIA, { name: title })}\n className={cn(\n \"flex min-h-[132px] flex-col overflow-hidden p-4 text-left\",\n extensionModuleCardSurfaceClassName,\n extensionModuleCardInteractiveClassName,\n )}\n >\n <div className=\"flex items-start gap-3\">\n <McpLogoBadge\n entry={catalog}\n fallback={<Puzzle strokeWidth={2.25} />}\n />\n\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n <header className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-sm font-semibold\" title={title}>\n {title}\n </h3>\n <p className=\"mt-0.5 text-xs text-tertiary-alt\">{transport}</p>\n </div>\n <CirclePlusCheckToggle\n testId={`mcp-installed-toggle-${server.id}`}\n isSelected\n onToggle={(selected) => {\n if (!selected) {\n onDelete();\n }\n }}\n enableLabelKey={I18nKey.MCP$TOGGLE_ADD_SERVER}\n disableLabelKey={I18nKey.MCP$TOGGLE_REMOVE_SERVER}\n />\n </header>\n\n {catalog?.description ? (\n <p\n data-testid={`mcp-server-description-${server.id}`}\n className=\"line-clamp-2 break-words text-xs leading-relaxed text-tertiary-light\"\n >\n {catalog.description}\n </p>\n ) : null}\n\n {detailLine ? (\n <p\n data-testid={`mcp-server-detail-${server.id}`}\n className=\"truncate text-xs text-tertiary-alt\"\n title={detailLine}\n >\n {detailLine}\n </p>\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"mpBAwBA,SAAS,EAAwB,EAA+B,CAC9D,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,MACT,IAAK,QACH,MAAO,OACT,IAAK,QACH,MAAO,QACT,QACE,OAAO,GAIb,SAAS,EAAe,EAAiC,CAEvD,OADI,EAAO,OAAS,QAAgB,EAAO,MAAQ,EAAO,SAAW,GAC9D,EAAO,KAAO,GAGvB,SAAS,EAAoB,EAAiC,CAC5D,GAAI,EAAO,OAAS,QAAS,CAC3B,IAAM,EACJ,EAAO,MAAQ,EAAO,KAAK,OAAS,EAAI,IAAI,EAAO,KAAK,KAAK,IAAI,GAAK,GACxE,MAAO,GAAG,EAAO,SAAW,KAAK,IAAO,MAAM,CAEhD,OAAO,EAAO,KAAO,GAGvB,SAAgB,EAAoB,CAClC,SACA,SACA,YAC2B,CAC3B,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,EAAU,EAAA,0BACd,EACA,EAAA,yBAAyB,EAAA,QAAgB,CAC1C,CAEK,EAAQ,GAAS,MAAQ,EAAe,EAAO,CAC/C,EAAa,EAAoB,EAAO,CACxC,EAAY,EAAwB,EAAO,KAAK,CAStD,OACE,EAAA,EAAA,KAAC,MAAD,CACE,cAAY,kBACZ,iBAAgB,EAAO,GACvB,KAAK,SACL,SAAU,EACV,QAAS,EACT,UAdmB,GAA+B,EAChD,EAAM,MAAQ,SAAW,EAAM,MAAQ,OACzC,EAAM,gBAAgB,CACtB,GAAQ,GAYR,aAAY,EAAE,EAAA,QAAQ,qBAAsB,CAAE,KAAM,EAAO,CAAC,CAC5D,UAAW,EAAA,GACT,4DACA,EAAA,oCACA,EAAA,wCACD,WAED,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kCAAf,EACE,EAAA,EAAA,KAAC,EAAA,aAAD,CACE,MAAO,EACP,UAAU,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,YAAa,KAAQ,CAAA,CACvC,CAAA,EAEF,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,8CAAf,EACE,EAAA,EAAA,MAAC,SAAD,CAAQ,UAAU,kDAAlB,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0BAAf,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCAAwC,iBACnD,EACE,CAAA,EACL,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,4CAAoC,EAAc,CAAA,CAC3D,IACN,EAAA,EAAA,KAAC,EAAA,sBAAD,CACE,OAAQ,wBAAwB,EAAO,KACvC,WAAA,GACA,SAAW,GAAa,CACjB,GACH,GAAU,EAGd,eAAgB,EAAA,QAAQ,sBACxB,gBAAiB,EAAA,QAAQ,yBACzB,CAAA,CACK,GAER,GAAS,aACR,EAAA,EAAA,KAAC,IAAD,CACE,cAAa,0BAA0B,EAAO,KAC9C,UAAU,gFAET,EAAQ,YACP,CAAA,CACF,KAEH,GACC,EAAA,EAAA,KAAC,IAAD,CACE,cAAa,qBAAqB,EAAO,KACzC,UAAU,qCACV,MAAO,WAEN,EACC,CAAA,CACF,KACA,GACF,GACF,CAAA"}