@openhands/agent-canvas 1.7.2 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (599) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{Trans-DP5rcauH.js → Trans-Bwpzk1wT.js} +1 -1
  4. package/build/assets/{acp-providers-BHKZvEm5.js → acp-providers-C921BlYB.js} +1 -1
  5. package/build/assets/active-backend-context-BiwzkzDy.js +2 -0
  6. package/build/assets/agent-context-settings-DXNT_dcw.js +1 -0
  7. package/build/assets/agent-profiles-settings-BymJf3EP.js +1 -0
  8. package/build/assets/agent-server-conversation-service.api-CYSWw-2g.js +41 -0
  9. package/build/assets/agent-settings-BjgQQe-_.js +1 -0
  10. package/build/assets/{agent-settings-BIOsUglV.js → agent-settings-WzqXk6B4.js} +2 -2
  11. package/build/assets/{alert-banner-C1nzoXBC.js → alert-banner-DR8EVyZM.js} +1 -1
  12. package/build/assets/api-error-message-e16L1kwH.js +1 -0
  13. package/build/assets/api-key-entry-screen-DI0I04O3.js +1 -0
  14. package/build/assets/app-settings-DGistSFV.js +1 -0
  15. package/build/assets/automation-C_eCrGyP.js +1 -0
  16. package/build/assets/automation-detail-DY6x2FW1.js +2 -0
  17. package/build/assets/automation-export-C09f-Lua.js +2 -0
  18. package/build/assets/automation-setup-route-CqKp0717.js +1 -0
  19. package/build/assets/automations-list-CqWJ7qXW.js +1 -0
  20. package/build/assets/{back-nav-button-Be_L157B.js → back-nav-button-D4ngzpSh.js} +1 -1
  21. package/build/assets/backend-form-modal-B8D5hBzK.js +1 -0
  22. package/build/assets/{backend-synced-settings-badge-BNpEylNP.js → backend-synced-settings-badge-BnzI8Ysj.js} +1 -1
  23. package/build/assets/{badge-DwgrwohM.js → badge-1Mf1iPcX.js} +1 -1
  24. package/build/assets/{base-modal-CSHhJTSr.js → base-modal-BBuy0WQQ.js} +1 -1
  25. package/build/assets/{brand-button-CQO8oqVo.js → brand-button-DGN6Y9o6.js} +1 -1
  26. package/build/assets/browser-D_ekTlTS.js +6 -0
  27. package/build/assets/{browser-tab-CEApjoEV.js → browser-tab-D4a4Ou_w.js} +1 -1
  28. package/build/assets/{chat-send-button-D4614wUz.js → chat-send-button-CgbcjD97.js} +1 -1
  29. package/build/assets/check-CPLXgluF.js +1 -0
  30. package/build/assets/chevron-down-CP4QHvyc.js +1 -0
  31. package/build/assets/circle-check-Dpy2_xSI.js +1 -0
  32. package/build/assets/{circle-plus-check-toggle-E3Ecb_gg.js → circle-plus-check-toggle-yTAS-nX3.js} +1 -1
  33. package/build/assets/cloud-funnel-analytics-CEOl5Gxr.js +1 -0
  34. package/build/assets/{combobox-caret-C8_eGdp2.js → combobox-caret-Bd2yySnF.js} +1 -1
  35. package/build/assets/command-menu-Bj6X4ckE.js +1 -0
  36. package/build/assets/condenser-settings-EAXQNR2E.js +1 -0
  37. package/build/assets/{confirmation-modal-gZtbojCm.js → confirmation-modal-NCUPr2-O.js} +1 -1
  38. package/build/assets/{context-menu-list-item-BTHGFhIx.js → context-menu-list-item-CrCrYuPF.js} +1 -1
  39. package/build/assets/conversation-BzyIcSwr.js +1 -0
  40. package/build/assets/conversation-CUJ0Vo8g.js +90 -0
  41. package/build/assets/conversation-panel-BzyIcSwr.js +1 -0
  42. package/build/assets/conversation-state-store-F62HvuI1.js +1 -0
  43. package/build/assets/{conversation-tab-empty-state-BCMHkGQk.js → conversation-tab-empty-state-BCZ7rUMH.js} +1 -1
  44. package/build/assets/{copy-B8Y5ufoR.js → copy-DCmZtz6n.js} +1 -1
  45. package/build/assets/{copy-to-clipboard-button-C4l3CMSd.js → copy-to-clipboard-button-D_Lp6-Fl.js} +1 -1
  46. package/build/assets/{device-verify-C_M7Z8xs.js → device-verify-DLmolX8Q.js} +1 -1
  47. package/build/assets/{dropdown-classes-DQlj-MpS.js → dropdown-classes-BB8rzqXL.js} +1 -1
  48. package/build/assets/{entry.client-DETaouwO.js → entry.client-BbIYOsIg.js} +2 -2
  49. package/build/assets/{enum-filter-dropdown-paB-lFSP.js → enum-filter-dropdown-C08-srev.js} +1 -1
  50. package/build/assets/{environment-switch-overlay-D0FgCMqs.js → environment-switch-overlay-BepBBX66.js} +1 -1
  51. package/build/assets/extensions-hub-R3KNv-5V.js +1 -0
  52. package/build/assets/extensions-navigation-CfWFmI1I.js +1 -0
  53. package/build/assets/{external-link-Cnnd6ikC.js → external-link-BdBSg8rk.js} +1 -1
  54. package/build/assets/files-tab-DEq8MbHu.js +1 -0
  55. package/build/assets/{form-control-classes-CSPevi7c.js → form-control-classes-DAfsCJTe.js} +1 -1
  56. package/build/assets/{format-time-delta-DuhE50B-.js → format-time-delta-CxfPJpzC.js} +1 -1
  57. package/build/assets/git-provider-icon-BZqqUPlm.js +1 -0
  58. package/build/assets/git-repo-dropdown-9WKINV6J.js +1 -0
  59. package/build/assets/git-repo-dropdown-DEpOwUez.js +1 -0
  60. package/build/assets/{highlighted-source-view-suUKd5if.js → highlighted-source-view-CX9oIoVT.js} +1 -1
  61. package/build/assets/home-CY0JaxiY.js +1 -0
  62. package/build/assets/home-CaNWlVvB.js +1 -0
  63. package/build/assets/home-store-Ch1ErdBc.js +1 -0
  64. package/build/assets/index-home-CaNWlVvB.js +1 -0
  65. package/build/assets/info-CmWQXtRQ.js +1 -0
  66. package/build/assets/install-server-modal-BWrudmZU.js +1 -0
  67. package/build/assets/{launch-Ccnhte5b.js → launch-B1POpHuP.js} +1 -1
  68. package/build/assets/{list-todo-_BXQzOiB.js → list-todo-DtiL3lTp.js} +1 -1
  69. package/build/assets/llm-not-configured-banner-3tMsM4K6.js +27 -0
  70. package/build/assets/llm-settings-CXo8iPNW.js +1 -0
  71. package/build/assets/llm-settings-D0W8mJDk.js +1 -0
  72. package/build/assets/{llm-subscription-service-W5BprsNA.js → llm-subscription-service-DBJbfd8Z.js} +1 -1
  73. package/build/assets/loader-circle-B4QDBARx.js +1 -0
  74. package/build/assets/{loading-spinner-CcpnCr_d.js → loading-spinner-DfZ_bhV7.js} +1 -1
  75. package/build/assets/manage-backends-modal-CwyWsiag.js +1 -0
  76. package/build/assets/manifest-39f4789d.js +1 -0
  77. package/build/assets/{markdown-renderer-CvOO0YIr.js → markdown-renderer-DgiLLhW6.js} +6 -6
  78. package/build/assets/mcp-DXG9LWrI.js +9 -0
  79. package/build/assets/mcp-marketplace-utils-DFmhKc5s.js +1 -0
  80. package/build/assets/messages-kBjKaAeA.js +40 -0
  81. package/build/assets/{modal-body-DQhiw-AR.js → modal-body-CMsDpalT.js} +1 -1
  82. package/build/assets/{modal-classes-YaEEa5eZ.js → modal-classes-B6PDrxXo.js} +1 -1
  83. package/build/assets/{modal-close-button-turIYn0t.js → modal-close-button-DyxBZaAb.js} +1 -1
  84. package/build/assets/{onboarding-BegDrOKn.js → onboarding-47hh2IHA.js} +1 -1
  85. package/build/assets/onboarding-modal-9BuvvROo.js +1 -0
  86. package/build/assets/organization-service.api-UDy63-oC.js +1 -0
  87. package/build/assets/{pencil-8_lvWDoZ.js → pencil-BjgtZmWp.js} +1 -1
  88. package/build/assets/{planner-tab-w6HT0N_A.js → planner-tab-BWk8885v.js} +1 -1
  89. package/build/assets/plugins-management-service-CjkgF2dd.js +1 -0
  90. package/build/assets/plus-DrKuuvMe.js +1 -0
  91. package/build/assets/profiles-service.api-CukSFLzz.js +1 -0
  92. package/build/assets/providers-CqUWC85T.js +1 -0
  93. package/build/assets/proxy-BBUG3sd2.js +1 -0
  94. package/build/assets/{puzzle-DXWdfaa7.js → puzzle-BoNc6zZ8.js} +1 -1
  95. package/build/assets/recommended-automations-launcher-ejxy1P27.js +1 -0
  96. package/build/assets/{refresh-cw-D7CYLy-d.js → refresh-cw-BrM5ZAZD.js} +1 -1
  97. package/build/assets/root-5S-M8SYa.js +2 -0
  98. package/build/assets/root-DZ39lS5f.css +1 -0
  99. package/build/assets/root-layout-BPqoa0gv.js +3 -0
  100. package/build/assets/schema-field-nImDoY6-.js +1 -0
  101. package/build/assets/{sdk-section-page-BW-i45yr.js → sdk-section-page-BxMrtUNV.js} +1 -1
  102. package/build/assets/search-Dc2qR4O2.js +1 -0
  103. package/build/assets/secrets-service-Dhjh3HhH.js +1 -0
  104. package/build/assets/{secrets-settings-D7U1ErCH.js → secrets-settings-CPdxceT_.js} +1 -1
  105. package/build/assets/segmented-toggle-Do6oyepX.js +1 -0
  106. package/build/assets/settings-BRbnfKEm.js +1 -0
  107. package/build/assets/{settings-dropdown-input-Dx6vlkgf.js → settings-dropdown-input-DYCULKpp.js} +1 -1
  108. package/build/assets/{settings-index-COAdxm2Q.js → settings-index-C9o2NBO0.js} +1 -1
  109. package/build/assets/settings-input-B-q2gkVy.js +1 -0
  110. package/build/assets/{settings-list-classes-gQdBahdt.js → settings-list-classes-WpQi0q1L.js} +1 -1
  111. package/build/assets/{settings-modal-CFnbQ8_4.js → settings-modal-CEK0AIx6.js} +1 -1
  112. package/build/assets/settings-service.api-CZiPD8__.js +1 -0
  113. package/build/assets/{settings-switch-UNSf8K8I.js → settings-switch-LqKdGxHL.js} +1 -1
  114. package/build/assets/shared-conversation-Bu-dQlgp.js +1 -0
  115. package/build/assets/{sidebar-layout-DXHtbEj1.js → sidebar-layout-oHBGQmLh.js} +1 -1
  116. package/build/assets/{sidebar-mobile-menu-toggle-U78hQRJ1.js → sidebar-mobile-menu-toggle-ND-hgygu.js} +1 -1
  117. package/build/assets/{sidebar-nav-link-pvUivfK2.js → sidebar-nav-link-CrujNA09.js} +1 -1
  118. package/build/assets/{sidebar-store-DwrYKwYr.js → sidebar-store-Bui-WNEr.js} +1 -1
  119. package/build/assets/{skill-card-pill-row-D7XCz5uk.js → skill-card-pill-row-CZBI7OqH.js} +1 -1
  120. package/build/assets/{skill-icon-badge-HqBWZ2Eq.js → skill-icon-badge-BOov_phZ.js} +1 -1
  121. package/build/assets/{skills-plugins-BPhaNpfx.js → skills-plugins-D0PiHWAD.js} +1 -1
  122. package/build/assets/{skills-settings-CcwMtnnJ.js → skills-settings-B43KArIz.js} +2 -2
  123. package/build/assets/{styled-tooltip-DsjDnR_W.js → styled-tooltip-C7grwnOX.js} +1 -1
  124. package/build/assets/{task-list-tab-BmaTwjaS.js → task-list-tab-R3ac6m7O.js} +1 -1
  125. package/build/assets/{terminal-BRcoba5B.js → terminal-yqkNdEAx.js} +1 -1
  126. package/build/assets/{toggle-switch-BptY3XRG.js → toggle-switch-BeSrbgCg.js} +1 -1
  127. package/build/assets/{trash-2-Bq4lHbTB.js → trash-2-wW5TWcdN.js} +1 -1
  128. package/build/assets/{typography-C6fuRTTT.js → typography-iYhzLlHO.js} +1 -1
  129. package/build/assets/{use-acp-credential-form-B0_pZ_uS.js → use-acp-credential-form-DUxbxmbq.js} +1 -1
  130. package/build/assets/use-activate-agent-profile-CDHA52tC.js +1 -0
  131. package/build/assets/use-agent-profiles-TsOdIyw5.js +1 -0
  132. package/build/assets/{use-can-manage-org-profiles-CrG1km7R.js → use-can-manage-org-profiles-Bt1M71u5.js} +1 -1
  133. package/build/assets/use-cloud-current-user-id-DWt7HCgf.js +1 -0
  134. package/build/assets/{use-config-Csy8EAP9.js → use-config-CxlEdf_v.js} +1 -1
  135. package/build/assets/{use-create-conversation-Dsa4nzU9.js → use-create-conversation-nOJ6Um5h.js} +1 -1
  136. package/build/assets/{use-create-secret-BnxuAjDt.js → use-create-secret-Dj5ang9x.js} +1 -1
  137. package/build/assets/use-is-authed-BT7Iud4U.js +1 -0
  138. package/build/assets/{use-is-creating-conversation-CIAcnd8M.js → use-is-creating-conversation-CAggrM75.js} +1 -1
  139. package/build/assets/use-llm-profiles-2Wc2db8u.js +1 -0
  140. package/build/assets/use-onboarding-completion-gxQlcEy2.js +1 -0
  141. package/build/assets/use-plugins-marketplace-CVO7sXYR.js +1 -0
  142. package/build/assets/use-save-agent-profile-D0wC5ExW.js +1 -0
  143. package/build/assets/{use-save-settings-BRh9p_fv.js → use-save-settings-L3aMaDeS.js} +1 -1
  144. package/build/assets/use-settings-8nt3DGxW.js +1 -0
  145. package/build/assets/use-settings-nav-items-DHAAD-zk.js +16 -0
  146. package/build/assets/use-skills-CE6miQ3r.js +1 -0
  147. package/build/assets/use-tracking-BGboadaZ.js +68 -0
  148. package/build/assets/{use-user-conversation-GnGhs_Ob.js → use-user-conversation-BIIpGUgM.js} +1 -1
  149. package/build/assets/useInfiniteQuery-BLRVmVPU.js +1 -0
  150. package/build/assets/{useMutation-DyQXZFEF.js → useMutation-CaSHLnX0.js} +1 -1
  151. package/build/assets/{useQueries-B3T1a7qt.js → useQueries--d_WWAzc.js} +1 -1
  152. package/build/assets/{useQuery-B38jBavx.js → useQuery-DiPh8LRJ.js} +1 -1
  153. package/build/assets/utils-BgGG1znF.js +1 -0
  154. package/build/assets/{vendor~browser-CIoZCqGs.js → vendor~browser-IVYgIgG1.js} +1 -1
  155. package/build/assets/{vendor~entry.client-Di4qO77Y.js → vendor~entry.client-BcYIVQvB.js} +1 -1
  156. package/build/assets/{vendor~entry.client-BfviqoVc.js → vendor~entry.client-CXM9oiAk.js} +1 -1
  157. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~g4xrpilz-CJ7amdtQ.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0bpqexo-CbTboogo.js} +2 -2
  158. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~d4by102p-C2f0ZhS-.js} +1 -1
  159. package/build/assets/{vendor~files-tab-vm3f67Pz.js → vendor~files-tab-C7RmQJwN.js} +1 -1
  160. package/build/assets/{vendor~index-home~home~conversation-panel~conversation-kX4LrGQC.js → vendor~index-home~home~conversation-panel~conversation-Bqp1ZqJM.js} +1 -1
  161. package/build/assets/{vendor~root-layout~conversation-panel~conversation-DpA6fir3.js → vendor~root-layout~conversation-panel~conversation-BCn8lzeG.js} +1 -1
  162. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~automation-setup-route-B_L-gcOG.js +1 -0
  163. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-sjx0x5ac.js +1 -0
  164. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~automation-setup-route~onboarding-modal-D7IDevqN.js +1 -0
  165. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~bi2r7bko-Bw4AuHN1.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~dfc8ddxy-tTyxnjXT.js} +1 -1
  166. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hakxo2tj-ClV0p9g3.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gy8zbn65-CGt6bWRT.js} +1 -1
  167. package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~eywn6ulz-BKxxr74w.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~dufan6ng-Dtdw8H0q.js} +17 -4
  168. package/build/assets/{verification-settings-CaCzojbc.js → verification-settings-DBsnSXC3.js} +1 -1
  169. package/build/assets/x-omAzpXkl.js +1 -0
  170. package/build/favicon-16x16.png +0 -0
  171. package/build/favicon-32x32.png +0 -0
  172. package/build/favicon.ico +0 -0
  173. package/build/index.html +4 -4
  174. package/build/locales/ar/openhands.json +39 -2
  175. package/build/locales/ca/openhands.json +39 -2
  176. package/build/locales/de/openhands.json +39 -2
  177. package/build/locales/en/openhands.json +40 -3
  178. package/build/locales/es/openhands.json +39 -2
  179. package/build/locales/fr/openhands.json +39 -2
  180. package/build/locales/it/openhands.json +39 -2
  181. package/build/locales/ja/openhands.json +39 -2
  182. package/build/locales/ko-KR/openhands.json +39 -2
  183. package/build/locales/no/openhands.json +39 -2
  184. package/build/locales/pt/openhands.json +39 -2
  185. package/build/locales/tr/openhands.json +39 -2
  186. package/build/locales/uk/openhands.json +39 -2
  187. package/build/locales/zh-CN/openhands.json +39 -2
  188. package/build/locales/zh-TW/openhands.json +39 -2
  189. package/config/defaults.json +4 -4
  190. package/dist/api/agent-server-adapter.cjs +3 -3
  191. package/dist/api/agent-server-adapter.cjs.map +1 -1
  192. package/dist/api/agent-server-adapter.d.ts +46 -6
  193. package/dist/api/agent-server-adapter.js +187 -168
  194. package/dist/api/agent-server-adapter.js.map +1 -1
  195. package/dist/api/agent-server-compatibility.cjs +1 -1
  196. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  197. package/dist/api/agent-server-compatibility.d.ts +4 -0
  198. package/dist/api/agent-server-compatibility.js +41 -38
  199. package/dist/api/agent-server-compatibility.js.map +1 -1
  200. package/dist/api/automation-service/automation-service.api.cjs +1 -1
  201. package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
  202. package/dist/api/automation-service/automation-service.api.d.ts +20 -0
  203. package/dist/api/automation-service/automation-service.api.js +136 -99
  204. package/dist/api/automation-service/automation-service.api.js.map +1 -1
  205. package/dist/api/backend-registry/storage.cjs +1 -1
  206. package/dist/api/backend-registry/storage.cjs.map +1 -1
  207. package/dist/api/backend-registry/storage.js +1 -1
  208. package/dist/api/backend-registry/storage.js.map +1 -1
  209. package/dist/api/backend-registry/types.d.ts +2 -0
  210. package/dist/api/cloud/conversation-service.api.cjs +1 -1
  211. package/dist/api/cloud/conversation-service.api.js +22 -22
  212. package/dist/api/mcp-service/mcp-service.api.cjs +1 -1
  213. package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -1
  214. package/dist/api/mcp-service/mcp-service.api.js +19 -19
  215. package/dist/api/mcp-service/mcp-service.api.js.map +1 -1
  216. package/dist/api/settings-service/settings-service.api.cjs +1 -1
  217. package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
  218. package/dist/api/settings-service/settings-service.api.js +26 -12
  219. package/dist/api/settings-service/settings-service.api.js.map +1 -1
  220. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs +2 -0
  221. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs.map +1 -0
  222. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.d.ts +12 -0
  223. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js +94 -0
  224. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js.map +1 -0
  225. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
  226. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
  227. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +31 -90
  228. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
  229. package/dist/components/features/automations/recommended-automations-launcher.d.ts +0 -7
  230. package/dist/components/features/automations/recommended-automations-section.d.ts +0 -6
  231. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  232. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  233. package/dist/components/features/backends/backend-form-modal.js +568 -358
  234. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  235. package/dist/components/features/backends/device-flow-auth.cjs +1 -1
  236. package/dist/components/features/backends/device-flow-auth.cjs.map +1 -1
  237. package/dist/components/features/backends/device-flow-auth.d.ts +9 -1
  238. package/dist/components/features/backends/device-flow-auth.js +56 -55
  239. package/dist/components/features/backends/device-flow-auth.js.map +1 -1
  240. package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
  241. package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
  242. package/dist/components/features/backends/manage-backends-modal.js +1 -1
  243. package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
  244. package/dist/components/features/chat/chat-interface.cjs +1 -1
  245. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  246. package/dist/components/features/chat/chat-interface.js +105 -105
  247. package/dist/components/features/chat/chat-interface.js.map +1 -1
  248. package/dist/components/features/chat/chat-message.cjs +1 -1
  249. package/dist/components/features/chat/chat-message.cjs.map +1 -1
  250. package/dist/components/features/chat/chat-message.d.ts +2 -1
  251. package/dist/components/features/chat/chat-message.js +59 -49
  252. package/dist/components/features/chat/chat-message.js.map +1 -1
  253. package/dist/components/features/chat/pending-user-messages.cjs +1 -1
  254. package/dist/components/features/chat/pending-user-messages.cjs.map +1 -1
  255. package/dist/components/features/chat/pending-user-messages.js +4 -1
  256. package/dist/components/features/chat/pending-user-messages.js.map +1 -1
  257. package/dist/components/features/chat/typing-indicator.cjs +1 -1
  258. package/dist/components/features/chat/typing-indicator.cjs.map +1 -1
  259. package/dist/components/features/chat/typing-indicator.d.ts +8 -1
  260. package/dist/components/features/chat/typing-indicator.js +94 -10
  261. package/dist/components/features/chat/typing-indicator.js.map +1 -1
  262. package/dist/components/features/command-menu/command-menu-items.d.ts +5 -1
  263. package/dist/components/features/files-tab/segmented-toggle.cjs +1 -1
  264. package/dist/components/features/files-tab/segmented-toggle.cjs.map +1 -1
  265. package/dist/components/features/files-tab/segmented-toggle.d.ts +2 -0
  266. package/dist/components/features/files-tab/segmented-toggle.js +17 -14
  267. package/dist/components/features/files-tab/segmented-toggle.js.map +1 -1
  268. package/dist/components/features/manifest/manifest-form-field.d.ts +27 -0
  269. package/dist/components/features/manifest/manifest-prerequisites-step.d.ts +11 -0
  270. package/dist/components/features/manifest/manifest-review-step.d.ts +14 -0
  271. package/dist/components/features/manifest/manifest-setup-dialog.d.ts +14 -0
  272. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  273. package/dist/components/features/mcp-page/custom-server-editor.js +16 -16
  274. package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
  275. package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
  276. package/dist/components/features/mcp-page/installed-server-card.d.ts +2 -2
  277. package/dist/components/features/mcp-page/installed-server-card.js +6 -7
  278. package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
  279. package/dist/components/features/mcp-page/installed-servers-section.cjs +1 -1
  280. package/dist/components/features/mcp-page/installed-servers-section.cjs.map +1 -1
  281. package/dist/components/features/mcp-page/installed-servers-section.d.ts +2 -2
  282. package/dist/components/features/mcp-page/installed-servers-section.js +2 -2
  283. package/dist/components/features/mcp-page/installed-servers-section.js.map +1 -1
  284. package/dist/components/features/mcp-page/mcp-server-health.cjs +1 -1
  285. package/dist/components/features/mcp-page/mcp-server-health.js +4 -4
  286. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +1 -1
  287. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
  288. package/dist/components/features/settings/mcp-settings/mcp-server-form.js +2 -1
  289. package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
  290. package/dist/components/features/settings/settings-input.cjs +1 -1
  291. package/dist/components/features/settings/settings-input.cjs.map +1 -1
  292. package/dist/components/features/settings/settings-input.d.ts +6 -0
  293. package/dist/components/features/settings/settings-input.js +13 -8
  294. package/dist/components/features/settings/settings-input.js.map +1 -1
  295. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  296. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  297. package/dist/components/features/sidebar/sidebar-rail-body.js +124 -123
  298. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  299. package/dist/config/defaults.cjs +1 -1
  300. package/dist/config/defaults.cjs.map +1 -1
  301. package/dist/config/defaults.js +3 -3
  302. package/dist/config/defaults.js.map +1 -1
  303. package/dist/contexts/active-backend-context.cjs +1 -1
  304. package/dist/contexts/active-backend-context.cjs.map +1 -1
  305. package/dist/contexts/active-backend-context.d.ts +3 -2
  306. package/dist/contexts/active-backend-context.js +55 -42
  307. package/dist/contexts/active-backend-context.js.map +1 -1
  308. package/dist/favicon-16x16.png +0 -0
  309. package/dist/favicon-32x32.png +0 -0
  310. package/dist/favicon.ico +0 -0
  311. package/dist/hooks/mutation/use-update-mcp-server.cjs +1 -1
  312. package/dist/hooks/mutation/use-update-mcp-server.js +5 -5
  313. package/dist/hooks/query/query-keys.cjs.map +1 -1
  314. package/dist/hooks/query/query-keys.d.ts +4 -0
  315. package/dist/hooks/query/query-keys.js.map +1 -1
  316. package/dist/hooks/query/use-cloud-current-user-id.cjs +1 -1
  317. package/dist/hooks/query/use-cloud-current-user-id.cjs.map +1 -1
  318. package/dist/hooks/query/use-cloud-current-user-id.js +7 -5
  319. package/dist/hooks/query/use-cloud-current-user-id.js.map +1 -1
  320. package/dist/hooks/query/use-cloud-organizations.cjs +1 -1
  321. package/dist/hooks/query/use-cloud-organizations.cjs.map +1 -1
  322. package/dist/hooks/query/use-cloud-organizations.js +5 -1
  323. package/dist/hooks/query/use-cloud-organizations.js.map +1 -1
  324. package/dist/hooks/query/use-manifest-capabilities.d.ts +21 -0
  325. package/dist/hooks/query/use-manifest-prerequisites.d.ts +24 -0
  326. package/dist/hooks/use-can-manage-org-profiles.cjs +1 -1
  327. package/dist/hooks/use-can-manage-org-profiles.cjs.map +1 -1
  328. package/dist/hooks/use-can-manage-org-profiles.js +2 -1
  329. package/dist/hooks/use-can-manage-org-profiles.js.map +1 -1
  330. package/dist/hooks/use-llm-configured.cjs +1 -1
  331. package/dist/hooks/use-llm-configured.cjs.map +1 -1
  332. package/dist/hooks/use-llm-configured.js +2 -1
  333. package/dist/hooks/use-llm-configured.js.map +1 -1
  334. package/dist/hooks/use-manifest-preflight.d.ts +18 -0
  335. package/dist/hooks/use-tracking.cjs +1 -1
  336. package/dist/hooks/use-tracking.cjs.map +1 -1
  337. package/dist/hooks/use-tracking.d.ts +14 -0
  338. package/dist/hooks/use-tracking.js +28 -10
  339. package/dist/hooks/use-tracking.js.map +1 -1
  340. package/dist/i18n/declaration.cjs +1 -1
  341. package/dist/i18n/declaration.cjs.map +1 -1
  342. package/dist/i18n/declaration.d.ts +38 -1
  343. package/dist/i18n/declaration.js +1 -1
  344. package/dist/i18n/declaration.js.map +1 -1
  345. package/dist/i18n/translation.cjs +2 -2
  346. package/dist/i18n/translation.cjs.map +1 -1
  347. package/dist/i18n/translation.js +645 -16
  348. package/dist/i18n/translation.js.map +1 -1
  349. package/dist/icons/external-link.cjs +2 -0
  350. package/dist/icons/external-link.cjs.map +1 -0
  351. package/dist/icons/external-link.js +22 -0
  352. package/dist/icons/external-link.js.map +1 -0
  353. package/dist/icons/server.cjs +2 -0
  354. package/dist/icons/server.cjs.map +1 -0
  355. package/dist/icons/server.js +17 -0
  356. package/dist/icons/server.js.map +1 -0
  357. package/dist/locales/ar/openhands.json +39 -2
  358. package/dist/locales/ca/openhands.json +39 -2
  359. package/dist/locales/de/openhands.json +39 -2
  360. package/dist/locales/en/openhands.json +40 -3
  361. package/dist/locales/es/openhands.json +39 -2
  362. package/dist/locales/fr/openhands.json +39 -2
  363. package/dist/locales/it/openhands.json +39 -2
  364. package/dist/locales/ja/openhands.json +39 -2
  365. package/dist/locales/ko-KR/openhands.json +39 -2
  366. package/dist/locales/no/openhands.json +39 -2
  367. package/dist/locales/pt/openhands.json +39 -2
  368. package/dist/locales/tr/openhands.json +39 -2
  369. package/dist/locales/uk/openhands.json +39 -2
  370. package/dist/locales/zh-CN/openhands.json +39 -2
  371. package/dist/locales/zh-TW/openhands.json +39 -2
  372. package/dist/manifests/automation-interface.cjs +2 -0
  373. package/dist/manifests/automation-interface.cjs.map +1 -0
  374. package/dist/manifests/automation-interface.d.ts +44 -0
  375. package/dist/manifests/automation-interface.js +81 -0
  376. package/dist/manifests/automation-interface.js.map +1 -0
  377. package/dist/manifests/automation-setup.cjs +2 -0
  378. package/dist/manifests/automation-setup.cjs.map +1 -0
  379. package/dist/manifests/automation-setup.d.ts +52 -0
  380. package/dist/manifests/automation-setup.js +8 -0
  381. package/dist/manifests/automation-setup.js.map +1 -0
  382. package/dist/manifests/interface-validation.cjs +2 -0
  383. package/dist/manifests/interface-validation.cjs.map +1 -0
  384. package/dist/manifests/interface-validation.d.ts +27 -0
  385. package/dist/manifests/interface-validation.js +182 -0
  386. package/dist/manifests/interface-validation.js.map +1 -0
  387. package/dist/manifests/manifest-actions.d.ts +15 -0
  388. package/dist/manifests/manifest-capabilities.d.ts +25 -0
  389. package/dist/manifests/manifest-error-map.d.ts +40 -0
  390. package/dist/manifests/manifest-local-validation.d.ts +56 -0
  391. package/dist/manifests/manifest-registry.cjs +2 -0
  392. package/dist/manifests/manifest-registry.cjs.map +1 -0
  393. package/dist/manifests/manifest-registry.d.ts +15 -0
  394. package/dist/manifests/manifest-registry.js +26 -0
  395. package/dist/manifests/manifest-registry.js.map +1 -0
  396. package/dist/manifests/manifest-sources.cjs +2 -0
  397. package/dist/manifests/manifest-sources.cjs.map +1 -0
  398. package/dist/manifests/manifest-sources.d.ts +15 -0
  399. package/dist/manifests/manifest-sources.js +8 -0
  400. package/dist/manifests/manifest-sources.js.map +1 -0
  401. package/dist/manifests/manifest-template.d.ts +18 -0
  402. package/dist/manifests/manifest-validation.cjs +2 -0
  403. package/dist/manifests/manifest-validation.cjs.map +1 -0
  404. package/dist/manifests/manifest-validation.d.ts +30 -0
  405. package/dist/manifests/manifest-validation.js +145 -0
  406. package/dist/manifests/manifest-validation.js.map +1 -0
  407. package/dist/manifests/types.cjs +2 -0
  408. package/dist/manifests/types.cjs.map +1 -0
  409. package/dist/manifests/types.d.ts +227 -0
  410. package/dist/manifests/types.js +6 -0
  411. package/dist/manifests/types.js.map +1 -0
  412. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +9 -0
  413. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -0
  414. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +75 -0
  415. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -0
  416. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs +9 -0
  417. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs.map +1 -0
  418. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js +78 -0
  419. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js.map +1 -0
  420. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs +17 -0
  421. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs.map +1 -0
  422. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js +89 -0
  423. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js.map +1 -0
  424. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs +10 -0
  425. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs.map +1 -0
  426. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js +17 -0
  427. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js.map +1 -0
  428. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs +9 -0
  429. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs.map +1 -0
  430. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js +15 -0
  431. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js.map +1 -0
  432. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs +9 -0
  433. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs.map +1 -0
  434. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js +18 -0
  435. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js.map +1 -0
  436. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs +9 -0
  437. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs.map +1 -0
  438. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js +14 -0
  439. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js.map +1 -0
  440. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs +9 -0
  441. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs.map +1 -0
  442. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js +14 -0
  443. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js.map +1 -0
  444. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +2 -0
  445. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -0
  446. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +23 -0
  447. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -0
  448. package/dist/node_modules/@openhands/extensions/automations/index.cjs +2 -0
  449. package/dist/node_modules/@openhands/extensions/automations/index.cjs.map +1 -0
  450. package/dist/node_modules/@openhands/extensions/automations/index.js +18 -0
  451. package/dist/node_modules/@openhands/extensions/automations/index.js.map +1 -0
  452. package/dist/node_modules/@openhands/extensions/automations/interface.cjs +2 -0
  453. package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -0
  454. package/dist/node_modules/@openhands/extensions/automations/interface.js +89 -0
  455. package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -0
  456. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
  457. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
  458. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +3 -3
  459. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
  460. package/dist/node_modules/@openhands/extensions/skills/index.cjs +17 -4
  461. package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
  462. package/dist/node_modules/@openhands/extensions/skills/index.js +5 -5
  463. package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
  464. package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.cjs +1 -1
  465. package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.cjs.map +1 -1
  466. package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.js +9 -0
  467. package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.js.map +1 -1
  468. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs +2 -0
  469. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs.map +1 -0
  470. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js +29 -0
  471. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js.map +1 -0
  472. package/dist/package.cjs +1 -1
  473. package/dist/package.cjs.map +1 -1
  474. package/dist/package.js +3 -3
  475. package/dist/package.js.map +1 -1
  476. package/dist/routes/app-settings.cjs +1 -1
  477. package/dist/routes/app-settings.js +5 -5
  478. package/dist/routes/mcp.cjs +1 -1
  479. package/dist/routes/mcp.cjs.map +1 -1
  480. package/dist/routes/mcp.js +73 -82
  481. package/dist/routes/mcp.js.map +1 -1
  482. package/dist/services/telemetry.cjs +1 -1
  483. package/dist/services/telemetry.cjs.map +1 -1
  484. package/dist/services/telemetry.d.ts +8 -0
  485. package/dist/services/telemetry.js +163 -116
  486. package/dist/services/telemetry.js.map +1 -1
  487. package/dist/types/agent-server/core/events/conversation-state-event.d.ts +2 -19
  488. package/dist/types/agent-server/core/events/observation-event.d.ts +2 -18
  489. package/dist/types/automation.d.ts +7 -3
  490. package/dist/types/mcp-server.d.ts +5 -0
  491. package/dist/types/settings.d.ts +3 -0
  492. package/dist/utils/api-error-message.d.ts +6 -2
  493. package/dist/utils/automation-catalog.cjs +2 -0
  494. package/dist/utils/automation-catalog.cjs.map +1 -0
  495. package/dist/utils/automation-catalog.d.ts +28 -0
  496. package/dist/utils/automation-catalog.js +5 -0
  497. package/dist/utils/automation-catalog.js.map +1 -0
  498. package/dist/utils/automation-timeout.d.ts +3 -2
  499. package/dist/utils/mcp-config.cjs +1 -1
  500. package/dist/utils/mcp-config.cjs.map +1 -1
  501. package/dist/utils/mcp-config.d.ts +8 -0
  502. package/dist/utils/mcp-config.js +25 -20
  503. package/dist/utils/mcp-config.js.map +1 -1
  504. package/dist/utils/mcp-installed-servers.cjs +1 -1
  505. package/dist/utils/mcp-installed-servers.cjs.map +1 -1
  506. package/dist/utils/mcp-installed-servers.js +6 -3
  507. package/dist/utils/mcp-installed-servers.js.map +1 -1
  508. package/dist/utils/responder-deployment.d.ts +5 -1
  509. package/dist/utils/transcript-export/index.cjs +5 -5
  510. package/dist/utils/transcript-export/index.js +12 -12
  511. package/package.json +3 -3
  512. package/scripts/check-sdk-version-sync.mjs +6 -6
  513. package/scripts/check-translation-completeness.cjs +1 -0
  514. package/scripts/dev-safe.mjs +17 -12
  515. package/scripts/dev-static.mjs +17 -0
  516. package/scripts/dev-with-automation.mjs +12 -14
  517. package/scripts/ingress.mjs +22 -0
  518. package/scripts/proxy-utils.mjs +157 -2
  519. package/scripts/runtime-services-info.mjs +6 -6
  520. package/scripts/static-build.mjs +0 -7
  521. package/scripts/static-server.mjs +10 -0
  522. package/build/assets/active-backend-context-BlZPzZNU.js +0 -1
  523. package/build/assets/agent-context-settings-CTaN-Iw9.js +0 -1
  524. package/build/assets/agent-profiles-settings-CR4VTqv_.js +0 -1
  525. package/build/assets/agent-server-conversation-service.api-Btmi4q6d.js +0 -41
  526. package/build/assets/agent-settings-KQs-occT.js +0 -1
  527. package/build/assets/api-key-entry-screen-BhR24gkM.js +0 -1
  528. package/build/assets/app-settings-Bs4sY8WP.js +0 -1
  529. package/build/assets/automation-BGP_I1RR.js +0 -1
  530. package/build/assets/automation-detail-CwDnJbYR.js +0 -2
  531. package/build/assets/automation-export-Bu-r-EzL.js +0 -2
  532. package/build/assets/automations-list-CYw7_6FR.js +0 -1
  533. package/build/assets/backend-form-modal-Ce-KRHOJ.js +0 -1
  534. package/build/assets/browser-BUDJnBg4.js +0 -6
  535. package/build/assets/check-BMOG005H.js +0 -1
  536. package/build/assets/chevron-down-CV1zZP_K.js +0 -1
  537. package/build/assets/circle-check-lvN_jFN5.js +0 -1
  538. package/build/assets/client-source-1v-kWLNU.js +0 -1
  539. package/build/assets/cloud-funnel-analytics-CasMM7EO.js +0 -1
  540. package/build/assets/command-menu-N_BriUy8.js +0 -1
  541. package/build/assets/condenser-settings-Czi8cKxV.js +0 -1
  542. package/build/assets/conversation-C25pc2dT.js +0 -1
  543. package/build/assets/conversation-CObLYSJd.js +0 -90
  544. package/build/assets/conversation-panel-C25pc2dT.js +0 -1
  545. package/build/assets/conversation-state-store-DTq4hFoP.js +0 -1
  546. package/build/assets/extensions-hub-BKftOQ-X.js +0 -1
  547. package/build/assets/extensions-navigation-DF24q1H1.js +0 -1
  548. package/build/assets/files-tab-SAiFCnS5.js +0 -1
  549. package/build/assets/git-provider-icon-BREx-yUX.js +0 -1
  550. package/build/assets/home-EPNFgzUh.js +0 -1
  551. package/build/assets/home-sN90Xcxp.js +0 -1
  552. package/build/assets/index-home-EPNFgzUh.js +0 -1
  553. package/build/assets/install-server-modal-BI8yUfmr.js +0 -1
  554. package/build/assets/llm-not-configured-banner-DTWzISnk.js +0 -27
  555. package/build/assets/llm-settings-BXk5_Pac.js +0 -1
  556. package/build/assets/llm-settings-C1vpgWam.js +0 -1
  557. package/build/assets/loader-circle-6zlEYCJw.js +0 -1
  558. package/build/assets/manage-backends-modal-DhflyGTf.js +0 -1
  559. package/build/assets/manifest-8082e879.js +0 -1
  560. package/build/assets/mcp-CxLPda-W.js +0 -9
  561. package/build/assets/messages-DINDkPNK.js +0 -40
  562. package/build/assets/onboarding-modal-DdvE6rzw.js +0 -1
  563. package/build/assets/organization-service.api-CT2OQlLz.js +0 -1
  564. package/build/assets/plugins-management-service-DVkoM3eA.js +0 -1
  565. package/build/assets/plus-vIbGD459.js +0 -1
  566. package/build/assets/profiles-service.api-CBafmAPO.js +0 -1
  567. package/build/assets/providers-9UzRB9mT.js +0 -1
  568. package/build/assets/proxy-C79PCMjo.js +0 -1
  569. package/build/assets/recommended-automations-launcher-BF2mtAKw.js +0 -58
  570. package/build/assets/root-B5JXKp1P.css +0 -1
  571. package/build/assets/root-Sj7W28yE.js +0 -2
  572. package/build/assets/root-layout-DbhKVoc7.js +0 -3
  573. package/build/assets/schema-field-CV6bFnoL.js +0 -1
  574. package/build/assets/search-sKuYKllf.js +0 -1
  575. package/build/assets/secrets-service-BjK-bPN2.js +0 -1
  576. package/build/assets/segmented-toggle-DbbD3Tve.js +0 -1
  577. package/build/assets/settings-Bj5Oo45A.js +0 -1
  578. package/build/assets/settings-input-BjW_zyTN.js +0 -1
  579. package/build/assets/settings-service.api-DryhKdSr.js +0 -1
  580. package/build/assets/shared-conversation-CnMxy7p_.js +0 -1
  581. package/build/assets/telemetry-cmCL3o6Z.js +0 -2
  582. package/build/assets/use-activate-agent-profile-DH33MvVj.js +0 -1
  583. package/build/assets/use-agent-profiles-Dmd_4H8q.js +0 -1
  584. package/build/assets/use-cloud-current-user-id-B6DP3s47.js +0 -1
  585. package/build/assets/use-is-authed-BsS4XwSL.js +0 -1
  586. package/build/assets/use-llm-profiles-BMQoc612.js +0 -1
  587. package/build/assets/use-onboarding-completion-B-2BTS-y.js +0 -1
  588. package/build/assets/use-plugins-marketplace-PBc_XNz_.js +0 -1
  589. package/build/assets/use-save-agent-profile-2Mk9ZX37.js +0 -1
  590. package/build/assets/use-settings-DBI44RnH.js +0 -1
  591. package/build/assets/use-settings-nav-items-Cva28C-c.js +0 -16
  592. package/build/assets/use-skills-RQsCtdzN.js +0 -1
  593. package/build/assets/use-tracking-CN1nIMnY.js +0 -1
  594. package/build/assets/utils-qjs_KuS4.js +0 -1
  595. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation-EShpjxey.js +0 -1
  596. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-DD_UNO02.js +0 -1
  597. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-Be63Q2Ln.js +0 -1
  598. package/build/assets/x-EjvKGawc.js +0 -1
  599. /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f1hl7voa-BrmgjeOw.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~emdr2jt4-BrmgjeOw.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"installed-server-card.js","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\";\nimport { getInstalledServerTitle } from \"#/utils/mcp-installed-server-display\";\nimport { McpServerHealthSection } from \"./mcp-server-health\";\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 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 = getInstalledServerTitle(server, catalog);\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\n <McpServerHealthSection\n server={server}\n catalog={catalog}\n onEdit={onEdit}\n />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AA0BA,SAAS,EAAwB,GAA+B;CAC9D,QAAQ,GAAR;EACE,KAAK,OACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,SACE,OAAO;CACX;AACF;AAEA,SAAS,EAAoB,GAAiC;CAC5D,IAAI,EAAO,SAAS,SAAS;EAC3B,IAAM,IACJ,EAAO,QAAQ,EAAO,KAAK,SAAS,IAAI,IAAI,EAAO,KAAK,KAAK,GAAG,MAAM;EACxE,OAAO,GAAG,EAAO,WAAW,KAAK,IAAO,KAAK;CAC/C;CACA,OAAO,EAAO,OAAO;AACvB;AAEA,SAAgB,EAAoB,EAClC,WACA,WACA,eAC2B;CAC3B,IAAM,EAAE,SAAM,EAAe,WAAW,GAClC,IAAU,EACd,GACA,EAAyB,CAAe,CAC1C,GAEM,IAAQ,EAAwB,GAAQ,CAAO,GAC/C,IAAa,EAAoB,CAAM,GACvC,IAAY,EAAwB,EAAO,IAAI;CASrD,OACE,kBAAC,OAAD;EACE,eAAY;EACZ,kBAAgB,EAAO;EACvB,MAAK;EACL,UAAU;EACV,SAAS;EACT,YAdmB,MAA+B;GACpD,CAAI,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,eAAe,GACrB,EAAO;EAEX;EAUI,cAAY,EAAE,EAAQ,sBAAsB,EAAE,MAAM,EAAM,CAAC;EAC3D,WAAW,EACT,6DACA,GACA,CACF;YAEA,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IACE,OAAO;IACP,UAAU,kBAAC,GAAD,EAAQ,aAAa,KAAO,CAAA;GACvC,CAAA,GAED,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,UAAD;MAAQ,WAAU;gBAAlB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;QAAwC;kBACnD;OACC,CAAA,GACJ,kBAAC,KAAD;QAAG,WAAU;kBAAoC;OAAa,CAAA,CAC3D;UACL,kBAAC,GAAD;OACE,QAAQ,wBAAwB,EAAO;OACvC,YAAA;OACA,WAAW,MAAa;QACtB,AAAK,KACH,EAAS;OAEb;OACA,gBAAgB,EAAQ;OACxB,iBAAiB,EAAQ;MAC1B,CAAA,CACK;;KAEP,GAAS,cACR,kBAAC,KAAD;MACE,eAAa,0BAA0B,EAAO;MAC9C,WAAU;gBAET,EAAQ;KACR,CAAA,IACD;KAEH,IACC,kBAAC,KAAD;MACE,eAAa,qBAAqB,EAAO;MACzC,WAAU;MACV,OAAO;gBAEN;KACA,CAAA,IACD;KAEJ,kBAAC,GAAD;MACU;MACC;MACD;KACT,CAAA;IACE;KACF;;CACF,CAAA;AAET"}
1
+ {"version":3,"file":"installed-server-card.js","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\";\nimport { getInstalledServerTitle } from \"#/utils/mcp-installed-server-display\";\nimport { McpServerHealthSection } from \"./mcp-server-health\";\n\ninterface InstalledServerCardProps {\n server: MCPServerConfig;\n onEdit: () => void;\n onToggleEnabled: (enabled: boolean) => 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 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 onToggleEnabled,\n}: InstalledServerCardProps) {\n const { t } = useTranslation(\"openhands\");\n const catalog = findCatalogEntryForServer(\n server,\n getMcpMarketplaceCatalog(MCP_MARKETPLACE),\n );\n\n const title = getInstalledServerTitle(server, catalog);\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 {/* Enable/disable, not remove: a disabled server keeps its full\n configuration (secrets included) and is simply withheld from\n the agent. Removing lives in the editor, reached by clicking\n the card. */}\n <CirclePlusCheckToggle\n testId={`mcp-installed-toggle-${server.id}`}\n isSelected={server.enabled !== false}\n onToggle={onToggleEnabled}\n enableLabelKey={I18nKey.MCP$TOGGLE_ENABLE_SERVER}\n disableLabelKey={I18nKey.MCP$TOGGLE_DISABLE_SERVER}\n disableTooltipKey={I18nKey.COMMON$DISABLE}\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\n <McpServerHealthSection\n server={server}\n catalog={catalog}\n onEdit={onEdit}\n />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AA0BA,SAAS,EAAwB,GAA+B;CAC9D,QAAQ,GAAR;EACE,KAAK,OACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,SACE,OAAO;CACX;AACF;AAEA,SAAS,EAAoB,GAAiC;CAC5D,IAAI,EAAO,SAAS,SAAS;EAC3B,IAAM,IACJ,EAAO,QAAQ,EAAO,KAAK,SAAS,IAAI,IAAI,EAAO,KAAK,KAAK,GAAG,MAAM;EACxE,OAAO,GAAG,EAAO,WAAW,KAAK,IAAO,KAAK;CAC/C;CACA,OAAO,EAAO,OAAO;AACvB;AAEA,SAAgB,EAAoB,EAClC,WACA,WACA,sBAC2B;CAC3B,IAAM,EAAE,SAAM,EAAe,WAAW,GAClC,IAAU,EACd,GACA,EAAyB,CAAe,CAC1C,GAEM,IAAQ,EAAwB,GAAQ,CAAO,GAC/C,IAAa,EAAoB,CAAM,GACvC,IAAY,EAAwB,EAAO,IAAI;CASrD,OACE,kBAAC,OAAD;EACE,eAAY;EACZ,kBAAgB,EAAO;EACvB,MAAK;EACL,UAAU;EACV,SAAS;EACT,YAdmB,MAA+B;GACpD,CAAI,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,eAAe,GACrB,EAAO;EAEX;EAUI,cAAY,EAAE,EAAQ,sBAAsB,EAAE,MAAM,EAAM,CAAC;EAC3D,WAAW,EACT,6DACA,GACA,CACF;YAEA,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IACE,OAAO;IACP,UAAU,kBAAC,GAAD,EAAQ,aAAa,KAAO,CAAA;GACvC,CAAA,GAED,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,UAAD;MAAQ,WAAU;gBAAlB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;QAAwC;kBACnD;OACC,CAAA,GACJ,kBAAC,KAAD;QAAG,WAAU;kBAAoC;OAAa,CAAA,CAC3D;UAKL,kBAAC,GAAD;OACE,QAAQ,wBAAwB,EAAO;OACvC,YAAY,EAAO,YAAY;OAC/B,UAAU;OACV,gBAAgB,EAAQ;OACxB,iBAAiB,EAAQ;OACzB,mBAAmB,EAAQ;MAC5B,CAAA,CACK;;KAEP,GAAS,cACR,kBAAC,KAAD;MACE,eAAa,0BAA0B,EAAO;MAC9C,WAAU;gBAET,EAAQ;KACR,CAAA,IACD;KAEH,IACC,kBAAC,KAAD;MACE,eAAa,qBAAqB,EAAO;MACzC,WAAU;MACV,OAAO;gBAEN;KACA,CAAA,IACD;KAEJ,kBAAC,GAAD;MACU;MACC;MACD;KACT,CAAA;IACE;KACF;;CACF,CAAA;AAET"}
@@ -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("../../../utils/extension-module-card-classes.cjs"),r=require("./installed-server-card.cjs");let i=require("react/jsx-runtime");function a({servers:a,hasAnyInstalled:o,query:s=``,onEdit:c,onDelete:l}){let{t:u}=e.useTranslation(`openhands`);return a.length===0?o&&s.trim().length>0?(0,i.jsx)(`div`,{"data-testid":`mcp-installed-empty-search`,className:`rounded-xl border border-[var(--oh-border)] p-6 text-center`,children:(0,i.jsx)(`p`,{className:`text-xs text-tertiary-light`,children:u(t.I18nKey.MCP$SEARCH_EMPTY)})}):(0,i.jsxs)(`div`,{"data-testid":`mcp-installed-empty`,className:n.extensionModuleEmptyStateClassName,children:[(0,i.jsx)(`p`,{className:`text-sm text-white`,children:u(t.I18nKey.MCP$INSTALLED_EMPTY_TITLE)}),(0,i.jsx)(`p`,{className:`text-xs text-tertiary-light mt-1`,children:u(t.I18nKey.MCP$INSTALLED_EMPTY_HINT)})]}):(0,i.jsx)(`div`,{className:n.extensionModuleCardGridContainerClassName,children:(0,i.jsx)(`div`,{"data-testid":`mcp-installed-list`,className:n.extensionModuleCardGridClassName,children:a.map(e=>(0,i.jsx)(r.InstalledServerCard,{server:e,onEdit:()=>c(e),onDelete:()=>l(e.id)},e.id))})})}exports.InstalledServersSection=a;
1
+ require("../../../_virtual/_rolldown/runtime.cjs");const e=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),t=require("../../../i18n/declaration.cjs"),n=require("../../../utils/extension-module-card-classes.cjs"),r=require("./installed-server-card.cjs");let i=require("react/jsx-runtime");function a({servers:a,hasAnyInstalled:o,query:s=``,onEdit:c,onToggleEnabled:l}){let{t:u}=e.useTranslation(`openhands`);return a.length===0?o&&s.trim().length>0?(0,i.jsx)(`div`,{"data-testid":`mcp-installed-empty-search`,className:`rounded-xl border border-[var(--oh-border)] p-6 text-center`,children:(0,i.jsx)(`p`,{className:`text-xs text-tertiary-light`,children:u(t.I18nKey.MCP$SEARCH_EMPTY)})}):(0,i.jsxs)(`div`,{"data-testid":`mcp-installed-empty`,className:n.extensionModuleEmptyStateClassName,children:[(0,i.jsx)(`p`,{className:`text-sm text-white`,children:u(t.I18nKey.MCP$INSTALLED_EMPTY_TITLE)}),(0,i.jsx)(`p`,{className:`text-xs text-tertiary-light mt-1`,children:u(t.I18nKey.MCP$INSTALLED_EMPTY_HINT)})]}):(0,i.jsx)(`div`,{className:n.extensionModuleCardGridContainerClassName,children:(0,i.jsx)(`div`,{"data-testid":`mcp-installed-list`,className:n.extensionModuleCardGridClassName,children:a.map(e=>(0,i.jsx)(r.InstalledServerCard,{server:e,onEdit:()=>c(e),onToggleEnabled:t=>l(e,t)},e.id))})})}exports.InstalledServersSection=a;
2
2
  //# sourceMappingURL=installed-servers-section.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"installed-servers-section.cjs","names":[],"sources":["../../../../src/components/features/mcp-page/installed-servers-section.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport { InstalledServerCard } from \"./installed-server-card\";\nimport {\n extensionModuleCardGridClassName,\n extensionModuleCardGridContainerClassName,\n extensionModuleEmptyStateClassName,\n} from \"#/utils/extension-module-card-classes\";\n\ninterface InstalledServersSectionProps {\n /** Already-filtered list — search filtering happens upstream. */\n servers: MCPServerConfig[];\n /**\n * True iff there is at least one installed server before applying\n * the search filter. Lets the section differentiate \"nothing\n * installed yet\" from \"no installed servers match the current\n * search\".\n */\n hasAnyInstalled: boolean;\n /** Current search query — empty string means no filter applied. */\n query?: string;\n onEdit: (server: MCPServerConfig) => void;\n onDelete: (serverId: string) => void;\n}\n\nexport function InstalledServersSection({\n servers,\n hasAnyInstalled,\n query = \"\",\n onEdit,\n onDelete,\n}: InstalledServersSectionProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isEmpty = servers.length === 0;\n\n if (isEmpty) {\n // Filter narrowed everything out — vs. nothing was installed in\n // the first place. Different copy in each case.\n if (hasAnyInstalled && query.trim().length > 0) {\n return (\n <div\n data-testid=\"mcp-installed-empty-search\"\n className=\"rounded-xl border border-[var(--oh-border)] p-6 text-center\"\n >\n <p className=\"text-xs text-tertiary-light\">\n {t(I18nKey.MCP$SEARCH_EMPTY)}\n </p>\n </div>\n );\n }\n return (\n <div\n data-testid=\"mcp-installed-empty\"\n className={extensionModuleEmptyStateClassName}\n >\n <p className=\"text-sm text-white\">\n {t(I18nKey.MCP$INSTALLED_EMPTY_TITLE)}\n </p>\n <p className=\"text-xs text-tertiary-light mt-1\">\n {t(I18nKey.MCP$INSTALLED_EMPTY_HINT)}\n </p>\n </div>\n );\n }\n\n return (\n <div className={extensionModuleCardGridContainerClassName}>\n <div\n data-testid=\"mcp-installed-list\"\n className={extensionModuleCardGridClassName}\n >\n {servers.map((server) => (\n <InstalledServerCard\n key={server.id}\n server={server}\n onEdit={() => onEdit(server)}\n onDelete={() => onDelete(server.id)}\n />\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"0TA0BA,SAAgB,EAAwB,CACtC,UACA,kBACA,QAAQ,GACR,SACA,YAC+B,CAC/B,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAkCxC,OAhCgB,EAAQ,SAAW,EAK7B,GAAmB,EAAM,KAAK,EAAE,OAAS,GAEzC,EAAA,EAAA,KAAC,MAAD,CACE,cAAY,6BACZ,UAAU,wEAEV,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,uCACV,EAAE,EAAA,QAAQ,gBAAgB,CAC1B,CAAA,CACA,CAAA,GAIP,EAAA,EAAA,MAAC,MAAD,CACE,cAAY,sBACZ,UAAW,EAAA,4CAFb,EAIE,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,8BACV,EAAE,EAAA,QAAQ,yBAAyB,CACnC,CAAA,GACH,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,4CACV,EAAE,EAAA,QAAQ,wBAAwB,CAClC,CAAA,CACA,KAKP,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAA,oDACd,EAAA,EAAA,KAAC,MAAD,CACE,cAAY,qBACZ,UAAW,EAAA,0CAEV,EAAQ,IAAK,IACZ,EAAA,EAAA,KAAC,EAAA,oBAAD,CAEU,SACR,WAAc,EAAO,CAAM,EAC3B,aAAgB,EAAS,EAAO,EAAE,CACnC,EAJM,EAAO,EAIb,CACF,CACE,CAAA,CACF,CAAA,CAET"}
1
+ {"version":3,"file":"installed-servers-section.cjs","names":[],"sources":["../../../../src/components/features/mcp-page/installed-servers-section.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport { InstalledServerCard } from \"./installed-server-card\";\nimport {\n extensionModuleCardGridClassName,\n extensionModuleCardGridContainerClassName,\n extensionModuleEmptyStateClassName,\n} from \"#/utils/extension-module-card-classes\";\n\ninterface InstalledServersSectionProps {\n /** Already-filtered list — search filtering happens upstream. */\n servers: MCPServerConfig[];\n /**\n * True iff there is at least one installed server before applying\n * the search filter. Lets the section differentiate \"nothing\n * installed yet\" from \"no installed servers match the current\n * search\".\n */\n hasAnyInstalled: boolean;\n /** Current search query — empty string means no filter applied. */\n query?: string;\n onEdit: (server: MCPServerConfig) => void;\n onToggleEnabled: (server: MCPServerConfig, enabled: boolean) => void;\n}\n\nexport function InstalledServersSection({\n servers,\n hasAnyInstalled,\n query = \"\",\n onEdit,\n onToggleEnabled,\n}: InstalledServersSectionProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isEmpty = servers.length === 0;\n\n if (isEmpty) {\n // Filter narrowed everything out — vs. nothing was installed in\n // the first place. Different copy in each case.\n if (hasAnyInstalled && query.trim().length > 0) {\n return (\n <div\n data-testid=\"mcp-installed-empty-search\"\n className=\"rounded-xl border border-[var(--oh-border)] p-6 text-center\"\n >\n <p className=\"text-xs text-tertiary-light\">\n {t(I18nKey.MCP$SEARCH_EMPTY)}\n </p>\n </div>\n );\n }\n return (\n <div\n data-testid=\"mcp-installed-empty\"\n className={extensionModuleEmptyStateClassName}\n >\n <p className=\"text-sm text-white\">\n {t(I18nKey.MCP$INSTALLED_EMPTY_TITLE)}\n </p>\n <p className=\"text-xs text-tertiary-light mt-1\">\n {t(I18nKey.MCP$INSTALLED_EMPTY_HINT)}\n </p>\n </div>\n );\n }\n\n return (\n <div className={extensionModuleCardGridContainerClassName}>\n <div\n data-testid=\"mcp-installed-list\"\n className={extensionModuleCardGridClassName}\n >\n {servers.map((server) => (\n <InstalledServerCard\n key={server.id}\n server={server}\n onEdit={() => onEdit(server)}\n onToggleEnabled={(enabled) => onToggleEnabled(server, enabled)}\n />\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"0TA0BA,SAAgB,EAAwB,CACtC,UACA,kBACA,QAAQ,GACR,SACA,mBAC+B,CAC/B,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAkCxC,OAhCgB,EAAQ,SAAW,EAK7B,GAAmB,EAAM,KAAK,EAAE,OAAS,GAEzC,EAAA,EAAA,KAAC,MAAD,CACE,cAAY,6BACZ,UAAU,wEAEV,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,uCACV,EAAE,EAAA,QAAQ,gBAAgB,CAC1B,CAAA,CACA,CAAA,GAIP,EAAA,EAAA,MAAC,MAAD,CACE,cAAY,sBACZ,UAAW,EAAA,4CAFb,EAIE,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,8BACV,EAAE,EAAA,QAAQ,yBAAyB,CACnC,CAAA,GACH,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,4CACV,EAAE,EAAA,QAAQ,wBAAwB,CAClC,CAAA,CACA,KAKP,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAA,oDACd,EAAA,EAAA,KAAC,MAAD,CACE,cAAY,qBACZ,UAAW,EAAA,0CAEV,EAAQ,IAAK,IACZ,EAAA,EAAA,KAAC,EAAA,oBAAD,CAEU,SACR,WAAc,EAAO,CAAM,EAC3B,gBAAkB,GAAY,EAAgB,EAAQ,CAAO,CAC9D,EAJM,EAAO,EAIb,CACF,CACE,CAAA,CACF,CAAA,CAET"}
@@ -12,7 +12,7 @@ interface InstalledServersSectionProps {
12
12
  /** Current search query — empty string means no filter applied. */
13
13
  query?: string;
14
14
  onEdit: (server: MCPServerConfig) => void;
15
- onDelete: (serverId: string) => void;
15
+ onToggleEnabled: (server: MCPServerConfig, enabled: boolean) => void;
16
16
  }
17
- export declare function InstalledServersSection({ servers, hasAnyInstalled, query, onEdit, onDelete, }: InstalledServersSectionProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare function InstalledServersSection({ servers, hasAnyInstalled, query, onEdit, onToggleEnabled, }: InstalledServersSectionProps): import("react/jsx-runtime").JSX.Element;
18
18
  export {};
@@ -4,7 +4,7 @@ import { extensionModuleCardGridClassName as n, extensionModuleCardGridContainer
4
4
  import { InstalledServerCard as a } from "./installed-server-card.js";
5
5
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
6
6
  //#region src/components/features/mcp-page/installed-servers-section.tsx
7
- function c({ servers: c, hasAnyInstalled: l, query: u = "", onEdit: d, onDelete: f }) {
7
+ function c({ servers: c, hasAnyInstalled: l, query: u = "", onEdit: d, onToggleEnabled: f }) {
8
8
  let { t: p } = e("openhands");
9
9
  return c.length === 0 ? l && u.trim().length > 0 ? /* @__PURE__ */ o("div", {
10
10
  "data-testid": "mcp-installed-empty-search",
@@ -31,7 +31,7 @@ function c({ servers: c, hasAnyInstalled: l, query: u = "", onEdit: d, onDelete:
31
31
  children: c.map((e) => /* @__PURE__ */ o(a, {
32
32
  server: e,
33
33
  onEdit: () => d(e),
34
- onDelete: () => f(e.id)
34
+ onToggleEnabled: (t) => f(e, t)
35
35
  }, e.id))
36
36
  })
37
37
  });
@@ -1 +1 @@
1
- {"version":3,"file":"installed-servers-section.js","names":[],"sources":["../../../../src/components/features/mcp-page/installed-servers-section.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport { InstalledServerCard } from \"./installed-server-card\";\nimport {\n extensionModuleCardGridClassName,\n extensionModuleCardGridContainerClassName,\n extensionModuleEmptyStateClassName,\n} from \"#/utils/extension-module-card-classes\";\n\ninterface InstalledServersSectionProps {\n /** Already-filtered list — search filtering happens upstream. */\n servers: MCPServerConfig[];\n /**\n * True iff there is at least one installed server before applying\n * the search filter. Lets the section differentiate \"nothing\n * installed yet\" from \"no installed servers match the current\n * search\".\n */\n hasAnyInstalled: boolean;\n /** Current search query — empty string means no filter applied. */\n query?: string;\n onEdit: (server: MCPServerConfig) => void;\n onDelete: (serverId: string) => void;\n}\n\nexport function InstalledServersSection({\n servers,\n hasAnyInstalled,\n query = \"\",\n onEdit,\n onDelete,\n}: InstalledServersSectionProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isEmpty = servers.length === 0;\n\n if (isEmpty) {\n // Filter narrowed everything out — vs. nothing was installed in\n // the first place. Different copy in each case.\n if (hasAnyInstalled && query.trim().length > 0) {\n return (\n <div\n data-testid=\"mcp-installed-empty-search\"\n className=\"rounded-xl border border-[var(--oh-border)] p-6 text-center\"\n >\n <p className=\"text-xs text-tertiary-light\">\n {t(I18nKey.MCP$SEARCH_EMPTY)}\n </p>\n </div>\n );\n }\n return (\n <div\n data-testid=\"mcp-installed-empty\"\n className={extensionModuleEmptyStateClassName}\n >\n <p className=\"text-sm text-white\">\n {t(I18nKey.MCP$INSTALLED_EMPTY_TITLE)}\n </p>\n <p className=\"text-xs text-tertiary-light mt-1\">\n {t(I18nKey.MCP$INSTALLED_EMPTY_HINT)}\n </p>\n </div>\n );\n }\n\n return (\n <div className={extensionModuleCardGridContainerClassName}>\n <div\n data-testid=\"mcp-installed-list\"\n className={extensionModuleCardGridClassName}\n >\n {servers.map((server) => (\n <InstalledServerCard\n key={server.id}\n server={server}\n onEdit={() => onEdit(server)}\n onDelete={() => onDelete(server.id)}\n />\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;AA0BA,SAAgB,EAAwB,EACtC,YACA,oBACA,WAAQ,IACR,WACA,eAC+B;CAC/B,IAAM,EAAE,SAAM,EAAe,WAAW;CAkCxC,OAhCgB,EAAQ,WAAW,IAK7B,KAAmB,EAAM,KAAK,EAAE,SAAS,IAEzC,kBAAC,OAAD;EACE,eAAY;EACZ,WAAU;YAEV,kBAAC,KAAD;GAAG,WAAU;aACV,EAAE,EAAQ,gBAAgB;EAC1B,CAAA;CACA,CAAA,IAIP,kBAAC,OAAD;EACE,eAAY;EACZ,WAAW;YAFb,CAIE,kBAAC,KAAD;GAAG,WAAU;aACV,EAAE,EAAQ,yBAAyB;EACnC,CAAA,GACH,kBAAC,KAAD;GAAG,WAAU;aACV,EAAE,EAAQ,wBAAwB;EAClC,CAAA,CACA;MAKP,kBAAC,OAAD;EAAK,WAAW;YACd,kBAAC,OAAD;GACE,eAAY;GACZ,WAAW;aAEV,EAAQ,KAAK,MACZ,kBAAC,GAAD;IAEU;IACR,cAAc,EAAO,CAAM;IAC3B,gBAAgB,EAAS,EAAO,EAAE;GACnC,GAJM,EAAO,EAIb,CACF;EACE,CAAA;CACF,CAAA;AAET"}
1
+ {"version":3,"file":"installed-servers-section.js","names":[],"sources":["../../../../src/components/features/mcp-page/installed-servers-section.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { MCPServerConfig } from \"#/types/mcp-server\";\nimport { InstalledServerCard } from \"./installed-server-card\";\nimport {\n extensionModuleCardGridClassName,\n extensionModuleCardGridContainerClassName,\n extensionModuleEmptyStateClassName,\n} from \"#/utils/extension-module-card-classes\";\n\ninterface InstalledServersSectionProps {\n /** Already-filtered list — search filtering happens upstream. */\n servers: MCPServerConfig[];\n /**\n * True iff there is at least one installed server before applying\n * the search filter. Lets the section differentiate \"nothing\n * installed yet\" from \"no installed servers match the current\n * search\".\n */\n hasAnyInstalled: boolean;\n /** Current search query — empty string means no filter applied. */\n query?: string;\n onEdit: (server: MCPServerConfig) => void;\n onToggleEnabled: (server: MCPServerConfig, enabled: boolean) => void;\n}\n\nexport function InstalledServersSection({\n servers,\n hasAnyInstalled,\n query = \"\",\n onEdit,\n onToggleEnabled,\n}: InstalledServersSectionProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isEmpty = servers.length === 0;\n\n if (isEmpty) {\n // Filter narrowed everything out — vs. nothing was installed in\n // the first place. Different copy in each case.\n if (hasAnyInstalled && query.trim().length > 0) {\n return (\n <div\n data-testid=\"mcp-installed-empty-search\"\n className=\"rounded-xl border border-[var(--oh-border)] p-6 text-center\"\n >\n <p className=\"text-xs text-tertiary-light\">\n {t(I18nKey.MCP$SEARCH_EMPTY)}\n </p>\n </div>\n );\n }\n return (\n <div\n data-testid=\"mcp-installed-empty\"\n className={extensionModuleEmptyStateClassName}\n >\n <p className=\"text-sm text-white\">\n {t(I18nKey.MCP$INSTALLED_EMPTY_TITLE)}\n </p>\n <p className=\"text-xs text-tertiary-light mt-1\">\n {t(I18nKey.MCP$INSTALLED_EMPTY_HINT)}\n </p>\n </div>\n );\n }\n\n return (\n <div className={extensionModuleCardGridContainerClassName}>\n <div\n data-testid=\"mcp-installed-list\"\n className={extensionModuleCardGridClassName}\n >\n {servers.map((server) => (\n <InstalledServerCard\n key={server.id}\n server={server}\n onEdit={() => onEdit(server)}\n onToggleEnabled={(enabled) => onToggleEnabled(server, enabled)}\n />\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;AA0BA,SAAgB,EAAwB,EACtC,YACA,oBACA,WAAQ,IACR,WACA,sBAC+B;CAC/B,IAAM,EAAE,SAAM,EAAe,WAAW;CAkCxC,OAhCgB,EAAQ,WAAW,IAK7B,KAAmB,EAAM,KAAK,EAAE,SAAS,IAEzC,kBAAC,OAAD;EACE,eAAY;EACZ,WAAU;YAEV,kBAAC,KAAD;GAAG,WAAU;aACV,EAAE,EAAQ,gBAAgB;EAC1B,CAAA;CACA,CAAA,IAIP,kBAAC,OAAD;EACE,eAAY;EACZ,WAAW;YAFb,CAIE,kBAAC,KAAD;GAAG,WAAU;aACV,EAAE,EAAQ,yBAAyB;EACnC,CAAA,GACH,kBAAC,KAAD;GAAG,WAAU;aACV,EAAE,EAAQ,wBAAwB;EAClC,CAAA,CACA;MAKP,kBAAC,OAAD;EAAK,WAAW;YACd,kBAAC,OAAD;GACE,eAAY;GACZ,WAAW;aAEV,EAAQ,KAAK,MACZ,kBAAC,GAAD;IAEU;IACR,cAAc,EAAO,CAAM;IAC3B,kBAAkB,MAAY,EAAgB,GAAQ,CAAO;GAC9D,GAJM,EAAO,EAIb,CACF;EACE,CAAA;CACF,CAAA;AAET"}
@@ -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("../../../utils/retrieve-axios-error-message.cjs"),a=require("../../../utils/custom-toast-handlers.cjs"),o=require("../../../contexts/active-backend-context.cjs"),s=require("../../../api/mcp-health/probe-mcp-server-health.cjs"),c=require("../../../hooks/mutation/use-update-mcp-server.cjs"),l=require("../../../hooks/use-mcp-server-health.cjs"),u=require("../../../utils/mcp-test-error-message.cjs");let d=require("react");d=e.__toESM(d,1);let f=require("react/jsx-runtime");var p={unchecked:`bg-[var(--oh-text-tertiary)]`,checking:`bg-[var(--oh-interactive-selected)] animate-pulse`,healthy:`bg-[var(--oh-status-success)]`,failed:`bg-red-500`},m=`text-xs text-[var(--oh-muted)] underline transition-colors hover:text-white disabled:cursor-not-allowed disabled:opacity-60`;function h(e){return e.status===`healthy`?e.verification===`verified`?`healthy`:`healthy-connectivity`:e.status}function g(e,t){switch(t.status){case`checking`:return e(n.I18nKey.MCP$HEALTH_STATUS_CHECKING);case`healthy`:return t.verification===`verified`?e(n.I18nKey.MCP$HEALTH_STATUS_VERIFIED,{count:t.toolCount}):e(n.I18nKey.MCP$HEALTH_STATUS_CONNECTIVITY_ONLY);case`failed`:return u.makeMcpTestErrorMessage(e,t.kind,t.error);default:return e(n.I18nKey.MCP$HEALTH_STATUS_UNCHECKED)}}function _({server:e,catalog:u,onEdit:d}){let{t:_}=t.useTranslation(`openhands`),{backend:v}=o.useActiveBackend(),{health:y,probe:b,reauthorize:x}=l.useMcpServerHealth(e),{mutate:S}=c.useUpdateMcpServer();if(v.kind===`cloud`)return null;let C=y.status===`checking`,w=y.status===`failed`,T=g(_,y),E=async()=>{let t=await x();if(!t?.ok||!t.oauth_state||e.auth?.strategy!==`oauth2`)return;let r={...e,auth:{...e.auth,state:t.oauth_state}};S({serverId:e.id,server:r},{onSuccess:()=>s.seedMcpServerHealth(r,t,[]),onError:e=>a.displayErrorToast(i.retrieveAxiosErrorMessage(e)||_(n.I18nKey.ERROR$GENERIC))})};return(0,f.jsxs)(`div`,{"data-testid":`mcp-server-health-${e.id}`,role:`presentation`,className:`flex flex-col gap-1.5`,onClick:e=>e.stopPropagation(),onKeyDown:e=>e.stopPropagation(),children:[(0,f.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,f.jsx)(`span`,{"data-testid":`mcp-health-dot`,"data-status":h(y),"aria-hidden":`true`,className:r.cn(`inline-block h-2 w-2 shrink-0 rounded-full`,p[y.status])}),(0,f.jsx)(`p`,{"data-testid":`mcp-health-label-${e.id}`,className:r.cn(`line-clamp-2 break-words text-xs`,w?`text-red-500`:`text-tertiary-alt`),title:T,children:T})]}),y.status===`healthy`&&y.verification===`connectivity-only`?(0,f.jsx)(`p`,{className:`text-xs text-tertiary-light`,children:_(n.I18nKey.MCP$HEALTH_CONNECTIVITY_ONLY_HINT)}):null,(0,f.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,f.jsx)(`button`,{type:`button`,"data-testid":`mcp-health-probe-${e.id}`,className:m,onClick:()=>void b(),disabled:C,children:_(w?n.I18nKey.MCP$HEALTH_RETRY:n.I18nKey.MCP$TEST_BUTTON)}),w&&y.kind===`credentials`?(0,f.jsx)(`button`,{type:`button`,"data-testid":`mcp-health-update-credentials-${e.id}`,className:m,onClick:d,children:_(n.I18nKey.MCP$HEALTH_UPDATE_CREDENTIALS)}):null,w&&e.auth?.strategy===`oauth2`?(0,f.jsx)(`button`,{type:`button`,"data-testid":`mcp-health-reauthorize-${e.id}`,className:m,onClick:()=>void E(),children:_(n.I18nKey.MCP$HEALTH_REAUTHORIZE)}):null,w&&u?.docsUrl?(0,f.jsx)(`a`,{href:u.docsUrl,target:`_blank`,rel:`noreferrer`,className:m,children:_(n.I18nKey.MCP$VIEW_DOCS)}):null]})]})}exports.McpServerHealthSection=_;
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("../../../utils/retrieve-axios-error-message.cjs"),a=require("../../../utils/custom-toast-handlers.cjs"),o=require("../../../contexts/active-backend-context.cjs"),s=require("../../../hooks/mutation/use-update-mcp-server.cjs"),c=require("../../../api/mcp-health/probe-mcp-server-health.cjs"),l=require("../../../hooks/use-mcp-server-health.cjs"),u=require("../../../utils/mcp-test-error-message.cjs");let d=require("react");d=e.__toESM(d,1);let f=require("react/jsx-runtime");var p={unchecked:`bg-[var(--oh-text-tertiary)]`,checking:`bg-[var(--oh-interactive-selected)] animate-pulse`,healthy:`bg-[var(--oh-status-success)]`,failed:`bg-red-500`},m=`text-xs text-[var(--oh-muted)] underline transition-colors hover:text-white disabled:cursor-not-allowed disabled:opacity-60`;function h(e){return e.status===`healthy`?e.verification===`verified`?`healthy`:`healthy-connectivity`:e.status}function g(e,t){switch(t.status){case`checking`:return e(n.I18nKey.MCP$HEALTH_STATUS_CHECKING);case`healthy`:return t.verification===`verified`?e(n.I18nKey.MCP$HEALTH_STATUS_VERIFIED,{count:t.toolCount}):e(n.I18nKey.MCP$HEALTH_STATUS_CONNECTIVITY_ONLY);case`failed`:return u.makeMcpTestErrorMessage(e,t.kind,t.error);default:return e(n.I18nKey.MCP$HEALTH_STATUS_UNCHECKED)}}function _({server:e,catalog:u,onEdit:d}){let{t:_}=t.useTranslation(`openhands`),{backend:v}=o.useActiveBackend(),{health:y,probe:b,reauthorize:x}=l.useMcpServerHealth(e),{mutate:S}=s.useUpdateMcpServer();if(v.kind===`cloud`)return null;let C=y.status===`checking`,w=y.status===`failed`,T=g(_,y),E=async()=>{let t=await x();if(!t?.ok||!t.oauth_state||e.auth?.strategy!==`oauth2`)return;let r={...e,auth:{...e.auth,state:t.oauth_state}};S({serverId:e.id,server:r},{onSuccess:()=>c.seedMcpServerHealth(r,t,[]),onError:e=>a.displayErrorToast(i.retrieveAxiosErrorMessage(e)||_(n.I18nKey.ERROR$GENERIC))})};return(0,f.jsxs)(`div`,{"data-testid":`mcp-server-health-${e.id}`,role:`presentation`,className:`flex flex-col gap-1.5`,onClick:e=>e.stopPropagation(),onKeyDown:e=>e.stopPropagation(),children:[(0,f.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,f.jsx)(`span`,{"data-testid":`mcp-health-dot`,"data-status":h(y),"aria-hidden":`true`,className:r.cn(`inline-block h-2 w-2 shrink-0 rounded-full`,p[y.status])}),(0,f.jsx)(`p`,{"data-testid":`mcp-health-label-${e.id}`,className:r.cn(`line-clamp-2 break-words text-xs`,w?`text-red-500`:`text-tertiary-alt`),title:T,children:T})]}),y.status===`healthy`&&y.verification===`connectivity-only`?(0,f.jsx)(`p`,{className:`text-xs text-tertiary-light`,children:_(n.I18nKey.MCP$HEALTH_CONNECTIVITY_ONLY_HINT)}):null,(0,f.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,f.jsx)(`button`,{type:`button`,"data-testid":`mcp-health-probe-${e.id}`,className:m,onClick:()=>void b(),disabled:C,children:_(w?n.I18nKey.MCP$HEALTH_RETRY:n.I18nKey.MCP$TEST_BUTTON)}),w&&y.kind===`credentials`?(0,f.jsx)(`button`,{type:`button`,"data-testid":`mcp-health-update-credentials-${e.id}`,className:m,onClick:d,children:_(n.I18nKey.MCP$HEALTH_UPDATE_CREDENTIALS)}):null,w&&e.auth?.strategy===`oauth2`?(0,f.jsx)(`button`,{type:`button`,"data-testid":`mcp-health-reauthorize-${e.id}`,className:m,onClick:()=>void E(),children:_(n.I18nKey.MCP$HEALTH_REAUTHORIZE)}):null,w&&u?.docsUrl?(0,f.jsx)(`a`,{href:u.docsUrl,target:`_blank`,rel:`noreferrer`,className:m,children:_(n.I18nKey.MCP$VIEW_DOCS)}):null]})]})}exports.McpServerHealthSection=_;
2
2
  //# sourceMappingURL=mcp-server-health.cjs.map
@@ -4,8 +4,8 @@ import { cn as n } from "../../../utils/utils.js";
4
4
  import { retrieveAxiosErrorMessage as r } from "../../../utils/retrieve-axios-error-message.js";
5
5
  import { displayErrorToast as i } from "../../../utils/custom-toast-handlers.js";
6
6
  import { useActiveBackend as a } from "../../../contexts/active-backend-context.js";
7
- import { seedMcpServerHealth as o } from "../../../api/mcp-health/probe-mcp-server-health.js";
8
- import { useUpdateMcpServer as s } from "../../../hooks/mutation/use-update-mcp-server.js";
7
+ import { useUpdateMcpServer as o } from "../../../hooks/mutation/use-update-mcp-server.js";
8
+ import { seedMcpServerHealth as s } from "../../../api/mcp-health/probe-mcp-server-health.js";
9
9
  import { useMcpServerHealth as c } from "../../../hooks/use-mcp-server-health.js";
10
10
  import { makeMcpTestErrorMessage as l } from "../../../utils/mcp-test-error-message.js";
11
11
  import "react";
@@ -29,7 +29,7 @@ function h(e, n) {
29
29
  }
30
30
  }
31
31
  function g({ server: l, catalog: g, onEdit: _ }) {
32
- let { t: v } = e("openhands"), { backend: y } = a(), { health: b, probe: x, reauthorize: S } = c(l), { mutate: C } = s();
32
+ let { t: v } = e("openhands"), { backend: y } = a(), { health: b, probe: x, reauthorize: S } = c(l), { mutate: C } = o();
33
33
  if (y.kind === "cloud") return null;
34
34
  let w = b.status === "checking", T = b.status === "failed", E = h(v, b), D = async () => {
35
35
  let e = await S();
@@ -45,7 +45,7 @@ function g({ server: l, catalog: g, onEdit: _ }) {
45
45
  serverId: l.id,
46
46
  server: n
47
47
  }, {
48
- onSuccess: () => o(n, e, []),
48
+ onSuccess: () => s(n, e, []),
49
49
  onError: (e) => i(r(e) || v(t.ERROR$GENERIC))
50
50
  });
51
51
  };
@@ -1,7 +1,7 @@
1
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("../../../../node_modules/lucide-react/dist/esm/icons/trash-2.cjs"),i=require("../../../../utils/utils.cjs"),a=require("../../../../utils/mcp-server-name.cjs"),o=require("../../../../utils/form-control-classes.cjs"),s=require("../brand-button.cjs"),c=require("../optional-tag.cjs"),l=require("../settings-input.cjs"),u=require("../settings-dropdown-input.cjs");let d=require("react");d=e.__toESM(d,1);let f=require("react/jsx-runtime");function p({mode:e,server:p,existingServers:m,onSubmit:h,onCancel:g,onDelete:_,isActionDisabled:v=!1,onTest:y,isTestPending:b=!1,testMessage:x=null}){let{t:S}=t.useTranslation(`openhands`),[C,w]=d.default.useState(p?.type||`sse`),[T,E]=d.default.useState(()=>p?.auth?.strategy===`oauth2`?`oauth2`:p?.auth?.strategy===`header`?`header`:p?.auth?.strategy===`bearer`||p?.auth?.strategy===`api_key`?`bearer`:`none`),[D,O]=d.default.useState(()=>p?.auth?.strategy===`oauth2`?p.auth.authentication?.client_auth_method??`auto`:`auto`),[k,A]=d.default.useState(null),j=d.default.useRef(null),M=[{key:`sse`,label:S(n.I18nKey.SETTINGS$MCP_SERVER_TYPE_SSE)},{key:`stdio`,label:S(n.I18nKey.SETTINGS$MCP_SERVER_TYPE_STDIO)},{key:`shttp`,label:S(n.I18nKey.SETTINGS$MCP_SERVER_TYPE_SHTTP)}],N=[{key:`none`,label:S(n.I18nKey.SETTINGS$MCP_AUTH_MODE_NONE)},{key:`bearer`,label:S(n.I18nKey.SETTINGS$MCP_AUTH_MODE_BEARER)},{key:`header`,label:S(n.I18nKey.SETTINGS$MCP_AUTH_MODE_HEADER)},{key:`oauth2`,label:S(n.I18nKey.SETTINGS$MCP_AUTH_MODE_OAUTH)}],P=[{key:`auto`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_AUTO)},{key:`none`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_NONE)},{key:`client_secret_post`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_SECRET_POST)},{key:`client_secret_basic`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_SECRET_BASIC)},{key:`private_key_jwt`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_PRIVATE_KEY_JWT)}],F=e=>{if(!e)return S(n.I18nKey.SETTINGS$MCP_ERROR_URL_REQUIRED);try{let t=new URL(e);if(![`http:`,`https:`].includes(t.protocol))return S(n.I18nKey.SETTINGS$MCP_ERROR_URL_INVALID_PROTOCOL)}catch{return S(n.I18nKey.SETTINGS$MCP_ERROR_URL_INVALID)}return null},I=e=>e?a.isValidMcpServerName(e)?null:S(n.I18nKey.SETTINGS$MCP_ERROR_NAME_INVALID):S(n.I18nKey.SETTINGS$MCP_ERROR_NAME_REQUIRED),L=t=>!m||!(e===`add`||e===`edit`&&p?.name!==t)?null:m.filter(e=>e.type===`stdio`).map(e=>e.name).filter(Boolean).includes(t)?S(n.I18nKey.SETTINGS$MCP_ERROR_NAME_DUPLICATE):null,R=e=>e?e.includes(` `)?S(n.I18nKey.SETTINGS$MCP_ERROR_COMMAND_NO_SPACES):null:S(n.I18nKey.SETTINGS$MCP_ERROR_COMMAND_REQUIRED),z=t=>{if(!m)return null;let r=p?.url;return(e===`add`||e===`edit`&&r!==t)&&m.some(e=>(e.type===`sse`||e.type===`shttp`)&&e.url===t)?S(n.I18nKey.SETTINGS$MCP_ERROR_URL_DUPLICATE):null},B=e=>{if(!e.trim())return null;let t=e.split(`
2
2
  `);for(let e=0;e<t.length;e+=1){let r=t[e].trim();if(r){let e=r.indexOf(`=`);if(e===-1||!r.substring(0,e).trim())return S(n.I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT)}}return null},V=e=>{if(T===`header`){let t=e.get(`headers`)?.toString()||``;return t.trim()?B(t):S(n.I18nKey.SETTINGS$MCP_ERROR_HEADER_REQUIRED)}if(T===`oauth2`){let t=e.get(`oauth_client_id`)?.toString().trim();if(e.get(`oauth_client_secret`)?.toString().trim()&&!t)return S(n.I18nKey.SETTINGS$MCP_ERROR_OAUTH_SECRET_REQUIRES_ID)}return null},H=e=>{if(!e.trim())return null;let t=parseInt(e.trim(),10);return Number.isNaN(t)?S(n.I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_INVALID_NUMBER):t<=0?S(n.I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_POSITIVE):t>3600?S(n.I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_MAX_EXCEEDED):null},U=e=>{let t=e.get(`name`)?.toString().trim()||``,n=e.get(`command`)?.toString().trim()||``,r=e.get(`env`)?.toString()||``;return I(t)||L(t)||R(n)||B(r)||null},W=e=>{if(C===`sse`||C===`shttp`){let t=e.get(`url`)?.toString().trim()||``,r=F(t);if(r)return r;let i=z(t);if(i)return i;let o=e.get(`name`)?.toString().trim()||``;if(o&&!a.isValidMcpServerName(o))return S(n.I18nKey.SETTINGS$MCP_ERROR_NAME_INVALID);if(C===`shttp`){let t=H(e.get(`timeout`)?.toString()||``);if(t)return t}return V(e)}return C===`stdio`?U(e):null},G=e=>{let t={},n=e.trim();if(!n)return t;for(let e of n.split(`
3
3
  `)){let n=e.trim(),r=n.indexOf(`=`),i=r>=0?n.substring(0,r).trim():``;n&&r!==-1&&i&&(t[i]=n.substring(r+1).trim())}return t},K=e=>e?Object.entries(e).map(([e,t])=>`${e}=${t}`).join(`
4
- `):``,q=e=>e?.strategy===`bearer`||e?.strategy===`api_key`?e.value??``:``,J=e=>e?.strategy===`header`?K(e.headers):``,Y=p?.auth?.strategy===`oauth2`?p.auth.authentication:void 0,X=p?.auth?.strategy===`oauth2`?p.auth.state:void 0,Z=e=>{if(T===`none`)return;if(T===`bearer`){let t=e.get(`api_key`)?.toString().trim();return t?p?.auth?.strategy===`api_key`?{...p.auth,value:t}:{strategy:`bearer`,value:t}:void 0}if(T===`header`)return{strategy:`header`,headers:G(e.get(`headers`)?.toString()||``)};let t=e.get(`oauth_scopes`)?.toString().trim(),n=e.get(`oauth_client_id`)?.toString().trim(),r=e.get(`oauth_client_secret`)?.toString().trim();return{strategy:`oauth2`,authentication:{type:`oauth`,...D!==`auto`&&{client_auth_method:D},...t&&{scopes:t},...n&&{client_id:n},...r&&{client_secret:r}},...X&&{state:X}}},Q=e=>{let t={id:p?.id||`${C}-${Date.now()}`,type:C};if(C===`sse`||C===`shttp`){let n=e.get(`name`)?.toString().trim(),r=e.get(`url`)?.toString().trim(),i=e.get(`timeout`)?.toString().trim(),a=Z(e),o={...t,...n&&{name:n},url:r,...a&&{auth:a}};if(C===`shttp`&&i){let e=parseInt(i,10);Number.isNaN(e)||(o.timeout=e)}return o}let n=e.get(`name`)?.toString().trim(),r=e.get(`command`)?.toString().trim(),i=e.get(`args`)?.toString().trim(),a=e.get(`env`)?.toString().trim(),o=i?i.split(`
4
+ `):``,q=e=>e?.strategy===`bearer`||e?.strategy===`api_key`?e.value??``:``,J=e=>e?.strategy===`header`?K(e.headers):``,Y=p?.auth?.strategy===`oauth2`?p.auth.authentication:void 0,X=p?.auth?.strategy===`oauth2`?p.auth.state:void 0,Z=e=>{if(T===`none`)return;if(T===`bearer`){let t=e.get(`api_key`)?.toString().trim();return t?p?.auth?.strategy===`api_key`?{...p.auth,value:t}:{strategy:`bearer`,value:t}:void 0}if(T===`header`)return{strategy:`header`,headers:G(e.get(`headers`)?.toString()||``)};let t=e.get(`oauth_scopes`)?.toString().trim(),n=e.get(`oauth_client_id`)?.toString().trim(),r=e.get(`oauth_client_secret`)?.toString().trim();return{strategy:`oauth2`,authentication:{type:`oauth`,...D!==`auto`&&{client_auth_method:D},...t&&{scopes:t},...n&&{client_id:n},...r&&{client_secret:r}},...X&&{state:X}}},Q=e=>{let t={id:p?.id||`${C}-${Date.now()}`,type:C,...p?.enabled===!1&&{enabled:!1}};if(C===`sse`||C===`shttp`){let n=e.get(`name`)?.toString().trim(),r=e.get(`url`)?.toString().trim(),i=e.get(`timeout`)?.toString().trim(),a=Z(e),o={...t,...n&&{name:n},url:r,...a&&{auth:a}};if(C===`shttp`&&i){let e=parseInt(i,10);Number.isNaN(e)||(o.timeout=e)}return o}let n=e.get(`name`)?.toString().trim(),r=e.get(`command`)?.toString().trim(),i=e.get(`args`)?.toString().trim(),a=e.get(`env`)?.toString().trim(),o=i?i.split(`
5
5
  `).map(e=>e.trim()).filter(Boolean):[],s=G(a||``);return{...t,name:n,command:r,...o.length>0&&{args:o},...Object.keys(s).length>0&&{env:s}}};return(0,f.jsxs)(`form`,{ref:j,"data-testid":e===`add`?`add-mcp-server-form`:`edit-mcp-server-form`,onSubmit:e=>{e.preventDefault(),A(null);let t=new FormData(e.currentTarget),n=W(t);if(n){A(n);return}h(Q(t))},className:`flex flex-col items-start gap-6`,noValidate:!0,children:[e===`add`&&(0,f.jsx)(u.SettingsDropdownInput,{testId:`server-type-dropdown`,name:`server-type`,label:S(n.I18nKey.SETTINGS$MCP_SERVER_TYPE),items:M,selectedKey:C,onSelectionChange:e=>w(e),onInputChange:()=>{},isClearable:!1,allowsCustomValue:!1,required:!0,wrapperClassName:`w-full min-w-0`}),k&&(0,f.jsx)(`p`,{className:`text-red-500 text-sm`,children:k}),(C===`sse`||C===`shttp`)&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(l.SettingsInput,{testId:`server-name-input`,name:`name`,type:`text`,label:S(n.I18nKey.SETTINGS$MCP_SERVER_NAME),className:`w-full min-w-0`,showOptionalTag:!0,defaultValue:p?.name||``,placeholder:`my_search_server`,pattern:a.MCP_SERVER_NAME_PATTERN.source}),(0,f.jsx)(l.SettingsInput,{testId:`url-input`,name:`url`,type:`url`,label:S(n.I18nKey.SETTINGS$MCP_URL),className:`w-full min-w-0`,required:!0,defaultValue:p?.url||``,placeholder:`https://api.example.com`}),(0,f.jsx)(u.SettingsDropdownInput,{testId:`auth-mode-dropdown`,name:`auth-mode`,label:S(n.I18nKey.SETTINGS$MCP_AUTHENTICATION),items:N,selectedKey:T,onSelectionChange:e=>E(e),onInputChange:()=>{},isClearable:!1,allowsCustomValue:!1,wrapperClassName:`w-full min-w-0`}),T===`bearer`&&(0,f.jsx)(l.SettingsInput,{testId:`api-key-input`,name:`api_key`,type:`password`,label:S(n.I18nKey.SETTINGS$MCP_API_KEY),className:`w-full min-w-0`,required:!0,defaultValue:q(p?.auth),placeholder:S(n.I18nKey.SETTINGS$MCP_API_KEY_PLACEHOLDER)}),T===`header`&&(0,f.jsxs)(`label`,{className:`flex flex-col gap-2.5 w-full min-w-0`,children:[(0,f.jsx)(`span`,{className:`text-sm`,children:S(n.I18nKey.SETTINGS$MCP_HEADERS)}),(0,f.jsx)(`textarea`,{"data-testid":`headers-input`,name:`headers`,rows:4,defaultValue:J(p?.auth),placeholder:S(n.I18nKey.SETTINGS$MCP_HEADERS_PLACEHOLDER),className:i.cn(o.formControlMultilineFieldClassName,`resize-none placeholder:italic`,`disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]`)})]}),T===`oauth2`&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(u.SettingsDropdownInput,{testId:`oauth-client-auth-method-dropdown`,name:`oauth_client_auth_method`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH),items:P,selectedKey:D,onSelectionChange:e=>O(e),onInputChange:()=>{},isClearable:!1,allowsCustomValue:!1,wrapperClassName:`w-full min-w-0`}),(0,f.jsx)(l.SettingsInput,{testId:`oauth-client-id-input`,name:`oauth_client_id`,type:`text`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_ID),className:`w-full min-w-0`,showOptionalTag:!0,defaultValue:Y?.client_id||``,placeholder:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_ID_PLACEHOLDER)}),(0,f.jsx)(l.SettingsInput,{testId:`oauth-client-secret-input`,name:`oauth_client_secret`,type:`password`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_SECRET),className:`w-full min-w-0`,showOptionalTag:!0,defaultValue:Y?.client_secret||``,placeholder:S(n.I18nKey.SETTINGS$MCP_OAUTH_CLIENT_SECRET_PLACEHOLDER)}),(0,f.jsx)(l.SettingsInput,{testId:`oauth-scopes-input`,name:`oauth_scopes`,type:`text`,label:S(n.I18nKey.SETTINGS$MCP_OAUTH_SCOPES),className:`w-full min-w-0`,showOptionalTag:!0,defaultValue:Array.isArray(Y?.scopes)?Y.scopes.join(` `):Y?.scopes||``,placeholder:S(n.I18nKey.SETTINGS$MCP_OAUTH_SCOPES_PLACEHOLDER)})]}),C===`shttp`&&(0,f.jsx)(l.SettingsInput,{testId:`timeout-input`,name:`timeout`,type:`number`,label:S(n.I18nKey.SETTINGS$MCP_TIMEOUT_LABEL),className:`w-full min-w-0`,showOptionalTag:!0,defaultValue:p?.timeout?.toString()||``,placeholder:`60`,min:1,max:3600})]}),C===`stdio`&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(l.SettingsInput,{testId:`name-input`,name:`name`,type:`text`,label:S(n.I18nKey.SETTINGS$MCP_NAME),className:`w-full min-w-0`,required:!0,defaultValue:p?.name||``,placeholder:`my_mcp_server`,pattern:a.MCP_SERVER_NAME_PATTERN.source}),(0,f.jsx)(l.SettingsInput,{testId:`command-input`,name:`command`,type:`text`,label:S(n.I18nKey.SETTINGS$MCP_COMMAND),className:`w-full min-w-0`,required:!0,defaultValue:p?.command||``,placeholder:`npx`}),(0,f.jsxs)(`label`,{className:`flex flex-col gap-2.5 w-full min-w-0`,children:[(0,f.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,f.jsx)(`span`,{className:`text-sm`,children:S(n.I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS)}),(0,f.jsx)(c.OptionalTag,{})]}),(0,f.jsx)(`textarea`,{"data-testid":`args-input`,name:`args`,rows:3,defaultValue:p?.args?.join(`
6
6
  `)||``,placeholder:`arg1
7
7
  arg2
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server-form.cjs","names":[],"sources":["../../../../../src/components/features/settings/mcp-settings/mcp-server-form.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Trash2 } from \"lucide-react\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { SettingsInput } from \"../settings-input\";\nimport { SettingsDropdownInput } from \"../settings-dropdown-input\";\nimport { BrandButton } from \"../brand-button\";\nimport { OptionalTag } from \"../optional-tag\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlMultilineFieldClassName } from \"#/utils/form-control-classes\";\nimport {\n isValidMcpServerName,\n MCP_SERVER_NAME_PATTERN,\n} from \"#/utils/mcp-server-name\";\nimport type {\n MCPAuthCredential,\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type { MCPServerConfig } from \"#/types/mcp-server\";\n\ntype MCPServerType = \"sse\" | \"stdio\" | \"shttp\";\ntype RemoteAuthMode = \"none\" | \"bearer\" | \"header\" | \"oauth2\";\ntype OAuthClientAuthMethodOption = \"auto\" | MCPOAuthClientAuthMethod;\n\nexport interface TestMessage {\n ok: boolean;\n text: string;\n}\n\ninterface MCPServerFormProps {\n mode: \"add\" | \"edit\";\n server?: MCPServerConfig;\n existingServers?: MCPServerConfig[];\n onSubmit: (server: MCPServerConfig) => void;\n onCancel: () => void;\n onDelete?: () => void;\n isActionDisabled?: boolean;\n onTest?: (server: MCPServerConfig) => void;\n isTestPending?: boolean;\n testMessage?: TestMessage | null;\n}\n\nexport function MCPServerForm({\n mode,\n server,\n existingServers,\n onSubmit,\n onCancel,\n onDelete,\n isActionDisabled = false,\n onTest,\n isTestPending = false,\n testMessage = null,\n}: MCPServerFormProps) {\n const { t } = useTranslation(\"openhands\");\n const [serverType, setServerType] = React.useState<MCPServerType>(\n server?.type || \"sse\",\n );\n const [authMode, setAuthMode] = React.useState<RemoteAuthMode>(() => {\n if (server?.auth?.strategy === \"oauth2\") return \"oauth2\";\n if (server?.auth?.strategy === \"header\") return \"header\";\n if (\n server?.auth?.strategy === \"bearer\" ||\n server?.auth?.strategy === \"api_key\"\n ) {\n return \"bearer\";\n }\n return \"none\";\n });\n const [oauthClientAuthMethod, setOAuthClientAuthMethod] =\n React.useState<OAuthClientAuthMethodOption>(() =>\n server?.auth?.strategy === \"oauth2\"\n ? (server.auth.authentication?.client_auth_method ?? \"auto\")\n : \"auto\",\n );\n const [error, setError] = React.useState<string | null>(null);\n const formRef = React.useRef<HTMLFormElement>(null);\n\n const serverTypeOptions = [\n { key: \"sse\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_SSE) },\n { key: \"stdio\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_STDIO) },\n { key: \"shttp\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_SHTTP) },\n ];\n const authModeOptions = [\n { key: \"none\", label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_NONE) },\n { key: \"bearer\", label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_BEARER) },\n { key: \"header\", label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_HEADER) },\n { key: \"oauth2\", label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_OAUTH) },\n ];\n const oauthClientAuthMethodOptions = [\n { key: \"auto\", label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_AUTO) },\n { key: \"none\", label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_NONE) },\n {\n key: \"client_secret_post\",\n label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_SECRET_POST),\n },\n {\n key: \"client_secret_basic\",\n label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_SECRET_BASIC),\n },\n {\n key: \"private_key_jwt\",\n label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_PRIVATE_KEY_JWT),\n },\n ];\n\n const validateUrl = (url: string): string | null => {\n if (!url) return t(I18nKey.SETTINGS$MCP_ERROR_URL_REQUIRED);\n try {\n const urlObj = new URL(url);\n if (![\"http:\", \"https:\"].includes(urlObj.protocol)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_URL_INVALID_PROTOCOL);\n }\n } catch {\n return t(I18nKey.SETTINGS$MCP_ERROR_URL_INVALID);\n }\n return null;\n };\n\n const validateName = (name: string): string | null => {\n if (!name) return t(I18nKey.SETTINGS$MCP_ERROR_NAME_REQUIRED);\n if (!isValidMcpServerName(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_INVALID);\n }\n return null;\n };\n\n const validateNameUniqueness = (name: string): string | null => {\n if (!existingServers) return null;\n const shouldCheckUniqueness =\n mode === \"add\" || (mode === \"edit\" && server?.name !== name);\n if (!shouldCheckUniqueness) return null;\n\n const existingStdioNames = existingServers\n .filter((s) => s.type === \"stdio\")\n .map((s) => s.name)\n .filter(Boolean);\n if (existingStdioNames.includes(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_DUPLICATE);\n }\n return null;\n };\n\n const validateCommand = (command: string): string | null => {\n if (!command) return t(I18nKey.SETTINGS$MCP_ERROR_COMMAND_REQUIRED);\n if (command.includes(\" \")) {\n return t(I18nKey.SETTINGS$MCP_ERROR_COMMAND_NO_SPACES);\n }\n return null;\n };\n\n const validateUrlUniqueness = (url: string): string | null => {\n if (!existingServers) return null;\n const originalUrl = server?.url;\n const changed = mode === \"add\" || (mode === \"edit\" && originalUrl !== url);\n if (!changed) return null;\n // For URL-based servers (sse/shttp), ensure URL is unique across both types\n const exists = existingServers.some(\n (s) => (s.type === \"sse\" || s.type === \"shttp\") && s.url === url,\n );\n if (exists) return t(I18nKey.SETTINGS$MCP_ERROR_URL_DUPLICATE);\n return null;\n };\n\n const validateEnvFormat = (envString: string): string | null => {\n if (!envString.trim()) return null;\n const lines = envString.split(\"\\n\");\n for (let i = 0; i < lines.length; i += 1) {\n const trimmed = lines[i].trim();\n if (trimmed) {\n const eq = trimmed.indexOf(\"=\");\n if (eq === -1) return t(I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);\n const key = trimmed.substring(0, eq).trim();\n if (!key) return t(I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);\n }\n }\n return null;\n };\n\n const validateRemoteAuth = (formData: FormData): string | null => {\n if (authMode === \"header\") {\n const headerString = formData.get(\"headers\")?.toString() || \"\";\n if (!headerString.trim())\n return t(I18nKey.SETTINGS$MCP_ERROR_HEADER_REQUIRED);\n return validateEnvFormat(headerString);\n }\n if (authMode === \"oauth2\") {\n const clientId = formData.get(\"oauth_client_id\")?.toString().trim();\n const clientSecret = formData\n .get(\"oauth_client_secret\")\n ?.toString()\n .trim();\n if (clientSecret && !clientId) {\n return t(I18nKey.SETTINGS$MCP_ERROR_OAUTH_SECRET_REQUIRES_ID);\n }\n }\n return null;\n };\n\n const validateTimeout = (timeoutStr: string): string | null => {\n if (!timeoutStr.trim()) return null; // Optional field\n\n const timeout = parseInt(timeoutStr.trim(), 10);\n if (Number.isNaN(timeout)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_INVALID_NUMBER);\n }\n if (timeout <= 0) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_POSITIVE);\n }\n if (timeout > 3600) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_MAX_EXCEEDED);\n }\n return null;\n };\n\n const validateStdioServer = (formData: FormData): string | null => {\n const name = formData.get(\"name\")?.toString().trim() || \"\";\n const command = formData.get(\"command\")?.toString().trim() || \"\";\n const envString = formData.get(\"env\")?.toString() || \"\";\n\n const nameError = validateName(name);\n if (nameError) return nameError;\n\n const uniquenessError = validateNameUniqueness(name);\n if (uniquenessError) return uniquenessError;\n\n const commandError = validateCommand(command);\n if (commandError) return commandError;\n\n // Validate environment variable format\n const envError = validateEnvFormat(envString);\n if (envError) return envError;\n\n return null;\n };\n\n const validateForm = (formData: FormData): string | null => {\n if (serverType === \"sse\" || serverType === \"shttp\") {\n const url = formData.get(\"url\")?.toString().trim() || \"\";\n const urlError = validateUrl(url);\n if (urlError) return urlError;\n const urlDupError = validateUrlUniqueness(url);\n if (urlDupError) return urlDupError;\n\n // The name is optional, but when provided it becomes the mcp_config\n // key (and the reference used in mcp_server_refs), so hold it to the\n // same safe-identifier rule as stdio names.\n const name = formData.get(\"name\")?.toString().trim() || \"\";\n if (name && !isValidMcpServerName(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_INVALID);\n }\n\n // Validate timeout for SHTTP servers only\n if (serverType === \"shttp\") {\n const timeoutStr = formData.get(\"timeout\")?.toString() || \"\";\n const timeoutError = validateTimeout(timeoutStr);\n if (timeoutError) return timeoutError;\n }\n\n return validateRemoteAuth(formData);\n }\n\n if (serverType === \"stdio\") {\n return validateStdioServer(formData);\n }\n\n return null;\n };\n\n const parseEnvironmentVariables = (\n envString: string,\n ): Record<string, string> => {\n const env: Record<string, string> = {};\n const input = envString.trim();\n if (!input) return env;\n\n for (const line of input.split(\"\\n\")) {\n const trimmed = line.trim();\n const eq = trimmed.indexOf(\"=\");\n const key = eq >= 0 ? trimmed.substring(0, eq).trim() : \"\";\n if (trimmed && eq !== -1 && key) {\n env[key] = trimmed.substring(eq + 1).trim();\n }\n }\n return env;\n };\n\n const formatEnvironmentVariables = (\n env?: Record<string, string> | null,\n ): string => {\n if (!env) return \"\";\n return Object.entries(env)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"\\n\");\n };\n\n const editableAuthValue = (auth: MCPAuthCredential | undefined): string => {\n if (auth?.strategy === \"bearer\" || auth?.strategy === \"api_key\") {\n return auth.value ?? \"\";\n }\n return \"\";\n };\n\n const editableHeaderValue = (auth: MCPAuthCredential | undefined): string => {\n if (auth?.strategy !== \"header\") return \"\";\n return formatEnvironmentVariables(auth.headers);\n };\n\n const oauthAuthentication =\n server?.auth?.strategy === \"oauth2\"\n ? server.auth.authentication\n : undefined;\n const oauthState =\n server?.auth?.strategy === \"oauth2\" ? server.auth.state : undefined;\n\n const authFromFormData = (\n formData: FormData,\n ): MCPAuthCredential | undefined => {\n if (authMode === \"none\") return undefined;\n if (authMode === \"bearer\") {\n const value = formData.get(\"api_key\")?.toString().trim();\n if (!value) return undefined;\n if (server?.auth?.strategy === \"api_key\") {\n return { ...server.auth, value };\n }\n return { strategy: \"bearer\", value };\n }\n if (authMode === \"header\") {\n const headers = parseEnvironmentVariables(\n formData.get(\"headers\")?.toString() || \"\",\n );\n return { strategy: \"header\", headers };\n }\n\n const scopes = formData.get(\"oauth_scopes\")?.toString().trim();\n const clientId = formData.get(\"oauth_client_id\")?.toString().trim();\n const clientSecret = formData.get(\"oauth_client_secret\")?.toString().trim();\n const authentication: MCPAuthenticationConfig = {\n type: \"oauth\",\n ...(oauthClientAuthMethod !== \"auto\" && {\n client_auth_method: oauthClientAuthMethod,\n }),\n ...(scopes && { scopes }),\n ...(clientId && { client_id: clientId }),\n ...(clientSecret && { client_secret: clientSecret }),\n };\n return {\n strategy: \"oauth2\",\n authentication,\n ...(oauthState && { state: oauthState }),\n };\n };\n\n const buildConfig = (formData: FormData): MCPServerConfig => {\n const baseConfig = {\n id: server?.id || `${serverType}-${Date.now()}`,\n type: serverType,\n };\n\n if (serverType === \"sse\" || serverType === \"shttp\") {\n const name = formData.get(\"name\")?.toString().trim();\n const url = formData.get(\"url\")?.toString().trim();\n const timeoutStr = formData.get(\"timeout\")?.toString().trim();\n const auth = authFromFormData(formData);\n\n const serverConfig: MCPServerConfig = {\n ...baseConfig,\n ...(name && { name }),\n url: url!,\n ...(auth && { auth }),\n };\n\n // Only add timeout for SHTTP servers\n if (serverType === \"shttp\" && timeoutStr) {\n const timeoutValue = parseInt(timeoutStr, 10);\n if (!Number.isNaN(timeoutValue)) {\n serverConfig.timeout = timeoutValue;\n }\n }\n\n return serverConfig;\n }\n\n // stdio\n const name = formData.get(\"name\")?.toString().trim();\n const command = formData.get(\"command\")?.toString().trim();\n const argsString = formData.get(\"args\")?.toString().trim();\n const envString = formData.get(\"env\")?.toString().trim();\n\n const args = argsString\n ? argsString\n .split(\"\\n\")\n .map((arg) => arg.trim())\n .filter(Boolean)\n : [];\n const env = parseEnvironmentVariables(envString || \"\");\n\n return {\n ...baseConfig,\n name: name!,\n command: command!,\n ...(args.length > 0 && { args }),\n ...(Object.keys(env).length > 0 && { env }),\n };\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n const formData = new FormData(event.currentTarget);\n const validationError = validateForm(formData);\n\n if (validationError) {\n setError(validationError);\n return;\n }\n\n onSubmit(buildConfig(formData));\n };\n\n const handleTestClick = () => {\n if (!onTest || !formRef.current) return;\n setError(null);\n const formData = new FormData(formRef.current);\n const validationError = validateForm(formData);\n if (validationError) {\n setError(validationError);\n return;\n }\n onTest(buildConfig(formData));\n };\n\n const formTestId =\n mode === \"add\" ? \"add-mcp-server-form\" : \"edit-mcp-server-form\";\n\n return (\n <form\n ref={formRef}\n data-testid={formTestId}\n onSubmit={handleSubmit}\n className=\"flex flex-col items-start gap-6\"\n noValidate\n >\n {mode === \"add\" && (\n <SettingsDropdownInput\n testId=\"server-type-dropdown\"\n name=\"server-type\"\n label={t(I18nKey.SETTINGS$MCP_SERVER_TYPE)}\n items={serverTypeOptions}\n selectedKey={serverType}\n onSelectionChange={(key) => setServerType(key as MCPServerType)}\n onInputChange={() => {}} // Prevent input changes\n isClearable={false}\n allowsCustomValue={false}\n required\n wrapperClassName=\"w-full min-w-0\"\n />\n )}\n\n {error && <p className=\"text-red-500 text-sm\">{error}</p>}\n\n {(serverType === \"sse\" || serverType === \"shttp\") && (\n <>\n <SettingsInput\n testId=\"server-name-input\"\n name=\"name\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_SERVER_NAME)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={server?.name || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"my_search_server\"\n pattern={MCP_SERVER_NAME_PATTERN.source}\n />\n\n <SettingsInput\n testId=\"url-input\"\n name=\"url\"\n type=\"url\"\n label={t(I18nKey.SETTINGS$MCP_URL)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.url || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"https://api.example.com\"\n />\n\n <SettingsDropdownInput\n testId=\"auth-mode-dropdown\"\n name=\"auth-mode\"\n label={t(I18nKey.SETTINGS$MCP_AUTHENTICATION)}\n items={authModeOptions}\n selectedKey={authMode}\n onSelectionChange={(key) => setAuthMode(key as RemoteAuthMode)}\n onInputChange={() => {}}\n isClearable={false}\n allowsCustomValue={false}\n wrapperClassName=\"w-full min-w-0\"\n />\n\n {authMode === \"bearer\" && (\n <SettingsInput\n testId=\"api-key-input\"\n name=\"api_key\"\n type=\"password\"\n label={t(I18nKey.SETTINGS$MCP_API_KEY)}\n className=\"w-full min-w-0\"\n required\n defaultValue={editableAuthValue(server?.auth)}\n placeholder={t(I18nKey.SETTINGS$MCP_API_KEY_PLACEHOLDER)}\n />\n )}\n\n {authMode === \"header\" && (\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <span className=\"text-sm\">{t(I18nKey.SETTINGS$MCP_HEADERS)}</span>\n <textarea\n data-testid=\"headers-input\"\n name=\"headers\"\n rows={4}\n defaultValue={editableHeaderValue(server?.auth)}\n placeholder={t(I18nKey.SETTINGS$MCP_HEADERS_PLACEHOLDER)}\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n </label>\n )}\n\n {authMode === \"oauth2\" && (\n <>\n <SettingsDropdownInput\n testId=\"oauth-client-auth-method-dropdown\"\n name=\"oauth_client_auth_method\"\n label={t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH)}\n items={oauthClientAuthMethodOptions}\n selectedKey={oauthClientAuthMethod}\n onSelectionChange={(key) =>\n setOAuthClientAuthMethod(key as OAuthClientAuthMethodOption)\n }\n onInputChange={() => {}}\n isClearable={false}\n allowsCustomValue={false}\n wrapperClassName=\"w-full min-w-0\"\n />\n <SettingsInput\n testId=\"oauth-client-id-input\"\n name=\"oauth_client_id\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_ID)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={oauthAuthentication?.client_id || \"\"}\n placeholder={t(\n I18nKey.SETTINGS$MCP_OAUTH_CLIENT_ID_PLACEHOLDER,\n )}\n />\n <SettingsInput\n testId=\"oauth-client-secret-input\"\n name=\"oauth_client_secret\"\n type=\"password\"\n label={t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_SECRET)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={oauthAuthentication?.client_secret || \"\"}\n placeholder={t(\n I18nKey.SETTINGS$MCP_OAUTH_CLIENT_SECRET_PLACEHOLDER,\n )}\n />\n <SettingsInput\n testId=\"oauth-scopes-input\"\n name=\"oauth_scopes\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_OAUTH_SCOPES)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={\n Array.isArray(oauthAuthentication?.scopes)\n ? oauthAuthentication.scopes.join(\" \")\n : oauthAuthentication?.scopes || \"\"\n }\n placeholder={t(I18nKey.SETTINGS$MCP_OAUTH_SCOPES_PLACEHOLDER)}\n />\n </>\n )}\n\n {serverType === \"shttp\" && (\n <SettingsInput\n testId=\"timeout-input\"\n name=\"timeout\"\n type=\"number\"\n label={t(I18nKey.SETTINGS$MCP_TIMEOUT_LABEL)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={server?.timeout?.toString() || \"\"}\n placeholder=\"60\"\n min={1}\n max={3600}\n />\n )}\n </>\n )}\n\n {serverType === \"stdio\" && (\n <>\n <SettingsInput\n testId=\"name-input\"\n name=\"name\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_NAME)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.name || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"my_mcp_server\"\n pattern={MCP_SERVER_NAME_PATTERN.source}\n />\n\n <SettingsInput\n testId=\"command-input\"\n name=\"command\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_COMMAND)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.command || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"npx\"\n />\n\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">\n {t(I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS)}\n </span>\n <OptionalTag />\n </div>\n <textarea\n data-testid=\"args-input\"\n name=\"args\"\n rows={3}\n defaultValue={server?.args?.join(\"\\n\") || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"arg1&#10;arg2&#10;arg3\"\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n <p className=\"text-xs text-tertiary-alt\">\n {t(I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS_HELP)}\n </p>\n </label>\n\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">\n {t(I18nKey.SETTINGS$MCP_ENVIRONMENT_VARIABLES)}\n </span>\n <OptionalTag />\n </div>\n <textarea\n data-testid=\"env-input\"\n name=\"env\"\n rows={4}\n defaultValue={formatEnvironmentVariables(server?.env)}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"KEY1=value1&#10;KEY2=value2\"\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n </label>\n </>\n )}\n\n {testMessage && (\n <p\n data-testid=\"mcp-test-message\"\n className={\n testMessage.ok\n ? \"text-sm text-green-500 whitespace-pre-wrap\"\n : \"text-sm text-red-500 whitespace-pre-wrap\"\n }\n >\n {testMessage.text}\n </p>\n )}\n\n <div\n className={cn(\n \"flex w-full items-center gap-2\",\n onDelete ? \"justify-between\" : \"justify-end\",\n )}\n >\n {onDelete ? (\n <BrandButton\n testId=\"mcp-custom-editor-delete\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onDelete}\n isDisabled={isActionDisabled}\n startContent={\n <Trash2 aria-hidden className=\"size-4\" strokeWidth={2} />\n }\n >\n {t(I18nKey.BUTTON$DELETE)}\n </BrandButton>\n ) : null}\n <div className=\"flex items-center gap-2\">\n <BrandButton\n testId=\"cancel-button\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onCancel}\n isDisabled={isActionDisabled}\n >\n {t(I18nKey.BUTTON$CANCEL)}\n </BrandButton>\n {onTest && (\n <BrandButton\n testId=\"mcp-test-connection\"\n type=\"button\"\n variant=\"secondary\"\n onClick={handleTestClick}\n isDisabled={isActionDisabled || isTestPending}\n >\n {isTestPending\n ? t(I18nKey.MCP$VERIFYING)\n : t(I18nKey.MCP$TEST_BUTTON)}\n </BrandButton>\n )}\n <BrandButton\n testId=\"submit-button\"\n type=\"submit\"\n variant=\"primary\"\n isDisabled={isActionDisabled || isTestPending}\n >\n {mode === \"add\" && t(I18nKey.SETTINGS$MCP_ADD_SERVER)}\n {mode === \"edit\" && t(I18nKey.SETTINGS$MCP_SAVE_SERVER)}\n </BrandButton>\n </div>\n </div>\n </form>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server-form.cjs","names":[],"sources":["../../../../../src/components/features/settings/mcp-settings/mcp-server-form.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Trash2 } from \"lucide-react\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { SettingsInput } from \"../settings-input\";\nimport { SettingsDropdownInput } from \"../settings-dropdown-input\";\nimport { BrandButton } from \"../brand-button\";\nimport { OptionalTag } from \"../optional-tag\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlMultilineFieldClassName } from \"#/utils/form-control-classes\";\nimport {\n isValidMcpServerName,\n MCP_SERVER_NAME_PATTERN,\n} from \"#/utils/mcp-server-name\";\nimport type {\n MCPAuthCredential,\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type { MCPServerConfig } from \"#/types/mcp-server\";\n\ntype MCPServerType = \"sse\" | \"stdio\" | \"shttp\";\ntype RemoteAuthMode = \"none\" | \"bearer\" | \"header\" | \"oauth2\";\ntype OAuthClientAuthMethodOption = \"auto\" | MCPOAuthClientAuthMethod;\n\nexport interface TestMessage {\n ok: boolean;\n text: string;\n}\n\ninterface MCPServerFormProps {\n mode: \"add\" | \"edit\";\n server?: MCPServerConfig;\n existingServers?: MCPServerConfig[];\n onSubmit: (server: MCPServerConfig) => void;\n onCancel: () => void;\n onDelete?: () => void;\n isActionDisabled?: boolean;\n onTest?: (server: MCPServerConfig) => void;\n isTestPending?: boolean;\n testMessage?: TestMessage | null;\n}\n\nexport function MCPServerForm({\n mode,\n server,\n existingServers,\n onSubmit,\n onCancel,\n onDelete,\n isActionDisabled = false,\n onTest,\n isTestPending = false,\n testMessage = null,\n}: MCPServerFormProps) {\n const { t } = useTranslation(\"openhands\");\n const [serverType, setServerType] = React.useState<MCPServerType>(\n server?.type || \"sse\",\n );\n const [authMode, setAuthMode] = React.useState<RemoteAuthMode>(() => {\n if (server?.auth?.strategy === \"oauth2\") return \"oauth2\";\n if (server?.auth?.strategy === \"header\") return \"header\";\n if (\n server?.auth?.strategy === \"bearer\" ||\n server?.auth?.strategy === \"api_key\"\n ) {\n return \"bearer\";\n }\n return \"none\";\n });\n const [oauthClientAuthMethod, setOAuthClientAuthMethod] =\n React.useState<OAuthClientAuthMethodOption>(() =>\n server?.auth?.strategy === \"oauth2\"\n ? (server.auth.authentication?.client_auth_method ?? \"auto\")\n : \"auto\",\n );\n const [error, setError] = React.useState<string | null>(null);\n const formRef = React.useRef<HTMLFormElement>(null);\n\n const serverTypeOptions = [\n { key: \"sse\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_SSE) },\n { key: \"stdio\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_STDIO) },\n { key: \"shttp\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_SHTTP) },\n ];\n const authModeOptions = [\n { key: \"none\", label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_NONE) },\n { key: \"bearer\", label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_BEARER) },\n { key: \"header\", label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_HEADER) },\n { key: \"oauth2\", label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_OAUTH) },\n ];\n const oauthClientAuthMethodOptions = [\n { key: \"auto\", label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_AUTO) },\n { key: \"none\", label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_NONE) },\n {\n key: \"client_secret_post\",\n label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_SECRET_POST),\n },\n {\n key: \"client_secret_basic\",\n label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_SECRET_BASIC),\n },\n {\n key: \"private_key_jwt\",\n label: t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH_PRIVATE_KEY_JWT),\n },\n ];\n\n const validateUrl = (url: string): string | null => {\n if (!url) return t(I18nKey.SETTINGS$MCP_ERROR_URL_REQUIRED);\n try {\n const urlObj = new URL(url);\n if (![\"http:\", \"https:\"].includes(urlObj.protocol)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_URL_INVALID_PROTOCOL);\n }\n } catch {\n return t(I18nKey.SETTINGS$MCP_ERROR_URL_INVALID);\n }\n return null;\n };\n\n const validateName = (name: string): string | null => {\n if (!name) return t(I18nKey.SETTINGS$MCP_ERROR_NAME_REQUIRED);\n if (!isValidMcpServerName(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_INVALID);\n }\n return null;\n };\n\n const validateNameUniqueness = (name: string): string | null => {\n if (!existingServers) return null;\n const shouldCheckUniqueness =\n mode === \"add\" || (mode === \"edit\" && server?.name !== name);\n if (!shouldCheckUniqueness) return null;\n\n const existingStdioNames = existingServers\n .filter((s) => s.type === \"stdio\")\n .map((s) => s.name)\n .filter(Boolean);\n if (existingStdioNames.includes(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_DUPLICATE);\n }\n return null;\n };\n\n const validateCommand = (command: string): string | null => {\n if (!command) return t(I18nKey.SETTINGS$MCP_ERROR_COMMAND_REQUIRED);\n if (command.includes(\" \")) {\n return t(I18nKey.SETTINGS$MCP_ERROR_COMMAND_NO_SPACES);\n }\n return null;\n };\n\n const validateUrlUniqueness = (url: string): string | null => {\n if (!existingServers) return null;\n const originalUrl = server?.url;\n const changed = mode === \"add\" || (mode === \"edit\" && originalUrl !== url);\n if (!changed) return null;\n // For URL-based servers (sse/shttp), ensure URL is unique across both types\n const exists = existingServers.some(\n (s) => (s.type === \"sse\" || s.type === \"shttp\") && s.url === url,\n );\n if (exists) return t(I18nKey.SETTINGS$MCP_ERROR_URL_DUPLICATE);\n return null;\n };\n\n const validateEnvFormat = (envString: string): string | null => {\n if (!envString.trim()) return null;\n const lines = envString.split(\"\\n\");\n for (let i = 0; i < lines.length; i += 1) {\n const trimmed = lines[i].trim();\n if (trimmed) {\n const eq = trimmed.indexOf(\"=\");\n if (eq === -1) return t(I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);\n const key = trimmed.substring(0, eq).trim();\n if (!key) return t(I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);\n }\n }\n return null;\n };\n\n const validateRemoteAuth = (formData: FormData): string | null => {\n if (authMode === \"header\") {\n const headerString = formData.get(\"headers\")?.toString() || \"\";\n if (!headerString.trim())\n return t(I18nKey.SETTINGS$MCP_ERROR_HEADER_REQUIRED);\n return validateEnvFormat(headerString);\n }\n if (authMode === \"oauth2\") {\n const clientId = formData.get(\"oauth_client_id\")?.toString().trim();\n const clientSecret = formData\n .get(\"oauth_client_secret\")\n ?.toString()\n .trim();\n if (clientSecret && !clientId) {\n return t(I18nKey.SETTINGS$MCP_ERROR_OAUTH_SECRET_REQUIRES_ID);\n }\n }\n return null;\n };\n\n const validateTimeout = (timeoutStr: string): string | null => {\n if (!timeoutStr.trim()) return null; // Optional field\n\n const timeout = parseInt(timeoutStr.trim(), 10);\n if (Number.isNaN(timeout)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_INVALID_NUMBER);\n }\n if (timeout <= 0) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_POSITIVE);\n }\n if (timeout > 3600) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_MAX_EXCEEDED);\n }\n return null;\n };\n\n const validateStdioServer = (formData: FormData): string | null => {\n const name = formData.get(\"name\")?.toString().trim() || \"\";\n const command = formData.get(\"command\")?.toString().trim() || \"\";\n const envString = formData.get(\"env\")?.toString() || \"\";\n\n const nameError = validateName(name);\n if (nameError) return nameError;\n\n const uniquenessError = validateNameUniqueness(name);\n if (uniquenessError) return uniquenessError;\n\n const commandError = validateCommand(command);\n if (commandError) return commandError;\n\n // Validate environment variable format\n const envError = validateEnvFormat(envString);\n if (envError) return envError;\n\n return null;\n };\n\n const validateForm = (formData: FormData): string | null => {\n if (serverType === \"sse\" || serverType === \"shttp\") {\n const url = formData.get(\"url\")?.toString().trim() || \"\";\n const urlError = validateUrl(url);\n if (urlError) return urlError;\n const urlDupError = validateUrlUniqueness(url);\n if (urlDupError) return urlDupError;\n\n // The name is optional, but when provided it becomes the mcp_config\n // key (and the reference used in mcp_server_refs), so hold it to the\n // same safe-identifier rule as stdio names.\n const name = formData.get(\"name\")?.toString().trim() || \"\";\n if (name && !isValidMcpServerName(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_INVALID);\n }\n\n // Validate timeout for SHTTP servers only\n if (serverType === \"shttp\") {\n const timeoutStr = formData.get(\"timeout\")?.toString() || \"\";\n const timeoutError = validateTimeout(timeoutStr);\n if (timeoutError) return timeoutError;\n }\n\n return validateRemoteAuth(formData);\n }\n\n if (serverType === \"stdio\") {\n return validateStdioServer(formData);\n }\n\n return null;\n };\n\n const parseEnvironmentVariables = (\n envString: string,\n ): Record<string, string> => {\n const env: Record<string, string> = {};\n const input = envString.trim();\n if (!input) return env;\n\n for (const line of input.split(\"\\n\")) {\n const trimmed = line.trim();\n const eq = trimmed.indexOf(\"=\");\n const key = eq >= 0 ? trimmed.substring(0, eq).trim() : \"\";\n if (trimmed && eq !== -1 && key) {\n env[key] = trimmed.substring(eq + 1).trim();\n }\n }\n return env;\n };\n\n const formatEnvironmentVariables = (\n env?: Record<string, string> | null,\n ): string => {\n if (!env) return \"\";\n return Object.entries(env)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"\\n\");\n };\n\n const editableAuthValue = (auth: MCPAuthCredential | undefined): string => {\n if (auth?.strategy === \"bearer\" || auth?.strategy === \"api_key\") {\n return auth.value ?? \"\";\n }\n return \"\";\n };\n\n const editableHeaderValue = (auth: MCPAuthCredential | undefined): string => {\n if (auth?.strategy !== \"header\") return \"\";\n return formatEnvironmentVariables(auth.headers);\n };\n\n const oauthAuthentication =\n server?.auth?.strategy === \"oauth2\"\n ? server.auth.authentication\n : undefined;\n const oauthState =\n server?.auth?.strategy === \"oauth2\" ? server.auth.state : undefined;\n\n const authFromFormData = (\n formData: FormData,\n ): MCPAuthCredential | undefined => {\n if (authMode === \"none\") return undefined;\n if (authMode === \"bearer\") {\n const value = formData.get(\"api_key\")?.toString().trim();\n if (!value) return undefined;\n if (server?.auth?.strategy === \"api_key\") {\n return { ...server.auth, value };\n }\n return { strategy: \"bearer\", value };\n }\n if (authMode === \"header\") {\n const headers = parseEnvironmentVariables(\n formData.get(\"headers\")?.toString() || \"\",\n );\n return { strategy: \"header\", headers };\n }\n\n const scopes = formData.get(\"oauth_scopes\")?.toString().trim();\n const clientId = formData.get(\"oauth_client_id\")?.toString().trim();\n const clientSecret = formData.get(\"oauth_client_secret\")?.toString().trim();\n const authentication: MCPAuthenticationConfig = {\n type: \"oauth\",\n ...(oauthClientAuthMethod !== \"auto\" && {\n client_auth_method: oauthClientAuthMethod,\n }),\n ...(scopes && { scopes }),\n ...(clientId && { client_id: clientId }),\n ...(clientSecret && { client_secret: clientSecret }),\n };\n return {\n strategy: \"oauth2\",\n authentication,\n ...(oauthState && { state: oauthState }),\n };\n };\n\n const buildConfig = (formData: FormData): MCPServerConfig => {\n const baseConfig = {\n id: server?.id || `${serverType}-${Date.now()}`,\n type: serverType,\n // The form has no enable/disable control (that lives on the card), so\n // carry the existing state forward — otherwise saving an edit to a\n // disabled server would silently switch it back on.\n ...(server?.enabled === false && { enabled: false }),\n };\n\n if (serverType === \"sse\" || serverType === \"shttp\") {\n const name = formData.get(\"name\")?.toString().trim();\n const url = formData.get(\"url\")?.toString().trim();\n const timeoutStr = formData.get(\"timeout\")?.toString().trim();\n const auth = authFromFormData(formData);\n\n const serverConfig: MCPServerConfig = {\n ...baseConfig,\n ...(name && { name }),\n url: url!,\n ...(auth && { auth }),\n };\n\n // Only add timeout for SHTTP servers\n if (serverType === \"shttp\" && timeoutStr) {\n const timeoutValue = parseInt(timeoutStr, 10);\n if (!Number.isNaN(timeoutValue)) {\n serverConfig.timeout = timeoutValue;\n }\n }\n\n return serverConfig;\n }\n\n // stdio\n const name = formData.get(\"name\")?.toString().trim();\n const command = formData.get(\"command\")?.toString().trim();\n const argsString = formData.get(\"args\")?.toString().trim();\n const envString = formData.get(\"env\")?.toString().trim();\n\n const args = argsString\n ? argsString\n .split(\"\\n\")\n .map((arg) => arg.trim())\n .filter(Boolean)\n : [];\n const env = parseEnvironmentVariables(envString || \"\");\n\n return {\n ...baseConfig,\n name: name!,\n command: command!,\n ...(args.length > 0 && { args }),\n ...(Object.keys(env).length > 0 && { env }),\n };\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n const formData = new FormData(event.currentTarget);\n const validationError = validateForm(formData);\n\n if (validationError) {\n setError(validationError);\n return;\n }\n\n onSubmit(buildConfig(formData));\n };\n\n const handleTestClick = () => {\n if (!onTest || !formRef.current) return;\n setError(null);\n const formData = new FormData(formRef.current);\n const validationError = validateForm(formData);\n if (validationError) {\n setError(validationError);\n return;\n }\n onTest(buildConfig(formData));\n };\n\n const formTestId =\n mode === \"add\" ? \"add-mcp-server-form\" : \"edit-mcp-server-form\";\n\n return (\n <form\n ref={formRef}\n data-testid={formTestId}\n onSubmit={handleSubmit}\n className=\"flex flex-col items-start gap-6\"\n noValidate\n >\n {mode === \"add\" && (\n <SettingsDropdownInput\n testId=\"server-type-dropdown\"\n name=\"server-type\"\n label={t(I18nKey.SETTINGS$MCP_SERVER_TYPE)}\n items={serverTypeOptions}\n selectedKey={serverType}\n onSelectionChange={(key) => setServerType(key as MCPServerType)}\n onInputChange={() => {}} // Prevent input changes\n isClearable={false}\n allowsCustomValue={false}\n required\n wrapperClassName=\"w-full min-w-0\"\n />\n )}\n\n {error && <p className=\"text-red-500 text-sm\">{error}</p>}\n\n {(serverType === \"sse\" || serverType === \"shttp\") && (\n <>\n <SettingsInput\n testId=\"server-name-input\"\n name=\"name\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_SERVER_NAME)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={server?.name || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"my_search_server\"\n pattern={MCP_SERVER_NAME_PATTERN.source}\n />\n\n <SettingsInput\n testId=\"url-input\"\n name=\"url\"\n type=\"url\"\n label={t(I18nKey.SETTINGS$MCP_URL)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.url || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"https://api.example.com\"\n />\n\n <SettingsDropdownInput\n testId=\"auth-mode-dropdown\"\n name=\"auth-mode\"\n label={t(I18nKey.SETTINGS$MCP_AUTHENTICATION)}\n items={authModeOptions}\n selectedKey={authMode}\n onSelectionChange={(key) => setAuthMode(key as RemoteAuthMode)}\n onInputChange={() => {}}\n isClearable={false}\n allowsCustomValue={false}\n wrapperClassName=\"w-full min-w-0\"\n />\n\n {authMode === \"bearer\" && (\n <SettingsInput\n testId=\"api-key-input\"\n name=\"api_key\"\n type=\"password\"\n label={t(I18nKey.SETTINGS$MCP_API_KEY)}\n className=\"w-full min-w-0\"\n required\n defaultValue={editableAuthValue(server?.auth)}\n placeholder={t(I18nKey.SETTINGS$MCP_API_KEY_PLACEHOLDER)}\n />\n )}\n\n {authMode === \"header\" && (\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <span className=\"text-sm\">{t(I18nKey.SETTINGS$MCP_HEADERS)}</span>\n <textarea\n data-testid=\"headers-input\"\n name=\"headers\"\n rows={4}\n defaultValue={editableHeaderValue(server?.auth)}\n placeholder={t(I18nKey.SETTINGS$MCP_HEADERS_PLACEHOLDER)}\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n </label>\n )}\n\n {authMode === \"oauth2\" && (\n <>\n <SettingsDropdownInput\n testId=\"oauth-client-auth-method-dropdown\"\n name=\"oauth_client_auth_method\"\n label={t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_AUTH)}\n items={oauthClientAuthMethodOptions}\n selectedKey={oauthClientAuthMethod}\n onSelectionChange={(key) =>\n setOAuthClientAuthMethod(key as OAuthClientAuthMethodOption)\n }\n onInputChange={() => {}}\n isClearable={false}\n allowsCustomValue={false}\n wrapperClassName=\"w-full min-w-0\"\n />\n <SettingsInput\n testId=\"oauth-client-id-input\"\n name=\"oauth_client_id\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_ID)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={oauthAuthentication?.client_id || \"\"}\n placeholder={t(\n I18nKey.SETTINGS$MCP_OAUTH_CLIENT_ID_PLACEHOLDER,\n )}\n />\n <SettingsInput\n testId=\"oauth-client-secret-input\"\n name=\"oauth_client_secret\"\n type=\"password\"\n label={t(I18nKey.SETTINGS$MCP_OAUTH_CLIENT_SECRET)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={oauthAuthentication?.client_secret || \"\"}\n placeholder={t(\n I18nKey.SETTINGS$MCP_OAUTH_CLIENT_SECRET_PLACEHOLDER,\n )}\n />\n <SettingsInput\n testId=\"oauth-scopes-input\"\n name=\"oauth_scopes\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_OAUTH_SCOPES)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={\n Array.isArray(oauthAuthentication?.scopes)\n ? oauthAuthentication.scopes.join(\" \")\n : oauthAuthentication?.scopes || \"\"\n }\n placeholder={t(I18nKey.SETTINGS$MCP_OAUTH_SCOPES_PLACEHOLDER)}\n />\n </>\n )}\n\n {serverType === \"shttp\" && (\n <SettingsInput\n testId=\"timeout-input\"\n name=\"timeout\"\n type=\"number\"\n label={t(I18nKey.SETTINGS$MCP_TIMEOUT_LABEL)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={server?.timeout?.toString() || \"\"}\n placeholder=\"60\"\n min={1}\n max={3600}\n />\n )}\n </>\n )}\n\n {serverType === \"stdio\" && (\n <>\n <SettingsInput\n testId=\"name-input\"\n name=\"name\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_NAME)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.name || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"my_mcp_server\"\n pattern={MCP_SERVER_NAME_PATTERN.source}\n />\n\n <SettingsInput\n testId=\"command-input\"\n name=\"command\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_COMMAND)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.command || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"npx\"\n />\n\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">\n {t(I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS)}\n </span>\n <OptionalTag />\n </div>\n <textarea\n data-testid=\"args-input\"\n name=\"args\"\n rows={3}\n defaultValue={server?.args?.join(\"\\n\") || \"\"}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"arg1&#10;arg2&#10;arg3\"\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n <p className=\"text-xs text-tertiary-alt\">\n {t(I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS_HELP)}\n </p>\n </label>\n\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">\n {t(I18nKey.SETTINGS$MCP_ENVIRONMENT_VARIABLES)}\n </span>\n <OptionalTag />\n </div>\n <textarea\n data-testid=\"env-input\"\n name=\"env\"\n rows={4}\n defaultValue={formatEnvironmentVariables(server?.env)}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"KEY1=value1&#10;KEY2=value2\"\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n </label>\n </>\n )}\n\n {testMessage && (\n <p\n data-testid=\"mcp-test-message\"\n className={\n testMessage.ok\n ? \"text-sm text-green-500 whitespace-pre-wrap\"\n : \"text-sm text-red-500 whitespace-pre-wrap\"\n }\n >\n {testMessage.text}\n </p>\n )}\n\n <div\n className={cn(\n \"flex w-full items-center gap-2\",\n onDelete ? \"justify-between\" : \"justify-end\",\n )}\n >\n {onDelete ? (\n <BrandButton\n testId=\"mcp-custom-editor-delete\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onDelete}\n isDisabled={isActionDisabled}\n startContent={\n <Trash2 aria-hidden className=\"size-4\" strokeWidth={2} />\n }\n >\n {t(I18nKey.BUTTON$DELETE)}\n </BrandButton>\n ) : null}\n <div className=\"flex items-center gap-2\">\n <BrandButton\n testId=\"cancel-button\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onCancel}\n isDisabled={isActionDisabled}\n >\n {t(I18nKey.BUTTON$CANCEL)}\n </BrandButton>\n {onTest && (\n <BrandButton\n testId=\"mcp-test-connection\"\n type=\"button\"\n variant=\"secondary\"\n onClick={handleTestClick}\n isDisabled={isActionDisabled || isTestPending}\n >\n {isTestPending\n ? t(I18nKey.MCP$VERIFYING)\n : t(I18nKey.MCP$TEST_BUTTON)}\n </BrandButton>\n )}\n <BrandButton\n testId=\"submit-button\"\n type=\"submit\"\n variant=\"primary\"\n isDisabled={isActionDisabled || isTestPending}\n >\n {mode === \"add\" && t(I18nKey.SETTINGS$MCP_ADD_SERVER)}\n {mode === \"edit\" && t(I18nKey.SETTINGS$MCP_SAVE_SERVER)}\n </BrandButton>\n </div>\n </div>\n </form>\n );\n}\n"],"mappings":"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"}
@@ -158,7 +158,8 @@ function h({ mode: h, server: g, existingServers: _, onSubmit: v, onCancel: y, o
158
158
  }, $ = (e) => {
159
159
  let t = {
160
160
  id: g?.id || `${E}-${Date.now()}`,
161
- type: E
161
+ type: E,
162
+ ...g?.enabled === !1 && { enabled: !1 }
162
163
  };
163
164
  if (E === "sse" || E === "shttp") {
164
165
  let n = e.get("name")?.toString().trim(), r = e.get("url")?.toString().trim(), i = e.get("timeout")?.toString().trim(), a = te(e), o = {