@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":"telemetry-consent-banner.js","names":[],"sources":["../../../../src/components/features/analytics/telemetry-consent-banner.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useTelemetry } from \"#/hooks/use-telemetry\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport {\n BaseModalTitle,\n BaseModalDescription,\n} from \"#/components/shared/modals/confirmation-modals/base-modal\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\n\ninterface TelemetryConsentBannerProps {\n /** Called after user makes a choice */\n onChoice?: (granted: boolean) => void;\n}\n\n/**\n * A consent modal for telemetry/analytics that appears on first use.\n *\n * This component:\n * - Shows as a full-screen modal overlay when consent is pending\n * - Waits for translations to load before displaying (prevents key flashing)\n * - Allows users to accept or decline tracking via checkbox\n * - Respects DO_NOT_TRACK environment variable\n * - Persists choice in localStorage\n * - Styled to match the OpenHands analytics consent modal\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <>\n * <TelemetryConsentBanner />\n * <MainContent />\n * </>\n * );\n * }\n * ```\n */\nexport function TelemetryConsentBanner({\n onChoice,\n}: TelemetryConsentBannerProps) {\n const { t, ready } = useTranslation(\"openhands\");\n const { showConsentPrompt, grantConsent, denyConsent } = useTelemetry();\n\n // Delay showing the modal slightly to ensure smooth rendering\n // This prevents the modal from flashing during initial hydration\n const [isReady, setIsReady] = useState(false);\n useEffect(() => {\n if (ready && showConsentPrompt) {\n // Small delay to ensure DOM is fully hydrated and translations loaded\n const timer = setTimeout(() => setIsReady(true), 50);\n return () => clearTimeout(timer);\n }\n setIsReady(false);\n return undefined;\n }, [ready, showConsentPrompt]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const formData = new FormData(e.currentTarget);\n const analytics = formData.get(\"analytics\") === \"on\";\n\n if (analytics) {\n grantConsent();\n } else {\n denyConsent();\n }\n onChoice?.(analytics);\n };\n\n // Don't render until translations are ready and component has stabilized\n if (!isReady) {\n return null;\n }\n\n return (\n <ModalBackdrop aria-label={t(I18nKey.TELEMETRY$CONSENT_TITLE)}>\n <form\n data-testid=\"telemetry-consent-form\"\n onSubmit={handleSubmit}\n className=\"flex flex-col gap-2\"\n >\n <ModalBody className=\"border border-[var(--oh-border)]\">\n <BaseModalTitle title={t(I18nKey.TELEMETRY$CONSENT_TITLE)} />\n <BaseModalDescription>\n {t(I18nKey.TELEMETRY$CONSENT_DESCRIPTION)}\n </BaseModalDescription>\n\n <label className=\"flex gap-2 items-center self-start text-sm cursor-pointer\">\n <input\n name=\"analytics\"\n type=\"checkbox\"\n defaultChecked\n className=\"w-4 h-4 cursor-pointer\"\n />\n {t(I18nKey.TELEMETRY$SEND_ANONYMOUS_DATA)}\n </label>\n\n <BrandButton\n testId=\"confirm-telemetry-preferences\"\n type=\"submit\"\n variant=\"primary\"\n className=\"w-full\"\n >\n {t(I18nKey.TELEMETRY$CONFIRM_PREFERENCES)}\n </BrandButton>\n </ModalBody>\n </form>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;AAwCA,SAAgB,EAAuB,EACrC,eAC8B;CAC9B,IAAM,EAAE,MAAG,aAAU,EAAe,YAAY,EAC1C,EAAE,sBAAmB,iBAAc,mBAAgB,GAAc,EAIjE,CAAC,GAAS,KAAc,EAAS,GAAM;AA6B7C,QA5BA,QAAgB;AACd,MAAI,KAAS,GAAmB;GAE9B,IAAM,IAAQ,iBAAiB,EAAW,GAAK,EAAE,GAAG;AACpD,gBAAa,aAAa,EAAM;;AAElC,IAAW,GAAM;IAEhB,CAAC,GAAO,EAAkB,CAAC,EAgBzB,IAKH,kBAAC,GAAD;EAAe,cAAY,EAAE,EAAQ,wBAAwB;
|
|
1
|
+
{"version":3,"file":"telemetry-consent-banner.js","names":[],"sources":["../../../../src/components/features/analytics/telemetry-consent-banner.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useTelemetry } from \"#/hooks/use-telemetry\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport {\n BaseModalTitle,\n BaseModalDescription,\n} from \"#/components/shared/modals/confirmation-modals/base-modal\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\n\ninterface TelemetryConsentBannerProps {\n /** Called after user makes a choice */\n onChoice?: (granted: boolean) => void;\n}\n\n/**\n * A consent modal for telemetry/analytics that appears on first use.\n *\n * This component:\n * - Shows as a full-screen modal overlay when consent is pending\n * - Waits for translations to load before displaying (prevents key flashing)\n * - Allows users to accept or decline tracking via checkbox\n * - Respects DO_NOT_TRACK environment variable\n * - Persists choice in localStorage\n * - Styled to match the OpenHands analytics consent modal\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <>\n * <TelemetryConsentBanner />\n * <MainContent />\n * </>\n * );\n * }\n * ```\n */\nexport function TelemetryConsentBanner({\n onChoice,\n}: TelemetryConsentBannerProps) {\n const { t, ready } = useTranslation(\"openhands\");\n const { showConsentPrompt, grantConsent, denyConsent } = useTelemetry();\n\n // Delay showing the modal slightly to ensure smooth rendering\n // This prevents the modal from flashing during initial hydration\n const [isReady, setIsReady] = useState(false);\n useEffect(() => {\n if (ready && showConsentPrompt) {\n // Small delay to ensure DOM is fully hydrated and translations loaded\n const timer = setTimeout(() => setIsReady(true), 50);\n return () => clearTimeout(timer);\n }\n setIsReady(false);\n return undefined;\n }, [ready, showConsentPrompt]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const formData = new FormData(e.currentTarget);\n const analytics = formData.get(\"analytics\") === \"on\";\n\n if (analytics) {\n grantConsent();\n } else {\n denyConsent();\n }\n onChoice?.(analytics);\n };\n\n // Don't render until translations are ready and component has stabilized\n if (!isReady) {\n return null;\n }\n\n return (\n <ModalBackdrop elevated aria-label={t(I18nKey.TELEMETRY$CONSENT_TITLE)}>\n <form\n data-testid=\"telemetry-consent-form\"\n onSubmit={handleSubmit}\n className=\"flex flex-col gap-2\"\n >\n <ModalBody className=\"border border-[var(--oh-border)]\">\n <BaseModalTitle title={t(I18nKey.TELEMETRY$CONSENT_TITLE)} />\n <BaseModalDescription>\n {t(I18nKey.TELEMETRY$CONSENT_DESCRIPTION)}\n </BaseModalDescription>\n\n <label className=\"flex gap-2 items-center self-start text-sm cursor-pointer\">\n <input\n name=\"analytics\"\n type=\"checkbox\"\n defaultChecked\n className=\"w-4 h-4 cursor-pointer\"\n />\n {t(I18nKey.TELEMETRY$SEND_ANONYMOUS_DATA)}\n </label>\n\n <BrandButton\n testId=\"confirm-telemetry-preferences\"\n type=\"submit\"\n variant=\"primary\"\n className=\"w-full\"\n >\n {t(I18nKey.TELEMETRY$CONFIRM_PREFERENCES)}\n </BrandButton>\n </ModalBody>\n </form>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;AAwCA,SAAgB,EAAuB,EACrC,eAC8B;CAC9B,IAAM,EAAE,MAAG,aAAU,EAAe,YAAY,EAC1C,EAAE,sBAAmB,iBAAc,mBAAgB,GAAc,EAIjE,CAAC,GAAS,KAAc,EAAS,GAAM;AA6B7C,QA5BA,QAAgB;AACd,MAAI,KAAS,GAAmB;GAE9B,IAAM,IAAQ,iBAAiB,EAAW,GAAK,EAAE,GAAG;AACpD,gBAAa,aAAa,EAAM;;AAElC,IAAW,GAAM;IAEhB,CAAC,GAAO,EAAkB,CAAC,EAgBzB,IAKH,kBAAC,GAAD;EAAe,UAAA;EAAS,cAAY,EAAE,EAAQ,wBAAwB;YACpE,kBAAC,QAAD;GACE,eAAY;GACZ,WAtBgB,MAAwC;AAC5D,MAAE,gBAAgB;IAElB,IAAM,IAAY,IADG,SAAS,EAAE,cACd,CAAS,IAAI,YAAY,KAAK;AAOhD,IALI,IACF,GAAc,GAEd,GAAa,EAEf,IAAW,EAAU;;GAajB,WAAU;aAEV,kBAAC,GAAD;IAAW,WAAU;cAArB;KACE,kBAAC,GAAD,EAAgB,OAAO,EAAE,EAAQ,wBAAwB,EAAI,CAAA;KAC7D,kBAAC,GAAD,EAAA,UACG,EAAE,EAAQ,8BAA8B,EACpB,CAAA;KAEvB,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,SAAD;OACE,MAAK;OACL,MAAK;OACL,gBAAA;OACA,WAAU;OACV,CAAA,EACD,EAAE,EAAQ,8BAA8B,CACnC;;KAER,kBAAC,GAAD;MACE,QAAO;MACP,MAAK;MACL,SAAQ;MACR,WAAU;gBAET,EAAE,EAAQ,8BAA8B;MAC7B,CAAA;KACJ;;GACP,CAAA;EACO,CAAA,GApCT"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { type AutomationRun } from "#/types/automation";
|
|
1
|
+
import { type Automation, type AutomationRun } from "#/types/automation";
|
|
2
2
|
interface ActivityLogItemProps {
|
|
3
3
|
run: AutomationRun;
|
|
4
|
+
automation?: Automation;
|
|
4
5
|
}
|
|
5
|
-
export declare function ActivityLogItem({ run }: ActivityLogItemProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function ActivityLogItem({ run, automation }: ActivityLogItemProps): import("react/jsx-runtime").JSX.Element;
|
|
6
7
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { Automation } from "#/types/automation";
|
|
1
2
|
interface ActivityLogSectionProps {
|
|
2
|
-
|
|
3
|
+
automation: Automation;
|
|
3
4
|
}
|
|
4
|
-
export declare function ActivityLogSection({
|
|
5
|
+
export declare function ActivityLogSection({ automation }: ActivityLogSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
5
6
|
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Automation, AutomationRun } from "#/types/automation";
|
|
2
|
+
interface DebugAutomationButtonProps {
|
|
3
|
+
/** The failed run being debugged. */
|
|
4
|
+
run: AutomationRun;
|
|
5
|
+
/** The parent automation, used to add context to the debug prompt. */
|
|
6
|
+
automation?: Automation;
|
|
7
|
+
/** The run's stderr, already computed by the enclosing logs modal. */
|
|
8
|
+
stderr: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Starts a new OpenHands conversation seeded with the failed run's error
|
|
12
|
+
* details so the agent begins debugging immediately. Kept as its own component
|
|
13
|
+
* (rather than inlined into the logs modal) so `useCreateConversation` — which
|
|
14
|
+
* requires a QueryClientProvider — only mounts for failed runs.
|
|
15
|
+
*/
|
|
16
|
+
export declare function DebugAutomationButton({ run, automation, stderr, }: DebugAutomationButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Automation, type AutomationRun } from "#/types/automation";
|
|
1
2
|
interface RunLogsModalProps {
|
|
2
3
|
/** Conversation that owns the bash command. */
|
|
3
4
|
conversationId: string | null;
|
|
@@ -5,6 +6,10 @@ interface RunLogsModalProps {
|
|
|
5
6
|
bashCommandId: string | null;
|
|
6
7
|
isOpen: boolean;
|
|
7
8
|
onClose: () => void;
|
|
9
|
+
/** The run these logs belong to; enables the debug action for failed runs. */
|
|
10
|
+
run?: AutomationRun;
|
|
11
|
+
/** The parent automation, used to add context to the debug prompt. */
|
|
12
|
+
automation?: Automation;
|
|
8
13
|
}
|
|
9
|
-
export declare function RunLogsModal({ conversationId, bashCommandId, isOpen, onClose, }: RunLogsModalProps): import("react/jsx-runtime").JSX.Element | null;
|
|
14
|
+
export declare function RunLogsModal({ conversationId, bashCommandId, isOpen, onClose, run, automation, }: RunLogsModalProps): import("react/jsx-runtime").JSX.Element | null;
|
|
10
15
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/utils.cjs`),i=require(`../../../context/navigation-context.cjs`),a=require(`../../../node_modules/@openhands/typescript-client/dist/client/server-client.cjs`),o=require(`../../../api/agent-server-config.cjs`),s=require(`../../../api/agent-server-client-options.cjs`),c=require(`../../../api/agent-server-compatibility.cjs`),l=require(`../../../utils/user-facing-error.cjs`),u=require(`../../../node_modules/@tanstack/react-query/build/modern/useQuery.cjs`),d=require(`../../../contexts/active-backend-context.cjs`),f=require(`../../shared/modals/modal-backdrop.cjs`),p=require(`../../shared/modals/modal-body.cjs`),m=require(`../../../utils/modal-classes.cjs`),h=require(`../../shared/modals/modal-close-button.cjs`),g=require(`../settings/brand-button.cjs`),_=require(`../settings/settings-input.cjs`),v=require(`../../../hooks/query/use-backends-health.cjs`),y=require(`../../../assets/branding/openhands-logo-white.cjs`),b=require(`../../../icons/chevron-down-small.cjs`),x=require(`./backend-status-label.cjs`),S=require(`./backend-status-dot.cjs`),C=require(`./device-flow-auth.cjs`);let w=require(`react`);w=e.__toESM(w,1);let T=require(`react/jsx-runtime`);function E(e){let t=e.trim().toLowerCase();return t.includes(`all-hands.dev`)||t.includes(`openhands.dev`)?`cloud`:`local`}function D(e){let t=e.toLowerCase().replace(/^\[|\]$/g,``);return!!(t===`localhost`||t===`::1`||t===`::`||t===`0.0.0.0`||/^127\./.test(t)||/^::ffff:127\./i.test(t)||/^10\./.test(t)||/^192\.168\./.test(t)||/^172\.(1[6-9]|2\d|3[01])\./.test(t)||/^fe[89ab][0-9a-f]:/i.test(t)||/^f[cd][0-9a-f]{2}:/i.test(t)||t.endsWith(`.local`)||!t.includes(`.`)&&!t.includes(`:`))}function O(e){let t=e.trim().replace(/\/+$/,``);if(!t)return``;if(/^https?:\/\//i.test(t))return t;let n=t.match(/^\[([^\]]+)\]/);return`${D(n?n[1]:(t.match(/:/g)??[]).length>1?t:t.split(`:`)[0])?`http`:`https`}://${t}`}function k(e){let t=e.trim();if(!t||/\s/.test(t))return!1;let n=O(t);if(!n)return!1;try{let e=new URL(n);return(e.protocol===`http:`||e.protocol===`https:`)&&e.hostname.length>0}catch{return!1}}var A=`https://app.all-hands.dev`;function j(e,t){return e(n.I18nKey.BACKEND$CONNECTION_TEST_FAILED,{host:t,interpolation:{escapeValue:!1}})}function M(e){return l.getUserFacingConnectionErrorMessage(e)}function N(e,t){let n=M(t);return n?`${e}\n${n}`:e}async function P(e){e.kind===`local`&&c.assertAgentServerVersionIsSupported(await new a.ServerClient(s.getAgentServerClientOptions({host:e.host,sessionApiKey:e.apiKey||null,timeout:5e3})).getServerInfo())}function F({backend:e,testIdRoot:r}){let{t:i}=t.useTranslation(`openhands`),o=v.useBackendsHealth([e])[e.id],l=o?.isConnected??null,d=o?.disabled===!0,f=o?.consecutiveFailures??0,p=o?.lastError??null,{data:m}=u.useQuery({queryKey:[`backend-version`,e.host,e.apiKey],queryFn:async()=>c.getDisplayAgentServerVersion(await new a.ServerClient(s.getAgentServerClientOptions({host:e.host,sessionApiKey:e.apiKey||null,timeout:5e3})).getServerInfo()),retry:!1,staleTime:6e4,enabled:e.kind===`local`&&!d}),h=x.getBackendStatusLabel(i,e,o),g=e.kind===`cloud`?i(n.I18nKey.BACKEND$KIND_CLOUD):i(n.I18nKey.BACKEND$KIND_LOCAL);return(0,T.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,T.jsxs)(`div`,{"data-testid":`${r}-status`,className:`flex items-center gap-3 text-sm`,children:[(0,T.jsx)(S.BackendStatusDot,{isConnected:l}),(0,T.jsx)(`span`,{className:`text-white`,"data-testid":`${r}-status-label`,children:h}),(0,T.jsx)(`span`,{className:`text-tertiary-alt`,children:`·`}),(0,T.jsx)(`span`,{className:`text-[var(--oh-text-tertiary)]`,children:g}),m?(0,T.jsx)(`span`,{className:`text-xs text-[var(--oh-muted)]`,"data-testid":`${r}-version`,children:i(n.I18nKey.BACKEND$VERSION_LABEL,{version:m})}):null]}),d?(0,T.jsxs)(`div`,{"data-testid":`${r}-status-error`,className:`flex flex-col gap-1 rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm`,children:[(0,T.jsx)(`span`,{className:`font-semibold text-red-300`,children:i(n.I18nKey.BACKEND$HEALTH_FAILED_TITLE)}),(0,T.jsx)(`span`,{className:`text-xs text-[var(--oh-text-tertiary)]`,children:i(n.I18nKey.BACKEND$HEALTH_FAILED_DETAIL,{count:f})}),p?(0,T.jsx)(`span`,{"data-testid":`${r}-status-error-message`,className:`text-xs text-red-300 whitespace-pre-wrap break-words`,children:p}):null]}):null]})}function I({initialName:e=``,initialHost:n=``,initialApiKey:r=``,onTestConnection:i,onSuccess:a,requireApiKey:o=!1,onSubmitOverride:s}){let{t:c}=t.useTranslation(`openhands`),[l,u]=w.default.useState(e),[d,f]=w.default.useState(n),[p,m]=w.default.useState(r),[h,g]=w.default.useState(null),[_,v]=w.default.useState(!1),y=E(d),b=o||y!==`local`,x=l.trim().length>0&&k(d)&&(!b||p.trim().length>0);return{name:l,setName:u,host:d,setHost:f,apiKey:p,setApiKey:m,connectionError:h,setConnectionError:g,isSubmitting:_,kind:y,canSubmit:x,handleSubmit:w.default.useCallback(async e=>{if(e.preventDefault(),!x||_)return;let t={name:l.trim(),host:O(d),apiKey:p.trim(),kind:y};g(null),v(!0);try{s?await s(t):(await i(t),a())}catch(e){g(N(j(c,t.host),e))}finally{v(!1)}},[x,_,l,d,p,y,i,a,o,s,c])}}function L({mode:e,backend:i,onSubmitted:a,renderActions:o,testIdRoot:s,hostReadOnly:c,requireApiKey:l,hideConfigurationFields:u=!1,onSubmitOverride:f}){let{t:p}=t.useTranslation(`openhands`),{addBackend:m,updateBackend:h}=d.useActiveBackendContext(),v=e===`edit`&&i?i.kind:null,{name:y,setName:b,host:x,setHost:S,apiKey:C,setApiKey:E,connectionError:D,setConnectionError:j,isSubmitting:M,kind:N,handleSubmit:L}=I({initialName:i?.name??``,initialHost:i?.host??``,initialApiKey:i?.apiKey??``,onTestConnection:P,onSuccess:async()=>{let t={name:y.trim(),host:O(x),apiKey:C.trim(),kind:v??N};e===`edit`&&i?h(i.id,t):m(t),a()},requireApiKey:l,onSubmitOverride:f}),[R,z]=w.default.useState(!1),[B,V]=w.default.useState(!1),H=v??N,U=s??(e===`edit`?`edit-backend`:`add-backend`),W=l||H!==`local`,G=y.trim().length>0&&k(x)&&(!W||C.trim().length>0),K=R&&!y.trim()?p(n.I18nKey.BACKEND$NAME_REQUIRED):void 0,q=B?x.trim()?k(x)?void 0:p(n.I18nKey.BACKEND$HOST_INVALID):p(n.I18nKey.BACKEND$HOST_REQUIRED):void 0;return(0,T.jsxs)(`form`,{"data-testid":`${U}-form`,onSubmit:async e=>{if(!G){z(!0),V(!0);return}await L(e)},className:`flex flex-col gap-4`,children:[(0,T.jsxs)(`div`,{"data-testid":`${U}-configuration-fields`,className:r.cn(`flex flex-col gap-4`,u&&`hidden`),children:[(0,T.jsx)(_.SettingsInput,{testId:`${U}-name`,name:`${U}-name`,type:`text`,label:p(n.I18nKey.BACKEND$NAME_LABEL),value:y,onChange:e=>{b(e),j(null)},onBlur:()=>z(!0),placeholder:`Production`,className:`w-full`,showRequiredTag:!0,error:K}),(0,T.jsx)(_.SettingsInput,{testId:`${U}-host`,name:`${U}-host`,type:`text`,label:p(n.I18nKey.BACKEND$HOST_LABEL),value:x,onChange:c?void 0:e=>{S(e),j(null)},onBlur:()=>V(!0),placeholder:A,className:`w-full`,showRequiredTag:!0,error:q,isDisabled:c}),(0,T.jsx)(_.SettingsInput,{testId:`${U}-api-key`,name:`${U}-api-key`,type:`password`,label:p(n.I18nKey.BACKEND$KEY_LABEL),value:C,onChange:e=>{E(e),j(null)},placeholder:``,className:`w-full`}),D?(0,T.jsx)(`div`,{role:`alert`,"data-testid":`${U}-error`,className:`rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-300 whitespace-pre-wrap break-words`,children:D}):null,e===`edit`&&i&&(0,T.jsx)(F,{backend:i,testIdRoot:U})]}),o?o({canSubmit:G&&!M,isSubmitting:M,testIdRoot:U}):(0,T.jsxs)(`div`,{className:`flex justify-end gap-2 mt-2 w-full`,children:[(0,T.jsx)(g.BrandButton,{type:`button`,variant:`secondary`,onClick:a,testId:`${U}-cancel`,children:p(n.I18nKey.BUTTON$CANCEL)}),(0,T.jsx)(g.BrandButton,{type:`submit`,variant:`primary`,isDisabled:!G||M,testId:`${U}-submit`,children:p(n.I18nKey.BACKEND$SAVE)})]})]})}function R(){let{currentPath:e,navigate:t}=i.useNavigation();return w.default.useCallback(()=>{/^\/automations\/[^/]+/.test(e)?t(`/automations`):/^\/conversations\/[^/]+/.test(e)&&t(`/conversations`)},[e,t])}function z({onConnected:e,testIdRoot:r=`add-backend`,initialManualBackend:i,requireManualApiKey:a=!1,manualSubmitLabel:s,manualSubmittingLabel:c,manualSubmitTestId:l}){let{t:u}=t.useTranslation(`openhands`),d=o.getLockedCloudHost();return d?(0,T.jsx)(`div`,{"data-testid":`${r}-connection-options`,className:`flex justify-center`,children:(0,T.jsx)(`div`,{className:`w-full`,children:(0,T.jsx)(V,{onConnected:e,testIdRoot:r,lockedHost:d})})}):(0,T.jsxs)(`div`,{"data-testid":`${r}-connection-options`,className:`flex flex-col gap-6 md:flex-row`,children:[(0,T.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,T.jsx)(B,{onConnected:e,testIdRoot:r,initialBackend:i,requireApiKey:a,submitLabel:s??u(n.I18nKey.BACKEND$CONNECT),submittingLabel:c??u(n.I18nKey.ONBOARDING$BACKEND_STATUS_CHECKING),submitTestId:l})}),(0,T.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,T.jsx)(V,{onConnected:e,testIdRoot:r})})]})}function B({onConnected:e,testIdRoot:r,initialBackend:i,requireApiKey:a,submitLabel:o,submittingLabel:s,submitTestId:c}){let{t:l}=t.useTranslation(`openhands`),{name:u,setName:d,host:f,setHost:p,apiKey:m,setApiKey:h,connectionError:v,setConnectionError:y,isSubmitting:b,kind:x,canSubmit:S,handleSubmit:C}=I({initialName:i?.name??``,initialHost:i?.host??``,initialApiKey:i?.apiKey??``,onTestConnection:P,onSuccess:()=>{e({name:u.trim(),host:O(f),apiKey:m.trim(),kind:x})},requireApiKey:a});return(0,T.jsxs)(`form`,{"data-testid":`${r}-form`,onSubmit:C,className:`flex flex-col gap-4 flex-1 min-w-0`,children:[(0,T.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,T.jsx)(_.SettingsInput,{testId:`${r}-name`,name:`${r}-name`,type:`text`,label:l(n.I18nKey.BACKEND$NAME_LABEL),value:u,onChange:e=>{d(e),y(null)},placeholder:`e.g. My Server`,className:`w-full`}),(0,T.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)]`,children:l(n.I18nKey.BACKEND$NAME_HELPER)})]}),(0,T.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,T.jsx)(_.SettingsInput,{testId:`${r}-host`,name:`${r}-host`,type:`text`,label:l(n.I18nKey.BACKEND$HOST_LABEL),value:f,onChange:e=>{p(e),y(null)},placeholder:`http://localhost:8000`,className:`w-full`}),(0,T.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)]`,"data-testid":`${r}-host-helper`,children:l(n.I18nKey.BACKEND$HOST_HELPER)})]}),(0,T.jsx)(_.SettingsInput,{testId:`${r}-api-key`,name:`${r}-api-key`,type:`password`,label:l(n.I18nKey.BACKEND$KEY_LABEL),value:m,onChange:e=>{h(e),y(null)},placeholder:`sk-••••••••••`,className:`w-full`}),v?(0,T.jsx)(`div`,{role:`alert`,"data-testid":`${r}-error`,className:`rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-300 whitespace-pre-wrap break-words`,children:v}):null,(0,T.jsx)(g.BrandButton,{type:`submit`,variant:`secondary`,isDisabled:!S||b,testId:c??`${r}-submit`,className:`w-full text-center`,children:b?s:o})]})}function V({onConnected:e,testIdRoot:i,lockedHost:a}){let{t:o}=t.useTranslation(`openhands`),[s,c]=w.default.useState(!1),[l,u]=w.default.useState(``),d=a??(l.trim()||A);return(0,T.jsxs)(`div`,{className:`flex flex-1 min-w-0 flex-col items-center gap-3`,children:[(0,T.jsxs)(`div`,{className:`flex flex-col items-center gap-1`,children:[(0,T.jsx)(y.default,{width:56,height:56,"aria-hidden":!0}),(0,T.jsx)(`h4`,{className:m.modalTitleLgMediumClassName,"data-testid":`${i}-cloud-title`,children:o(n.I18nKey.BACKEND$CLOUD_TITLE)})]}),(0,T.jsx)(`p`,{className:`text-center text-sm leading-relaxed text-[var(--oh-muted)]`,children:o(n.I18nKey.BACKEND$CLOUD_DESCRIPTION)}),(0,T.jsx)(C.DeviceFlowAuth,{host:d,onSuccess:t=>{e({name:`OpenHands Cloud`,host:O(d),apiKey:t,kind:`cloud`})},testIdRoot:i}),a?null:(0,T.jsxs)(`div`,{className:`w-full`,children:[(0,T.jsxs)(`button`,{type:`button`,onClick:()=>c(e=>!e),"aria-expanded":s,"data-testid":`${i}-advanced-toggle`,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`,children:[(0,T.jsx)(`span`,{children:o(n.I18nKey.BACKEND$ADVANCED)}),(0,T.jsx)(b.default,{className:r.cn(`h-4 w-4 shrink-0 text-muted transition-transform`,s&&`rotate-180`),"aria-hidden":!0})]}),(0,T.jsxs)(`div`,{className:r.cn(`pt-2`,!s&&`pointer-events-none invisible`),"aria-hidden":!s,children:[(0,T.jsx)(_.SettingsInput,{testId:`${i}-cloud-host`,name:`${i}-cloud-host`,type:`text`,label:o(n.I18nKey.BACKEND$HOST_LABEL),value:l,onChange:u,placeholder:A,className:`w-full`}),(0,T.jsx)(`p`,{className:`mt-1 text-xs text-[var(--oh-muted)]`,children:o(n.I18nKey.BACKEND$LOGIN_CLOUD_HINT)})]})]})]})}function H({onClose:e}){let{addBackend:t}=d.useActiveBackendContext(),n=R();return(0,T.jsx)(z,{onConnected:w.default.useCallback(r=>{t(r),n(),e()},[t,n,e])})}function U({mode:e,backend:i,onClose:a}){let{t:o}=t.useTranslation(`openhands`);if(e===`add`)return(0,T.jsx)(f.ModalBackdrop,{onClose:a,closeOnEscape:!1,"aria-label":o(n.I18nKey.BACKEND$ADD_TITLE),children:(0,T.jsxs)(`div`,{"data-testid":`add-backend-modal`,className:r.cn(`relative rounded-xl border border-[var(--oh-border)] bg-base-secondary`,p.modalWidthClassName(`xl`),p.MODAL_MAX_WIDTH_VIEWPORT),children:[(0,T.jsx)(h.ModalCloseButton,{onClose:a,testId:`add-backend-close`}),(0,T.jsx)(`div`,{className:`px-6 pt-6 pb-2 pr-12`,children:(0,T.jsx)(`h2`,{className:m.modalTitleLgClassName,children:o(n.I18nKey.BACKEND$ADD_TITLE)})}),(0,T.jsx)(`div`,{className:`px-6 pb-6 pt-2`,children:(0,T.jsx)(H,{onClose:a})})]})});let s=`edit-backend`;return(0,T.jsx)(f.ModalBackdrop,{onClose:a,closeOnEscape:!1,"aria-label":o(n.I18nKey.BACKEND$EDIT_TITLE),children:(0,T.jsxs)(`div`,{"data-testid":`${s}-modal`,className:r.cn(`relative bg-base-secondary p-6 rounded-xl flex flex-col gap-4 border border-[var(--oh-border)]`,p.modalWidthClassName(`md`)),children:[(0,T.jsx)(h.ModalCloseButton,{onClose:a,testId:`${s}-close`}),(0,T.jsx)(`h2`,{className:r.cn(`pr-6`,m.modalTitleLgClassName),children:o(n.I18nKey.BACKEND$EDIT_TITLE)}),(0,T.jsx)(L,{mode:`edit`,backend:i,onSubmitted:a,testIdRoot:s})]})})}exports.BackendFormModal=U;
|
|
1
|
+
const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/utils.cjs`),i=require(`../../../context/navigation-context.cjs`),a=require(`../../../node_modules/@openhands/typescript-client/dist/client/server-client.cjs`);require(`../../../node_modules/@openhands/typescript-client/dist/clients.cjs`);const o=require(`../../../api/agent-server-config.cjs`),s=require(`../../../api/agent-server-client-options.cjs`),c=require(`../../../api/agent-server-compatibility.cjs`),l=require(`../../../utils/user-facing-error.cjs`),u=require(`../../../node_modules/@tanstack/react-query/build/modern/useQuery.cjs`),d=require(`../../../contexts/active-backend-context.cjs`),f=require(`../../../hooks/use-tracking.cjs`),p=require(`../../shared/modals/modal-backdrop.cjs`),m=require(`../../shared/modals/modal-body.cjs`),h=require(`../../../utils/modal-classes.cjs`),g=require(`../../shared/modals/modal-close-button.cjs`),_=require(`../settings/brand-button.cjs`),v=require(`../settings/settings-input.cjs`),y=require(`../../../hooks/query/use-backends-health.cjs`),b=require(`../../../assets/branding/openhands-logo-white.cjs`),x=require(`../files-tab/segmented-toggle.cjs`),S=require(`../../../api/device-flow-client.cjs`),C=require(`../../../icons/chevron-down-small.cjs`),w=require(`./backend-status-label.cjs`),T=require(`./backend-status-dot.cjs`),E=require(`./device-flow-auth.cjs`);let D=require(`react`);D=e.__toESM(D,1);let O=require(`react/jsx-runtime`);function k(e){return S.isOpenHandsCloudHost(e)?`cloud`:`local`}function A(e){let t=e.toLowerCase().replace(/^\[|\]$/g,``);return!!(t===`localhost`||t===`::1`||t===`::`||t===`0.0.0.0`||/^127\./.test(t)||/^::ffff:127\./i.test(t)||/^10\./.test(t)||/^192\.168\./.test(t)||/^172\.(1[6-9]|2\d|3[01])\./.test(t)||/^fe[89ab][0-9a-f]:/i.test(t)||/^f[cd][0-9a-f]{2}:/i.test(t)||t.endsWith(`.local`)||!t.includes(`.`)&&!t.includes(`:`))}function j(e){let t=e.trim().replace(/\/+$/,``);if(!t)return``;if(/^https?:\/\//i.test(t))return t;let n=t.match(/^\[([^\]]+)\]/);return`${A(n?n[1]:(t.match(/:/g)??[]).length>1?t:t.split(`:`)[0])?`http`:`https`}://${t}`}function M(e){let t=e.trim();if(!t||/\s/.test(t))return!1;let n=j(t);if(!n)return!1;try{let e=new URL(n);return(e.protocol===`http:`||e.protocol===`https:`)&&e.hostname.length>0}catch{return!1}}var N=`https://app.all-hands.dev`;function P(e,t){return e(n.I18nKey.BACKEND$CONNECTION_TEST_FAILED,{host:t,interpolation:{escapeValue:!1}})}function F(e){return l.getUserFacingConnectionErrorMessage(e)}function I(e,t){let n=F(t);return n?`${e}\n${n}`:e}async function L(e){e.kind===`local`&&c.assertAgentServerVersionIsSupported(await new a.ServerClient(s.getAgentServerClientOptions({host:e.host,sessionApiKey:e.apiKey||null,timeout:5e3})).getServerInfo())}function R({backend:e,testIdRoot:r}){let{t:i}=t.useTranslation(`openhands`),o=y.useBackendsHealth([e])[e.id],l=o?.isConnected??null,d=o?.disabled===!0,f=o?.consecutiveFailures??0,p=o?.lastError??null,{data:m}=u.useQuery({queryKey:[`backend-version`,e.host,e.apiKey],queryFn:async()=>c.getDisplayAgentServerVersion(await new a.ServerClient(s.getAgentServerClientOptions({host:e.host,sessionApiKey:e.apiKey||null,timeout:5e3})).getServerInfo()),retry:!1,staleTime:6e4,enabled:e.kind===`local`&&!d}),h=w.getBackendStatusLabel(i,e,o),g=e.kind===`cloud`?i(n.I18nKey.BACKEND$KIND_CLOUD):i(n.I18nKey.BACKEND$KIND_LOCAL);return(0,O.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,O.jsxs)(`div`,{"data-testid":`${r}-status`,className:`flex items-center gap-3 text-sm`,children:[(0,O.jsx)(T.BackendStatusDot,{isConnected:l}),(0,O.jsx)(`span`,{className:`text-white`,"data-testid":`${r}-status-label`,children:h}),(0,O.jsx)(`span`,{className:`text-tertiary-alt`,children:`·`}),(0,O.jsx)(`span`,{className:`text-[var(--oh-text-tertiary)]`,children:g}),m?(0,O.jsx)(`span`,{className:`text-xs text-[var(--oh-muted)]`,"data-testid":`${r}-version`,children:i(n.I18nKey.BACKEND$VERSION_LABEL,{version:m})}):null]}),d?(0,O.jsxs)(`div`,{"data-testid":`${r}-status-error`,className:`flex flex-col gap-1 rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm`,children:[(0,O.jsx)(`span`,{className:`font-semibold text-red-300`,children:i(n.I18nKey.BACKEND$HEALTH_FAILED_TITLE)}),(0,O.jsx)(`span`,{className:`text-xs text-[var(--oh-text-tertiary)]`,children:i(n.I18nKey.BACKEND$HEALTH_FAILED_DETAIL,{count:f})}),p?(0,O.jsx)(`span`,{"data-testid":`${r}-status-error-message`,className:`text-xs text-red-300 whitespace-pre-wrap break-words`,children:p}):null]}):null]})}function z({initialName:e=``,initialHost:n=``,initialApiKey:r=``,onTestConnection:i,onSuccess:a,requireApiKey:o=!1,onSubmitOverride:s}){let{t:c}=t.useTranslation(`openhands`),[l,u]=D.default.useState(e),[d,f]=D.default.useState(n),[p,m]=D.default.useState(r),[h,g]=D.default.useState(null),[_,v]=D.default.useState(!1),[y,b]=D.default.useState(null),x=y??k(d),S=o||x!==`local`,C=l.trim().length>0&&M(d)&&(!S||p.trim().length>0);return{name:l,setName:u,host:d,setHost:f,apiKey:p,setApiKey:m,connectionError:h,setConnectionError:g,isSubmitting:_,kind:x,setKind:b,canSubmit:C,handleSubmit:D.default.useCallback(async e=>{if(e.preventDefault(),!C||_)return;let t={name:l.trim(),host:j(d),apiKey:p.trim(),kind:x};g(null),v(!0);try{s?await s(t):(await i(t),a())}catch(e){g(I(P(c,t.host),e))}finally{v(!1)}},[C,_,l,d,p,x,i,a,o,s,c])}}function B({mode:e,backend:i,onSubmitted:a,renderActions:o,testIdRoot:s,hostReadOnly:c,requireApiKey:l,hideConfigurationFields:u=!1,onSubmitOverride:f}){let{t:p}=t.useTranslation(`openhands`),{addBackend:m,updateBackend:h}=d.useActiveBackendContext(),g=e===`edit`&&i?i.kind:null,{name:y,setName:b,host:x,setHost:S,apiKey:C,setApiKey:w,connectionError:T,setConnectionError:E,isSubmitting:k,kind:A,handleSubmit:P}=z({initialName:i?.name??``,initialHost:i?.host??``,initialApiKey:i?.apiKey??``,onTestConnection:L,onSuccess:async()=>{let t={name:y.trim(),host:j(x),apiKey:C.trim(),kind:g??A};e===`edit`&&i?h(i.id,t):m(t),a()},requireApiKey:l,onSubmitOverride:f}),[F,I]=D.default.useState(!1),[B,V]=D.default.useState(!1),H=g??A,U=s??(e===`edit`?`edit-backend`:`add-backend`),W=l||H!==`local`,G=y.trim().length>0&&M(x)&&(!W||C.trim().length>0),K=F&&!y.trim()?p(n.I18nKey.BACKEND$NAME_REQUIRED):void 0,q=B?x.trim()?M(x)?void 0:p(n.I18nKey.BACKEND$HOST_INVALID):p(n.I18nKey.BACKEND$HOST_REQUIRED):void 0;return(0,O.jsxs)(`form`,{"data-testid":`${U}-form`,onSubmit:async e=>{if(!G){I(!0),V(!0);return}await P(e)},className:`flex flex-col gap-4`,children:[(0,O.jsxs)(`div`,{"data-testid":`${U}-configuration-fields`,className:r.cn(`flex flex-col gap-4`,u&&`hidden`),children:[(0,O.jsx)(v.SettingsInput,{testId:`${U}-name`,name:`${U}-name`,type:`text`,label:p(n.I18nKey.BACKEND$NAME_LABEL),value:y,onChange:e=>{b(e),E(null)},onBlur:()=>I(!0),placeholder:`Production`,className:`w-full`,showRequiredTag:!0,error:K}),(0,O.jsx)(v.SettingsInput,{testId:`${U}-host`,name:`${U}-host`,type:`text`,label:p(n.I18nKey.BACKEND$HOST_LABEL),value:x,onChange:c?void 0:e=>{S(e),E(null)},onBlur:()=>V(!0),placeholder:N,className:`w-full`,showRequiredTag:!0,error:q,isDisabled:c}),(0,O.jsx)(v.SettingsInput,{testId:`${U}-api-key`,name:`${U}-api-key`,type:`password`,label:p(n.I18nKey.BACKEND$KEY_LABEL),value:C,onChange:e=>{w(e),E(null)},placeholder:``,className:`w-full`}),T?(0,O.jsx)(`div`,{role:`alert`,"data-testid":`${U}-error`,className:`rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-300 whitespace-pre-wrap break-words`,children:T}):null,e===`edit`&&i&&(0,O.jsx)(R,{backend:i,testIdRoot:U})]}),o?o({canSubmit:G&&!k,isSubmitting:k,testIdRoot:U}):(0,O.jsxs)(`div`,{className:`flex justify-end gap-2 mt-2 w-full`,children:[(0,O.jsx)(_.BrandButton,{type:`button`,variant:`secondary`,onClick:a,testId:`${U}-cancel`,children:p(n.I18nKey.BUTTON$CANCEL)}),(0,O.jsx)(_.BrandButton,{type:`submit`,variant:`primary`,isDisabled:!G||k,testId:`${U}-submit`,children:p(n.I18nKey.BACKEND$SAVE)})]})]})}function V(){let{currentPath:e,navigate:t}=i.useNavigation();return D.default.useCallback(()=>{/^\/automations\/[^/]+/.test(e)?t(`/automations`):/^\/conversations\/[^/]+/.test(e)&&t(`/conversations`)},[e,t])}function H({onConnected:e,testIdRoot:r=`add-backend`,initialManualBackend:i,requireManualApiKey:a=!1,manualSubmitLabel:s,manualSubmittingLabel:c,manualSubmitTestId:l}){let{t:u}=t.useTranslation(`openhands`),d=o.getLockedCloudHost();return d?(0,O.jsx)(`div`,{"data-testid":`${r}-connection-options`,className:`flex justify-center`,children:(0,O.jsx)(`div`,{className:`w-full`,children:(0,O.jsx)(W,{onConnected:e,testIdRoot:r,lockedHost:d})})}):(0,O.jsxs)(`div`,{"data-testid":`${r}-connection-options`,className:`flex flex-col gap-6 md:flex-row`,children:[(0,O.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,O.jsx)(U,{onConnected:e,testIdRoot:r,initialBackend:i,requireApiKey:a,submitLabel:s??u(n.I18nKey.BACKEND$CONNECT),submittingLabel:c??u(n.I18nKey.ONBOARDING$BACKEND_STATUS_CHECKING),submitTestId:l})}),(0,O.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,O.jsx)(W,{onConnected:e,testIdRoot:r})})]})}function U({onConnected:e,testIdRoot:r,initialBackend:i,requireApiKey:a,submitLabel:o,submittingLabel:s,submitTestId:c}){let{t:l}=t.useTranslation(`openhands`),{name:u,setName:d,host:f,setHost:p,apiKey:m,setApiKey:h,connectionError:g,setConnectionError:y,isSubmitting:b,kind:S,setKind:C,canSubmit:w,handleSubmit:T}=z({initialName:i?.name??``,initialHost:i?.host??``,initialApiKey:i?.apiKey??``,onTestConnection:L,onSuccess:()=>{e({name:u.trim(),host:j(f),apiKey:m.trim(),kind:S},`manual`)},requireApiKey:a});return(0,O.jsxs)(`form`,{"data-testid":`${r}-form`,onSubmit:T,className:`flex flex-col gap-4 flex-1 min-w-0`,children:[(0,O.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,O.jsx)(v.SettingsInput,{testId:`${r}-name`,name:`${r}-name`,type:`text`,label:l(n.I18nKey.BACKEND$NAME_LABEL),value:u,onChange:e=>{d(e),y(null)},placeholder:`e.g. My Server`,className:`w-full`}),(0,O.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)]`,children:l(n.I18nKey.BACKEND$NAME_HELPER)})]}),(0,O.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,O.jsx)(v.SettingsInput,{testId:`${r}-host`,name:`${r}-host`,type:`text`,label:l(n.I18nKey.BACKEND$HOST_LABEL),value:f,onChange:e=>{p(e),y(null)},placeholder:`http://localhost:8000`,className:`w-full`}),(0,O.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)]`,"data-testid":`${r}-host-helper`,children:l(n.I18nKey.BACKEND$HOST_HELPER)})]}),(0,O.jsxs)(`div`,{className:`flex flex-col items-start gap-2.5`,children:[(0,O.jsx)(`span`,{className:`text-sm`,children:l(n.I18nKey.BACKEND$KIND_LABEL)}),(0,O.jsx)(x.SegmentedToggle,{value:S,options:[{value:`local`,label:l(n.I18nKey.BACKEND$KIND_LOCAL)},{value:`cloud`,label:l(n.I18nKey.BACKEND$KIND_CLOUD)}],onChange:e=>C(e),ariaLabel:l(n.I18nKey.BACKEND$KIND_LABEL),testId:`${r}-kind`})]}),(0,O.jsx)(v.SettingsInput,{testId:`${r}-api-key`,name:`${r}-api-key`,type:`password`,label:l(n.I18nKey.BACKEND$KEY_LABEL),value:m,onChange:e=>{h(e),y(null)},placeholder:`sk-••••••••••`,className:`w-full`}),g?(0,O.jsx)(`div`,{role:`alert`,"data-testid":`${r}-error`,className:`rounded-md border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-300 whitespace-pre-wrap break-words`,children:g}):null,(0,O.jsx)(_.BrandButton,{type:`submit`,variant:`secondary`,isDisabled:!w||b,testId:c??`${r}-submit`,className:`w-full text-center`,children:b?s:o})]})}function W({onConnected:e,testIdRoot:i,lockedHost:a}){let{t:o}=t.useTranslation(`openhands`),[s,c]=D.default.useState(!1),[l,u]=D.default.useState(``),d=a??(l.trim()||N);return(0,O.jsxs)(`div`,{className:`flex flex-1 min-w-0 flex-col items-center gap-3 pb-7`,children:[(0,O.jsxs)(`div`,{className:`flex flex-col items-center gap-1`,children:[(0,O.jsx)(b.default,{width:56,height:56,"aria-hidden":!0}),(0,O.jsx)(`h4`,{className:h.modalTitleLgMediumClassName,"data-testid":`${i}-cloud-title`,children:o(n.I18nKey.BACKEND$CLOUD_TITLE)})]}),(0,O.jsx)(`p`,{className:`text-center text-sm leading-relaxed text-[var(--oh-muted)]`,children:o(n.I18nKey.BACKEND$CLOUD_DESCRIPTION)}),(0,O.jsx)(E.DeviceFlowAuth,{host:d,onSuccess:t=>{e({name:`OpenHands Cloud`,host:j(d),apiKey:t,kind:`cloud`},`cloud_login`)},testIdRoot:i}),a?null:(0,O.jsxs)(`div`,{className:`w-full`,children:[(0,O.jsxs)(`button`,{type:`button`,onClick:()=>c(e=>!e),"aria-expanded":s,"data-testid":`${i}-advanced-toggle`,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`,children:[(0,O.jsx)(`span`,{children:o(n.I18nKey.BACKEND$ADVANCED)}),(0,O.jsx)(C.default,{className:r.cn(`h-4 w-4 shrink-0 text-muted transition-transform`,s&&`rotate-180`),"aria-hidden":!0})]}),(0,O.jsxs)(`div`,{className:r.cn(`pt-2`,!s&&`pointer-events-none invisible`),"aria-hidden":!s,children:[(0,O.jsx)(v.SettingsInput,{testId:`${i}-cloud-host`,name:`${i}-cloud-host`,type:`text`,label:o(n.I18nKey.BACKEND$HOST_LABEL),value:l,onChange:u,placeholder:N,className:`w-full`}),(0,O.jsx)(`p`,{className:`mt-1 text-xs text-[var(--oh-muted)]`,children:o(n.I18nKey.BACKEND$LOGIN_CLOUD_HINT)})]})]})]})}function G({onClose:e,source:t}){let{addBackend:n}=d.useActiveBackendContext(),r=V(),{trackBackendAdded:i}=f.useTracking();return(0,O.jsx)(H,{onConnected:D.default.useCallback((a,o)=>{n(a);let s=a.host===N;i({backendKind:a.kind,connectionMethod:o,isOpenhandsCloud:s,isCustomHost:!s,hasApiKey:!!a.apiKey,source:t}),r(),e()},[n,r,e,i,t])})}function K({mode:e,backend:i,onClose:a,source:o=`add_backend_modal`}){let{t:s}=t.useTranslation(`openhands`);if(e===`add`)return(0,O.jsx)(p.ModalBackdrop,{onClose:a,closeOnEscape:!1,"aria-label":s(n.I18nKey.BACKEND$ADD_TITLE),children:(0,O.jsxs)(`div`,{"data-testid":`add-backend-modal`,className:r.cn(`relative rounded-xl border border-[var(--oh-border)] bg-base-secondary`,m.modalWidthClassName(`xl`),m.MODAL_MAX_WIDTH_VIEWPORT),children:[(0,O.jsx)(g.ModalCloseButton,{onClose:a,testId:`add-backend-close`}),(0,O.jsx)(`div`,{className:`px-6 pt-6 pb-2 pr-12`,children:(0,O.jsx)(`h2`,{className:h.modalTitleLgClassName,children:s(n.I18nKey.BACKEND$ADD_TITLE)})}),(0,O.jsx)(`div`,{className:`px-6 pb-6 pt-2`,children:(0,O.jsx)(G,{onClose:a,source:o})})]})});let c=`edit-backend`;return(0,O.jsx)(p.ModalBackdrop,{onClose:a,closeOnEscape:!1,"aria-label":s(n.I18nKey.BACKEND$EDIT_TITLE),children:(0,O.jsxs)(`div`,{"data-testid":`${c}-modal`,className:r.cn(`relative bg-base-secondary p-6 rounded-xl flex flex-col gap-4 border border-[var(--oh-border)]`,m.modalWidthClassName(`md`)),children:[(0,O.jsx)(g.ModalCloseButton,{onClose:a,testId:`${c}-close`}),(0,O.jsx)(`h2`,{className:r.cn(`pr-6`,h.modalTitleLgClassName),children:s(n.I18nKey.BACKEND$EDIT_TITLE)}),(0,O.jsx)(B,{mode:`edit`,backend:i,onSubmitted:a,testIdRoot:c})]})})}exports.BackendFormModal=K;
|
|
2
2
|
//# sourceMappingURL=backend-form-modal.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-form-modal.cjs","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.cjs","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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"}
|
|
@@ -6,7 +6,11 @@ interface BackendFormModalProps {
|
|
|
6
6
|
/** Required when `mode === "edit"`. */
|
|
7
7
|
backend?: Backend;
|
|
8
8
|
onClose: () => void;
|
|
9
|
+
/** Analytics surface for the `backend_added` event (add mode only). */
|
|
10
|
+
source?: BackendAddedSource;
|
|
9
11
|
}
|
|
12
|
+
export type BackendConnectionMethod = "manual" | "cloud_login";
|
|
13
|
+
export type BackendAddedSource = "add_backend_modal" | "manage_backends_modal";
|
|
10
14
|
export interface BackendFormSubmitPayload {
|
|
11
15
|
name: string;
|
|
12
16
|
host: string;
|
|
@@ -71,7 +75,7 @@ export interface BackendFormProps {
|
|
|
71
75
|
*/
|
|
72
76
|
export declare function BackendForm({ mode, backend, onSubmitted, renderActions, testIdRoot: explicitTestIdRoot, hostReadOnly, requireApiKey, hideConfigurationFields, onSubmitOverride, }: BackendFormProps): import("react/jsx-runtime").JSX.Element;
|
|
73
77
|
interface BackendConnectionOptionsProps {
|
|
74
|
-
onConnected: (payload: BackendFormSubmitPayload) => void;
|
|
78
|
+
onConnected: (payload: BackendFormSubmitPayload, connectionMethod: BackendConnectionMethod) => void;
|
|
75
79
|
testIdRoot?: string;
|
|
76
80
|
initialManualBackend?: Partial<Pick<BackendFormSubmitPayload, "name" | "host" | "apiKey">>;
|
|
77
81
|
requireManualApiKey?: boolean;
|
|
@@ -90,5 +94,5 @@ export declare function BackendConnectionOptions({ onConnected, testIdRoot, init
|
|
|
90
94
|
* (manual connection | OR | Cloud login). In **edit** mode it wraps
|
|
91
95
|
* the standard `BackendForm`.
|
|
92
96
|
*/
|
|
93
|
-
export declare function BackendFormModal({ mode, backend, onClose, }: BackendFormModalProps): import("react/jsx-runtime").JSX.Element;
|
|
97
|
+
export declare function BackendFormModal({ mode, backend, onClose, source, }: BackendFormModalProps): import("react/jsx-runtime").JSX.Element;
|
|
94
98
|
export {};
|