@openhands/agent-canvas 1.0.0-beta.6 → 1.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (802) hide show
  1. package/README.md +24 -7
  2. package/README.windows.md +27 -0
  3. package/bin/agent-canvas.mjs +26 -3
  4. package/build/assets/{QueryClientProvider-CkGuhXg-.js → QueryClientProvider-Cnr-Yl3j.js} +1 -1
  5. package/build/assets/{Trans-Cvm_-SMi.js → Trans-4jmk54WC.js} +1 -1
  6. package/build/assets/acp-providers-CPdgcp13.js +1 -0
  7. package/build/assets/{acp-route-guard-B2yoBZ_4.js → acp-route-guard-BoVmCn0e.js} +1 -1
  8. package/build/assets/active-backend-context-Beu-LZL-.js +1 -0
  9. package/build/assets/add-backend-modal-BheqYXHK.js +1 -0
  10. package/build/assets/agent-server-client-options-HEOwGVIU.js +1 -0
  11. package/build/assets/agent-server-compatibility-CdI3N7dr.js +1 -0
  12. package/build/assets/agent-server-conversation-service.api-CORdqJZg.js +5 -0
  13. package/build/assets/{agent-settings-CnGSCmK8.js → agent-settings-UFvcGjoI.js} +1 -1
  14. package/build/assets/{alert-banner-DtzAX654.js → alert-banner-DFnn_lC6.js} +1 -1
  15. package/build/assets/{analytics-consent-form-modal-CHZ3I37v.js → analytics-consent-form-modal-CVNugqzu.js} +1 -1
  16. package/build/assets/api-key-entry-screen-M6su2VSf.js +1 -0
  17. package/build/assets/{app-settings-Db9ITeJH.js → app-settings-BlvBhBdc.js} +1 -1
  18. package/build/assets/automation-detail-BWrQk4Oa.js +1 -0
  19. package/build/assets/automations-list-ux9KvYsU.js +1 -0
  20. package/build/assets/back-nav-button-7dQJ2k3O.js +1 -0
  21. package/build/assets/backend-form-modal-CDnEYjaU.js +1 -0
  22. package/build/assets/{backend-synced-settings-badge-Dc6c7GT4.js → backend-synced-settings-badge-BTIj-Ffq.js} +1 -1
  23. package/build/assets/base-modal-C2oy2EBG.js +1 -0
  24. package/build/assets/brand-button-DJ_S16rO.js +1 -0
  25. package/build/assets/{browser-D810xUYt.js → browser-CGM-k-sH.js} +2 -2
  26. package/build/assets/browser-store-DAsixKdU.js +1 -0
  27. package/build/assets/{browser-tab-B-aIqXRl.js → browser-tab-dvSPdvkm.js} +1 -1
  28. package/build/assets/{checkmark-DL7acQA7.js → checkmark-Dus0b6jt.js} +1 -1
  29. package/build/assets/{chevron-left-small-CVWf8TI6.js → chevron-left-small-_uvG7RVM.js} +1 -1
  30. package/build/assets/{circle-plus-check-toggle-P7ZZToV4.js → circle-plus-check-toggle-DKS8MAVV.js} +1 -1
  31. package/build/assets/{close-B5LROHR3.js → close-BU5iTc66.js} +1 -1
  32. package/build/assets/code-tag-BzyqOtPD.js +1 -0
  33. package/build/assets/combobox-caret-BJC7XJsz.js +1 -0
  34. package/build/assets/{command-store-DFN_17p1.js → command-store-CE1weJy8.js} +1 -1
  35. package/build/assets/{condenser-settings-wnEKhBof.js → condenser-settings-BolbDvm5.js} +1 -1
  36. package/build/assets/{confirmation-modal-Dau3w_sa.js → confirmation-modal-B5Ca6qFE.js} +1 -1
  37. package/build/assets/context-menu-list-item-7tAcm2c3.js +1 -0
  38. package/build/assets/conversation-D0N4dw_p.js +19 -0
  39. package/build/assets/conversation-DhRJuZLG.js +1 -0
  40. package/build/assets/conversation-panel-CNqHbS_Z.js +1 -0
  41. package/build/assets/conversation-service.api-BsJy6uuL.js +1 -0
  42. package/build/assets/conversation-state-store-D-w0uurj.js +1 -0
  43. package/build/assets/conversation-store-CC-isCnP.js +1 -0
  44. package/build/assets/{conversation-tab-empty-state-DyssnnWa.js → conversation-tab-empty-state-CStQLPVW.js} +1 -1
  45. package/build/assets/conversation-websocket-context-DvHgx_FE.js +3 -0
  46. package/build/assets/{copy-DYgmUdIw.js → copy-Chg-sFu3.js} +1 -1
  47. package/build/assets/{custom-toast-handlers-C-SZFmto.js → custom-toast-handlers-ufGJ6_Rc.js} +1 -1
  48. package/build/assets/declaration-CR6HMp29.js +1 -0
  49. package/build/assets/{device-verify-DqDlphsG.js → device-verify-C6mj28zv.js} +1 -1
  50. package/build/assets/dist-DNeWJ2bh.js +1 -0
  51. package/build/assets/dropdown-classes-BsVmxlNG.js +1 -0
  52. package/build/assets/edit-automation-modal-BpX-t-HD.js +1 -0
  53. package/build/assets/ellipsis-button-Vh5MvRZa.js +1 -0
  54. package/build/assets/entry.client-Ck9rQCg-.js +2 -0
  55. package/build/assets/enum-filter-dropdown-5JeF2RLb.js +1 -0
  56. package/build/assets/{environment-switch-overlay-XL8yCGP6.js → environment-switch-overlay-Tf_BIfeR.js} +1 -1
  57. package/build/assets/extensions-hub-CE9QOb5n.js +1 -0
  58. package/build/assets/{extensions-navigation-BYR8Giqq.js → extensions-navigation-DSLGNGbS.js} +1 -1
  59. package/build/assets/file-BTY6Gyy9.js +1 -0
  60. package/build/assets/files-tab-cL668j1I.js +1 -0
  61. package/build/assets/files-tab-store-m0ARqX_E.js +1 -0
  62. package/build/assets/{folder-ZZJVGgd7.js → folder-D1T2W1cj.js} +1 -1
  63. package/build/assets/git-control-bar-branch-button-DtIrOrie.js +27 -0
  64. package/build/assets/git-provider-icon-CHdGBdU2.js +1 -0
  65. package/build/assets/globe-Bzj_0oXT.js +1 -0
  66. package/build/assets/home-Cz2Veg56.js +1 -0
  67. package/build/assets/{i18n-CTohRuoO.js → i18n-DET2iOyh.js} +1 -1
  68. package/build/assets/install-server-modal-B9nXCS3u.js +1 -0
  69. package/build/assets/launch-CWz0dm4o.js +1 -0
  70. package/build/assets/{lesson-plan-dH5Bj0pN.js → lesson-plan-duSsqWVs.js} +1 -1
  71. package/build/assets/link-external-DGxVm4Ps.js +1 -0
  72. package/build/assets/{llm-client-DaH1TuyR.js → llm-client-CYEaUjGx.js} +1 -1
  73. package/build/assets/llm-settings-DFkXHuvT.js +1 -0
  74. package/build/assets/llm-settings-DhrdCXqX.js +1 -0
  75. package/build/assets/{loading-spinner-BPtYORNK.js → loading-spinner-5GT9q1xy.js} +1 -1
  76. package/build/assets/manage-backends-modal-DpBD_vR9.js +1 -0
  77. package/build/assets/manage-workspaces-modal-CtRbxREx.js +1 -0
  78. package/build/assets/manifest-eed90ff5.js +1 -0
  79. package/build/assets/{markdown-renderer-DMzf2i4x.js → markdown-renderer-B3IAVfv4.js} +1 -1
  80. package/build/assets/mcp-BUe7kiYM.js +9 -0
  81. package/build/assets/messages-dqp_KYyl.js +36 -0
  82. package/build/assets/{modal-backdrop-BAbgYsqB.js → modal-backdrop-RfNCrSpK.js} +1 -1
  83. package/build/assets/{modal-body-BI6Ru2Qr.js → modal-body-aoa2fx5W.js} +1 -1
  84. package/build/assets/modal-classes-6YqcqA6y.js +1 -0
  85. package/build/assets/{modal-close-button-t1Gh3qmL.js → modal-close-button-CtWOUMmw.js} +1 -1
  86. package/build/assets/{model-selector-SM9IUz-q.js → model-selector-BvSTrkhT.js} +1 -1
  87. package/build/assets/{navigation-context-D0YWpT8d.js → navigation-context-BdKYH32C.js} +1 -1
  88. package/build/assets/{navigation-link-Cn7KP3c5.js → navigation-link-U4vY9i_C.js} +1 -1
  89. package/build/assets/{openhands-logo-CnrF6LKb.js → openhands-logo-CCo0wJZX.js} +1 -1
  90. package/build/assets/{option-service.api-KvY_mZMY.js → option-service.api-DmNVxAvS.js} +1 -1
  91. package/build/assets/{organization-service.api-DzYTHTYC.js → organization-service.api-DbnougaQ.js} +1 -1
  92. package/build/assets/{path-utils-C3bQf6lJ.js → path-utils-onx24uF5.js} +1 -1
  93. package/build/assets/{plan-components-atxXCF0R.js → plan-components-CRDMQzsS.js} +1 -1
  94. package/build/assets/{planner-tab-BlrCpv-7.js → planner-tab-CmIjLz7q.js} +1 -1
  95. package/build/assets/{profiles-client-D6IkTJof.js → profiles-client-fEmgWkCW.js} +1 -1
  96. package/build/assets/{providers-Bx6EfrzZ.js → providers-CbD7fiic.js} +1 -1
  97. package/build/assets/proxy-BAdHH8QB.js +1 -0
  98. package/build/assets/{query-client-config-B7u9asM0.js → query-client-config-CRnGSujB.js} +1 -1
  99. package/build/assets/{recommended-automations-launcher-CgV8FyPK.js → recommended-automations-launcher-uTyODuzB.js} +3 -3
  100. package/build/assets/{root-dNntxffj.js → root-DmjpFpTu.js} +2 -2
  101. package/build/assets/root-Z2VHU4R3.css +1 -0
  102. package/build/assets/root-layout-DejMsKhy.js +2 -0
  103. package/build/assets/{sdk-section-page-DOIKvwSL.js → sdk-section-page-BgDlMhcq.js} +1 -1
  104. package/build/assets/{sdk-settings-schema-DsUf9wu1.js → sdk-settings-schema-CLmJ9sho.js} +1 -1
  105. package/build/assets/{search-27Owlc3A.js → search-SuJctqNJ.js} +1 -1
  106. package/build/assets/secrets-service-B7CxNinp.js +1 -0
  107. package/build/assets/secrets-settings-yK7CqIpm.js +1 -0
  108. package/build/assets/{server-client-DyAQ3NZ_.js → server-client-Kh4QSwDJ.js} +1 -1
  109. package/build/assets/{settings-BYkVX7vW.js → settings-DN5PpgRD.js} +1 -1
  110. package/build/assets/{settings-dropdown-input-BJYvGdg-.js → settings-dropdown-input-BtoovFre.js} +1 -1
  111. package/build/assets/{settings-gear-C77PgE_O.js → settings-gear-Dd8K2_8B.js} +1 -1
  112. package/build/assets/settings-index-DKC8IY1P.js +1 -0
  113. package/build/assets/{settings-input-Bn7F5C75.js → settings-input-CehsXnb3.js} +1 -1
  114. package/build/assets/settings-list-classes-E3v_f6QG.js +1 -0
  115. package/build/assets/settings-modal-DJ4kGzUx.js +1 -0
  116. package/build/assets/{settings-section-header-context-BgZe5YkE.js → settings-section-header-context-DewwJ0-F.js} +1 -1
  117. package/build/assets/settings-service.api-C3rxTtPj.js +1 -0
  118. package/build/assets/{settings-switch-BeIKrWms.js → settings-switch-BiBuS3xa.js} +1 -1
  119. package/build/assets/{settings-utils-B6Nl07io.js → settings-utils-DY04tWG1.js} +1 -1
  120. package/build/assets/{shared-conversation-AMyqXvpk.js → shared-conversation-h9YnBtCU.js} +1 -1
  121. package/build/assets/sidebar-mobile-menu-toggle-D0-AvsnT.js +1 -0
  122. package/build/assets/{sidebar-nav-link-BGjiJq-4.js → sidebar-nav-link-OhIeFyna.js} +1 -1
  123. package/build/assets/{sidebar-store-Uy3v0AOV.js → sidebar-store-DnQAJAE5.js} +1 -1
  124. package/build/assets/{skill-card-pill-row-DF1axQCG.js → skill-card-pill-row-BW9qvhoK.js} +1 -1
  125. package/build/assets/{skills-ChIKZPK4.js → skills-0GRKX5Xj.js} +1 -1
  126. package/build/assets/{skills-plugins-CcI_19lM.js → skills-plugins-DNcsNF88.js} +1 -1
  127. package/build/assets/skills-settings-7liFiSY6.js +2 -0
  128. package/build/assets/{styled-tooltip-CBzrri6o.js → styled-tooltip-hdfMXPQC.js} +1 -1
  129. package/build/assets/{switch-skeleton-DnC9wLp7.js → switch-skeleton-DSKqSx2A.js} +1 -1
  130. package/build/assets/{task-list-tab-DUJn1sgz.js → task-list-tab-DT6_zfUs.js} +1 -1
  131. package/build/assets/{terminal-DgQk1Ay6.js → terminal-CDhQGDua.js} +2 -2
  132. package/build/assets/{terminal-RmuaSdhJ.js → terminal-CPYWdo4j.js} +1 -1
  133. package/build/assets/{toggle-switch-Pvyp2RAN.js → toggle-switch-T2v6sJ6l.js} +1 -1
  134. package/build/assets/{typography-gpuWmrQO.js → typography-BDgnT7Yp.js} +1 -1
  135. package/build/assets/{u-check-circle-IUIfACQQ.js → u-check-circle-DOauqQKb.js} +1 -1
  136. package/build/assets/{u-check-circle-half-C1YxB6py.js → u-check-circle-half-steSK_JB.js} +1 -1
  137. package/build/assets/{u-circuit-BmVikJHu.js → u-circuit-x3ExjBbU.js} +1 -1
  138. package/build/assets/{u-edit-CFvXHqZk.js → u-edit-BbrptMCa.js} +1 -1
  139. package/build/assets/{use-active-conversation-BEFNwnFk.js → use-active-conversation-DHGcmjCK.js} +1 -1
  140. package/build/assets/use-agent-settings-schema-CLoTOSJI.js +1 -0
  141. package/build/assets/{use-agent-state-Bkrd1FZq.js → use-agent-state-PKrUPMJ3.js} +1 -1
  142. package/build/assets/{use-cloud-current-user-id-CvkXFnTT.js → use-cloud-current-user-id-Ddr75hEz.js} +1 -1
  143. package/build/assets/{use-config-Co1O8-Ey.js → use-config-OIMQLQ2s.js} +1 -1
  144. package/build/assets/{use-create-conversation-CEgXpkfH.js → use-create-conversation-Bszyp13O.js} +1 -1
  145. package/build/assets/{use-event-store-BT_gV3ut.js → use-event-store-BomO7ywK.js} +1 -1
  146. package/build/assets/{use-get-secrets-DuhdIA59.js → use-get-secrets-8Jby8ele.js} +1 -1
  147. package/build/assets/{use-handle-plan-click-Ckkm5eIY.js → use-handle-plan-click-CohJPvvW.js} +1 -1
  148. package/build/assets/use-is-authed-dw2026rR.js +1 -0
  149. package/build/assets/{use-is-creating-conversation-BZ5hB_Bg.js → use-is-creating-conversation-DX2qSlfL.js} +1 -1
  150. package/build/assets/{use-launch-skill-in-chat-fNN_xGZG.js → use-launch-skill-in-chat-sQNEOLGD.js} +1 -1
  151. package/build/assets/use-llm-profiles-C861aFAq.js +1 -0
  152. package/build/assets/use-runtime-is-ready-Do2h_hRl.js +1 -0
  153. package/build/assets/{use-save-settings-VUrj_QNG.js → use-save-settings-DkAOEfD9.js} +1 -1
  154. package/build/assets/use-settings-D5hbTS9t.js +1 -0
  155. package/build/assets/{use-settings-nav-items-1ZvovKSr.js → use-settings-nav-items-BcSbo02d.js} +1 -1
  156. package/build/assets/{use-skills-DAMLFjKU.js → use-skills-D7PS0fH0.js} +1 -1
  157. package/build/assets/{use-task-list-CLJbuJgM.js → use-task-list-CsT10CBb.js} +1 -1
  158. package/build/assets/{use-unified-vscode-url-DdSRw-6P.js → use-unified-vscode-url-DEoe-NRI.js} +1 -1
  159. package/build/assets/use-user-conversation-Cs5H1pUF.js +1 -0
  160. package/build/assets/{useMutation-DqrumCWD.js → useMutation-GSSKKebK.js} +1 -1
  161. package/build/assets/{useTranslation-DCOdSSMl.js → useTranslation-B6voJV4y.js} +1 -1
  162. package/build/assets/utils-DCVfKFRt.js +1 -0
  163. package/build/assets/{vendor~browser-BNjNhjFU.js → vendor~browser-BrOJLj3y.js} +1 -1
  164. package/build/assets/vendor~conversation-panel~conversation-C9o-K1hW.js +1 -0
  165. package/build/assets/vendor~conversation-panel~conversation~index-RXYdJYxU.js +1 -0
  166. package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~jfc6hidu-VnmIZrq3.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~jfc6hidu-DJS-rJdI.js} +1 -1
  167. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DpAdkv8m.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-6ByzelMS.js} +1 -1
  168. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-B92czPCF.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BED5W_c4.js} +1 -1
  169. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-By5W2oHN.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CCbqAFiI.js} +1 -1
  170. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BbFOrAjI.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CG96FCly.js} +1 -1
  171. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-smY2r837.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-E4d6IEfI.js} +1 -1
  172. package/build/assets/{vendor~home~mcp~automations-list-Cs-TO3fK.js → vendor~home~mcp~automations-list-CZSK-lT2.js} +1 -1
  173. package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-Z3nsiNNq.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-CjJdFLoM.js} +1 -1
  174. package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-DbfELDJu.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-m8dOii0J.js} +2 -2
  175. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation-DjAjXS5J.js → vendor~root-layout~home~conversation-panel~conversation-B5WNMnt4.js} +1 -1
  176. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~i4kjfqhl-CbAhtEMv.js +1 -0
  177. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-6Rm8U_Sr.js +9 -0
  178. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-BkQGKpye.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-tTR8C6m0.js} +1 -1
  179. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-Bbs7UJ5U.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-BJbu9kpL.js} +2 -2
  180. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-DTwbEEcX.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-hTzSytKK.js} +1 -1
  181. package/build/assets/{vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~f2l2lr17-CDXvdvb2.js → vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~f2l2lr17-DYXOLEck.js} +1 -1
  182. package/build/assets/{verification-settings-CsbvQcYS.js → verification-settings-Dlt8pINd.js} +1 -1
  183. package/build/assets/{vscode-tab-DjNArCgY.js → vscode-tab-DgepcYtF.js} +1 -1
  184. package/build/assets/{waiting-for-runtime-message-CntjExbU.js → waiting-for-runtime-message-CdK3btDZ.js} +1 -1
  185. package/build/assets/{x-mark-CrpjscNc.js → x-mark-BrkSPIiT.js} +1 -1
  186. package/build/index.html +4 -4
  187. package/build/locales/ar/openhands.json +20 -2
  188. package/build/locales/ca/openhands.json +20 -2
  189. package/build/locales/de/openhands.json +20 -2
  190. package/build/locales/en/openhands.json +20 -2
  191. package/build/locales/es/openhands.json +20 -2
  192. package/build/locales/fr/openhands.json +20 -2
  193. package/build/locales/it/openhands.json +20 -2
  194. package/build/locales/ja/openhands.json +20 -2
  195. package/build/locales/ko-KR/openhands.json +20 -2
  196. package/build/locales/no/openhands.json +20 -2
  197. package/build/locales/pt/openhands.json +20 -2
  198. package/build/locales/tr/openhands.json +20 -2
  199. package/build/locales/uk/openhands.json +20 -2
  200. package/build/locales/zh-CN/openhands.json +20 -2
  201. package/build/locales/zh-TW/openhands.json +20 -2
  202. package/dist/api/acp-service/acp-service.api.d.ts +18 -0
  203. package/dist/api/agent-server-adapter.cjs +3 -3
  204. package/dist/api/agent-server-adapter.cjs.map +1 -1
  205. package/dist/api/agent-server-adapter.js +54 -55
  206. package/dist/api/agent-server-adapter.js.map +1 -1
  207. package/dist/api/agent-server-client-options.cjs +1 -1
  208. package/dist/api/agent-server-client-options.cjs.map +1 -1
  209. package/dist/api/agent-server-client-options.d.ts +4 -0
  210. package/dist/api/agent-server-client-options.js +18 -12
  211. package/dist/api/agent-server-client-options.js.map +1 -1
  212. package/dist/api/agent-server-compatibility.cjs +1 -1
  213. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  214. package/dist/api/agent-server-compatibility.d.ts +1 -1
  215. package/dist/api/agent-server-compatibility.js +30 -25
  216. package/dist/api/agent-server-compatibility.js.map +1 -1
  217. package/dist/api/agent-server-config.cjs +1 -1
  218. package/dist/api/agent-server-config.cjs.map +1 -1
  219. package/dist/api/agent-server-config.d.ts +1 -51
  220. package/dist/api/agent-server-config.js +20 -70
  221. package/dist/api/agent-server-config.js.map +1 -1
  222. package/dist/api/backend-registry/active-store.cjs +1 -1
  223. package/dist/api/backend-registry/active-store.cjs.map +1 -1
  224. package/dist/api/backend-registry/active-store.d.ts +11 -5
  225. package/dist/api/backend-registry/active-store.js +36 -27
  226. package/dist/api/backend-registry/active-store.js.map +1 -1
  227. package/dist/api/backend-registry/auth.cjs +1 -1
  228. package/dist/api/backend-registry/auth.cjs.map +1 -1
  229. package/dist/api/backend-registry/auth.js +3 -9
  230. package/dist/api/backend-registry/auth.js.map +1 -1
  231. package/dist/api/backend-registry/default-backend.cjs +1 -1
  232. package/dist/api/backend-registry/default-backend.cjs.map +1 -1
  233. package/dist/api/backend-registry/default-backend.d.ts +9 -16
  234. package/dist/api/backend-registry/default-backend.js +5 -4
  235. package/dist/api/backend-registry/default-backend.js.map +1 -1
  236. package/dist/api/backend-registry/storage.cjs +1 -1
  237. package/dist/api/backend-registry/storage.cjs.map +1 -1
  238. package/dist/api/backend-registry/storage.js +67 -34
  239. package/dist/api/backend-registry/storage.js.map +1 -1
  240. package/dist/api/cloud/conversation-service.api.cjs.map +1 -1
  241. package/dist/api/cloud/conversation-service.api.d.ts +8 -13
  242. package/dist/api/cloud/conversation-service.api.js.map +1 -1
  243. package/dist/api/cloud/organization-service.api.cjs.map +1 -1
  244. package/dist/api/cloud/organization-service.api.d.ts +1 -2
  245. package/dist/api/cloud/organization-service.api.js.map +1 -1
  246. package/dist/api/cloud/proxy.cjs +1 -1
  247. package/dist/api/cloud/proxy.cjs.map +1 -1
  248. package/dist/api/cloud/proxy.d.ts +6 -6
  249. package/dist/api/cloud/proxy.js +33 -24
  250. package/dist/api/cloud/proxy.js.map +1 -1
  251. package/dist/api/cloud/sandbox-service.api.cjs.map +1 -1
  252. package/dist/api/cloud/sandbox-service.api.d.ts +3 -3
  253. package/dist/api/cloud/sandbox-service.api.js.map +1 -1
  254. package/dist/api/cloud/secrets-service.api.cjs.map +1 -1
  255. package/dist/api/cloud/secrets-service.api.d.ts +3 -4
  256. package/dist/api/cloud/secrets-service.api.js.map +1 -1
  257. package/dist/api/cloud/settings-service.api.cjs +1 -1
  258. package/dist/api/cloud/settings-service.api.cjs.map +1 -1
  259. package/dist/api/cloud/settings-service.api.js +5 -1
  260. package/dist/api/cloud/settings-service.api.js.map +1 -1
  261. package/dist/api/cloud/skills-service.api.cjs.map +1 -1
  262. package/dist/api/cloud/skills-service.api.d.ts +5 -5
  263. package/dist/api/cloud/skills-service.api.js.map +1 -1
  264. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  265. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  266. package/dist/api/conversation-service/agent-server-conversation-service.api.js +115 -108
  267. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  268. package/dist/api/device-flow-client.cjs +1 -1
  269. package/dist/api/device-flow-client.cjs.map +1 -1
  270. package/dist/api/device-flow-client.d.ts +3 -5
  271. package/dist/api/device-flow-client.js +55 -66
  272. package/dist/api/device-flow-client.js.map +1 -1
  273. package/dist/api/event-service/event-service.api.cjs +1 -1
  274. package/dist/api/event-service/event-service.api.cjs.map +1 -1
  275. package/dist/api/event-service/event-service.api.d.ts +3 -3
  276. package/dist/api/event-service/event-service.api.js +17 -17
  277. package/dist/api/event-service/event-service.api.js.map +1 -1
  278. package/dist/api/git-service/agent-server-git-service.api.cjs +1 -1
  279. package/dist/api/git-service/agent-server-git-service.api.js +11 -11
  280. package/dist/api/runtime-service/agent-server-runtime-service.cjs +1 -1
  281. package/dist/api/runtime-service/agent-server-runtime-service.js +6 -6
  282. package/dist/components/conversation-events/chat/event-content-helpers/get-action-content.cjs +2 -2
  283. package/dist/components/conversation-events/chat/event-content-helpers/get-action-content.js +10 -10
  284. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-result.cjs.map +1 -1
  285. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-result.d.ts +5 -5
  286. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-result.js.map +1 -1
  287. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs +1 -1
  288. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs.map +1 -1
  289. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js +1 -1
  290. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js.map +1 -1
  291. package/dist/components/features/automations/automation-action-button-classes.d.ts +2 -2
  292. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  293. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  294. package/dist/components/features/backends/backend-form-modal.d.ts +1 -0
  295. package/dist/components/features/backends/backend-form-modal.js +203 -140
  296. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  297. package/dist/components/features/backends/backend-selector.cjs +1 -1
  298. package/dist/components/features/backends/backend-selector.cjs.map +1 -1
  299. package/dist/components/features/backends/backend-selector.js +117 -105
  300. package/dist/components/features/backends/backend-selector.js.map +1 -1
  301. package/dist/components/features/backends/backend-status-dot.cjs +1 -1
  302. package/dist/components/features/backends/backend-status-dot.cjs.map +1 -1
  303. package/dist/components/features/backends/backend-status-dot.d.ts +1 -1
  304. package/dist/components/features/backends/backend-status-dot.js +1 -1
  305. package/dist/components/features/backends/backend-status-dot.js.map +1 -1
  306. package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
  307. package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
  308. package/dist/components/features/backends/manage-backends-modal.js +81 -70
  309. package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
  310. package/dist/components/features/chat/change-agent-button.cjs +1 -1
  311. package/dist/components/features/chat/change-agent-button.cjs.map +1 -1
  312. package/dist/components/features/chat/change-agent-button.js +59 -57
  313. package/dist/components/features/chat/change-agent-button.js.map +1 -1
  314. package/dist/components/features/chat/change-agent-context-menu.cjs +1 -1
  315. package/dist/components/features/chat/change-agent-context-menu.cjs.map +1 -1
  316. package/dist/components/features/chat/change-agent-context-menu.d.ts +3 -1
  317. package/dist/components/features/chat/change-agent-context-menu.js +30 -25
  318. package/dist/components/features/chat/change-agent-context-menu.js.map +1 -1
  319. package/dist/components/features/chat/chat-add-file-button.cjs +1 -1
  320. package/dist/components/features/chat/chat-add-file-button.cjs.map +1 -1
  321. package/dist/components/features/chat/chat-add-file-button.js +39 -38
  322. package/dist/components/features/chat/chat-add-file-button.js.map +1 -1
  323. package/dist/components/features/chat/chat-message.cjs +1 -1
  324. package/dist/components/features/chat/chat-message.cjs.map +1 -1
  325. package/dist/components/features/chat/chat-message.d.ts +2 -1
  326. package/dist/components/features/chat/chat-message.js +185 -57
  327. package/dist/components/features/chat/chat-message.js.map +1 -1
  328. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  329. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  330. package/dist/components/features/chat/components/chat-input-actions.js +113 -113
  331. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  332. package/dist/components/features/chat/components/chat-input-model.cjs +1 -1
  333. package/dist/components/features/chat/components/chat-input-model.cjs.map +1 -1
  334. package/dist/components/features/chat/components/chat-input-model.js +52 -51
  335. package/dist/components/features/chat/components/chat-input-model.js.map +1 -1
  336. package/dist/components/features/chat/components/slash-command-menu.cjs +2 -2
  337. package/dist/components/features/chat/components/slash-command-menu.cjs.map +1 -1
  338. package/dist/components/features/chat/components/slash-command-menu.js +38 -34
  339. package/dist/components/features/chat/components/slash-command-menu.js.map +1 -1
  340. package/dist/components/features/chat/git-control-bar-pr-button.cjs +1 -1
  341. package/dist/components/features/chat/git-control-bar-pr-button.cjs.map +1 -1
  342. package/dist/components/features/chat/git-control-bar-pr-button.js +16 -15
  343. package/dist/components/features/chat/git-control-bar-pr-button.js.map +1 -1
  344. package/dist/components/features/chat/git-control-bar-pull-button.cjs +1 -1
  345. package/dist/components/features/chat/git-control-bar-pull-button.cjs.map +1 -1
  346. package/dist/components/features/chat/git-control-bar-pull-button.js +16 -15
  347. package/dist/components/features/chat/git-control-bar-pull-button.js.map +1 -1
  348. package/dist/components/features/chat/git-control-bar-push-button.cjs +1 -1
  349. package/dist/components/features/chat/git-control-bar-push-button.cjs.map +1 -1
  350. package/dist/components/features/chat/git-control-bar-push-button.js +16 -15
  351. package/dist/components/features/chat/git-control-bar-push-button.js.map +1 -1
  352. package/dist/components/features/chat/git-control-bar.cjs +1 -1
  353. package/dist/components/features/chat/git-control-bar.cjs.map +1 -1
  354. package/dist/components/features/chat/git-control-bar.js +63 -62
  355. package/dist/components/features/chat/git-control-bar.js.map +1 -1
  356. package/dist/components/features/chat/pending-user-messages.cjs +1 -1
  357. package/dist/components/features/chat/pending-user-messages.cjs.map +1 -1
  358. package/dist/components/features/chat/pending-user-messages.js +27 -23
  359. package/dist/components/features/chat/pending-user-messages.js.map +1 -1
  360. package/dist/components/features/chat/switch-profile-button.cjs +1 -1
  361. package/dist/components/features/chat/switch-profile-button.cjs.map +1 -1
  362. package/dist/components/features/chat/switch-profile-button.js +26 -25
  363. package/dist/components/features/chat/switch-profile-button.js.map +1 -1
  364. package/dist/components/features/chat/switch-profile-context-menu.cjs +1 -1
  365. package/dist/components/features/chat/switch-profile-context-menu.cjs.map +1 -1
  366. package/dist/components/features/chat/switch-profile-context-menu.js +77 -67
  367. package/dist/components/features/chat/switch-profile-context-menu.js.map +1 -1
  368. package/dist/components/features/context-menu/context-menu-icon-text-with-description.cjs +1 -1
  369. package/dist/components/features/context-menu/context-menu-icon-text-with-description.cjs.map +1 -1
  370. package/dist/components/features/context-menu/context-menu-icon-text-with-description.d.ts +2 -1
  371. package/dist/components/features/context-menu/context-menu-icon-text-with-description.js +3 -2
  372. package/dist/components/features/context-menu/context-menu-icon-text-with-description.js.map +1 -1
  373. package/dist/components/features/context-menu/context-menu-icon-text.cjs +1 -1
  374. package/dist/components/features/context-menu/context-menu-icon-text.cjs.map +1 -1
  375. package/dist/components/features/context-menu/context-menu-icon-text.d.ts +2 -1
  376. package/dist/components/features/context-menu/context-menu-icon-text.js +20 -10
  377. package/dist/components/features/context-menu/context-menu-icon-text.js.map +1 -1
  378. package/dist/components/features/context-menu/context-menu-list-item.cjs +1 -1
  379. package/dist/components/features/context-menu/context-menu-list-item.cjs.map +1 -1
  380. package/dist/components/features/context-menu/context-menu-list-item.js +10 -9
  381. package/dist/components/features/context-menu/context-menu-list-item.js.map +1 -1
  382. package/dist/components/features/controls/agent-status.cjs +1 -1
  383. package/dist/components/features/controls/agent-status.js +12 -12
  384. package/dist/components/features/controls/git-tools-submenu.cjs +1 -1
  385. package/dist/components/features/controls/git-tools-submenu.cjs.map +1 -1
  386. package/dist/components/features/controls/git-tools-submenu.js +1 -1
  387. package/dist/components/features/controls/git-tools-submenu.js.map +1 -1
  388. package/dist/components/features/controls/macros-submenu.cjs +1 -1
  389. package/dist/components/features/controls/macros-submenu.cjs.map +1 -1
  390. package/dist/components/features/controls/macros-submenu.js +1 -1
  391. package/dist/components/features/controls/macros-submenu.js.map +1 -1
  392. package/dist/components/features/controls/server-status-context-menu-icon-text.cjs +1 -1
  393. package/dist/components/features/controls/server-status-context-menu-icon-text.cjs.map +1 -1
  394. package/dist/components/features/controls/server-status-context-menu-icon-text.js +14 -15
  395. package/dist/components/features/controls/server-status-context-menu-icon-text.js.map +1 -1
  396. package/dist/components/features/controls/server-status-context-menu.cjs +1 -1
  397. package/dist/components/features/controls/server-status-context-menu.js +4 -4
  398. package/dist/components/features/controls/server-status.cjs +1 -1
  399. package/dist/components/features/controls/server-status.js +7 -7
  400. package/dist/components/features/controls/tools-context-menu-icon-text.cjs +1 -1
  401. package/dist/components/features/controls/tools-context-menu-icon-text.cjs.map +1 -1
  402. package/dist/components/features/controls/tools-context-menu-icon-text.js +16 -16
  403. package/dist/components/features/controls/tools-context-menu-icon-text.js.map +1 -1
  404. package/dist/components/features/conversation/conversation-name-context-menu-icon-text.cjs +1 -1
  405. package/dist/components/features/conversation/conversation-name-context-menu-icon-text.cjs.map +1 -1
  406. package/dist/components/features/conversation/conversation-name-context-menu-icon-text.js +11 -11
  407. package/dist/components/features/conversation/conversation-name-context-menu-icon-text.js.map +1 -1
  408. package/dist/components/features/conversation/conversation-name-with-status.cjs +1 -1
  409. package/dist/components/features/conversation/conversation-name-with-status.js +11 -11
  410. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
  411. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
  412. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +60 -47
  413. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
  414. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.cjs +1 -1
  415. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.cjs.map +1 -1
  416. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.js +86 -82
  417. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.js.map +1 -1
  418. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs +1 -1
  419. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js +4 -4
  420. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs +1 -1
  421. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js +9 -9
  422. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs +1 -1
  423. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs.map +1 -1
  424. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js +93 -93
  425. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js.map +1 -1
  426. package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
  427. package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
  428. package/dist/components/features/conversation-panel/conversation-panel.js +177 -177
  429. package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
  430. package/dist/components/features/conversation-panel/ellipsis-button.cjs +1 -1
  431. package/dist/components/features/conversation-panel/ellipsis-button.cjs.map +1 -1
  432. package/dist/components/features/conversation-panel/ellipsis-button.js +13 -13
  433. package/dist/components/features/conversation-panel/ellipsis-button.js.map +1 -1
  434. package/dist/components/features/conversation-panel/local-new-conversation-menu.cjs +1 -1
  435. package/dist/components/features/conversation-panel/local-new-conversation-menu.cjs.map +1 -1
  436. package/dist/components/features/conversation-panel/local-new-conversation-menu.js +57 -53
  437. package/dist/components/features/conversation-panel/local-new-conversation-menu.js.map +1 -1
  438. package/dist/components/features/conversation-panel/new-conversation-dropdown-styles.cjs +1 -1
  439. package/dist/components/features/conversation-panel/new-conversation-dropdown-styles.cjs.map +1 -1
  440. package/dist/components/features/conversation-panel/new-conversation-dropdown-styles.js +3 -2
  441. package/dist/components/features/conversation-panel/new-conversation-dropdown-styles.js.map +1 -1
  442. package/dist/components/features/conversation-panel/start-task-card/start-task-status-badge.cjs +1 -1
  443. package/dist/components/features/conversation-panel/start-task-card/start-task-status-badge.cjs.map +1 -1
  444. package/dist/components/features/conversation-panel/start-task-card/start-task-status-badge.js +11 -8
  445. package/dist/components/features/conversation-panel/start-task-card/start-task-status-badge.js.map +1 -1
  446. package/dist/components/features/conversation-panel/system-message-modal/tab-content.cjs.map +1 -1
  447. package/dist/components/features/conversation-panel/system-message-modal/tab-content.d.ts +2 -5
  448. package/dist/components/features/conversation-panel/system-message-modal/tab-content.js.map +1 -1
  449. package/dist/components/features/files-tab/file-content-viewer.cjs +1 -1
  450. package/dist/components/features/files-tab/file-content-viewer.cjs.map +1 -1
  451. package/dist/components/features/files-tab/file-content-viewer.js +45 -42
  452. package/dist/components/features/files-tab/file-content-viewer.js.map +1 -1
  453. package/dist/components/features/home/llm-not-configured-banner.d.ts +11 -0
  454. package/dist/components/features/home/shared/dropdown-item.cjs +1 -1
  455. package/dist/components/features/home/shared/dropdown-item.cjs.map +1 -1
  456. package/dist/components/features/home/shared/dropdown-item.js +20 -16
  457. package/dist/components/features/home/shared/dropdown-item.js.map +1 -1
  458. package/dist/components/features/home/shared/generic-dropdown-menu.cjs +1 -1
  459. package/dist/components/features/home/shared/generic-dropdown-menu.cjs.map +1 -1
  460. package/dist/components/features/home/shared/generic-dropdown-menu.js +23 -22
  461. package/dist/components/features/home/shared/generic-dropdown-menu.js.map +1 -1
  462. package/dist/components/features/home/workspace-dropdown/folder-browser-modal.cjs +1 -1
  463. package/dist/components/features/home/workspace-dropdown/folder-browser-modal.cjs.map +1 -1
  464. package/dist/components/features/home/workspace-dropdown/folder-browser-modal.js +103 -102
  465. package/dist/components/features/home/workspace-dropdown/folder-browser-modal.js.map +1 -1
  466. package/dist/components/features/home/workspace-dropdown/manage-workspaces-modal.cjs +1 -1
  467. package/dist/components/features/home/workspace-dropdown/manage-workspaces-modal.cjs.map +1 -1
  468. package/dist/components/features/home/workspace-dropdown/manage-workspaces-modal.js +68 -67
  469. package/dist/components/features/home/workspace-dropdown/manage-workspaces-modal.js.map +1 -1
  470. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  471. package/dist/components/features/mcp-page/custom-server-editor.cjs.map +1 -1
  472. package/dist/components/features/mcp-page/custom-server-editor.js +62 -60
  473. package/dist/components/features/mcp-page/custom-server-editor.js.map +1 -1
  474. package/dist/components/features/mcp-page/index.cjs +1 -1
  475. package/dist/components/features/mcp-page/index.d.ts +1 -0
  476. package/dist/components/features/mcp-page/index.js +1 -0
  477. package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
  478. package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
  479. package/dist/components/features/mcp-page/install-server-modal.js +141 -121
  480. package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
  481. package/dist/components/features/mcp-page/save-as-secret-toggle.cjs +2 -0
  482. package/dist/components/features/mcp-page/save-as-secret-toggle.cjs.map +1 -0
  483. package/dist/components/features/mcp-page/save-as-secret-toggle.d.ts +7 -0
  484. package/dist/components/features/mcp-page/save-as-secret-toggle.js +50 -0
  485. package/dist/components/features/mcp-page/save-as-secret-toggle.js.map +1 -0
  486. package/dist/components/features/onboarding/onboarding-modal.d.ts +2 -2
  487. package/dist/components/features/onboarding/steps/check-backend-step.d.ts +1 -1
  488. package/dist/components/features/onboarding/steps/choose-agent-step.d.ts +2 -1
  489. package/dist/components/features/onboarding/steps/setup-acp-secrets-step.d.ts +19 -10
  490. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
  491. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.d.ts +5 -0
  492. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +2 -0
  493. package/dist/components/features/settings/llm-profiles/profile-actions-menu.cjs +1 -1
  494. package/dist/components/features/settings/llm-profiles/profile-actions-menu.js +1 -0
  495. package/dist/components/features/skills/extensions-navigation.cjs +1 -1
  496. package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
  497. package/dist/components/features/skills/extensions-navigation.js +1 -1
  498. package/dist/components/features/skills/extensions-navigation.js.map +1 -1
  499. package/dist/components/shared/buttons/back-nav-button.cjs +2 -0
  500. package/dist/components/shared/buttons/back-nav-button.cjs.map +1 -0
  501. package/dist/components/shared/buttons/back-nav-button.d.ts +17 -0
  502. package/dist/components/shared/buttons/back-nav-button.js +33 -0
  503. package/dist/components/shared/buttons/back-nav-button.js.map +1 -0
  504. package/dist/components/shared/buttons/conversation-confirmation-buttons.cjs +1 -1
  505. package/dist/components/shared/buttons/conversation-confirmation-buttons.js +5 -5
  506. package/dist/components/shared/filters/enum-filter-dropdown.cjs +1 -1
  507. package/dist/components/shared/filters/enum-filter-dropdown.cjs.map +1 -1
  508. package/dist/components/shared/filters/enum-filter-dropdown.js +32 -31
  509. package/dist/components/shared/filters/enum-filter-dropdown.js.map +1 -1
  510. package/dist/components/shared/modals/confirmation-modals/base-modal.cjs +1 -1
  511. package/dist/components/shared/modals/confirmation-modals/base-modal.cjs.map +1 -1
  512. package/dist/components/shared/modals/confirmation-modals/base-modal.js +14 -13
  513. package/dist/components/shared/modals/confirmation-modals/base-modal.js.map +1 -1
  514. package/dist/components/shared/modals/settings/settings-modal.cjs +1 -1
  515. package/dist/components/shared/modals/settings/settings-modal.cjs.map +1 -1
  516. package/dist/components/shared/modals/settings/settings-modal.js +17 -16
  517. package/dist/components/shared/modals/settings/settings-modal.js.map +1 -1
  518. package/dist/components/shared/text-shimmer.cjs +2 -0
  519. package/dist/components/shared/text-shimmer.cjs.map +1 -0
  520. package/dist/components/shared/text-shimmer.d.ts +11 -0
  521. package/dist/components/shared/text-shimmer.js +43 -0
  522. package/dist/components/shared/text-shimmer.js.map +1 -0
  523. package/dist/constants/acp-providers.cjs +1 -1
  524. package/dist/constants/acp-providers.cjs.map +1 -1
  525. package/dist/constants/acp-providers.d.ts +16 -3
  526. package/dist/constants/acp-providers.js +0 -1
  527. package/dist/constants/acp-providers.js.map +1 -1
  528. package/dist/contexts/active-backend-context.cjs +1 -1
  529. package/dist/contexts/active-backend-context.cjs.map +1 -1
  530. package/dist/contexts/active-backend-context.js +32 -32
  531. package/dist/contexts/active-backend-context.js.map +1 -1
  532. package/dist/hooks/chat/use-chat-input-logic.cjs +1 -1
  533. package/dist/hooks/chat/use-chat-input-logic.cjs.map +1 -1
  534. package/dist/hooks/chat/use-chat-input-logic.js +13 -6
  535. package/dist/hooks/chat/use-chat-input-logic.js.map +1 -1
  536. package/dist/hooks/mutation/use-save-fields-as-secrets.cjs +2 -0
  537. package/dist/hooks/mutation/use-save-fields-as-secrets.cjs.map +1 -0
  538. package/dist/hooks/mutation/use-save-fields-as-secrets.d.ts +9 -0
  539. package/dist/hooks/mutation/use-save-fields-as-secrets.js +24 -0
  540. package/dist/hooks/mutation/use-save-fields-as-secrets.js.map +1 -0
  541. package/dist/hooks/mutation/use-unified-start-conversation.cjs +1 -1
  542. package/dist/hooks/mutation/use-unified-start-conversation.js +8 -8
  543. package/dist/hooks/mutation/use-unified-stop-conversation.cjs +1 -1
  544. package/dist/hooks/mutation/use-unified-stop-conversation.js +15 -15
  545. package/dist/hooks/query/use-acp-auth-status.d.ts +36 -0
  546. package/dist/hooks/query/use-agent-settings-schema.cjs +1 -1
  547. package/dist/hooks/query/use-agent-settings-schema.cjs.map +1 -1
  548. package/dist/hooks/query/use-agent-settings-schema.js +26 -16
  549. package/dist/hooks/query/use-agent-settings-schema.js.map +1 -1
  550. package/dist/hooks/query/use-backends-health.cjs +1 -1
  551. package/dist/hooks/query/use-backends-health.cjs.map +1 -1
  552. package/dist/hooks/query/use-backends-health.d.ts +2 -0
  553. package/dist/hooks/query/use-backends-health.js +31 -21
  554. package/dist/hooks/query/use-backends-health.js.map +1 -1
  555. package/dist/hooks/query/use-paginated-conversations.cjs +1 -1
  556. package/dist/hooks/query/use-paginated-conversations.cjs.map +1 -1
  557. package/dist/hooks/query/use-paginated-conversations.js +15 -14
  558. package/dist/hooks/query/use-paginated-conversations.js.map +1 -1
  559. package/dist/hooks/query/use-settings.cjs +1 -1
  560. package/dist/hooks/query/use-settings.cjs.map +1 -1
  561. package/dist/hooks/query/use-settings.js +65 -52
  562. package/dist/hooks/query/use-settings.js.map +1 -1
  563. package/dist/hooks/query/use-user-conversation.cjs +1 -1
  564. package/dist/hooks/query/use-user-conversation.cjs.map +1 -1
  565. package/dist/hooks/query/use-user-conversation.js +20 -11
  566. package/dist/hooks/query/use-user-conversation.js.map +1 -1
  567. package/dist/hooks/use-agent-state.cjs +1 -1
  568. package/dist/hooks/use-agent-state.js +13 -13
  569. package/dist/hooks/use-conversation-name-context-menu.cjs +1 -1
  570. package/dist/hooks/use-conversation-name-context-menu.js +10 -10
  571. package/dist/hooks/use-conversation-name-context-menu.js.map +1 -1
  572. package/dist/hooks/use-llm-configured.d.ts +25 -0
  573. package/dist/hooks/use-runtime-is-ready.cjs +1 -1
  574. package/dist/hooks/use-runtime-is-ready.js +5 -5
  575. package/dist/i18n/declaration.cjs +1 -1
  576. package/dist/i18n/declaration.cjs.map +1 -1
  577. package/dist/i18n/declaration.d.ts +19 -1
  578. package/dist/i18n/declaration.js +1 -1
  579. package/dist/i18n/declaration.js.map +1 -1
  580. package/dist/i18n/translation.cjs +3 -3
  581. package/dist/i18n/translation.cjs.map +1 -1
  582. package/dist/i18n/translation.js +321 -15
  583. package/dist/i18n/translation.js.map +1 -1
  584. package/dist/icons/stop-circle.cjs +1 -1
  585. package/dist/icons/stop-circle.cjs.map +1 -1
  586. package/dist/icons/stop-circle.js +7 -10
  587. package/dist/icons/stop-circle.js.map +1 -1
  588. package/dist/locales/ar/openhands.json +20 -2
  589. package/dist/locales/ca/openhands.json +20 -2
  590. package/dist/locales/de/openhands.json +20 -2
  591. package/dist/locales/en/openhands.json +20 -2
  592. package/dist/locales/es/openhands.json +20 -2
  593. package/dist/locales/fr/openhands.json +20 -2
  594. package/dist/locales/it/openhands.json +20 -2
  595. package/dist/locales/ja/openhands.json +20 -2
  596. package/dist/locales/ko-KR/openhands.json +20 -2
  597. package/dist/locales/no/openhands.json +20 -2
  598. package/dist/locales/pt/openhands.json +20 -2
  599. package/dist/locales/tr/openhands.json +20 -2
  600. package/dist/locales/uk/openhands.json +20 -2
  601. package/dist/locales/zh-CN/openhands.json +20 -2
  602. package/dist/locales/zh-TW/openhands.json +20 -2
  603. package/dist/node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.cjs +2 -0
  604. package/dist/node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.cjs.map +1 -0
  605. package/dist/node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js +15 -0
  606. package/dist/node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js.map +1 -0
  607. package/dist/package.cjs +1 -1
  608. package/dist/package.cjs.map +1 -1
  609. package/dist/package.js +1 -1
  610. package/dist/package.js.map +1 -1
  611. package/dist/routes/conversation.cjs +1 -1
  612. package/dist/routes/conversation.cjs.map +1 -1
  613. package/dist/routes/conversation.js +1 -1
  614. package/dist/routes/conversation.js.map +1 -1
  615. package/dist/routes/llm-settings.cjs +1 -1
  616. package/dist/routes/llm-settings.cjs.map +1 -1
  617. package/dist/routes/llm-settings.js +55 -54
  618. package/dist/routes/llm-settings.js.map +1 -1
  619. package/dist/routes/secrets-settings.cjs +1 -1
  620. package/dist/routes/secrets-settings.cjs.map +1 -1
  621. package/dist/routes/secrets-settings.js +19 -27
  622. package/dist/routes/secrets-settings.js.map +1 -1
  623. package/dist/stores/conversation-store.cjs +1 -1
  624. package/dist/stores/conversation-store.cjs.map +1 -1
  625. package/dist/stores/conversation-store.d.ts +4 -0
  626. package/dist/stores/conversation-store.js +6 -0
  627. package/dist/stores/conversation-store.js.map +1 -1
  628. package/dist/types/agent-server/core/events/acp-tool-call-event.d.ts +6 -4
  629. package/dist/types/agent-server/core/events/system-event.d.ts +5 -0
  630. package/dist/types/automation.d.ts +15 -0
  631. package/dist/types/settings.d.ts +3 -1
  632. package/dist/ui/combobox-caret.cjs +1 -1
  633. package/dist/ui/combobox-caret.cjs.map +1 -1
  634. package/dist/ui/combobox-caret.d.ts +1 -1
  635. package/dist/ui/combobox-caret.js +9 -8
  636. package/dist/ui/combobox-caret.js.map +1 -1
  637. package/dist/ui/context-menu.cjs +1 -1
  638. package/dist/ui/context-menu.cjs.map +1 -1
  639. package/dist/ui/context-menu.js +9 -8
  640. package/dist/ui/context-menu.js.map +1 -1
  641. package/dist/ui/dropdown/dropdown-menu.cjs +1 -1
  642. package/dist/ui/dropdown/dropdown-menu.cjs.map +1 -1
  643. package/dist/ui/dropdown/dropdown-menu.js +21 -17
  644. package/dist/ui/dropdown/dropdown-menu.js.map +1 -1
  645. package/dist/ui/dropdown/dropdown.cjs +1 -1
  646. package/dist/ui/dropdown/dropdown.cjs.map +1 -1
  647. package/dist/ui/dropdown/dropdown.js +2 -2
  648. package/dist/ui/dropdown/dropdown.js.map +1 -1
  649. package/dist/utils/automation-schedule.d.ts +1 -0
  650. package/dist/utils/dropdown-classes.cjs +2 -0
  651. package/dist/utils/dropdown-classes.cjs.map +1 -0
  652. package/dist/utils/dropdown-classes.d.ts +32 -0
  653. package/dist/utils/dropdown-classes.js +8 -0
  654. package/dist/utils/dropdown-classes.js.map +1 -0
  655. package/dist/utils/form-control-classes.cjs +1 -1
  656. package/dist/utils/form-control-classes.cjs.map +1 -1
  657. package/dist/utils/form-control-classes.d.ts +18 -2
  658. package/dist/utils/form-control-classes.js +4 -3
  659. package/dist/utils/form-control-classes.js.map +1 -1
  660. package/dist/utils/git-control-bar-classes.cjs +2 -0
  661. package/dist/utils/git-control-bar-classes.cjs.map +1 -0
  662. package/dist/utils/git-control-bar-classes.d.ts +4 -0
  663. package/dist/utils/git-control-bar-classes.js +14 -0
  664. package/dist/utils/git-control-bar-classes.js.map +1 -0
  665. package/dist/utils/handle-event-for-ui.cjs.map +1 -1
  666. package/dist/utils/handle-event-for-ui.d.ts +6 -3
  667. package/dist/utils/handle-event-for-ui.js.map +1 -1
  668. package/dist/utils/mobile-top-bar-icon-button-classes.cjs +1 -1
  669. package/dist/utils/mobile-top-bar-icon-button-classes.cjs.map +1 -1
  670. package/dist/utils/mobile-top-bar-icon-button-classes.js +3 -3
  671. package/dist/utils/mobile-top-bar-icon-button-classes.js.map +1 -1
  672. package/dist/utils/modal-classes.cjs +2 -0
  673. package/dist/utils/modal-classes.cjs.map +1 -0
  674. package/dist/utils/modal-classes.d.ts +8 -0
  675. package/dist/utils/modal-classes.js +7 -0
  676. package/dist/utils/modal-classes.js.map +1 -0
  677. package/dist/utils/openhands-llm.cjs +2 -0
  678. package/dist/utils/openhands-llm.cjs.map +1 -0
  679. package/dist/utils/openhands-llm.d.ts +2 -0
  680. package/dist/utils/openhands-llm.js +9 -0
  681. package/dist/utils/openhands-llm.js.map +1 -0
  682. package/dist/utils/redact-custom-secrets.cjs +2 -0
  683. package/dist/utils/redact-custom-secrets.cjs.map +1 -0
  684. package/dist/utils/redact-custom-secrets.d.ts +6 -0
  685. package/dist/utils/redact-custom-secrets.js +10 -0
  686. package/dist/utils/redact-custom-secrets.js.map +1 -0
  687. package/dist/utils/status.cjs +1 -1
  688. package/dist/utils/status.cjs.map +1 -1
  689. package/dist/utils/status.d.ts +2 -1
  690. package/dist/utils/status.js +9 -8
  691. package/dist/utils/status.js.map +1 -1
  692. package/dist/utils/system-message-adapter.cjs +1 -1
  693. package/dist/utils/system-message-adapter.cjs.map +1 -1
  694. package/dist/utils/system-message-adapter.js +10 -7
  695. package/dist/utils/system-message-adapter.js.map +1 -1
  696. package/dist/utils/utils.cjs +1 -1
  697. package/dist/utils/utils.cjs.map +1 -1
  698. package/dist/utils/utils.d.ts +2 -1
  699. package/dist/utils/utils.js +21 -20
  700. package/dist/utils/utils.js.map +1 -1
  701. package/package.json +1 -1
  702. package/scripts/dev-safe.mjs +3 -1
  703. package/scripts/dev-static.mjs +2 -2
  704. package/scripts/dev-with-automation.mjs +283 -108
  705. package/scripts/static-build.mjs +20 -19
  706. package/scripts/static-server.mjs +50 -3
  707. package/build/assets/acp-providers-CbiRekh9.js +0 -1
  708. package/build/assets/active-backend-context-cCM1vYYZ.js +0 -1
  709. package/build/assets/add-backend-modal-DIUQzMPa.js +0 -1
  710. package/build/assets/agent-server-client-options-Bc5ZorQZ.js +0 -1
  711. package/build/assets/agent-server-compatibility-BlkUsrX2.js +0 -1
  712. package/build/assets/agent-server-conversation-service.api-C2V5SlHu.js +0 -5
  713. package/build/assets/api-key-entry-screen-B2gynaCp.js +0 -1
  714. package/build/assets/automation-detail-DJvbVSYK.js +0 -1
  715. package/build/assets/automations-list-6FDbI5dc.js +0 -1
  716. package/build/assets/backend-form-modal-Dnk33xA_.js +0 -1
  717. package/build/assets/base-modal-_dYTw1ri.js +0 -1
  718. package/build/assets/brand-button-Br7f0kZJ.js +0 -1
  719. package/build/assets/browser-store-Couc4S5D.js +0 -1
  720. package/build/assets/clock-BRjCgHTc.js +0 -1
  721. package/build/assets/combobox-caret-to1O8irE.js +0 -1
  722. package/build/assets/context-menu-list-item-CWNFpuiC.js +0 -1
  723. package/build/assets/conversation-DVrKU0oz.js +0 -19
  724. package/build/assets/conversation-Dlys-D5A.js +0 -1
  725. package/build/assets/conversation-panel-iF09WjZ4.js +0 -1
  726. package/build/assets/conversation-service.api-CCfztilW.js +0 -1
  727. package/build/assets/conversation-state-store-u5jepov0.js +0 -1
  728. package/build/assets/conversation-store-Z5iMCRpc.js +0 -1
  729. package/build/assets/conversation-websocket-context-DhJhqUna.js +0 -3
  730. package/build/assets/declaration-BNMqORFE.js +0 -1
  731. package/build/assets/dist-BxBP7tFD.js +0 -1
  732. package/build/assets/edit-automation-modal-BGzR3nfZ.js +0 -1
  733. package/build/assets/ellipsis-button-ZyLMPURn.js +0 -1
  734. package/build/assets/entry.client-1VMHpktY.js +0 -2
  735. package/build/assets/enum-filter-dropdown-CEgCdu4A.js +0 -1
  736. package/build/assets/extensions-hub-C651jsVh.js +0 -1
  737. package/build/assets/files-tab-R5z0lLdY.js +0 -1
  738. package/build/assets/files-tab-store-CDyVTXNT.js +0 -1
  739. package/build/assets/git-control-bar-branch-button-COdRAYHb.js +0 -27
  740. package/build/assets/git-provider-icon-BzLbc0yC.js +0 -1
  741. package/build/assets/home-e-egNUXZ.js +0 -1
  742. package/build/assets/install-server-modal-DHlbgqVH.js +0 -1
  743. package/build/assets/launch-CshDse3e.js +0 -1
  744. package/build/assets/link-external-D2POYx4c.js +0 -1
  745. package/build/assets/llm-settings-Bql-vydt.js +0 -1
  746. package/build/assets/llm-settings-C_tal6Ds.js +0 -1
  747. package/build/assets/manage-backends-modal-l7RkKfwX.js +0 -1
  748. package/build/assets/manage-workspaces-modal-DhKF_8z3.js +0 -1
  749. package/build/assets/manifest-3bf30d69.js +0 -1
  750. package/build/assets/mcp-ByeBfdfU.js +0 -9
  751. package/build/assets/messages-D0rWot7s.js +0 -36
  752. package/build/assets/proxy-CxydCnis.js +0 -1
  753. package/build/assets/root-DHeCXo9N.css +0 -1
  754. package/build/assets/root-layout-Czo9Ma6Q.js +0 -2
  755. package/build/assets/secrets-service-BsnKFc2x.js +0 -1
  756. package/build/assets/secrets-settings-Bz_UohPJ.js +0 -1
  757. package/build/assets/settings-client-C73C7IgV.js +0 -1
  758. package/build/assets/settings-index-Dz0BmdJD.js +0 -1
  759. package/build/assets/settings-list-classes-Bf80tWtc.js +0 -1
  760. package/build/assets/settings-modal-Brzgh5Yw.js +0 -1
  761. package/build/assets/settings-service.api-CZ3uWx4v.js +0 -1
  762. package/build/assets/sidebar-mobile-menu-toggle-Do_aA9Zm.js +0 -1
  763. package/build/assets/skills-settings-DlA5hlXw.js +0 -2
  764. package/build/assets/status-hp6M6E7E.js +0 -1
  765. package/build/assets/use-agent-settings-schema-33Un7UF2.js +0 -1
  766. package/build/assets/use-is-authed-BggE5wPj.js +0 -1
  767. package/build/assets/use-llm-profiles-DDOol3gK.js +0 -1
  768. package/build/assets/use-runtime-is-ready-B7EF4BKU.js +0 -1
  769. package/build/assets/use-settings-DQIZmIov.js +0 -1
  770. package/build/assets/use-user-conversation-C6hrMMtn.js +0 -1
  771. package/build/assets/utils-i18rdUj2.js +0 -1
  772. package/build/assets/vendor~conversation-panel~conversation-a9SyrrhV.js +0 -1
  773. package/build/assets/vendor~conversation-panel~conversation~index-C23ZXO4R.js +0 -1
  774. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~i4kjfqhl-BebWhFNT.js +0 -1
  775. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-DzIXV3Ui.js +0 -9
  776. /package/build/assets/{automation-IdgZq6ZK.js → automation-XDPAjiZi.js} +0 -0
  777. /package/build/assets/{color-themes-DSaoIL6A.js → color-themes-B9pm9c-R.js} +0 -0
  778. /package/build/assets/{common-DR1t-EeP.js → common-DqjLSBOt.js} +0 -0
  779. /package/build/assets/{conversation-local-storage-UYl-SX-r.js → conversation-local-storage-YmOVXxxW.js} +0 -0
  780. /package/build/assets/{dist-C6t0EXL7.js → dist-C3NfioQC.js} +0 -0
  781. /package/build/assets/{environment-switch-store-C4ulFJKp.js → environment-switch-store-CiurvTtK.js} +0 -0
  782. /package/build/assets/{health-store-BDC2rM-X.js → health-store-B5f0S2FY.js} +0 -0
  783. /package/build/assets/{map-provider-COBVzZYo.js → map-provider-BJ_8KZKU.js} +0 -0
  784. /package/build/assets/{middleware-BC9EwbB9.js → middleware-CfatjPYZ.js} +0 -0
  785. /package/build/assets/{objectWithoutPropertiesLoose-Du6eBn-V.js → objectWithoutPropertiesLoose-DSQKyRhw.js} +0 -0
  786. /package/build/assets/{react-Do0CT17Y.js → react-Dy05vyj5.js} +0 -0
  787. /package/build/assets/{sdk-settings-field-metadata-CBPmeqYa.js → sdk-settings-field-metadata-DQiaIBie.js} +0 -0
  788. /package/build/assets/{settings-D_H-qsRm.js → settings-DGY6n4J2.js} +0 -0
  789. /package/build/assets/{settings-like-page-layout-classes-I0BDBEoq.js → settings-like-page-layout-classes-D7YjdTd0.js} +0 -0
  790. /package/build/assets/{use-breakpoint-DbJ6FkQ-.js → use-breakpoint-DF_RiQ6s.js} +0 -0
  791. /package/build/assets/{use-click-outside-element-DffgWWoZ.js → use-click-outside-element-DhxCUyWl.js} +0 -0
  792. /package/build/assets/{v4-CNn21NXa.js → v4-khGvL7i2.js} +0 -0
  793. /package/build/assets/{vendor~browser-DDiZgqD3.js → vendor~browser-DisFGEp9.js} +0 -0
  794. /package/build/assets/{vendor~browser-tab-BgwV1mxF.js → vendor~browser-tab-BxhTtM9_.js} +0 -0
  795. /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-DbvX3OcM.js → vendor~conversation-panel~conversation~alert-banner-w-I2sY6c.js} +0 -0
  796. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~zm51vy4j-iOsylxCS.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~zm51vy4j-BClAMeFe.js} +0 -0
  797. /package/build/assets/{vendor~files-tab-BGKayPiK.js → vendor~files-tab-BtkpAiMX.js} +0 -0
  798. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BW6261Sb.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CyZ-3lDQ.js} +0 -0
  799. /package/build/assets/{vendor~home~mcp~automations-list-DoPfwaXj.js → vendor~home~mcp~automations-list-BgV86Sti.js} +0 -0
  800. /package/build/assets/{vendor~launch-vdeRTWFu.js → vendor~launch-BXgl67Re.js} +0 -0
  801. /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~ninslayh-D9P8e98a.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~ninslayh-CLlsvdNP.js} +0 -0
  802. /package/build/assets/{vendor~terminal-DUrOWGFE.js → vendor~terminal-DZaJIY8A.js} +0 -0
@@ -1,31 +1,32 @@
1
1
  import { cn as e } from "../../../../utils/utils.js";
2
2
  import { ModalBody as t } from "../modal-body.js";
3
3
  import { ModalButton as n } from "../../buttons/modal-button.js";
4
+ import { modalTitleClassName as r } from "../../../../utils/modal-classes.js";
4
5
  import "react";
5
- import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
7
  //#region src/components/shared/modals/confirmation-modals/base-modal.tsx
7
- function a({ title: t, id: n, className: i }) {
8
- return /* @__PURE__ */ r("span", {
8
+ function o({ title: t, id: n, className: a }) {
9
+ return /* @__PURE__ */ i("span", {
9
10
  id: n,
10
- className: e("text-xl leading-6 -tracking-[0.01em] font-medium text-content-2", i),
11
+ className: e(r, a),
11
12
  children: t
12
13
  });
13
14
  }
14
- function o({ description: e, children: t }) {
15
- return /* @__PURE__ */ r("span", {
15
+ function s({ description: e, children: t }) {
16
+ return /* @__PURE__ */ i("span", {
16
17
  className: "text-xs text-modal-muted",
17
18
  children: t || e
18
19
  });
19
20
  }
20
- function s({ testId: e, title: s, description: c, buttons: l }) {
21
- return /* @__PURE__ */ i(t, {
21
+ function c({ testId: e, title: r, description: c, buttons: l }) {
22
+ return /* @__PURE__ */ a(t, {
22
23
  testID: e,
23
- children: [/* @__PURE__ */ i("div", {
24
+ children: [/* @__PURE__ */ a("div", {
24
25
  className: "flex flex-col gap-2 self-start",
25
- children: [/* @__PURE__ */ r(a, { title: s }), /* @__PURE__ */ r(o, { description: c })]
26
- }), /* @__PURE__ */ r("div", {
26
+ children: [/* @__PURE__ */ i(o, { title: r }), /* @__PURE__ */ i(s, { description: c })]
27
+ }), /* @__PURE__ */ i("div", {
27
28
  className: "flex flex-col gap-2 w-full",
28
- children: l.map((e, t) => /* @__PURE__ */ r(n, {
29
+ children: l.map((e, t) => /* @__PURE__ */ i(n, {
29
30
  onClick: e.onClick,
30
31
  text: e.text,
31
32
  className: e.className
@@ -34,6 +35,6 @@ function s({ testId: e, title: s, description: c, buttons: l }) {
34
35
  });
35
36
  }
36
37
  //#endregion
37
- export { s as BaseModal, o as BaseModalDescription, a as BaseModalTitle };
38
+ export { c as BaseModal, s as BaseModalDescription, o as BaseModalTitle };
38
39
 
39
40
  //# sourceMappingURL=base-modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-modal.js","names":[],"sources":["../../../../../src/components/shared/modals/confirmation-modals/base-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { ModalBody } from \"../modal-body\";\nimport { ModalButton } from \"../../buttons/modal-button\";\nimport { cn } from \"#/utils/utils\";\n\ninterface ButtonConfig {\n text: string;\n onClick: () => void;\n className: React.HTMLProps<HTMLButtonElement>[\"className\"];\n}\n\ninterface BaseModalTitleProps {\n title: React.ReactNode;\n id?: string;\n className?: string;\n}\n\nexport function BaseModalTitle({ title, id, className }: BaseModalTitleProps) {\n return (\n <span\n id={id}\n className={cn(\n \"text-xl leading-6 -tracking-[0.01em] font-medium text-content-2\",\n className,\n )}\n >\n {title}\n </span>\n );\n}\n\ninterface BaseModalDescriptionProps {\n description?: React.ReactNode;\n children?: React.ReactNode;\n}\n\nexport function BaseModalDescription({\n description,\n children,\n}: BaseModalDescriptionProps) {\n return (\n <span className=\"text-xs text-modal-muted\">{children || description}</span>\n );\n}\n\ninterface BaseModalProps {\n testId?: string;\n title: string;\n description: string;\n buttons: ButtonConfig[];\n}\n\nexport function BaseModal({\n testId,\n title,\n description,\n buttons,\n}: BaseModalProps) {\n return (\n <ModalBody testID={testId}>\n <div className=\"flex flex-col gap-2 self-start\">\n <BaseModalTitle title={title} />\n <BaseModalDescription description={description} />\n </div>\n\n <div className=\"flex flex-col gap-2 w-full\">\n {buttons.map((button, index) => (\n <ModalButton\n key={index}\n onClick={button.onClick}\n text={button.text}\n className={button.className}\n />\n ))}\n </div>\n </ModalBody>\n );\n}\n"],"mappings":";;;;;;AAiBA,SAAgB,EAAe,EAAE,UAAO,OAAI,gBAAkC;AAC5E,QACE,kBAAC,QAAD;EACM;EACJ,WAAW,EACT,mEACA,EACD;YAEA;EACI,CAAA;;AASX,SAAgB,EAAqB,EACnC,gBACA,eAC4B;AAC5B,QACE,kBAAC,QAAD;EAAM,WAAU;YAA4B,KAAY;EAAmB,CAAA;;AAW/E,SAAgB,EAAU,EACxB,WACA,UACA,gBACA,cACiB;AACjB,QACE,kBAAC,GAAD;EAAW,QAAQ;YAAnB,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAuB,UAAS,CAAA,EAChC,kBAAC,GAAD,EAAmC,gBAAe,CAAA,CAC9C;MAEN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAQ,KAAK,GAAQ,MACpB,kBAAC,GAAD;IAEE,SAAS,EAAO;IAChB,MAAM,EAAO;IACb,WAAW,EAAO;IAClB,EAJK,EAIL,CACF;GACE,CAAA,CACI"}
1
+ {"version":3,"file":"base-modal.js","names":[],"sources":["../../../../../src/components/shared/modals/confirmation-modals/base-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { ModalBody } from \"../modal-body\";\nimport { ModalButton } from \"../../buttons/modal-button\";\nimport { cn } from \"#/utils/utils\";\nimport { modalTitleClassName } from \"#/utils/modal-classes\";\n\ninterface ButtonConfig {\n text: string;\n onClick: () => void;\n className: React.HTMLProps<HTMLButtonElement>[\"className\"];\n}\n\ninterface BaseModalTitleProps {\n title: React.ReactNode;\n id?: string;\n className?: string;\n}\n\nexport function BaseModalTitle({ title, id, className }: BaseModalTitleProps) {\n return (\n <span id={id} className={cn(modalTitleClassName, className)}>\n {title}\n </span>\n );\n}\n\ninterface BaseModalDescriptionProps {\n description?: React.ReactNode;\n children?: React.ReactNode;\n}\n\nexport function BaseModalDescription({\n description,\n children,\n}: BaseModalDescriptionProps) {\n return (\n <span className=\"text-xs text-modal-muted\">{children || description}</span>\n );\n}\n\ninterface BaseModalProps {\n testId?: string;\n title: string;\n description: string;\n buttons: ButtonConfig[];\n}\n\nexport function BaseModal({\n testId,\n title,\n description,\n buttons,\n}: BaseModalProps) {\n return (\n <ModalBody testID={testId}>\n <div className=\"flex flex-col gap-2 self-start\">\n <BaseModalTitle title={title} />\n <BaseModalDescription description={description} />\n </div>\n\n <div className=\"flex flex-col gap-2 w-full\">\n {buttons.map((button, index) => (\n <ModalButton\n key={index}\n onClick={button.onClick}\n text={button.text}\n className={button.className}\n />\n ))}\n </div>\n </ModalBody>\n );\n}\n"],"mappings":";;;;;;;AAkBA,SAAgB,EAAe,EAAE,UAAO,OAAI,gBAAkC;AAC5E,QACE,kBAAC,QAAD;EAAU;EAAI,WAAW,EAAG,GAAqB,EAAU;YACxD;EACI,CAAA;;AASX,SAAgB,EAAqB,EACnC,gBACA,eAC4B;AAC5B,QACE,kBAAC,QAAD;EAAM,WAAU;YAA4B,KAAY;EAAmB,CAAA;;AAW/E,SAAgB,EAAU,EACxB,WACA,UACA,gBACA,cACiB;AACjB,QACE,kBAAC,GAAD;EAAW,QAAQ;YAAnB,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAuB,UAAS,CAAA,EAChC,kBAAC,GAAD,EAAmC,gBAAe,CAAA,CAC9C;MAEN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAQ,KAAK,GAAQ,MACpB,kBAAC,GAAD;IAEE,SAAS,EAAO;IAChB,MAAM,EAAO;IACb,WAAW,EAAO;IAClB,EAJK,EAIL,CACF;GACE,CAAA,CACI"}
@@ -1,2 +1,2 @@
1
- require(`../../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../../i18n/declaration.cjs`),n=require(`../../../../utils/utils.cjs`),r=require(`../../../../services/settings.cjs`),i=require(`../modal-backdrop.cjs`),a=require(`../modal-body.cjs`),o=require(`../../../../ui/help-link.cjs`),s=require(`./settings-form.cjs`);let c=require(`react/jsx-runtime`);function l({onClose:l,settings:u}){let{t:d}=e.useTranslation(`openhands`);return(0,c.jsx)(i.ModalBackdrop,{children:(0,c.jsxs)(`div`,{"data-testid":`ai-config-modal`,className:n.cn(`bg-[var(--oh-surface)] m-4 p-6 rounded-xl flex flex-col gap-[17px] border border-[var(--oh-border)] api-configuration-modal`,a.modalWidthClassName(`md`),a.MODAL_MAX_WIDTH_VIEWPORT),children:[(0,c.jsx)(`span`,{className:`text-5 leading-6 font-medium -tracking-[0.2px]`,children:d(t.I18nKey.AI_SETTINGS$TITLE)}),(0,c.jsx)(o.HelpLink,{testId:`advanced-settings-link`,text:`${d(t.I18nKey.SETTINGS$DESCRIPTION)}. ${d(t.I18nKey.SETTINGS$FOR_OTHER_OPTIONS)} ${d(t.I18nKey.COMMON$SEE)}`,linkText:d(t.I18nKey.COMMON$ADVANCED_SETTINGS),href:`/settings`,suffix:`.`,size:`settings`,linkColor:`white`,suffixClassName:`text-white`}),(0,c.jsx)(s.SettingsForm,{settings:u||r.DEFAULT_SETTINGS,onClose:l})]})})}exports.SettingsModal=l;
1
+ require(`../../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../../i18n/declaration.cjs`),n=require(`../../../../utils/utils.cjs`),r=require(`../../../../services/settings.cjs`),i=require(`../modal-backdrop.cjs`),a=require(`../modal-body.cjs`),o=require(`../../../../utils/modal-classes.cjs`),s=require(`../../../../ui/help-link.cjs`),c=require(`./settings-form.cjs`);let l=require(`react/jsx-runtime`);function u({onClose:u,settings:d}){let{t:f}=e.useTranslation(`openhands`);return(0,l.jsx)(i.ModalBackdrop,{children:(0,l.jsxs)(`div`,{"data-testid":`ai-config-modal`,className:n.cn(`bg-[var(--oh-surface)] m-4 p-6 rounded-xl flex flex-col gap-[17px] border border-[var(--oh-border)] api-configuration-modal`,a.modalWidthClassName(`md`),a.MODAL_MAX_WIDTH_VIEWPORT),children:[(0,l.jsx)(`span`,{className:o.modalTitleClassName,children:f(t.I18nKey.AI_SETTINGS$TITLE)}),(0,l.jsx)(s.HelpLink,{testId:`advanced-settings-link`,text:`${f(t.I18nKey.SETTINGS$DESCRIPTION)}. ${f(t.I18nKey.SETTINGS$FOR_OTHER_OPTIONS)} ${f(t.I18nKey.COMMON$SEE)}`,linkText:f(t.I18nKey.COMMON$ADVANCED_SETTINGS),href:`/settings`,suffix:`.`,size:`settings`,linkColor:`white`,suffixClassName:`text-white`}),(0,l.jsx)(c.SettingsForm,{settings:d||r.DEFAULT_SETTINGS,onClose:u})]})})}exports.SettingsModal=u;
2
2
  //# sourceMappingURL=settings-modal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings-modal.cjs","names":[],"sources":["../../../../../src/components/shared/modals/settings/settings-modal.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"../modal-backdrop\";\nimport { MODAL_MAX_WIDTH_VIEWPORT, modalWidthClassName } from \"../modal-body\";\nimport { cn } from \"#/utils/utils\";\nimport { SettingsForm } from \"./settings-form\";\nimport { Settings } from \"#/types/settings\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { HelpLink } from \"#/ui/help-link\";\n\ninterface SettingsModalProps {\n settings?: Settings;\n onClose: () => void;\n}\n\nexport function SettingsModal({ onClose, settings }: SettingsModalProps) {\n const { t } = useTranslation(\"openhands\");\n\n return (\n <ModalBackdrop>\n <div\n data-testid=\"ai-config-modal\"\n className={cn(\n \"bg-[var(--oh-surface)] m-4 p-6 rounded-xl flex flex-col gap-[17px] border border-[var(--oh-border)] api-configuration-modal\",\n modalWidthClassName(\"md\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n )}\n >\n <span className=\"text-5 leading-6 font-medium -tracking-[0.2px]\">\n {t(I18nKey.AI_SETTINGS$TITLE)}\n </span>\n <HelpLink\n testId=\"advanced-settings-link\"\n text={`${t(I18nKey.SETTINGS$DESCRIPTION)}. ${t(I18nKey.SETTINGS$FOR_OTHER_OPTIONS)} ${t(I18nKey.COMMON$SEE)}`}\n linkText={t(I18nKey.COMMON$ADVANCED_SETTINGS)}\n href=\"/settings\"\n suffix=\".\"\n size=\"settings\"\n linkColor=\"white\"\n suffixClassName=\"text-white\"\n />\n\n <SettingsForm\n settings={settings || DEFAULT_SETTINGS}\n onClose={onClose}\n />\n </div>\n </ModalBackdrop>\n );\n}\n"],"mappings":"icAeA,SAAgB,EAAc,CAAE,UAAS,YAAgC,CACvE,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CAEzC,OACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAAA,UACE,EAAA,EAAA,MAAC,MAAD,CACE,cAAY,kBACZ,UAAW,EAAA,GACT,8HACA,EAAA,oBAAoB,KAAK,CACzB,EAAA,yBACD,UANH,EAQE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,0DACb,EAAE,EAAA,QAAQ,kBAAkB,CACxB,CAAA,EACP,EAAA,EAAA,KAAC,EAAA,SAAD,CACE,OAAO,yBACP,KAAM,GAAG,EAAE,EAAA,QAAQ,qBAAqB,CAAC,IAAI,EAAE,EAAA,QAAQ,2BAA2B,CAAC,GAAG,EAAE,EAAA,QAAQ,WAAW,GAC3G,SAAU,EAAE,EAAA,QAAQ,yBAAyB,CAC7C,KAAK,YACL,OAAO,IACP,KAAK,WACL,UAAU,QACV,gBAAgB,aAChB,CAAA,EAEF,EAAA,EAAA,KAAC,EAAA,aAAD,CACE,SAAU,GAAY,EAAA,iBACb,UACT,CAAA,CACE,GACQ,CAAA"}
1
+ {"version":3,"file":"settings-modal.cjs","names":[],"sources":["../../../../../src/components/shared/modals/settings/settings-modal.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"../modal-backdrop\";\nimport { MODAL_MAX_WIDTH_VIEWPORT, modalWidthClassName } from \"../modal-body\";\nimport { cn } from \"#/utils/utils\";\nimport { SettingsForm } from \"./settings-form\";\nimport { Settings } from \"#/types/settings\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { HelpLink } from \"#/ui/help-link\";\nimport { modalTitleClassName } from \"#/utils/modal-classes\";\n\ninterface SettingsModalProps {\n settings?: Settings;\n onClose: () => void;\n}\n\nexport function SettingsModal({ onClose, settings }: SettingsModalProps) {\n const { t } = useTranslation(\"openhands\");\n\n return (\n <ModalBackdrop>\n <div\n data-testid=\"ai-config-modal\"\n className={cn(\n \"bg-[var(--oh-surface)] m-4 p-6 rounded-xl flex flex-col gap-[17px] border border-[var(--oh-border)] api-configuration-modal\",\n modalWidthClassName(\"md\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n )}\n >\n <span className={modalTitleClassName}>\n {t(I18nKey.AI_SETTINGS$TITLE)}\n </span>\n <HelpLink\n testId=\"advanced-settings-link\"\n text={`${t(I18nKey.SETTINGS$DESCRIPTION)}. ${t(I18nKey.SETTINGS$FOR_OTHER_OPTIONS)} ${t(I18nKey.COMMON$SEE)}`}\n linkText={t(I18nKey.COMMON$ADVANCED_SETTINGS)}\n href=\"/settings\"\n suffix=\".\"\n size=\"settings\"\n linkColor=\"white\"\n suffixClassName=\"text-white\"\n />\n\n <SettingsForm\n settings={settings || DEFAULT_SETTINGS}\n onClose={onClose}\n />\n </div>\n </ModalBackdrop>\n );\n}\n"],"mappings":"kfAgBA,SAAgB,EAAc,CAAE,UAAS,YAAgC,CACvE,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CAEzC,OACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAAA,UACE,EAAA,EAAA,MAAC,MAAD,CACE,cAAY,kBACZ,UAAW,EAAA,GACT,8HACA,EAAA,oBAAoB,KAAK,CACzB,EAAA,yBACD,UANH,EAQE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,6BACd,EAAE,EAAA,QAAQ,kBAAkB,CACxB,CAAA,EACP,EAAA,EAAA,KAAC,EAAA,SAAD,CACE,OAAO,yBACP,KAAM,GAAG,EAAE,EAAA,QAAQ,qBAAqB,CAAC,IAAI,EAAE,EAAA,QAAQ,2BAA2B,CAAC,GAAG,EAAE,EAAA,QAAQ,WAAW,GAC3G,SAAU,EAAE,EAAA,QAAQ,yBAAyB,CAC7C,KAAK,YACL,OAAO,IACP,KAAK,WACL,UAAU,QACV,gBAAgB,aAChB,CAAA,EAEF,EAAA,EAAA,KAAC,EAAA,aAAD,CACE,SAAU,GAAY,EAAA,iBACb,UACT,CAAA,CACE,GACQ,CAAA"}
@@ -4,38 +4,39 @@ import { cn as n } from "../../../../utils/utils.js";
4
4
  import { DEFAULT_SETTINGS as r } from "../../../../services/settings.js";
5
5
  import { ModalBackdrop as i } from "../modal-backdrop.js";
6
6
  import { MODAL_MAX_WIDTH_VIEWPORT as a, modalWidthClassName as o } from "../modal-body.js";
7
- import { HelpLink as s } from "../../../../ui/help-link.js";
8
- import { SettingsForm as c } from "./settings-form.js";
9
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
+ import { modalTitleClassName as s } from "../../../../utils/modal-classes.js";
8
+ import { HelpLink as c } from "../../../../ui/help-link.js";
9
+ import { SettingsForm as l } from "./settings-form.js";
10
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
10
11
  //#region src/components/shared/modals/settings/settings-modal.tsx
11
- function d({ onClose: d, settings: f }) {
12
- let { t: p } = e("openhands");
13
- return /* @__PURE__ */ l(i, { children: /* @__PURE__ */ u("div", {
12
+ function f({ onClose: f, settings: p }) {
13
+ let { t: m } = e("openhands");
14
+ return /* @__PURE__ */ u(i, { children: /* @__PURE__ */ d("div", {
14
15
  "data-testid": "ai-config-modal",
15
16
  className: n("bg-[var(--oh-surface)] m-4 p-6 rounded-xl flex flex-col gap-[17px] border border-[var(--oh-border)] api-configuration-modal", o("md"), a),
16
17
  children: [
17
- /* @__PURE__ */ l("span", {
18
- className: "text-5 leading-6 font-medium -tracking-[0.2px]",
19
- children: p(t.AI_SETTINGS$TITLE)
18
+ /* @__PURE__ */ u("span", {
19
+ className: s,
20
+ children: m(t.AI_SETTINGS$TITLE)
20
21
  }),
21
- /* @__PURE__ */ l(s, {
22
+ /* @__PURE__ */ u(c, {
22
23
  testId: "advanced-settings-link",
23
- text: `${p(t.SETTINGS$DESCRIPTION)}. ${p(t.SETTINGS$FOR_OTHER_OPTIONS)} ${p(t.COMMON$SEE)}`,
24
- linkText: p(t.COMMON$ADVANCED_SETTINGS),
24
+ text: `${m(t.SETTINGS$DESCRIPTION)}. ${m(t.SETTINGS$FOR_OTHER_OPTIONS)} ${m(t.COMMON$SEE)}`,
25
+ linkText: m(t.COMMON$ADVANCED_SETTINGS),
25
26
  href: "/settings",
26
27
  suffix: ".",
27
28
  size: "settings",
28
29
  linkColor: "white",
29
30
  suffixClassName: "text-white"
30
31
  }),
31
- /* @__PURE__ */ l(c, {
32
- settings: f || r,
33
- onClose: d
32
+ /* @__PURE__ */ u(l, {
33
+ settings: p || r,
34
+ onClose: f
34
35
  })
35
36
  ]
36
37
  }) });
37
38
  }
38
39
  //#endregion
39
- export { d as SettingsModal };
40
+ export { f as SettingsModal };
40
41
 
41
42
  //# sourceMappingURL=settings-modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings-modal.js","names":[],"sources":["../../../../../src/components/shared/modals/settings/settings-modal.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"../modal-backdrop\";\nimport { MODAL_MAX_WIDTH_VIEWPORT, modalWidthClassName } from \"../modal-body\";\nimport { cn } from \"#/utils/utils\";\nimport { SettingsForm } from \"./settings-form\";\nimport { Settings } from \"#/types/settings\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { HelpLink } from \"#/ui/help-link\";\n\ninterface SettingsModalProps {\n settings?: Settings;\n onClose: () => void;\n}\n\nexport function SettingsModal({ onClose, settings }: SettingsModalProps) {\n const { t } = useTranslation(\"openhands\");\n\n return (\n <ModalBackdrop>\n <div\n data-testid=\"ai-config-modal\"\n className={cn(\n \"bg-[var(--oh-surface)] m-4 p-6 rounded-xl flex flex-col gap-[17px] border border-[var(--oh-border)] api-configuration-modal\",\n modalWidthClassName(\"md\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n )}\n >\n <span className=\"text-5 leading-6 font-medium -tracking-[0.2px]\">\n {t(I18nKey.AI_SETTINGS$TITLE)}\n </span>\n <HelpLink\n testId=\"advanced-settings-link\"\n text={`${t(I18nKey.SETTINGS$DESCRIPTION)}. ${t(I18nKey.SETTINGS$FOR_OTHER_OPTIONS)} ${t(I18nKey.COMMON$SEE)}`}\n linkText={t(I18nKey.COMMON$ADVANCED_SETTINGS)}\n href=\"/settings\"\n suffix=\".\"\n size=\"settings\"\n linkColor=\"white\"\n suffixClassName=\"text-white\"\n />\n\n <SettingsForm\n settings={settings || DEFAULT_SETTINGS}\n onClose={onClose}\n />\n </div>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;AAeA,SAAgB,EAAc,EAAE,YAAS,eAAgC;CACvE,IAAM,EAAE,SAAM,EAAe,YAAY;AAEzC,QACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;EACE,eAAY;EACZ,WAAW,EACT,+HACA,EAAoB,KAAK,EACzB,EACD;YANH;GAQE,kBAAC,QAAD;IAAM,WAAU;cACb,EAAE,EAAQ,kBAAkB;IACxB,CAAA;GACP,kBAAC,GAAD;IACE,QAAO;IACP,MAAM,GAAG,EAAE,EAAQ,qBAAqB,CAAC,IAAI,EAAE,EAAQ,2BAA2B,CAAC,GAAG,EAAE,EAAQ,WAAW;IAC3G,UAAU,EAAE,EAAQ,yBAAyB;IAC7C,MAAK;IACL,QAAO;IACP,MAAK;IACL,WAAU;IACV,iBAAgB;IAChB,CAAA;GAEF,kBAAC,GAAD;IACE,UAAU,KAAY;IACb;IACT,CAAA;GACE;KACQ,CAAA"}
1
+ {"version":3,"file":"settings-modal.js","names":[],"sources":["../../../../../src/components/shared/modals/settings/settings-modal.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ModalBackdrop } from \"../modal-backdrop\";\nimport { MODAL_MAX_WIDTH_VIEWPORT, modalWidthClassName } from \"../modal-body\";\nimport { cn } from \"#/utils/utils\";\nimport { SettingsForm } from \"./settings-form\";\nimport { Settings } from \"#/types/settings\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { HelpLink } from \"#/ui/help-link\";\nimport { modalTitleClassName } from \"#/utils/modal-classes\";\n\ninterface SettingsModalProps {\n settings?: Settings;\n onClose: () => void;\n}\n\nexport function SettingsModal({ onClose, settings }: SettingsModalProps) {\n const { t } = useTranslation(\"openhands\");\n\n return (\n <ModalBackdrop>\n <div\n data-testid=\"ai-config-modal\"\n className={cn(\n \"bg-[var(--oh-surface)] m-4 p-6 rounded-xl flex flex-col gap-[17px] border border-[var(--oh-border)] api-configuration-modal\",\n modalWidthClassName(\"md\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n )}\n >\n <span className={modalTitleClassName}>\n {t(I18nKey.AI_SETTINGS$TITLE)}\n </span>\n <HelpLink\n testId=\"advanced-settings-link\"\n text={`${t(I18nKey.SETTINGS$DESCRIPTION)}. ${t(I18nKey.SETTINGS$FOR_OTHER_OPTIONS)} ${t(I18nKey.COMMON$SEE)}`}\n linkText={t(I18nKey.COMMON$ADVANCED_SETTINGS)}\n href=\"/settings\"\n suffix=\".\"\n size=\"settings\"\n linkColor=\"white\"\n suffixClassName=\"text-white\"\n />\n\n <SettingsForm\n settings={settings || DEFAULT_SETTINGS}\n onClose={onClose}\n />\n </div>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;;AAgBA,SAAgB,EAAc,EAAE,YAAS,eAAgC;CACvE,IAAM,EAAE,SAAM,EAAe,YAAY;AAEzC,QACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;EACE,eAAY;EACZ,WAAW,EACT,+HACA,EAAoB,KAAK,EACzB,EACD;YANH;GAQE,kBAAC,QAAD;IAAM,WAAW;cACd,EAAE,EAAQ,kBAAkB;IACxB,CAAA;GACP,kBAAC,GAAD;IACE,QAAO;IACP,MAAM,GAAG,EAAE,EAAQ,qBAAqB,CAAC,IAAI,EAAE,EAAQ,2BAA2B,CAAC,GAAG,EAAE,EAAQ,WAAW;IAC3G,UAAU,EAAE,EAAQ,yBAAyB;IAC7C,MAAK;IACL,QAAO;IACP,MAAK;IACL,WAAU;IACV,iBAAgB;IAChB,CAAA;GAEF,kBAAC,GAAD;IACE,UAAU,KAAY;IACb;IACT,CAAA;GACE;KACQ,CAAA"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../../_virtual/_rolldown/runtime.cjs`),t=require(`../../utils/utils.cjs`),n=require(`../../node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.cjs`);let r=require(`react`);r=e.__toESM(r,1);let i=require(`react/jsx-runtime`);var a=`200%`,o=8,s=o*2;function c({children:e,as:c=`p`,className:l,duration:u=2,spread:d=2,style:f,...p}){let m=n.useReducedMotion(),h=`oh-text-shimmer-${(0,r.useId)().replace(/:/g,``)}`,g=(0,r.useMemo)(()=>Math.min(o/2-1,1+d/2),[d]),_=(0,r.useMemo)(()=>{let e=o/2;return{...f,backgroundImage:`repeating-linear-gradient(90deg, var(--oh-muted) 0%, var(--oh-muted) ${e-g}%, var(--oh-foreground) ${e}%, var(--oh-muted) ${e+g}%, var(--oh-muted) ${o}%)`,backgroundSize:`${a} 100%`,backgroundRepeat:`no-repeat`,WebkitBackgroundClip:`text`,backgroundClip:`text`,color:`transparent`,WebkitTextFillColor:`transparent`,animation:`${h} ${u}s linear infinite`}},[h,g,u,f]);return m?(0,i.jsx)(c,{className:t.cn(`text-[var(--oh-muted)]`,l),style:f,...p,children:e}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`style`,{dangerouslySetInnerHTML:{__html:`@keyframes ${h}{from{background-position:${s}% center}to{background-position:0% center}}`}}),(0,i.jsx)(c,{className:t.cn(`relative inline-block`,l),style:_,...p,children:e})]})}var l=r.default.memo(c);exports.TextShimmer=l;
2
+ //# sourceMappingURL=text-shimmer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-shimmer.cjs","names":[],"sources":["../../../src/components/shared/text-shimmer.tsx"],"sourcesContent":["import React, { useId, useMemo } from \"react\";\nimport { useReducedMotion } from \"framer-motion\";\nimport { cn } from \"#/utils/utils\";\n\n/**\n * The gradient is an oversized repeating pattern; animating background-position\n * by exactly one period loops with no visible jump and no muted gap between\n * sweeps (the pattern is periodic, so a highlight is always near the text).\n */\nconst SHIMMER_BACKGROUND_SIZE = \"200%\";\n/** Gradient period as a percentage of the (oversized) background image. */\nconst SHIMMER_PERIOD = 8;\n/** Shifting background-position by one period == 2 * period (image is 2x wide). */\nconst SHIMMER_TRAVEL = SHIMMER_PERIOD * 2;\n\nexport type TextShimmerProps = {\n children: string;\n as?: React.ElementType;\n className?: string;\n duration?: number;\n spread?: number;\n} & Omit<React.HTMLAttributes<HTMLElement>, \"children\" | \"className\">;\n\nfunction TextShimmerComponent({\n children,\n as: Component = \"p\",\n className,\n duration = 2,\n spread = 2,\n style,\n ...rest\n}: TextShimmerProps) {\n const reduceMotion = useReducedMotion();\n const reactId = useId();\n const animationName = `oh-text-shimmer-${reactId.replace(/:/g, \"\")}`;\n\n // Wider spread => wider bright band within each repeating period.\n const bandHalfWidth = useMemo(\n () => Math.min(SHIMMER_PERIOD / 2 - 1, 1 + spread / 2),\n [spread],\n );\n\n const shimmerStyle = useMemo(() => {\n const center = SHIMMER_PERIOD / 2;\n return {\n ...style,\n backgroundImage: `repeating-linear-gradient(90deg, var(--oh-muted) 0%, var(--oh-muted) ${center - bandHalfWidth}%, var(--oh-foreground) ${center}%, var(--oh-muted) ${center + bandHalfWidth}%, var(--oh-muted) ${SHIMMER_PERIOD}%)`,\n backgroundSize: `${SHIMMER_BACKGROUND_SIZE} 100%`,\n backgroundRepeat: \"no-repeat\",\n WebkitBackgroundClip: \"text\",\n backgroundClip: \"text\",\n color: \"transparent\",\n WebkitTextFillColor: \"transparent\",\n animation: `${animationName} ${duration}s linear infinite`,\n } as React.CSSProperties;\n }, [animationName, bandHalfWidth, duration, style]);\n\n if (reduceMotion) {\n return (\n <Component\n className={cn(\"text-[var(--oh-muted)]\", className)}\n style={style}\n {...rest}\n >\n {children}\n </Component>\n );\n }\n\n return (\n <>\n <style\n dangerouslySetInnerHTML={{\n __html: `@keyframes ${animationName}{from{background-position:${SHIMMER_TRAVEL}% center}to{background-position:0% center}}`,\n }}\n />\n <Component\n className={cn(\"relative inline-block\", className)}\n style={shimmerStyle}\n {...rest}\n >\n {children}\n </Component>\n </>\n );\n}\n\nexport const TextShimmer = React.memo(TextShimmerComponent);\n"],"mappings":"wQASA,IAAM,EAA0B,OAE1B,EAAiB,EAEjB,EAAiB,EAAiB,EAUxC,SAAS,EAAqB,CAC5B,WACA,GAAI,EAAY,IAChB,YACA,WAAW,EACX,SAAS,EACT,QACA,GAAG,GACgB,CACnB,IAAM,EAAe,EAAA,kBAAkB,CAEjC,EAAgB,oBAAA,EAAA,EAAA,QAAmB,CAAQ,QAAQ,KAAM,GAAG,GAG5D,GAAA,EAAA,EAAA,aACE,KAAK,IAAI,EAAiB,EAAI,EAAG,EAAI,EAAS,EAAE,CACtD,CAAC,EAAO,CACT,CAEK,GAAA,EAAA,EAAA,aAA6B,CACjC,IAAM,EAAS,EAAiB,EAChC,MAAO,CACL,GAAG,EACH,gBAAiB,wEAAwE,EAAS,EAAc,0BAA0B,EAAO,qBAAqB,EAAS,EAAc,qBAAqB,EAAe,IACjO,eAAgB,GAAG,EAAwB,OAC3C,iBAAkB,YAClB,qBAAsB,OACtB,eAAgB,OAChB,MAAO,cACP,oBAAqB,cACrB,UAAW,GAAG,EAAc,GAAG,EAAS,mBACzC,EACA,CAAC,EAAe,EAAe,EAAU,EAAM,CAAC,CAcnD,OAZI,GAEA,EAAA,EAAA,KAAC,EAAD,CACE,UAAW,EAAA,GAAG,yBAA0B,EAAU,CAC3C,QACP,GAAI,EAEH,WACS,CAAA,EAKd,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,QAAD,CACE,wBAAyB,CACvB,OAAQ,cAAc,EAAc,4BAA4B,EAAe,6CAChF,CACD,CAAA,EACF,EAAA,EAAA,KAAC,EAAD,CACE,UAAW,EAAA,GAAG,wBAAyB,EAAU,CACjD,MAAO,EACP,GAAI,EAEH,WACS,CAAA,CACX,CAAA,CAAA,CAIP,IAAa,EAAc,EAAA,QAAM,KAAK,EAAqB"}
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ export type TextShimmerProps = {
3
+ children: string;
4
+ as?: React.ElementType;
5
+ className?: string;
6
+ duration?: number;
7
+ spread?: number;
8
+ } & Omit<React.HTMLAttributes<HTMLElement>, "children" | "className">;
9
+ declare function TextShimmerComponent({ children, as: Component, className, duration, spread, style, ...rest }: TextShimmerProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare const TextShimmer: React.MemoExoticComponent<typeof TextShimmerComponent>;
11
+ export {};
@@ -0,0 +1,43 @@
1
+ import { cn as e } from "../../utils/utils.js";
2
+ import { useReducedMotion as t } from "../../node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js";
3
+ import n, { useId as r, useMemo as i } from "react";
4
+ import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
5
+ //#region src/components/shared/text-shimmer.tsx
6
+ var c = "200%", l = 8, u = l * 2;
7
+ function d({ children: n, as: d = "p", className: f, duration: p = 2, spread: m = 2, style: h, ...g }) {
8
+ let _ = t(), v = `oh-text-shimmer-${r().replace(/:/g, "")}`, y = i(() => Math.min(l / 2 - 1, 1 + m / 2), [m]), b = i(() => {
9
+ let e = l / 2;
10
+ return {
11
+ ...h,
12
+ backgroundImage: `repeating-linear-gradient(90deg, var(--oh-muted) 0%, var(--oh-muted) ${e - y}%, var(--oh-foreground) ${e}%, var(--oh-muted) ${e + y}%, var(--oh-muted) ${l}%)`,
13
+ backgroundSize: `${c} 100%`,
14
+ backgroundRepeat: "no-repeat",
15
+ WebkitBackgroundClip: "text",
16
+ backgroundClip: "text",
17
+ color: "transparent",
18
+ WebkitTextFillColor: "transparent",
19
+ animation: `${v} ${p}s linear infinite`
20
+ };
21
+ }, [
22
+ v,
23
+ y,
24
+ p,
25
+ h
26
+ ]);
27
+ return _ ? /* @__PURE__ */ o(d, {
28
+ className: e("text-[var(--oh-muted)]", f),
29
+ style: h,
30
+ ...g,
31
+ children: n
32
+ }) : /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("style", { dangerouslySetInnerHTML: { __html: `@keyframes ${v}{from{background-position:${u}% center}to{background-position:0% center}}` } }), /* @__PURE__ */ o(d, {
33
+ className: e("relative inline-block", f),
34
+ style: b,
35
+ ...g,
36
+ children: n
37
+ })] });
38
+ }
39
+ var f = n.memo(d);
40
+ //#endregion
41
+ export { f as TextShimmer };
42
+
43
+ //# sourceMappingURL=text-shimmer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-shimmer.js","names":[],"sources":["../../../src/components/shared/text-shimmer.tsx"],"sourcesContent":["import React, { useId, useMemo } from \"react\";\nimport { useReducedMotion } from \"framer-motion\";\nimport { cn } from \"#/utils/utils\";\n\n/**\n * The gradient is an oversized repeating pattern; animating background-position\n * by exactly one period loops with no visible jump and no muted gap between\n * sweeps (the pattern is periodic, so a highlight is always near the text).\n */\nconst SHIMMER_BACKGROUND_SIZE = \"200%\";\n/** Gradient period as a percentage of the (oversized) background image. */\nconst SHIMMER_PERIOD = 8;\n/** Shifting background-position by one period == 2 * period (image is 2x wide). */\nconst SHIMMER_TRAVEL = SHIMMER_PERIOD * 2;\n\nexport type TextShimmerProps = {\n children: string;\n as?: React.ElementType;\n className?: string;\n duration?: number;\n spread?: number;\n} & Omit<React.HTMLAttributes<HTMLElement>, \"children\" | \"className\">;\n\nfunction TextShimmerComponent({\n children,\n as: Component = \"p\",\n className,\n duration = 2,\n spread = 2,\n style,\n ...rest\n}: TextShimmerProps) {\n const reduceMotion = useReducedMotion();\n const reactId = useId();\n const animationName = `oh-text-shimmer-${reactId.replace(/:/g, \"\")}`;\n\n // Wider spread => wider bright band within each repeating period.\n const bandHalfWidth = useMemo(\n () => Math.min(SHIMMER_PERIOD / 2 - 1, 1 + spread / 2),\n [spread],\n );\n\n const shimmerStyle = useMemo(() => {\n const center = SHIMMER_PERIOD / 2;\n return {\n ...style,\n backgroundImage: `repeating-linear-gradient(90deg, var(--oh-muted) 0%, var(--oh-muted) ${center - bandHalfWidth}%, var(--oh-foreground) ${center}%, var(--oh-muted) ${center + bandHalfWidth}%, var(--oh-muted) ${SHIMMER_PERIOD}%)`,\n backgroundSize: `${SHIMMER_BACKGROUND_SIZE} 100%`,\n backgroundRepeat: \"no-repeat\",\n WebkitBackgroundClip: \"text\",\n backgroundClip: \"text\",\n color: \"transparent\",\n WebkitTextFillColor: \"transparent\",\n animation: `${animationName} ${duration}s linear infinite`,\n } as React.CSSProperties;\n }, [animationName, bandHalfWidth, duration, style]);\n\n if (reduceMotion) {\n return (\n <Component\n className={cn(\"text-[var(--oh-muted)]\", className)}\n style={style}\n {...rest}\n >\n {children}\n </Component>\n );\n }\n\n return (\n <>\n <style\n dangerouslySetInnerHTML={{\n __html: `@keyframes ${animationName}{from{background-position:${SHIMMER_TRAVEL}% center}to{background-position:0% center}}`,\n }}\n />\n <Component\n className={cn(\"relative inline-block\", className)}\n style={shimmerStyle}\n {...rest}\n >\n {children}\n </Component>\n </>\n );\n}\n\nexport const TextShimmer = React.memo(TextShimmerComponent);\n"],"mappings":";;;;;AASA,IAAM,IAA0B,QAE1B,IAAiB,GAEjB,IAAiB,IAAiB;AAUxC,SAAS,EAAqB,EAC5B,aACA,IAAI,IAAY,KAChB,cACA,cAAW,GACX,YAAS,GACT,UACA,GAAG,KACgB;CACnB,IAAM,IAAe,GAAkB,EAEjC,IAAgB,mBADN,GACyB,CAAQ,QAAQ,MAAM,GAAG,IAG5D,IAAgB,QACd,KAAK,IAAI,IAAiB,IAAI,GAAG,IAAI,IAAS,EAAE,EACtD,CAAC,EAAO,CACT,EAEK,IAAe,QAAc;EACjC,IAAM,IAAS,IAAiB;AAChC,SAAO;GACL,GAAG;GACH,iBAAiB,wEAAwE,IAAS,EAAc,0BAA0B,EAAO,qBAAqB,IAAS,EAAc,qBAAqB,EAAe;GACjO,gBAAgB,GAAG,EAAwB;GAC3C,kBAAkB;GAClB,sBAAsB;GACtB,gBAAgB;GAChB,OAAO;GACP,qBAAqB;GACrB,WAAW,GAAG,EAAc,GAAG,EAAS;GACzC;IACA;EAAC;EAAe;EAAe;EAAU;EAAM,CAAC;AAcnD,QAZI,IAEA,kBAAC,GAAD;EACE,WAAW,EAAG,0BAA0B,EAAU;EAC3C;EACP,GAAI;EAEH;EACS,CAAA,GAKd,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,SAAD,EACE,yBAAyB,EACvB,QAAQ,cAAc,EAAc,4BAA4B,EAAe,8CAChF,EACD,CAAA,EACF,kBAAC,GAAD;EACE,WAAW,EAAG,yBAAyB,EAAU;EACjD,OAAO;EACP,GAAI;EAEH;EACS,CAAA,CACX,EAAA,CAAA;;AAIP,IAAa,IAAc,EAAM,KAAK,EAAqB"}
@@ -1,2 +1,2 @@
1
- require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../i18n/declaration.cjs`),t=require(`../node_modules/@openhands/typescript-client/dist/models/acp.cjs`);require(`../node_modules/@openhands/typescript-client/dist/index.cjs`);var n=new Set([`default`,`default (recommended)`]);function r(e){if(typeof e!=`string`)return null;let t=e.trim();return!t||n.has(t.toLowerCase())||t===`acp-managed`?null:t}function i(e){for(let t of[e.runtimeName,e.runtimeId,e.configured,e.sdkLlm]){let e=r(t);if(e)return e}return e.providerDefault??null}var a={"claude-code":{icon:`claude-code`,description_key:e.I18nKey.ONBOARDING$AGENT_CLAUDE_CODE_DESCRIPTION},codex:{icon:`codex`,description_key:e.I18nKey.ONBOARDING$AGENT_CODEX_DESCRIPTION},"gemini-cli":{icon:`gemini`,description_key:e.I18nKey.ONBOARDING$AGENT_GEMINI_CLI_DESCRIPTION}},o=Object.entries(a).map(([e,n])=>{let r=t.getAcpProvider(e);return{key:e,display_name:r?.display_name??e,default_command:r?[...r.default_command]:[],available_models:r?.available_models?.map(e=>({id:e.id,label:e.label})),default_model:r?.default_model??void 0,description_key:n.description_key,icon:n.icon}});e.I18nKey.ONBOARDING$ACP_SECRET_API_KEY_HINT,e.I18nKey.ONBOARDING$ACP_SECRET_BASE_URL_HINT,e.I18nKey.ONBOARDING$ACP_SECRET_API_KEY_HINT,e.I18nKey.ONBOARDING$ACP_SECRET_BASE_URL_HINT;function s(e){if(e)return o.find(t=>t.key===e)}function c(e){let t=s(e);return t?t.display_name:null}function l(e){return s(e)?.icon??`cli-generic`}function u(e,t){return t?s(e)?.available_models?.find(e=>e.id===t)?.label??t:null}exports.ACP_PROVIDERS=o,exports.getAcpProvider=s,exports.getAcpProviderDisplayName=c,exports.labelForAcpModel=u,exports.resolveAcpProviderIcon=l,exports.resolveEffectiveAcpModel=i;
1
+ require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../i18n/declaration.cjs`),t=require(`../node_modules/@openhands/typescript-client/dist/models/acp.cjs`);require(`../node_modules/@openhands/typescript-client/dist/index.cjs`);var n=new Set([`default`,`default (recommended)`]);function r(e){if(typeof e!=`string`)return null;let t=e.trim();return!t||n.has(t.toLowerCase())||t===`acp-managed`?null:t}function i(e){for(let t of[e.runtimeName,e.runtimeId,e.configured,e.sdkLlm]){let e=r(t);if(e)return e}return e.providerDefault??null}var a={"claude-code":{icon:`claude-code`,description_key:e.I18nKey.ONBOARDING$AGENT_CLAUDE_CODE_DESCRIPTION},codex:{icon:`codex`,description_key:e.I18nKey.ONBOARDING$AGENT_CODEX_DESCRIPTION},"gemini-cli":{icon:`gemini`,description_key:e.I18nKey.ONBOARDING$AGENT_GEMINI_CLI_DESCRIPTION}},o=Object.entries(a).map(([e,n])=>{let r=t.getAcpProvider(e);return{key:e,display_name:r?.display_name??e,default_command:r?[...r.default_command]:[],available_models:r?.available_models?.map(e=>({id:e.id,label:e.label})),default_model:r?.default_model??void 0,description_key:n.description_key,icon:n.icon}});function s(e){if(e)return o.find(t=>t.key===e)}function c(e){let t=s(e);return t?t.display_name:null}function l(e){return s(e)?.icon??`cli-generic`}function u(e,t){return t?s(e)?.available_models?.find(e=>e.id===t)?.label??t:null}exports.ACP_PROVIDERS=o,exports.getAcpProvider=s,exports.getAcpProviderDisplayName=c,exports.labelForAcpModel=u,exports.resolveAcpProviderIcon=l,exports.resolveEffectiveAcpModel=i;
2
2
  //# sourceMappingURL=acp-providers.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"acp-providers.cjs","names":[],"sources":["../../src/constants/acp-providers.ts"],"sourcesContent":["import { getAcpProvider as getClientAcpProvider } from \"@openhands/typescript-client\";\nimport { I18nKey } from \"#/i18n/declaration\";\n\nexport type ACPProviderIcon =\n | \"claude-code\"\n | \"codex\"\n | \"gemini\"\n | \"cli-generic\";\n\nexport const ACP_PROVIDER_FALLBACK_ICON: ACPProviderIcon = \"cli-generic\";\n\n// SDK placeholder strings the ACP wrapper returns before the user has\n// chosen a real model — surfacing either would lie about what's running.\nexport const ACP_DEFAULT_PLACEHOLDERS = new Set([\n \"default\",\n \"default (recommended)\",\n]);\n\n// Sentinel ``agent.llm.model`` returned by older SDKs for ACP conversations\n// in lieu of a real model. Suppressed at every consumer that resolves a\n// display string.\nexport const ACP_MANAGED_SENTINEL = \"acp-managed\";\n\n/**\n * Filter for \"real\" ACP model strings — non-empty, not the SDK's \"default\"\n * placeholder, not the legacy ``acp-managed`` sentinel. Returns the trimmed\n * value on success, ``null`` otherwise.\n */\nfunction realAcpModel(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n if (!trimmed) return null;\n if (ACP_DEFAULT_PLACEHOLDERS.has(trimmed.toLowerCase())) return null;\n if (trimmed === ACP_MANAGED_SENTINEL) return null;\n return trimmed;\n}\n\n/**\n * Single source of truth for resolving the model string to surface for an\n * ACP conversation/settings context. Consumed by the conversation adapter\n * (chip text), the conversation-creation path (concrete ``acp_model``\n * payload), the Settings → Agent form (initial value), and the chat-input\n * model label.\n *\n * Precedence: SDK runtime fields → user-configured ``acp_model`` →\n * legacy ``agent.llm.model`` → provider default (when ``providerDefault``\n * is passed). Pass ``providerDefault`` only on surfaces that should\n * silently substitute the registry default; omit it for the conversation\n * chip, which must distinguish \"no concrete model\" from \"default\".\n */\nexport function resolveEffectiveAcpModel(inputs: {\n runtimeName?: string | null;\n runtimeId?: string | null;\n configured?: string | null;\n sdkLlm?: string | null;\n providerDefault?: string | null;\n}): string | null {\n for (const candidate of [\n inputs.runtimeName,\n inputs.runtimeId,\n inputs.configured,\n inputs.sdkLlm,\n ]) {\n const value = realAcpModel(candidate);\n if (value) return value;\n }\n return inputs.providerDefault ?? null;\n}\n\n/**\n * Shape of a built-in ACP (Agent Client Protocol) provider as Canvas consumes\n * it. The data fields (display name, launch command, model picker + default)\n * are sourced at module load from ``@openhands/typescript-client``'s ACP\n * registry — the generated mirror of the Python source of truth\n * ``openhands.sdk.settings.acp_providers``. This config only adds the\n * Canvas-specific UI fields ({@link ACPProviderConfig.icon} +\n * {@link ACPProviderConfig.description_key}); see {@link ACP_PROVIDER_UI}.\n */\nexport interface ACPProviderConfig {\n /** Stable registry key, also stored on conversations as ``tags.acpserver``. */\n key: string;\n /** Human-readable name shown in dropdowns and conversation chips. */\n display_name: string;\n /**\n * Tokens passed to the agent-server as ``acp_command`` when this preset\n * is picked. Each entry must be a real ACP-protocol stdio server — the\n * SDK validates this against the {@link ACPProviderConfig.key}.\n *\n * NB: ``npx -y @openai/codex acp`` looks plausible but is **not** an\n * ACP server — the codex CLI has no ``acp`` subcommand and exits with\n * ``Error: stdin is not a terminal`` when spawned without a TTY, which\n * silently deadlocks the agent-server's ACP handshake. Use\n * ``@zed-industries/codex-acp`` (the Zed-shipped wrapper) instead.\n */\n default_command: string[];\n /**\n * Suggested ACP model IDs for the provider's picker, sourced from the\n * typescript-client registry. Not authoritative access checks; users can\n * still enter a custom override in Settings -> Agent.\n */\n available_models?: ACPModelOption[];\n /** Model ID preselected for built-in providers so Canvas never saves blank. */\n default_model?: string;\n /**\n * i18n key for the one-line provider description rendered under the\n * onboarding tile. Stored on the registry so adding a new ACP\n * provider only requires editing this file (not the onboarding tile\n * list separately).\n */\n description_key: I18nKey;\n /**\n * Serializable icon key used by UI surfaces that render provider\n * choices. Kept as a string so the SDK mirror check can continue to\n * parse this registry without importing React components.\n */\n icon?: ACPProviderIcon;\n}\n\nexport interface ACPModelOption {\n /** Exact model ID sent as ``acp_model``. */\n id: string;\n /** Human-readable label shown in Settings -> Agent. */\n label: string;\n}\n\n// Canvas-only UI metadata per built-in provider, keyed by the ACP registry\n// key. Everything else — display name, launch command, model picker list and\n// default — comes from the typescript-client registry below. Adding a model\n// or a provider happens upstream in the SDK; Canvas only owns the brand icon\n// and the onboarding-tile description here. A provider with no entry here is\n// intentionally not surfaced in the UI.\nconst ACP_PROVIDER_UI: Record<\n string,\n { icon: ACPProviderIcon; description_key: I18nKey }\n> = {\n \"claude-code\": {\n icon: \"claude-code\",\n description_key: I18nKey.ONBOARDING$AGENT_CLAUDE_CODE_DESCRIPTION,\n },\n codex: {\n icon: \"codex\",\n description_key: I18nKey.ONBOARDING$AGENT_CODEX_DESCRIPTION,\n },\n \"gemini-cli\": {\n icon: \"gemini\",\n description_key: I18nKey.ONBOARDING$AGENT_GEMINI_CLI_DESCRIPTION,\n },\n};\n\n// Built-in ACP providers Canvas surfaces, built by enriching each upstream\n// registry record (``@openhands/typescript-client`` → Python SDK) with the\n// Canvas UI metadata above. Model lists + defaults are no longer hand-kept\n// here (closes agent-canvas#740) — they track the SDK via the pinned client.\nexport const ACP_PROVIDERS: ACPProviderConfig[] = Object.entries(\n ACP_PROVIDER_UI,\n).map(([key, ui]) => {\n const info = getClientAcpProvider(key);\n return {\n key,\n display_name: info?.display_name ?? key,\n default_command: info ? [...info.default_command] : [],\n available_models: info?.available_models?.map((model) => ({\n id: model.id,\n label: model.label,\n })),\n default_model: info?.default_model ?? undefined,\n description_key: ui.description_key,\n icon: ui.icon,\n };\n});\n\nexport const ACP_CUSTOM_PRESET_KEY = \"custom\";\n\n/**\n * A credential an ACP provider authenticates with, surfaced during onboarding\n * so the user can populate it without leaving the flow. The {@link name} is\n * both the global-secret name and the environment variable the agent-server\n * exports into the ACP subprocess — keeping them identical is what makes a\n * saved secret actually reach the provider CLI.\n */\nexport interface ACPProviderSecretField {\n /** Secret name and env var (e.g. ``\"ANTHROPIC_API_KEY\"``). Must satisfy the\n * secret-name pattern ``^[a-zA-Z][a-zA-Z0-9_]{0,63}$``. */\n name: string;\n /** Render as a masked password input (API keys) rather than a plain-text\n * input (base URLs). Every field is optional regardless — the whole step is\n * skippable — so this only controls masking, not whether the field gates. */\n secret?: boolean;\n /** i18n key for the one-line helper text under the field. */\n hint_key: I18nKey;\n}\n\n// Credentials Canvas prompts for during onboarding, keyed by ACP registry key.\n// Only providers that authenticate through an env-var API key appear here:\n// Claude Code (Anthropic) and Codex (OpenAI). Gemini CLI authenticates via an\n// interactive OAuth login rather than a static key, so it has no entry and its\n// onboarding credentials step is skipped. Every field is optional (the step is\n// skippable): the API keys render masked, the base-URL entries are plain-text\n// overrides for proxies/gateways. A provider with no entry simply shows no\n// credentials step.\nconst ACP_PROVIDER_SECRETS: Record<string, ACPProviderSecretField[]> = {\n \"claude-code\": [\n {\n name: \"ANTHROPIC_API_KEY\",\n secret: true,\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_API_KEY_HINT,\n },\n {\n name: \"ANTHROPIC_BASE_URL\",\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_BASE_URL_HINT,\n },\n ],\n codex: [\n {\n name: \"OPENAI_API_KEY\",\n secret: true,\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_API_KEY_HINT,\n },\n {\n name: \"OPENAI_BASE_URL\",\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_BASE_URL_HINT,\n },\n ],\n};\n\n/**\n * List the credentials Canvas should prompt for when onboarding the given ACP\n * provider. Returns ``[]`` for OpenHands, the ``\"custom\"`` preset, providers\n * that don't use a static API key (Gemini CLI), and any unknown key — callers\n * treat an empty list as \"no credentials step for this provider\".\n */\nexport function getAcpProviderSecrets(\n key: string | null | undefined,\n): ACPProviderSecretField[] {\n if (!key) return [];\n return ACP_PROVIDER_SECRETS[key] ?? [];\n}\n\n/**\n * Look up a built-in ACP provider config by its registry key.\n *\n * Returns ``undefined`` for an empty / null key, for the ``\"custom\"`` preset\n * (which has no registry entry), and for any forward-compatible key Canvas's\n * registry doesn't know about yet. Centralizes the ``ACP_PROVIDERS.find(...)``\n * lookup shared by the resolvers below and by the adapter / settings surfaces\n * so the key-comparison shape lives in one place.\n */\nexport function getAcpProvider(\n key: string | null | undefined,\n): ACPProviderConfig | undefined {\n if (!key) return undefined;\n return ACP_PROVIDERS.find((provider) => provider.key === key);\n}\n\n/**\n * Resolve an ACP provider registry key (the value stored under\n * ``tags.acpserver`` on a conversation) to a human display name for the\n * sidebar chip.\n *\n * Returns ``null`` for an empty / null key and for keys not in\n * {@link ACP_PROVIDERS} — most notably ``\"custom\"`` (the user-supplied\n * command preset has no canonical brand name) and any forward-compatible\n * value Canvas's registry doesn't know about yet. Callers should fall\n * back to a generic ``\"ACP\"`` label in that case so the chip still\n * communicates \"this is an ACP conversation\".\n *\n * Kept separate from {@link buildAcpAgentSettingsDiff}'s lookup so the\n * conversation-card render path can resolve display names without\n * importing the settings-payload builder.\n */\nexport function getAcpProviderDisplayName(\n key: string | null | undefined,\n): string | null {\n const found = getAcpProvider(key);\n return found ? found.display_name : null;\n}\n\n/**\n * Resolve an ACP provider registry key to the icon discriminator the\n * conversation chip should render alongside the model text.\n *\n * Falls back to {@link ACP_PROVIDER_FALLBACK_ICON} for ``\"custom\"``,\n * unknown keys, or a missing key — the chip then shows a neutral\n * terminal glyph that still communicates \"this is an ACP conversation\"\n * without claiming a brand identity we don't know.\n */\nexport function resolveAcpProviderIcon(\n key: string | null | undefined,\n): ACPProviderIcon {\n return getAcpProvider(key)?.icon ?? ACP_PROVIDER_FALLBACK_ICON;\n}\n\n/**\n * Resolve a raw ``acp_model`` ID to the human-readable label the provider's\n * picker shows for it (e.g. ``\"claude-opus-4-7\"`` → ``\"Claude Opus 4.7\"``).\n *\n * Falls back to the raw ID when the provider is unknown or the ID isn't one\n * of its registered {@link ACPModelOption}s — so a user's custom override\n * still renders something meaningful rather than nothing. Returns ``null``\n * only when there is no model to show, letting the conversation chip decide\n * to display the provider name instead.\n */\nexport function labelForAcpModel(\n serverKey: string | null | undefined,\n modelId: string | null | undefined,\n): string | null {\n if (!modelId) return null;\n const provider = getAcpProvider(serverKey);\n const match = provider?.available_models?.find((m) => m.id === modelId);\n return match?.label ?? modelId;\n}\n\n/**\n * Build the ``agent_settings_diff`` payload PATCH /api/settings expects\n * for the agent-kind/provider choice the user just made.\n *\n * Used by both the Settings → Agent page and the onboarding \"choose\n * agent\" step — keeping the shape in one helper means a future change\n * (e.g. always seeding ``acp_command`` from the registry instead of\n * sending ``[]``, or adding new ``acp_*`` reset fields) lands in both\n * surfaces atomically.\n *\n * Returns ``null`` for an unknown ACP provider key by default — the\n * caller can skip the save (the UI shouldn't surface unknown options,\n * but the defensive path keeps a buggy preset list from corrupting\n * settings).\n *\n * Pass ``allowUnknownServer: true`` to opt into pass-through for keys\n * that aren't in {@link ACP_PROVIDERS} or ``ACP_CUSTOM_PRESET_KEY``.\n * The Settings → Agent page uses this when the user opens settings\n * that already carry an ``acp_server`` value canvas's registry\n * doesn't know about (e.g. set out-of-band via the API for a provider\n * we haven't mirrored yet) and saves without changing the command —\n * otherwise the original key would be silently demoted to ``\"custom\"``.\n */\nexport function buildAcpAgentSettingsDiff(\n providerKey: string,\n options: {\n command?: string[];\n model?: string | null;\n allowUnknownServer?: boolean;\n } = {},\n): Record<string, unknown> | null {\n if (providerKey === \"openhands\") {\n // Switching back to OpenHands. The agent-server's ``Settings.update``\n // applies a fresh ``{'agent_kind': ...}`` base whenever the kind\n // flips, so any ``acp_*`` fields would be discarded before\n // validation. Send the kind alone.\n return { agent_kind: \"openhands\" };\n }\n\n const isCustom = providerKey === ACP_CUSTOM_PRESET_KEY;\n const provider = isCustom ? undefined : getAcpProvider(providerKey);\n if (!isCustom && !provider && !options.allowUnknownServer) {\n return null;\n }\n\n const model =\n options.model === undefined\n ? (provider?.default_model ?? null)\n : options.model;\n\n // ``acp_args: []`` resets any API-set ``acp_args`` that would\n // otherwise survive and concatenate to ``acp_command`` at spawn time\n // (the agent-server merges the two before exec). Callers building the\n // payload from a textarea that already shows the merged command\n // (Settings → Agent) round-trip correctly — the merged tokens land in\n // ``acp_command`` here, so no args are lost.\n return {\n agent_kind: \"acp\",\n acp_server: providerKey,\n acp_command: options.command ?? [],\n acp_args: [],\n acp_model: model ?? null,\n };\n}\n"],"mappings":"6OAaA,IAAa,EAA2B,IAAI,IAAI,CAC9C,UACA,wBACD,CAAC,CAYF,SAAS,EAAa,EAA+B,CACnD,GAAI,OAAO,GAAU,SAAU,OAAO,KACtC,IAAM,EAAU,EAAM,MAAM,CAI5B,MAHI,CAAC,GACD,EAAyB,IAAI,EAAQ,aAAa,CAAC,EACnD,IAAA,cAAyC,KACtC,EAgBT,SAAgB,EAAyB,EAMvB,CAChB,IAAK,IAAM,IAAa,CACtB,EAAO,YACP,EAAO,UACP,EAAO,WACP,EAAO,OACR,CAAE,CACD,IAAM,EAAQ,EAAa,EAAU,CACrC,GAAI,EAAO,OAAO,EAEpB,OAAO,EAAO,iBAAmB,KAiEnC,IAAM,EAGF,CACF,cAAe,CACb,KAAM,cACN,gBAAiB,EAAA,QAAQ,yCAC1B,CACD,MAAO,CACL,KAAM,QACN,gBAAiB,EAAA,QAAQ,mCAC1B,CACD,aAAc,CACZ,KAAM,SACN,gBAAiB,EAAA,QAAQ,wCAC1B,CACF,CAMY,EAAqC,OAAO,QACvD,EACD,CAAC,KAAK,CAAC,EAAK,KAAQ,CACnB,IAAM,EAAO,EAAA,eAAqB,EAAI,CACtC,MAAO,CACL,MACA,aAAc,GAAM,cAAgB,EACpC,gBAAiB,EAAO,CAAC,GAAG,EAAK,gBAAgB,CAAG,EAAE,CACtD,iBAAkB,GAAM,kBAAkB,IAAK,IAAW,CACxD,GAAI,EAAM,GACV,MAAO,EAAM,MACd,EAAE,CACH,cAAe,GAAM,eAAiB,IAAA,GACtC,gBAAiB,EAAG,gBACpB,KAAM,EAAG,KACV,EACD,CAoCc,EAAA,QAAQ,mCAIR,EAAA,QAAQ,oCAOR,EAAA,QAAQ,mCAIR,EAAA,QAAQ,oCA2BxB,SAAgB,EACd,EAC+B,CAC1B,KACL,OAAO,EAAc,KAAM,GAAa,EAAS,MAAQ,EAAI,CAmB/D,SAAgB,EACd,EACe,CACf,IAAM,EAAQ,EAAe,EAAI,CACjC,OAAO,EAAQ,EAAM,aAAe,KAYtC,SAAgB,EACd,EACiB,CACjB,OAAO,EAAe,EAAI,EAAE,MAAA,cAa9B,SAAgB,EACd,EACA,EACe,CAIf,OAHK,EACY,EAAe,EAClB,EAAU,kBAAkB,KAAM,GAAM,EAAE,KAAO,EAAQ,EACzD,OAAS,EAHF"}
1
+ {"version":3,"file":"acp-providers.cjs","names":[],"sources":["../../src/constants/acp-providers.ts"],"sourcesContent":["import { getAcpProvider as getClientAcpProvider } from \"@openhands/typescript-client\";\nimport { I18nKey } from \"#/i18n/declaration\";\n\n/** Upstream registry fields not yet on the pinned client's exported type. */\ntype ClientAcpProviderRegistry = NonNullable<\n ReturnType<typeof getClientAcpProvider>\n> & {\n available_models?: Array<{ id: string; label: string }>;\n default_model?: string;\n};\n\nexport type ACPProviderIcon =\n | \"claude-code\"\n | \"codex\"\n | \"gemini\"\n | \"cli-generic\";\n\nexport const ACP_PROVIDER_FALLBACK_ICON: ACPProviderIcon = \"cli-generic\";\n\n// SDK placeholder strings the ACP wrapper returns before the user has\n// chosen a real model — surfacing either would lie about what's running.\nexport const ACP_DEFAULT_PLACEHOLDERS = new Set([\n \"default\",\n \"default (recommended)\",\n]);\n\n// Sentinel ``agent.llm.model`` returned by older SDKs for ACP conversations\n// in lieu of a real model. Suppressed at every consumer that resolves a\n// display string.\nexport const ACP_MANAGED_SENTINEL = \"acp-managed\";\n\n/**\n * Filter for \"real\" ACP model strings — non-empty, not the SDK's \"default\"\n * placeholder, not the legacy ``acp-managed`` sentinel. Returns the trimmed\n * value on success, ``null`` otherwise.\n */\nfunction realAcpModel(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n if (!trimmed) return null;\n if (ACP_DEFAULT_PLACEHOLDERS.has(trimmed.toLowerCase())) return null;\n if (trimmed === ACP_MANAGED_SENTINEL) return null;\n return trimmed;\n}\n\n/**\n * Single source of truth for resolving the model string to surface for an\n * ACP conversation/settings context. Consumed by the conversation adapter\n * (chip text), the conversation-creation path (concrete ``acp_model``\n * payload), the Settings → Agent form (initial value), and the chat-input\n * model label.\n *\n * Precedence: SDK runtime fields → user-configured ``acp_model`` →\n * legacy ``agent.llm.model`` → provider default (when ``providerDefault``\n * is passed). Pass ``providerDefault`` only on surfaces that should\n * silently substitute the registry default; omit it for the conversation\n * chip, which must distinguish \"no concrete model\" from \"default\".\n */\nexport function resolveEffectiveAcpModel(inputs: {\n runtimeName?: string | null;\n runtimeId?: string | null;\n configured?: string | null;\n sdkLlm?: string | null;\n providerDefault?: string | null;\n}): string | null {\n for (const candidate of [\n inputs.runtimeName,\n inputs.runtimeId,\n inputs.configured,\n inputs.sdkLlm,\n ]) {\n const value = realAcpModel(candidate);\n if (value) return value;\n }\n return inputs.providerDefault ?? null;\n}\n\n/**\n * Shape of a built-in ACP (Agent Client Protocol) provider as Canvas consumes\n * it. The data fields (display name, launch command, model picker + default)\n * are sourced at module load from ``@openhands/typescript-client``'s ACP\n * registry — the generated mirror of the Python source of truth\n * ``openhands.sdk.settings.acp_providers``. This config only adds the\n * Canvas-specific UI fields ({@link ACPProviderConfig.icon} +\n * {@link ACPProviderConfig.description_key}); see {@link ACP_PROVIDER_UI}.\n */\nexport interface ACPProviderConfig {\n /** Stable registry key, also stored on conversations as ``tags.acpserver``. */\n key: string;\n /** Human-readable name shown in dropdowns and conversation chips. */\n display_name: string;\n /**\n * Tokens passed to the agent-server as ``acp_command`` when this preset\n * is picked. Each entry must be a real ACP-protocol stdio server — the\n * SDK validates this against the {@link ACPProviderConfig.key}.\n *\n * NB: ``npx -y @openai/codex acp`` looks plausible but is **not** an\n * ACP server — the codex CLI has no ``acp`` subcommand and exits with\n * ``Error: stdin is not a terminal`` when spawned without a TTY, which\n * silently deadlocks the agent-server's ACP handshake. Use\n * ``@zed-industries/codex-acp`` (the Zed-shipped wrapper) instead.\n */\n default_command: string[];\n /**\n * Suggested ACP model IDs for the provider's picker, sourced from the\n * typescript-client registry. Not authoritative access checks; users can\n * still enter a custom override in Settings -> Agent.\n */\n available_models?: ACPModelOption[];\n /** Model ID preselected for built-in providers so Canvas never saves blank. */\n default_model?: string;\n /**\n * i18n key for the one-line provider description rendered under the\n * onboarding tile. Stored on the registry so adding a new ACP\n * provider only requires editing this file (not the onboarding tile\n * list separately).\n */\n description_key: I18nKey;\n /**\n * Serializable icon key used by UI surfaces that render provider\n * choices. Kept as a string so the SDK mirror check can continue to\n * parse this registry without importing React components.\n */\n icon?: ACPProviderIcon;\n}\n\nexport interface ACPModelOption {\n /** Exact model ID sent as ``acp_model``. */\n id: string;\n /** Human-readable label shown in Settings -> Agent. */\n label: string;\n}\n\n// Canvas-only UI metadata per built-in provider, keyed by the ACP registry\n// key. Everything else — display name, launch command, model picker list and\n// default — comes from the typescript-client registry below. Adding a model\n// or a provider happens upstream in the SDK; Canvas only owns the brand icon\n// and the onboarding-tile description here. A provider with no entry here is\n// intentionally not surfaced in the UI.\nconst ACP_PROVIDER_UI: Record<\n string,\n { icon: ACPProviderIcon; description_key: I18nKey }\n> = {\n \"claude-code\": {\n icon: \"claude-code\",\n description_key: I18nKey.ONBOARDING$AGENT_CLAUDE_CODE_DESCRIPTION,\n },\n codex: {\n icon: \"codex\",\n description_key: I18nKey.ONBOARDING$AGENT_CODEX_DESCRIPTION,\n },\n \"gemini-cli\": {\n icon: \"gemini\",\n description_key: I18nKey.ONBOARDING$AGENT_GEMINI_CLI_DESCRIPTION,\n },\n};\n\n// Built-in ACP providers Canvas surfaces, built by enriching each upstream\n// registry record (``@openhands/typescript-client`` → Python SDK) with the\n// Canvas UI metadata above. Model lists + defaults are no longer hand-kept\n// here (closes agent-canvas#740) — they track the SDK via the pinned client.\nexport const ACP_PROVIDERS: ACPProviderConfig[] = Object.entries(\n ACP_PROVIDER_UI,\n).map(([key, ui]) => {\n const info = getClientAcpProvider(key) as ClientAcpProviderRegistry | null;\n return {\n key,\n display_name: info?.display_name ?? key,\n default_command: info ? [...info.default_command] : [],\n available_models: info?.available_models?.map((model) => ({\n id: model.id,\n label: model.label,\n })),\n default_model: info?.default_model ?? undefined,\n description_key: ui.description_key,\n icon: ui.icon,\n };\n});\n\nexport const ACP_CUSTOM_PRESET_KEY = \"custom\";\n\n/**\n * A credential an ACP provider authenticates with, surfaced during onboarding\n * so the user can populate it without leaving the flow. The {@link name} is\n * both the global-secret name and the environment variable the agent-server\n * exports into the ACP subprocess — keeping them identical is what makes a\n * saved secret actually reach the provider CLI.\n */\nexport interface ACPProviderSecretField {\n /** Secret name and env var (e.g. ``\"ANTHROPIC_API_KEY\"``). Must satisfy the\n * secret-name pattern ``^[a-zA-Z][a-zA-Z0-9_]{0,63}$``. */\n name: string;\n /** Render as a masked password input (API keys) rather than a plain-text\n * input (base URLs). Every field is optional regardless — the whole step is\n * skippable — so this only controls masking, not whether the field gates. */\n secret?: boolean;\n /** i18n key for the one-line helper text under the field. */\n hint_key: I18nKey;\n}\n\n/**\n * List the credentials Canvas should prompt for when onboarding the given ACP\n * provider, derived from the SDK registry's ``api_key_env_var`` /\n * ``base_url_env_var`` (mirrored via ``@openhands/typescript-client``) rather\n * than a hand-maintained per-provider list — so the field names track the SDK\n * as providers are added or renamed, with no parallel copy to drift. Each field\n * name equals the env var the agent-server exports into the provider subprocess\n * (which is what makes a saved secret reach the CLI); the API key renders\n * masked, the base URL plain-text. All three built-ins (Claude Code, Codex,\n * Gemini CLI) expose an API key + optional base URL.\n *\n * Every field is optional — the step is skippable — and a subscription / OAuth\n * login takes precedence over a key at runtime (most relevant for Gemini, whose\n * Google login is the common local path).\n *\n * Returns ``[]`` for OpenHands, the ``\"custom\"`` preset, any unknown key, and a\n * future OAuth-only provider whose registry entry has no ``api_key_env_var`` —\n * callers treat an empty list as \"no credentials step for this provider\".\n */\nexport function getAcpProviderSecrets(\n key: string | null | undefined,\n): ACPProviderSecretField[] {\n const info = key ? getClientAcpProvider(key) : null;\n if (!info) return [];\n const fields: ACPProviderSecretField[] = [];\n if (info.api_key_env_var) {\n fields.push({\n name: info.api_key_env_var,\n secret: true,\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_API_KEY_HINT,\n });\n }\n if (info.base_url_env_var) {\n fields.push({\n name: info.base_url_env_var,\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_BASE_URL_HINT,\n });\n }\n return fields;\n}\n\n/**\n * Look up a built-in ACP provider config by its registry key.\n *\n * Returns ``undefined`` for an empty / null key, for the ``\"custom\"`` preset\n * (which has no registry entry), and for any forward-compatible key Canvas's\n * registry doesn't know about yet. Centralizes the ``ACP_PROVIDERS.find(...)``\n * lookup shared by the resolvers below and by the adapter / settings surfaces\n * so the key-comparison shape lives in one place.\n */\nexport function getAcpProvider(\n key: string | null | undefined,\n): ACPProviderConfig | undefined {\n if (!key) return undefined;\n return ACP_PROVIDERS.find((provider) => provider.key === key);\n}\n\n/**\n * Resolve an ACP provider registry key (the value stored under\n * ``tags.acpserver`` on a conversation) to a human display name for the\n * sidebar chip.\n *\n * Returns ``null`` for an empty / null key and for keys not in\n * {@link ACP_PROVIDERS} — most notably ``\"custom\"`` (the user-supplied\n * command preset has no canonical brand name) and any forward-compatible\n * value Canvas's registry doesn't know about yet. Callers should fall\n * back to a generic ``\"ACP\"`` label in that case so the chip still\n * communicates \"this is an ACP conversation\".\n *\n * Kept separate from {@link buildAcpAgentSettingsDiff}'s lookup so the\n * conversation-card render path can resolve display names without\n * importing the settings-payload builder.\n */\nexport function getAcpProviderDisplayName(\n key: string | null | undefined,\n): string | null {\n const found = getAcpProvider(key);\n return found ? found.display_name : null;\n}\n\n/**\n * Resolve an ACP provider registry key to the icon discriminator the\n * conversation chip should render alongside the model text.\n *\n * Falls back to {@link ACP_PROVIDER_FALLBACK_ICON} for ``\"custom\"``,\n * unknown keys, or a missing key — the chip then shows a neutral\n * terminal glyph that still communicates \"this is an ACP conversation\"\n * without claiming a brand identity we don't know.\n */\nexport function resolveAcpProviderIcon(\n key: string | null | undefined,\n): ACPProviderIcon {\n return getAcpProvider(key)?.icon ?? ACP_PROVIDER_FALLBACK_ICON;\n}\n\n/**\n * Resolve a raw ``acp_model`` ID to the human-readable label the provider's\n * picker shows for it (e.g. ``\"claude-opus-4-7\"`` → ``\"Claude Opus 4.7\"``).\n *\n * Falls back to the raw ID when the provider is unknown or the ID isn't one\n * of its registered {@link ACPModelOption}s — so a user's custom override\n * still renders something meaningful rather than nothing. Returns ``null``\n * only when there is no model to show, letting the conversation chip decide\n * to display the provider name instead.\n */\nexport function labelForAcpModel(\n serverKey: string | null | undefined,\n modelId: string | null | undefined,\n): string | null {\n if (!modelId) return null;\n const provider = getAcpProvider(serverKey);\n const match = provider?.available_models?.find((m) => m.id === modelId);\n return match?.label ?? modelId;\n}\n\n/**\n * Build the ``agent_settings_diff`` payload PATCH /api/settings expects\n * for the agent-kind/provider choice the user just made.\n *\n * Used by both the Settings → Agent page and the onboarding \"choose\n * agent\" step — keeping the shape in one helper means a future change\n * (e.g. always seeding ``acp_command`` from the registry instead of\n * sending ``[]``, or adding new ``acp_*`` reset fields) lands in both\n * surfaces atomically.\n *\n * Returns ``null`` for an unknown ACP provider key by default — the\n * caller can skip the save (the UI shouldn't surface unknown options,\n * but the defensive path keeps a buggy preset list from corrupting\n * settings).\n *\n * Pass ``allowUnknownServer: true`` to opt into pass-through for keys\n * that aren't in {@link ACP_PROVIDERS} or ``ACP_CUSTOM_PRESET_KEY``.\n * The Settings → Agent page uses this when the user opens settings\n * that already carry an ``acp_server`` value canvas's registry\n * doesn't know about (e.g. set out-of-band via the API for a provider\n * we haven't mirrored yet) and saves without changing the command —\n * otherwise the original key would be silently demoted to ``\"custom\"``.\n */\nexport function buildAcpAgentSettingsDiff(\n providerKey: string,\n options: {\n command?: string[];\n model?: string | null;\n allowUnknownServer?: boolean;\n } = {},\n): Record<string, unknown> | null {\n if (providerKey === \"openhands\") {\n // Switching back to OpenHands. The agent-server's ``Settings.update``\n // applies a fresh ``{'agent_kind': ...}`` base whenever the kind\n // flips, so any ``acp_*`` fields would be discarded before\n // validation. Send the kind alone.\n return { agent_kind: \"openhands\" };\n }\n\n const isCustom = providerKey === ACP_CUSTOM_PRESET_KEY;\n const provider = isCustom ? undefined : getAcpProvider(providerKey);\n if (!isCustom && !provider && !options.allowUnknownServer) {\n return null;\n }\n\n const model =\n options.model === undefined\n ? (provider?.default_model ?? null)\n : options.model;\n\n // ``acp_args: []`` resets any API-set ``acp_args`` that would\n // otherwise survive and concatenate to ``acp_command`` at spawn time\n // (the agent-server merges the two before exec). Callers building the\n // payload from a textarea that already shows the merged command\n // (Settings → Agent) round-trip correctly — the merged tokens land in\n // ``acp_command`` here, so no args are lost.\n return {\n agent_kind: \"acp\",\n acp_server: providerKey,\n acp_command: options.command ?? [],\n acp_args: [],\n acp_model: model ?? null,\n };\n}\n"],"mappings":"6OAqBA,IAAa,EAA2B,IAAI,IAAI,CAC9C,UACA,wBACD,CAAC,CAYF,SAAS,EAAa,EAA+B,CACnD,GAAI,OAAO,GAAU,SAAU,OAAO,KACtC,IAAM,EAAU,EAAM,MAAM,CAI5B,MAHI,CAAC,GACD,EAAyB,IAAI,EAAQ,aAAa,CAAC,EACnD,IAAA,cAAyC,KACtC,EAgBT,SAAgB,EAAyB,EAMvB,CAChB,IAAK,IAAM,IAAa,CACtB,EAAO,YACP,EAAO,UACP,EAAO,WACP,EAAO,OACR,CAAE,CACD,IAAM,EAAQ,EAAa,EAAU,CACrC,GAAI,EAAO,OAAO,EAEpB,OAAO,EAAO,iBAAmB,KAiEnC,IAAM,EAGF,CACF,cAAe,CACb,KAAM,cACN,gBAAiB,EAAA,QAAQ,yCAC1B,CACD,MAAO,CACL,KAAM,QACN,gBAAiB,EAAA,QAAQ,mCAC1B,CACD,aAAc,CACZ,KAAM,SACN,gBAAiB,EAAA,QAAQ,wCAC1B,CACF,CAMY,EAAqC,OAAO,QACvD,EACD,CAAC,KAAK,CAAC,EAAK,KAAQ,CACnB,IAAM,EAAO,EAAA,eAAqB,EAAI,CACtC,MAAO,CACL,MACA,aAAc,GAAM,cAAgB,EACpC,gBAAiB,EAAO,CAAC,GAAG,EAAK,gBAAgB,CAAG,EAAE,CACtD,iBAAkB,GAAM,kBAAkB,IAAK,IAAW,CACxD,GAAI,EAAM,GACV,MAAO,EAAM,MACd,EAAE,CACH,cAAe,GAAM,eAAiB,IAAA,GACtC,gBAAiB,EAAG,gBACpB,KAAM,EAAG,KACV,EACD,CAyEF,SAAgB,EACd,EAC+B,CAC1B,KACL,OAAO,EAAc,KAAM,GAAa,EAAS,MAAQ,EAAI,CAmB/D,SAAgB,EACd,EACe,CACf,IAAM,EAAQ,EAAe,EAAI,CACjC,OAAO,EAAQ,EAAM,aAAe,KAYtC,SAAgB,EACd,EACiB,CACjB,OAAO,EAAe,EAAI,EAAE,MAAA,cAa9B,SAAgB,EACd,EACA,EACe,CAIf,OAHK,EACY,EAAe,EAClB,EAAU,kBAAkB,KAAM,GAAM,EAAE,KAAO,EAAQ,EACzD,OAAS,EAHF"}
@@ -99,9 +99,22 @@ export interface ACPProviderSecretField {
99
99
  }
100
100
  /**
101
101
  * List the credentials Canvas should prompt for when onboarding the given ACP
102
- * provider. Returns ``[]`` for OpenHands, the ``"custom"`` preset, providers
103
- * that don't use a static API key (Gemini CLI), and any unknown key — callers
104
- * treat an empty list as "no credentials step for this provider".
102
+ * provider, derived from the SDK registry's ``api_key_env_var`` /
103
+ * ``base_url_env_var`` (mirrored via ``@openhands/typescript-client``) rather
104
+ * than a hand-maintained per-provider list so the field names track the SDK
105
+ * as providers are added or renamed, with no parallel copy to drift. Each field
106
+ * name equals the env var the agent-server exports into the provider subprocess
107
+ * (which is what makes a saved secret reach the CLI); the API key renders
108
+ * masked, the base URL plain-text. All three built-ins (Claude Code, Codex,
109
+ * Gemini CLI) expose an API key + optional base URL.
110
+ *
111
+ * Every field is optional — the step is skippable — and a subscription / OAuth
112
+ * login takes precedence over a key at runtime (most relevant for Gemini, whose
113
+ * Google login is the common local path).
114
+ *
115
+ * Returns ``[]`` for OpenHands, the ``"custom"`` preset, any unknown key, and a
116
+ * future OAuth-only provider whose registry entry has no ``api_key_env_var`` —
117
+ * callers treat an empty list as "no credentials step for this provider".
105
118
  */
106
119
  export declare function getAcpProviderSecrets(key: string | null | undefined): ACPProviderSecretField[];
107
120
  /**
@@ -47,7 +47,6 @@ var a = {
47
47
  icon: n.icon
48
48
  };
49
49
  });
50
- e.ONBOARDING$ACP_SECRET_API_KEY_HINT, e.ONBOARDING$ACP_SECRET_BASE_URL_HINT, e.ONBOARDING$ACP_SECRET_API_KEY_HINT, e.ONBOARDING$ACP_SECRET_BASE_URL_HINT;
51
50
  function s(e) {
52
51
  if (e) return o.find((t) => t.key === e);
53
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"acp-providers.js","names":[],"sources":["../../src/constants/acp-providers.ts"],"sourcesContent":["import { getAcpProvider as getClientAcpProvider } from \"@openhands/typescript-client\";\nimport { I18nKey } from \"#/i18n/declaration\";\n\nexport type ACPProviderIcon =\n | \"claude-code\"\n | \"codex\"\n | \"gemini\"\n | \"cli-generic\";\n\nexport const ACP_PROVIDER_FALLBACK_ICON: ACPProviderIcon = \"cli-generic\";\n\n// SDK placeholder strings the ACP wrapper returns before the user has\n// chosen a real model — surfacing either would lie about what's running.\nexport const ACP_DEFAULT_PLACEHOLDERS = new Set([\n \"default\",\n \"default (recommended)\",\n]);\n\n// Sentinel ``agent.llm.model`` returned by older SDKs for ACP conversations\n// in lieu of a real model. Suppressed at every consumer that resolves a\n// display string.\nexport const ACP_MANAGED_SENTINEL = \"acp-managed\";\n\n/**\n * Filter for \"real\" ACP model strings — non-empty, not the SDK's \"default\"\n * placeholder, not the legacy ``acp-managed`` sentinel. Returns the trimmed\n * value on success, ``null`` otherwise.\n */\nfunction realAcpModel(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n if (!trimmed) return null;\n if (ACP_DEFAULT_PLACEHOLDERS.has(trimmed.toLowerCase())) return null;\n if (trimmed === ACP_MANAGED_SENTINEL) return null;\n return trimmed;\n}\n\n/**\n * Single source of truth for resolving the model string to surface for an\n * ACP conversation/settings context. Consumed by the conversation adapter\n * (chip text), the conversation-creation path (concrete ``acp_model``\n * payload), the Settings → Agent form (initial value), and the chat-input\n * model label.\n *\n * Precedence: SDK runtime fields → user-configured ``acp_model`` →\n * legacy ``agent.llm.model`` → provider default (when ``providerDefault``\n * is passed). Pass ``providerDefault`` only on surfaces that should\n * silently substitute the registry default; omit it for the conversation\n * chip, which must distinguish \"no concrete model\" from \"default\".\n */\nexport function resolveEffectiveAcpModel(inputs: {\n runtimeName?: string | null;\n runtimeId?: string | null;\n configured?: string | null;\n sdkLlm?: string | null;\n providerDefault?: string | null;\n}): string | null {\n for (const candidate of [\n inputs.runtimeName,\n inputs.runtimeId,\n inputs.configured,\n inputs.sdkLlm,\n ]) {\n const value = realAcpModel(candidate);\n if (value) return value;\n }\n return inputs.providerDefault ?? null;\n}\n\n/**\n * Shape of a built-in ACP (Agent Client Protocol) provider as Canvas consumes\n * it. The data fields (display name, launch command, model picker + default)\n * are sourced at module load from ``@openhands/typescript-client``'s ACP\n * registry — the generated mirror of the Python source of truth\n * ``openhands.sdk.settings.acp_providers``. This config only adds the\n * Canvas-specific UI fields ({@link ACPProviderConfig.icon} +\n * {@link ACPProviderConfig.description_key}); see {@link ACP_PROVIDER_UI}.\n */\nexport interface ACPProviderConfig {\n /** Stable registry key, also stored on conversations as ``tags.acpserver``. */\n key: string;\n /** Human-readable name shown in dropdowns and conversation chips. */\n display_name: string;\n /**\n * Tokens passed to the agent-server as ``acp_command`` when this preset\n * is picked. Each entry must be a real ACP-protocol stdio server — the\n * SDK validates this against the {@link ACPProviderConfig.key}.\n *\n * NB: ``npx -y @openai/codex acp`` looks plausible but is **not** an\n * ACP server — the codex CLI has no ``acp`` subcommand and exits with\n * ``Error: stdin is not a terminal`` when spawned without a TTY, which\n * silently deadlocks the agent-server's ACP handshake. Use\n * ``@zed-industries/codex-acp`` (the Zed-shipped wrapper) instead.\n */\n default_command: string[];\n /**\n * Suggested ACP model IDs for the provider's picker, sourced from the\n * typescript-client registry. Not authoritative access checks; users can\n * still enter a custom override in Settings -> Agent.\n */\n available_models?: ACPModelOption[];\n /** Model ID preselected for built-in providers so Canvas never saves blank. */\n default_model?: string;\n /**\n * i18n key for the one-line provider description rendered under the\n * onboarding tile. Stored on the registry so adding a new ACP\n * provider only requires editing this file (not the onboarding tile\n * list separately).\n */\n description_key: I18nKey;\n /**\n * Serializable icon key used by UI surfaces that render provider\n * choices. Kept as a string so the SDK mirror check can continue to\n * parse this registry without importing React components.\n */\n icon?: ACPProviderIcon;\n}\n\nexport interface ACPModelOption {\n /** Exact model ID sent as ``acp_model``. */\n id: string;\n /** Human-readable label shown in Settings -> Agent. */\n label: string;\n}\n\n// Canvas-only UI metadata per built-in provider, keyed by the ACP registry\n// key. Everything else — display name, launch command, model picker list and\n// default — comes from the typescript-client registry below. Adding a model\n// or a provider happens upstream in the SDK; Canvas only owns the brand icon\n// and the onboarding-tile description here. A provider with no entry here is\n// intentionally not surfaced in the UI.\nconst ACP_PROVIDER_UI: Record<\n string,\n { icon: ACPProviderIcon; description_key: I18nKey }\n> = {\n \"claude-code\": {\n icon: \"claude-code\",\n description_key: I18nKey.ONBOARDING$AGENT_CLAUDE_CODE_DESCRIPTION,\n },\n codex: {\n icon: \"codex\",\n description_key: I18nKey.ONBOARDING$AGENT_CODEX_DESCRIPTION,\n },\n \"gemini-cli\": {\n icon: \"gemini\",\n description_key: I18nKey.ONBOARDING$AGENT_GEMINI_CLI_DESCRIPTION,\n },\n};\n\n// Built-in ACP providers Canvas surfaces, built by enriching each upstream\n// registry record (``@openhands/typescript-client`` → Python SDK) with the\n// Canvas UI metadata above. Model lists + defaults are no longer hand-kept\n// here (closes agent-canvas#740) — they track the SDK via the pinned client.\nexport const ACP_PROVIDERS: ACPProviderConfig[] = Object.entries(\n ACP_PROVIDER_UI,\n).map(([key, ui]) => {\n const info = getClientAcpProvider(key);\n return {\n key,\n display_name: info?.display_name ?? key,\n default_command: info ? [...info.default_command] : [],\n available_models: info?.available_models?.map((model) => ({\n id: model.id,\n label: model.label,\n })),\n default_model: info?.default_model ?? undefined,\n description_key: ui.description_key,\n icon: ui.icon,\n };\n});\n\nexport const ACP_CUSTOM_PRESET_KEY = \"custom\";\n\n/**\n * A credential an ACP provider authenticates with, surfaced during onboarding\n * so the user can populate it without leaving the flow. The {@link name} is\n * both the global-secret name and the environment variable the agent-server\n * exports into the ACP subprocess — keeping them identical is what makes a\n * saved secret actually reach the provider CLI.\n */\nexport interface ACPProviderSecretField {\n /** Secret name and env var (e.g. ``\"ANTHROPIC_API_KEY\"``). Must satisfy the\n * secret-name pattern ``^[a-zA-Z][a-zA-Z0-9_]{0,63}$``. */\n name: string;\n /** Render as a masked password input (API keys) rather than a plain-text\n * input (base URLs). Every field is optional regardless — the whole step is\n * skippable — so this only controls masking, not whether the field gates. */\n secret?: boolean;\n /** i18n key for the one-line helper text under the field. */\n hint_key: I18nKey;\n}\n\n// Credentials Canvas prompts for during onboarding, keyed by ACP registry key.\n// Only providers that authenticate through an env-var API key appear here:\n// Claude Code (Anthropic) and Codex (OpenAI). Gemini CLI authenticates via an\n// interactive OAuth login rather than a static key, so it has no entry and its\n// onboarding credentials step is skipped. Every field is optional (the step is\n// skippable): the API keys render masked, the base-URL entries are plain-text\n// overrides for proxies/gateways. A provider with no entry simply shows no\n// credentials step.\nconst ACP_PROVIDER_SECRETS: Record<string, ACPProviderSecretField[]> = {\n \"claude-code\": [\n {\n name: \"ANTHROPIC_API_KEY\",\n secret: true,\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_API_KEY_HINT,\n },\n {\n name: \"ANTHROPIC_BASE_URL\",\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_BASE_URL_HINT,\n },\n ],\n codex: [\n {\n name: \"OPENAI_API_KEY\",\n secret: true,\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_API_KEY_HINT,\n },\n {\n name: \"OPENAI_BASE_URL\",\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_BASE_URL_HINT,\n },\n ],\n};\n\n/**\n * List the credentials Canvas should prompt for when onboarding the given ACP\n * provider. Returns ``[]`` for OpenHands, the ``\"custom\"`` preset, providers\n * that don't use a static API key (Gemini CLI), and any unknown key — callers\n * treat an empty list as \"no credentials step for this provider\".\n */\nexport function getAcpProviderSecrets(\n key: string | null | undefined,\n): ACPProviderSecretField[] {\n if (!key) return [];\n return ACP_PROVIDER_SECRETS[key] ?? [];\n}\n\n/**\n * Look up a built-in ACP provider config by its registry key.\n *\n * Returns ``undefined`` for an empty / null key, for the ``\"custom\"`` preset\n * (which has no registry entry), and for any forward-compatible key Canvas's\n * registry doesn't know about yet. Centralizes the ``ACP_PROVIDERS.find(...)``\n * lookup shared by the resolvers below and by the adapter / settings surfaces\n * so the key-comparison shape lives in one place.\n */\nexport function getAcpProvider(\n key: string | null | undefined,\n): ACPProviderConfig | undefined {\n if (!key) return undefined;\n return ACP_PROVIDERS.find((provider) => provider.key === key);\n}\n\n/**\n * Resolve an ACP provider registry key (the value stored under\n * ``tags.acpserver`` on a conversation) to a human display name for the\n * sidebar chip.\n *\n * Returns ``null`` for an empty / null key and for keys not in\n * {@link ACP_PROVIDERS} — most notably ``\"custom\"`` (the user-supplied\n * command preset has no canonical brand name) and any forward-compatible\n * value Canvas's registry doesn't know about yet. Callers should fall\n * back to a generic ``\"ACP\"`` label in that case so the chip still\n * communicates \"this is an ACP conversation\".\n *\n * Kept separate from {@link buildAcpAgentSettingsDiff}'s lookup so the\n * conversation-card render path can resolve display names without\n * importing the settings-payload builder.\n */\nexport function getAcpProviderDisplayName(\n key: string | null | undefined,\n): string | null {\n const found = getAcpProvider(key);\n return found ? found.display_name : null;\n}\n\n/**\n * Resolve an ACP provider registry key to the icon discriminator the\n * conversation chip should render alongside the model text.\n *\n * Falls back to {@link ACP_PROVIDER_FALLBACK_ICON} for ``\"custom\"``,\n * unknown keys, or a missing key — the chip then shows a neutral\n * terminal glyph that still communicates \"this is an ACP conversation\"\n * without claiming a brand identity we don't know.\n */\nexport function resolveAcpProviderIcon(\n key: string | null | undefined,\n): ACPProviderIcon {\n return getAcpProvider(key)?.icon ?? ACP_PROVIDER_FALLBACK_ICON;\n}\n\n/**\n * Resolve a raw ``acp_model`` ID to the human-readable label the provider's\n * picker shows for it (e.g. ``\"claude-opus-4-7\"`` → ``\"Claude Opus 4.7\"``).\n *\n * Falls back to the raw ID when the provider is unknown or the ID isn't one\n * of its registered {@link ACPModelOption}s — so a user's custom override\n * still renders something meaningful rather than nothing. Returns ``null``\n * only when there is no model to show, letting the conversation chip decide\n * to display the provider name instead.\n */\nexport function labelForAcpModel(\n serverKey: string | null | undefined,\n modelId: string | null | undefined,\n): string | null {\n if (!modelId) return null;\n const provider = getAcpProvider(serverKey);\n const match = provider?.available_models?.find((m) => m.id === modelId);\n return match?.label ?? modelId;\n}\n\n/**\n * Build the ``agent_settings_diff`` payload PATCH /api/settings expects\n * for the agent-kind/provider choice the user just made.\n *\n * Used by both the Settings → Agent page and the onboarding \"choose\n * agent\" step — keeping the shape in one helper means a future change\n * (e.g. always seeding ``acp_command`` from the registry instead of\n * sending ``[]``, or adding new ``acp_*`` reset fields) lands in both\n * surfaces atomically.\n *\n * Returns ``null`` for an unknown ACP provider key by default — the\n * caller can skip the save (the UI shouldn't surface unknown options,\n * but the defensive path keeps a buggy preset list from corrupting\n * settings).\n *\n * Pass ``allowUnknownServer: true`` to opt into pass-through for keys\n * that aren't in {@link ACP_PROVIDERS} or ``ACP_CUSTOM_PRESET_KEY``.\n * The Settings → Agent page uses this when the user opens settings\n * that already carry an ``acp_server`` value canvas's registry\n * doesn't know about (e.g. set out-of-band via the API for a provider\n * we haven't mirrored yet) and saves without changing the command —\n * otherwise the original key would be silently demoted to ``\"custom\"``.\n */\nexport function buildAcpAgentSettingsDiff(\n providerKey: string,\n options: {\n command?: string[];\n model?: string | null;\n allowUnknownServer?: boolean;\n } = {},\n): Record<string, unknown> | null {\n if (providerKey === \"openhands\") {\n // Switching back to OpenHands. The agent-server's ``Settings.update``\n // applies a fresh ``{'agent_kind': ...}`` base whenever the kind\n // flips, so any ``acp_*`` fields would be discarded before\n // validation. Send the kind alone.\n return { agent_kind: \"openhands\" };\n }\n\n const isCustom = providerKey === ACP_CUSTOM_PRESET_KEY;\n const provider = isCustom ? undefined : getAcpProvider(providerKey);\n if (!isCustom && !provider && !options.allowUnknownServer) {\n return null;\n }\n\n const model =\n options.model === undefined\n ? (provider?.default_model ?? null)\n : options.model;\n\n // ``acp_args: []`` resets any API-set ``acp_args`` that would\n // otherwise survive and concatenate to ``acp_command`` at spawn time\n // (the agent-server merges the two before exec). Callers building the\n // payload from a textarea that already shows the merged command\n // (Settings → Agent) round-trip correctly — the merged tokens land in\n // ``acp_command`` here, so no args are lost.\n return {\n agent_kind: \"acp\",\n acp_server: providerKey,\n acp_command: options.command ?? [],\n acp_args: [],\n acp_model: model ?? null,\n };\n}\n"],"mappings":";;;AAaA,IAAa,IAA2B,IAAI,IAAI,CAC9C,WACA,wBACD,CAAC;AAYF,SAAS,EAAa,GAA+B;AACnD,KAAI,OAAO,KAAU,SAAU,QAAO;CACtC,IAAM,IAAU,EAAM,MAAM;AAI5B,QAHI,CAAC,KACD,EAAyB,IAAI,EAAQ,aAAa,CAAC,IACnD,MAAA,gBAAyC,OACtC;;AAgBT,SAAgB,EAAyB,GAMvB;AAChB,MAAK,IAAM,KAAa;EACtB,EAAO;EACP,EAAO;EACP,EAAO;EACP,EAAO;EACR,EAAE;EACD,IAAM,IAAQ,EAAa,EAAU;AACrC,MAAI,EAAO,QAAO;;AAEpB,QAAO,EAAO,mBAAmB;;AAiEnC,IAAM,IAGF;CACF,eAAe;EACb,MAAM;EACN,iBAAiB,EAAQ;EAC1B;CACD,OAAO;EACL,MAAM;EACN,iBAAiB,EAAQ;EAC1B;CACD,cAAc;EACZ,MAAM;EACN,iBAAiB,EAAQ;EAC1B;CACF,EAMY,IAAqC,OAAO,QACvD,EACD,CAAC,KAAK,CAAC,GAAK,OAAQ;CACnB,IAAM,IAAO,EAAqB,EAAI;AACtC,QAAO;EACL;EACA,cAAc,GAAM,gBAAgB;EACpC,iBAAiB,IAAO,CAAC,GAAG,EAAK,gBAAgB,GAAG,EAAE;EACtD,kBAAkB,GAAM,kBAAkB,KAAK,OAAW;GACxD,IAAI,EAAM;GACV,OAAO,EAAM;GACd,EAAE;EACH,eAAe,GAAM,iBAAiB,KAAA;EACtC,iBAAiB,EAAG;EACpB,MAAM,EAAG;EACV;EACD;AAoCc,EAAQ,oCAIR,EAAQ,qCAOR,EAAQ,oCAIR,EAAQ;AA2BxB,SAAgB,EACd,GAC+B;AAC1B,OACL,QAAO,EAAc,MAAM,MAAa,EAAS,QAAQ,EAAI;;AAmB/D,SAAgB,EACd,GACe;CACf,IAAM,IAAQ,EAAe,EAAI;AACjC,QAAO,IAAQ,EAAM,eAAe;;AAYtC,SAAgB,EACd,GACiB;AACjB,QAAO,EAAe,EAAI,EAAE,QAAA;;AAa9B,SAAgB,EACd,GACA,GACe;AAIf,QAHK,IACY,EAAe,EAClB,EAAU,kBAAkB,MAAM,MAAM,EAAE,OAAO,EAAQ,EACzD,SAAS,IAHF"}
1
+ {"version":3,"file":"acp-providers.js","names":[],"sources":["../../src/constants/acp-providers.ts"],"sourcesContent":["import { getAcpProvider as getClientAcpProvider } from \"@openhands/typescript-client\";\nimport { I18nKey } from \"#/i18n/declaration\";\n\n/** Upstream registry fields not yet on the pinned client's exported type. */\ntype ClientAcpProviderRegistry = NonNullable<\n ReturnType<typeof getClientAcpProvider>\n> & {\n available_models?: Array<{ id: string; label: string }>;\n default_model?: string;\n};\n\nexport type ACPProviderIcon =\n | \"claude-code\"\n | \"codex\"\n | \"gemini\"\n | \"cli-generic\";\n\nexport const ACP_PROVIDER_FALLBACK_ICON: ACPProviderIcon = \"cli-generic\";\n\n// SDK placeholder strings the ACP wrapper returns before the user has\n// chosen a real model — surfacing either would lie about what's running.\nexport const ACP_DEFAULT_PLACEHOLDERS = new Set([\n \"default\",\n \"default (recommended)\",\n]);\n\n// Sentinel ``agent.llm.model`` returned by older SDKs for ACP conversations\n// in lieu of a real model. Suppressed at every consumer that resolves a\n// display string.\nexport const ACP_MANAGED_SENTINEL = \"acp-managed\";\n\n/**\n * Filter for \"real\" ACP model strings — non-empty, not the SDK's \"default\"\n * placeholder, not the legacy ``acp-managed`` sentinel. Returns the trimmed\n * value on success, ``null`` otherwise.\n */\nfunction realAcpModel(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n if (!trimmed) return null;\n if (ACP_DEFAULT_PLACEHOLDERS.has(trimmed.toLowerCase())) return null;\n if (trimmed === ACP_MANAGED_SENTINEL) return null;\n return trimmed;\n}\n\n/**\n * Single source of truth for resolving the model string to surface for an\n * ACP conversation/settings context. Consumed by the conversation adapter\n * (chip text), the conversation-creation path (concrete ``acp_model``\n * payload), the Settings → Agent form (initial value), and the chat-input\n * model label.\n *\n * Precedence: SDK runtime fields → user-configured ``acp_model`` →\n * legacy ``agent.llm.model`` → provider default (when ``providerDefault``\n * is passed). Pass ``providerDefault`` only on surfaces that should\n * silently substitute the registry default; omit it for the conversation\n * chip, which must distinguish \"no concrete model\" from \"default\".\n */\nexport function resolveEffectiveAcpModel(inputs: {\n runtimeName?: string | null;\n runtimeId?: string | null;\n configured?: string | null;\n sdkLlm?: string | null;\n providerDefault?: string | null;\n}): string | null {\n for (const candidate of [\n inputs.runtimeName,\n inputs.runtimeId,\n inputs.configured,\n inputs.sdkLlm,\n ]) {\n const value = realAcpModel(candidate);\n if (value) return value;\n }\n return inputs.providerDefault ?? null;\n}\n\n/**\n * Shape of a built-in ACP (Agent Client Protocol) provider as Canvas consumes\n * it. The data fields (display name, launch command, model picker + default)\n * are sourced at module load from ``@openhands/typescript-client``'s ACP\n * registry — the generated mirror of the Python source of truth\n * ``openhands.sdk.settings.acp_providers``. This config only adds the\n * Canvas-specific UI fields ({@link ACPProviderConfig.icon} +\n * {@link ACPProviderConfig.description_key}); see {@link ACP_PROVIDER_UI}.\n */\nexport interface ACPProviderConfig {\n /** Stable registry key, also stored on conversations as ``tags.acpserver``. */\n key: string;\n /** Human-readable name shown in dropdowns and conversation chips. */\n display_name: string;\n /**\n * Tokens passed to the agent-server as ``acp_command`` when this preset\n * is picked. Each entry must be a real ACP-protocol stdio server — the\n * SDK validates this against the {@link ACPProviderConfig.key}.\n *\n * NB: ``npx -y @openai/codex acp`` looks plausible but is **not** an\n * ACP server — the codex CLI has no ``acp`` subcommand and exits with\n * ``Error: stdin is not a terminal`` when spawned without a TTY, which\n * silently deadlocks the agent-server's ACP handshake. Use\n * ``@zed-industries/codex-acp`` (the Zed-shipped wrapper) instead.\n */\n default_command: string[];\n /**\n * Suggested ACP model IDs for the provider's picker, sourced from the\n * typescript-client registry. Not authoritative access checks; users can\n * still enter a custom override in Settings -> Agent.\n */\n available_models?: ACPModelOption[];\n /** Model ID preselected for built-in providers so Canvas never saves blank. */\n default_model?: string;\n /**\n * i18n key for the one-line provider description rendered under the\n * onboarding tile. Stored on the registry so adding a new ACP\n * provider only requires editing this file (not the onboarding tile\n * list separately).\n */\n description_key: I18nKey;\n /**\n * Serializable icon key used by UI surfaces that render provider\n * choices. Kept as a string so the SDK mirror check can continue to\n * parse this registry without importing React components.\n */\n icon?: ACPProviderIcon;\n}\n\nexport interface ACPModelOption {\n /** Exact model ID sent as ``acp_model``. */\n id: string;\n /** Human-readable label shown in Settings -> Agent. */\n label: string;\n}\n\n// Canvas-only UI metadata per built-in provider, keyed by the ACP registry\n// key. Everything else — display name, launch command, model picker list and\n// default — comes from the typescript-client registry below. Adding a model\n// or a provider happens upstream in the SDK; Canvas only owns the brand icon\n// and the onboarding-tile description here. A provider with no entry here is\n// intentionally not surfaced in the UI.\nconst ACP_PROVIDER_UI: Record<\n string,\n { icon: ACPProviderIcon; description_key: I18nKey }\n> = {\n \"claude-code\": {\n icon: \"claude-code\",\n description_key: I18nKey.ONBOARDING$AGENT_CLAUDE_CODE_DESCRIPTION,\n },\n codex: {\n icon: \"codex\",\n description_key: I18nKey.ONBOARDING$AGENT_CODEX_DESCRIPTION,\n },\n \"gemini-cli\": {\n icon: \"gemini\",\n description_key: I18nKey.ONBOARDING$AGENT_GEMINI_CLI_DESCRIPTION,\n },\n};\n\n// Built-in ACP providers Canvas surfaces, built by enriching each upstream\n// registry record (``@openhands/typescript-client`` → Python SDK) with the\n// Canvas UI metadata above. Model lists + defaults are no longer hand-kept\n// here (closes agent-canvas#740) — they track the SDK via the pinned client.\nexport const ACP_PROVIDERS: ACPProviderConfig[] = Object.entries(\n ACP_PROVIDER_UI,\n).map(([key, ui]) => {\n const info = getClientAcpProvider(key) as ClientAcpProviderRegistry | null;\n return {\n key,\n display_name: info?.display_name ?? key,\n default_command: info ? [...info.default_command] : [],\n available_models: info?.available_models?.map((model) => ({\n id: model.id,\n label: model.label,\n })),\n default_model: info?.default_model ?? undefined,\n description_key: ui.description_key,\n icon: ui.icon,\n };\n});\n\nexport const ACP_CUSTOM_PRESET_KEY = \"custom\";\n\n/**\n * A credential an ACP provider authenticates with, surfaced during onboarding\n * so the user can populate it without leaving the flow. The {@link name} is\n * both the global-secret name and the environment variable the agent-server\n * exports into the ACP subprocess — keeping them identical is what makes a\n * saved secret actually reach the provider CLI.\n */\nexport interface ACPProviderSecretField {\n /** Secret name and env var (e.g. ``\"ANTHROPIC_API_KEY\"``). Must satisfy the\n * secret-name pattern ``^[a-zA-Z][a-zA-Z0-9_]{0,63}$``. */\n name: string;\n /** Render as a masked password input (API keys) rather than a plain-text\n * input (base URLs). Every field is optional regardless — the whole step is\n * skippable — so this only controls masking, not whether the field gates. */\n secret?: boolean;\n /** i18n key for the one-line helper text under the field. */\n hint_key: I18nKey;\n}\n\n/**\n * List the credentials Canvas should prompt for when onboarding the given ACP\n * provider, derived from the SDK registry's ``api_key_env_var`` /\n * ``base_url_env_var`` (mirrored via ``@openhands/typescript-client``) rather\n * than a hand-maintained per-provider list — so the field names track the SDK\n * as providers are added or renamed, with no parallel copy to drift. Each field\n * name equals the env var the agent-server exports into the provider subprocess\n * (which is what makes a saved secret reach the CLI); the API key renders\n * masked, the base URL plain-text. All three built-ins (Claude Code, Codex,\n * Gemini CLI) expose an API key + optional base URL.\n *\n * Every field is optional — the step is skippable — and a subscription / OAuth\n * login takes precedence over a key at runtime (most relevant for Gemini, whose\n * Google login is the common local path).\n *\n * Returns ``[]`` for OpenHands, the ``\"custom\"`` preset, any unknown key, and a\n * future OAuth-only provider whose registry entry has no ``api_key_env_var`` —\n * callers treat an empty list as \"no credentials step for this provider\".\n */\nexport function getAcpProviderSecrets(\n key: string | null | undefined,\n): ACPProviderSecretField[] {\n const info = key ? getClientAcpProvider(key) : null;\n if (!info) return [];\n const fields: ACPProviderSecretField[] = [];\n if (info.api_key_env_var) {\n fields.push({\n name: info.api_key_env_var,\n secret: true,\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_API_KEY_HINT,\n });\n }\n if (info.base_url_env_var) {\n fields.push({\n name: info.base_url_env_var,\n hint_key: I18nKey.ONBOARDING$ACP_SECRET_BASE_URL_HINT,\n });\n }\n return fields;\n}\n\n/**\n * Look up a built-in ACP provider config by its registry key.\n *\n * Returns ``undefined`` for an empty / null key, for the ``\"custom\"`` preset\n * (which has no registry entry), and for any forward-compatible key Canvas's\n * registry doesn't know about yet. Centralizes the ``ACP_PROVIDERS.find(...)``\n * lookup shared by the resolvers below and by the adapter / settings surfaces\n * so the key-comparison shape lives in one place.\n */\nexport function getAcpProvider(\n key: string | null | undefined,\n): ACPProviderConfig | undefined {\n if (!key) return undefined;\n return ACP_PROVIDERS.find((provider) => provider.key === key);\n}\n\n/**\n * Resolve an ACP provider registry key (the value stored under\n * ``tags.acpserver`` on a conversation) to a human display name for the\n * sidebar chip.\n *\n * Returns ``null`` for an empty / null key and for keys not in\n * {@link ACP_PROVIDERS} — most notably ``\"custom\"`` (the user-supplied\n * command preset has no canonical brand name) and any forward-compatible\n * value Canvas's registry doesn't know about yet. Callers should fall\n * back to a generic ``\"ACP\"`` label in that case so the chip still\n * communicates \"this is an ACP conversation\".\n *\n * Kept separate from {@link buildAcpAgentSettingsDiff}'s lookup so the\n * conversation-card render path can resolve display names without\n * importing the settings-payload builder.\n */\nexport function getAcpProviderDisplayName(\n key: string | null | undefined,\n): string | null {\n const found = getAcpProvider(key);\n return found ? found.display_name : null;\n}\n\n/**\n * Resolve an ACP provider registry key to the icon discriminator the\n * conversation chip should render alongside the model text.\n *\n * Falls back to {@link ACP_PROVIDER_FALLBACK_ICON} for ``\"custom\"``,\n * unknown keys, or a missing key — the chip then shows a neutral\n * terminal glyph that still communicates \"this is an ACP conversation\"\n * without claiming a brand identity we don't know.\n */\nexport function resolveAcpProviderIcon(\n key: string | null | undefined,\n): ACPProviderIcon {\n return getAcpProvider(key)?.icon ?? ACP_PROVIDER_FALLBACK_ICON;\n}\n\n/**\n * Resolve a raw ``acp_model`` ID to the human-readable label the provider's\n * picker shows for it (e.g. ``\"claude-opus-4-7\"`` → ``\"Claude Opus 4.7\"``).\n *\n * Falls back to the raw ID when the provider is unknown or the ID isn't one\n * of its registered {@link ACPModelOption}s — so a user's custom override\n * still renders something meaningful rather than nothing. Returns ``null``\n * only when there is no model to show, letting the conversation chip decide\n * to display the provider name instead.\n */\nexport function labelForAcpModel(\n serverKey: string | null | undefined,\n modelId: string | null | undefined,\n): string | null {\n if (!modelId) return null;\n const provider = getAcpProvider(serverKey);\n const match = provider?.available_models?.find((m) => m.id === modelId);\n return match?.label ?? modelId;\n}\n\n/**\n * Build the ``agent_settings_diff`` payload PATCH /api/settings expects\n * for the agent-kind/provider choice the user just made.\n *\n * Used by both the Settings → Agent page and the onboarding \"choose\n * agent\" step — keeping the shape in one helper means a future change\n * (e.g. always seeding ``acp_command`` from the registry instead of\n * sending ``[]``, or adding new ``acp_*`` reset fields) lands in both\n * surfaces atomically.\n *\n * Returns ``null`` for an unknown ACP provider key by default — the\n * caller can skip the save (the UI shouldn't surface unknown options,\n * but the defensive path keeps a buggy preset list from corrupting\n * settings).\n *\n * Pass ``allowUnknownServer: true`` to opt into pass-through for keys\n * that aren't in {@link ACP_PROVIDERS} or ``ACP_CUSTOM_PRESET_KEY``.\n * The Settings → Agent page uses this when the user opens settings\n * that already carry an ``acp_server`` value canvas's registry\n * doesn't know about (e.g. set out-of-band via the API for a provider\n * we haven't mirrored yet) and saves without changing the command —\n * otherwise the original key would be silently demoted to ``\"custom\"``.\n */\nexport function buildAcpAgentSettingsDiff(\n providerKey: string,\n options: {\n command?: string[];\n model?: string | null;\n allowUnknownServer?: boolean;\n } = {},\n): Record<string, unknown> | null {\n if (providerKey === \"openhands\") {\n // Switching back to OpenHands. The agent-server's ``Settings.update``\n // applies a fresh ``{'agent_kind': ...}`` base whenever the kind\n // flips, so any ``acp_*`` fields would be discarded before\n // validation. Send the kind alone.\n return { agent_kind: \"openhands\" };\n }\n\n const isCustom = providerKey === ACP_CUSTOM_PRESET_KEY;\n const provider = isCustom ? undefined : getAcpProvider(providerKey);\n if (!isCustom && !provider && !options.allowUnknownServer) {\n return null;\n }\n\n const model =\n options.model === undefined\n ? (provider?.default_model ?? null)\n : options.model;\n\n // ``acp_args: []`` resets any API-set ``acp_args`` that would\n // otherwise survive and concatenate to ``acp_command`` at spawn time\n // (the agent-server merges the two before exec). Callers building the\n // payload from a textarea that already shows the merged command\n // (Settings → Agent) round-trip correctly — the merged tokens land in\n // ``acp_command`` here, so no args are lost.\n return {\n agent_kind: \"acp\",\n acp_server: providerKey,\n acp_command: options.command ?? [],\n acp_args: [],\n acp_model: model ?? null,\n };\n}\n"],"mappings":";;;AAqBA,IAAa,IAA2B,IAAI,IAAI,CAC9C,WACA,wBACD,CAAC;AAYF,SAAS,EAAa,GAA+B;AACnD,KAAI,OAAO,KAAU,SAAU,QAAO;CACtC,IAAM,IAAU,EAAM,MAAM;AAI5B,QAHI,CAAC,KACD,EAAyB,IAAI,EAAQ,aAAa,CAAC,IACnD,MAAA,gBAAyC,OACtC;;AAgBT,SAAgB,EAAyB,GAMvB;AAChB,MAAK,IAAM,KAAa;EACtB,EAAO;EACP,EAAO;EACP,EAAO;EACP,EAAO;EACR,EAAE;EACD,IAAM,IAAQ,EAAa,EAAU;AACrC,MAAI,EAAO,QAAO;;AAEpB,QAAO,EAAO,mBAAmB;;AAiEnC,IAAM,IAGF;CACF,eAAe;EACb,MAAM;EACN,iBAAiB,EAAQ;EAC1B;CACD,OAAO;EACL,MAAM;EACN,iBAAiB,EAAQ;EAC1B;CACD,cAAc;EACZ,MAAM;EACN,iBAAiB,EAAQ;EAC1B;CACF,EAMY,IAAqC,OAAO,QACvD,EACD,CAAC,KAAK,CAAC,GAAK,OAAQ;CACnB,IAAM,IAAO,EAAqB,EAAI;AACtC,QAAO;EACL;EACA,cAAc,GAAM,gBAAgB;EACpC,iBAAiB,IAAO,CAAC,GAAG,EAAK,gBAAgB,GAAG,EAAE;EACtD,kBAAkB,GAAM,kBAAkB,KAAK,OAAW;GACxD,IAAI,EAAM;GACV,OAAO,EAAM;GACd,EAAE;EACH,eAAe,GAAM,iBAAiB,KAAA;EACtC,iBAAiB,EAAG;EACpB,MAAM,EAAG;EACV;EACD;AAyEF,SAAgB,EACd,GAC+B;AAC1B,OACL,QAAO,EAAc,MAAM,MAAa,EAAS,QAAQ,EAAI;;AAmB/D,SAAgB,EACd,GACe;CACf,IAAM,IAAQ,EAAe,EAAI;AACjC,QAAO,IAAQ,EAAM,eAAe;;AAYtC,SAAgB,EACd,GACiB;AACjB,QAAO,EAAe,EAAI,EAAE,QAAA;;AAa9B,SAAgB,EACd,GACA,GACe;AAIf,QAHK,IACY,EAAe,EAClB,EAAU,kBAAkB,MAAM,MAAM,EAAE,OAAO,EAAQ,EACzD,SAAS,IAHF"}
@@ -1,2 +1,2 @@
1
- const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../api/backend-registry/default-backend.cjs`),n=require(`../api/backend-registry/active-store.cjs`),r=require(`../api/backend-registry/health-store.cjs`);let i=require(`react`);i=e.__toESM(i,1);let a=require(`react/jsx-runtime`);var o=i.default.createContext(null);function s(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`backend-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function c({children:e}){let t=i.default.useSyncExternalStore(n.subscribeActiveBackend,n.getSnapshot,n.getSnapshot),c=i.default.useCallback((e,t)=>{let r=n.getActiveSelection()?.backendId??null,i=n.getActiveSelection()?.orgId??null,a=t??null;e===r&&a===i||n.setActiveSelection({backendId:e,orgId:a})},[]),l=i.default.useCallback(e=>{let t={...e,id:s()};return n.setRegisteredBackends([...n.getRegisteredBackends(),t]),n.setActiveSelection({backendId:t.id}),t},[]),u=i.default.useCallback((e,t)=>{let i=n.getRegisteredBackends().find(t=>t.id===e);n.setRegisteredBackends(n.getRegisteredBackends().map(n=>n.id===e?{...n,...t}:n));let a=t.host!==void 0&&i!==void 0&&t.host!==i.host,o=t.apiKey!==void 0&&i!==void 0&&t.apiKey!==i.apiKey;(a||o)&&r.resetBackendHealth(e)},[]),d=i.default.useCallback(e=>{n.setRegisteredBackends(n.getRegisteredBackends().filter(t=>t.id!==e)),r.dropBackendHealth(e)},[]),f=i.default.useMemo(()=>({backends:t.backends,active:t.active,setActive:c,addBackend:l,updateBackend:u,removeBackend:d}),[t,c,l,u,d]);return(0,a.jsx)(o.Provider,{value:f,children:e})}function l(){let e=i.default.useContext(o);if(!e)throw Error(`useActiveBackendContext must be used inside <ActiveBackendProvider>`);return e}function u(){let e=i.default.useContext(o);return e?e.active:{backend:t.makeDefaultLocalBackend(),orgId:null}}exports.ActiveBackendProvider=c,exports.useActiveBackend=u,exports.useActiveBackendContext=l;
1
+ const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../api/backend-registry/default-backend.cjs`),n=require(`../api/backend-registry/active-store.cjs`),r=require(`../api/backend-registry/health-store.cjs`);let i=require(`react`);i=e.__toESM(i,1);let a=require(`react/jsx-runtime`);var o=i.default.createContext(null);function s(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`backend-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function c({children:e}){let t=i.default.useSyncExternalStore(n.subscribeActiveBackend,n.getSnapshot,n.getSnapshot),c=i.default.useCallback((e,t)=>{let r=n.getActiveSelection()?.backendId??null,i=n.getActiveSelection()?.orgId??null,a=t??null;e===r&&a===i||n.setActiveSelection({backendId:e,orgId:a})},[]),l=i.default.useCallback(e=>{let t={...e,id:s()};return n.setRegisteredBackends([...n.getRegisteredBackends(),t]),n.setActiveSelection({backendId:t.id}),t},[]),u=i.default.useCallback((e,t)=>{let i=n.getRegisteredBackends().find(t=>t.id===e);n.setRegisteredBackends(n.getRegisteredBackends().map(n=>n.id===e?{...n,...t}:n));let a=t.host!==void 0&&i!==void 0&&t.host!==i.host,o=t.apiKey!==void 0&&i!==void 0&&t.apiKey!==i.apiKey;(a||o)&&r.resetBackendHealth(e)},[]),d=i.default.useCallback(e=>{n.setRegisteredBackends(n.getRegisteredBackends().filter(t=>t.id!==e)),r.dropBackendHealth(e)},[]),f=i.default.useMemo(()=>({backends:t.backends,active:t.active,setActive:c,addBackend:l,updateBackend:u,removeBackend:d}),[t,c,l,u,d]);return(0,a.jsx)(o.Provider,{value:f,children:e})}function l(){let e=i.default.useContext(o);if(!e)throw Error(`useActiveBackendContext must be used inside <ActiveBackendProvider>`);return e}function u(){let e=i.default.useContext(o);return e?e.active:{backend:t.makeDefaultLocalBackend()??n.NO_BACKEND,orgId:null}}exports.ActiveBackendProvider=c,exports.useActiveBackend=u,exports.useActiveBackendContext=l;
2
2
  //# sourceMappingURL=active-backend-context.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"active-backend-context.cjs","names":[],"sources":["../../src/contexts/active-backend-context.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n getActiveSelection,\n getRegisteredBackends,\n getSnapshot,\n setActiveSelection,\n setRegisteredBackends,\n subscribeActiveBackend,\n} from \"#/api/backend-registry/active-store\";\nimport { makeDefaultLocalBackend } from \"#/api/backend-registry/default-backend\";\nimport {\n dropBackendHealth,\n resetBackendHealth,\n} from \"#/api/backend-registry/health-store\";\nimport {\n type Backend,\n type BackendSelection,\n type ResolvedActiveBackend,\n} from \"#/api/backend-registry/types\";\n\ninterface ActiveBackendContextValue {\n backends: Backend[];\n active: ResolvedActiveBackend;\n setActive: (backendId: string, orgId?: string | null) => void;\n addBackend: (backend: Omit<Backend, \"id\">) => Backend;\n updateBackend: (id: string, patch: Partial<Omit<Backend, \"id\">>) => void;\n removeBackend: (id: string) => void;\n}\n\nconst ActiveBackendContext =\n React.createContext<ActiveBackendContextValue | null>(null);\n\nfunction generateId(): string {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n return `backend-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function ActiveBackendProvider({\n children,\n}: {\n children: React.ReactNode;\n}) {\n const snapshot = React.useSyncExternalStore(\n subscribeActiveBackend,\n getSnapshot,\n getSnapshot,\n );\n\n const setActive = React.useCallback(\n (backendId: string, orgId?: string | null) => {\n const prevBackendId = getActiveSelection()?.backendId ?? null;\n const prevOrgId = getActiveSelection()?.orgId ?? null;\n const nextOrgId = orgId ?? null;\n\n if (backendId === prevBackendId && nextOrgId === prevOrgId) return;\n\n const next: BackendSelection = { backendId, orgId: nextOrgId };\n setActiveSelection(next);\n\n // No blanket `invalidateQueries()` here. Long-lived queries\n // (`useSettings`, `usePaginatedConversations`,\n // `useGitRepositories`, `useAppInstallations`,\n // `useCloudCurrentUserId`, `useGitUser`, …) include the active\n // backend's `id` and `orgId` in their query keys, so React Query\n // treats a backend/org switch as a brand-new query and fetches\n // automatically — once, with no duplicate waves.\n },\n [],\n );\n\n // @spec BM-001 — Auto-switch to newly connected backend\n const addBackend = React.useCallback(\n (backend: Omit<Backend, \"id\">): Backend => {\n const next: Backend = { ...backend, id: generateId() };\n const list = [...getRegisteredBackends(), next];\n setRegisteredBackends(list);\n setActiveSelection({ backendId: next.id });\n return next;\n },\n [],\n );\n\n const updateBackend = React.useCallback(\n (id: string, patch: Partial<Omit<Backend, \"id\">>) => {\n const prev = getRegisteredBackends().find((b) => b.id === id);\n const list = getRegisteredBackends().map((b) =>\n b.id === id ? { ...b, ...patch } : b,\n );\n setRegisteredBackends(list);\n\n // Re-arm health polling when the user edits the fields that\n // actually drive the probe. Cosmetic edits (name) shouldn't\n // re-enable a backend that was disabled for being unreachable.\n const hostChanged =\n patch.host !== undefined &&\n prev !== undefined &&\n patch.host !== prev.host;\n const apiKeyChanged =\n patch.apiKey !== undefined &&\n prev !== undefined &&\n patch.apiKey !== prev.apiKey;\n if (hostChanged || apiKeyChanged) {\n resetBackendHealth(id);\n }\n },\n [],\n );\n\n const removeBackend = React.useCallback((id: string) => {\n const list = getRegisteredBackends().filter((b) => b.id !== id);\n setRegisteredBackends(list);\n dropBackendHealth(id);\n // If the active selection pointed at this backend, the active\n // store falls back to the first remaining local backend (or the\n // env-derived default if no locals exist); consumer hooks re-key\n // by the new active backend identity and refetch automatically.\n }, []);\n\n const value = React.useMemo<ActiveBackendContextValue>(\n () => ({\n backends: snapshot.backends,\n active: snapshot.active,\n setActive,\n addBackend,\n updateBackend,\n removeBackend,\n }),\n [snapshot, setActive, addBackend, updateBackend, removeBackend],\n );\n\n return (\n <ActiveBackendContext.Provider value={value}>\n {children}\n </ActiveBackendContext.Provider>\n );\n}\n\nexport function useActiveBackendContext(): ActiveBackendContextValue {\n const ctx = React.useContext(ActiveBackendContext);\n if (!ctx) {\n throw new Error(\n \"useActiveBackendContext must be used inside <ActiveBackendProvider>\",\n );\n }\n return ctx;\n}\n\n/**\n * Read the resolved active backend.\n *\n * Falls back to a synthesized env-derived local backend when called\n * outside an `<ActiveBackendProvider>` (e.g. from a unit test that\n * mounts a narrow component without the full provider stack). That\n * synthesized backend is identical to the seed used on first install.\n *\n * Components that need to mutate state (`setActive`, `addBackend`,\n * etc.) must use `useActiveBackendContext()` directly — that throws if\n * the provider is missing, since mutation requires the live store.\n */\nexport function useActiveBackend(): ResolvedActiveBackend {\n const ctx = React.useContext(ActiveBackendContext);\n if (ctx) return ctx.active;\n return { backend: makeDefaultLocalBackend(), orgId: null };\n}\n"],"mappings":"qSA6BA,IAAM,EACJ,EAAA,QAAM,cAAgD,KAAK,CAE7D,SAAS,GAAqB,CAO5B,OALE,OAAO,OAAW,KAClB,OAAO,OAAO,YAAe,WAEtB,OAAO,YAAY,CAErB,WAAW,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAG,GAAG,GAGzE,SAAgB,EAAsB,CACpC,YAGC,CACD,IAAM,EAAW,EAAA,QAAM,qBACrB,EAAA,uBACA,EAAA,YACA,EAAA,YACD,CAEK,EAAY,EAAA,QAAM,aACrB,EAAmB,IAA0B,CAC5C,IAAM,EAAgB,EAAA,oBAAoB,EAAE,WAAa,KACnD,EAAY,EAAA,oBAAoB,EAAE,OAAS,KAC3C,EAAY,GAAS,KAEvB,IAAc,GAAiB,IAAc,GAGjD,EAAA,mBAAmB,CADc,YAAW,MAAO,EAChC,CAAK,EAU1B,EAAE,CACH,CAGK,EAAa,EAAA,QAAM,YACtB,GAA0C,CACzC,IAAM,EAAgB,CAAE,GAAG,EAAS,GAAI,GAAY,CAAE,CAItD,OAFA,EAAA,sBAAsB,CADR,GAAG,EAAA,uBAAuB,CAAE,EACpB,CAAK,CAC3B,EAAA,mBAAmB,CAAE,UAAW,EAAK,GAAI,CAAC,CACnC,GAET,EAAE,CACH,CAEK,EAAgB,EAAA,QAAM,aACzB,EAAY,IAAwC,CACnD,IAAM,EAAO,EAAA,uBAAuB,CAAC,KAAM,GAAM,EAAE,KAAO,EAAG,CAI7D,EAAA,sBAHa,EAAA,uBAAuB,CAAC,IAAK,GACxC,EAAE,KAAO,EAAK,CAAE,GAAG,EAAG,GAAG,EAAO,CAAG,EAEf,CAAK,CAK3B,IAAM,EACJ,EAAM,OAAS,IAAA,IACf,IAAS,IAAA,IACT,EAAM,OAAS,EAAK,KAChB,EACJ,EAAM,SAAW,IAAA,IACjB,IAAS,IAAA,IACT,EAAM,SAAW,EAAK,QACpB,GAAe,IACjB,EAAA,mBAAmB,EAAG,EAG1B,EAAE,CACH,CAEK,EAAgB,EAAA,QAAM,YAAa,GAAe,CAEtD,EAAA,sBADa,EAAA,uBAAuB,CAAC,OAAQ,GAAM,EAAE,KAAO,EACtC,CAAK,CAC3B,EAAA,kBAAkB,EAAG,EAKpB,EAAE,CAAC,CAEA,EAAQ,EAAA,QAAM,aACX,CACL,SAAU,EAAS,SACnB,OAAQ,EAAS,OACjB,YACA,aACA,gBACA,gBACD,EACD,CAAC,EAAU,EAAW,EAAY,EAAe,EAAc,CAChE,CAED,OACE,EAAA,EAAA,KAAC,EAAqB,SAAtB,CAAsC,QACnC,WAC6B,CAAA,CAIpC,SAAgB,GAAqD,CACnE,IAAM,EAAM,EAAA,QAAM,WAAW,EAAqB,CAClD,GAAI,CAAC,EACH,MAAU,MACR,sEACD,CAEH,OAAO,EAeT,SAAgB,GAA0C,CACxD,IAAM,EAAM,EAAA,QAAM,WAAW,EAAqB,CAElD,OADI,EAAY,EAAI,OACb,CAAE,QAAS,EAAA,yBAAyB,CAAE,MAAO,KAAM"}
1
+ {"version":3,"file":"active-backend-context.cjs","names":[],"sources":["../../src/contexts/active-backend-context.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n getActiveSelection,\n getRegisteredBackends,\n getSnapshot,\n NO_BACKEND,\n setActiveSelection,\n setRegisteredBackends,\n subscribeActiveBackend,\n} from \"#/api/backend-registry/active-store\";\nimport { makeDefaultLocalBackend } from \"#/api/backend-registry/default-backend\";\nimport {\n dropBackendHealth,\n resetBackendHealth,\n} from \"#/api/backend-registry/health-store\";\nimport {\n type Backend,\n type BackendSelection,\n type ResolvedActiveBackend,\n} from \"#/api/backend-registry/types\";\n\ninterface ActiveBackendContextValue {\n backends: Backend[];\n active: ResolvedActiveBackend;\n setActive: (backendId: string, orgId?: string | null) => void;\n addBackend: (backend: Omit<Backend, \"id\">) => Backend;\n updateBackend: (id: string, patch: Partial<Omit<Backend, \"id\">>) => void;\n removeBackend: (id: string) => void;\n}\n\nconst ActiveBackendContext =\n React.createContext<ActiveBackendContextValue | null>(null);\n\nfunction generateId(): string {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n return `backend-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function ActiveBackendProvider({\n children,\n}: {\n children: React.ReactNode;\n}) {\n const snapshot = React.useSyncExternalStore(\n subscribeActiveBackend,\n getSnapshot,\n getSnapshot,\n );\n\n const setActive = React.useCallback(\n (backendId: string, orgId?: string | null) => {\n const prevBackendId = getActiveSelection()?.backendId ?? null;\n const prevOrgId = getActiveSelection()?.orgId ?? null;\n const nextOrgId = orgId ?? null;\n\n if (backendId === prevBackendId && nextOrgId === prevOrgId) return;\n\n const next: BackendSelection = { backendId, orgId: nextOrgId };\n setActiveSelection(next);\n\n // No blanket `invalidateQueries()` here. Long-lived queries\n // (`useSettings`, `usePaginatedConversations`,\n // `useGitRepositories`, `useAppInstallations`,\n // `useCloudCurrentUserId`, `useGitUser`, …) include the active\n // backend's `id` and `orgId` in their query keys, so React Query\n // treats a backend/org switch as a brand-new query and fetches\n // automatically — once, with no duplicate waves.\n },\n [],\n );\n\n // @spec BM-001 — Auto-switch to newly connected backend\n const addBackend = React.useCallback(\n (backend: Omit<Backend, \"id\">): Backend => {\n const next: Backend = { ...backend, id: generateId() };\n const list = [...getRegisteredBackends(), next];\n setRegisteredBackends(list);\n setActiveSelection({ backendId: next.id });\n return next;\n },\n [],\n );\n\n const updateBackend = React.useCallback(\n (id: string, patch: Partial<Omit<Backend, \"id\">>) => {\n const prev = getRegisteredBackends().find((b) => b.id === id);\n const list = getRegisteredBackends().map((b) =>\n b.id === id ? { ...b, ...patch } : b,\n );\n setRegisteredBackends(list);\n\n // Re-arm health polling when the user edits the fields that\n // actually drive the probe. Cosmetic edits (name) shouldn't\n // re-enable a backend that was disabled for being unreachable.\n const hostChanged =\n patch.host !== undefined &&\n prev !== undefined &&\n patch.host !== prev.host;\n const apiKeyChanged =\n patch.apiKey !== undefined &&\n prev !== undefined &&\n patch.apiKey !== prev.apiKey;\n if (hostChanged || apiKeyChanged) {\n resetBackendHealth(id);\n }\n },\n [],\n );\n\n const removeBackend = React.useCallback((id: string) => {\n const list = getRegisteredBackends().filter((b) => b.id !== id);\n setRegisteredBackends(list);\n dropBackendHealth(id);\n // If the active selection pointed at this backend, the active\n // store falls back to the first remaining local backend (or the\n // env-derived default if no locals exist); consumer hooks re-key\n // by the new active backend identity and refetch automatically.\n }, []);\n\n const value = React.useMemo<ActiveBackendContextValue>(\n () => ({\n backends: snapshot.backends,\n active: snapshot.active,\n setActive,\n addBackend,\n updateBackend,\n removeBackend,\n }),\n [snapshot, setActive, addBackend, updateBackend, removeBackend],\n );\n\n return (\n <ActiveBackendContext.Provider value={value}>\n {children}\n </ActiveBackendContext.Provider>\n );\n}\n\nexport function useActiveBackendContext(): ActiveBackendContextValue {\n const ctx = React.useContext(ActiveBackendContext);\n if (!ctx) {\n throw new Error(\n \"useActiveBackendContext must be used inside <ActiveBackendProvider>\",\n );\n }\n return ctx;\n}\n\n/**\n * Read the resolved active backend.\n *\n * Falls back to a synthesized env-derived local backend when called\n * outside an `<ActiveBackendProvider>` (e.g. from a unit test that\n * mounts a narrow component without the full provider stack). That\n * synthesized backend is identical to the seed used on first install.\n *\n * Components that need to mutate state (`setActive`, `addBackend`,\n * etc.) must use `useActiveBackendContext()` directly — that throws if\n * the provider is missing, since mutation requires the live store.\n */\nexport function useActiveBackend(): ResolvedActiveBackend {\n const ctx = React.useContext(ActiveBackendContext);\n if (ctx) return ctx.active;\n return { backend: makeDefaultLocalBackend() ?? NO_BACKEND, orgId: null };\n}\n"],"mappings":"qSA8BA,IAAM,EACJ,EAAA,QAAM,cAAgD,KAAK,CAE7D,SAAS,GAAqB,CAO5B,OALE,OAAO,OAAW,KAClB,OAAO,OAAO,YAAe,WAEtB,OAAO,YAAY,CAErB,WAAW,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAG,GAAG,GAGzE,SAAgB,EAAsB,CACpC,YAGC,CACD,IAAM,EAAW,EAAA,QAAM,qBACrB,EAAA,uBACA,EAAA,YACA,EAAA,YACD,CAEK,EAAY,EAAA,QAAM,aACrB,EAAmB,IAA0B,CAC5C,IAAM,EAAgB,EAAA,oBAAoB,EAAE,WAAa,KACnD,EAAY,EAAA,oBAAoB,EAAE,OAAS,KAC3C,EAAY,GAAS,KAEvB,IAAc,GAAiB,IAAc,GAGjD,EAAA,mBAAmB,CADc,YAAW,MAAO,EAChC,CAAK,EAU1B,EAAE,CACH,CAGK,EAAa,EAAA,QAAM,YACtB,GAA0C,CACzC,IAAM,EAAgB,CAAE,GAAG,EAAS,GAAI,GAAY,CAAE,CAItD,OAFA,EAAA,sBAAsB,CADR,GAAG,EAAA,uBAAuB,CAAE,EACpB,CAAK,CAC3B,EAAA,mBAAmB,CAAE,UAAW,EAAK,GAAI,CAAC,CACnC,GAET,EAAE,CACH,CAEK,EAAgB,EAAA,QAAM,aACzB,EAAY,IAAwC,CACnD,IAAM,EAAO,EAAA,uBAAuB,CAAC,KAAM,GAAM,EAAE,KAAO,EAAG,CAI7D,EAAA,sBAHa,EAAA,uBAAuB,CAAC,IAAK,GACxC,EAAE,KAAO,EAAK,CAAE,GAAG,EAAG,GAAG,EAAO,CAAG,EAEf,CAAK,CAK3B,IAAM,EACJ,EAAM,OAAS,IAAA,IACf,IAAS,IAAA,IACT,EAAM,OAAS,EAAK,KAChB,EACJ,EAAM,SAAW,IAAA,IACjB,IAAS,IAAA,IACT,EAAM,SAAW,EAAK,QACpB,GAAe,IACjB,EAAA,mBAAmB,EAAG,EAG1B,EAAE,CACH,CAEK,EAAgB,EAAA,QAAM,YAAa,GAAe,CAEtD,EAAA,sBADa,EAAA,uBAAuB,CAAC,OAAQ,GAAM,EAAE,KAAO,EACtC,CAAK,CAC3B,EAAA,kBAAkB,EAAG,EAKpB,EAAE,CAAC,CAEA,EAAQ,EAAA,QAAM,aACX,CACL,SAAU,EAAS,SACnB,OAAQ,EAAS,OACjB,YACA,aACA,gBACA,gBACD,EACD,CAAC,EAAU,EAAW,EAAY,EAAe,EAAc,CAChE,CAED,OACE,EAAA,EAAA,KAAC,EAAqB,SAAtB,CAAsC,QACnC,WAC6B,CAAA,CAIpC,SAAgB,GAAqD,CACnE,IAAM,EAAM,EAAA,QAAM,WAAW,EAAqB,CAClD,GAAI,CAAC,EACH,MAAU,MACR,sEACD,CAEH,OAAO,EAeT,SAAgB,GAA0C,CACxD,IAAM,EAAM,EAAA,QAAM,WAAW,EAAqB,CAElD,OADI,EAAY,EAAI,OACb,CAAE,QAAS,EAAA,yBAAyB,EAAI,EAAA,WAAY,MAAO,KAAM"}