@openhands/agent-canvas 1.1.0 → 1.2.1
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.
- package/README.md +1 -1
- package/README.windows.md +2 -2
- package/build/assets/Trans-De9RwQhA.js +1 -0
- package/build/assets/__vite-browser-external-4xJsU2-u.js +1 -0
- package/build/assets/{acp-providers-B_ZxlEbx.js → acp-providers-D_D8VUpP.js} +1 -1
- package/build/assets/active-backend-context-u2tdYRgH.js +1 -0
- package/build/assets/add-backend-modal-DIEyAkA4.js +1 -0
- package/build/assets/agent-profiles-settings-BovdV4N8.js +1 -0
- package/build/assets/{agent-server-client-options-CxnCYyIW.js → agent-server-client-options-DVLRd9sw.js} +1 -1
- package/build/assets/agent-server-conversation-service.api-BP73yONA.js +5 -0
- package/build/assets/agent-settings-FGL3Yvkp.js +1 -0
- package/build/assets/agent-settings-Ofbh6UTD.js +2 -0
- package/build/assets/alert-banner-BW0wRYw6.js +1 -0
- package/build/assets/api-key-entry-screen-CZIdRmUJ.js +1 -0
- package/build/assets/app-settings-BHJ9nKti.js +1 -0
- package/build/assets/automation-detail-DwYGzLkp.js +2 -0
- package/build/assets/automations-list-CuAfJmMW.js +1 -0
- package/build/assets/back-nav-button-BYmxFxGt.js +1 -0
- package/build/assets/backend-form-modal-BiaOB2C4.js +1 -0
- package/build/assets/backend-synced-settings-badge-Bs3FSXsS.js +1 -0
- package/build/assets/base-modal-CC5Pp8CF.js +1 -0
- package/build/assets/bot-D7eUAuSB.js +1 -0
- package/build/assets/brand-button-DKPMEKcW.js +1 -0
- package/build/assets/{browser-CCwPzPsD.js → browser-B39N74jU.js} +2 -2
- package/build/assets/browser-store-BI6uklCG.js +1 -0
- package/build/assets/browser-tab-aiDg7aEn.js +1 -0
- package/build/assets/chat-send-button-DxuZIoW8.js +1 -0
- package/build/assets/check-Bvi71siz.js +1 -0
- package/build/assets/checkmark-h7udgXMM.js +1 -0
- package/build/assets/{chevron-down-BxZEAIv4.js → chevron-down-CI8A6tet.js} +1 -1
- package/build/assets/circle-plus-check-toggle-T3eAIuPQ.js +1 -0
- package/build/assets/close-p3Op5lxI.js +1 -0
- package/build/assets/code-tag-DYlAhEQY.js +1 -0
- package/build/assets/{color-themes-CTNRQd1a.js → color-themes-DPBzNtVg.js} +4 -4
- package/build/assets/combobox-caret-CLGvOs32.js +1 -0
- package/build/assets/command-menu-DKrLCRla.js +1 -0
- package/build/assets/{command-store-C-57Heey.js → command-store-D8J5LMW1.js} +1 -1
- package/build/assets/condenser-settings-D_5vY4m3.js +1 -0
- package/build/assets/confirmation-modal-BK1F0A68.js +1 -0
- package/build/assets/context-menu-list-item-DBFzplWW.js +1 -0
- package/build/assets/conversation-DnVC6vRV.js +1 -0
- package/build/assets/conversation-local-storage-F6zVMM--.js +1 -0
- package/build/assets/conversation-panel-ZEz-z3az.js +1 -0
- package/build/assets/conversation-service.api-CqZcHr1c.js +1 -0
- package/build/assets/conversation-state-store-B2Bp32XI.js +1 -0
- package/build/assets/conversation-store-LptbOvKa.js +1 -0
- package/build/assets/conversation-tab-empty-state-m8IUkfMj.js +1 -0
- package/build/assets/conversation-xkBS3AHC.js +19 -0
- package/build/assets/copy-3JCw_XFB.js +1 -0
- package/build/assets/copy-BLmGeJcd.js +1 -0
- package/build/assets/copy-to-clipboard-button-Aj9wFmt2.js +1 -0
- package/build/assets/createLucideIcon-CVAsW2Yo.js +1 -0
- package/build/assets/declaration-B9kpCaYl.js +1 -0
- package/build/assets/device-verify-B5YCrvSu.js +1 -0
- package/build/assets/dist-CodhvuAP.js +1 -0
- package/build/assets/dropdown-classes-CgQ45JmQ.js +1 -0
- package/build/assets/edit-automation-modal-B6U96gVV.js +1 -0
- package/build/assets/ellipsis-button-1BV9Sga8.js +1 -0
- package/build/assets/entry.client-Dy--3GeA.js +2 -0
- package/build/assets/enum-filter-dropdown-DCITiYVi.js +1 -0
- package/build/assets/environment-switch-overlay-DUnKILNH.js +1 -0
- package/build/assets/extensions-hub-CksKNpP9.js +1 -0
- package/build/assets/{extensions-navigation-DfLHdTUC.js → extensions-navigation-Di9rJ-b5.js} +1 -1
- package/build/assets/{external-link-D8njjDTk.js → external-link-D2zJjE9G.js} +1 -1
- package/build/assets/files-tab-61Vaihc6.js +1 -0
- package/build/assets/files-tab-store-DJsPxYdg.js +1 -0
- package/build/assets/folder-mMWFvaw0.js +1 -0
- package/build/assets/form-control-classes-9rkU4usZ.js +1 -0
- package/build/assets/get-language-from-path-CPNnuVhI.js +1 -0
- package/build/assets/git-provider-icon-aQRcUVI-.js +1 -0
- package/build/assets/home-5gOtUe-n.js +1 -0
- package/build/assets/iconBase-DaTRRUjy.js +1 -0
- package/build/assets/index-redirect-CUUJiNki.js +1 -0
- package/build/assets/install-server-modal-BRab9inF.js +1 -0
- package/build/assets/launch-1TJRKkkX.js +1 -0
- package/build/assets/lesson-plan-BtrZUCuj.js +4 -0
- package/build/assets/link-external-DfKQroKX.js +1 -0
- package/build/assets/{list-todo-B_Ts2JmZ.js → list-todo-BfH6yYUK.js} +1 -1
- package/build/assets/llm-not-configured-banner-BrU5uHto.js +27 -0
- package/build/assets/llm-settings-BpdU51Jo.js +1 -0
- package/build/assets/llm-settings-DsInf6yD.js +1 -0
- package/build/assets/{llm-subscription-service-BX_AtNlO.js → llm-subscription-service-CKyaV24y.js} +1 -1
- package/build/assets/loader-circle-BEykUKYG.js +1 -0
- package/build/assets/loading-spinner-DHAIPZkP.js +1 -0
- package/build/assets/manage-backends-modal-BREySP-J.js +1 -0
- package/build/assets/manifest-a5bb7568.js +1 -0
- package/build/assets/{markdown-renderer-DWy7Np7u.js → markdown-renderer-D8mayGjI.js} +1 -1
- package/build/assets/mcp-XXf8k6mb.js +9 -0
- package/build/assets/messages-D2oZb47Z.js +40 -0
- package/build/assets/middleware-DYHYNAnP.js +6 -0
- package/build/assets/modal-backdrop-zVwfOJZr.js +1 -0
- package/build/assets/modal-body-Dcu5McCa.js +1 -0
- package/build/assets/{modal-classes-C4kS6ib_.js → modal-classes-DPqxSyuP.js} +1 -1
- package/build/assets/modal-close-button-CTCX4nCH.js +1 -0
- package/build/assets/model-selector-VDHBytb6.js +1 -0
- package/build/assets/{mouse-pointer-click-CXAx4FyM.js → mouse-pointer-click-PdEQPL6v.js} +1 -1
- package/build/assets/navigation-context-DPs2G0X8.js +1 -0
- package/build/assets/navigation-link-D8hfwvxI.js +1 -0
- package/build/assets/onboarding-D32kiGME.js +1 -0
- package/build/assets/onboarding-modal-C084vkv7.js +1 -0
- package/build/assets/openhands-logo-bcNw5bkY.js +1 -0
- package/build/assets/option-service.api-Cl5VLGyw.js +1 -0
- package/build/assets/organization-service.api-CnynNoT-.js +1 -0
- package/build/assets/path-utils-BeOmjIcE.js +1 -0
- package/build/assets/{pencil-CsL0ns9y.js → pencil-Dj2XjKmI.js} +1 -1
- package/build/assets/plan-components-j9X4AxYM.js +1 -0
- package/build/assets/planner-tab-AZMjJx31.js +1 -0
- package/build/assets/plugins-management-service-BAp70KN7.js +1 -0
- package/build/assets/profiles-service.api-CeYEmSM3.js +1 -0
- package/build/assets/providers-vX9jk9Vy.js +1 -0
- package/build/assets/{proxy-TeteRRW5.js → proxy-CHmFkV16.js} +1 -1
- package/build/assets/react-DPDgL6du.js +1 -0
- package/build/assets/recommended-automations-launcher-Bk8tQ-Cn.js +58 -0
- package/build/assets/{refresh-cw-GkGYXsU-.js → refresh-cw-DM82EIyx.js} +1 -1
- package/build/assets/root-CxWZUXTQ.css +1 -0
- package/build/assets/root-layout-CoWw4kpz.js +2 -0
- package/build/assets/root-tuEPDx-i.js +2 -0
- package/build/assets/runtime-waiting-state-DkzLgvMn.js +1 -0
- package/build/assets/schema-field-nvq_Juo2.js +1 -0
- package/build/assets/sdk-section-page-CgT70FaZ.js +1 -0
- package/build/assets/sdk-settings-schema-BjBkMHzZ.js +1 -0
- package/build/assets/search-4DHskuhE.js +1 -0
- package/build/assets/search-BsjCEFNf.js +1 -0
- package/build/assets/secrets-service-CZYjNxFw.js +1 -0
- package/build/assets/secrets-settings-BCxk9p9s.js +1 -0
- package/build/assets/segmented-toggle-Cen5AMUc.js +1 -0
- package/build/assets/settings-CedTdtb5.js +1 -0
- package/build/assets/settings-dropdown-input-xzoZwgUe.js +1 -0
- package/build/assets/settings-gear-MXCyZW0x.js +1 -0
- package/build/assets/settings-index-Cct3PJSP.js +1 -0
- package/build/assets/settings-input-DYs7t3oK.js +1 -0
- package/build/assets/settings-list-classes-DvQr5jVS.js +1 -0
- package/build/assets/{settings-CN_HaPjH.js → settings-mQUckT0g.js} +1 -1
- package/build/assets/settings-modal-DwLybV_O.js +1 -0
- package/build/assets/settings-section-header-context-COMOIaxV.js +1 -0
- package/build/assets/settings-service.api-DldkFI1x.js +1 -0
- package/build/assets/settings-switch-C2N2xqEb.js +1 -0
- package/build/assets/{settings-utils-9-_6iVIn.js → settings-utils-BMdG65By.js} +1 -1
- package/build/assets/shared-conversation-DnDwfLgg.js +1 -0
- package/build/assets/sidebar-layout-BtpUSN3j.js +1 -0
- package/build/assets/sidebar-mobile-menu-toggle-B8k3qu84.js +1 -0
- package/build/assets/sidebar-nav-link-CIB3NBRW.js +1 -0
- package/build/assets/sidebar-store-CZuE8AH5.js +1 -0
- package/build/assets/skill-card-pill-row-D2bUe2kB.js +1 -0
- package/build/assets/skills-9cDZONKh.js +1 -0
- package/build/assets/skills-plugins-B68ay6Pu.js +1 -0
- package/build/assets/skills-settings-A6sUy0T7.js +2 -0
- package/build/assets/{square-chevron-right-Cfi-SUY0.js → square-chevron-right-Czw3FFWc.js} +1 -1
- package/build/assets/styled-tooltip-DsKsFjuq.js +1 -0
- package/build/assets/suspense-X5dBsJzn.js +1 -0
- package/build/assets/switch-skeleton-DqQwalyu.js +1 -0
- package/build/assets/task-list-tab-BAThr9Ex.js +1 -0
- package/build/assets/{terminal-HakoMrQX.js → terminal-BmT0_gIH.js} +2 -2
- package/build/assets/terminal-BuLtIrb9.js +1 -0
- package/build/assets/toggle-switch-DBlOOzBr.js +1 -0
- package/build/assets/{trash-2-Bq4hqiRH.js → trash-2-Be_7y3Mn.js} +1 -1
- package/build/assets/typography-YGPBGzOG.js +1 -0
- package/build/assets/u-check-circle-BqoIxNz_.js +1 -0
- package/build/assets/u-check-circle-half-LiwZkuFe.js +1 -0
- package/build/assets/u-edit-DJ90xc8Z.js +1 -0
- package/build/assets/use-acp-credential-form-Bs6s0DTU.js +1 -0
- package/build/assets/use-activate-agent-profile-CKtTToSx.js +1 -0
- package/build/assets/use-active-agent-profile-CWLPpOtK.js +1 -0
- package/build/assets/use-active-conversation-DI5S5M1w.js +1 -0
- package/build/assets/use-agent-profiles-DPcaYLpm.js +1 -0
- package/build/assets/use-agent-state-Buh3bQDh.js +1 -0
- package/build/assets/use-backends-health-CxkvJy2N.js +1 -0
- package/build/assets/use-breakpoint-B-O0lQ84.js +1 -0
- package/build/assets/use-can-manage-org-profiles-DeX2Mfje.js +1 -0
- package/build/assets/use-click-outside-element-Bf4Omzot.js +1 -0
- package/build/assets/use-cloud-current-user-id-D_PQGfmT.js +1 -0
- package/build/assets/use-config-ur0RbjCP.js +1 -0
- package/build/assets/use-create-conversation-D9OWYcte.js +1 -0
- package/build/assets/use-create-secret-CVFSlhlR.js +1 -0
- package/build/assets/use-event-store-YSOxy9FC.js +4 -0
- package/build/assets/use-handle-plan-click-Dug8egQl.js +1 -0
- package/build/assets/use-is-authed-_dhQ2Xuj.js +1 -0
- package/build/assets/use-launch-skill-in-chat-BnoDgvAy.js +1 -0
- package/build/assets/use-llm-profiles-DjackuP1.js +1 -0
- package/build/assets/use-onboarding-completion-C_Swglzp.js +1 -0
- package/build/assets/use-plugins-marketplace-BGb-KgfD.js +1 -0
- package/build/assets/use-runtime-is-ready-Diiq65Q-.js +1 -0
- package/build/assets/use-save-agent-profile-aKKLqDJM.js +1 -0
- package/build/assets/{use-save-settings-DErJDIDL.js → use-save-settings-CChDyjOB.js} +1 -1
- package/build/assets/use-settings-dX4fKUPF.js +1 -0
- package/build/assets/use-settings-nav-items-D6pHnvxg.js +16 -0
- package/build/assets/use-skills-Dqo-pDDx.js +1 -0
- package/build/assets/use-task-list-CmWGElgb.js +1 -0
- package/build/assets/use-tracking-GtXCHmTv.js +1 -0
- package/build/assets/use-user-conversation-6uOXFP95.js +1 -0
- package/build/assets/useMutation-DCE9RcgK.js +1 -0
- package/build/assets/useMutationState-BUab8Kxr.js +1 -0
- package/build/assets/useQueries-CRzaAqzH.js +1 -0
- package/build/assets/useQuery-CpjHYtZc.js +1 -0
- package/build/assets/useTranslation-Cgy4JA_g.js +1 -0
- package/build/assets/utils-CE0lDWtb.js +1 -0
- package/build/assets/vendor-styling-CI0PQ3ab.js +22 -0
- package/build/assets/{vendor~browser-BQU4C3CQ.js → vendor~browser-Cvg7jXCP.js} +1 -1
- package/build/assets/{vendor~browser-tab-Cim6xN2k.js → vendor~browser-tab-Di0kh5Zw.js} +1 -1
- package/build/assets/vendor~conversation-panel~conversation~alert-banner-DHDkknt5.js +1 -0
- package/build/assets/vendor~entry.client-9tWQ_Ugw.js +1 -0
- package/build/assets/{vendor~entry.client-lAMyAlBD.js → vendor~entry.client-D6BtSOtn.js} +1 -1
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~d1e18dtv-5Q6lQJdE.js +177 -0
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~i3v2mlbw-BrJQ3XZH.js +1 -0
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~ncdxw0bh-ClHnt5lR.js +10 -0
- package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~t35o0b0f-Bss49YXv.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~k6tszsdc-Bb-xMtbv.js} +1 -1
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~nn5zty47-Zl0G1QCy.js +1 -0
- package/build/assets/{vendor~entry.client~root~root-layout~index-redirect~home~conversation-panel~conversation~la~fpbtwbmk-DDSPtjxR.js → vendor~entry.client~root~root-layout~index-redirect~home~conversation-panel~conversation~la~byh8a1g4-XNPdpuO8.js} +1 -1
- package/build/assets/{vendor~files-tab-BvQLon-P.js → vendor~files-tab-B02k3xvx.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation-DBPRU26Z.js → vendor~home~conversation-panel~conversation-CYMF9JYB.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DnEBAp2W.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-9UMeuPV6.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CzI-A-Gz.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BD0GaRGa.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-ByET2Quf.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CqXiHwjU.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DCYBrned.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D7EUmQ8Y.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DnctfFZL.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DTzw2x50.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-pSG7lnvH.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-d8aETPbZ.js} +1 -1
- package/build/assets/{vendor~launch-DqoOsAhA.js → vendor~launch-CHXA9cJu.js} +1 -1
- package/build/assets/vendor~root-layout~conversation-panel~conversation-CpiTHpHl.js +1 -0
- package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-BJl81v7J.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-_TdZcNMD.js} +1 -1
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation-Cn2jwSga.js +1 -0
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~enjl5xdm-mMKDm94D.js +48 -0
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~skills-settings~automations-~ki5qnp0d-DRld6s9c.js → vendor~root-layout~home~conversation-panel~conversation~launch~skills-settings~automations-~ki5qnp0d-rV6d1Iv_.js} +502 -43
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-9d2kA26V.js → vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-CZM4hwUT.js} +1 -1
- package/build/assets/vendor~root-layout~home~mcp~automations-list~onboarding-modal-CXyYYvYh.js +1 -0
- package/build/assets/verification-settings-D_zsNB_c.js +1 -0
- package/build/assets/x-Cb0WAtak.js +1 -0
- package/build/assets/x-mark-Batp6gXa.js +1 -0
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +138 -1
- package/build/locales/ca/openhands.json +138 -1
- package/build/locales/de/openhands.json +138 -1
- package/build/locales/en/openhands.json +138 -1
- package/build/locales/es/openhands.json +138 -1
- package/build/locales/fr/openhands.json +138 -1
- package/build/locales/it/openhands.json +138 -1
- package/build/locales/ja/openhands.json +138 -1
- package/build/locales/ko-KR/openhands.json +138 -1
- package/build/locales/no/openhands.json +138 -1
- package/build/locales/pt/openhands.json +138 -1
- package/build/locales/tr/openhands.json +138 -1
- package/build/locales/uk/openhands.json +138 -1
- package/build/locales/zh-CN/openhands.json +138 -1
- package/build/locales/zh-TW/openhands.json +138 -1
- package/config/defaults.json +7 -9
- package/dist/_virtual/__vite-browser-external.cjs +2 -0
- package/dist/_virtual/__vite-browser-external.cjs.map +1 -0
- package/dist/_virtual/__vite-browser-external.js +9 -0
- package/dist/_virtual/__vite-browser-external.js.map +1 -0
- package/dist/api/agent-profiles-service/agent-profiles-service.api.cjs +2 -0
- package/dist/api/agent-profiles-service/agent-profiles-service.api.cjs.map +1 -0
- package/dist/api/agent-profiles-service/agent-profiles-service.api.d.ts +22 -0
- package/dist/api/agent-profiles-service/agent-profiles-service.api.js +35 -0
- package/dist/api/agent-profiles-service/agent-profiles-service.api.js.map +1 -0
- package/dist/api/agent-server-adapter.cjs +2 -2
- package/dist/api/agent-server-adapter.cjs.map +1 -1
- package/dist/api/agent-server-adapter.d.ts +11 -1
- package/dist/api/agent-server-adapter.js +60 -60
- package/dist/api/agent-server-adapter.js.map +1 -1
- package/dist/api/agent-server-compatibility.cjs +1 -1
- package/dist/api/agent-server-compatibility.cjs.map +1 -1
- package/dist/api/agent-server-compatibility.js +1 -0
- package/dist/api/agent-server-compatibility.js.map +1 -1
- package/dist/api/agent-server-home.cjs +1 -1
- package/dist/api/agent-server-home.cjs.map +1 -1
- package/dist/api/agent-server-home.js +1 -0
- package/dist/api/agent-server-home.js.map +1 -1
- package/dist/api/cloud/agent-profiles-service.api.cjs +2 -0
- package/dist/api/cloud/agent-profiles-service.api.cjs.map +1 -0
- package/dist/api/cloud/agent-profiles-service.api.d.ts +7 -0
- package/dist/api/cloud/agent-profiles-service.api.js +58 -0
- package/dist/api/cloud/agent-profiles-service.api.js.map +1 -0
- package/dist/api/cloud/organization-service.api.cjs +1 -1
- package/dist/api/cloud/organization-service.api.cjs.map +1 -1
- package/dist/api/cloud/organization-service.api.d.ts +8 -0
- package/dist/api/cloud/organization-service.api.js +3 -1
- package/dist/api/cloud/organization-service.api.js.map +1 -1
- package/dist/api/cloud/profiles-service.api.cjs +2 -0
- package/dist/api/cloud/profiles-service.api.cjs.map +1 -0
- package/dist/api/cloud/profiles-service.api.d.ts +7 -0
- package/dist/api/cloud/profiles-service.api.js +75 -0
- package/dist/api/cloud/profiles-service.api.js.map +1 -0
- package/dist/api/cloud/settings-service.api.cjs +1 -1
- package/dist/api/cloud/settings-service.api.cjs.map +1 -1
- package/dist/api/cloud/settings-service.api.js +1 -1
- package/dist/api/cloud/settings-service.api.js.map +1 -1
- package/dist/api/config-service/config-service.api.cjs +1 -1
- package/dist/api/config-service/config-service.api.cjs.map +1 -1
- package/dist/api/config-service/config-service.api.js +1 -0
- package/dist/api/config-service/config-service.api.js.map +1 -1
- package/dist/api/conversation-metadata-store.cjs.map +1 -1
- package/dist/api/conversation-metadata-store.d.ts +11 -0
- package/dist/api/conversation-metadata-store.js.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +20 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.js +134 -105
- package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.types.d.ts +2 -0
- package/dist/api/conversation-service/conversation-service.api.cjs +1 -1
- package/dist/api/conversation-service/conversation-service.api.cjs.map +1 -1
- package/dist/api/conversation-service/conversation-service.api.d.ts +1 -0
- package/dist/api/conversation-service/conversation-service.api.js +4 -0
- package/dist/api/conversation-service/conversation-service.api.js.map +1 -1
- package/dist/api/device-flow-client.cjs +1 -1
- package/dist/api/device-flow-client.cjs.map +1 -1
- package/dist/api/device-flow-client.js +33 -25
- package/dist/api/device-flow-client.js.map +1 -1
- package/dist/api/event-service/event-service.api.cjs +1 -1
- package/dist/api/event-service/event-service.api.cjs.map +1 -1
- package/dist/api/event-service/event-service.api.js +1 -0
- package/dist/api/event-service/event-service.api.js.map +1 -1
- package/dist/api/mcp-service/mcp-redacted-credentials.cjs +1 -1
- package/dist/api/mcp-service/mcp-redacted-credentials.cjs.map +1 -1
- package/dist/api/mcp-service/mcp-redacted-credentials.d.ts +3 -3
- package/dist/api/mcp-service/mcp-redacted-credentials.js +29 -30
- package/dist/api/mcp-service/mcp-redacted-credentials.js.map +1 -1
- package/dist/api/mcp-service/mcp-service.api.cjs +1 -1
- package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -1
- package/dist/api/mcp-service/mcp-service.api.d.ts +8 -1
- package/dist/api/mcp-service/mcp-service.api.js +129 -23
- package/dist/api/mcp-service/mcp-service.api.js.map +1 -1
- package/dist/api/option-service/option-service.api.cjs +1 -1
- package/dist/api/option-service/option-service.api.cjs.map +1 -1
- package/dist/api/option-service/option-service.api.js +1 -0
- package/dist/api/option-service/option-service.api.js.map +1 -1
- package/dist/api/plugins-management-service.cjs +2 -0
- package/dist/api/plugins-management-service.cjs.map +1 -0
- package/dist/api/plugins-management-service.d.ts +50 -0
- package/dist/api/plugins-management-service.js +41 -0
- package/dist/api/plugins-management-service.js.map +1 -0
- package/dist/api/plugins-service.d.ts +49 -0
- package/dist/api/profiles-service/profiles-service.api.cjs +1 -1
- package/dist/api/profiles-service/profiles-service.api.cjs.map +1 -1
- package/dist/api/profiles-service/profiles-service.api.js +21 -14
- package/dist/api/profiles-service/profiles-service.api.js.map +1 -1
- package/dist/api/runtime-service/agent-server-runtime-service.cjs +1 -1
- package/dist/api/runtime-service/agent-server-runtime-service.cjs.map +1 -1
- package/dist/api/runtime-service/agent-server-runtime-service.js +1 -0
- package/dist/api/runtime-service/agent-server-runtime-service.js.map +1 -1
- package/dist/api/secrets-service.cjs +1 -1
- package/dist/api/secrets-service.cjs.map +1 -1
- package/dist/api/secrets-service.js +1 -0
- package/dist/api/secrets-service.js.map +1 -1
- package/dist/api/settings-service/settings-service.api.cjs +1 -1
- package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
- package/dist/api/settings-service/settings-service.api.js +92 -50
- package/dist/api/settings-service/settings-service.api.js.map +1 -1
- package/dist/api/skills-service.cjs +1 -1
- package/dist/api/skills-service.cjs.map +1 -1
- package/dist/api/skills-service.js +1 -0
- package/dist/api/skills-service.js.map +1 -1
- package/dist/api/workspaces-service/workspaces-service.api.cjs +1 -1
- package/dist/api/workspaces-service/workspaces-service.api.cjs.map +1 -1
- package/dist/api/workspaces-service/workspaces-service.api.js +1 -0
- package/dist/api/workspaces-service/workspaces-service.api.js.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +57 -38
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs +2 -1
- package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js +13 -9
- package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js +65 -26
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message.cjs +2 -2
- package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message.js +78 -76
- package/dist/components/conversation-events/chat/event-message.js.map +1 -1
- package/dist/components/features/analytics/telemetry-consent-banner.cjs +1 -1
- package/dist/components/features/analytics/telemetry-consent-banner.cjs.map +1 -1
- package/dist/components/features/analytics/telemetry-consent-banner.js +1 -0
- package/dist/components/features/analytics/telemetry-consent-banner.js.map +1 -1
- package/dist/components/features/automations/detail/activity-log-item.d.ts +3 -2
- package/dist/components/features/automations/detail/activity-log-section.d.ts +3 -2
- package/dist/components/features/automations/detail/debug-automation-button.d.ts +17 -0
- package/dist/components/features/automations/detail/run-logs-modal.d.ts +6 -1
- package/dist/components/features/backends/backend-form-modal.cjs +1 -1
- package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
- package/dist/components/features/backends/backend-form-modal.d.ts +6 -2
- package/dist/components/features/backends/backend-form-modal.js +198 -161
- package/dist/components/features/backends/backend-form-modal.js.map +1 -1
- package/dist/components/features/backends/backend-row.cjs +1 -1
- package/dist/components/features/backends/backend-row.cjs.map +1 -1
- package/dist/components/features/backends/backend-row.d.ts +2 -1
- package/dist/components/features/backends/backend-row.js +60 -54
- package/dist/components/features/backends/backend-row.js.map +1 -1
- package/dist/components/features/backends/backend-selector.cjs +1 -1
- package/dist/components/features/backends/backend-selector.cjs.map +1 -1
- package/dist/components/features/backends/backend-selector.js +4 -4
- package/dist/components/features/backends/backend-version.cjs +1 -1
- package/dist/components/features/backends/backend-version.cjs.map +1 -1
- package/dist/components/features/backends/backend-version.js +1 -0
- package/dist/components/features/backends/backend-version.js.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.js +72 -61
- package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
- package/dist/components/features/chat/change-agent-button.cjs +1 -1
- package/dist/components/features/chat/change-agent-button.js +9 -9
- package/dist/components/features/chat/chat-add-file-button.cjs +1 -1
- package/dist/components/features/chat/chat-add-file-button.cjs.map +1 -1
- package/dist/components/features/chat/chat-add-file-button.js +38 -34
- package/dist/components/features/chat/chat-add-file-button.js.map +1 -1
- package/dist/components/features/chat/chat-interface.cjs +2 -2
- package/dist/components/features/chat/chat-interface.cjs.map +1 -1
- package/dist/components/features/chat/chat-interface.js +136 -129
- package/dist/components/features/chat/chat-interface.js.map +1 -1
- package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
- package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
- package/dist/components/features/chat/components/chat-input-actions.js +100 -87
- package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs +2 -0
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs.map +1 -0
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.d.ts +15 -0
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.js +118 -0
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.js.map +1 -0
- package/dist/components/features/chat/components/chat-input-model.cjs +1 -1
- package/dist/components/features/chat/components/chat-input-model.js +17 -17
- package/dist/components/features/chat/components/chat-input-profile-picker.cjs +2 -0
- package/dist/components/features/chat/components/chat-input-profile-picker.cjs.map +1 -0
- package/dist/components/features/chat/components/chat-input-profile-picker.d.ts +9 -0
- package/dist/components/features/chat/components/chat-input-profile-picker.js +112 -0
- package/dist/components/features/chat/components/chat-input-profile-picker.js.map +1 -0
- package/dist/components/features/chat/components/resolve-picker-kind.cjs +2 -0
- package/dist/components/features/chat/components/resolve-picker-kind.cjs.map +1 -0
- package/dist/components/features/chat/components/resolve-picker-kind.d.ts +29 -0
- package/dist/components/features/chat/components/resolve-picker-kind.js +8 -0
- package/dist/components/features/chat/components/resolve-picker-kind.js.map +1 -0
- package/dist/components/features/chat/goal-status-banner.cjs +2 -0
- package/dist/components/features/chat/goal-status-banner.cjs.map +1 -0
- package/dist/components/features/chat/goal-status-banner.d.ts +11 -0
- package/dist/components/features/chat/goal-status-banner.js +12 -0
- package/dist/components/features/chat/goal-status-banner.js.map +1 -0
- package/dist/components/features/chat/goal-status-content.cjs +2 -0
- package/dist/components/features/chat/goal-status-content.cjs.map +1 -0
- package/dist/components/features/chat/goal-status-content.d.ts +21 -0
- package/dist/components/features/chat/goal-status-content.js +98 -0
- package/dist/components/features/chat/goal-status-content.js.map +1 -0
- package/dist/components/features/chat/interactive-chat-box.cjs +1 -1
- package/dist/components/features/chat/interactive-chat-box.cjs.map +1 -1
- package/dist/components/features/chat/interactive-chat-box.js +20 -19
- package/dist/components/features/chat/interactive-chat-box.js.map +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/code-block.cjs +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/code-block.cjs.map +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/code-block.d.ts +10 -3
- package/dist/components/features/chat/tool-visualizers/primitives/code-block.js +29 -16
- package/dist/components/features/chat/tool-visualizers/primitives/code-block.js.map +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/output-pane.cjs +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/output-pane.cjs.map +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/output-pane.d.ts +2 -2
- package/dist/components/features/chat/tool-visualizers/primitives/output-pane.js +16 -16
- package/dist/components/features/chat/tool-visualizers/primitives/output-pane.js.map +1 -1
- package/dist/components/features/chat/user-message-body.cjs +1 -1
- package/dist/components/features/chat/user-message-body.cjs.map +1 -1
- package/dist/components/features/chat/user-message-body.js +20 -20
- package/dist/components/features/chat/user-message-body.js.map +1 -1
- package/dist/components/features/command-menu/command-menu-items.d.ts +32 -0
- package/dist/components/features/command-menu/command-menu-trigger.cjs +2 -0
- package/dist/components/features/command-menu/command-menu-trigger.cjs.map +1 -0
- package/dist/components/features/command-menu/command-menu-trigger.d.ts +5 -0
- package/dist/components/features/command-menu/command-menu-trigger.js +53 -0
- package/dist/components/features/command-menu/command-menu-trigger.js.map +1 -0
- package/dist/components/features/command-menu/command-menu.d.ts +2 -0
- package/dist/components/features/command-menu/index.d.ts +2 -0
- package/dist/components/features/controls/tools-context-menu.cjs +1 -1
- package/dist/components/features/controls/tools-context-menu.cjs.map +1 -1
- package/dist/components/features/controls/tools-context-menu.d.ts +3 -1
- package/dist/components/features/controls/tools-context-menu.js +94 -77
- package/dist/components/features/controls/tools-context-menu.js.map +1 -1
- package/dist/components/features/conversation-panel/cloud-new-conversation-menu.cjs +1 -1
- package/dist/components/features/conversation-panel/cloud-new-conversation-menu.cjs.map +1 -1
- package/dist/components/features/conversation-panel/cloud-new-conversation-menu.js +8 -5
- package/dist/components/features/conversation-panel/cloud-new-conversation-menu.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.d.ts +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.js +2 -1
- package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
- package/dist/components/features/conversation-panel/local-new-conversation-menu.cjs +1 -1
- package/dist/components/features/conversation-panel/local-new-conversation-menu.cjs.map +1 -1
- package/dist/components/features/conversation-panel/local-new-conversation-menu.js +4 -1
- package/dist/components/features/conversation-panel/local-new-conversation-menu.js.map +1 -1
- package/dist/components/features/conversation-panel/plugins-modal.cjs +2 -0
- package/dist/components/features/conversation-panel/plugins-modal.cjs.map +1 -0
- package/dist/components/features/conversation-panel/plugins-modal.d.ts +12 -0
- package/dist/components/features/conversation-panel/plugins-modal.js +62 -0
- package/dist/components/features/conversation-panel/plugins-modal.js.map +1 -0
- package/dist/components/features/home/git-repo-dropdown/git-repo-dropdown.cjs +1 -1
- package/dist/components/features/home/git-repo-dropdown/git-repo-dropdown.cjs.map +1 -1
- package/dist/components/features/home/git-repo-dropdown/git-repo-dropdown.js +4 -4
- package/dist/components/features/mcp-logo-badge.cjs +1 -1
- package/dist/components/features/mcp-logo-badge.cjs.map +1 -1
- package/dist/components/features/mcp-logo-badge.js +17 -15
- package/dist/components/features/mcp-logo-badge.js.map +1 -1
- package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
- package/dist/components/features/mcp-page/custom-server-editor.cjs.map +1 -1
- package/dist/components/features/mcp-page/custom-server-editor.js +102 -59
- package/dist/components/features/mcp-page/custom-server-editor.js.map +1 -1
- package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
- package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
- package/dist/components/features/mcp-page/install-server-modal.js +284 -169
- package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
- package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
- package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
- package/dist/components/features/mcp-page/installed-server-card.js +16 -18
- package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
- package/dist/components/features/onboarding/onboarding-host.d.ts +3 -13
- package/dist/components/features/plugins/add-plugin-modal.d.ts +6 -0
- package/dist/components/features/plugins/build-plugins-view-model.d.ts +39 -0
- package/dist/components/features/plugins/plugin-card.d.ts +13 -0
- package/dist/components/features/plugins/plugin-detail-modal.d.ts +13 -0
- package/dist/components/features/plugins/plugin-picker-card.d.ts +10 -0
- package/dist/components/features/plugins/plugin-picker-modal.d.ts +9 -0
- package/dist/components/features/plugins/plugin-picker-trigger.d.ts +9 -0
- package/dist/components/features/plugins/plugin-picker.d.ts +18 -0
- package/dist/components/features/plugins/plugin-spec-identity.d.ts +28 -0
- package/dist/components/features/plugins/plugins-toolbar.d.ts +9 -0
- package/dist/components/features/settings/agent-profiles/agent-profile-actions-menu.d.ts +16 -0
- package/dist/components/features/settings/agent-profiles/agent-profile-row.d.ts +13 -0
- package/dist/components/features/settings/agent-profiles/agent-profiles-body.d.ts +15 -0
- package/dist/components/features/settings/agent-profiles/agent-profiles-local-view.d.ts +7 -0
- package/dist/components/features/settings/agent-profiles/agent-profiles-manager.d.ts +7 -0
- package/dist/components/features/settings/agent-profiles/delete-agent-profile-modal.d.ts +7 -0
- package/dist/components/features/settings/agent-profiles/index.d.ts +6 -0
- package/dist/components/features/settings/agent-profiles/merge-agent-profile-save-input.d.ts +18 -0
- package/dist/components/features/settings/llm-profiles/llm-profiles-manager.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/llm-profiles-manager.js +1 -0
- package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +1 -1
- package/dist/components/features/settings/llm-profiles/profile-row.d.ts +3 -1
- package/dist/components/features/settings/llm-profiles/profiles-body.d.ts +3 -1
- package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.cjs +1 -1
- package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.cjs.map +1 -1
- package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.js +3 -2
- package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.js.map +1 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +7 -7
- package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-form.js +279 -130
- package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-list-item.d.ts +1 -12
- package/dist/components/features/settings/mcp-settings/mcp-server-list.d.ts +1 -11
- package/dist/components/features/settings/settings-dropdown-input.cjs +1 -1
- package/dist/components/features/settings/settings-dropdown-input.js +6 -6
- package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.d.ts +1 -2
- package/dist/components/features/sidebar/sidebar-rail-body.js +81 -82
- package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
- package/dist/components/features/sidebar/sidebar.cjs +1 -1
- package/dist/components/features/sidebar/sidebar.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar.js +45 -46
- package/dist/components/features/sidebar/sidebar.js.map +1 -1
- package/dist/components/features/skills/extensions-navigation.cjs +1 -1
- package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
- package/dist/components/features/skills/extensions-navigation.js +1 -2
- package/dist/components/features/skills/extensions-navigation.js.map +1 -1
- package/dist/components/shared/modals/modal-backdrop.cjs +1 -1
- package/dist/components/shared/modals/modal-backdrop.cjs.map +1 -1
- package/dist/components/shared/modals/modal-backdrop.d.ts +5 -1
- package/dist/components/shared/modals/modal-backdrop.js +3 -3
- package/dist/components/shared/modals/modal-backdrop.js.map +1 -1
- package/dist/components/shared/modals/settings/model-selector.cjs +1 -1
- package/dist/components/shared/modals/settings/model-selector.js +16 -16
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +7 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/contexts/conversation-websocket-context.cjs +3 -3
- package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
- package/dist/contexts/conversation-websocket-context.js +200 -197
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/hooks/chat/use-goal-interceptor.cjs +2 -0
- package/dist/hooks/chat/use-goal-interceptor.cjs.map +1 -0
- package/dist/hooks/chat/use-goal-interceptor.d.ts +8 -0
- package/dist/hooks/chat/use-goal-interceptor.js +37 -0
- package/dist/hooks/chat/use-goal-interceptor.js.map +1 -0
- package/dist/hooks/chat/use-grip-resize.cjs +1 -1
- package/dist/hooks/chat/use-grip-resize.cjs.map +1 -1
- package/dist/hooks/chat/use-grip-resize.js +17 -16
- package/dist/hooks/chat/use-grip-resize.js.map +1 -1
- package/dist/hooks/chat/use-model-interceptor.cjs +1 -1
- package/dist/hooks/chat/use-model-interceptor.cjs.map +1 -1
- package/dist/hooks/chat/use-model-interceptor.d.ts +3 -3
- package/dist/hooks/chat/use-model-interceptor.js +8 -9
- package/dist/hooks/chat/use-model-interceptor.js.map +1 -1
- package/dist/hooks/chat/use-slash-command.cjs +1 -1
- package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
- package/dist/hooks/chat/use-slash-command.js +4 -4
- package/dist/hooks/chat/use-slash-command.js.map +1 -1
- package/dist/hooks/mutation/conversation-mutation-utils.cjs +1 -1
- package/dist/hooks/mutation/conversation-mutation-utils.cjs.map +1 -1
- package/dist/hooks/mutation/conversation-mutation-utils.d.ts +17 -0
- package/dist/hooks/mutation/conversation-mutation-utils.js +23 -4
- package/dist/hooks/mutation/conversation-mutation-utils.js.map +1 -1
- package/dist/hooks/mutation/use-activate-agent-profile.cjs +2 -0
- package/dist/hooks/mutation/use-activate-agent-profile.cjs.map +1 -0
- package/dist/hooks/mutation/use-activate-agent-profile.d.ts +23 -0
- package/dist/hooks/mutation/use-activate-agent-profile.js +34 -0
- package/dist/hooks/mutation/use-activate-agent-profile.js.map +1 -0
- package/dist/hooks/mutation/use-activate-llm-profile.cjs +1 -1
- package/dist/hooks/mutation/use-activate-llm-profile.js +1 -1
- package/dist/hooks/mutation/use-add-mcp-server.cjs +1 -1
- package/dist/hooks/mutation/use-add-mcp-server.cjs.map +1 -1
- package/dist/hooks/mutation/use-add-mcp-server.d.ts +1 -12
- package/dist/hooks/mutation/use-add-mcp-server.js +10 -34
- package/dist/hooks/mutation/use-add-mcp-server.js.map +1 -1
- package/dist/hooks/mutation/use-apply-onboarding-agent-profile.d.ts +20 -0
- package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
- package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
- package/dist/hooks/mutation/use-create-conversation.d.ts +2 -0
- package/dist/hooks/mutation/use-create-conversation.js +94 -25
- package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
- package/dist/hooks/mutation/use-delete-agent-profile.d.ts +1 -0
- package/dist/hooks/mutation/use-delete-llm-profile.cjs +1 -1
- package/dist/hooks/mutation/use-delete-llm-profile.js +1 -1
- package/dist/hooks/mutation/use-delete-mcp-server.cjs +1 -1
- package/dist/hooks/mutation/use-delete-mcp-server.js +4 -4
- package/dist/hooks/mutation/use-fork-conversation.cjs +2 -0
- package/dist/hooks/mutation/use-fork-conversation.cjs.map +1 -0
- package/dist/hooks/mutation/use-fork-conversation.d.ts +24 -0
- package/dist/hooks/mutation/use-fork-conversation.js +29 -0
- package/dist/hooks/mutation/use-fork-conversation.js.map +1 -0
- package/dist/hooks/mutation/use-install-plugin.d.ts +7 -0
- package/dist/hooks/mutation/use-new-conversation-command.cjs +1 -1
- package/dist/hooks/mutation/use-new-conversation-command.cjs.map +1 -1
- package/dist/hooks/mutation/use-new-conversation-command.d.ts +1 -0
- package/dist/hooks/mutation/use-new-conversation-command.js +20 -10
- package/dist/hooks/mutation/use-new-conversation-command.js.map +1 -1
- package/dist/hooks/mutation/use-rename-agent-profile.d.ts +6 -0
- package/dist/hooks/mutation/use-rename-llm-profile.cjs +1 -1
- package/dist/hooks/mutation/use-rename-llm-profile.js +1 -1
- package/dist/hooks/mutation/use-save-agent-profile.d.ts +5 -0
- package/dist/hooks/mutation/use-save-llm-profile.cjs +1 -1
- package/dist/hooks/mutation/use-save-llm-profile.js +1 -1
- package/dist/hooks/mutation/use-switch-acp-model.cjs.map +1 -1
- package/dist/hooks/mutation/use-switch-acp-model.js.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.d.ts +3 -4
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.js +10 -35
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.js.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.cjs +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.cjs.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.d.ts +20 -5
- package/dist/hooks/mutation/use-switch-llm-profile.js +38 -14
- package/dist/hooks/mutation/use-switch-llm-profile.js.map +1 -1
- package/dist/hooks/mutation/use-update-mcp-server.cjs +1 -1
- package/dist/hooks/mutation/use-update-mcp-server.cjs.map +1 -1
- package/dist/hooks/mutation/use-update-mcp-server.js +11 -37
- package/dist/hooks/mutation/use-update-mcp-server.js.map +1 -1
- package/dist/hooks/query/query-keys.cjs +1 -1
- package/dist/hooks/query/query-keys.cjs.map +1 -1
- package/dist/hooks/query/query-keys.d.ts +21 -0
- package/dist/hooks/query/query-keys.js +7 -3
- package/dist/hooks/query/query-keys.js.map +1 -1
- package/dist/hooks/query/use-active-conversation.cjs +1 -1
- package/dist/hooks/query/use-active-conversation.cjs.map +1 -1
- package/dist/hooks/query/use-active-conversation.js +17 -16
- package/dist/hooks/query/use-active-conversation.js.map +1 -1
- package/dist/hooks/query/use-agent-profiles.cjs +2 -0
- package/dist/hooks/query/use-agent-profiles.cjs.map +1 -0
- package/dist/hooks/query/use-agent-profiles.d.ts +13 -0
- package/dist/hooks/query/use-agent-profiles.js +24 -0
- package/dist/hooks/query/use-agent-profiles.js.map +1 -0
- package/dist/hooks/query/use-backends-health.cjs +1 -1
- package/dist/hooks/query/use-backends-health.cjs.map +1 -1
- package/dist/hooks/query/use-backends-health.js +18 -3
- package/dist/hooks/query/use-backends-health.js.map +1 -1
- package/dist/hooks/query/use-conversation-history.cjs +1 -1
- package/dist/hooks/query/use-conversation-history.cjs.map +1 -1
- package/dist/hooks/query/use-conversation-history.js +4 -2
- package/dist/hooks/query/use-conversation-history.js.map +1 -1
- package/dist/hooks/query/use-local-workspaces.cjs +1 -1
- package/dist/hooks/query/use-local-workspaces.cjs.map +1 -1
- package/dist/hooks/query/use-local-workspaces.js +1 -0
- package/dist/hooks/query/use-local-workspaces.js.map +1 -1
- package/dist/hooks/query/use-plugins-marketplace.d.ts +7 -0
- package/dist/hooks/query/use-resolved-workspaces.cjs +1 -1
- package/dist/hooks/query/use-resolved-workspaces.cjs.map +1 -1
- package/dist/hooks/query/use-resolved-workspaces.js +7 -6
- package/dist/hooks/query/use-resolved-workspaces.js.map +1 -1
- package/dist/hooks/query/use-search-subdirs.cjs +1 -1
- package/dist/hooks/query/use-search-subdirs.cjs.map +1 -1
- package/dist/hooks/query/use-search-subdirs.js +1 -0
- package/dist/hooks/query/use-search-subdirs.js.map +1 -1
- package/dist/hooks/query/use-settings.cjs +1 -1
- package/dist/hooks/query/use-settings.cjs.map +1 -1
- package/dist/hooks/query/use-settings.js +11 -11
- package/dist/hooks/query/use-settings.js.map +1 -1
- package/dist/hooks/query/use-verified-models.cjs +1 -1
- package/dist/hooks/query/use-verified-models.cjs.map +1 -1
- package/dist/hooks/query/use-verified-models.js +1 -0
- package/dist/hooks/query/use-verified-models.js.map +1 -1
- package/dist/hooks/use-acp-model-context.cjs +1 -1
- package/dist/hooks/use-acp-model-context.cjs.map +1 -1
- package/dist/hooks/use-acp-model-context.d.ts +1 -1
- package/dist/hooks/use-acp-model-context.js +9 -8
- package/dist/hooks/use-acp-model-context.js.map +1 -1
- package/dist/hooks/use-active-agent-profile.cjs +2 -0
- package/dist/hooks/use-active-agent-profile.cjs.map +1 -0
- package/dist/hooks/use-active-agent-profile.d.ts +20 -0
- package/dist/hooks/use-active-agent-profile.js +17 -0
- package/dist/hooks/use-active-agent-profile.js.map +1 -0
- package/dist/hooks/use-auto-resize.cjs +1 -1
- package/dist/hooks/use-auto-resize.cjs.map +1 -1
- package/dist/hooks/use-auto-resize.d.ts +2 -0
- package/dist/hooks/use-auto-resize.js +49 -45
- package/dist/hooks/use-auto-resize.js.map +1 -1
- package/dist/hooks/use-can-manage-org-profiles.cjs +1 -0
- package/dist/hooks/use-can-manage-org-profiles.d.ts +18 -0
- package/dist/hooks/use-can-manage-org-profiles.js +2 -0
- package/dist/hooks/use-chat-input-llm-profile-state.cjs +2 -0
- package/dist/hooks/use-chat-input-llm-profile-state.cjs.map +1 -0
- package/dist/hooks/use-chat-input-llm-profile-state.d.ts +23 -0
- package/dist/hooks/use-chat-input-llm-profile-state.js +30 -0
- package/dist/hooks/use-chat-input-llm-profile-state.js.map +1 -0
- package/dist/hooks/use-chat-input-model-state.cjs.map +1 -1
- package/dist/hooks/use-chat-input-model-state.d.ts +1 -1
- package/dist/hooks/use-chat-input-model-state.js.map +1 -1
- package/dist/hooks/use-chat-input-profile-state.cjs +2 -0
- package/dist/hooks/use-chat-input-profile-state.cjs.map +1 -0
- package/dist/hooks/use-chat-input-profile-state.d.ts +20 -0
- package/dist/hooks/use-chat-input-profile-state.js +22 -0
- package/dist/hooks/use-chat-input-profile-state.js.map +1 -0
- package/dist/hooks/use-conversation-name-context-menu.cjs +1 -1
- package/dist/hooks/use-conversation-name-context-menu.cjs.map +1 -1
- package/dist/hooks/use-conversation-name-context-menu.d.ts +4 -0
- package/dist/hooks/use-conversation-name-context-menu.js +44 -37
- package/dist/hooks/use-conversation-name-context-menu.js.map +1 -1
- package/dist/hooks/use-conversation-plugins.cjs +2 -0
- package/dist/hooks/use-conversation-plugins.cjs.map +1 -0
- package/dist/hooks/use-conversation-plugins.d.ts +9 -0
- package/dist/hooks/use-conversation-plugins.js +12 -0
- package/dist/hooks/use-conversation-plugins.js.map +1 -0
- package/dist/hooks/use-handle-plan-click.cjs +1 -1
- package/dist/hooks/use-handle-plan-click.cjs.map +1 -1
- package/dist/hooks/use-handle-plan-click.js +2 -1
- package/dist/hooks/use-handle-plan-click.js.map +1 -1
- package/dist/hooks/use-llm-configured.cjs +1 -1
- package/dist/hooks/use-llm-configured.cjs.map +1 -1
- package/dist/hooks/use-llm-configured.js +17 -16
- package/dist/hooks/use-llm-configured.js.map +1 -1
- package/dist/hooks/use-tracking.cjs +1 -1
- package/dist/hooks/use-tracking.cjs.map +1 -1
- package/dist/hooks/use-tracking.d.ts +51 -1
- package/dist/hooks/use-tracking.js +61 -2
- package/dist/hooks/use-tracking.js.map +1 -1
- package/dist/i18n/declaration.cjs +1 -1
- package/dist/i18n/declaration.cjs.map +1 -1
- package/dist/i18n/declaration.d.ts +138 -1
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +18 -3
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +2329 -0
- package/dist/i18n/translation.js.map +1 -1
- package/dist/icons/slack.cjs +2 -0
- package/dist/icons/slack.cjs.map +1 -0
- package/dist/icons/slack.js +19 -0
- package/dist/icons/slack.js.map +1 -0
- package/dist/icons/u-puzzle-piece.cjs +2 -0
- package/dist/icons/u-puzzle-piece.cjs.map +1 -0
- package/dist/icons/u-puzzle-piece.js +19 -0
- package/dist/icons/u-puzzle-piece.js.map +1 -0
- package/dist/icons/x-circle-solid.cjs +2 -0
- package/dist/icons/x-circle-solid.cjs.map +1 -0
- package/dist/icons/x-circle-solid.js +13 -0
- package/dist/icons/x-circle-solid.js.map +1 -0
- package/dist/locales/ar/openhands.json +138 -1
- package/dist/locales/ca/openhands.json +138 -1
- package/dist/locales/de/openhands.json +138 -1
- package/dist/locales/en/openhands.json +138 -1
- package/dist/locales/es/openhands.json +138 -1
- package/dist/locales/fr/openhands.json +138 -1
- package/dist/locales/it/openhands.json +138 -1
- package/dist/locales/ja/openhands.json +138 -1
- package/dist/locales/ko-KR/openhands.json +138 -1
- package/dist/locales/no/openhands.json +138 -1
- package/dist/locales/pt/openhands.json +138 -1
- package/dist/locales/tr/openhands.json +138 -1
- package/dist/locales/uk/openhands.json +138 -1
- package/dist/locales/zh-CN/openhands.json +138 -1
- package/dist/locales/zh-TW/openhands.json +138 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.js +0 -20
- package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/asana.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/asana.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/asana.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/asana.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.js +70 -3
- package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/bitbucket.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/bitbucket.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/bitbucket.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/bitbucket.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/box.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/box.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/box.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/box.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/canva.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/canva.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/canva.js +3 -7
- package/dist/node_modules/@openhands/extensions/integrations/catalog/canva.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/confluence.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/confluence.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/confluence.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/confluence.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +27 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/discord.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/discord.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/discord.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/discord.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.js +20 -26
- package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/github.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/github.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/github.js +0 -9
- package/dist/node_modules/@openhands/extensions/integrations/catalog/github.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gmail.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gmail.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gmail.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gmail.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-calendar.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-calendar.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-calendar.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-calendar.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-docs.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-docs.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-docs.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-docs.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-drive.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-drive.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-drive.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-drive.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-sheets.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-sheets.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-sheets.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/google-sheets.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/intercom.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/intercom.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/intercom.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/intercom.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/jira.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/jira.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/jira.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/jira.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.js +13 -13
- package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-outlook.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-outlook.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-outlook.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-outlook.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-teams.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-teams.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-teams.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-teams.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/miro.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/miro.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/miro.js +14 -10
- package/dist/node_modules/@openhands/extensions/integrations/catalog/miro.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/monday.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/monday.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/monday.js +13 -10
- package/dist/node_modules/@openhands/extensions/integrations/catalog/monday.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/netlify.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/netlify.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/netlify.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/netlify.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js +1 -8
- package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/okta.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/okta.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/okta.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/okta.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/onedrive.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/onedrive.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/onedrive.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/onedrive.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.js +20 -18
- package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/quickbooks.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/quickbooks.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/quickbooks.js +66 -21
- package/dist/node_modules/@openhands/extensions/integrations/catalog/quickbooks.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/salesforce.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/salesforce.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/salesforce.js +17 -11
- package/dist/node_modules/@openhands/extensions/integrations/catalog/salesforce.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.js +12 -17
- package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/sharepoint.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/sharepoint.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/sharepoint.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/sharepoint.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.js +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.js +14 -19
- package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.js +15 -20
- package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.cjs +2 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.js +33 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/trello.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/trello.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/trello.js +10 -8
- package/dist/node_modules/@openhands/extensions/integrations/catalog/trello.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/vercel.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/vercel.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/vercel.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/vercel.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/xero.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/xero.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/xero.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/xero.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/zoom.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/zoom.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/zoom.js +1 -6
- package/dist/node_modules/@openhands/extensions/integrations/catalog/zoom.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js +71 -89
- package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/index.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/index.js +4 -4
- package/dist/node_modules/@openhands/extensions/integrations/index.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/skills/index.cjs +502 -43
- package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/skills/index.js +58 -33
- package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-profiles-client.cjs +2 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-profiles-client.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-profiles-client.js +40 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-profiles-client.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js +4 -4
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.js +3 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js +3 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.cjs +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.js +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/http-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/http-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/http-client.js +84 -27
- package/dist/node_modules/@openhands/typescript-client/dist/client/http-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.js +9 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.cjs +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.js +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/plugins-client.cjs +2 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/plugins-client.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/plugins-client.js +42 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/plugins-client.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.cjs +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.js +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/skills-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/skills-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/skills-client.js +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/skills-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.cjs +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.js +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.cjs +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.js +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/clients.cjs +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/clients.js +20 -0
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/conversation-manager.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/conversation-manager.js +18 -0
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/conversation.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/conversation.js +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-conversation.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-conversation.js +2 -0
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.js +15 -17
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/index.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/index.js +3 -0
- package/dist/node_modules/@openhands/typescript-client/dist/workspace/workspace.cjs +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/workspace/workspace.js +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +7 -4
- package/dist/package.js.map +1 -1
- package/dist/routes/agent-settings.d.ts +106 -0
- package/dist/routes/files-tab.cjs +1 -1
- package/dist/routes/files-tab.js +23 -23
- package/dist/routes/llm-settings.cjs +1 -1
- package/dist/routes/llm-settings.cjs.map +1 -1
- package/dist/routes/llm-settings.d.ts +6 -4
- package/dist/routes/llm-settings.js +0 -1
- package/dist/routes/llm-settings.js.map +1 -1
- package/dist/routes/mcp.cjs.map +1 -1
- package/dist/routes/mcp.js.map +1 -1
- package/dist/services/settings.cjs +1 -1
- package/dist/services/settings.cjs.map +1 -1
- package/dist/services/settings.js +2 -6
- package/dist/services/settings.js.map +1 -1
- package/dist/stores/command-menu-store.cjs +2 -0
- package/dist/stores/command-menu-store.cjs.map +1 -0
- package/dist/stores/command-menu-store.d.ts +8 -0
- package/dist/stores/command-menu-store.js +12 -0
- package/dist/stores/command-menu-store.js.map +1 -0
- package/dist/stores/conversation-panel-preferences-store.cjs +1 -1
- package/dist/stores/conversation-panel-preferences-store.cjs.map +1 -1
- package/dist/stores/conversation-panel-preferences-store.js +1 -1
- package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
- package/dist/stores/conversation-store.cjs +1 -1
- package/dist/stores/conversation-store.cjs.map +1 -1
- package/dist/stores/conversation-store.d.ts +1 -0
- package/dist/stores/conversation-store.js +1 -0
- package/dist/stores/conversation-store.js.map +1 -1
- package/dist/stores/goal-store.cjs +2 -0
- package/dist/stores/goal-store.cjs.map +1 -0
- package/dist/stores/goal-store.d.ts +28 -0
- package/dist/stores/goal-store.js +14 -0
- package/dist/stores/goal-store.js.map +1 -0
- package/dist/themes/color-themes.cjs +3 -3
- package/dist/themes/color-themes.cjs.map +1 -1
- package/dist/themes/color-themes.d.ts +13 -2
- package/dist/themes/color-themes.js +2 -2
- package/dist/themes/color-themes.js.map +1 -1
- package/dist/types/agent-server/core/events/conversation-state-event.d.ts +39 -3
- package/dist/types/agent-server/type-guards.cjs +1 -1
- package/dist/types/agent-server/type-guards.cjs.map +1 -1
- package/dist/types/agent-server/type-guards.d.ts +2 -1
- package/dist/types/agent-server/type-guards.js +3 -3
- package/dist/types/agent-server/type-guards.js.map +1 -1
- package/dist/types/mcp-auth.cjs +2 -0
- package/dist/types/mcp-auth.cjs.map +1 -0
- package/dist/types/mcp-auth.d.ts +43 -0
- package/dist/types/mcp-auth.js +13 -0
- package/dist/types/mcp-auth.js.map +1 -0
- package/dist/types/mcp-server.d.ts +22 -1
- package/dist/types/settings.d.ts +6 -4
- package/dist/ui/context-menu.d.ts +1 -1
- package/dist/utils/acp-command.d.ts +64 -0
- package/dist/utils/automation-debug-prompt.d.ts +18 -0
- package/dist/utils/constants.cjs +1 -1
- package/dist/utils/constants.cjs.map +1 -1
- package/dist/utils/constants.d.ts +2 -0
- package/dist/utils/constants.js +12 -3
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/dropdown-classes.cjs +1 -1
- package/dist/utils/dropdown-classes.cjs.map +1 -1
- package/dist/utils/dropdown-classes.js +4 -2
- package/dist/utils/dropdown-classes.js.map +1 -1
- package/dist/utils/form-control-classes.cjs +1 -1
- package/dist/utils/form-control-classes.js +1 -1
- package/dist/utils/handle-event-for-ui.cjs +1 -1
- package/dist/utils/handle-event-for-ui.cjs.map +1 -1
- package/dist/utils/handle-event-for-ui.js +72 -37
- package/dist/utils/handle-event-for-ui.js.map +1 -1
- package/dist/utils/mcp-config.cjs +1 -1
- package/dist/utils/mcp-config.cjs.map +1 -1
- package/dist/utils/mcp-config.d.ts +15 -9
- package/dist/utils/mcp-config.js +124 -53
- package/dist/utils/mcp-config.js.map +1 -1
- package/dist/utils/mcp-installed-server-display.cjs +2 -0
- package/dist/utils/mcp-installed-server-display.cjs.map +1 -0
- package/dist/utils/mcp-installed-server-display.d.ts +8 -0
- package/dist/utils/mcp-installed-server-display.js +12 -0
- package/dist/utils/mcp-installed-server-display.js.map +1 -0
- package/dist/utils/mcp-installed-servers.cjs +1 -1
- package/dist/utils/mcp-installed-servers.cjs.map +1 -1
- package/dist/utils/mcp-installed-servers.js +4 -4
- package/dist/utils/mcp-installed-servers.js.map +1 -1
- package/dist/utils/mcp-marketplace-utils.cjs +1 -1
- package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
- package/dist/utils/mcp-marketplace-utils.d.ts +2 -0
- package/dist/utils/mcp-marketplace-utils.js +31 -16
- package/dist/utils/mcp-marketplace-utils.js.map +1 -1
- package/dist/utils/mcp-server-name.cjs +2 -0
- package/dist/utils/mcp-server-name.cjs.map +1 -0
- package/dist/utils/mcp-server-name.d.ts +3 -0
- package/dist/utils/mcp-server-name.js +12 -0
- package/dist/utils/mcp-server-name.js.map +1 -0
- package/dist/utils/plugin-display.cjs +2 -0
- package/dist/utils/plugin-display.cjs.map +1 -0
- package/dist/utils/plugin-display.d.ts +20 -0
- package/dist/utils/plugin-display.js +29 -0
- package/dist/utils/plugin-display.js.map +1 -0
- package/dist/utils/settings-utils.cjs.map +1 -1
- package/dist/utils/settings-utils.js.map +1 -1
- package/dist/utils/workspaces-compatibility.cjs +1 -1
- package/dist/utils/workspaces-compatibility.cjs.map +1 -1
- package/dist/utils/workspaces-compatibility.js +1 -0
- package/dist/utils/workspaces-compatibility.js.map +1 -1
- package/package.json +7 -4
- package/scripts/check-sdk-version-sync.mjs +6 -6
- package/scripts/check-translation-completeness.cjs +6 -0
- package/scripts/dev-safe.mjs +14 -3
- package/scripts/dev-with-automation.mjs +4 -0
- package/scripts/gen-acp-docker-env.mjs +107 -0
- package/scripts/ingress.mjs +66 -226
- package/scripts/proxy-utils.mjs +171 -0
- package/scripts/static-server.mjs +127 -283
- package/build/assets/Trans-CiZR6eVI.js +0 -1
- package/build/assets/active-backend-context-CEuva6ZJ.js +0 -1
- package/build/assets/add-backend-modal-b_eiVk3A.js +0 -1
- package/build/assets/agent-server-conversation-service.api-D_uJ7BKc.js +0 -5
- package/build/assets/agent-settings-DyfziYyM.js +0 -2
- package/build/assets/alert-banner-BFayS5vM.js +0 -1
- package/build/assets/analytics-consent-form-modal-CQ22qlFF.js +0 -1
- package/build/assets/api-key-entry-screen-KnIwP0vN.js +0 -1
- package/build/assets/app-settings-CBaHJ5vJ.js +0 -1
- package/build/assets/automation-detail-DgQswnXg.js +0 -1
- package/build/assets/automations-list-D99p6CoQ.js +0 -1
- package/build/assets/back-nav-button-Cp9z-wsG.js +0 -1
- package/build/assets/backend-form-modal-BABAz-zH.js +0 -1
- package/build/assets/backend-synced-settings-badge-DzwWQC4T.js +0 -1
- package/build/assets/base-modal-1bHiB5Wf.js +0 -1
- package/build/assets/brand-button-FHWgEb4Q.js +0 -1
- package/build/assets/browser-store-B9h0eW79.js +0 -1
- package/build/assets/browser-tab-JiCXo0Nc.js +0 -1
- package/build/assets/chat-send-button-QtyofqFt.js +0 -1
- package/build/assets/check-6ieIiPhW.js +0 -1
- package/build/assets/checkmark-BfgRVMHK.js +0 -1
- package/build/assets/circle-plus-check-toggle-CmINKfZj.js +0 -1
- package/build/assets/close-DhH0uMa7.js +0 -1
- package/build/assets/code-tag-CnORXDJj.js +0 -1
- package/build/assets/combobox-caret-BB15S7zY.js +0 -1
- package/build/assets/condenser-settings-BOKNShD9.js +0 -1
- package/build/assets/confirmation-modal-CofmThy4.js +0 -1
- package/build/assets/context-menu-list-item-DO12IEaK.js +0 -1
- package/build/assets/conversation-DIzv-jq8.js +0 -1
- package/build/assets/conversation-DV3odvMe.js +0 -19
- package/build/assets/conversation-local-storage-DK7yJr5N.js +0 -1
- package/build/assets/conversation-panel-CgCarTAn.js +0 -1
- package/build/assets/conversation-service.api-RV_bOKNz.js +0 -1
- package/build/assets/conversation-state-store-4obo4ZMf.js +0 -1
- package/build/assets/conversation-store-CXrL0v-X.js +0 -6
- package/build/assets/conversation-tab-empty-state-CqT5ur_H.js +0 -1
- package/build/assets/copy-C5tBqfWu.js +0 -1
- package/build/assets/copy-to-clipboard-button-BVFYcsg_.js +0 -1
- package/build/assets/createLucideIcon-D3nkdIAN.js +0 -1
- package/build/assets/declaration-B0yY_dkQ.js +0 -1
- package/build/assets/device-verify-DRupI_hz.js +0 -1
- package/build/assets/dist-D5d5zm8o.js +0 -1
- package/build/assets/dist-fV7trlfb.js +0 -1
- package/build/assets/dropdown-classes-5IsMjYYw.js +0 -1
- package/build/assets/edit-automation-modal-BG-gd82b.js +0 -1
- package/build/assets/ellipsis-button-DWvVZO_r.js +0 -1
- package/build/assets/entry.client-uhbVfCtd.js +0 -2
- package/build/assets/enum-filter-dropdown-CB2fqz_e.js +0 -1
- package/build/assets/environment-switch-overlay-Oeal5TVq.js +0 -1
- package/build/assets/extensions-hub-DxiE0AZR.js +0 -1
- package/build/assets/files-tab-1F2OlNeH.js +0 -1
- package/build/assets/files-tab-store-C1q5Rbx3.js +0 -1
- package/build/assets/folder-C5tr7xyN.js +0 -1
- package/build/assets/get-language-from-path-E1JKsbeE.js +0 -1
- package/build/assets/git-provider-icon-CKs-22Ts.js +0 -1
- package/build/assets/home-B3E0le0g.js +0 -1
- package/build/assets/iconBase-DMoh3FEg.js +0 -1
- package/build/assets/index-redirect-DhuK5mhS.js +0 -1
- package/build/assets/install-server-modal-DjintV14.js +0 -1
- package/build/assets/is-backend-llm-ready-Bj44pekN.js +0 -1
- package/build/assets/launch-DCU3S84p.js +0 -1
- package/build/assets/lesson-plan-BUUPKVsa.js +0 -3
- package/build/assets/link-external-CF4KHxx-.js +0 -1
- package/build/assets/llm-client-BakM_czF.js +0 -1
- package/build/assets/llm-not-configured-banner-BV-NIjfR.js +0 -27
- package/build/assets/llm-settings-B5d7PHzz.js +0 -1
- package/build/assets/llm-settings-C5whb-0p.js +0 -1
- package/build/assets/loader-circle-DyX8DmLg.js +0 -1
- package/build/assets/loading-spinner-BvOAco8a.js +0 -1
- package/build/assets/manage-backends-modal-D9ClxVpM.js +0 -1
- package/build/assets/manifest-38a873aa.js +0 -1
- package/build/assets/mcp-7rk44GRS.js +0 -9
- package/build/assets/mcp-client-DxHXYNOw.js +0 -1
- package/build/assets/messages-DgBEaXil.js +0 -43
- package/build/assets/modal-backdrop-DjAC2zOZ.js +0 -1
- package/build/assets/modal-body-OJdIUJ68.js +0 -1
- package/build/assets/modal-close-button-BNjGesHc.js +0 -1
- package/build/assets/model-selector-w2uGPM5y.js +0 -1
- package/build/assets/navigation-context-CUJ60pLI.js +0 -1
- package/build/assets/navigation-link-BiPKTOHF.js +0 -1
- package/build/assets/onboarding-Cit87z8g.js +0 -1
- package/build/assets/onboarding-modal-JPrzvr8W.js +0 -1
- package/build/assets/openhands-logo-uNs9g6LY.js +0 -1
- package/build/assets/option-service.api-BLYUhnCF.js +0 -1
- package/build/assets/organization-service.api-DpSSwlZu.js +0 -1
- package/build/assets/path-utils-B4WAVqvK.js +0 -1
- package/build/assets/plan-components-DSOTFW2D.js +0 -1
- package/build/assets/planner-tab-LmoxgKKe.js +0 -1
- package/build/assets/preload-helper-D_sPnjeL.js +0 -1
- package/build/assets/profiles-client-B4SJ4ZAf.js +0 -1
- package/build/assets/providers-BGUAB8kf.js +0 -1
- package/build/assets/react-Dn-iWFF5.js +0 -1
- package/build/assets/react-dom-BBXlXOZX.js +0 -1
- package/build/assets/react-uQK8du1l.js +0 -1
- package/build/assets/recommended-automations-launcher-Df9MXUpX.js +0 -50
- package/build/assets/root-BShAdYGY.css +0 -1
- package/build/assets/root-C99reK-P.js +0 -2
- package/build/assets/root-layout-BtH64XeC.js +0 -2
- package/build/assets/runtime-waiting-state-C7MjXDeW.js +0 -1
- package/build/assets/schema-field-BCDuEMrl.js +0 -1
- package/build/assets/sdk-section-page-XJN9mGju.js +0 -1
- package/build/assets/sdk-settings-schema-B15AE1GH.js +0 -1
- package/build/assets/search-rob4u9f8.js +0 -1
- package/build/assets/secrets-service-CrPyCR8u.js +0 -1
- package/build/assets/secrets-settings-UJn15N7E.js +0 -1
- package/build/assets/settings-C5aUD_sQ.js +0 -1
- package/build/assets/settings-dropdown-input-DQRt2_RA.js +0 -1
- package/build/assets/settings-gear-B7bZDo_8.js +0 -1
- package/build/assets/settings-index-zP_rYIW1.js +0 -1
- package/build/assets/settings-input-n8FzVso3.js +0 -1
- package/build/assets/settings-list-classes-DquY3fwm.js +0 -1
- package/build/assets/settings-modal-szlQ6LpE.js +0 -1
- package/build/assets/settings-section-header-context-DrXgyNC-.js +0 -1
- package/build/assets/settings-service.api-B4G8NzCM.js +0 -1
- package/build/assets/settings-switch-DsbEm3ie.js +0 -1
- package/build/assets/shared-conversation-BrAvqeaI.js +0 -1
- package/build/assets/sidebar-mobile-menu-toggle-BRZGCe-l.js +0 -1
- package/build/assets/sidebar-nav-link-B_EygIce.js +0 -1
- package/build/assets/skill-card-pill-row-Bq9Imkdh.js +0 -1
- package/build/assets/skills-Wg6i0kbu.js +0 -1
- package/build/assets/skills-client-DNd444Bm.js +0 -1
- package/build/assets/skills-plugins-DaGkVI7-.js +0 -1
- package/build/assets/skills-settings-Dlp0WFaT.js +0 -2
- package/build/assets/styled-tooltip-ulgpZDga.js +0 -1
- package/build/assets/suspense-BqBQEuKs.js +0 -1
- package/build/assets/switch-skeleton-C49gVWOQ.js +0 -1
- package/build/assets/task-list-tab-Bz-UlCm2.js +0 -1
- package/build/assets/telemetry-DD3HKMgf.js +0 -2
- package/build/assets/terminal-BwLvVzyJ.js +0 -1
- package/build/assets/toggle-switch-CxW8-lBI.js +0 -1
- package/build/assets/typography-BLf_mRKH.js +0 -1
- package/build/assets/u-check-circle-CxTAJuY9.js +0 -1
- package/build/assets/u-check-circle-half-Bj73jfUG.js +0 -1
- package/build/assets/u-circuit-C-6V9H9C.js +0 -1
- package/build/assets/u-edit-C7OnK2sa.js +0 -1
- package/build/assets/use-acp-credential-form-oehc057O.js +0 -1
- package/build/assets/use-active-conversation-CFXVX2on.js +0 -1
- package/build/assets/use-agent-state-D6xfZA4-.js +0 -1
- package/build/assets/use-backends-health-93yRIOWs.js +0 -1
- package/build/assets/use-breakpoint-Xdy_aZHE.js +0 -1
- package/build/assets/use-click-outside-element-CADb_gCP.js +0 -1
- package/build/assets/use-cloud-current-user-id-CzOXsy04.js +0 -1
- package/build/assets/use-config-oXjEWyb6.js +0 -1
- package/build/assets/use-create-conversation-D-YkgrxS.js +0 -1
- package/build/assets/use-create-secret-CX7Ij7W4.js +0 -1
- package/build/assets/use-event-store-DMRAQQi8.js +0 -1
- package/build/assets/use-handle-plan-click-CwW2Ijc2.js +0 -1
- package/build/assets/use-is-authed-CNbX1KMm.js +0 -1
- package/build/assets/use-launch-skill-in-chat-xI9byRUw.js +0 -1
- package/build/assets/use-llm-profiles-BXRZ2rBh.js +0 -1
- package/build/assets/use-runtime-is-ready-Dwzs9_vp.js +0 -1
- package/build/assets/use-settings-_usWr_qn.js +0 -1
- package/build/assets/use-settings-nav-items-DoB5iH-7.js +0 -16
- package/build/assets/use-skills-BtorhoCN.js +0 -1
- package/build/assets/use-task-list-u46BhYBC.js +0 -1
- package/build/assets/use-tracking-Ca7p71hH.js +0 -1
- package/build/assets/use-user-conversation-U-16WF6G.js +0 -1
- package/build/assets/useMutation-CseCrRRO.js +0 -1
- package/build/assets/useQuery-bowvACed.js +0 -1
- package/build/assets/useTranslation-KhTtKmnv.js +0 -1
- package/build/assets/utils-cRyMoFbz.js +0 -1
- package/build/assets/vendor~conversation-panel~conversation~alert-banner-CjfR7T3x.js +0 -1
- package/build/assets/vendor~entry.client-_zl82x5T.js +0 -1
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~dj9x5fm9-CgCGB-3J.js +0 -177
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~jfvr34cq-BJdsUTJG.js +0 -1
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~m3df9r20-BynFAJ_S.js +0 -1
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~nk00xiud-MfCRtPrK.js +0 -9
- package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~ghtfhmuy-BHDILMe2.js +0 -1
- package/build/assets/vendor~root-layout~conversation-panel~conversation-BFZmbXpq.js +0 -1
- package/build/assets/vendor~root-layout~conversation-panel~conversation~index-BPY-kNjK.js +0 -1
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation-BhWqQNmF.js +0 -1
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~cfyi58ut-CnnEa0dP.js +0 -1
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~clac83qc-DMX6XUwI.js +0 -2
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~ldu51w4e-Cqp6k3RG.js +0 -1
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~ldu51w4e-DS4GWhCz.js +0 -9
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~ji28rqgb-DVffa9Ks.js +0 -48
- package/build/assets/vendor~root-layout~home~mcp~automations-list~onboarding-modal-BzR6ypP3.js +0 -1
- package/build/assets/vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~hzfcl1q6-BcvHZmEZ.js +0 -2
- package/build/assets/vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~hzfcl1q6-Cuvp6wqR.js +0 -14
- package/build/assets/verification-settings-DKZnUHD6.js +0 -1
- package/build/assets/x-DpnGZyVW.js +0 -1
- package/build/assets/x-mark-x3tvCZzc.js +0 -1
- package/dist/components/features/analytics/analytics-consent-form-modal.d.ts +0 -5
- package/dist/components/features/chat/switch-profile-button.cjs +0 -2
- package/dist/components/features/chat/switch-profile-button.cjs.map +0 -1
- package/dist/components/features/chat/switch-profile-button.d.ts +0 -1
- package/dist/components/features/chat/switch-profile-button.js +0 -48
- package/dist/components/features/chat/switch-profile-button.js.map +0 -1
- package/dist/components/features/chat/switch-profile-context-menu.cjs +0 -2
- package/dist/components/features/chat/switch-profile-context-menu.cjs.map +0 -1
- package/dist/components/features/chat/switch-profile-context-menu.d.ts +0 -9
- package/dist/components/features/chat/switch-profile-context-menu.js +0 -106
- package/dist/components/features/chat/switch-profile-context-menu.js.map +0 -1
- package/dist/components/features/onboarding/is-backend-llm-ready.d.ts +0 -30
- package/dist/icons/u-circuit.cjs +0 -2
- package/dist/icons/u-circuit.cjs.map +0 -1
- package/dist/icons/u-circuit.js +0 -19
- package/dist/icons/u-circuit.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/clickup.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/clickup.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/clickup.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/clickup.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/dropbox.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/dropbox.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/dropbox.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/dropbox.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/freshdesk.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/freshdesk.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/freshdesk.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/freshdesk.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/mailchimp.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/mailchimp.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/mailchimp.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/mailchimp.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/pipedrive.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/pipedrive.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/pipedrive.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/pipedrive.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/plaid.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/plaid.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/plaid.js +0 -28
- package/dist/node_modules/@openhands/extensions/integrations/catalog/plaid.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/servicenow.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/servicenow.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/servicenow.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/servicenow.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/shopify.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/shopify.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/shopify.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/shopify.js.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/zendesk.cjs +0 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/zendesk.cjs.map +0 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/zendesk.js +0 -35
- package/dist/node_modules/@openhands/extensions/integrations/catalog/zendesk.js.map +0 -1
- /package/build/assets/{agent-server-ui-style-scope-CIDFDeQb.js → agent-server-ui-style-scope-COnDHTm5.js} +0 -0
- /package/build/assets/{automation-DNgDxqtq.js → automation-BU8zu-FP.js} +0 -0
- /package/build/assets/{common-KeiA2Rod.js → common-Dh7OqABE.js} +0 -0
- /package/build/assets/{environment-switch-store-BpKxp6Xq.js → environment-switch-store-DkjlKWzN.js} +0 -0
- /package/build/assets/{extension-module-card-classes-DvvyImGv.js → extension-module-card-classes-9V3J9J_b.js} +0 -0
- /package/build/assets/{git-status-mapper-B3_HbzUT.js → git-status-mapper-BI8FyUVp.js} +0 -0
- /package/build/assets/{handle-capture-consent-BChvj6mt.js → handle-capture-consent-CPMXU29K.js} +0 -0
- /package/build/assets/{llm-subscription-C1xDoa3K.js → llm-subscription-DtsX5Lhg.js} +0 -0
- /package/build/assets/{map-provider-MonJL5SS.js → map-provider-BM2SJarp.js} +0 -0
- /package/build/assets/{objectWithoutPropertiesLoose-BRYudkUn.js → objectWithoutPropertiesLoose-BgYIAs2y.js} +0 -0
- /package/build/assets/{rolldown-runtime-wFmyQBCi.js → rolldown-runtime-BFRubm34.js} +0 -0
- /package/build/assets/{settings-like-page-layout-classes-DNg2vKSM.js → settings-like-page-layout-classes-DENKlZpD.js} +0 -0
- /package/build/assets/{v4-BMWDcIWQ.js → v4-DbCkTSoU.js} +0 -0
- /package/build/assets/{vendor~browser-yZEspfT9.js → vendor~browser-Dqd33JyP.js} +0 -0
- /package/build/assets/{vendor~terminal-CcUoOdAH.js → vendor~terminal-aeP3PnKf.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-form-modal.js","names":[],"sources":["../../../../src/components/features/backends/backend-form-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { ServerClient } from \"@openhands/typescript-client/clients\";\nimport OpenHandsLogoWhite from \"#/assets/branding/openhands-logo-white.svg?react\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport {\n MODAL_MAX_WIDTH_VIEWPORT,\n modalWidthClassName,\n} from \"#/components/shared/modals/modal-body\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useBackendsHealth } from \"#/hooks/query/use-backends-health\";\nimport { getAgentServerClientOptions } from \"#/api/agent-server-client-options\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport {\n assertAgentServerVersionIsSupported,\n getDisplayAgentServerVersion,\n} from \"#/api/agent-server-compatibility\";\nimport ChevronDownSmallIcon from \"#/icons/chevron-down-small.svg?react\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { Backend, BackendKind } from \"#/api/backend-registry/types\";\nimport { getUserFacingConnectionErrorMessage } from \"#/utils/user-facing-error\";\nimport { cn } from \"#/utils/utils\";\nimport {\n modalTitleLgClassName,\n modalTitleLgMediumClassName,\n} from \"#/utils/modal-classes\";\nimport { getBackendStatusLabel } from \"./backend-status-label\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\n\nexport type BackendFormMode = \"add\" | \"edit\";\n\ninterface BackendFormModalProps {\n mode: BackendFormMode;\n /** Required when `mode === \"edit\"`. */\n backend?: Backend;\n onClose: () => void;\n}\n\nfunction inferKindFromHost(host: string): BackendKind {\n const trimmed = host.trim().toLowerCase();\n if (trimmed.includes(\"all-hands.dev\") || trimmed.includes(\"openhands.dev\")) {\n return \"cloud\";\n }\n return \"local\";\n}\n\n/**\n * Returns true for hostnames that represent a local / private-network address.\n * Used by normalizeHost to choose http:// instead of https://.\n */\nfunction isLocalAddress(hostname: string): boolean {\n // Strip IPv6 bracket notation: [::1] → ::1\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n // IPv6 loopback, any-address, and named loopback\n if (h === \"localhost\" || h === \"::1\" || h === \"::\" || h === \"0.0.0.0\")\n return true;\n // 127.x.x.x loopback range + IPv4-mapped loopback (::ffff:127.x.x.x)\n if (/^127\\./.test(h) || /^::ffff:127\\./i.test(h)) return true;\n // RFC 1918 private ranges\n if (/^10\\./.test(h)) return true;\n if (/^192\\.168\\./.test(h)) return true;\n if (/^172\\.(1[6-9]|2\\d|3[01])\\./.test(h)) return true;\n // IPv6 link-local (fe80::/10) and unique local (fc00::/7)\n if (/^fe[89ab][0-9a-f]:/i.test(h)) return true;\n if (/^f[cd][0-9a-f]{2}:/i.test(h)) return true;\n // mDNS / Bonjour (.local)\n if (h.endsWith(\".local\")) return true;\n // Single-label hostnames (no dots, no colons) are local network names.\n // Colons are excluded so bare IPv6 addresses don't accidentally match.\n if (!h.includes(\".\") && !h.includes(\":\")) return true;\n return false;\n}\n\nfunction normalizeHost(host: string): string {\n const trimmed = host.trim().replace(/\\/+$/, \"\");\n if (!trimmed) return \"\";\n // Already has an explicit scheme — respect it.\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed;\n // Extract the pure hostname for scheme selection, handling three cases:\n // [::1]:8080 → bracket IPv6 notation → extract ::1\n // ::1 → bare IPv6 (multiple colons, no bracket) → whole string\n // host:port → regular host:port → part before the colon\n const bracketMatch = trimmed.match(/^\\[([^\\]]+)\\]/);\n const hostname = bracketMatch\n ? bracketMatch[1]\n : (trimmed.match(/:/g) ?? []).length > 1\n ? trimmed\n : trimmed.split(\":\")[0];\n const scheme = isLocalAddress(hostname) ? \"http\" : \"https\";\n return `${scheme}://${trimmed}`;\n}\n\n/**\n * Returns true when `host` represents a reachable backend URL.\n *\n * Rules (applied in order):\n * 1. Must be non-empty after trimming.\n * 2. Must contain no whitespace — spaces can never appear in a host/port.\n * 3. After normalisation (bare hosts get `https://` prepended), must parse\n * as a valid http or https URL with a non-empty hostname.\n */\nfunction isValidHostUrl(host: string): boolean {\n const trimmed = host.trim();\n if (!trimmed) return false;\n // Spaces anywhere in the input are an immediate rejection.\n if (/\\s/.test(trimmed)) return false;\n const normalized = normalizeHost(trimmed);\n if (!normalized) return false;\n try {\n const url = new URL(normalized);\n return (\n (url.protocol === \"http:\" || url.protocol === \"https:\") &&\n url.hostname.length > 0\n );\n } catch {\n return false;\n }\n}\n\nconst DEFAULT_OPENHANDS_CLOUD_HOST = \"https://app.all-hands.dev\";\n\nfunction getConnectionTestFailedTitle(\n t: ReturnType<typeof useTranslation>[\"t\"],\n host: string,\n): string {\n return t(I18nKey.BACKEND$CONNECTION_TEST_FAILED, {\n host,\n interpolation: { escapeValue: false },\n });\n}\n\nfunction getConnectionErrorDetail(error: unknown): string | null {\n return getUserFacingConnectionErrorMessage(error);\n}\n\nfunction getConnectionTestFailedMessage(title: string, error: unknown): string {\n const detail = getConnectionErrorDetail(error);\n return detail ? `${title}\\n${detail}` : title;\n}\n\nasync function testBackendConnection(\n backend: Pick<Backend, \"host\" | \"apiKey\" | \"kind\">,\n): Promise<void> {\n // Cloud backends authenticate via OAuth; preflight GET is not applicable.\n if (backend.kind !== \"local\") return;\n\n const serverInfo = await new ServerClient(\n getAgentServerClientOptions({\n host: backend.host,\n sessionApiKey: backend.apiKey || null,\n timeout: 5000,\n }),\n ).getServerInfo();\n assertAgentServerVersionIsSupported(serverInfo);\n}\n\n/**\n * Live status row for the edit form: shows a connection dot, a\n * \"Local\"/\"Cloud\" label, and the agent server's reported version when\n * available. Replaces the legacy local/cloud radio fieldset (kind is\n * now inferred from the host).\n */\nfunction BackendStatusBadge({\n backend,\n testIdRoot,\n}: {\n backend: Backend;\n testIdRoot: string;\n}) {\n const { t } = useTranslation(\"openhands\");\n const healthByBackendId = useBackendsHealth([backend]);\n const health = healthByBackendId[backend.id];\n const isConnected = health?.isConnected ?? null;\n const disabled = health?.disabled === true;\n const consecutiveFailures = health?.consecutiveFailures ?? 0;\n const lastError = health?.lastError ?? null;\n\n const { data: version } = useQuery({\n queryKey: [\"backend-version\", backend.host, backend.apiKey],\n queryFn: async () => {\n const info = await new ServerClient(\n getAgentServerClientOptions({\n host: backend.host,\n sessionApiKey: backend.apiKey || null,\n timeout: 5000,\n }),\n ).getServerInfo();\n return getDisplayAgentServerVersion(info);\n },\n retry: false,\n staleTime: 60_000,\n enabled: backend.kind === \"local\" && !disabled,\n });\n\n const statusLabel = getBackendStatusLabel(t, backend, health);\n\n const kindLabel =\n backend.kind === \"cloud\"\n ? t(I18nKey.BACKEND$KIND_CLOUD)\n : t(I18nKey.BACKEND$KIND_LOCAL);\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div\n data-testid={`${testIdRoot}-status`}\n className=\"flex items-center gap-3 text-sm\"\n >\n <BackendStatusDot isConnected={isConnected} />\n <span className=\"text-white\" data-testid={`${testIdRoot}-status-label`}>\n {statusLabel}\n </span>\n <span className=\"text-tertiary-alt\">·</span>\n <span className=\"text-[var(--oh-text-tertiary)]\">{kindLabel}</span>\n {version ? (\n <span\n className=\"text-xs text-[var(--oh-muted)]\"\n data-testid={`${testIdRoot}-version`}\n >\n {t(I18nKey.BACKEND$VERSION_LABEL, { version })}\n </span>\n ) : null}\n </div>\n\n {disabled ? (\n <div\n data-testid={`${testIdRoot}-status-error`}\n className=\"flex flex-col gap-1 rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm\"\n >\n <span className=\"font-semibold text-red-300\">\n {t(I18nKey.BACKEND$HEALTH_FAILED_TITLE)}\n </span>\n <span className=\"text-xs text-[var(--oh-text-tertiary)]\">\n {t(I18nKey.BACKEND$HEALTH_FAILED_DETAIL, {\n count: consecutiveFailures,\n })}\n </span>\n {lastError ? (\n <span\n data-testid={`${testIdRoot}-status-error-message`}\n className=\"text-xs text-red-300 whitespace-pre-wrap break-words\"\n >\n {lastError}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface BackendFormSubmitPayload {\n name: string;\n host: string;\n apiKey: string;\n kind: BackendKind;\n}\n\ninterface UseBackendFormOptions {\n initialName?: string;\n initialHost?: string;\n initialApiKey?: string;\n /**\n * Called to test the connection. The hook does NOT call\n * `testBackendConnection` directly so callers can inject a\n * wrapped version (e.g. with extra logging or different timeout).\n * Should throw on failure.\n */\n onTestConnection: (payload: BackendFormSubmitPayload) => Promise<void>;\n /** Called after a successful connection test and persistence. */\n onSuccess: () => void;\n /** Require a non-empty API key even when the host looks local. */\n requireApiKey?: boolean;\n /**\n * When provided, completely replaces the default submit flow\n * (onTestConnection + onSuccess). The hook still manages form state\n * and canSubmit validation, but the caller owns error handling and\n * success side effects. Should throw on failure.\n */\n onSubmitOverride?: (payload: BackendFormSubmitPayload) => Promise<void>;\n}\n\n/**\n * Shared hook for the backend-form state used by both `BackendForm`\n * (edit/add mode) and `ManualConnectionColumn` (add-mode-only column).\n * Encapsulates name / host / apiKey fields, `connectionError`,\n * `isSubmitting`, and the shared `handleSubmit` flow.\n */\nfunction useBackendForm({\n initialName = \"\",\n initialHost = \"\",\n initialApiKey = \"\",\n onTestConnection,\n onSuccess,\n requireApiKey = false,\n onSubmitOverride,\n}: UseBackendFormOptions) {\n const { t } = useTranslation(\"openhands\");\n\n const [name, setName] = React.useState(initialName);\n const [host, setHost] = React.useState(initialHost);\n const [apiKey, setApiKey] = React.useState(initialApiKey);\n const [connectionError, setConnectionError] = React.useState<string | null>(\n null,\n );\n const [isSubmitting, setIsSubmitting] = React.useState(false);\n\n const kind = inferKindFromHost(host);\n const needsApiKey = requireApiKey || kind !== \"local\";\n const canSubmit =\n name.trim().length > 0 &&\n isValidHostUrl(host) &&\n (!needsApiKey || apiKey.trim().length > 0);\n\n const handleSubmit = React.useCallback(\n async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n if (!canSubmit || isSubmitting) return;\n\n const payload: BackendFormSubmitPayload = {\n name: name.trim(),\n host: normalizeHost(host),\n apiKey: apiKey.trim(),\n kind,\n };\n\n setConnectionError(null);\n setIsSubmitting(true);\n\n try {\n // When onSubmitOverride is provided, it completely replaces the\n // default flow (onTestConnection + onSuccess).\n if (onSubmitOverride) {\n await onSubmitOverride(payload);\n } else {\n await onTestConnection(payload);\n onSuccess();\n }\n } catch (error) {\n setConnectionError(\n getConnectionTestFailedMessage(\n getConnectionTestFailedTitle(t, payload.host),\n error,\n ),\n );\n } finally {\n setIsSubmitting(false);\n }\n },\n [\n canSubmit,\n isSubmitting,\n name,\n host,\n apiKey,\n kind,\n onTestConnection,\n onSuccess,\n requireApiKey,\n onSubmitOverride,\n t,\n ],\n );\n\n return {\n name,\n setName,\n host,\n setHost,\n apiKey,\n setApiKey,\n connectionError,\n setConnectionError,\n isSubmitting,\n kind,\n canSubmit,\n handleSubmit,\n };\n}\n\nexport interface BackendFormProps {\n mode: BackendFormMode;\n /** Required when `mode === \"edit\"`. */\n backend?: Backend;\n /**\n * Called after the form is submitted and the backend has been\n * persisted. Use this to dismiss a containing modal, advance an\n * onboarding step, etc.\n */\n onSubmitted: () => void;\n /**\n * Optional render slot rendered in place of the default\n * Save / Cancel button row, so callers (e.g. the onboarding flow)\n * can re-skin the action area while still owning submission via the\n * standard `<form onSubmit>` flow. Receives the form's submit-ready\n * state.\n */\n renderActions?: (state: {\n canSubmit: boolean;\n isSubmitting: boolean;\n testIdRoot: string;\n }) => React.ReactNode;\n /** Used to disambiguate test ids across the same screen. */\n testIdRoot?: string;\n /** When true, the host field is pre-filled and disabled. */\n hostReadOnly?: boolean;\n /**\n * When true, a non-empty API key is required for submission regardless\n * of the inferred backend kind. The standard add form allows empty\n * keys for local backends; the auth-gate screen needs to enforce one.\n */\n requireApiKey?: boolean;\n /**\n * When true, hides the name/host/API-key inputs (and related inline\n * errors) while keeping the action row visible — used by onboarding\n * after a successful connection probe.\n */\n hideConfigurationFields?: boolean;\n /**\n * Replace the default synchronous add/update-and-close submit with a\n * custom async handler. The form builds the payload, validates\n * client-side, then hands it to this callback. If the callback throws,\n * the form remains open so the caller can surface errors.\n */\n onSubmitOverride?: (payload: BackendFormSubmitPayload) => Promise<void>;\n}\n\n/**\n * Reusable form body for adding / editing a backend. Renders the\n * common name / host / API-key inputs plus the kind selector\n * (radio buttons in `add` mode, status badge in `edit` mode).\n *\n * Rendered as a `<form>`, so consumers should put any extra controls\n * either inside `renderActions` or as siblings inside a wrapping\n * element — but submission flows through the standard form submit so\n * Enter-to-submit still works.\n */\nexport function BackendForm({\n mode,\n backend,\n onSubmitted,\n renderActions,\n testIdRoot: explicitTestIdRoot,\n hostReadOnly,\n requireApiKey,\n hideConfigurationFields = false,\n onSubmitOverride,\n}: BackendFormProps) {\n const { t } = useTranslation(\"openhands\");\n const { addBackend, updateBackend } = useActiveBackendContext();\n\n // In edit mode preserve the existing backend's kind so that renaming or\n // rotating the API key on a cloud backend (e.g. an OHE/enterprise instance\n // on a custom domain) does not silently downgrade it to \"local\" and switch\n // the auth header from `Authorization: Bearer` to `X-Session-API-Key`.\n // Only infer from the host when adding a new backend.\n const fixedKind: BackendKind | null =\n mode === \"edit\" && backend ? backend.kind : null;\n\n const {\n name,\n setName,\n host,\n setHost,\n apiKey,\n setApiKey,\n connectionError,\n setConnectionError,\n isSubmitting,\n kind: inferredKind,\n handleSubmit: runSubmit,\n } = useBackendForm({\n initialName: backend?.name ?? \"\",\n initialHost: backend?.host ?? \"\",\n initialApiKey: backend?.apiKey ?? \"\",\n onTestConnection: testBackendConnection,\n onSuccess: async () => {\n const payload: BackendFormSubmitPayload = {\n name: name.trim(),\n host: normalizeHost(host),\n apiKey: apiKey.trim(),\n kind: fixedKind ?? inferredKind,\n };\n if (mode === \"edit\" && backend) {\n updateBackend(backend.id, payload);\n } else {\n addBackend(payload);\n }\n onSubmitted();\n },\n requireApiKey,\n onSubmitOverride,\n });\n\n // Inline validation: only show errors after the user has left a field.\n const [nameTouched, setNameTouched] = React.useState(false);\n const [hostTouched, setHostTouched] = React.useState(false);\n\n const kind = fixedKind ?? inferredKind;\n const testIdRoot =\n explicitTestIdRoot ?? (mode === \"edit\" ? \"edit-backend\" : \"add-backend\");\n\n const needsApiKey = requireApiKey || kind !== \"local\";\n const canSubmit =\n name.trim().length > 0 &&\n isValidHostUrl(host) &&\n (!needsApiKey || apiKey.trim().length > 0);\n\n // Error messages — only surfaced after the user has blurred the field.\n const nameError =\n nameTouched && !name.trim() ? t(I18nKey.BACKEND$NAME_REQUIRED) : undefined;\n const hostError = hostTouched\n ? !host.trim()\n ? t(I18nKey.BACKEND$HOST_REQUIRED)\n : !isValidHostUrl(host)\n ? t(I18nKey.BACKEND$HOST_INVALID)\n : undefined\n : undefined;\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n if (!canSubmit) {\n // Mark all validated fields as touched so inline errors become visible\n // (e.g. user pressed Enter before filling required fields).\n setNameTouched(true);\n setHostTouched(true);\n return;\n }\n await runSubmit(event);\n };\n\n return (\n <form\n data-testid={`${testIdRoot}-form`}\n onSubmit={handleSubmit}\n className=\"flex flex-col gap-4\"\n >\n <div\n data-testid={`${testIdRoot}-configuration-fields`}\n className={cn(\n \"flex flex-col gap-4\",\n hideConfigurationFields && \"hidden\",\n )}\n >\n <SettingsInput\n testId={`${testIdRoot}-name`}\n name={`${testIdRoot}-name`}\n type=\"text\"\n label={t(I18nKey.BACKEND$NAME_LABEL)}\n value={name}\n onChange={(value) => {\n setName(value);\n setConnectionError(null);\n }}\n onBlur={() => setNameTouched(true)}\n // eslint-disable-next-line i18next/no-literal-string -- example placeholder, not user-facing copy\n placeholder=\"Production\"\n className=\"w-full\"\n showRequiredTag\n error={nameError}\n />\n\n <SettingsInput\n testId={`${testIdRoot}-host`}\n name={`${testIdRoot}-host`}\n type=\"text\"\n label={t(I18nKey.BACKEND$HOST_LABEL)}\n value={host}\n onChange={\n hostReadOnly\n ? undefined\n : (value) => {\n setHost(value);\n setConnectionError(null);\n }\n }\n onBlur={() => setHostTouched(true)}\n placeholder={DEFAULT_OPENHANDS_CLOUD_HOST}\n className=\"w-full\"\n showRequiredTag\n error={hostError}\n isDisabled={hostReadOnly}\n />\n\n <SettingsInput\n testId={`${testIdRoot}-api-key`}\n name={`${testIdRoot}-api-key`}\n type=\"password\"\n label={t(I18nKey.BACKEND$KEY_LABEL)}\n value={apiKey}\n onChange={(value) => {\n setApiKey(value);\n setConnectionError(null);\n }}\n placeholder=\"\"\n className=\"w-full\"\n />\n\n {connectionError ? (\n <div\n role=\"alert\"\n data-testid={`${testIdRoot}-error`}\n className=\"rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-300 whitespace-pre-wrap break-words\"\n >\n {connectionError}\n </div>\n ) : null}\n\n {mode === \"edit\" && backend && (\n <BackendStatusBadge backend={backend} testIdRoot={testIdRoot} />\n )}\n </div>\n\n {renderActions ? (\n renderActions({\n canSubmit: canSubmit && !isSubmitting,\n isSubmitting,\n testIdRoot,\n })\n ) : (\n <div className=\"flex justify-end gap-2 mt-2 w-full\">\n <BrandButton\n type=\"button\"\n variant=\"secondary\"\n onClick={onSubmitted}\n testId={`${testIdRoot}-cancel`}\n >\n {t(I18nKey.BUTTON$CANCEL)}\n </BrandButton>\n <BrandButton\n type=\"submit\"\n variant=\"primary\"\n isDisabled={!canSubmit || isSubmitting}\n testId={`${testIdRoot}-submit`}\n >\n {t(I18nKey.BACKEND$SAVE)}\n </BrandButton>\n </div>\n )}\n </form>\n );\n}\n\n// ── Add-mode two-column layout ──────────────────────────────────────\n\n/**\n * @spec BM-002 — Adding a backend auto-switches the active selection to it\n * (BM-001), so a backend-scoped detail page the user is viewing now belongs\n * to the previous backend. Redirect to that section's list so they never see\n * stale data, mirroring the switch-backend redirect in BackendSelector.\n */\nfunction useRedirectAfterAddBackend() {\n const { currentPath, navigate } = useNavigation();\n return React.useCallback(() => {\n if (/^\\/automations\\/[^/]+/.test(currentPath)) navigate(\"/automations\");\n else if (/^\\/conversations\\/[^/]+/.test(currentPath))\n navigate(\"/conversations\");\n }, [currentPath, navigate]);\n}\n\ninterface BackendConnectionOptionsProps {\n onConnected: (payload: BackendFormSubmitPayload) => void;\n testIdRoot?: string;\n initialManualBackend?: Partial<\n Pick<BackendFormSubmitPayload, \"name\" | \"host\" | \"apiKey\">\n >;\n requireManualApiKey?: boolean;\n manualSubmitLabel?: React.ReactNode;\n manualSubmittingLabel?: React.ReactNode;\n manualSubmitTestId?: string;\n}\n\n/**\n * Manual agent-server connection plus OpenHands Cloud OAuth login.\n * Used by both the Add Backend modal and the onboarding backend step so\n * supported backend choices stay consistent across first-run and settings UI.\n */\nexport function BackendConnectionOptions({\n onConnected,\n testIdRoot = \"add-backend\",\n initialManualBackend,\n requireManualApiKey = false,\n manualSubmitLabel,\n manualSubmittingLabel,\n manualSubmitTestId,\n}: BackendConnectionOptionsProps) {\n const { t } = useTranslation(\"openhands\");\n const lockedCloudHost = getLockedCloudHost();\n\n if (lockedCloudHost) {\n return (\n <div\n data-testid={`${testIdRoot}-connection-options`}\n className=\"flex justify-center\"\n >\n <div className=\"w-full\">\n <CloudLoginColumn\n onConnected={onConnected}\n testIdRoot={testIdRoot}\n lockedHost={lockedCloudHost}\n />\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-testid={`${testIdRoot}-connection-options`}\n className=\"flex flex-col gap-6 md:flex-row\"\n >\n <div className=\"flex-1 min-w-0\">\n <ManualConnectionColumn\n onConnected={onConnected}\n testIdRoot={testIdRoot}\n initialBackend={initialManualBackend}\n requireApiKey={requireManualApiKey}\n submitLabel={manualSubmitLabel ?? t(I18nKey.BACKEND$CONNECT)}\n submittingLabel={\n manualSubmittingLabel ??\n t(I18nKey.ONBOARDING$BACKEND_STATUS_CHECKING)\n }\n submitTestId={manualSubmitTestId}\n />\n </div>\n\n <div className=\"flex-1 min-w-0\">\n <CloudLoginColumn onConnected={onConnected} testIdRoot={testIdRoot} />\n </div>\n </div>\n );\n}\n\ninterface ManualConnectionColumnProps {\n onConnected: (payload: BackendFormSubmitPayload) => void;\n testIdRoot: string;\n initialBackend?: Partial<\n Pick<BackendFormSubmitPayload, \"name\" | \"host\" | \"apiKey\">\n >;\n requireApiKey: boolean;\n submitLabel: React.ReactNode;\n submittingLabel: React.ReactNode;\n submitTestId?: string;\n}\n\n/**\n * Manual connection via Host + API Key. Designed for self-hosted agent servers\n * and self-hosted OpenHands Cloud with API key auth.\n */\nfunction ManualConnectionColumn({\n onConnected,\n testIdRoot,\n initialBackend,\n requireApiKey,\n submitLabel,\n submittingLabel,\n submitTestId,\n}: ManualConnectionColumnProps) {\n const { t } = useTranslation(\"openhands\");\n\n const {\n name,\n setName,\n host,\n setHost,\n apiKey,\n setApiKey,\n connectionError,\n setConnectionError,\n isSubmitting,\n kind,\n canSubmit,\n handleSubmit,\n } = useBackendForm({\n initialName: initialBackend?.name ?? \"\",\n initialHost: initialBackend?.host ?? \"\",\n initialApiKey: initialBackend?.apiKey ?? \"\",\n onTestConnection: testBackendConnection,\n onSuccess: () => {\n onConnected({\n name: name.trim(),\n host: normalizeHost(host),\n apiKey: apiKey.trim(),\n kind,\n });\n },\n requireApiKey,\n });\n\n return (\n <form\n data-testid={`${testIdRoot}-form`}\n onSubmit={handleSubmit}\n className=\"flex flex-col gap-4 flex-1 min-w-0\"\n >\n <div className=\"flex flex-col gap-1\">\n <SettingsInput\n testId={`${testIdRoot}-name`}\n name={`${testIdRoot}-name`}\n type=\"text\"\n label={t(I18nKey.BACKEND$NAME_LABEL)}\n value={name}\n onChange={(value) => {\n setName(value);\n setConnectionError(null);\n }}\n // eslint-disable-next-line i18next/no-literal-string -- example placeholder, not user-facing copy\n placeholder=\"e.g. My Server\"\n className=\"w-full\"\n />\n <p className=\"text-xs text-[var(--oh-muted)]\">\n {t(I18nKey.BACKEND$NAME_HELPER)}\n </p>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <SettingsInput\n testId={`${testIdRoot}-host`}\n name={`${testIdRoot}-host`}\n type=\"text\"\n label={t(I18nKey.BACKEND$HOST_LABEL)}\n value={host}\n onChange={(value) => {\n setHost(value);\n setConnectionError(null);\n }}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"http://localhost:8000\"\n className=\"w-full\"\n />\n <p\n className=\"text-xs text-[var(--oh-muted)]\"\n data-testid={`${testIdRoot}-host-helper`}\n >\n {t(I18nKey.BACKEND$HOST_HELPER)}\n </p>\n </div>\n\n <SettingsInput\n testId={`${testIdRoot}-api-key`}\n name={`${testIdRoot}-api-key`}\n type=\"password\"\n label={t(I18nKey.BACKEND$KEY_LABEL)}\n value={apiKey}\n onChange={(value) => {\n setApiKey(value);\n setConnectionError(null);\n }}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"sk-••••••••••\"\n className=\"w-full\"\n />\n\n {connectionError ? (\n <div\n role=\"alert\"\n data-testid={`${testIdRoot}-error`}\n className=\"rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-300 whitespace-pre-wrap break-words\"\n >\n {connectionError}\n </div>\n ) : null}\n\n <BrandButton\n type=\"submit\"\n variant=\"secondary\"\n isDisabled={!canSubmit || isSubmitting}\n testId={submitTestId ?? `${testIdRoot}-submit`}\n className=\"w-full text-center\"\n >\n {isSubmitting ? submittingLabel : submitLabel}\n </BrandButton>\n </form>\n );\n}\n\ninterface CloudLoginColumnProps {\n onConnected: (payload: BackendFormSubmitPayload) => void;\n testIdRoot: string;\n lockedHost?: string;\n}\n\n/**\n * One-click OAuth login with OpenHands Cloud. Includes an \"Advanced\"\n * disclosure for users who self-host OpenHands Cloud and need to override the\n * host.\n */\nfunction CloudLoginColumn({\n onConnected,\n testIdRoot,\n lockedHost,\n}: CloudLoginColumnProps) {\n const { t } = useTranslation(\"openhands\");\n\n const [advancedOpen, setAdvancedOpen] = React.useState(false);\n const [customHost, setCustomHost] = React.useState(\"\");\n\n const effectiveHost =\n lockedHost ?? (customHost.trim() || DEFAULT_OPENHANDS_CLOUD_HOST);\n\n const handleLoginSuccess = (apiKey: string) => {\n onConnected({\n name: \"OpenHands Cloud\",\n host: normalizeHost(effectiveHost),\n apiKey,\n kind: \"cloud\",\n });\n };\n\n return (\n <div className=\"flex flex-1 min-w-0 flex-col items-center gap-3\">\n <div className=\"flex flex-col items-center gap-1\">\n <OpenHandsLogoWhite width={56} height={56} aria-hidden />\n\n <h4\n className={modalTitleLgMediumClassName}\n data-testid={`${testIdRoot}-cloud-title`}\n >\n {t(I18nKey.BACKEND$CLOUD_TITLE)}\n </h4>\n </div>\n\n <p className=\"text-center text-sm leading-relaxed text-[var(--oh-muted)]\">\n {t(I18nKey.BACKEND$CLOUD_DESCRIPTION)}\n </p>\n\n <DeviceFlowAuth\n host={effectiveHost}\n onSuccess={handleLoginSuccess}\n testIdRoot={testIdRoot}\n />\n\n {lockedHost ? null : (\n <div className=\"w-full\">\n <button\n type=\"button\"\n onClick={() => setAdvancedOpen((open) => !open)}\n aria-expanded={advancedOpen}\n data-testid={`${testIdRoot}-advanced-toggle`}\n className=\"flex w-full cursor-pointer items-center justify-center gap-1 text-center text-xs text-[var(--oh-muted)] transition-colors hover:text-content-2\"\n >\n <span>{t(I18nKey.BACKEND$ADVANCED)}</span>\n <ChevronDownSmallIcon\n className={cn(\n \"h-4 w-4 shrink-0 text-muted transition-transform\",\n advancedOpen && \"rotate-180\",\n )}\n aria-hidden\n />\n </button>\n <div\n className={cn(\n \"pt-2\",\n !advancedOpen && \"pointer-events-none invisible\",\n )}\n aria-hidden={!advancedOpen}\n >\n <SettingsInput\n testId={`${testIdRoot}-cloud-host`}\n name={`${testIdRoot}-cloud-host`}\n type=\"text\"\n label={t(I18nKey.BACKEND$HOST_LABEL)}\n value={customHost}\n onChange={setCustomHost}\n placeholder={DEFAULT_OPENHANDS_CLOUD_HOST}\n className=\"w-full\"\n />\n <p className=\"mt-1 text-xs text-[var(--oh-muted)]\">\n {t(I18nKey.BACKEND$LOGIN_CLOUD_HINT)}\n </p>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction AddBackendConnectionOptions({ onClose }: { onClose: () => void }) {\n const { addBackend } = useActiveBackendContext();\n const redirectAfterAdd = useRedirectAfterAddBackend();\n\n const handleConnected = React.useCallback(\n (payload: BackendFormSubmitPayload) => {\n addBackend(payload);\n redirectAfterAdd();\n onClose();\n },\n [addBackend, redirectAfterAdd, onClose],\n );\n\n return <BackendConnectionOptions onConnected={handleConnected} />;\n}\n\n// ── Modal wrappers ──────────────────────────────────────────────────\n\n/**\n * Modal wrapper. In **add** mode it renders a two-column layout\n * (manual connection | OR | Cloud login). In **edit** mode it wraps\n * the standard `BackendForm`.\n */\nexport function BackendFormModal({\n mode,\n backend,\n onClose,\n}: BackendFormModalProps) {\n const { t } = useTranslation(\"openhands\");\n\n if (mode === \"add\") {\n return (\n <ModalBackdrop\n onClose={onClose}\n closeOnEscape={false}\n aria-label={t(I18nKey.BACKEND$ADD_TITLE)}\n >\n <div\n data-testid=\"add-backend-modal\"\n className={cn(\n \"relative rounded-xl border border-[var(--oh-border)] bg-base-secondary\",\n modalWidthClassName(\"xl\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n )}\n >\n <ModalCloseButton onClose={onClose} testId=\"add-backend-close\" />\n {/* Header */}\n <div className=\"px-6 pt-6 pb-2 pr-12\">\n <h2 className={modalTitleLgClassName}>\n {t(I18nKey.BACKEND$ADD_TITLE)}\n </h2>\n </div>\n\n <div className=\"px-6 pb-6 pt-2\">\n <AddBackendConnectionOptions onClose={onClose} />\n </div>\n </div>\n </ModalBackdrop>\n );\n }\n\n // Edit mode — single-column form (unchanged)\n const testIdRoot = \"edit-backend\";\n return (\n <ModalBackdrop\n onClose={onClose}\n closeOnEscape={false}\n aria-label={t(I18nKey.BACKEND$EDIT_TITLE)}\n >\n <div\n data-testid={`${testIdRoot}-modal`}\n className={cn(\n \"relative bg-base-secondary p-6 rounded-xl flex flex-col gap-4 border border-[var(--oh-border)]\",\n modalWidthClassName(\"md\"),\n )}\n >\n <ModalCloseButton onClose={onClose} testId={`${testIdRoot}-close`} />\n <h2 className={cn(\"pr-6\", modalTitleLgClassName)}>\n {t(I18nKey.BACKEND$EDIT_TITLE)}\n </h2>\n <BackendForm\n mode=\"edit\"\n backend={backend}\n onSubmitted={onClose}\n testIdRoot={testIdRoot}\n />\n </div>\n </ModalBackdrop>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"backend-form-modal.js","names":[],"sources":["../../../../src/components/features/backends/backend-form-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { ServerClient } from \"@openhands/typescript-client/clients\";\nimport OpenHandsLogoWhite from \"#/assets/branding/openhands-logo-white.svg?react\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport {\n MODAL_MAX_WIDTH_VIEWPORT,\n modalWidthClassName,\n} from \"#/components/shared/modals/modal-body\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { SegmentedToggle } from \"#/components/features/files-tab/segmented-toggle\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useBackendsHealth } from \"#/hooks/query/use-backends-health\";\nimport { useTracking } from \"#/hooks/use-tracking\";\nimport { getAgentServerClientOptions } from \"#/api/agent-server-client-options\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { isOpenHandsCloudHost } from \"#/api/device-flow-client\";\nimport {\n assertAgentServerVersionIsSupported,\n getDisplayAgentServerVersion,\n} from \"#/api/agent-server-compatibility\";\nimport ChevronDownSmallIcon from \"#/icons/chevron-down-small.svg?react\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { Backend, BackendKind } from \"#/api/backend-registry/types\";\nimport { getUserFacingConnectionErrorMessage } from \"#/utils/user-facing-error\";\nimport { cn } from \"#/utils/utils\";\nimport {\n modalTitleLgClassName,\n modalTitleLgMediumClassName,\n} from \"#/utils/modal-classes\";\nimport { getBackendStatusLabel } from \"./backend-status-label\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\n\nexport type BackendFormMode = \"add\" | \"edit\";\n\ninterface BackendFormModalProps {\n mode: BackendFormMode;\n /** Required when `mode === \"edit\"`. */\n backend?: Backend;\n onClose: () => void;\n /** Analytics surface for the `backend_added` event (add mode only). */\n source?: BackendAddedSource;\n}\n\n/**\n * Seed the default backend kind from the host. Uses proper hostname-suffix\n * matching (via {@link isOpenHandsCloudHost}) rather than a substring test, so\n * a look-alike host such as `all-hands-testing.dev` isn't misread as cloud.\n *\n * This is only a *default*: a self-hosted OpenHands Cloud/Enterprise instance\n * on a truly custom domain is indistinguishable from a local agent-server by\n * host alone, so the manual add form lets the user override the kind\n * explicitly (see the Type selector in ManualConnectionColumn).\n */\nfunction inferKindFromHost(host: string): BackendKind {\n return isOpenHandsCloudHost(host) ? \"cloud\" : \"local\";\n}\n\n/**\n * Returns true for hostnames that represent a local / private-network address.\n * Used by normalizeHost to choose http:// instead of https://.\n */\nfunction isLocalAddress(hostname: string): boolean {\n // Strip IPv6 bracket notation: [::1] → ::1\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n // IPv6 loopback, any-address, and named loopback\n if (h === \"localhost\" || h === \"::1\" || h === \"::\" || h === \"0.0.0.0\")\n return true;\n // 127.x.x.x loopback range + IPv4-mapped loopback (::ffff:127.x.x.x)\n if (/^127\\./.test(h) || /^::ffff:127\\./i.test(h)) return true;\n // RFC 1918 private ranges\n if (/^10\\./.test(h)) return true;\n if (/^192\\.168\\./.test(h)) return true;\n if (/^172\\.(1[6-9]|2\\d|3[01])\\./.test(h)) return true;\n // IPv6 link-local (fe80::/10) and unique local (fc00::/7)\n if (/^fe[89ab][0-9a-f]:/i.test(h)) return true;\n if (/^f[cd][0-9a-f]{2}:/i.test(h)) return true;\n // mDNS / Bonjour (.local)\n if (h.endsWith(\".local\")) return true;\n // Single-label hostnames (no dots, no colons) are local network names.\n // Colons are excluded so bare IPv6 addresses don't accidentally match.\n if (!h.includes(\".\") && !h.includes(\":\")) return true;\n return false;\n}\n\nfunction normalizeHost(host: string): string {\n const trimmed = host.trim().replace(/\\/+$/, \"\");\n if (!trimmed) return \"\";\n // Already has an explicit scheme — respect it.\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed;\n // Extract the pure hostname for scheme selection, handling three cases:\n // [::1]:8080 → bracket IPv6 notation → extract ::1\n // ::1 → bare IPv6 (multiple colons, no bracket) → whole string\n // host:port → regular host:port → part before the colon\n const bracketMatch = trimmed.match(/^\\[([^\\]]+)\\]/);\n const hostname = bracketMatch\n ? bracketMatch[1]\n : (trimmed.match(/:/g) ?? []).length > 1\n ? trimmed\n : trimmed.split(\":\")[0];\n const scheme = isLocalAddress(hostname) ? \"http\" : \"https\";\n return `${scheme}://${trimmed}`;\n}\n\n/**\n * Returns true when `host` represents a reachable backend URL.\n *\n * Rules (applied in order):\n * 1. Must be non-empty after trimming.\n * 2. Must contain no whitespace — spaces can never appear in a host/port.\n * 3. After normalisation (bare hosts get `https://` prepended), must parse\n * as a valid http or https URL with a non-empty hostname.\n */\nfunction isValidHostUrl(host: string): boolean {\n const trimmed = host.trim();\n if (!trimmed) return false;\n // Spaces anywhere in the input are an immediate rejection.\n if (/\\s/.test(trimmed)) return false;\n const normalized = normalizeHost(trimmed);\n if (!normalized) return false;\n try {\n const url = new URL(normalized);\n return (\n (url.protocol === \"http:\" || url.protocol === \"https:\") &&\n url.hostname.length > 0\n );\n } catch {\n return false;\n }\n}\n\nconst DEFAULT_OPENHANDS_CLOUD_HOST = \"https://app.all-hands.dev\";\n\nexport type BackendConnectionMethod = \"manual\" | \"cloud_login\";\n\nexport type BackendAddedSource = \"add_backend_modal\" | \"manage_backends_modal\";\n\nfunction getConnectionTestFailedTitle(\n t: ReturnType<typeof useTranslation>[\"t\"],\n host: string,\n): string {\n return t(I18nKey.BACKEND$CONNECTION_TEST_FAILED, {\n host,\n interpolation: { escapeValue: false },\n });\n}\n\nfunction getConnectionErrorDetail(error: unknown): string | null {\n return getUserFacingConnectionErrorMessage(error);\n}\n\nfunction getConnectionTestFailedMessage(title: string, error: unknown): string {\n const detail = getConnectionErrorDetail(error);\n return detail ? `${title}\\n${detail}` : title;\n}\n\nasync function testBackendConnection(\n backend: Pick<Backend, \"host\" | \"apiKey\" | \"kind\">,\n): Promise<void> {\n // Cloud backends authenticate via OAuth; preflight GET is not applicable.\n if (backend.kind !== \"local\") return;\n\n const serverInfo = await new ServerClient(\n getAgentServerClientOptions({\n host: backend.host,\n sessionApiKey: backend.apiKey || null,\n timeout: 5000,\n }),\n ).getServerInfo();\n assertAgentServerVersionIsSupported(serverInfo);\n}\n\n/**\n * Live status row for the edit form: shows a connection dot, a\n * \"Local\"/\"Cloud\" label, and the agent server's reported version when\n * available. Replaces the legacy local/cloud radio fieldset (kind is\n * now inferred from the host).\n */\nfunction BackendStatusBadge({\n backend,\n testIdRoot,\n}: {\n backend: Backend;\n testIdRoot: string;\n}) {\n const { t } = useTranslation(\"openhands\");\n const healthByBackendId = useBackendsHealth([backend]);\n const health = healthByBackendId[backend.id];\n const isConnected = health?.isConnected ?? null;\n const disabled = health?.disabled === true;\n const consecutiveFailures = health?.consecutiveFailures ?? 0;\n const lastError = health?.lastError ?? null;\n\n const { data: version } = useQuery({\n queryKey: [\"backend-version\", backend.host, backend.apiKey],\n queryFn: async () => {\n const info = await new ServerClient(\n getAgentServerClientOptions({\n host: backend.host,\n sessionApiKey: backend.apiKey || null,\n timeout: 5000,\n }),\n ).getServerInfo();\n return getDisplayAgentServerVersion(info);\n },\n retry: false,\n staleTime: 60_000,\n enabled: backend.kind === \"local\" && !disabled,\n });\n\n const statusLabel = getBackendStatusLabel(t, backend, health);\n\n const kindLabel =\n backend.kind === \"cloud\"\n ? t(I18nKey.BACKEND$KIND_CLOUD)\n : t(I18nKey.BACKEND$KIND_LOCAL);\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div\n data-testid={`${testIdRoot}-status`}\n className=\"flex items-center gap-3 text-sm\"\n >\n <BackendStatusDot isConnected={isConnected} />\n <span className=\"text-white\" data-testid={`${testIdRoot}-status-label`}>\n {statusLabel}\n </span>\n <span className=\"text-tertiary-alt\">·</span>\n <span className=\"text-[var(--oh-text-tertiary)]\">{kindLabel}</span>\n {version ? (\n <span\n className=\"text-xs text-[var(--oh-muted)]\"\n data-testid={`${testIdRoot}-version`}\n >\n {t(I18nKey.BACKEND$VERSION_LABEL, { version })}\n </span>\n ) : null}\n </div>\n\n {disabled ? (\n <div\n data-testid={`${testIdRoot}-status-error`}\n className=\"flex flex-col gap-1 rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm\"\n >\n <span className=\"font-semibold text-red-300\">\n {t(I18nKey.BACKEND$HEALTH_FAILED_TITLE)}\n </span>\n <span className=\"text-xs text-[var(--oh-text-tertiary)]\">\n {t(I18nKey.BACKEND$HEALTH_FAILED_DETAIL, {\n count: consecutiveFailures,\n })}\n </span>\n {lastError ? (\n <span\n data-testid={`${testIdRoot}-status-error-message`}\n className=\"text-xs text-red-300 whitespace-pre-wrap break-words\"\n >\n {lastError}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface BackendFormSubmitPayload {\n name: string;\n host: string;\n apiKey: string;\n kind: BackendKind;\n}\n\ninterface UseBackendFormOptions {\n initialName?: string;\n initialHost?: string;\n initialApiKey?: string;\n /**\n * Called to test the connection. The hook does NOT call\n * `testBackendConnection` directly so callers can inject a\n * wrapped version (e.g. with extra logging or different timeout).\n * Should throw on failure.\n */\n onTestConnection: (payload: BackendFormSubmitPayload) => Promise<void>;\n /** Called after a successful connection test and persistence. */\n onSuccess: () => void;\n /** Require a non-empty API key even when the host looks local. */\n requireApiKey?: boolean;\n /**\n * When provided, completely replaces the default submit flow\n * (onTestConnection + onSuccess). The hook still manages form state\n * and canSubmit validation, but the caller owns error handling and\n * success side effects. Should throw on failure.\n */\n onSubmitOverride?: (payload: BackendFormSubmitPayload) => Promise<void>;\n}\n\n/**\n * Shared hook for the backend-form state used by both `BackendForm`\n * (edit/add mode) and `ManualConnectionColumn` (add-mode-only column).\n * Encapsulates name / host / apiKey fields, `connectionError`,\n * `isSubmitting`, and the shared `handleSubmit` flow.\n */\nfunction useBackendForm({\n initialName = \"\",\n initialHost = \"\",\n initialApiKey = \"\",\n onTestConnection,\n onSuccess,\n requireApiKey = false,\n onSubmitOverride,\n}: UseBackendFormOptions) {\n const { t } = useTranslation(\"openhands\");\n\n const [name, setName] = React.useState(initialName);\n const [host, setHost] = React.useState(initialHost);\n const [apiKey, setApiKey] = React.useState(initialApiKey);\n const [connectionError, setConnectionError] = React.useState<string | null>(\n null,\n );\n const [isSubmitting, setIsSubmitting] = React.useState(false);\n const [kindOverride, setKindOverride] = React.useState<BackendKind | null>(\n null,\n );\n\n // Kind follows host inference until the user explicitly picks a type, then\n // respects that choice. A custom-domain OHE can't be distinguished from a\n // custom-domain local agent-server by host alone, so ManualConnectionColumn\n // exposes `setKind` (a Type selector) to let the user declare it.\n const kind = kindOverride ?? inferKindFromHost(host);\n const needsApiKey = requireApiKey || kind !== \"local\";\n const canSubmit =\n name.trim().length > 0 &&\n isValidHostUrl(host) &&\n (!needsApiKey || apiKey.trim().length > 0);\n\n const handleSubmit = React.useCallback(\n async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n if (!canSubmit || isSubmitting) return;\n\n const payload: BackendFormSubmitPayload = {\n name: name.trim(),\n host: normalizeHost(host),\n apiKey: apiKey.trim(),\n kind,\n };\n\n setConnectionError(null);\n setIsSubmitting(true);\n\n try {\n // When onSubmitOverride is provided, it completely replaces the\n // default flow (onTestConnection + onSuccess).\n if (onSubmitOverride) {\n await onSubmitOverride(payload);\n } else {\n await onTestConnection(payload);\n onSuccess();\n }\n } catch (error) {\n setConnectionError(\n getConnectionTestFailedMessage(\n getConnectionTestFailedTitle(t, payload.host),\n error,\n ),\n );\n } finally {\n setIsSubmitting(false);\n }\n },\n [\n canSubmit,\n isSubmitting,\n name,\n host,\n apiKey,\n kind,\n onTestConnection,\n onSuccess,\n requireApiKey,\n onSubmitOverride,\n t,\n ],\n );\n\n return {\n name,\n setName,\n host,\n setHost,\n apiKey,\n setApiKey,\n connectionError,\n setConnectionError,\n isSubmitting,\n kind,\n setKind: setKindOverride,\n canSubmit,\n handleSubmit,\n };\n}\n\nexport interface BackendFormProps {\n mode: BackendFormMode;\n /** Required when `mode === \"edit\"`. */\n backend?: Backend;\n /**\n * Called after the form is submitted and the backend has been\n * persisted. Use this to dismiss a containing modal, advance an\n * onboarding step, etc.\n */\n onSubmitted: () => void;\n /**\n * Optional render slot rendered in place of the default\n * Save / Cancel button row, so callers (e.g. the onboarding flow)\n * can re-skin the action area while still owning submission via the\n * standard `<form onSubmit>` flow. Receives the form's submit-ready\n * state.\n */\n renderActions?: (state: {\n canSubmit: boolean;\n isSubmitting: boolean;\n testIdRoot: string;\n }) => React.ReactNode;\n /** Used to disambiguate test ids across the same screen. */\n testIdRoot?: string;\n /** When true, the host field is pre-filled and disabled. */\n hostReadOnly?: boolean;\n /**\n * When true, a non-empty API key is required for submission regardless\n * of the inferred backend kind. The standard add form allows empty\n * keys for local backends; the auth-gate screen needs to enforce one.\n */\n requireApiKey?: boolean;\n /**\n * When true, hides the name/host/API-key inputs (and related inline\n * errors) while keeping the action row visible — used by onboarding\n * after a successful connection probe.\n */\n hideConfigurationFields?: boolean;\n /**\n * Replace the default synchronous add/update-and-close submit with a\n * custom async handler. The form builds the payload, validates\n * client-side, then hands it to this callback. If the callback throws,\n * the form remains open so the caller can surface errors.\n */\n onSubmitOverride?: (payload: BackendFormSubmitPayload) => Promise<void>;\n}\n\n/**\n * Reusable form body for adding / editing a backend. Renders the\n * common name / host / API-key inputs plus the kind selector\n * (radio buttons in `add` mode, status badge in `edit` mode).\n *\n * Rendered as a `<form>`, so consumers should put any extra controls\n * either inside `renderActions` or as siblings inside a wrapping\n * element — but submission flows through the standard form submit so\n * Enter-to-submit still works.\n */\nexport function BackendForm({\n mode,\n backend,\n onSubmitted,\n renderActions,\n testIdRoot: explicitTestIdRoot,\n hostReadOnly,\n requireApiKey,\n hideConfigurationFields = false,\n onSubmitOverride,\n}: BackendFormProps) {\n const { t } = useTranslation(\"openhands\");\n const { addBackend, updateBackend } = useActiveBackendContext();\n\n // In edit mode preserve the existing backend's kind so that renaming or\n // rotating the API key on a cloud backend (e.g. an OHE/enterprise instance\n // on a custom domain) does not silently downgrade it to \"local\" and switch\n // the auth header from `Authorization: Bearer` to `X-Session-API-Key`.\n // Only infer from the host when adding a new backend.\n const fixedKind: BackendKind | null =\n mode === \"edit\" && backend ? backend.kind : null;\n\n const {\n name,\n setName,\n host,\n setHost,\n apiKey,\n setApiKey,\n connectionError,\n setConnectionError,\n isSubmitting,\n kind: inferredKind,\n handleSubmit: runSubmit,\n } = useBackendForm({\n initialName: backend?.name ?? \"\",\n initialHost: backend?.host ?? \"\",\n initialApiKey: backend?.apiKey ?? \"\",\n onTestConnection: testBackendConnection,\n onSuccess: async () => {\n const payload: BackendFormSubmitPayload = {\n name: name.trim(),\n host: normalizeHost(host),\n apiKey: apiKey.trim(),\n kind: fixedKind ?? inferredKind,\n };\n if (mode === \"edit\" && backend) {\n updateBackend(backend.id, payload);\n } else {\n addBackend(payload);\n }\n onSubmitted();\n },\n requireApiKey,\n onSubmitOverride,\n });\n\n // Inline validation: only show errors after the user has left a field.\n const [nameTouched, setNameTouched] = React.useState(false);\n const [hostTouched, setHostTouched] = React.useState(false);\n\n const kind = fixedKind ?? inferredKind;\n const testIdRoot =\n explicitTestIdRoot ?? (mode === \"edit\" ? \"edit-backend\" : \"add-backend\");\n\n const needsApiKey = requireApiKey || kind !== \"local\";\n const canSubmit =\n name.trim().length > 0 &&\n isValidHostUrl(host) &&\n (!needsApiKey || apiKey.trim().length > 0);\n\n // Error messages — only surfaced after the user has blurred the field.\n const nameError =\n nameTouched && !name.trim() ? t(I18nKey.BACKEND$NAME_REQUIRED) : undefined;\n const hostError = hostTouched\n ? !host.trim()\n ? t(I18nKey.BACKEND$HOST_REQUIRED)\n : !isValidHostUrl(host)\n ? t(I18nKey.BACKEND$HOST_INVALID)\n : undefined\n : undefined;\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n if (!canSubmit) {\n // Mark all validated fields as touched so inline errors become visible\n // (e.g. user pressed Enter before filling required fields).\n setNameTouched(true);\n setHostTouched(true);\n return;\n }\n await runSubmit(event);\n };\n\n return (\n <form\n data-testid={`${testIdRoot}-form`}\n onSubmit={handleSubmit}\n className=\"flex flex-col gap-4\"\n >\n <div\n data-testid={`${testIdRoot}-configuration-fields`}\n className={cn(\n \"flex flex-col gap-4\",\n hideConfigurationFields && \"hidden\",\n )}\n >\n <SettingsInput\n testId={`${testIdRoot}-name`}\n name={`${testIdRoot}-name`}\n type=\"text\"\n label={t(I18nKey.BACKEND$NAME_LABEL)}\n value={name}\n onChange={(value) => {\n setName(value);\n setConnectionError(null);\n }}\n onBlur={() => setNameTouched(true)}\n // eslint-disable-next-line i18next/no-literal-string -- example placeholder, not user-facing copy\n placeholder=\"Production\"\n className=\"w-full\"\n showRequiredTag\n error={nameError}\n />\n\n <SettingsInput\n testId={`${testIdRoot}-host`}\n name={`${testIdRoot}-host`}\n type=\"text\"\n label={t(I18nKey.BACKEND$HOST_LABEL)}\n value={host}\n onChange={\n hostReadOnly\n ? undefined\n : (value) => {\n setHost(value);\n setConnectionError(null);\n }\n }\n onBlur={() => setHostTouched(true)}\n placeholder={DEFAULT_OPENHANDS_CLOUD_HOST}\n className=\"w-full\"\n showRequiredTag\n error={hostError}\n isDisabled={hostReadOnly}\n />\n\n <SettingsInput\n testId={`${testIdRoot}-api-key`}\n name={`${testIdRoot}-api-key`}\n type=\"password\"\n label={t(I18nKey.BACKEND$KEY_LABEL)}\n value={apiKey}\n onChange={(value) => {\n setApiKey(value);\n setConnectionError(null);\n }}\n placeholder=\"\"\n className=\"w-full\"\n />\n\n {connectionError ? (\n <div\n role=\"alert\"\n data-testid={`${testIdRoot}-error`}\n className=\"rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-300 whitespace-pre-wrap break-words\"\n >\n {connectionError}\n </div>\n ) : null}\n\n {mode === \"edit\" && backend && (\n <BackendStatusBadge backend={backend} testIdRoot={testIdRoot} />\n )}\n </div>\n\n {renderActions ? (\n renderActions({\n canSubmit: canSubmit && !isSubmitting,\n isSubmitting,\n testIdRoot,\n })\n ) : (\n <div className=\"flex justify-end gap-2 mt-2 w-full\">\n <BrandButton\n type=\"button\"\n variant=\"secondary\"\n onClick={onSubmitted}\n testId={`${testIdRoot}-cancel`}\n >\n {t(I18nKey.BUTTON$CANCEL)}\n </BrandButton>\n <BrandButton\n type=\"submit\"\n variant=\"primary\"\n isDisabled={!canSubmit || isSubmitting}\n testId={`${testIdRoot}-submit`}\n >\n {t(I18nKey.BACKEND$SAVE)}\n </BrandButton>\n </div>\n )}\n </form>\n );\n}\n\n// ── Add-mode two-column layout ──────────────────────────────────────\n\n/**\n * @spec BM-002 — Adding a backend auto-switches the active selection to it\n * (BM-001), so a backend-scoped detail page the user is viewing now belongs\n * to the previous backend. Redirect to that section's list so they never see\n * stale data, mirroring the switch-backend redirect in BackendSelector.\n */\nfunction useRedirectAfterAddBackend() {\n const { currentPath, navigate } = useNavigation();\n return React.useCallback(() => {\n if (/^\\/automations\\/[^/]+/.test(currentPath)) navigate(\"/automations\");\n else if (/^\\/conversations\\/[^/]+/.test(currentPath))\n navigate(\"/conversations\");\n }, [currentPath, navigate]);\n}\n\ninterface BackendConnectionOptionsProps {\n onConnected: (\n payload: BackendFormSubmitPayload,\n connectionMethod: BackendConnectionMethod,\n ) => void;\n testIdRoot?: string;\n initialManualBackend?: Partial<\n Pick<BackendFormSubmitPayload, \"name\" | \"host\" | \"apiKey\">\n >;\n requireManualApiKey?: boolean;\n manualSubmitLabel?: React.ReactNode;\n manualSubmittingLabel?: React.ReactNode;\n manualSubmitTestId?: string;\n}\n\n/**\n * Manual agent-server connection plus OpenHands Cloud OAuth login.\n * Used by both the Add Backend modal and the onboarding backend step so\n * supported backend choices stay consistent across first-run and settings UI.\n */\nexport function BackendConnectionOptions({\n onConnected,\n testIdRoot = \"add-backend\",\n initialManualBackend,\n requireManualApiKey = false,\n manualSubmitLabel,\n manualSubmittingLabel,\n manualSubmitTestId,\n}: BackendConnectionOptionsProps) {\n const { t } = useTranslation(\"openhands\");\n const lockedCloudHost = getLockedCloudHost();\n\n if (lockedCloudHost) {\n return (\n <div\n data-testid={`${testIdRoot}-connection-options`}\n className=\"flex justify-center\"\n >\n <div className=\"w-full\">\n <CloudLoginColumn\n onConnected={onConnected}\n testIdRoot={testIdRoot}\n lockedHost={lockedCloudHost}\n />\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-testid={`${testIdRoot}-connection-options`}\n className=\"flex flex-col gap-6 md:flex-row\"\n >\n <div className=\"flex-1 min-w-0\">\n <ManualConnectionColumn\n onConnected={onConnected}\n testIdRoot={testIdRoot}\n initialBackend={initialManualBackend}\n requireApiKey={requireManualApiKey}\n submitLabel={manualSubmitLabel ?? t(I18nKey.BACKEND$CONNECT)}\n submittingLabel={\n manualSubmittingLabel ??\n t(I18nKey.ONBOARDING$BACKEND_STATUS_CHECKING)\n }\n submitTestId={manualSubmitTestId}\n />\n </div>\n\n <div className=\"flex-1 min-w-0\">\n <CloudLoginColumn onConnected={onConnected} testIdRoot={testIdRoot} />\n </div>\n </div>\n );\n}\n\ninterface ManualConnectionColumnProps {\n onConnected: (\n payload: BackendFormSubmitPayload,\n connectionMethod: BackendConnectionMethod,\n ) => void;\n testIdRoot: string;\n initialBackend?: Partial<\n Pick<BackendFormSubmitPayload, \"name\" | \"host\" | \"apiKey\">\n >;\n requireApiKey: boolean;\n submitLabel: React.ReactNode;\n submittingLabel: React.ReactNode;\n submitTestId?: string;\n}\n\n/**\n * Manual connection via Host + API Key. Designed for self-hosted agent servers\n * and self-hosted OpenHands Cloud with API key auth.\n */\nfunction ManualConnectionColumn({\n onConnected,\n testIdRoot,\n initialBackend,\n requireApiKey,\n submitLabel,\n submittingLabel,\n submitTestId,\n}: ManualConnectionColumnProps) {\n const { t } = useTranslation(\"openhands\");\n\n const {\n name,\n setName,\n host,\n setHost,\n apiKey,\n setApiKey,\n connectionError,\n setConnectionError,\n isSubmitting,\n kind,\n setKind,\n canSubmit,\n handleSubmit,\n } = useBackendForm({\n initialName: initialBackend?.name ?? \"\",\n initialHost: initialBackend?.host ?? \"\",\n initialApiKey: initialBackend?.apiKey ?? \"\",\n onTestConnection: testBackendConnection,\n onSuccess: () => {\n onConnected(\n {\n name: name.trim(),\n host: normalizeHost(host),\n apiKey: apiKey.trim(),\n kind,\n },\n \"manual\",\n );\n },\n requireApiKey,\n });\n\n return (\n <form\n data-testid={`${testIdRoot}-form`}\n onSubmit={handleSubmit}\n className=\"flex flex-col gap-4 flex-1 min-w-0\"\n >\n <div className=\"flex flex-col gap-1\">\n <SettingsInput\n testId={`${testIdRoot}-name`}\n name={`${testIdRoot}-name`}\n type=\"text\"\n label={t(I18nKey.BACKEND$NAME_LABEL)}\n value={name}\n onChange={(value) => {\n setName(value);\n setConnectionError(null);\n }}\n // eslint-disable-next-line i18next/no-literal-string -- example placeholder, not user-facing copy\n placeholder=\"e.g. My Server\"\n className=\"w-full\"\n />\n <p className=\"text-xs text-[var(--oh-muted)]\">\n {t(I18nKey.BACKEND$NAME_HELPER)}\n </p>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <SettingsInput\n testId={`${testIdRoot}-host`}\n name={`${testIdRoot}-host`}\n type=\"text\"\n label={t(I18nKey.BACKEND$HOST_LABEL)}\n value={host}\n onChange={(value) => {\n setHost(value);\n setConnectionError(null);\n }}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"http://localhost:8000\"\n className=\"w-full\"\n />\n <p\n className=\"text-xs text-[var(--oh-muted)]\"\n data-testid={`${testIdRoot}-host-helper`}\n >\n {t(I18nKey.BACKEND$HOST_HELPER)}\n </p>\n </div>\n\n <div className=\"flex flex-col items-start gap-2.5\">\n <span className=\"text-sm\">{t(I18nKey.BACKEND$KIND_LABEL)}</span>\n <SegmentedToggle<BackendKind>\n value={kind}\n options={[\n { value: \"local\", label: t(I18nKey.BACKEND$KIND_LOCAL) },\n { value: \"cloud\", label: t(I18nKey.BACKEND$KIND_CLOUD) },\n ]}\n onChange={(value) => setKind(value)}\n ariaLabel={t(I18nKey.BACKEND$KIND_LABEL)}\n testId={`${testIdRoot}-kind`}\n />\n </div>\n\n <SettingsInput\n testId={`${testIdRoot}-api-key`}\n name={`${testIdRoot}-api-key`}\n type=\"password\"\n label={t(I18nKey.BACKEND$KEY_LABEL)}\n value={apiKey}\n onChange={(value) => {\n setApiKey(value);\n setConnectionError(null);\n }}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"sk-••••••••••\"\n className=\"w-full\"\n />\n\n {connectionError ? (\n <div\n role=\"alert\"\n data-testid={`${testIdRoot}-error`}\n className=\"rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-300 whitespace-pre-wrap break-words\"\n >\n {connectionError}\n </div>\n ) : null}\n\n <BrandButton\n type=\"submit\"\n variant=\"secondary\"\n isDisabled={!canSubmit || isSubmitting}\n testId={submitTestId ?? `${testIdRoot}-submit`}\n className=\"w-full text-center\"\n >\n {isSubmitting ? submittingLabel : submitLabel}\n </BrandButton>\n </form>\n );\n}\n\ninterface CloudLoginColumnProps {\n onConnected: (\n payload: BackendFormSubmitPayload,\n connectionMethod: BackendConnectionMethod,\n ) => void;\n testIdRoot: string;\n lockedHost?: string;\n}\n\n/**\n * One-click OAuth login with OpenHands Cloud. Includes an \"Advanced\"\n * disclosure for users who self-host OpenHands Cloud and need to override the\n * host.\n */\nfunction CloudLoginColumn({\n onConnected,\n testIdRoot,\n lockedHost,\n}: CloudLoginColumnProps) {\n const { t } = useTranslation(\"openhands\");\n\n const [advancedOpen, setAdvancedOpen] = React.useState(false);\n const [customHost, setCustomHost] = React.useState(\"\");\n\n const effectiveHost =\n lockedHost ?? (customHost.trim() || DEFAULT_OPENHANDS_CLOUD_HOST);\n\n const handleLoginSuccess = (apiKey: string) => {\n onConnected(\n {\n name: \"OpenHands Cloud\",\n host: normalizeHost(effectiveHost),\n apiKey,\n kind: \"cloud\",\n },\n \"cloud_login\",\n );\n };\n\n return (\n <div className=\"flex flex-1 min-w-0 flex-col items-center gap-3 pb-7\">\n <div className=\"flex flex-col items-center gap-1\">\n <OpenHandsLogoWhite width={56} height={56} aria-hidden />\n\n <h4\n className={modalTitleLgMediumClassName}\n data-testid={`${testIdRoot}-cloud-title`}\n >\n {t(I18nKey.BACKEND$CLOUD_TITLE)}\n </h4>\n </div>\n\n <p className=\"text-center text-sm leading-relaxed text-[var(--oh-muted)]\">\n {t(I18nKey.BACKEND$CLOUD_DESCRIPTION)}\n </p>\n\n <DeviceFlowAuth\n host={effectiveHost}\n onSuccess={handleLoginSuccess}\n testIdRoot={testIdRoot}\n />\n\n {lockedHost ? null : (\n <div className=\"w-full\">\n <button\n type=\"button\"\n onClick={() => setAdvancedOpen((open) => !open)}\n aria-expanded={advancedOpen}\n data-testid={`${testIdRoot}-advanced-toggle`}\n className=\"flex w-full cursor-pointer items-center justify-center gap-1 text-center text-xs text-[var(--oh-muted)] transition-colors hover:text-content-2\"\n >\n <span>{t(I18nKey.BACKEND$ADVANCED)}</span>\n <ChevronDownSmallIcon\n className={cn(\n \"h-4 w-4 shrink-0 text-muted transition-transform\",\n advancedOpen && \"rotate-180\",\n )}\n aria-hidden\n />\n </button>\n <div\n className={cn(\n \"pt-2\",\n !advancedOpen && \"pointer-events-none invisible\",\n )}\n aria-hidden={!advancedOpen}\n >\n <SettingsInput\n testId={`${testIdRoot}-cloud-host`}\n name={`${testIdRoot}-cloud-host`}\n type=\"text\"\n label={t(I18nKey.BACKEND$HOST_LABEL)}\n value={customHost}\n onChange={setCustomHost}\n placeholder={DEFAULT_OPENHANDS_CLOUD_HOST}\n className=\"w-full\"\n />\n <p className=\"mt-1 text-xs text-[var(--oh-muted)]\">\n {t(I18nKey.BACKEND$LOGIN_CLOUD_HINT)}\n </p>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction AddBackendConnectionOptions({\n onClose,\n source,\n}: {\n onClose: () => void;\n source: BackendAddedSource;\n}) {\n const { addBackend } = useActiveBackendContext();\n const redirectAfterAdd = useRedirectAfterAddBackend();\n const { trackBackendAdded } = useTracking();\n\n const handleConnected = React.useCallback(\n (\n payload: BackendFormSubmitPayload,\n connectionMethod: BackendConnectionMethod,\n ) => {\n addBackend(payload);\n // Coarse, non-sensitive host classification — never emit the raw host.\n const isOpenHandsCloud = payload.host === DEFAULT_OPENHANDS_CLOUD_HOST;\n trackBackendAdded({\n backendKind: payload.kind,\n connectionMethod,\n isOpenhandsCloud: isOpenHandsCloud,\n isCustomHost: !isOpenHandsCloud,\n hasApiKey: Boolean(payload.apiKey),\n source,\n });\n redirectAfterAdd();\n onClose();\n },\n [addBackend, redirectAfterAdd, onClose, trackBackendAdded, source],\n );\n\n return <BackendConnectionOptions onConnected={handleConnected} />;\n}\n\n// ── Modal wrappers ──────────────────────────────────────────────────\n\n/**\n * Modal wrapper. In **add** mode it renders a two-column layout\n * (manual connection | OR | Cloud login). In **edit** mode it wraps\n * the standard `BackendForm`.\n */\nexport function BackendFormModal({\n mode,\n backend,\n onClose,\n source = \"add_backend_modal\",\n}: BackendFormModalProps) {\n const { t } = useTranslation(\"openhands\");\n\n if (mode === \"add\") {\n return (\n <ModalBackdrop\n onClose={onClose}\n closeOnEscape={false}\n aria-label={t(I18nKey.BACKEND$ADD_TITLE)}\n >\n <div\n data-testid=\"add-backend-modal\"\n className={cn(\n \"relative rounded-xl border border-[var(--oh-border)] bg-base-secondary\",\n modalWidthClassName(\"xl\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n )}\n >\n <ModalCloseButton onClose={onClose} testId=\"add-backend-close\" />\n {/* Header */}\n <div className=\"px-6 pt-6 pb-2 pr-12\">\n <h2 className={modalTitleLgClassName}>\n {t(I18nKey.BACKEND$ADD_TITLE)}\n </h2>\n </div>\n\n <div className=\"px-6 pb-6 pt-2\">\n <AddBackendConnectionOptions onClose={onClose} source={source} />\n </div>\n </div>\n </ModalBackdrop>\n );\n }\n\n // Edit mode — single-column form (unchanged)\n const testIdRoot = \"edit-backend\";\n return (\n <ModalBackdrop\n onClose={onClose}\n closeOnEscape={false}\n aria-label={t(I18nKey.BACKEND$EDIT_TITLE)}\n >\n <div\n data-testid={`${testIdRoot}-modal`}\n className={cn(\n \"relative bg-base-secondary p-6 rounded-xl flex flex-col gap-4 border border-[var(--oh-border)]\",\n modalWidthClassName(\"md\"),\n )}\n >\n <ModalCloseButton onClose={onClose} testId={`${testIdRoot}-close`} />\n <h2 className={cn(\"pr-6\", modalTitleLgClassName)}>\n {t(I18nKey.BACKEND$EDIT_TITLE)}\n </h2>\n <BackendForm\n mode=\"edit\"\n backend={backend}\n onSubmitted={onClose}\n testIdRoot={testIdRoot}\n />\n </div>\n </ModalBackdrop>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../node_modules/lucide-react/dist/esm/icons/pencil.cjs`),r=require(`../../../node_modules/lucide-react/dist/esm/icons/refresh-cw.cjs`),i=require(`../../../node_modules/lucide-react/dist/esm/icons/trash-2.cjs`),a=require(`../../../utils/utils.cjs`),o=require(`../../../hooks/query/use-backends-health.cjs`),
|
|
1
|
+
require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../node_modules/lucide-react/dist/esm/icons/pencil.cjs`),r=require(`../../../node_modules/lucide-react/dist/esm/icons/refresh-cw.cjs`),i=require(`../../../node_modules/lucide-react/dist/esm/icons/trash-2.cjs`),a=require(`../../../utils/utils.cjs`),o=require(`../../../api/agent-server-config.cjs`),s=require(`../../../hooks/query/use-backends-health.cjs`),c=require(`./backend-status-label.cjs`),l=require(`./backend-status-dot.cjs`),u=require(`./device-flow-auth.cjs`),d=require(`./backend-version.cjs`);let f=require(`react/jsx-runtime`);var p=`inline-flex cursor-pointer items-center justify-center rounded-md p-1 text-muted transition-colors hover:bg-interactive-hover hover:text-white`;function m({backend:m,health:h,orgLabel:g,onSelect:_,onEdit:v,onRemove:y,onLogin:b}){let{t:x}=e.useTranslation(`openhands`),S=s.isInvalidBackendApiKeyHealthError(h?.lastError),C=m.kind===`cloud`&&s.isCloudBackendLoggedOutHealthError(h?.lastError),w=!S&&!C&&h?.isConnected===!1&&h.lastError?h.lastError:null,T=C?x(t.I18nKey.BACKEND$LOGGED_OUT):c.getBackendStatusLabel(x,m,h),E=h?.isConnected===!0?`text-green-300`:h?.isConnected===!1?`text-red-300`:`text-[var(--oh-muted)]`,D=S?!1:h?.isConnected??null,O=h?.isConnected===!0&&!S,k=o.getLockedCloudHost();return(0,f.jsxs)(`li`,{className:`flex items-stretch`,"data-testid":`manage-backends-row-${m.name}`,children:[(0,f.jsxs)(`button`,{type:`button`,disabled:!O,onClick:_,className:a.cn(`flex min-w-0 flex-1 items-center gap-3 px-3 py-3 text-left`,O?`cursor-pointer transition-colors hover:bg-interactive-hover focus-visible:bg-interactive-hover focus-visible:outline-none`:`cursor-default`),children:[(0,f.jsx)(l.BackendStatusDot,{isConnected:D}),(0,f.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col`,children:[(0,f.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,f.jsx)(`span`,{className:`truncate text-sm text-white`,children:m.name}),(0,f.jsx)(d.BackendVersion,{backend:m})]}),g?(0,f.jsx)(`span`,{"data-testid":`manage-backends-org-${m.name}`,className:`truncate text-xs text-[var(--oh-text-secondary)]`,children:g}):null,(0,f.jsx)(`span`,{className:`truncate text-xs text-[var(--oh-muted)]`,children:m.host}),(0,f.jsx)(`span`,{"data-testid":`manage-backends-status-${m.name}`,className:a.cn(`truncate text-xs`,E),children:T}),w?(0,f.jsx)(`span`,{"data-testid":`manage-backends-status-detail-${m.name}`,title:w,className:`text-xs text-red-300/80 whitespace-normal break-words`,children:w}):null]}),(0,f.jsx)(`span`,{className:`px-2 py-1 rounded-full text-[11px] uppercase tracking-wide text-[var(--oh-text-tertiary)] bg-[var(--oh-surface)] border border-[var(--oh-border)]`,children:m.kind===`cloud`?x(t.I18nKey.BACKEND$KIND_CLOUD):x(t.I18nKey.BACKEND$KIND_LOCAL)})]}),(0,f.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2 px-3 py-3`,children:[C&&b?(0,f.jsx)(u.DeviceFlowAuth,{host:m.host,onSuccess:b,testIdRoot:`manage-backends-login-${m.id}`,idleButtonLabel:x(t.I18nKey.BACKEND$LOG_BACK_IN),idleButtonContent:(0,f.jsx)(r.RefreshCw,{className:`size-4`,strokeWidth:2,"aria-hidden":!0}),className:`w-auto`,buttonVariant:`unstyled`,buttonClassName:p,statusDisplay:`modal`}):null,!k&&(0,f.jsx)(`button`,{type:`button`,onClick:v,"aria-label":x(t.I18nKey.BACKEND$EDIT),"data-testid":`manage-backends-edit-${m.name}`,className:p,children:(0,f.jsx)(n.Pencil,{"aria-hidden":!0,className:`size-4`,strokeWidth:2})}),!k&&(0,f.jsx)(`button`,{type:`button`,onClick:y,"aria-label":x(t.I18nKey.BACKEND$REMOVE),"data-testid":`manage-backends-remove-${m.name}`,className:p,children:(0,f.jsx)(i.Trash2,{"aria-hidden":!0,className:`size-4`,strokeWidth:2})})]})]})}exports.BackendRow=m;
|
|
2
2
|
//# sourceMappingURL=backend-row.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-row.cjs","names":[],"sources":["../../../../src/components/features/backends/backend-row.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { Pencil, RefreshCw, Trash2 } from \"lucide-react\";\n\nimport { type Backend } from \"#/api/backend-registry/types\";\nimport {\n isCloudBackendLoggedOutHealthError,\n isInvalidBackendApiKeyHealthError,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { BackendVersion } from \"./backend-version\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\nimport { getBackendStatusLabel } from \"./backend-status-label\";\n\nconst ROW_ACTION_BUTTON_CLASS =\n \"inline-flex cursor-pointer items-center justify-center rounded-md p-1 text-muted transition-colors hover:bg-interactive-hover hover:text-white\";\n\ninterface BackendRowProps {\n backend: Backend;\n health: BackendHealth | undefined;\n onSelect: () => void;\n onEdit: () => void;\n onRemove: () => void;\n onLogin?: (apiKey: string) => void;\n}\n\nexport function BackendRow({\n backend,\n health,\n onSelect,\n onEdit,\n onRemove,\n onLogin,\n}: BackendRowProps) {\n const { t } = useTranslation(\"openhands\");\n const isInvalidApiKey = isInvalidBackendApiKeyHealthError(health?.lastError);\n const isCloudLoggedOut =\n backend.kind === \"cloud\" &&\n isCloudBackendLoggedOutHealthError(health?.lastError);\n const statusDetail =\n !isInvalidApiKey &&\n !isCloudLoggedOut &&\n health?.isConnected === false &&\n health.lastError\n ? health.lastError\n : null;\n const statusLabel = isCloudLoggedOut\n ? t(I18nKey.BACKEND$LOGGED_OUT)\n : getBackendStatusLabel(t, backend, health);\n const statusClassName =\n health?.isConnected === true\n ? \"text-green-300\"\n : health?.isConnected === false\n ? \"text-red-300\"\n : \"text-[var(--oh-muted)]\";\n const dotStatus = isInvalidApiKey ? false : (health?.isConnected ?? null);\n const canSelect = health?.isConnected === true && !isInvalidApiKey;\n\n return (\n <li\n className=\"flex items-stretch\"\n data-testid={`manage-backends-row-${backend.name}`}\n >\n <button\n type=\"button\"\n disabled={!canSelect}\n onClick={onSelect}\n className={cn(\n \"flex min-w-0 flex-1 items-center gap-3 px-3 py-3 text-left\",\n canSelect\n ? \"cursor-pointer transition-colors hover:bg-interactive-hover focus-visible:bg-interactive-hover focus-visible:outline-none\"\n : \"cursor-default\",\n )}\n >\n <BackendStatusDot isConnected={dotStatus} />\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"truncate text-sm text-white\">{backend.name}</span>\n <BackendVersion backend={backend} />\n </div>\n <span className=\"truncate text-xs text-[var(--oh-muted)]\">\n {backend.host}\n </span>\n <span\n data-testid={`manage-backends-status-${backend.name}`}\n className={cn(\"truncate text-xs\", statusClassName)}\n >\n {statusLabel}\n </span>\n {statusDetail ? (\n <span\n data-testid={`manage-backends-status-detail-${backend.name}`}\n title={statusDetail}\n className=\"text-xs text-red-300/80 whitespace-normal break-words\"\n >\n {statusDetail}\n </span>\n ) : null}\n </div>\n <span className=\"px-2 py-1 rounded-full text-[11px] uppercase tracking-wide text-[var(--oh-text-tertiary)] bg-[var(--oh-surface)] border border-[var(--oh-border)]\">\n {backend.kind === \"cloud\"\n ? t(I18nKey.BACKEND$KIND_CLOUD)\n : t(I18nKey.BACKEND$KIND_LOCAL)}\n </span>\n </button>\n <div className=\"flex shrink-0 items-center gap-2 px-3 py-3\">\n {isCloudLoggedOut && onLogin ? (\n <DeviceFlowAuth\n host={backend.host}\n onSuccess={onLogin}\n testIdRoot={`manage-backends-login-${backend.id}`}\n idleButtonLabel={t(I18nKey.BACKEND$LOG_BACK_IN)}\n idleButtonContent={\n <RefreshCw className=\"size-4\" strokeWidth={2} aria-hidden />\n }\n className=\"w-auto\"\n buttonVariant=\"unstyled\"\n buttonClassName={ROW_ACTION_BUTTON_CLASS}\n statusDisplay=\"modal\"\n />\n ) : null}\n <button\n
|
|
1
|
+
{"version":3,"file":"backend-row.cjs","names":[],"sources":["../../../../src/components/features/backends/backend-row.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { Pencil, RefreshCw, Trash2 } from \"lucide-react\";\n\nimport { type Backend } from \"#/api/backend-registry/types\";\nimport {\n isCloudBackendLoggedOutHealthError,\n isInvalidBackendApiKeyHealthError,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { BackendVersion } from \"./backend-version\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\nimport { getBackendStatusLabel } from \"./backend-status-label\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\n\nconst ROW_ACTION_BUTTON_CLASS =\n \"inline-flex cursor-pointer items-center justify-center rounded-md p-1 text-muted transition-colors hover:bg-interactive-hover hover:text-white\";\n\ninterface BackendRowProps {\n backend: Backend;\n health: BackendHealth | undefined;\n orgLabel?: string;\n onSelect: () => void;\n onEdit: () => void;\n onRemove: () => void;\n onLogin?: (apiKey: string) => void;\n}\n\nexport function BackendRow({\n backend,\n health,\n orgLabel,\n onSelect,\n onEdit,\n onRemove,\n onLogin,\n}: BackendRowProps) {\n const { t } = useTranslation(\"openhands\");\n const isInvalidApiKey = isInvalidBackendApiKeyHealthError(health?.lastError);\n const isCloudLoggedOut =\n backend.kind === \"cloud\" &&\n isCloudBackendLoggedOutHealthError(health?.lastError);\n const statusDetail =\n !isInvalidApiKey &&\n !isCloudLoggedOut &&\n health?.isConnected === false &&\n health.lastError\n ? health.lastError\n : null;\n const statusLabel = isCloudLoggedOut\n ? t(I18nKey.BACKEND$LOGGED_OUT)\n : getBackendStatusLabel(t, backend, health);\n const statusClassName =\n health?.isConnected === true\n ? \"text-green-300\"\n : health?.isConnected === false\n ? \"text-red-300\"\n : \"text-[var(--oh-muted)]\";\n const dotStatus = isInvalidApiKey ? false : (health?.isConnected ?? null);\n const canSelect = health?.isConnected === true && !isInvalidApiKey;\n const lockedCloudHost = getLockedCloudHost();\n\n return (\n <li\n className=\"flex items-stretch\"\n data-testid={`manage-backends-row-${backend.name}`}\n >\n <button\n type=\"button\"\n disabled={!canSelect}\n onClick={onSelect}\n className={cn(\n \"flex min-w-0 flex-1 items-center gap-3 px-3 py-3 text-left\",\n canSelect\n ? \"cursor-pointer transition-colors hover:bg-interactive-hover focus-visible:bg-interactive-hover focus-visible:outline-none\"\n : \"cursor-default\",\n )}\n >\n <BackendStatusDot isConnected={dotStatus} />\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"truncate text-sm text-white\">{backend.name}</span>\n <BackendVersion backend={backend} />\n </div>\n {orgLabel ? (\n <span\n data-testid={`manage-backends-org-${backend.name}`}\n className=\"truncate text-xs text-[var(--oh-text-secondary)]\"\n >\n {orgLabel}\n </span>\n ) : null}\n <span className=\"truncate text-xs text-[var(--oh-muted)]\">\n {backend.host}\n </span>\n <span\n data-testid={`manage-backends-status-${backend.name}`}\n className={cn(\"truncate text-xs\", statusClassName)}\n >\n {statusLabel}\n </span>\n {statusDetail ? (\n <span\n data-testid={`manage-backends-status-detail-${backend.name}`}\n title={statusDetail}\n className=\"text-xs text-red-300/80 whitespace-normal break-words\"\n >\n {statusDetail}\n </span>\n ) : null}\n </div>\n <span className=\"px-2 py-1 rounded-full text-[11px] uppercase tracking-wide text-[var(--oh-text-tertiary)] bg-[var(--oh-surface)] border border-[var(--oh-border)]\">\n {backend.kind === \"cloud\"\n ? t(I18nKey.BACKEND$KIND_CLOUD)\n : t(I18nKey.BACKEND$KIND_LOCAL)}\n </span>\n </button>\n <div className=\"flex shrink-0 items-center gap-2 px-3 py-3\">\n {isCloudLoggedOut && onLogin ? (\n <DeviceFlowAuth\n host={backend.host}\n onSuccess={onLogin}\n testIdRoot={`manage-backends-login-${backend.id}`}\n idleButtonLabel={t(I18nKey.BACKEND$LOG_BACK_IN)}\n idleButtonContent={\n <RefreshCw className=\"size-4\" strokeWidth={2} aria-hidden />\n }\n className=\"w-auto\"\n buttonVariant=\"unstyled\"\n buttonClassName={ROW_ACTION_BUTTON_CLASS}\n statusDisplay=\"modal\"\n />\n ) : null}\n {!lockedCloudHost && (\n <button\n type=\"button\"\n onClick={onEdit}\n aria-label={t(I18nKey.BACKEND$EDIT)}\n data-testid={`manage-backends-edit-${backend.name}`}\n className={ROW_ACTION_BUTTON_CLASS}\n >\n <Pencil aria-hidden className=\"size-4\" strokeWidth={2} />\n </button>\n )}\n {!lockedCloudHost && (\n <button\n type=\"button\"\n onClick={onRemove}\n aria-label={t(I18nKey.BACKEND$REMOVE)}\n data-testid={`manage-backends-remove-${backend.name}`}\n className={ROW_ACTION_BUTTON_CLASS}\n >\n <Trash2 aria-hidden className=\"size-4\" strokeWidth={2} />\n </button>\n )}\n </div>\n </li>\n );\n}\n"],"mappings":"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"}
|
|
@@ -3,10 +3,11 @@ import { type BackendHealth } from "#/hooks/query/use-backends-health";
|
|
|
3
3
|
interface BackendRowProps {
|
|
4
4
|
backend: Backend;
|
|
5
5
|
health: BackendHealth | undefined;
|
|
6
|
+
orgLabel?: string;
|
|
6
7
|
onSelect: () => void;
|
|
7
8
|
onEdit: () => void;
|
|
8
9
|
onRemove: () => void;
|
|
9
10
|
onLogin?: (apiKey: string) => void;
|
|
10
11
|
}
|
|
11
|
-
export declare function BackendRow({ backend, health, onSelect, onEdit, onRemove, onLogin, }: BackendRowProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function BackendRow({ backend, health, orgLabel, onSelect, onEdit, onRemove, onLogin, }: BackendRowProps): import("react/jsx-runtime").JSX.Element;
|
|
12
13
|
export {};
|
|
@@ -4,95 +4,101 @@ import { Pencil as n } from "../../../node_modules/lucide-react/dist/esm/icons/p
|
|
|
4
4
|
import { RefreshCw as r } from "../../../node_modules/lucide-react/dist/esm/icons/refresh-cw.js";
|
|
5
5
|
import { Trash2 as i } from "../../../node_modules/lucide-react/dist/esm/icons/trash-2.js";
|
|
6
6
|
import { cn as a } from "../../../utils/utils.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
7
|
+
import { getLockedCloudHost as o } from "../../../api/agent-server-config.js";
|
|
8
|
+
import { isCloudBackendLoggedOutHealthError as s, isInvalidBackendApiKeyHealthError as c } from "../../../hooks/query/use-backends-health.js";
|
|
9
|
+
import { getBackendStatusLabel as l } from "./backend-status-label.js";
|
|
10
|
+
import { BackendStatusDot as u } from "./backend-status-dot.js";
|
|
11
|
+
import { DeviceFlowAuth as d } from "./device-flow-auth.js";
|
|
12
|
+
import { BackendVersion as f } from "./backend-version.js";
|
|
13
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
13
14
|
//#region src/components/features/backends/backend-row.tsx
|
|
14
|
-
var
|
|
15
|
-
function
|
|
16
|
-
let { t:
|
|
17
|
-
return /* @__PURE__ */
|
|
15
|
+
var h = "inline-flex cursor-pointer items-center justify-center rounded-md p-1 text-muted transition-colors hover:bg-interactive-hover hover:text-white";
|
|
16
|
+
function g({ backend: g, health: _, orgLabel: v, onSelect: y, onEdit: b, onRemove: x, onLogin: S }) {
|
|
17
|
+
let { t: C } = e("openhands"), w = c(_?.lastError), T = g.kind === "cloud" && s(_?.lastError), E = !w && !T && _?.isConnected === !1 && _.lastError ? _.lastError : null, D = T ? C(t.BACKEND$LOGGED_OUT) : l(C, g, _), O = _?.isConnected === !0 ? "text-green-300" : _?.isConnected === !1 ? "text-red-300" : "text-[var(--oh-muted)]", k = w ? !1 : _?.isConnected ?? null, A = _?.isConnected === !0 && !w, j = o();
|
|
18
|
+
return /* @__PURE__ */ m("li", {
|
|
18
19
|
className: "flex items-stretch",
|
|
19
|
-
"data-testid": `manage-backends-row-${
|
|
20
|
-
children: [/* @__PURE__ */
|
|
20
|
+
"data-testid": `manage-backends-row-${g.name}`,
|
|
21
|
+
children: [/* @__PURE__ */ m("button", {
|
|
21
22
|
type: "button",
|
|
22
|
-
disabled: !
|
|
23
|
-
onClick:
|
|
24
|
-
className: a("flex min-w-0 flex-1 items-center gap-3 px-3 py-3 text-left",
|
|
23
|
+
disabled: !A,
|
|
24
|
+
onClick: y,
|
|
25
|
+
className: a("flex min-w-0 flex-1 items-center gap-3 px-3 py-3 text-left", A ? "cursor-pointer transition-colors hover:bg-interactive-hover focus-visible:bg-interactive-hover focus-visible:outline-none" : "cursor-default"),
|
|
25
26
|
children: [
|
|
26
|
-
/* @__PURE__ */
|
|
27
|
-
/* @__PURE__ */
|
|
27
|
+
/* @__PURE__ */ p(u, { isConnected: k }),
|
|
28
|
+
/* @__PURE__ */ m("div", {
|
|
28
29
|
className: "flex min-w-0 flex-1 flex-col",
|
|
29
30
|
children: [
|
|
30
|
-
/* @__PURE__ */
|
|
31
|
+
/* @__PURE__ */ m("div", {
|
|
31
32
|
className: "flex min-w-0 items-center gap-2",
|
|
32
|
-
children: [/* @__PURE__ */
|
|
33
|
+
children: [/* @__PURE__ */ p("span", {
|
|
33
34
|
className: "truncate text-sm text-white",
|
|
34
|
-
children:
|
|
35
|
-
}), /* @__PURE__ */ f
|
|
35
|
+
children: g.name
|
|
36
|
+
}), /* @__PURE__ */ p(f, { backend: g })]
|
|
36
37
|
}),
|
|
37
|
-
/* @__PURE__ */
|
|
38
|
+
v ? /* @__PURE__ */ p("span", {
|
|
39
|
+
"data-testid": `manage-backends-org-${g.name}`,
|
|
40
|
+
className: "truncate text-xs text-[var(--oh-text-secondary)]",
|
|
41
|
+
children: v
|
|
42
|
+
}) : null,
|
|
43
|
+
/* @__PURE__ */ p("span", {
|
|
38
44
|
className: "truncate text-xs text-[var(--oh-muted)]",
|
|
39
|
-
children:
|
|
45
|
+
children: g.host
|
|
40
46
|
}),
|
|
41
|
-
/* @__PURE__ */
|
|
42
|
-
"data-testid": `manage-backends-status-${
|
|
43
|
-
className: a("truncate text-xs",
|
|
44
|
-
children:
|
|
47
|
+
/* @__PURE__ */ p("span", {
|
|
48
|
+
"data-testid": `manage-backends-status-${g.name}`,
|
|
49
|
+
className: a("truncate text-xs", O),
|
|
50
|
+
children: D
|
|
45
51
|
}),
|
|
46
|
-
|
|
47
|
-
"data-testid": `manage-backends-status-detail-${
|
|
48
|
-
title:
|
|
52
|
+
E ? /* @__PURE__ */ p("span", {
|
|
53
|
+
"data-testid": `manage-backends-status-detail-${g.name}`,
|
|
54
|
+
title: E,
|
|
49
55
|
className: "text-xs text-red-300/80 whitespace-normal break-words",
|
|
50
|
-
children:
|
|
56
|
+
children: E
|
|
51
57
|
}) : null
|
|
52
58
|
]
|
|
53
59
|
}),
|
|
54
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ p("span", {
|
|
55
61
|
className: "px-2 py-1 rounded-full text-[11px] uppercase tracking-wide text-[var(--oh-text-tertiary)] bg-[var(--oh-surface)] border border-[var(--oh-border)]",
|
|
56
|
-
children:
|
|
62
|
+
children: g.kind === "cloud" ? C(t.BACKEND$KIND_CLOUD) : C(t.BACKEND$KIND_LOCAL)
|
|
57
63
|
})
|
|
58
64
|
]
|
|
59
|
-
}), /* @__PURE__ */
|
|
65
|
+
}), /* @__PURE__ */ m("div", {
|
|
60
66
|
className: "flex shrink-0 items-center gap-2 px-3 py-3",
|
|
61
67
|
children: [
|
|
62
|
-
|
|
63
|
-
host:
|
|
64
|
-
onSuccess:
|
|
65
|
-
testIdRoot: `manage-backends-login-${
|
|
66
|
-
idleButtonLabel:
|
|
67
|
-
idleButtonContent: /* @__PURE__ */
|
|
68
|
+
T && S ? /* @__PURE__ */ p(d, {
|
|
69
|
+
host: g.host,
|
|
70
|
+
onSuccess: S,
|
|
71
|
+
testIdRoot: `manage-backends-login-${g.id}`,
|
|
72
|
+
idleButtonLabel: C(t.BACKEND$LOG_BACK_IN),
|
|
73
|
+
idleButtonContent: /* @__PURE__ */ p(r, {
|
|
68
74
|
className: "size-4",
|
|
69
75
|
strokeWidth: 2,
|
|
70
76
|
"aria-hidden": !0
|
|
71
77
|
}),
|
|
72
78
|
className: "w-auto",
|
|
73
79
|
buttonVariant: "unstyled",
|
|
74
|
-
buttonClassName:
|
|
80
|
+
buttonClassName: h,
|
|
75
81
|
statusDisplay: "modal"
|
|
76
82
|
}) : null,
|
|
77
|
-
/* @__PURE__ */
|
|
83
|
+
!j && /* @__PURE__ */ p("button", {
|
|
78
84
|
type: "button",
|
|
79
|
-
onClick:
|
|
80
|
-
"aria-label":
|
|
81
|
-
"data-testid": `manage-backends-edit-${
|
|
82
|
-
className:
|
|
83
|
-
children: /* @__PURE__ */
|
|
85
|
+
onClick: b,
|
|
86
|
+
"aria-label": C(t.BACKEND$EDIT),
|
|
87
|
+
"data-testid": `manage-backends-edit-${g.name}`,
|
|
88
|
+
className: h,
|
|
89
|
+
children: /* @__PURE__ */ p(n, {
|
|
84
90
|
"aria-hidden": !0,
|
|
85
91
|
className: "size-4",
|
|
86
92
|
strokeWidth: 2
|
|
87
93
|
})
|
|
88
94
|
}),
|
|
89
|
-
/* @__PURE__ */
|
|
95
|
+
!j && /* @__PURE__ */ p("button", {
|
|
90
96
|
type: "button",
|
|
91
|
-
onClick:
|
|
92
|
-
"aria-label":
|
|
93
|
-
"data-testid": `manage-backends-remove-${
|
|
94
|
-
className:
|
|
95
|
-
children: /* @__PURE__ */
|
|
97
|
+
onClick: x,
|
|
98
|
+
"aria-label": C(t.BACKEND$REMOVE),
|
|
99
|
+
"data-testid": `manage-backends-remove-${g.name}`,
|
|
100
|
+
className: h,
|
|
101
|
+
children: /* @__PURE__ */ p(i, {
|
|
96
102
|
"aria-hidden": !0,
|
|
97
103
|
className: "size-4",
|
|
98
104
|
strokeWidth: 2
|
|
@@ -103,6 +109,6 @@ function h({ backend: h, health: g, onSelect: _, onEdit: v, onRemove: y, onLogin
|
|
|
103
109
|
});
|
|
104
110
|
}
|
|
105
111
|
//#endregion
|
|
106
|
-
export {
|
|
112
|
+
export { g as BackendRow };
|
|
107
113
|
|
|
108
114
|
//# sourceMappingURL=backend-row.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-row.js","names":[],"sources":["../../../../src/components/features/backends/backend-row.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { Pencil, RefreshCw, Trash2 } from \"lucide-react\";\n\nimport { type Backend } from \"#/api/backend-registry/types\";\nimport {\n isCloudBackendLoggedOutHealthError,\n isInvalidBackendApiKeyHealthError,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { BackendVersion } from \"./backend-version\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\nimport { getBackendStatusLabel } from \"./backend-status-label\";\n\nconst ROW_ACTION_BUTTON_CLASS =\n \"inline-flex cursor-pointer items-center justify-center rounded-md p-1 text-muted transition-colors hover:bg-interactive-hover hover:text-white\";\n\ninterface BackendRowProps {\n backend: Backend;\n health: BackendHealth | undefined;\n onSelect: () => void;\n onEdit: () => void;\n onRemove: () => void;\n onLogin?: (apiKey: string) => void;\n}\n\nexport function BackendRow({\n backend,\n health,\n onSelect,\n onEdit,\n onRemove,\n onLogin,\n}: BackendRowProps) {\n const { t } = useTranslation(\"openhands\");\n const isInvalidApiKey = isInvalidBackendApiKeyHealthError(health?.lastError);\n const isCloudLoggedOut =\n backend.kind === \"cloud\" &&\n isCloudBackendLoggedOutHealthError(health?.lastError);\n const statusDetail =\n !isInvalidApiKey &&\n !isCloudLoggedOut &&\n health?.isConnected === false &&\n health.lastError\n ? health.lastError\n : null;\n const statusLabel = isCloudLoggedOut\n ? t(I18nKey.BACKEND$LOGGED_OUT)\n : getBackendStatusLabel(t, backend, health);\n const statusClassName =\n health?.isConnected === true\n ? \"text-green-300\"\n : health?.isConnected === false\n ? \"text-red-300\"\n : \"text-[var(--oh-muted)]\";\n const dotStatus = isInvalidApiKey ? false : (health?.isConnected ?? null);\n const canSelect = health?.isConnected === true && !isInvalidApiKey;\n\n return (\n <li\n className=\"flex items-stretch\"\n data-testid={`manage-backends-row-${backend.name}`}\n >\n <button\n type=\"button\"\n disabled={!canSelect}\n onClick={onSelect}\n className={cn(\n \"flex min-w-0 flex-1 items-center gap-3 px-3 py-3 text-left\",\n canSelect\n ? \"cursor-pointer transition-colors hover:bg-interactive-hover focus-visible:bg-interactive-hover focus-visible:outline-none\"\n : \"cursor-default\",\n )}\n >\n <BackendStatusDot isConnected={dotStatus} />\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"truncate text-sm text-white\">{backend.name}</span>\n <BackendVersion backend={backend} />\n </div>\n <span className=\"truncate text-xs text-[var(--oh-muted)]\">\n {backend.host}\n </span>\n <span\n data-testid={`manage-backends-status-${backend.name}`}\n className={cn(\"truncate text-xs\", statusClassName)}\n >\n {statusLabel}\n </span>\n {statusDetail ? (\n <span\n data-testid={`manage-backends-status-detail-${backend.name}`}\n title={statusDetail}\n className=\"text-xs text-red-300/80 whitespace-normal break-words\"\n >\n {statusDetail}\n </span>\n ) : null}\n </div>\n <span className=\"px-2 py-1 rounded-full text-[11px] uppercase tracking-wide text-[var(--oh-text-tertiary)] bg-[var(--oh-surface)] border border-[var(--oh-border)]\">\n {backend.kind === \"cloud\"\n ? t(I18nKey.BACKEND$KIND_CLOUD)\n : t(I18nKey.BACKEND$KIND_LOCAL)}\n </span>\n </button>\n <div className=\"flex shrink-0 items-center gap-2 px-3 py-3\">\n {isCloudLoggedOut && onLogin ? (\n <DeviceFlowAuth\n host={backend.host}\n onSuccess={onLogin}\n testIdRoot={`manage-backends-login-${backend.id}`}\n idleButtonLabel={t(I18nKey.BACKEND$LOG_BACK_IN)}\n idleButtonContent={\n <RefreshCw className=\"size-4\" strokeWidth={2} aria-hidden />\n }\n className=\"w-auto\"\n buttonVariant=\"unstyled\"\n buttonClassName={ROW_ACTION_BUTTON_CLASS}\n statusDisplay=\"modal\"\n />\n ) : null}\n <button\n
|
|
1
|
+
{"version":3,"file":"backend-row.js","names":[],"sources":["../../../../src/components/features/backends/backend-row.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { Pencil, RefreshCw, Trash2 } from \"lucide-react\";\n\nimport { type Backend } from \"#/api/backend-registry/types\";\nimport {\n isCloudBackendLoggedOutHealthError,\n isInvalidBackendApiKeyHealthError,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { BackendVersion } from \"./backend-version\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\nimport { getBackendStatusLabel } from \"./backend-status-label\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\n\nconst ROW_ACTION_BUTTON_CLASS =\n \"inline-flex cursor-pointer items-center justify-center rounded-md p-1 text-muted transition-colors hover:bg-interactive-hover hover:text-white\";\n\ninterface BackendRowProps {\n backend: Backend;\n health: BackendHealth | undefined;\n orgLabel?: string;\n onSelect: () => void;\n onEdit: () => void;\n onRemove: () => void;\n onLogin?: (apiKey: string) => void;\n}\n\nexport function BackendRow({\n backend,\n health,\n orgLabel,\n onSelect,\n onEdit,\n onRemove,\n onLogin,\n}: BackendRowProps) {\n const { t } = useTranslation(\"openhands\");\n const isInvalidApiKey = isInvalidBackendApiKeyHealthError(health?.lastError);\n const isCloudLoggedOut =\n backend.kind === \"cloud\" &&\n isCloudBackendLoggedOutHealthError(health?.lastError);\n const statusDetail =\n !isInvalidApiKey &&\n !isCloudLoggedOut &&\n health?.isConnected === false &&\n health.lastError\n ? health.lastError\n : null;\n const statusLabel = isCloudLoggedOut\n ? t(I18nKey.BACKEND$LOGGED_OUT)\n : getBackendStatusLabel(t, backend, health);\n const statusClassName =\n health?.isConnected === true\n ? \"text-green-300\"\n : health?.isConnected === false\n ? \"text-red-300\"\n : \"text-[var(--oh-muted)]\";\n const dotStatus = isInvalidApiKey ? false : (health?.isConnected ?? null);\n const canSelect = health?.isConnected === true && !isInvalidApiKey;\n const lockedCloudHost = getLockedCloudHost();\n\n return (\n <li\n className=\"flex items-stretch\"\n data-testid={`manage-backends-row-${backend.name}`}\n >\n <button\n type=\"button\"\n disabled={!canSelect}\n onClick={onSelect}\n className={cn(\n \"flex min-w-0 flex-1 items-center gap-3 px-3 py-3 text-left\",\n canSelect\n ? \"cursor-pointer transition-colors hover:bg-interactive-hover focus-visible:bg-interactive-hover focus-visible:outline-none\"\n : \"cursor-default\",\n )}\n >\n <BackendStatusDot isConnected={dotStatus} />\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"truncate text-sm text-white\">{backend.name}</span>\n <BackendVersion backend={backend} />\n </div>\n {orgLabel ? (\n <span\n data-testid={`manage-backends-org-${backend.name}`}\n className=\"truncate text-xs text-[var(--oh-text-secondary)]\"\n >\n {orgLabel}\n </span>\n ) : null}\n <span className=\"truncate text-xs text-[var(--oh-muted)]\">\n {backend.host}\n </span>\n <span\n data-testid={`manage-backends-status-${backend.name}`}\n className={cn(\"truncate text-xs\", statusClassName)}\n >\n {statusLabel}\n </span>\n {statusDetail ? (\n <span\n data-testid={`manage-backends-status-detail-${backend.name}`}\n title={statusDetail}\n className=\"text-xs text-red-300/80 whitespace-normal break-words\"\n >\n {statusDetail}\n </span>\n ) : null}\n </div>\n <span className=\"px-2 py-1 rounded-full text-[11px] uppercase tracking-wide text-[var(--oh-text-tertiary)] bg-[var(--oh-surface)] border border-[var(--oh-border)]\">\n {backend.kind === \"cloud\"\n ? t(I18nKey.BACKEND$KIND_CLOUD)\n : t(I18nKey.BACKEND$KIND_LOCAL)}\n </span>\n </button>\n <div className=\"flex shrink-0 items-center gap-2 px-3 py-3\">\n {isCloudLoggedOut && onLogin ? (\n <DeviceFlowAuth\n host={backend.host}\n onSuccess={onLogin}\n testIdRoot={`manage-backends-login-${backend.id}`}\n idleButtonLabel={t(I18nKey.BACKEND$LOG_BACK_IN)}\n idleButtonContent={\n <RefreshCw className=\"size-4\" strokeWidth={2} aria-hidden />\n }\n className=\"w-auto\"\n buttonVariant=\"unstyled\"\n buttonClassName={ROW_ACTION_BUTTON_CLASS}\n statusDisplay=\"modal\"\n />\n ) : null}\n {!lockedCloudHost && (\n <button\n type=\"button\"\n onClick={onEdit}\n aria-label={t(I18nKey.BACKEND$EDIT)}\n data-testid={`manage-backends-edit-${backend.name}`}\n className={ROW_ACTION_BUTTON_CLASS}\n >\n <Pencil aria-hidden className=\"size-4\" strokeWidth={2} />\n </button>\n )}\n {!lockedCloudHost && (\n <button\n type=\"button\"\n onClick={onRemove}\n aria-label={t(I18nKey.BACKEND$REMOVE)}\n data-testid={`manage-backends-remove-${backend.name}`}\n className={ROW_ACTION_BUTTON_CLASS}\n >\n <Trash2 aria-hidden className=\"size-4\" strokeWidth={2} />\n </button>\n )}\n </div>\n </li>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAiBA,IAAM,IACJ;AAYF,SAAgB,EAAW,EACzB,YACA,WACA,aACA,aACA,WACA,aACA,cACkB;CAClB,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,IAAkB,EAAkC,GAAQ,UAAU,EACtE,IACJ,EAAQ,SAAS,WACjB,EAAmC,GAAQ,UAAU,EACjD,IACJ,CAAC,KACD,CAAC,KACD,GAAQ,gBAAgB,MACxB,EAAO,YACH,EAAO,YACP,MACA,IAAc,IAChB,EAAE,EAAQ,mBAAmB,GAC7B,EAAsB,GAAG,GAAS,EAAO,EACvC,IACJ,GAAQ,gBAAgB,KACpB,mBACA,GAAQ,gBAAgB,KACtB,iBACA,0BACF,IAAY,IAAkB,KAAS,GAAQ,eAAe,MAC9D,IAAY,GAAQ,gBAAgB,MAAQ,CAAC,GAC7C,IAAkB,GAAoB;AAE5C,QACE,kBAAC,MAAD;EACE,WAAU;EACV,eAAa,uBAAuB,EAAQ;YAF9C,CAIE,kBAAC,UAAD;GACE,MAAK;GACL,UAAU,CAAC;GACX,SAAS;GACT,WAAW,EACT,8DACA,IACI,8HACA,iBACL;aATH;IAWE,kBAAC,GAAD,EAAkB,aAAa,GAAa,CAAA;IAC5C,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QAAM,WAAU;kBAA+B,EAAQ;QAAY,CAAA,EACnE,kBAAC,GAAD,EAAyB,YAAW,CAAA,CAChC;;MACL,IACC,kBAAC,QAAD;OACE,eAAa,uBAAuB,EAAQ;OAC5C,WAAU;iBAET;OACI,CAAA,GACL;MACJ,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAQ;OACJ,CAAA;MACP,kBAAC,QAAD;OACE,eAAa,0BAA0B,EAAQ;OAC/C,WAAW,EAAG,oBAAoB,EAAgB;iBAEjD;OACI,CAAA;MACN,IACC,kBAAC,QAAD;OACE,eAAa,iCAAiC,EAAQ;OACtD,OAAO;OACP,WAAU;iBAET;OACI,CAAA,GACL;MACA;;IACN,kBAAC,QAAD;KAAM,WAAU;eACb,EAAQ,SAAS,UACd,EAAE,EAAQ,mBAAmB,GAC7B,EAAE,EAAQ,mBAAmB;KAC5B,CAAA;IACA;MACT,kBAAC,OAAD;GAAK,WAAU;aAAf;IACG,KAAoB,IACnB,kBAAC,GAAD;KACE,MAAM,EAAQ;KACd,WAAW;KACX,YAAY,yBAAyB,EAAQ;KAC7C,iBAAiB,EAAE,EAAQ,oBAAoB;KAC/C,mBACE,kBAAC,GAAD;MAAW,WAAU;MAAS,aAAa;MAAG,eAAA;MAAc,CAAA;KAE9D,WAAU;KACV,eAAc;KACd,iBAAiB;KACjB,eAAc;KACd,CAAA,GACA;IACH,CAAC,KACA,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,cAAY,EAAE,EAAQ,aAAa;KACnC,eAAa,wBAAwB,EAAQ;KAC7C,WAAW;eAEX,kBAAC,GAAD;MAAQ,eAAA;MAAY,WAAU;MAAS,aAAa;MAAK,CAAA;KAClD,CAAA;IAEV,CAAC,KACA,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,cAAY,EAAE,EAAQ,eAAe;KACrC,eAAa,0BAA0B,EAAQ;KAC/C,WAAW;eAEX,kBAAC,GAAD;MAAQ,eAAA;MAAY,WAAU;MAAS,aAAa;MAAK,CAAA;KAClD,CAAA;IAEP;KACH"}
|
|
@@ -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(`../../../node_modules/lucide-react/dist/esm/icons/plus.cjs`),i=require(`../../../node_modules/lucide-react/dist/esm/icons/settings.cjs`),a=require(`../../../utils/utils.cjs`),o=require(`../../../stores/conversation-store.cjs`),s=require(`../../../api/backend-registry/active-store.cjs`),c=require(`../../../contexts/active-backend-context.cjs`),
|
|
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/plus.cjs`),i=require(`../../../node_modules/lucide-react/dist/esm/icons/settings.cjs`),a=require(`../../../utils/utils.cjs`),o=require(`../../../stores/conversation-store.cjs`),s=require(`../../../api/backend-registry/active-store.cjs`),c=require(`../../../contexts/active-backend-context.cjs`),l=require(`../../../utils/form-control-classes.cjs`),u=require(`../../shared/buttons/styled-tooltip.cjs`),d=require(`../../../utils/dropdown-classes.cjs`),f=require(`../../shared/navigation-link.cjs`),ee=require(`../../../hooks/query/use-cloud-organizations.cjs`),te=require(`../../../hooks/query/use-cloud-current-user-id.cjs`),p=require(`../../../ui/dropdown/dropdown.cjs`),m=require(`../../../hooks/query/use-backends-health.cjs`),h=require(`./environment-switch-store.cjs`),g=require(`./backend-status-dot.cjs`),ne=require(`./add-backend-modal.cjs`),re=require(`./manage-backends-modal.cjs`);let _=require(`react`);_=e.__toESM(_,1);let v=require(`react/jsx-runtime`),y=require(`react-router`);var b=`::`;function x(e,t){return t?`${e}${b}${t}`:e}function S(e){let[t,n]=e.split(b);return{backendId:t,orgId:n??null}}function C(e){return(0,v.jsx)(g.BackendStatusDot,{isConnected:e?.isConnected??null})}function ie(){return(0,v.jsx)(g.BackendStatusDot,{isConnected:`unavailable`})}function w(e,t,n,r,i){let a=[],o=e.filter(e=>e.kind===`local`),s=e.filter(e=>e.kind===`cloud`);for(let e of o)a.push({value:x(e.id,null),label:e.name,prefix:C(i[e.id])});for(let e of s){let o=n[e.id],s=C(i[e.id]);if(!o||o.orgs.length===0)a.push({value:x(e.id,null),label:e.name,prefix:s});else{let n=r[e.id]?.userId??null;for(let r of o.orgs){let i=n&&n===r.id?t:r.name;a.push({value:x(e.id,r.id),label:`${e.name} – ${i}`,prefix:s})}}}return a}function T({openUpward:e=!1,hideTrigger:g=!1,defaultOpen:b=!1,onSelectOption:T,onOpenAddBackend:E,onOpenManageBackends:D,sidebarCollapsed:O=!1}={}){let{t:k}=t.useTranslation(`openhands`),{backends:A,active:j,setActive:M}=c.useActiveBackendContext(),N=ee.useAllCloudOrganizations(),P=te.useCloudCurrentUserId(),F=m.useBackendsHealth(A),I=(0,y.useNavigate)(),ae=(0,y.useMatch)(`/settings`),oe=(0,y.useMatch)(`/settings/*`),L=(0,y.useMatch)(`/conversations/:conversationId`),R=(0,y.useMatch)(`/automations/:automationId`),[z,B]=_.default.useState(!1),[V,H]=_.default.useState(!1),U=k(n.I18nKey.BACKEND$PERSONAL_WORKSPACE),W=_.default.useMemo(()=>w(A,U,N,P,F),[A,U,N,P,F]),G=s.isNoBackend(j.backend),K=k(n.I18nKey.BACKEND$NO_BACKEND_AVAILABLE),q=x(j.backend.id,j.orgId),J=G?void 0:W.find(e=>e.value===q),Y=!!(ae||oe),X=k(n.I18nKey.SIDEBAR$SETTINGS),se=o.useConversationStore(e=>e.isRightPanelShown),ce=!O||L&&se?`top`:`left`,le=Object.values(N).some(e=>e.isLoading);_.default.useEffect(()=>{if(G||j.backend.kind!==`cloud`||j.orgId)return;let{backend:e}=j,t=N[e.id];if(!t||t.orgs.length===0)return;let n=P[e.id]?.userId??null,r=(n?t.orgs.find(e=>e.id===n):void 0)??t.orgs[0];r&&M(e.id,r.id)},[j,N,P,M,G]);let Z=_.default.useCallback(()=>{if(E){E(),T?.();return}B(!0)},[E,T]),Q=_.default.useCallback(()=>{if(D){D(),T?.();return}H(!0)},[D,T]),$=_.default.useCallback(e=>{e.preventDefault(),e.stopPropagation()},[]),ue=_.default.useCallback(e=>{$(e),Z()},[Z,$]),de=_.default.useCallback(e=>{$(e),Z()},[Z,$]),fe=_.default.useCallback(e=>{$(e),Q()},[Q,$]),pe=_.default.useCallback(e=>{$(e),Q()},[Q,$]),me=(0,v.jsxs)(`div`,{className:d.dropdownMenuListClassName,children:[(0,v.jsxs)(`button`,{type:`button`,"data-testid":`add-backend-menu-item`,onMouseDown:$,onTouchStart:$,onTouchEnd:de,onClick:ue,className:a.cn(d.dropdownFooterActionClassName,`cursor-pointer rounded-md`),children:[(0,v.jsx)(`span`,{className:d.dropdownMenuRowIconWrapperClassName,"aria-hidden":!0,children:(0,v.jsx)(r.Plus,{width:16,height:16})}),k(n.I18nKey.BACKEND$ADD)]}),(0,v.jsxs)(`button`,{type:`button`,"data-testid":`manage-backends-menu-item`,onMouseDown:$,onTouchStart:$,onTouchEnd:pe,onClick:fe,className:a.cn(d.dropdownFooterActionClassName,`cursor-pointer rounded-md`),children:[(0,v.jsx)(`span`,{className:d.dropdownMenuRowIconWrapperClassName,"aria-hidden":!0,children:(0,v.jsx)(i.Settings,{width:16,height:16})}),k(n.I18nKey.BACKEND$MANAGE)]})]}),he=_.default.useCallback(async e=>{if(e===q)return;let{backendId:t,orgId:n}=S(e),r=A.find(e=>e.id===t);r&&(h.triggerEnvironmentSwitch(W.find(t=>t.value===e)?.label??r.name),await new Promise(e=>{setTimeout(e,400)}),L?I(`/conversations`):R&&I(`/automations`),M(r.id,n),T?.())},[q,A,L,R,I,W,M,k,T]);return(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2 w-full`,children:[(0,v.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,v.jsx)(p.Dropdown,{testId:`backend-selector`,defaultValue:J??{value:q,label:G?K:j.backend.name,prefix:G?ie():C(F[j.backend.id])},footer:me,openUpward:e,hideTrigger:g,defaultOpen:b,openOnHover:!g,onChange:e=>{e&&he(e.value)},placeholder:G?K:j.backend.name,loading:le,options:W,className:`h-10 px-2 py-0 bg-transparent border-transparent hover:bg-[var(--oh-surface-raised)] focus-within:bg-[var(--oh-surface-raised)] focus-within:border-transparent focus-within:ring-0`},`${q}-${J?.label??``}`)}),g?null:(0,v.jsx)(u.StyledTooltip,{content:X,placement:ce,offset:10,children:(0,v.jsx)(f.NavigationLink,{to:`/settings`,"data-testid":`backend-selector-settings-link`,"data-active":Y,"aria-label":X,className:Y?a.cn(`inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md bg-tertiary text-white font-normal cursor-pointer`,l.formControlTransitionClassName):a.cn(`inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer`,l.formControlTransitionClassName),children:(0,v.jsx)(i.Settings,{width:16,height:16})})})]}),z?(0,v.jsx)(ne.AddBackendModal,{onClose:()=>B(!1)}):null,V?(0,v.jsx)(re.ManageBackendsModal,{onClose:()=>H(!1)}):null]})}exports.BackendSelector=T;
|
|
2
2
|
//# sourceMappingURL=backend-selector.cjs.map
|