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

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-BAX8OU5C.js +1 -0
  7. package/build/assets/{acp-route-guard-B2yoBZ_4.js → acp-route-guard-HPk6TV-L.js} +1 -1
  8. package/build/assets/active-backend-context-BSPE-W72.js +1 -0
  9. package/build/assets/add-backend-modal-mXKmfMI2.js +1 -0
  10. package/build/assets/agent-server-client-options-9agOSarV.js +1 -0
  11. package/build/assets/agent-server-compatibility-B7QStIcH.js +1 -0
  12. package/build/assets/agent-server-conversation-service.api-B9TUYJon.js +5 -0
  13. package/build/assets/{agent-settings-CnGSCmK8.js → agent-settings-g3F623RJ.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-BQCNeNVt.js} +1 -1
  16. package/build/assets/api-key-entry-screen-myuWMqzW.js +1 -0
  17. package/build/assets/{app-settings-Db9ITeJH.js → app-settings-CCcX8ZEH.js} +1 -1
  18. package/build/assets/automation-detail-BDHLHSJd.js +1 -0
  19. package/build/assets/automations-list-CiNtQhq_.js +1 -0
  20. package/build/assets/back-nav-button-7dQJ2k3O.js +1 -0
  21. package/build/assets/backend-form-modal-D3bDMO3C.js +1 -0
  22. package/build/assets/{backend-synced-settings-badge-Dc6c7GT4.js → backend-synced-settings-badge-BkW5evM0.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-DCTulgLO.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-BKhikfYl.js +1 -0
  39. package/build/assets/conversation-DTn8jN8L.js +19 -0
  40. package/build/assets/conversation-panel-DfHR42mG.js +1 -0
  41. package/build/assets/conversation-service.api-B6CkzaKD.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-DShEuLjh.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-DamwL0s0.js +1 -0
  53. package/build/assets/ellipsis-button-Vh5MvRZa.js +1 -0
  54. package/build/assets/entry.client-Cn71WM8q.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-CUEmfvGy.js +1 -0
  58. package/build/assets/{extensions-navigation-BYR8Giqq.js → extensions-navigation-VQ-3umJ7.js} +1 -1
  59. package/build/assets/file-BTY6Gyy9.js +1 -0
  60. package/build/assets/files-tab-C47fQEeL.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-BT0aWH-o.js +27 -0
  64. package/build/assets/git-provider-icon-Pi-Cxpgv.js +1 -0
  65. package/build/assets/globe-Bzj_0oXT.js +1 -0
  66. package/build/assets/home-C3k6sFvB.js +1 -0
  67. package/build/assets/{i18n-CTohRuoO.js → i18n-DET2iOyh.js} +1 -1
  68. package/build/assets/install-server-modal-6fuq-TU6.js +1 -0
  69. package/build/assets/launch-DGghLfGx.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-BqyLKgUN.js} +1 -1
  73. package/build/assets/llm-settings-BKraGtOu.js +1 -0
  74. package/build/assets/llm-settings-DRQTgOF1.js +1 -0
  75. package/build/assets/{loading-spinner-BPtYORNK.js → loading-spinner-5GT9q1xy.js} +1 -1
  76. package/build/assets/manage-backends-modal-CRMwyU0t.js +1 -0
  77. package/build/assets/manage-workspaces-modal-BYmGD1W7.js +1 -0
  78. package/build/assets/manifest-99b06a11.js +1 -0
  79. package/build/assets/{markdown-renderer-DMzf2i4x.js → markdown-renderer-B3IAVfv4.js} +1 -1
  80. package/build/assets/mcp-CfDRAmPn.js +9 -0
  81. package/build/assets/messages-Ba1vaw6t.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-DcztJSxT.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-CGNANEcT.js} +1 -1
  91. package/build/assets/{organization-service.api-DzYTHTYC.js → organization-service.api-BeuMC9QL.js} +1 -1
  92. package/build/assets/{path-utils-C3bQf6lJ.js → path-utils-z12iCrQO.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-Dte6Vzza.js} +1 -1
  95. package/build/assets/{profiles-client-D6IkTJof.js → profiles-client-BrqNmaDV.js} +1 -1
  96. package/build/assets/{providers-Bx6EfrzZ.js → providers-eUyo6pgr.js} +1 -1
  97. package/build/assets/proxy-BqDMnUY-.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-D5ADbXao.js} +3 -3
  100. package/build/assets/{root-dNntxffj.js → root-BmhaEJJ8.js} +2 -2
  101. package/build/assets/root-Z2VHU4R3.css +1 -0
  102. package/build/assets/root-layout-CNggm0d8.js +2 -0
  103. package/build/assets/{sdk-section-page-DOIKvwSL.js → sdk-section-page-CRCRY3PG.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-B9AFn9OE.js +1 -0
  107. package/build/assets/secrets-settings-0UrKMS60.js +1 -0
  108. package/build/assets/{server-client-DyAQ3NZ_.js → server-client-DYv_GHPl.js} +1 -1
  109. package/build/assets/{settings-BYkVX7vW.js → settings-6t6LGW04.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-CR6Ou73o.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-T_Yk1Zfo.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-DwtyDeGh.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-BzccsVej.js} +1 -1
  121. package/build/assets/sidebar-mobile-menu-toggle-DGlRg6jG.js +1 -0
  122. package/build/assets/{sidebar-nav-link-BGjiJq-4.js → sidebar-nav-link-dgVb8Fpy.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-DctDrZ8Y.js} +1 -1
  127. package/build/assets/skills-settings-rvxImDj_.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-RmuaSdhJ.js → terminal-CPYWdo4j.js} +1 -1
  132. package/build/assets/{terminal-DgQk1Ay6.js → terminal-KldRPIRT.js} +2 -2
  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-sPgfSkql.js} +1 -1
  140. package/build/assets/use-agent-settings-schema-B66kGIi_.js +1 -0
  141. package/build/assets/{use-agent-state-Bkrd1FZq.js → use-agent-state-Dp3pD1h3.js} +1 -1
  142. package/build/assets/{use-cloud-current-user-id-CvkXFnTT.js → use-cloud-current-user-id-ClKFPjFz.js} +1 -1
  143. package/build/assets/{use-config-Co1O8-Ey.js → use-config-C9pvb0Sm.js} +1 -1
  144. package/build/assets/{use-create-conversation-CEgXpkfH.js → use-create-conversation-B-lwTnfE.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-oyC7PFRz.js} +1 -1
  147. package/build/assets/{use-handle-plan-click-Ckkm5eIY.js → use-handle-plan-click-DP6Rs-YP.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-Bh5JqZUZ.js +1 -0
  152. package/build/assets/use-runtime-is-ready-BakOUVU-.js +1 -0
  153. package/build/assets/{use-save-settings-VUrj_QNG.js → use-save-settings-uXXkqvD7.js} +1 -1
  154. package/build/assets/use-settings-DeO7nvpM.js +1 -0
  155. package/build/assets/{use-settings-nav-items-1ZvovKSr.js → use-settings-nav-items-BGMFn25b.js} +1 -1
  156. package/build/assets/{use-skills-DAMLFjKU.js → use-skills-DWIK3l3a.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-DXPtB317.js} +1 -1
  159. package/build/assets/use-user-conversation-DJen4YIP.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-D8soyAAx.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-C_zHuDx9.js} +1 -1
  183. package/build/assets/{vscode-tab-DjNArCgY.js → vscode-tab-DH9x7xXS.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 +15 -48
  220. package/dist/api/agent-server-config.js +25 -69
  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 +65 -6
  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 +1 @@
1
- {"version":3,"file":"local-new-conversation-menu.js","names":[],"sources":["../../../../src/components/features/conversation-panel/local-new-conversation-menu.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\nimport { useCreateConversation } from \"#/hooks/mutation/use-create-conversation\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useIsCreatingConversation } from \"#/hooks/use-is-creating-conversation\";\nimport {\n useAddWorkspaces,\n useAddWorkspaceParents,\n useRemoveWorkspace,\n useRemoveWorkspaceParent,\n} from \"#/hooks/mutation/use-local-workspaces-mutations\";\nimport { useLocalWorkspaces } from \"#/hooks/query/use-local-workspaces\";\nimport { useResolvedWorkspaces } from \"#/hooks/query/use-resolved-workspaces\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { getWorkspacesUnsupportedMessage } from \"#/utils/workspaces-compatibility\";\nimport RepoIcon from \"#/icons/repo.svg?react\";\n\nimport { FolderBrowserModal } from \"#/components/features/home/workspace-dropdown/folder-browser-modal\";\nimport { ManageWorkspacesModal } from \"#/components/features/home/workspace-dropdown/manage-workspaces-modal\";\n\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { Divider } from \"#/ui/divider\";\nimport { NEW_CONVERSATION_DROPDOWN_SURFACE } from \"./new-conversation-dropdown-styles\";\nimport { usePopoverFixedPlacement } from \"#/hooks/use-popover-fixed-placement\";\n\nexport type LocalNewConversationMenuTriggerProps = {\n onClick: () => void;\n \"aria-expanded\": boolean;\n \"aria-haspopup\": \"menu\";\n disabled?: boolean;\n};\n\nexport interface LocalNewConversationMenuProps {\n trigger: (props: LocalNewConversationMenuTriggerProps) => React.ReactNode;\n /** Root wrapper class (e.g. `relative` + alignment in header row) */\n className?: string;\n /** Panel positioning / dimensions when using absolute placement (sidebar) */\n popoverClassName: string;\n /** Optional test id for the popover surface */\n popoverTestId?: string;\n /**\n * Use `position: fixed` from the trigger rect so the menu is not clipped by\n * sidebar overflow (conversation panel header).\n */\n useFixedPlacement?: boolean;\n}\n\n/**\n * Workspace/repo picker + launch flow for local agent-server backends.\n * Shared by the sidebar \"+ New conversation\" control and the conversation\n * panel \"new thread folder\" control.\n */\nexport function LocalNewConversationMenu({\n trigger,\n className,\n popoverClassName,\n popoverTestId = \"new-conversation-popover\",\n useFixedPlacement = false,\n}: LocalNewConversationMenuProps) {\n const { t } = useTranslation(\"openhands\");\n const { navigate } = useNavigation();\n\n const [open, setOpen] = React.useState(false);\n const popoverRef = React.useRef<HTMLDivElement>(null);\n const triggerWrapRef = React.useRef<HTMLSpanElement>(null);\n const fixedBox = usePopoverFixedPlacement(triggerWrapRef, {\n open,\n enabled: useFixedPlacement,\n });\n\n const { data: workspacesData, error: workspacesError } = useLocalWorkspaces();\n const workspaceParents = workspacesData?.workspaceParents ?? [];\n const { mutate: addWorkspaces } = useAddWorkspaces();\n const { mutate: removeWorkspace } = useRemoveWorkspace();\n const { mutate: addWorkspaceParents } = useAddWorkspaceParents();\n const { mutate: removeWorkspaceParent } = useRemoveWorkspaceParent();\n const { workspaces } = useResolvedWorkspaces();\n const workspacesUnsupportedMessage = getWorkspacesUnsupportedMessage(\n workspacesError,\n t,\n );\n const [browserOpen, setBrowserOpen] = React.useState(false);\n const [manageOpen, setManageOpen] = React.useState(false);\n\n const { mutate: createConversation, isPending } = useCreateConversation();\n const isCreatingElsewhere = useIsCreatingConversation();\n const isCreating = isPending || isCreatingElsewhere;\n\n React.useEffect(() => {\n if (!open || browserOpen || manageOpen) return undefined;\n const onDown = (e: MouseEvent) => {\n if (\n popoverRef.current &&\n !popoverRef.current.contains(e.target as Node)\n ) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", onDown);\n return () => document.removeEventListener(\"mousedown\", onDown);\n }, [open, browserOpen, manageOpen]);\n\n React.useEffect(() => {\n if (!open || browserOpen || manageOpen) return undefined;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setOpen(false);\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [open, browserOpen, manageOpen]);\n\n const launch = (workingDir?: string) => {\n if (isCreating) return;\n createConversation(\n { workingDir },\n {\n onSuccess: (data) => {\n setOpen(false);\n navigate(`/conversations/${data.conversation_id}`);\n },\n },\n );\n };\n\n const itemClass = cn(\n \"flex w-full cursor-pointer items-center gap-2 rounded px-2 py-2 text-left text-sm text-white\",\n \"font-normal transition-colors hover:bg-[var(--oh-interactive-hover)]\",\n \"disabled:cursor-not-allowed disabled:opacity-60\",\n );\n\n const keepPopoverOpenOnMouseDown = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n },\n [],\n );\n\n const toggleOpen = React.useCallback(() => {\n setOpen((o) => !o);\n }, []);\n\n const showPopover = open && (!useFixedPlacement || fixedBox !== null);\n const workspaceActionsDisabled = Boolean(workspacesUnsupportedMessage);\n\n const fixedStyle: React.CSSProperties | undefined =\n useFixedPlacement && fixedBox\n ? {\n position: \"fixed\",\n top: fixedBox.top,\n left: fixedBox.left,\n width: fixedBox.width,\n }\n : undefined;\n\n const addWorkspacesButton = (\n <button\n type=\"button\"\n data-testid=\"add-workspaces-button\"\n disabled={workspaceActionsDisabled}\n onMouseDown={keepPopoverOpenOnMouseDown}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (workspaceActionsDisabled) return;\n setBrowserOpen(true);\n }}\n className={itemClass}\n >\n {t(I18nKey.HOME$ADD_WORKSPACES)}\n </button>\n );\n\n const addWorkspacesControl = workspacesUnsupportedMessage ? (\n <StyledTooltip content={workspacesUnsupportedMessage} placement=\"top\">\n <span className=\"block\">{addWorkspacesButton}</span>\n </StyledTooltip>\n ) : (\n addWorkspacesButton\n );\n\n return (\n <div\n className={cn(!useFixedPlacement && \"relative\", className)}\n ref={popoverRef}\n >\n <span ref={triggerWrapRef} className=\"inline-flex\">\n {trigger({\n onClick: toggleOpen,\n \"aria-expanded\": open,\n \"aria-haspopup\": \"menu\",\n disabled: isCreating,\n })}\n </span>\n\n {showPopover && (\n <div\n data-testid={popoverTestId}\n className={cn(\n NEW_CONVERSATION_DROPDOWN_SURFACE,\n !useFixedPlacement &&\n cn(\"absolute top-full mt-0\", popoverClassName),\n )}\n style={fixedStyle}\n >\n <ul className=\"flex max-h-[40vh] flex-col overflow-y-auto sm:max-h-[280px]\">\n <li>\n <button\n type=\"button\"\n disabled={isCreating}\n data-testid=\"launch-no-workspace\"\n onClick={() => launch()}\n className={itemClass}\n >\n <span className=\"text-[var(--oh-muted)]\">\n {t(I18nKey.HOME$NO_WORKSPACE_OPTION)}\n </span>\n </button>\n </li>\n {workspaces.map((w) => (\n <li key={w.id}>\n <button\n type=\"button\"\n disabled={isCreating}\n data-testid=\"launch-workspace\"\n data-workspace-path={w.path}\n onClick={() => launch(w.path)}\n className={itemClass}\n >\n <RepoIcon width={14} height={14} className=\"shrink-0\" />\n <span className=\"truncate\">{w.name}</span>\n </button>\n </li>\n ))}\n </ul>\n\n <div\n className=\"flex flex-col\"\n data-testid=\"new-conversation-menu-footer\"\n >\n <Divider\n inset=\"menu\"\n testId=\"new-conversation-menu-footer-divider\"\n />\n {addWorkspacesControl}\n {(workspaces.length > 0 || workspaceParents.length > 0) && (\n <button\n type=\"button\"\n data-testid=\"manage-workspaces-button\"\n onMouseDown={keepPopoverOpenOnMouseDown}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setManageOpen(true);\n }}\n className={itemClass}\n >\n {t(I18nKey.HOME$MANAGE_WORKSPACES)}\n </button>\n )}\n </div>\n </div>\n )}\n\n <FolderBrowserModal\n isOpen={browserOpen}\n onClose={() => setBrowserOpen(false)}\n onAdd={(items) => addWorkspaces(items)}\n onAddParent={(items) => addWorkspaceParents(items)}\n />\n\n <ManageWorkspacesModal\n isOpen={manageOpen}\n workspaces={workspaces}\n workspaceParents={workspaceParents}\n onClose={() => setManageOpen(false)}\n onRemove={(path) => removeWorkspace(path)}\n onRemoveParent={(path) => removeWorkspaceParent(path)}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,EAAyB,EACvC,YACA,cACA,qBACA,mBAAgB,4BAChB,uBAAoB,MACY;CAChC,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,gBAAa,GAAe,EAE9B,CAAC,GAAM,KAAW,EAAM,SAAS,GAAM,EACvC,IAAa,EAAM,OAAuB,KAAK,EAC/C,IAAiB,EAAM,OAAwB,KAAK,EACpD,IAAW,EAAyB,GAAgB;EACxD;EACA,SAAS;EACV,CAAC,EAEI,EAAE,MAAM,GAAgB,OAAO,MAAoB,GAAoB,EACvE,IAAmB,GAAgB,oBAAoB,EAAE,EACzD,EAAE,QAAQ,MAAkB,GAAkB,EAC9C,EAAE,QAAQ,MAAoB,GAAoB,EAClD,EAAE,QAAQ,MAAwB,IAAwB,EAC1D,EAAE,QAAQ,MAA0B,GAA0B,EAC9D,EAAE,kBAAe,GAAuB,EACxC,IAA+B,EACnC,GACA,EACD,EACK,CAAC,GAAa,KAAkB,EAAM,SAAS,GAAM,EACrD,CAAC,GAAY,KAAiB,EAAM,SAAS,GAAM,EAEnD,EAAE,QAAQ,GAAoB,iBAAc,IAAuB,EACnE,IAAsB,GAA2B,EACjD,IAAa,KAAa;AAgBhC,CAdA,EAAM,gBAAgB;AACpB,MAAI,CAAC,KAAQ,KAAe,EAAY;EACxC,IAAM,KAAU,MAAkB;AAChC,GACE,EAAW,WACX,CAAC,EAAW,QAAQ,SAAS,EAAE,OAAe,IAE9C,EAAQ,GAAM;;AAIlB,SADA,SAAS,iBAAiB,aAAa,EAAO,QACjC,SAAS,oBAAoB,aAAa,EAAO;IAC7D;EAAC;EAAM;EAAa;EAAW,CAAC,EAEnC,EAAM,gBAAgB;AACpB,MAAI,CAAC,KAAQ,KAAe,EAAY;EACxC,IAAM,KAAa,MAAyB;AAC1C,GAAI,EAAM,QAAQ,YAChB,EAAQ,GAAM;;AAIlB,SADA,OAAO,iBAAiB,WAAW,EAAU,QAChC,OAAO,oBAAoB,WAAW,EAAU;IAC5D;EAAC;EAAM;EAAa;EAAW,CAAC;CAEnC,IAAM,KAAU,MAAwB;AAClC,OACJ,EACE,EAAE,eAAY,EACd,EACE,YAAY,MAAS;AAEnB,GADA,EAAQ,GAAM,EACd,EAAS,kBAAkB,EAAK,kBAAkB;KAErD,CACF;IAGG,IAAY,EAChB,gGACA,wEACA,kDACD,EAEK,IAA6B,EAAM,aACtC,MAA+C;AAE9C,EADA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB;IAEzB,EAAE,CACH,EAEK,KAAa,EAAM,kBAAkB;AACzC,KAAS,MAAM,CAAC,EAAE;IACjB,EAAE,CAAC,EAEA,KAAc,MAAS,CAAC,KAAqB,MAAa,OAC1D,IAA2B,EAAQ,GAEnC,KACJ,KAAqB,IACjB;EACE,UAAU;EACV,KAAK,EAAS;EACd,MAAM,EAAS;EACf,OAAO,EAAS;EACjB,GACD,KAAA,GAEA,IACJ,kBAAC,UAAD;EACE,MAAK;EACL,eAAY;EACZ,UAAU;EACV,aAAa;EACb,UAAU,MAAU;AAClB,KAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACnB,MACJ,EAAe,GAAK;;EAEtB,WAAW;YAEV,EAAE,EAAQ,oBAAoB;EACxB,CAAA,EAGL,KAAuB,IAC3B,kBAAC,GAAD;EAAe,SAAS;EAA8B,WAAU;YAC9D,kBAAC,QAAD;GAAM,WAAU;aAAS;GAA2B,CAAA;EACtC,CAAA,GAEhB;AAGF,QACE,kBAAC,OAAD;EACE,WAAW,EAAG,CAAC,KAAqB,YAAY,EAAU;EAC1D,KAAK;YAFP;GAIE,kBAAC,QAAD;IAAM,KAAK;IAAgB,WAAU;cAClC,EAAQ;KACP,SAAS;KACT,iBAAiB;KACjB,iBAAiB;KACjB,UAAU;KACX,CAAC;IACG,CAAA;GAEN,MACC,kBAAC,OAAD;IACE,eAAa;IACb,WAAW,EACT,GACA,CAAC,KACC,EAAG,0BAA0B,EAAiB,CACjD;IACD,OAAO;cAPT,CASE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;MACE,MAAK;MACL,UAAU;MACV,eAAY;MACZ,eAAe,GAAQ;MACvB,WAAW;gBAEX,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAE,EAAQ,yBAAyB;OAC/B,CAAA;MACA,CAAA,EACN,CAAA,EACJ,EAAW,KAAK,MACf,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;MACE,MAAK;MACL,UAAU;MACV,eAAY;MACZ,uBAAqB,EAAE;MACvB,eAAe,EAAO,EAAE,KAAK;MAC7B,WAAW;gBANb,CAQE,kBAAC,GAAD;OAAU,OAAO;OAAI,QAAQ;OAAI,WAAU;OAAa,CAAA,EACxD,kBAAC,QAAD;OAAM,WAAU;iBAAY,EAAE;OAAY,CAAA,CACnC;SACN,EAZI,EAAE,GAYN,CACL,CACC;QAEL,kBAAC,OAAD;KACE,WAAU;KACV,eAAY;eAFd;MAIE,kBAAC,IAAD;OACE,OAAM;OACN,QAAO;OACP,CAAA;MACD;OACC,EAAW,SAAS,KAAK,EAAiB,SAAS,MACnD,kBAAC,UAAD;OACE,MAAK;OACL,eAAY;OACZ,aAAa;OACb,UAAU,MAAU;AAGlB,QAFA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACvB,EAAc,GAAK;;OAErB,WAAW;iBAEV,EAAE,EAAQ,uBAAuB;OAC3B,CAAA;MAEP;OACF;;GAGR,kBAAC,GAAD;IACE,QAAQ;IACR,eAAe,EAAe,GAAM;IACpC,QAAQ,MAAU,EAAc,EAAM;IACtC,cAAc,MAAU,EAAoB,EAAM;IAClD,CAAA;GAEF,kBAAC,GAAD;IACE,QAAQ;IACI;IACM;IAClB,eAAe,EAAc,GAAM;IACnC,WAAW,MAAS,EAAgB,EAAK;IACzC,iBAAiB,MAAS,EAAsB,EAAK;IACrD,CAAA;GACE"}
1
+ {"version":3,"file":"local-new-conversation-menu.js","names":[],"sources":["../../../../src/components/features/conversation-panel/local-new-conversation-menu.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\nimport { useCreateConversation } from \"#/hooks/mutation/use-create-conversation\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useIsCreatingConversation } from \"#/hooks/use-is-creating-conversation\";\nimport {\n useAddWorkspaces,\n useAddWorkspaceParents,\n useRemoveWorkspace,\n useRemoveWorkspaceParent,\n} from \"#/hooks/mutation/use-local-workspaces-mutations\";\nimport { useLocalWorkspaces } from \"#/hooks/query/use-local-workspaces\";\nimport { useResolvedWorkspaces } from \"#/hooks/query/use-resolved-workspaces\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport {\n dropdownMenuRowClassName,\n dropdownMenuListClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\nimport { getWorkspacesUnsupportedMessage } from \"#/utils/workspaces-compatibility\";\nimport RepoIcon from \"#/icons/repo.svg?react\";\n\nimport { FolderBrowserModal } from \"#/components/features/home/workspace-dropdown/folder-browser-modal\";\nimport { ManageWorkspacesModal } from \"#/components/features/home/workspace-dropdown/manage-workspaces-modal\";\n\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { Divider } from \"#/ui/divider\";\nimport { NEW_CONVERSATION_DROPDOWN_SURFACE } from \"./new-conversation-dropdown-styles\";\nimport { usePopoverFixedPlacement } from \"#/hooks/use-popover-fixed-placement\";\n\nexport type LocalNewConversationMenuTriggerProps = {\n onClick: () => void;\n \"aria-expanded\": boolean;\n \"aria-haspopup\": \"menu\";\n disabled?: boolean;\n};\n\nexport interface LocalNewConversationMenuProps {\n trigger: (props: LocalNewConversationMenuTriggerProps) => React.ReactNode;\n /** Root wrapper class (e.g. `relative` + alignment in header row) */\n className?: string;\n /** Panel positioning / dimensions when using absolute placement (sidebar) */\n popoverClassName: string;\n /** Optional test id for the popover surface */\n popoverTestId?: string;\n /**\n * Use `position: fixed` from the trigger rect so the menu is not clipped by\n * sidebar overflow (conversation panel header).\n */\n useFixedPlacement?: boolean;\n}\n\n/**\n * Workspace/repo picker + launch flow for local agent-server backends.\n * Shared by the sidebar \"+ New conversation\" control and the conversation\n * panel \"new thread folder\" control.\n */\nexport function LocalNewConversationMenu({\n trigger,\n className,\n popoverClassName,\n popoverTestId = \"new-conversation-popover\",\n useFixedPlacement = false,\n}: LocalNewConversationMenuProps) {\n const { t } = useTranslation(\"openhands\");\n const { navigate } = useNavigation();\n\n const [open, setOpen] = React.useState(false);\n const popoverRef = React.useRef<HTMLDivElement>(null);\n const triggerWrapRef = React.useRef<HTMLSpanElement>(null);\n const fixedBox = usePopoverFixedPlacement(triggerWrapRef, {\n open,\n enabled: useFixedPlacement,\n });\n\n const { data: workspacesData, error: workspacesError } = useLocalWorkspaces();\n const workspaceParents = workspacesData?.workspaceParents ?? [];\n const { mutate: addWorkspaces } = useAddWorkspaces();\n const { mutate: removeWorkspace } = useRemoveWorkspace();\n const { mutate: addWorkspaceParents } = useAddWorkspaceParents();\n const { mutate: removeWorkspaceParent } = useRemoveWorkspaceParent();\n const { workspaces } = useResolvedWorkspaces();\n const workspacesUnsupportedMessage = getWorkspacesUnsupportedMessage(\n workspacesError,\n t,\n );\n const [browserOpen, setBrowserOpen] = React.useState(false);\n const [manageOpen, setManageOpen] = React.useState(false);\n\n const { mutate: createConversation, isPending } = useCreateConversation();\n const isCreatingElsewhere = useIsCreatingConversation();\n const isCreating = isPending || isCreatingElsewhere;\n\n React.useEffect(() => {\n if (!open || browserOpen || manageOpen) return undefined;\n const onDown = (e: MouseEvent) => {\n if (\n popoverRef.current &&\n !popoverRef.current.contains(e.target as Node)\n ) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", onDown);\n return () => document.removeEventListener(\"mousedown\", onDown);\n }, [open, browserOpen, manageOpen]);\n\n React.useEffect(() => {\n if (!open || browserOpen || manageOpen) return undefined;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setOpen(false);\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [open, browserOpen, manageOpen]);\n\n const launch = (workingDir?: string) => {\n if (isCreating) return;\n createConversation(\n { workingDir },\n {\n onSuccess: (data) => {\n setOpen(false);\n navigate(`/conversations/${data.conversation_id}`);\n },\n },\n );\n };\n\n const itemClass = dropdownMenuRowClassName;\n\n const keepPopoverOpenOnMouseDown = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n },\n [],\n );\n\n const toggleOpen = React.useCallback(() => {\n setOpen((o) => !o);\n }, []);\n\n const showPopover = open && (!useFixedPlacement || fixedBox !== null);\n const workspaceActionsDisabled = Boolean(workspacesUnsupportedMessage);\n\n const fixedStyle: React.CSSProperties | undefined =\n useFixedPlacement && fixedBox\n ? {\n position: \"fixed\",\n top: fixedBox.top,\n left: fixedBox.left,\n width: fixedBox.width,\n }\n : undefined;\n\n const addWorkspacesButton = (\n <button\n type=\"button\"\n data-testid=\"add-workspaces-button\"\n disabled={workspaceActionsDisabled}\n onMouseDown={keepPopoverOpenOnMouseDown}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (workspaceActionsDisabled) return;\n setBrowserOpen(true);\n }}\n className={itemClass}\n >\n {t(I18nKey.HOME$ADD_WORKSPACES)}\n </button>\n );\n\n const addWorkspacesControl = workspacesUnsupportedMessage ? (\n <StyledTooltip content={workspacesUnsupportedMessage} placement=\"top\">\n <span className=\"block\">{addWorkspacesButton}</span>\n </StyledTooltip>\n ) : (\n addWorkspacesButton\n );\n\n return (\n <div\n className={cn(!useFixedPlacement && \"relative\", className)}\n ref={popoverRef}\n >\n <span ref={triggerWrapRef} className=\"inline-flex\">\n {trigger({\n onClick: toggleOpen,\n \"aria-expanded\": open,\n \"aria-haspopup\": \"menu\",\n disabled: isCreating,\n })}\n </span>\n\n {showPopover && (\n <div\n data-testid={popoverTestId}\n className={cn(\n NEW_CONVERSATION_DROPDOWN_SURFACE,\n !useFixedPlacement &&\n cn(\"absolute top-full mt-0\", popoverClassName),\n )}\n style={fixedStyle}\n >\n <ul\n className={cn(\n \"max-h-[40vh] overflow-y-auto sm:max-h-[280px]\",\n dropdownMenuListClassName,\n )}\n >\n <li>\n <button\n type=\"button\"\n disabled={isCreating}\n data-testid=\"launch-no-workspace\"\n onClick={() => launch()}\n className={itemClass}\n >\n <span className=\"text-[var(--oh-muted)]\">\n {t(I18nKey.HOME$NO_WORKSPACE_OPTION)}\n </span>\n </button>\n </li>\n {workspaces.map((w) => (\n <li key={w.id}>\n <button\n type=\"button\"\n disabled={isCreating}\n data-testid=\"launch-workspace\"\n data-workspace-path={w.path}\n onClick={() => launch(w.path)}\n className={itemClass}\n >\n <span\n className={dropdownMenuRowIconWrapperClassName}\n aria-hidden\n >\n <RepoIcon width={14} height={14} />\n </span>\n <span className=\"truncate\">{w.name}</span>\n </button>\n </li>\n ))}\n </ul>\n\n <div\n className={cn(\"flex flex-col\", dropdownMenuListClassName)}\n data-testid=\"new-conversation-menu-footer\"\n >\n <Divider\n inset=\"menu\"\n testId=\"new-conversation-menu-footer-divider\"\n />\n {addWorkspacesControl}\n {(workspaces.length > 0 || workspaceParents.length > 0) && (\n <button\n type=\"button\"\n data-testid=\"manage-workspaces-button\"\n onMouseDown={keepPopoverOpenOnMouseDown}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setManageOpen(true);\n }}\n className={itemClass}\n >\n {t(I18nKey.HOME$MANAGE_WORKSPACES)}\n </button>\n )}\n </div>\n </div>\n )}\n\n <FolderBrowserModal\n isOpen={browserOpen}\n onClose={() => setBrowserOpen(false)}\n onAdd={(items) => addWorkspaces(items)}\n onAddParent={(items) => addWorkspaceParents(items)}\n />\n\n <ManageWorkspacesModal\n isOpen={manageOpen}\n workspaces={workspaces}\n workspaceParents={workspaceParents}\n onClose={() => setManageOpen(false)}\n onRemove={(path) => removeWorkspace(path)}\n onRemoveParent={(path) => removeWorkspaceParent(path)}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2DA,SAAgB,EAAyB,EACvC,YACA,eACA,sBACA,mBAAgB,4BAChB,uBAAoB,MACY;CAChC,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,gBAAa,IAAe,EAE9B,CAAC,GAAM,KAAW,EAAM,SAAS,GAAM,EACvC,IAAa,EAAM,OAAuB,KAAK,EAC/C,IAAiB,EAAM,OAAwB,KAAK,EACpD,IAAW,EAAyB,GAAgB;EACxD;EACA,SAAS;EACV,CAAC,EAEI,EAAE,MAAM,GAAgB,OAAO,MAAoB,GAAoB,EACvE,IAAmB,GAAgB,oBAAoB,EAAE,EACzD,EAAE,QAAQ,MAAkB,GAAkB,EAC9C,EAAE,QAAQ,MAAoB,GAAoB,EAClD,EAAE,QAAQ,MAAwB,GAAwB,EAC1D,EAAE,QAAQ,MAA0B,GAA0B,EAC9D,EAAE,kBAAe,IAAuB,EACxC,IAA+B,EACnC,GACA,EACD,EACK,CAAC,GAAa,KAAkB,EAAM,SAAS,GAAM,EACrD,CAAC,GAAY,KAAiB,EAAM,SAAS,GAAM,EAEnD,EAAE,QAAQ,GAAoB,iBAAc,GAAuB,EACnE,IAAsB,GAA2B,EACjD,IAAa,KAAa;AAgBhC,CAdA,EAAM,gBAAgB;AACpB,MAAI,CAAC,KAAQ,KAAe,EAAY;EACxC,IAAM,KAAU,MAAkB;AAChC,GACE,EAAW,WACX,CAAC,EAAW,QAAQ,SAAS,EAAE,OAAe,IAE9C,EAAQ,GAAM;;AAIlB,SADA,SAAS,iBAAiB,aAAa,EAAO,QACjC,SAAS,oBAAoB,aAAa,EAAO;IAC7D;EAAC;EAAM;EAAa;EAAW,CAAC,EAEnC,EAAM,gBAAgB;AACpB,MAAI,CAAC,KAAQ,KAAe,EAAY;EACxC,IAAM,KAAa,MAAyB;AAC1C,GAAI,EAAM,QAAQ,YAChB,EAAQ,GAAM;;AAIlB,SADA,OAAO,iBAAiB,WAAW,EAAU,QAChC,OAAO,oBAAoB,WAAW,EAAU;IAC5D;EAAC;EAAM;EAAa;EAAW,CAAC;CAEnC,IAAM,KAAU,MAAwB;AAClC,OACJ,EACE,EAAE,eAAY,EACd,EACE,YAAY,MAAS;AAEnB,GADA,EAAQ,GAAM,EACd,EAAS,kBAAkB,EAAK,kBAAkB;KAErD,CACF;IAGG,IAAY,IAEZ,IAA6B,EAAM,aACtC,MAA+C;AAE9C,EADA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB;IAEzB,EAAE,CACH,EAEK,KAAa,EAAM,kBAAkB;AACzC,KAAS,MAAM,CAAC,EAAE;IACjB,EAAE,CAAC,EAEA,KAAc,MAAS,CAAC,KAAqB,MAAa,OAC1D,IAA2B,EAAQ,GAEnC,KACJ,KAAqB,IACjB;EACE,UAAU;EACV,KAAK,EAAS;EACd,MAAM,EAAS;EACf,OAAO,EAAS;EACjB,GACD,KAAA,GAEA,IACJ,kBAAC,UAAD;EACE,MAAK;EACL,eAAY;EACZ,UAAU;EACV,aAAa;EACb,UAAU,MAAU;AAClB,KAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACnB,MACJ,EAAe,GAAK;;EAEtB,WAAW;YAEV,EAAE,EAAQ,oBAAoB;EACxB,CAAA,EAGL,KAAuB,IAC3B,kBAAC,GAAD;EAAe,SAAS;EAA8B,WAAU;YAC9D,kBAAC,QAAD;GAAM,WAAU;aAAS;GAA2B,CAAA;EACtC,CAAA,GAEhB;AAGF,QACE,kBAAC,OAAD;EACE,WAAW,EAAG,CAAC,KAAqB,YAAY,GAAU;EAC1D,KAAK;YAFP;GAIE,kBAAC,QAAD;IAAM,KAAK;IAAgB,WAAU;cAClC,EAAQ;KACP,SAAS;KACT,iBAAiB;KACjB,iBAAiB;KACjB,UAAU;KACX,CAAC;IACG,CAAA;GAEN,MACC,kBAAC,OAAD;IACE,eAAa;IACb,WAAW,EACT,GACA,CAAC,KACC,EAAG,0BAA0B,GAAiB,CACjD;IACD,OAAO;cAPT,CASE,kBAAC,MAAD;KACE,WAAW,EACT,iDACA,EACD;eAJH,CAME,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;MACE,MAAK;MACL,UAAU;MACV,eAAY;MACZ,eAAe,GAAQ;MACvB,WAAW;gBAEX,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAE,EAAQ,yBAAyB;OAC/B,CAAA;MACA,CAAA,EACN,CAAA,EACJ,EAAW,KAAK,MACf,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;MACE,MAAK;MACL,UAAU;MACV,eAAY;MACZ,uBAAqB,EAAE;MACvB,eAAe,EAAO,EAAE,KAAK;MAC7B,WAAW;gBANb,CAQE,kBAAC,QAAD;OACE,WAAW;OACX,eAAA;iBAEA,kBAAC,GAAD;QAAU,OAAO;QAAI,QAAQ;QAAM,CAAA;OAC9B,CAAA,EACP,kBAAC,QAAD;OAAM,WAAU;iBAAY,EAAE;OAAY,CAAA,CACnC;SACN,EAjBI,EAAE,GAiBN,CACL,CACC;QAEL,kBAAC,OAAD;KACE,WAAW,EAAG,iBAAiB,EAA0B;KACzD,eAAY;eAFd;MAIE,kBAAC,GAAD;OACE,OAAM;OACN,QAAO;OACP,CAAA;MACD;OACC,EAAW,SAAS,KAAK,EAAiB,SAAS,MACnD,kBAAC,UAAD;OACE,MAAK;OACL,eAAY;OACZ,aAAa;OACb,UAAU,MAAU;AAGlB,QAFA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACvB,EAAc,GAAK;;OAErB,WAAW;iBAEV,EAAE,EAAQ,uBAAuB;OAC3B,CAAA;MAEP;OACF;;GAGR,kBAAC,GAAD;IACE,QAAQ;IACR,eAAe,EAAe,GAAM;IACpC,QAAQ,MAAU,EAAc,EAAM;IACtC,cAAc,MAAU,EAAoB,EAAM;IAClD,CAAA;GAEF,kBAAC,GAAD;IACE,QAAQ;IACI;IACM;IAClB,eAAe,EAAc,GAAM;IACnC,WAAW,MAAS,EAAgB,EAAK;IACzC,iBAAiB,MAAS,EAAsB,EAAK;IACrD,CAAA;GACE"}
@@ -1,2 +1,2 @@
1
- require(`../../../_virtual/_rolldown/runtime.cjs`);var e=require(`../../../utils/utils.cjs`).cn(`z-50 flex flex-col rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 text-white shadow-lg`);exports.NEW_CONVERSATION_DROPDOWN_SURFACE=e;
1
+ require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../utils/utils.cjs`),t=require(`../../../utils/dropdown-classes.cjs`);var n=e.cn(`z-50 flex flex-col rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 text-white shadow-lg`,t.dropdownMenuListGapClassName);exports.NEW_CONVERSATION_DROPDOWN_SURFACE=n;
2
2
  //# sourceMappingURL=new-conversation-dropdown-styles.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"new-conversation-dropdown-styles.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/new-conversation-dropdown-styles.ts"],"sourcesContent":["import { cn } from \"#/utils/utils\";\n\n/** Match conversation panel filter and other sidebar menus */\nexport const NEW_CONVERSATION_DROPDOWN_SURFACE = cn(\n \"z-50 flex flex-col rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 text-white shadow-lg\",\n);\n"],"mappings":"mDAGA,IAAa,qCAAoC,CAAA,GAC/C,mHACD"}
1
+ {"version":3,"file":"new-conversation-dropdown-styles.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/new-conversation-dropdown-styles.ts"],"sourcesContent":["import { cn } from \"#/utils/utils\";\nimport { dropdownMenuListGapClassName } from \"#/utils/dropdown-classes\";\n\n/** Match conversation panel filter and other sidebar menus */\nexport const NEW_CONVERSATION_DROPDOWN_SURFACE = cn(\n \"z-50 flex flex-col rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 text-white shadow-lg\",\n dropdownMenuListGapClassName,\n);\n"],"mappings":"gJAIA,IAAa,EAAoC,EAAA,GAC/C,mHACA,EAAA,6BACD"}
@@ -1,7 +1,8 @@
1
1
  import { cn as e } from "../../../utils/utils.js";
2
+ import { dropdownMenuListGapClassName as t } from "../../../utils/dropdown-classes.js";
2
3
  //#region src/components/features/conversation-panel/new-conversation-dropdown-styles.ts
3
- var t = e("z-50 flex flex-col rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 text-white shadow-lg");
4
+ var n = e("z-50 flex flex-col rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 text-white shadow-lg", t);
4
5
  //#endregion
5
- export { t as NEW_CONVERSATION_DROPDOWN_SURFACE };
6
+ export { n as NEW_CONVERSATION_DROPDOWN_SURFACE };
6
7
 
7
8
  //# sourceMappingURL=new-conversation-dropdown-styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"new-conversation-dropdown-styles.js","names":[],"sources":["../../../../src/components/features/conversation-panel/new-conversation-dropdown-styles.ts"],"sourcesContent":["import { cn } from \"#/utils/utils\";\n\n/** Match conversation panel filter and other sidebar menus */\nexport const NEW_CONVERSATION_DROPDOWN_SURFACE = cn(\n \"z-50 flex flex-col rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 text-white shadow-lg\",\n);\n"],"mappings":";;AAGA,IAAa,IAAoC,EAC/C,mHACD"}
1
+ {"version":3,"file":"new-conversation-dropdown-styles.js","names":[],"sources":["../../../../src/components/features/conversation-panel/new-conversation-dropdown-styles.ts"],"sourcesContent":["import { cn } from \"#/utils/utils\";\nimport { dropdownMenuListGapClassName } from \"#/utils/dropdown-classes\";\n\n/** Match conversation panel filter and other sidebar menus */\nexport const NEW_CONVERSATION_DROPDOWN_SURFACE = cn(\n \"z-50 flex flex-col rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 text-white shadow-lg\",\n dropdownMenuListGapClassName,\n);\n"],"mappings":";;;AAIA,IAAa,IAAoC,EAC/C,oHACA,EACD"}
@@ -1,2 +1,2 @@
1
- require(`../../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../../utils/utils.cjs`);let t=require(`react/jsx-runtime`);function n({taskStatus:n}){return n===`WORKING`?null:(0,t.jsx)(`span`,{className:e.cn(`text-xs font-medium px-2 py-0.5 rounded border flex-shrink-0`,(()=>{switch(n){case`READY`:return`bg-green-500/10 text-green-400 border-green-500/20`;case`ERROR`:return`bg-red-500/10 text-red-400 border-red-500/20`;default:return`bg-yellow-500/10 text-yellow-400 border-yellow-500/20`}})()),children:(e=>e.toLowerCase().replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase()))(n)})}exports.StartTaskStatusBadge=n;
1
+ require(`../../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../../utils/status.cjs`),n=require(`../../../../utils/utils.cjs`);let r=require(`react/jsx-runtime`);function i({taskStatus:i}){let{t:a}=e.useTranslation(`openhands`);return i===`WORKING`?null:(0,r.jsx)(`span`,{className:n.cn(`text-xs font-medium px-2 py-0.5 rounded border flex-shrink-0`,(()=>{switch(i){case`READY`:return`bg-green-500/10 text-green-400 border-green-500/20`;case`ERROR`:return`bg-red-500/10 text-red-400 border-red-500/20`;default:return`bg-yellow-500/10 text-yellow-400 border-yellow-500/20`}})()),children:a(t.getTaskStatusI18nKey(i))})}exports.StartTaskStatusBadge=i;
2
2
  //# sourceMappingURL=start-task-status-badge.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-task-status-badge.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/start-task-card/start-task-status-badge.tsx"],"sourcesContent":["import type { AppConversationStartTaskStatus } from \"#/api/conversation-service/agent-server-conversation-service.types\";\nimport { cn } from \"#/utils/utils\";\n\ninterface StartTaskStatusBadgeProps {\n taskStatus: AppConversationStartTaskStatus;\n}\n\nexport function StartTaskStatusBadge({\n taskStatus,\n}: StartTaskStatusBadgeProps) {\n // Don't show badge for WORKING status (most common, clutters UI)\n if (taskStatus === \"WORKING\") {\n return null;\n }\n\n // Format status for display\n const formatStatus = (status: string) =>\n status\n .toLowerCase()\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n\n // Get status color\n const getStatusStyle = () => {\n switch (taskStatus) {\n case \"READY\":\n return \"bg-green-500/10 text-green-400 border-green-500/20\";\n case \"ERROR\":\n return \"bg-red-500/10 text-red-400 border-red-500/20\";\n default:\n return \"bg-yellow-500/10 text-yellow-400 border-yellow-500/20\";\n }\n };\n\n return (\n <span\n className={cn(\n \"text-xs font-medium px-2 py-0.5 rounded border flex-shrink-0\",\n getStatusStyle(),\n )}\n >\n {formatStatus(taskStatus)}\n </span>\n );\n}\n"],"mappings":"wIAOA,SAAgB,EAAqB,CACnC,cAC4B,CAyB5B,OAvBI,IAAe,UACV,MAuBP,EAAA,EAAA,KAAC,OAAD,CACE,UAAW,EAAA,GACT,oEAduB,CAC3B,OAAQ,EAAR,CACE,IAAK,QACH,MAAO,qDACT,IAAK,QACH,MAAO,+CACT,QACE,MAAO,4DAQS,CACjB,WAvBiB,GACpB,EACG,aAAa,CACb,QAAQ,KAAM,IAAI,CAClB,QAAQ,QAAU,GAAM,EAAE,aAAa,CAAC,EAqB3B,EAAW,CACpB,CAAA"}
1
+ {"version":3,"file":"start-task-status-badge.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/start-task-card/start-task-status-badge.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport type { AppConversationStartTaskStatus } from \"#/api/conversation-service/agent-server-conversation-service.types\";\nimport { cn } from \"#/utils/utils\";\nimport { getTaskStatusI18nKey } from \"#/utils/status\";\n\ninterface StartTaskStatusBadgeProps {\n taskStatus: AppConversationStartTaskStatus;\n}\n\nexport function StartTaskStatusBadge({\n taskStatus,\n}: StartTaskStatusBadgeProps) {\n const { t } = useTranslation(\"openhands\");\n\n // Don't show badge for WORKING status (most common, clutters UI)\n if (taskStatus === \"WORKING\") {\n return null;\n }\n\n // Localized status label getTaskStatusI18nKey maps every status (including\n // the terminal READY/ERROR states) to its localized key.\n const getStatusLabel = () => t(getTaskStatusI18nKey(taskStatus));\n\n // Get status color\n const getStatusStyle = () => {\n switch (taskStatus) {\n case \"READY\":\n return \"bg-green-500/10 text-green-400 border-green-500/20\";\n case \"ERROR\":\n return \"bg-red-500/10 text-red-400 border-red-500/20\";\n default:\n return \"bg-yellow-500/10 text-yellow-400 border-yellow-500/20\";\n }\n };\n\n return (\n <span\n className={cn(\n \"text-xs font-medium px-2 py-0.5 rounded border flex-shrink-0\",\n getStatusStyle(),\n )}\n >\n {getStatusLabel()}\n </span>\n );\n}\n"],"mappings":"iQASA,SAAgB,EAAqB,CACnC,cAC4B,CAC5B,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CAuBzC,OApBI,IAAe,UACV,MAoBP,EAAA,EAAA,KAAC,OAAD,CACE,UAAW,EAAA,GACT,oEAduB,CAC3B,OAAQ,EAAR,CACE,IAAK,QACH,MAAO,qDACT,IAAK,QACH,MAAO,+CACT,QACE,MAAO,4DAQS,CACjB,UAnBwB,EAAE,EAAA,qBAAqB,EAAW,CAAC,CAsBvD,CAAA"}
@@ -1,19 +1,22 @@
1
- import { cn as e } from "../../../../utils/utils.js";
2
- import { jsx as t } from "react/jsx-runtime";
1
+ import { useTranslation as e } from "../../../../node_modules/react-i18next/dist/es/useTranslation.js";
2
+ import { getTaskStatusI18nKey as t } from "../../../../utils/status.js";
3
+ import { cn as n } from "../../../../utils/utils.js";
4
+ import { jsx as r } from "react/jsx-runtime";
3
5
  //#region src/components/features/conversation-panel/start-task-card/start-task-status-badge.tsx
4
- function n({ taskStatus: n }) {
5
- return n === "WORKING" ? null : /* @__PURE__ */ t("span", {
6
- className: e("text-xs font-medium px-2 py-0.5 rounded border flex-shrink-0", (() => {
7
- switch (n) {
6
+ function i({ taskStatus: i }) {
7
+ let { t: a } = e("openhands");
8
+ return i === "WORKING" ? null : /* @__PURE__ */ r("span", {
9
+ className: n("text-xs font-medium px-2 py-0.5 rounded border flex-shrink-0", (() => {
10
+ switch (i) {
8
11
  case "READY": return "bg-green-500/10 text-green-400 border-green-500/20";
9
12
  case "ERROR": return "bg-red-500/10 text-red-400 border-red-500/20";
10
13
  default: return "bg-yellow-500/10 text-yellow-400 border-yellow-500/20";
11
14
  }
12
15
  })()),
13
- children: ((e) => e.toLowerCase().replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()))(n)
16
+ children: a(t(i))
14
17
  });
15
18
  }
16
19
  //#endregion
17
- export { n as StartTaskStatusBadge };
20
+ export { i as StartTaskStatusBadge };
18
21
 
19
22
  //# sourceMappingURL=start-task-status-badge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-task-status-badge.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/start-task-card/start-task-status-badge.tsx"],"sourcesContent":["import type { AppConversationStartTaskStatus } from \"#/api/conversation-service/agent-server-conversation-service.types\";\nimport { cn } from \"#/utils/utils\";\n\ninterface StartTaskStatusBadgeProps {\n taskStatus: AppConversationStartTaskStatus;\n}\n\nexport function StartTaskStatusBadge({\n taskStatus,\n}: StartTaskStatusBadgeProps) {\n // Don't show badge for WORKING status (most common, clutters UI)\n if (taskStatus === \"WORKING\") {\n return null;\n }\n\n // Format status for display\n const formatStatus = (status: string) =>\n status\n .toLowerCase()\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n\n // Get status color\n const getStatusStyle = () => {\n switch (taskStatus) {\n case \"READY\":\n return \"bg-green-500/10 text-green-400 border-green-500/20\";\n case \"ERROR\":\n return \"bg-red-500/10 text-red-400 border-red-500/20\";\n default:\n return \"bg-yellow-500/10 text-yellow-400 border-yellow-500/20\";\n }\n };\n\n return (\n <span\n className={cn(\n \"text-xs font-medium px-2 py-0.5 rounded border flex-shrink-0\",\n getStatusStyle(),\n )}\n >\n {formatStatus(taskStatus)}\n </span>\n );\n}\n"],"mappings":";;;AAOA,SAAgB,EAAqB,EACnC,iBAC4B;AAyB5B,QAvBI,MAAe,YACV,OAuBP,kBAAC,QAAD;EACE,WAAW,EACT,uEAduB;AAC3B,WAAQ,GAAR;IACE,KAAK,QACH,QAAO;IACT,KAAK,QACH,QAAO;IACT,QACE,QAAO;;MAQS,CACjB;cAvBiB,MACpB,EACG,aAAa,CACb,QAAQ,MAAM,IAAI,CAClB,QAAQ,UAAU,MAAM,EAAE,aAAa,CAAC,EAqB3B,EAAW;EACpB,CAAA"}
1
+ {"version":3,"file":"start-task-status-badge.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/start-task-card/start-task-status-badge.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport type { AppConversationStartTaskStatus } from \"#/api/conversation-service/agent-server-conversation-service.types\";\nimport { cn } from \"#/utils/utils\";\nimport { getTaskStatusI18nKey } from \"#/utils/status\";\n\ninterface StartTaskStatusBadgeProps {\n taskStatus: AppConversationStartTaskStatus;\n}\n\nexport function StartTaskStatusBadge({\n taskStatus,\n}: StartTaskStatusBadgeProps) {\n const { t } = useTranslation(\"openhands\");\n\n // Don't show badge for WORKING status (most common, clutters UI)\n if (taskStatus === \"WORKING\") {\n return null;\n }\n\n // Localized status label getTaskStatusI18nKey maps every status (including\n // the terminal READY/ERROR states) to its localized key.\n const getStatusLabel = () => t(getTaskStatusI18nKey(taskStatus));\n\n // Get status color\n const getStatusStyle = () => {\n switch (taskStatus) {\n case \"READY\":\n return \"bg-green-500/10 text-green-400 border-green-500/20\";\n case \"ERROR\":\n return \"bg-red-500/10 text-red-400 border-red-500/20\";\n default:\n return \"bg-yellow-500/10 text-yellow-400 border-yellow-500/20\";\n }\n };\n\n return (\n <span\n className={cn(\n \"text-xs font-medium px-2 py-0.5 rounded border flex-shrink-0\",\n getStatusStyle(),\n )}\n >\n {getStatusLabel()}\n </span>\n );\n}\n"],"mappings":";;;;;AASA,SAAgB,EAAqB,EACnC,iBAC4B;CAC5B,IAAM,EAAE,SAAM,EAAe,YAAY;AAuBzC,QApBI,MAAe,YACV,OAoBP,kBAAC,QAAD;EACE,WAAW,EACT,uEAduB;AAC3B,WAAQ,GAAR;IACE,KAAK,QACH,QAAO;IACT,KAAK,QACH,QAAO;IACT,QACE,QAAO;;MAQS,CACjB;YAnBwB,EAAE,EAAqB,EAAW,CAAC;EAsBvD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"tab-content.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/system-message-modal/tab-content.tsx"],"sourcesContent":["import { SystemMessageContent } from \"./system-message-content\";\nimport { ToolsList } from \"./tools-list\";\nimport { EmptyToolsState } from \"./empty-tools-state\";\nimport { ChatCompletionToolParam } from \"#/types/agent-server/core\";\n\ninterface TabContentProps {\n activeTab: \"system\" | \"tools\";\n systemMessage: {\n content: string;\n tools: Array<Record<string, unknown>> | ChatCompletionToolParam[] | null;\n };\n expandedTools: Record<number, boolean>;\n onToggleTool: (index: number) => void;\n}\n\nexport function TabContent({\n activeTab,\n systemMessage,\n expandedTools,\n onToggleTool,\n}: TabContentProps) {\n if (activeTab === \"system\") {\n return <SystemMessageContent content={systemMessage.content} />;\n }\n\n if (activeTab === \"tools\") {\n if (systemMessage.tools && systemMessage.tools.length > 0) {\n return (\n <ToolsList\n tools={systemMessage.tools}\n expandedTools={expandedTools}\n onToggleTool={onToggleTool}\n />\n );\n }\n\n return <EmptyToolsState />;\n }\n\n return null;\n}\n"],"mappings":"4MAeA,SAAgB,EAAW,CACzB,YACA,gBACA,gBACA,gBACkB,CAmBlB,OAlBI,IAAc,UACT,EAAA,EAAA,KAAC,EAAA,qBAAD,CAAsB,QAAS,EAAc,QAAW,CAAA,CAG7D,IAAc,QACZ,EAAc,OAAS,EAAc,MAAM,OAAS,GAEpD,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,MAAO,EAAc,MACN,gBACD,eACd,CAAA,EAIC,EAAA,EAAA,KAAC,EAAA,gBAAD,EAAmB,CAAA,CAGrB"}
1
+ {"version":3,"file":"tab-content.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/system-message-modal/tab-content.tsx"],"sourcesContent":["import { SystemMessageContent } from \"./system-message-content\";\nimport { ToolsList } from \"./tools-list\";\nimport { EmptyToolsState } from \"./empty-tools-state\";\nimport { SystemMessageForModal } from \"#/utils/system-message-adapter\";\n\ninterface TabContentProps {\n activeTab: \"system\" | \"tools\";\n systemMessage: SystemMessageForModal;\n expandedTools: Record<number, boolean>;\n onToggleTool: (index: number) => void;\n}\n\nexport function TabContent({\n activeTab,\n systemMessage,\n expandedTools,\n onToggleTool,\n}: TabContentProps) {\n if (activeTab === \"system\") {\n return <SystemMessageContent content={systemMessage.content} />;\n }\n\n if (activeTab === \"tools\") {\n if (systemMessage.tools && systemMessage.tools.length > 0) {\n return (\n <ToolsList\n tools={systemMessage.tools}\n expandedTools={expandedTools}\n onToggleTool={onToggleTool}\n />\n );\n }\n\n return <EmptyToolsState />;\n }\n\n return null;\n}\n"],"mappings":"4MAYA,SAAgB,EAAW,CACzB,YACA,gBACA,gBACA,gBACkB,CAmBlB,OAlBI,IAAc,UACT,EAAA,EAAA,KAAC,EAAA,qBAAD,CAAsB,QAAS,EAAc,QAAW,CAAA,CAG7D,IAAc,QACZ,EAAc,OAAS,EAAc,MAAM,OAAS,GAEpD,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,MAAO,EAAc,MACN,gBACD,eACd,CAAA,EAIC,EAAA,EAAA,KAAC,EAAA,gBAAD,EAAmB,CAAA,CAGrB"}
@@ -1,10 +1,7 @@
1
- import { ChatCompletionToolParam } from "#/types/agent-server/core";
1
+ import { SystemMessageForModal } from "#/utils/system-message-adapter";
2
2
  interface TabContentProps {
3
3
  activeTab: "system" | "tools";
4
- systemMessage: {
5
- content: string;
6
- tools: Array<Record<string, unknown>> | ChatCompletionToolParam[] | null;
7
- };
4
+ systemMessage: SystemMessageForModal;
8
5
  expandedTools: Record<number, boolean>;
9
6
  onToggleTool: (index: number) => void;
10
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tab-content.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/system-message-modal/tab-content.tsx"],"sourcesContent":["import { SystemMessageContent } from \"./system-message-content\";\nimport { ToolsList } from \"./tools-list\";\nimport { EmptyToolsState } from \"./empty-tools-state\";\nimport { ChatCompletionToolParam } from \"#/types/agent-server/core\";\n\ninterface TabContentProps {\n activeTab: \"system\" | \"tools\";\n systemMessage: {\n content: string;\n tools: Array<Record<string, unknown>> | ChatCompletionToolParam[] | null;\n };\n expandedTools: Record<number, boolean>;\n onToggleTool: (index: number) => void;\n}\n\nexport function TabContent({\n activeTab,\n systemMessage,\n expandedTools,\n onToggleTool,\n}: TabContentProps) {\n if (activeTab === \"system\") {\n return <SystemMessageContent content={systemMessage.content} />;\n }\n\n if (activeTab === \"tools\") {\n if (systemMessage.tools && systemMessage.tools.length > 0) {\n return (\n <ToolsList\n tools={systemMessage.tools}\n expandedTools={expandedTools}\n onToggleTool={onToggleTool}\n />\n );\n }\n\n return <EmptyToolsState />;\n }\n\n return null;\n}\n"],"mappings":";;;;;AAeA,SAAgB,EAAW,EACzB,cACA,kBACA,kBACA,mBACkB;AAmBlB,QAlBI,MAAc,WACT,kBAAC,GAAD,EAAsB,SAAS,EAAc,SAAW,CAAA,GAG7D,MAAc,UACZ,EAAc,SAAS,EAAc,MAAM,SAAS,IAEpD,kBAAC,GAAD;EACE,OAAO,EAAc;EACN;EACD;EACd,CAAA,GAIC,kBAAC,GAAD,EAAmB,CAAA,GAGrB"}
1
+ {"version":3,"file":"tab-content.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/system-message-modal/tab-content.tsx"],"sourcesContent":["import { SystemMessageContent } from \"./system-message-content\";\nimport { ToolsList } from \"./tools-list\";\nimport { EmptyToolsState } from \"./empty-tools-state\";\nimport { SystemMessageForModal } from \"#/utils/system-message-adapter\";\n\ninterface TabContentProps {\n activeTab: \"system\" | \"tools\";\n systemMessage: SystemMessageForModal;\n expandedTools: Record<number, boolean>;\n onToggleTool: (index: number) => void;\n}\n\nexport function TabContent({\n activeTab,\n systemMessage,\n expandedTools,\n onToggleTool,\n}: TabContentProps) {\n if (activeTab === \"system\") {\n return <SystemMessageContent content={systemMessage.content} />;\n }\n\n if (activeTab === \"tools\") {\n if (systemMessage.tools && systemMessage.tools.length > 0) {\n return (\n <ToolsList\n tools={systemMessage.tools}\n expandedTools={expandedTools}\n onToggleTool={onToggleTool}\n />\n );\n }\n\n return <EmptyToolsState />;\n }\n\n return null;\n}\n"],"mappings":";;;;;AAYA,SAAgB,EAAW,EACzB,cACA,kBACA,kBACA,mBACkB;AAmBlB,QAlBI,MAAc,WACT,kBAAC,GAAD,EAAsB,SAAS,EAAc,SAAW,CAAA,GAG7D,MAAc,UACZ,EAAc,SAAS,EAAc,MAAM,SAAS,IAEpD,kBAAC,GAAD;EACE,OAAO,EAAc;EACN;EACD;EACd,CAAA,GAIC,kBAAC,GAAD,EAAmB,CAAA,GAGrB"}
@@ -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(`../markdown/markdown-renderer.cjs`),r=require(`../../../stores/use-workspace-mutation-counter.cjs`),i=require(`../../../hooks/query/use-workspace-file-content.cjs`),a=require(`./highlighted-source-view.cjs`);let o=require(`react/jsx-runtime`);var s=new Set([`html`,`htm`,`svg`]),c=new Set([`md`,`markdown`,`mdx`]);function l(e){let t=e.lastIndexOf(`.`);return t===-1?``:e.slice(t+1).toLowerCase()}function u({path:u,viewMode:d}){let{t:f}=e.useTranslation(`openhands`),p=i.useWorkspaceFileContent(u),m=r.useWorkspaceMutationCounter(e=>e.count);if(p.isLoading)return(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]`,children:f(t.I18nKey.FILES$LOADING_FILES)});if(p.isError||!p.data)return(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]`,"data-testid":`file-content-viewer-error`,children:p.error?.message??f(t.I18nKey.FILES$LOAD_ERROR)});let{kind:h,text:g,staticUrl:_,mimeType:v}=p.data,y=r.withWorkspaceCacheBuster(_,m);return d===`plain`?h===`text`&&g!==null?(0,o.jsx)(a.HighlightedSourceView,{path:u,text:g,mimeType:v??void 0}):(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]`,"data-testid":`file-content-viewer-binary-fallback`,children:f(t.I18nKey.FILES$BINARY_FALLBACK)}):h===`image`?(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center bg-[var(--oh-surface)] p-4`,"data-testid":`file-content-viewer-image`,children:(0,o.jsx)(`img`,{src:y,alt:u,className:`max-h-full max-w-full object-contain`})}):h===`pdf`?(0,o.jsx)(`iframe`,{title:u,src:y,sandbox:`allow-same-origin`,"data-testid":`file-content-viewer-iframe`,className:`h-full w-full bg-white`}):h===`binary`?(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]`,"data-testid":`file-content-viewer-binary-fallback`,children:f(t.I18nKey.FILES$BINARY_FALLBACK)}):v===`text/html`||s.has(l(u))?(0,o.jsx)(`iframe`,{title:u,src:y,sandbox:`allow-same-origin`,"data-testid":`file-content-viewer-iframe`,className:`h-full w-full bg-white`}):h===`text`&&c.has(l(u))?(0,o.jsx)(`div`,{"data-testid":`file-content-viewer-markdown`,className:`h-full w-full overflow-auto bg-[var(--oh-surface)] text-white custom-scrollbar-always`,children:(0,o.jsx)(`div`,{className:`prose prose-sm prose-invert max-w-none p-6 [--tw-prose-body:#fff] [--tw-prose-bold:#fff] [--tw-prose-headings:#fff] [--tw-prose-lead:#fff] [--tw-prose-counters:#fff] [--tw-prose-quotes:#fff] [--tw-prose-quote-borders:var(--oh-border-subtle)] [--tw-prose-bullets:var(--oh-muted)] [--tw-prose-hr:var(--oh-border-subtle)] [--tw-prose-captions:var(--oh-muted)] [--tw-prose-kbd:#fff]`,children:(0,o.jsx)(n.MarkdownRenderer,{content:g??``,includeStandard:!0,includeHeadings:!0})})}):h===`text`&&g!==null?(0,o.jsx)(a.HighlightedSourceView,{path:u,text:g,mimeType:v??void 0}):(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]`,"data-testid":`file-content-viewer-binary-fallback`,children:f(t.I18nKey.FILES$BINARY_FALLBACK)})}exports.FileContentViewer=u;
1
+ require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../markdown/markdown-renderer.cjs`),r=require(`../../../stores/use-workspace-mutation-counter.cjs`),i=require(`../../../hooks/query/use-workspace-file-content.cjs`),a=require(`./highlighted-source-view.cjs`);let o=require(`react/jsx-runtime`);var s=new Set([`html`,`htm`,`svg`]),c=new Set([`md`,`markdown`,`mdx`]),l={pptx:`PowerPoint`,ppt:`PowerPoint`,docx:`Word`,doc:`Word`,xlsx:`Excel`,xls:`Excel`};function u(e){let t=e.lastIndexOf(`.`);return t===-1?``:e.slice(t+1).toLowerCase()}function d({path:n}){let{t:r}=e.useTranslation(`openhands`),i=l[u(n)];return(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]`,"data-testid":i?`file-content-viewer-unsupported-document`:`file-content-viewer-binary-fallback`,children:i?r(t.I18nKey.FILES$UNSUPPORTED_DOCUMENT,{type:i}):r(t.I18nKey.FILES$BINARY_FALLBACK)})}function f({path:l,viewMode:f}){let{t:p}=e.useTranslation(`openhands`),m=i.useWorkspaceFileContent(l),h=r.useWorkspaceMutationCounter(e=>e.count);if(m.isLoading)return(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]`,children:p(t.I18nKey.FILES$LOADING_FILES)});if(m.isError||!m.data)return(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]`,"data-testid":`file-content-viewer-error`,children:m.error?.message??p(t.I18nKey.FILES$LOAD_ERROR)});let{kind:g,text:_,staticUrl:v,mimeType:y}=m.data,b=r.withWorkspaceCacheBuster(v,h);return f===`plain`?g===`text`&&_!==null?(0,o.jsx)(a.HighlightedSourceView,{path:l,text:_,mimeType:y??void 0}):(0,o.jsx)(d,{path:l}):g===`image`?(0,o.jsx)(`div`,{className:`flex h-full w-full items-center justify-center bg-[var(--oh-surface)] p-4`,"data-testid":`file-content-viewer-image`,children:(0,o.jsx)(`img`,{src:b,alt:l,className:`max-h-full max-w-full object-contain`})}):g===`pdf`?(0,o.jsx)(`iframe`,{title:l,src:b,sandbox:`allow-same-origin`,"data-testid":`file-content-viewer-iframe`,className:`h-full w-full bg-white`}):g===`binary`?(0,o.jsx)(d,{path:l}):y===`text/html`||s.has(u(l))?(0,o.jsx)(`iframe`,{title:l,src:b,sandbox:`allow-same-origin`,"data-testid":`file-content-viewer-iframe`,className:`h-full w-full bg-white`}):g===`text`&&c.has(u(l))?(0,o.jsx)(`div`,{"data-testid":`file-content-viewer-markdown`,className:`h-full w-full overflow-auto bg-[var(--oh-surface)] text-white custom-scrollbar-always`,children:(0,o.jsx)(`div`,{className:`prose prose-sm prose-invert max-w-none p-6 [--tw-prose-body:#fff] [--tw-prose-bold:#fff] [--tw-prose-headings:#fff] [--tw-prose-lead:#fff] [--tw-prose-counters:#fff] [--tw-prose-quotes:#fff] [--tw-prose-quote-borders:var(--oh-border-subtle)] [--tw-prose-bullets:var(--oh-muted)] [--tw-prose-hr:var(--oh-border-subtle)] [--tw-prose-captions:var(--oh-muted)] [--tw-prose-kbd:#fff]`,children:(0,o.jsx)(n.MarkdownRenderer,{content:_??``,includeStandard:!0,includeHeadings:!0})})}):g===`text`&&_!==null?(0,o.jsx)(a.HighlightedSourceView,{path:l,text:_,mimeType:y??void 0}):(0,o.jsx)(d,{path:l})}exports.FileContentViewer=f;
2
2
  //# sourceMappingURL=file-content-viewer.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-content-viewer.cjs","names":[],"sources":["../../../../src/components/features/files-tab/file-content-viewer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\n\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useWorkspaceFileContent } from \"#/hooks/query/use-workspace-file-content\";\nimport {\n useWorkspaceMutationCounter,\n withWorkspaceCacheBuster,\n} from \"#/stores/use-workspace-mutation-counter\";\nimport { MarkdownRenderer } from \"#/components/features/markdown/markdown-renderer\";\nimport { HighlightedSourceView } from \"./highlighted-source-view\";\nimport type { ViewMode } from \"./view-mode\";\n\ninterface FileContentViewerProps {\n path: string;\n viewMode: ViewMode;\n}\n\nconst HTML_LIKE_EXTS = new Set([\"html\", \"htm\", \"svg\"]);\nconst MARKDOWN_EXTS = new Set([\"md\", \"markdown\", \"mdx\"]);\n\nfunction getExtension(path: string): string {\n const idx = path.lastIndexOf(\".\");\n return idx === -1 ? \"\" : path.slice(idx + 1).toLowerCase();\n}\n\n/**\n * Renders the contents of a single workspace file. In `rich` mode we point\n * an iframe / <img> straight at the agent server's static workspace\n * fileserver for HTML / SVG / images / PDFs, so relative asset references\n * load naturally. In `plain` mode we always show the raw bytes as text (or\n * a fallback message for binaries).\n */\nexport function FileContentViewer({ path, viewMode }: FileContentViewerProps) {\n const { t } = useTranslation(\"openhands\");\n const query = useWorkspaceFileContent(path);\n // Subscribe to the workspace mutation counter so the iframe / <img> src\n // changes after every agent-side edit, forcing a fresh fetch even when\n // the *path* hasn't moved (e.g. agent rewrote `style.css` referenced by\n // the currently-displayed `index.html`).\n const mutationCounter = useWorkspaceMutationCounter((state) => state.count);\n\n if (query.isLoading) {\n return (\n <div className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\">\n {t(I18nKey.FILES$LOADING_FILES)}\n </div>\n );\n }\n\n if (query.isError || !query.data) {\n // Show a load-error message rather than the binary-fallback string —\n // these are completely different failure modes (couldn't even fetch\n // the file vs. fetched fine but the bytes aren't previewable) and\n // mixing them up hides real backend failures behind a misleading\n // \"Binary file\" label. Prefer the underlying error's own message when\n // we have one; fall back to the generic translated string otherwise.\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-error\"\n >\n {(query.error as Error | undefined)?.message ??\n t(I18nKey.FILES$LOAD_ERROR)}\n </div>\n );\n }\n\n const { kind, text, staticUrl, mimeType } = query.data;\n const bustedStaticUrl = withWorkspaceCacheBuster(staticUrl, mutationCounter);\n\n // ----- Plain mode: raw source bytes, syntax-highlighted when we can\n // recognize the grammar (falls through to a `<pre>` otherwise). This\n // includes \"plain\" view of markdown / HTML, where the point is to see\n // the markup behind the rich preview.\n if (viewMode === \"plain\") {\n if (kind === \"text\" && text !== null) {\n return (\n <HighlightedSourceView\n path={path}\n text={text}\n mimeType={mimeType ?? undefined}\n />\n );\n }\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-binary-fallback\"\n >\n {t(I18nKey.FILES$BINARY_FALLBACK)}\n </div>\n );\n }\n\n // ----- Rich mode: render HTML, markdown, images, PDFs from staticUrl. ----\n if (kind === \"image\") {\n return (\n <div\n className=\"flex h-full w-full items-center justify-center bg-[var(--oh-surface)] p-4\"\n data-testid=\"file-content-viewer-image\"\n >\n <img\n src={bustedStaticUrl}\n alt={path}\n className=\"max-h-full max-w-full object-contain\"\n />\n </div>\n );\n }\n\n if (kind === \"pdf\") {\n // PDFs can carry embedded JavaScript (AcroForm, OpenAction…). Even\n // though `staticUrl` lives on the agent server origin, the PDF\n // viewer's scripting capability isn't worth the risk for a file\n // preview, so we sandbox the iframe. `allow-same-origin` lets the\n // browser's built-in PDF viewer load the underlying bytes without\n // tripping cross-origin restrictions; we omit `allow-scripts`\n // because no PDF preview we care about needs to run JS in the\n // parent's origin.\n return (\n <iframe\n title={path}\n src={bustedStaticUrl}\n sandbox=\"allow-same-origin\"\n data-testid=\"file-content-viewer-iframe\"\n className=\"h-full w-full bg-white\"\n />\n );\n }\n\n if (kind === \"binary\") {\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-binary-fallback\"\n >\n {t(I18nKey.FILES$BINARY_FALLBACK)}\n </div>\n );\n }\n\n // Text-like content.\n if (mimeType === \"text/html\" || HTML_LIKE_EXTS.has(getExtension(path))) {\n // Sandbox the preview iframe: `allow-same-origin` keeps the frame on\n // the workspace fileserver's origin so relative `<link href=\"…\">`,\n // `<img src=\"…\">`, etc. continue to resolve, while the absence of\n // `allow-scripts` means any `<script>` (or `onerror=…`, inline event\n // handler, …) inside the previewed file is inert. This is exactly\n // the safe-preview posture we want — users can look at their HTML\n // without it executing in the canvas's context.\n return (\n <iframe\n title={path}\n src={bustedStaticUrl}\n sandbox=\"allow-same-origin\"\n data-testid=\"file-content-viewer-iframe\"\n className=\"h-full w-full bg-white\"\n />\n );\n }\n\n if (kind === \"text\" && MARKDOWN_EXTS.has(getExtension(path))) {\n // Match the right-pane chrome color so the rich-rendered markdown\n // blends with the surrounding files tab instead of painting a stark\n // white card. We use `prose-invert` (typography plugin's dark-theme\n // variant) and then layer arbitrary CSS-variable overrides on top to\n // pin body / bold / quote text to pure white — the user specifically\n // asked for every text element (not just headings) to read as white.\n // The custom heading components in `markdown/headings.tsx` already\n // hard-code `text-white`, so headers stay white through this change.\n return (\n <div\n data-testid=\"file-content-viewer-markdown\"\n className=\"h-full w-full overflow-auto bg-[var(--oh-surface)] text-white custom-scrollbar-always\"\n >\n <div className=\"prose prose-sm prose-invert max-w-none p-6 [--tw-prose-body:#fff] [--tw-prose-bold:#fff] [--tw-prose-headings:#fff] [--tw-prose-lead:#fff] [--tw-prose-counters:#fff] [--tw-prose-quotes:#fff] [--tw-prose-quote-borders:var(--oh-border-subtle)] [--tw-prose-bullets:var(--oh-muted)] [--tw-prose-hr:var(--oh-border-subtle)] [--tw-prose-captions:var(--oh-muted)] [--tw-prose-kbd:#fff]\">\n <MarkdownRenderer\n content={text ?? \"\"}\n includeStandard\n includeHeadings\n />\n </div>\n </div>\n );\n }\n\n // Rich mode for actual source code (.ts, .py, .yaml, .css, …): there\n // is no other \"rich\" rendering to fall back to, so highlighted source\n // IS the rich view. Identical to the plain-mode treatment — keeping\n // both branches reuse `HighlightedSourceView` means the toggle has the\n // same visual identity for source files in both modes (which is the\n // honest answer: source IS rendered code).\n if (kind === \"text\" && text !== null) {\n return (\n <HighlightedSourceView\n path={path}\n text={text}\n mimeType={mimeType ?? undefined}\n />\n );\n }\n\n // Truly unknown / empty payload — show a fallback so the pane is never\n // blank.\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-binary-fallback\"\n >\n {t(I18nKey.FILES$BINARY_FALLBACK)}\n </div>\n );\n}\n"],"mappings":"8aAiBA,IAAM,EAAiB,IAAI,IAAI,CAAC,OAAQ,MAAO,MAAM,CAAC,CAChD,EAAgB,IAAI,IAAI,CAAC,KAAM,WAAY,MAAM,CAAC,CAExD,SAAS,EAAa,EAAsB,CAC1C,IAAM,EAAM,EAAK,YAAY,IAAI,CACjC,OAAO,IAAQ,GAAK,GAAK,EAAK,MAAM,EAAM,EAAE,CAAC,aAAa,CAU5D,SAAgB,EAAkB,CAAE,OAAM,YAAoC,CAC5E,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,EAAQ,EAAA,wBAAwB,EAAK,CAKrC,EAAkB,EAAA,4BAA6B,GAAU,EAAM,MAAM,CAE3E,GAAI,EAAM,UACR,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yFACZ,EAAE,EAAA,QAAQ,oBAAoB,CAC3B,CAAA,CAIV,GAAI,EAAM,SAAW,CAAC,EAAM,KAO1B,OACE,EAAA,EAAA,KAAC,MAAD,CACE,UAAU,gFACV,cAAY,qCAEV,EAAM,OAA6B,SACnC,EAAE,EAAA,QAAQ,iBAAiB,CACzB,CAAA,CAIV,GAAM,CAAE,OAAM,OAAM,YAAW,YAAa,EAAM,KAC5C,EAAkB,EAAA,yBAAyB,EAAW,EAAgB,CAwI5E,OAlII,IAAa,QACX,IAAS,QAAU,IAAS,MAE5B,EAAA,EAAA,KAAC,EAAA,sBAAD,CACQ,OACA,OACN,SAAU,GAAY,IAAA,GACtB,CAAA,EAIJ,EAAA,EAAA,KAAC,MAAD,CACE,UAAU,gFACV,cAAY,+CAEX,EAAE,EAAA,QAAQ,sBAAsB,CAC7B,CAAA,CAKN,IAAS,SAET,EAAA,EAAA,KAAC,MAAD,CACE,UAAU,4EACV,cAAY,sCAEZ,EAAA,EAAA,KAAC,MAAD,CACE,IAAK,EACL,IAAK,EACL,UAAU,uCACV,CAAA,CACE,CAAA,CAIN,IAAS,OAUT,EAAA,EAAA,KAAC,SAAD,CACE,MAAO,EACP,IAAK,EACL,QAAQ,oBACR,cAAY,6BACZ,UAAU,yBACV,CAAA,CAIF,IAAS,UAET,EAAA,EAAA,KAAC,MAAD,CACE,UAAU,gFACV,cAAY,+CAEX,EAAE,EAAA,QAAQ,sBAAsB,CAC7B,CAAA,CAKN,IAAa,aAAe,EAAe,IAAI,EAAa,EAAK,CAAC,EASlE,EAAA,EAAA,KAAC,SAAD,CACE,MAAO,EACP,IAAK,EACL,QAAQ,oBACR,cAAY,6BACZ,UAAU,yBACV,CAAA,CAIF,IAAS,QAAU,EAAc,IAAI,EAAa,EAAK,CAAC,EAUxD,EAAA,EAAA,KAAC,MAAD,CACE,cAAY,+BACZ,UAAU,kGAEV,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,uYACb,EAAA,EAAA,KAAC,EAAA,iBAAD,CACE,QAAS,GAAQ,GACjB,gBAAA,GACA,gBAAA,GACA,CAAA,CACE,CAAA,CACF,CAAA,CAUN,IAAS,QAAU,IAAS,MAE5B,EAAA,EAAA,KAAC,EAAA,sBAAD,CACQ,OACA,OACN,SAAU,GAAY,IAAA,GACtB,CAAA,EAOJ,EAAA,EAAA,KAAC,MAAD,CACE,UAAU,gFACV,cAAY,+CAEX,EAAE,EAAA,QAAQ,sBAAsB,CAC7B,CAAA"}
1
+ {"version":3,"file":"file-content-viewer.cjs","names":[],"sources":["../../../../src/components/features/files-tab/file-content-viewer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\n\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useWorkspaceFileContent } from \"#/hooks/query/use-workspace-file-content\";\nimport {\n useWorkspaceMutationCounter,\n withWorkspaceCacheBuster,\n} from \"#/stores/use-workspace-mutation-counter\";\nimport { MarkdownRenderer } from \"#/components/features/markdown/markdown-renderer\";\nimport { HighlightedSourceView } from \"./highlighted-source-view\";\nimport type { ViewMode } from \"./view-mode\";\n\ninterface FileContentViewerProps {\n path: string;\n viewMode: ViewMode;\n}\n\nconst HTML_LIKE_EXTS = new Set([\"html\", \"htm\", \"svg\"]);\nconst MARKDOWN_EXTS = new Set([\"md\", \"markdown\", \"mdx\"]);\n\n// Office/document formats we can't preview inline. The label doubles as the\n// allow-list (a present entry => Office doc) and feeds a clear, format-named\n// \"no preview\" message instead of the generic binary fallback.\nconst OFFICE_DOCUMENT_LABELS: Record<string, string> = {\n pptx: \"PowerPoint\",\n ppt: \"PowerPoint\",\n docx: \"Word\",\n doc: \"Word\",\n xlsx: \"Excel\",\n xls: \"Excel\",\n};\n\nfunction getExtension(path: string): string {\n const idx = path.lastIndexOf(\".\");\n return idx === -1 ? \"\" : path.slice(idx + 1).toLowerCase();\n}\n\n/**\n * Fallback shown when a file's bytes aren't previewable. Office documents\n * (.pptx / .docx / .xlsx …) get a clear, format-named message; every other\n * binary keeps the generic \"binary file\" string so the pane is never blank.\n */\nfunction UnpreviewableFallback({ path }: { path: string }) {\n const { t } = useTranslation(\"openhands\");\n const documentLabel = OFFICE_DOCUMENT_LABELS[getExtension(path)];\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid={\n documentLabel\n ? \"file-content-viewer-unsupported-document\"\n : \"file-content-viewer-binary-fallback\"\n }\n >\n {documentLabel\n ? t(I18nKey.FILES$UNSUPPORTED_DOCUMENT, { type: documentLabel })\n : t(I18nKey.FILES$BINARY_FALLBACK)}\n </div>\n );\n}\n\n/**\n * Renders the contents of a single workspace file. In `rich` mode we point\n * an iframe / <img> straight at the agent server's static workspace\n * fileserver for HTML / SVG / images / PDFs, so relative asset references\n * load naturally. In `plain` mode we always show the raw bytes as text (or\n * a fallback message for binaries).\n */\nexport function FileContentViewer({ path, viewMode }: FileContentViewerProps) {\n const { t } = useTranslation(\"openhands\");\n const query = useWorkspaceFileContent(path);\n // Subscribe to the workspace mutation counter so the iframe / <img> src\n // changes after every agent-side edit, forcing a fresh fetch even when\n // the *path* hasn't moved (e.g. agent rewrote `style.css` referenced by\n // the currently-displayed `index.html`).\n const mutationCounter = useWorkspaceMutationCounter((state) => state.count);\n\n if (query.isLoading) {\n return (\n <div className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\">\n {t(I18nKey.FILES$LOADING_FILES)}\n </div>\n );\n }\n\n if (query.isError || !query.data) {\n // Show a load-error message rather than the binary-fallback string —\n // these are completely different failure modes (couldn't even fetch\n // the file vs. fetched fine but the bytes aren't previewable) and\n // mixing them up hides real backend failures behind a misleading\n // \"Binary file\" label. Prefer the underlying error's own message when\n // we have one; fall back to the generic translated string otherwise.\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-error\"\n >\n {(query.error as Error | undefined)?.message ??\n t(I18nKey.FILES$LOAD_ERROR)}\n </div>\n );\n }\n\n const { kind, text, staticUrl, mimeType } = query.data;\n const bustedStaticUrl = withWorkspaceCacheBuster(staticUrl, mutationCounter);\n\n // ----- Plain mode: raw source bytes, syntax-highlighted when we can\n // recognize the grammar (falls through to a `<pre>` otherwise). This\n // includes \"plain\" view of markdown / HTML, where the point is to see\n // the markup behind the rich preview.\n if (viewMode === \"plain\") {\n if (kind === \"text\" && text !== null) {\n return (\n <HighlightedSourceView\n path={path}\n text={text}\n mimeType={mimeType ?? undefined}\n />\n );\n }\n return <UnpreviewableFallback path={path} />;\n }\n\n // ----- Rich mode: render HTML, markdown, images, PDFs from staticUrl. ----\n if (kind === \"image\") {\n return (\n <div\n className=\"flex h-full w-full items-center justify-center bg-[var(--oh-surface)] p-4\"\n data-testid=\"file-content-viewer-image\"\n >\n <img\n src={bustedStaticUrl}\n alt={path}\n className=\"max-h-full max-w-full object-contain\"\n />\n </div>\n );\n }\n\n if (kind === \"pdf\") {\n // PDFs can carry embedded JavaScript (AcroForm, OpenAction…). Even\n // though `staticUrl` lives on the agent server origin, the PDF\n // viewer's scripting capability isn't worth the risk for a file\n // preview, so we sandbox the iframe. `allow-same-origin` lets the\n // browser's built-in PDF viewer load the underlying bytes without\n // tripping cross-origin restrictions; we omit `allow-scripts`\n // because no PDF preview we care about needs to run JS in the\n // parent's origin.\n return (\n <iframe\n title={path}\n src={bustedStaticUrl}\n sandbox=\"allow-same-origin\"\n data-testid=\"file-content-viewer-iframe\"\n className=\"h-full w-full bg-white\"\n />\n );\n }\n\n if (kind === \"binary\") {\n return <UnpreviewableFallback path={path} />;\n }\n\n // Text-like content.\n if (mimeType === \"text/html\" || HTML_LIKE_EXTS.has(getExtension(path))) {\n // Sandbox the preview iframe: `allow-same-origin` keeps the frame on\n // the workspace fileserver's origin so relative `<link href=\"…\">`,\n // `<img src=\"…\">`, etc. continue to resolve, while the absence of\n // `allow-scripts` means any `<script>` (or `onerror=…`, inline event\n // handler, …) inside the previewed file is inert. This is exactly\n // the safe-preview posture we want — users can look at their HTML\n // without it executing in the canvas's context.\n return (\n <iframe\n title={path}\n src={bustedStaticUrl}\n sandbox=\"allow-same-origin\"\n data-testid=\"file-content-viewer-iframe\"\n className=\"h-full w-full bg-white\"\n />\n );\n }\n\n if (kind === \"text\" && MARKDOWN_EXTS.has(getExtension(path))) {\n // Match the right-pane chrome color so the rich-rendered markdown\n // blends with the surrounding files tab instead of painting a stark\n // white card. We use `prose-invert` (typography plugin's dark-theme\n // variant) and then layer arbitrary CSS-variable overrides on top to\n // pin body / bold / quote text to pure white — the user specifically\n // asked for every text element (not just headings) to read as white.\n // The custom heading components in `markdown/headings.tsx` already\n // hard-code `text-white`, so headers stay white through this change.\n return (\n <div\n data-testid=\"file-content-viewer-markdown\"\n className=\"h-full w-full overflow-auto bg-[var(--oh-surface)] text-white custom-scrollbar-always\"\n >\n <div className=\"prose prose-sm prose-invert max-w-none p-6 [--tw-prose-body:#fff] [--tw-prose-bold:#fff] [--tw-prose-headings:#fff] [--tw-prose-lead:#fff] [--tw-prose-counters:#fff] [--tw-prose-quotes:#fff] [--tw-prose-quote-borders:var(--oh-border-subtle)] [--tw-prose-bullets:var(--oh-muted)] [--tw-prose-hr:var(--oh-border-subtle)] [--tw-prose-captions:var(--oh-muted)] [--tw-prose-kbd:#fff]\">\n <MarkdownRenderer\n content={text ?? \"\"}\n includeStandard\n includeHeadings\n />\n </div>\n </div>\n );\n }\n\n // Rich mode for actual source code (.ts, .py, .yaml, .css, …): there\n // is no other \"rich\" rendering to fall back to, so highlighted source\n // IS the rich view. Identical to the plain-mode treatment — keeping\n // both branches reuse `HighlightedSourceView` means the toggle has the\n // same visual identity for source files in both modes (which is the\n // honest answer: source IS rendered code).\n if (kind === \"text\" && text !== null) {\n return (\n <HighlightedSourceView\n path={path}\n text={text}\n mimeType={mimeType ?? undefined}\n />\n );\n }\n\n // Truly unknown / empty payload — show a fallback so the pane is never\n // blank.\n return <UnpreviewableFallback path={path} />;\n}\n"],"mappings":"8aAiBA,IAAM,EAAiB,IAAI,IAAI,CAAC,OAAQ,MAAO,MAAM,CAAC,CAChD,EAAgB,IAAI,IAAI,CAAC,KAAM,WAAY,MAAM,CAAC,CAKlD,EAAiD,CACrD,KAAM,aACN,IAAK,aACL,KAAM,OACN,IAAK,OACL,KAAM,QACN,IAAK,QACN,CAED,SAAS,EAAa,EAAsB,CAC1C,IAAM,EAAM,EAAK,YAAY,IAAI,CACjC,OAAO,IAAQ,GAAK,GAAK,EAAK,MAAM,EAAM,EAAE,CAAC,aAAa,CAQ5D,SAAS,EAAsB,CAAE,QAA0B,CACzD,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,EAAgB,EAAuB,EAAa,EAAK,EAC/D,OACE,EAAA,EAAA,KAAC,MAAD,CACE,UAAU,gFACV,cACE,EACI,2CACA,+CAGL,EACG,EAAE,EAAA,QAAQ,2BAA4B,CAAE,KAAM,EAAe,CAAC,CAC9D,EAAE,EAAA,QAAQ,sBAAsB,CAChC,CAAA,CAWV,SAAgB,EAAkB,CAAE,OAAM,YAAoC,CAC5E,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,EAAQ,EAAA,wBAAwB,EAAK,CAKrC,EAAkB,EAAA,4BAA6B,GAAU,EAAM,MAAM,CAE3E,GAAI,EAAM,UACR,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yFACZ,EAAE,EAAA,QAAQ,oBAAoB,CAC3B,CAAA,CAIV,GAAI,EAAM,SAAW,CAAC,EAAM,KAO1B,OACE,EAAA,EAAA,KAAC,MAAD,CACE,UAAU,gFACV,cAAY,qCAEV,EAAM,OAA6B,SACnC,EAAE,EAAA,QAAQ,iBAAiB,CACzB,CAAA,CAIV,GAAM,CAAE,OAAM,OAAM,YAAW,YAAa,EAAM,KAC5C,EAAkB,EAAA,yBAAyB,EAAW,EAAgB,CA0H5E,OApHI,IAAa,QACX,IAAS,QAAU,IAAS,MAE5B,EAAA,EAAA,KAAC,EAAA,sBAAD,CACQ,OACA,OACN,SAAU,GAAY,IAAA,GACtB,CAAA,EAGC,EAAA,EAAA,KAAC,EAAD,CAA6B,OAAQ,CAAA,CAI1C,IAAS,SAET,EAAA,EAAA,KAAC,MAAD,CACE,UAAU,4EACV,cAAY,sCAEZ,EAAA,EAAA,KAAC,MAAD,CACE,IAAK,EACL,IAAK,EACL,UAAU,uCACV,CAAA,CACE,CAAA,CAIN,IAAS,OAUT,EAAA,EAAA,KAAC,SAAD,CACE,MAAO,EACP,IAAK,EACL,QAAQ,oBACR,cAAY,6BACZ,UAAU,yBACV,CAAA,CAIF,IAAS,UACJ,EAAA,EAAA,KAAC,EAAD,CAA6B,OAAQ,CAAA,CAI1C,IAAa,aAAe,EAAe,IAAI,EAAa,EAAK,CAAC,EASlE,EAAA,EAAA,KAAC,SAAD,CACE,MAAO,EACP,IAAK,EACL,QAAQ,oBACR,cAAY,6BACZ,UAAU,yBACV,CAAA,CAIF,IAAS,QAAU,EAAc,IAAI,EAAa,EAAK,CAAC,EAUxD,EAAA,EAAA,KAAC,MAAD,CACE,cAAY,+BACZ,UAAU,kGAEV,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,uYACb,EAAA,EAAA,KAAC,EAAA,iBAAD,CACE,QAAS,GAAQ,GACjB,gBAAA,GACA,gBAAA,GACA,CAAA,CACE,CAAA,CACF,CAAA,CAUN,IAAS,QAAU,IAAS,MAE5B,EAAA,EAAA,KAAC,EAAA,sBAAD,CACQ,OACA,OACN,SAAU,GAAY,IAAA,GACtB,CAAA,EAMC,EAAA,EAAA,KAAC,EAAD,CAA6B,OAAQ,CAAA"}
@@ -14,77 +14,80 @@ var c = new Set([
14
14
  "md",
15
15
  "markdown",
16
16
  "mdx"
17
- ]);
18
- function u(e) {
17
+ ]), u = {
18
+ pptx: "PowerPoint",
19
+ ppt: "PowerPoint",
20
+ docx: "Word",
21
+ doc: "Word",
22
+ xlsx: "Excel",
23
+ xls: "Excel"
24
+ };
25
+ function d(e) {
19
26
  let t = e.lastIndexOf(".");
20
27
  return t === -1 ? "" : e.slice(t + 1).toLowerCase();
21
28
  }
22
- function d({ path: d, viewMode: f }) {
23
- let { t: p } = e("openhands"), m = a(d), h = r((e) => e.count);
24
- if (m.isLoading) return /* @__PURE__ */ s("div", {
29
+ function f({ path: n }) {
30
+ let { t: r } = e("openhands"), i = u[d(n)];
31
+ return /* @__PURE__ */ s("div", {
25
32
  className: "flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]",
26
- children: p(t.FILES$LOADING_FILES)
33
+ "data-testid": i ? "file-content-viewer-unsupported-document" : "file-content-viewer-binary-fallback",
34
+ children: i ? r(t.FILES$UNSUPPORTED_DOCUMENT, { type: i }) : r(t.FILES$BINARY_FALLBACK)
27
35
  });
28
- if (m.isError || !m.data) return /* @__PURE__ */ s("div", {
36
+ }
37
+ function p({ path: u, viewMode: p }) {
38
+ let { t: m } = e("openhands"), h = a(u), g = r((e) => e.count);
39
+ if (h.isLoading) return /* @__PURE__ */ s("div", {
29
40
  className: "flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]",
30
- "data-testid": "file-content-viewer-error",
31
- children: m.error?.message ?? p(t.FILES$LOAD_ERROR)
41
+ children: m(t.FILES$LOADING_FILES)
32
42
  });
33
- let { kind: g, text: _, staticUrl: v, mimeType: y } = m.data, b = i(v, h);
34
- return f === "plain" ? g === "text" && _ !== null ? /* @__PURE__ */ s(o, {
35
- path: d,
36
- text: _,
37
- mimeType: y ?? void 0
38
- }) : /* @__PURE__ */ s("div", {
43
+ if (h.isError || !h.data) return /* @__PURE__ */ s("div", {
39
44
  className: "flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]",
40
- "data-testid": "file-content-viewer-binary-fallback",
41
- children: p(t.FILES$BINARY_FALLBACK)
42
- }) : g === "image" ? /* @__PURE__ */ s("div", {
45
+ "data-testid": "file-content-viewer-error",
46
+ children: h.error?.message ?? m(t.FILES$LOAD_ERROR)
47
+ });
48
+ let { kind: _, text: v, staticUrl: y, mimeType: b } = h.data, x = i(y, g);
49
+ return p === "plain" ? _ === "text" && v !== null ? /* @__PURE__ */ s(o, {
50
+ path: u,
51
+ text: v,
52
+ mimeType: b ?? void 0
53
+ }) : /* @__PURE__ */ s(f, { path: u }) : _ === "image" ? /* @__PURE__ */ s("div", {
43
54
  className: "flex h-full w-full items-center justify-center bg-[var(--oh-surface)] p-4",
44
55
  "data-testid": "file-content-viewer-image",
45
56
  children: /* @__PURE__ */ s("img", {
46
- src: b,
47
- alt: d,
57
+ src: x,
58
+ alt: u,
48
59
  className: "max-h-full max-w-full object-contain"
49
60
  })
50
- }) : g === "pdf" ? /* @__PURE__ */ s("iframe", {
51
- title: d,
52
- src: b,
61
+ }) : _ === "pdf" ? /* @__PURE__ */ s("iframe", {
62
+ title: u,
63
+ src: x,
53
64
  sandbox: "allow-same-origin",
54
65
  "data-testid": "file-content-viewer-iframe",
55
66
  className: "h-full w-full bg-white"
56
- }) : g === "binary" ? /* @__PURE__ */ s("div", {
57
- className: "flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]",
58
- "data-testid": "file-content-viewer-binary-fallback",
59
- children: p(t.FILES$BINARY_FALLBACK)
60
- }) : y === "text/html" || c.has(u(d)) ? /* @__PURE__ */ s("iframe", {
61
- title: d,
62
- src: b,
67
+ }) : _ === "binary" ? /* @__PURE__ */ s(f, { path: u }) : b === "text/html" || c.has(d(u)) ? /* @__PURE__ */ s("iframe", {
68
+ title: u,
69
+ src: x,
63
70
  sandbox: "allow-same-origin",
64
71
  "data-testid": "file-content-viewer-iframe",
65
72
  className: "h-full w-full bg-white"
66
- }) : g === "text" && l.has(u(d)) ? /* @__PURE__ */ s("div", {
73
+ }) : _ === "text" && l.has(d(u)) ? /* @__PURE__ */ s("div", {
67
74
  "data-testid": "file-content-viewer-markdown",
68
75
  className: "h-full w-full overflow-auto bg-[var(--oh-surface)] text-white custom-scrollbar-always",
69
76
  children: /* @__PURE__ */ s("div", {
70
77
  className: "prose prose-sm prose-invert max-w-none p-6 [--tw-prose-body:#fff] [--tw-prose-bold:#fff] [--tw-prose-headings:#fff] [--tw-prose-lead:#fff] [--tw-prose-counters:#fff] [--tw-prose-quotes:#fff] [--tw-prose-quote-borders:var(--oh-border-subtle)] [--tw-prose-bullets:var(--oh-muted)] [--tw-prose-hr:var(--oh-border-subtle)] [--tw-prose-captions:var(--oh-muted)] [--tw-prose-kbd:#fff]",
71
78
  children: /* @__PURE__ */ s(n, {
72
- content: _ ?? "",
79
+ content: v ?? "",
73
80
  includeStandard: !0,
74
81
  includeHeadings: !0
75
82
  })
76
83
  })
77
- }) : g === "text" && _ !== null ? /* @__PURE__ */ s(o, {
78
- path: d,
79
- text: _,
80
- mimeType: y ?? void 0
81
- }) : /* @__PURE__ */ s("div", {
82
- className: "flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]",
83
- "data-testid": "file-content-viewer-binary-fallback",
84
- children: p(t.FILES$BINARY_FALLBACK)
85
- });
84
+ }) : _ === "text" && v !== null ? /* @__PURE__ */ s(o, {
85
+ path: u,
86
+ text: v,
87
+ mimeType: b ?? void 0
88
+ }) : /* @__PURE__ */ s(f, { path: u });
86
89
  }
87
90
  //#endregion
88
- export { d as FileContentViewer };
91
+ export { p as FileContentViewer };
89
92
 
90
93
  //# sourceMappingURL=file-content-viewer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-content-viewer.js","names":[],"sources":["../../../../src/components/features/files-tab/file-content-viewer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\n\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useWorkspaceFileContent } from \"#/hooks/query/use-workspace-file-content\";\nimport {\n useWorkspaceMutationCounter,\n withWorkspaceCacheBuster,\n} from \"#/stores/use-workspace-mutation-counter\";\nimport { MarkdownRenderer } from \"#/components/features/markdown/markdown-renderer\";\nimport { HighlightedSourceView } from \"./highlighted-source-view\";\nimport type { ViewMode } from \"./view-mode\";\n\ninterface FileContentViewerProps {\n path: string;\n viewMode: ViewMode;\n}\n\nconst HTML_LIKE_EXTS = new Set([\"html\", \"htm\", \"svg\"]);\nconst MARKDOWN_EXTS = new Set([\"md\", \"markdown\", \"mdx\"]);\n\nfunction getExtension(path: string): string {\n const idx = path.lastIndexOf(\".\");\n return idx === -1 ? \"\" : path.slice(idx + 1).toLowerCase();\n}\n\n/**\n * Renders the contents of a single workspace file. In `rich` mode we point\n * an iframe / <img> straight at the agent server's static workspace\n * fileserver for HTML / SVG / images / PDFs, so relative asset references\n * load naturally. In `plain` mode we always show the raw bytes as text (or\n * a fallback message for binaries).\n */\nexport function FileContentViewer({ path, viewMode }: FileContentViewerProps) {\n const { t } = useTranslation(\"openhands\");\n const query = useWorkspaceFileContent(path);\n // Subscribe to the workspace mutation counter so the iframe / <img> src\n // changes after every agent-side edit, forcing a fresh fetch even when\n // the *path* hasn't moved (e.g. agent rewrote `style.css` referenced by\n // the currently-displayed `index.html`).\n const mutationCounter = useWorkspaceMutationCounter((state) => state.count);\n\n if (query.isLoading) {\n return (\n <div className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\">\n {t(I18nKey.FILES$LOADING_FILES)}\n </div>\n );\n }\n\n if (query.isError || !query.data) {\n // Show a load-error message rather than the binary-fallback string —\n // these are completely different failure modes (couldn't even fetch\n // the file vs. fetched fine but the bytes aren't previewable) and\n // mixing them up hides real backend failures behind a misleading\n // \"Binary file\" label. Prefer the underlying error's own message when\n // we have one; fall back to the generic translated string otherwise.\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-error\"\n >\n {(query.error as Error | undefined)?.message ??\n t(I18nKey.FILES$LOAD_ERROR)}\n </div>\n );\n }\n\n const { kind, text, staticUrl, mimeType } = query.data;\n const bustedStaticUrl = withWorkspaceCacheBuster(staticUrl, mutationCounter);\n\n // ----- Plain mode: raw source bytes, syntax-highlighted when we can\n // recognize the grammar (falls through to a `<pre>` otherwise). This\n // includes \"plain\" view of markdown / HTML, where the point is to see\n // the markup behind the rich preview.\n if (viewMode === \"plain\") {\n if (kind === \"text\" && text !== null) {\n return (\n <HighlightedSourceView\n path={path}\n text={text}\n mimeType={mimeType ?? undefined}\n />\n );\n }\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-binary-fallback\"\n >\n {t(I18nKey.FILES$BINARY_FALLBACK)}\n </div>\n );\n }\n\n // ----- Rich mode: render HTML, markdown, images, PDFs from staticUrl. ----\n if (kind === \"image\") {\n return (\n <div\n className=\"flex h-full w-full items-center justify-center bg-[var(--oh-surface)] p-4\"\n data-testid=\"file-content-viewer-image\"\n >\n <img\n src={bustedStaticUrl}\n alt={path}\n className=\"max-h-full max-w-full object-contain\"\n />\n </div>\n );\n }\n\n if (kind === \"pdf\") {\n // PDFs can carry embedded JavaScript (AcroForm, OpenAction…). Even\n // though `staticUrl` lives on the agent server origin, the PDF\n // viewer's scripting capability isn't worth the risk for a file\n // preview, so we sandbox the iframe. `allow-same-origin` lets the\n // browser's built-in PDF viewer load the underlying bytes without\n // tripping cross-origin restrictions; we omit `allow-scripts`\n // because no PDF preview we care about needs to run JS in the\n // parent's origin.\n return (\n <iframe\n title={path}\n src={bustedStaticUrl}\n sandbox=\"allow-same-origin\"\n data-testid=\"file-content-viewer-iframe\"\n className=\"h-full w-full bg-white\"\n />\n );\n }\n\n if (kind === \"binary\") {\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-binary-fallback\"\n >\n {t(I18nKey.FILES$BINARY_FALLBACK)}\n </div>\n );\n }\n\n // Text-like content.\n if (mimeType === \"text/html\" || HTML_LIKE_EXTS.has(getExtension(path))) {\n // Sandbox the preview iframe: `allow-same-origin` keeps the frame on\n // the workspace fileserver's origin so relative `<link href=\"…\">`,\n // `<img src=\"…\">`, etc. continue to resolve, while the absence of\n // `allow-scripts` means any `<script>` (or `onerror=…`, inline event\n // handler, …) inside the previewed file is inert. This is exactly\n // the safe-preview posture we want — users can look at their HTML\n // without it executing in the canvas's context.\n return (\n <iframe\n title={path}\n src={bustedStaticUrl}\n sandbox=\"allow-same-origin\"\n data-testid=\"file-content-viewer-iframe\"\n className=\"h-full w-full bg-white\"\n />\n );\n }\n\n if (kind === \"text\" && MARKDOWN_EXTS.has(getExtension(path))) {\n // Match the right-pane chrome color so the rich-rendered markdown\n // blends with the surrounding files tab instead of painting a stark\n // white card. We use `prose-invert` (typography plugin's dark-theme\n // variant) and then layer arbitrary CSS-variable overrides on top to\n // pin body / bold / quote text to pure white — the user specifically\n // asked for every text element (not just headings) to read as white.\n // The custom heading components in `markdown/headings.tsx` already\n // hard-code `text-white`, so headers stay white through this change.\n return (\n <div\n data-testid=\"file-content-viewer-markdown\"\n className=\"h-full w-full overflow-auto bg-[var(--oh-surface)] text-white custom-scrollbar-always\"\n >\n <div className=\"prose prose-sm prose-invert max-w-none p-6 [--tw-prose-body:#fff] [--tw-prose-bold:#fff] [--tw-prose-headings:#fff] [--tw-prose-lead:#fff] [--tw-prose-counters:#fff] [--tw-prose-quotes:#fff] [--tw-prose-quote-borders:var(--oh-border-subtle)] [--tw-prose-bullets:var(--oh-muted)] [--tw-prose-hr:var(--oh-border-subtle)] [--tw-prose-captions:var(--oh-muted)] [--tw-prose-kbd:#fff]\">\n <MarkdownRenderer\n content={text ?? \"\"}\n includeStandard\n includeHeadings\n />\n </div>\n </div>\n );\n }\n\n // Rich mode for actual source code (.ts, .py, .yaml, .css, …): there\n // is no other \"rich\" rendering to fall back to, so highlighted source\n // IS the rich view. Identical to the plain-mode treatment — keeping\n // both branches reuse `HighlightedSourceView` means the toggle has the\n // same visual identity for source files in both modes (which is the\n // honest answer: source IS rendered code).\n if (kind === \"text\" && text !== null) {\n return (\n <HighlightedSourceView\n path={path}\n text={text}\n mimeType={mimeType ?? undefined}\n />\n );\n }\n\n // Truly unknown / empty payload — show a fallback so the pane is never\n // blank.\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-binary-fallback\"\n >\n {t(I18nKey.FILES$BINARY_FALLBACK)}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAiBA,IAAM,IAAiB,IAAI,IAAI;CAAC;CAAQ;CAAO;CAAM,CAAC,EAChD,IAAgB,IAAI,IAAI;CAAC;CAAM;CAAY;CAAM,CAAC;AAExD,SAAS,EAAa,GAAsB;CAC1C,IAAM,IAAM,EAAK,YAAY,IAAI;AACjC,QAAO,MAAQ,KAAK,KAAK,EAAK,MAAM,IAAM,EAAE,CAAC,aAAa;;AAU5D,SAAgB,EAAkB,EAAE,SAAM,eAAoC;CAC5E,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,IAAQ,EAAwB,EAAK,EAKrC,IAAkB,GAA6B,MAAU,EAAM,MAAM;AAE3E,KAAI,EAAM,UACR,QACE,kBAAC,OAAD;EAAK,WAAU;YACZ,EAAE,EAAQ,oBAAoB;EAC3B,CAAA;AAIV,KAAI,EAAM,WAAW,CAAC,EAAM,KAO1B,QACE,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;YAEV,EAAM,OAA6B,WACnC,EAAE,EAAQ,iBAAiB;EACzB,CAAA;CAIV,IAAM,EAAE,SAAM,SAAM,cAAW,gBAAa,EAAM,MAC5C,IAAkB,EAAyB,GAAW,EAAgB;AAwI5E,QAlII,MAAa,UACX,MAAS,UAAU,MAAS,OAE5B,kBAAC,GAAD;EACQ;EACA;EACN,UAAU,KAAY,KAAA;EACtB,CAAA,GAIJ,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;YAEX,EAAE,EAAQ,sBAAsB;EAC7B,CAAA,GAKN,MAAS,UAET,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;YAEZ,kBAAC,OAAD;GACE,KAAK;GACL,KAAK;GACL,WAAU;GACV,CAAA;EACE,CAAA,GAIN,MAAS,QAUT,kBAAC,UAAD;EACE,OAAO;EACP,KAAK;EACL,SAAQ;EACR,eAAY;EACZ,WAAU;EACV,CAAA,GAIF,MAAS,WAET,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;YAEX,EAAE,EAAQ,sBAAsB;EAC7B,CAAA,GAKN,MAAa,eAAe,EAAe,IAAI,EAAa,EAAK,CAAC,GASlE,kBAAC,UAAD;EACE,OAAO;EACP,KAAK;EACL,SAAQ;EACR,eAAY;EACZ,WAAU;EACV,CAAA,GAIF,MAAS,UAAU,EAAc,IAAI,EAAa,EAAK,CAAC,GAUxD,kBAAC,OAAD;EACE,eAAY;EACZ,WAAU;YAEV,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD;IACE,SAAS,KAAQ;IACjB,iBAAA;IACA,iBAAA;IACA,CAAA;GACE,CAAA;EACF,CAAA,GAUN,MAAS,UAAU,MAAS,OAE5B,kBAAC,GAAD;EACQ;EACA;EACN,UAAU,KAAY,KAAA;EACtB,CAAA,GAOJ,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;YAEX,EAAE,EAAQ,sBAAsB;EAC7B,CAAA"}
1
+ {"version":3,"file":"file-content-viewer.js","names":[],"sources":["../../../../src/components/features/files-tab/file-content-viewer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\n\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useWorkspaceFileContent } from \"#/hooks/query/use-workspace-file-content\";\nimport {\n useWorkspaceMutationCounter,\n withWorkspaceCacheBuster,\n} from \"#/stores/use-workspace-mutation-counter\";\nimport { MarkdownRenderer } from \"#/components/features/markdown/markdown-renderer\";\nimport { HighlightedSourceView } from \"./highlighted-source-view\";\nimport type { ViewMode } from \"./view-mode\";\n\ninterface FileContentViewerProps {\n path: string;\n viewMode: ViewMode;\n}\n\nconst HTML_LIKE_EXTS = new Set([\"html\", \"htm\", \"svg\"]);\nconst MARKDOWN_EXTS = new Set([\"md\", \"markdown\", \"mdx\"]);\n\n// Office/document formats we can't preview inline. The label doubles as the\n// allow-list (a present entry => Office doc) and feeds a clear, format-named\n// \"no preview\" message instead of the generic binary fallback.\nconst OFFICE_DOCUMENT_LABELS: Record<string, string> = {\n pptx: \"PowerPoint\",\n ppt: \"PowerPoint\",\n docx: \"Word\",\n doc: \"Word\",\n xlsx: \"Excel\",\n xls: \"Excel\",\n};\n\nfunction getExtension(path: string): string {\n const idx = path.lastIndexOf(\".\");\n return idx === -1 ? \"\" : path.slice(idx + 1).toLowerCase();\n}\n\n/**\n * Fallback shown when a file's bytes aren't previewable. Office documents\n * (.pptx / .docx / .xlsx …) get a clear, format-named message; every other\n * binary keeps the generic \"binary file\" string so the pane is never blank.\n */\nfunction UnpreviewableFallback({ path }: { path: string }) {\n const { t } = useTranslation(\"openhands\");\n const documentLabel = OFFICE_DOCUMENT_LABELS[getExtension(path)];\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid={\n documentLabel\n ? \"file-content-viewer-unsupported-document\"\n : \"file-content-viewer-binary-fallback\"\n }\n >\n {documentLabel\n ? t(I18nKey.FILES$UNSUPPORTED_DOCUMENT, { type: documentLabel })\n : t(I18nKey.FILES$BINARY_FALLBACK)}\n </div>\n );\n}\n\n/**\n * Renders the contents of a single workspace file. In `rich` mode we point\n * an iframe / <img> straight at the agent server's static workspace\n * fileserver for HTML / SVG / images / PDFs, so relative asset references\n * load naturally. In `plain` mode we always show the raw bytes as text (or\n * a fallback message for binaries).\n */\nexport function FileContentViewer({ path, viewMode }: FileContentViewerProps) {\n const { t } = useTranslation(\"openhands\");\n const query = useWorkspaceFileContent(path);\n // Subscribe to the workspace mutation counter so the iframe / <img> src\n // changes after every agent-side edit, forcing a fresh fetch even when\n // the *path* hasn't moved (e.g. agent rewrote `style.css` referenced by\n // the currently-displayed `index.html`).\n const mutationCounter = useWorkspaceMutationCounter((state) => state.count);\n\n if (query.isLoading) {\n return (\n <div className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\">\n {t(I18nKey.FILES$LOADING_FILES)}\n </div>\n );\n }\n\n if (query.isError || !query.data) {\n // Show a load-error message rather than the binary-fallback string —\n // these are completely different failure modes (couldn't even fetch\n // the file vs. fetched fine but the bytes aren't previewable) and\n // mixing them up hides real backend failures behind a misleading\n // \"Binary file\" label. Prefer the underlying error's own message when\n // we have one; fall back to the generic translated string otherwise.\n return (\n <div\n className=\"flex h-full w-full items-center justify-center text-sm text-[var(--oh-muted)]\"\n data-testid=\"file-content-viewer-error\"\n >\n {(query.error as Error | undefined)?.message ??\n t(I18nKey.FILES$LOAD_ERROR)}\n </div>\n );\n }\n\n const { kind, text, staticUrl, mimeType } = query.data;\n const bustedStaticUrl = withWorkspaceCacheBuster(staticUrl, mutationCounter);\n\n // ----- Plain mode: raw source bytes, syntax-highlighted when we can\n // recognize the grammar (falls through to a `<pre>` otherwise). This\n // includes \"plain\" view of markdown / HTML, where the point is to see\n // the markup behind the rich preview.\n if (viewMode === \"plain\") {\n if (kind === \"text\" && text !== null) {\n return (\n <HighlightedSourceView\n path={path}\n text={text}\n mimeType={mimeType ?? undefined}\n />\n );\n }\n return <UnpreviewableFallback path={path} />;\n }\n\n // ----- Rich mode: render HTML, markdown, images, PDFs from staticUrl. ----\n if (kind === \"image\") {\n return (\n <div\n className=\"flex h-full w-full items-center justify-center bg-[var(--oh-surface)] p-4\"\n data-testid=\"file-content-viewer-image\"\n >\n <img\n src={bustedStaticUrl}\n alt={path}\n className=\"max-h-full max-w-full object-contain\"\n />\n </div>\n );\n }\n\n if (kind === \"pdf\") {\n // PDFs can carry embedded JavaScript (AcroForm, OpenAction…). Even\n // though `staticUrl` lives on the agent server origin, the PDF\n // viewer's scripting capability isn't worth the risk for a file\n // preview, so we sandbox the iframe. `allow-same-origin` lets the\n // browser's built-in PDF viewer load the underlying bytes without\n // tripping cross-origin restrictions; we omit `allow-scripts`\n // because no PDF preview we care about needs to run JS in the\n // parent's origin.\n return (\n <iframe\n title={path}\n src={bustedStaticUrl}\n sandbox=\"allow-same-origin\"\n data-testid=\"file-content-viewer-iframe\"\n className=\"h-full w-full bg-white\"\n />\n );\n }\n\n if (kind === \"binary\") {\n return <UnpreviewableFallback path={path} />;\n }\n\n // Text-like content.\n if (mimeType === \"text/html\" || HTML_LIKE_EXTS.has(getExtension(path))) {\n // Sandbox the preview iframe: `allow-same-origin` keeps the frame on\n // the workspace fileserver's origin so relative `<link href=\"…\">`,\n // `<img src=\"…\">`, etc. continue to resolve, while the absence of\n // `allow-scripts` means any `<script>` (or `onerror=…`, inline event\n // handler, …) inside the previewed file is inert. This is exactly\n // the safe-preview posture we want — users can look at their HTML\n // without it executing in the canvas's context.\n return (\n <iframe\n title={path}\n src={bustedStaticUrl}\n sandbox=\"allow-same-origin\"\n data-testid=\"file-content-viewer-iframe\"\n className=\"h-full w-full bg-white\"\n />\n );\n }\n\n if (kind === \"text\" && MARKDOWN_EXTS.has(getExtension(path))) {\n // Match the right-pane chrome color so the rich-rendered markdown\n // blends with the surrounding files tab instead of painting a stark\n // white card. We use `prose-invert` (typography plugin's dark-theme\n // variant) and then layer arbitrary CSS-variable overrides on top to\n // pin body / bold / quote text to pure white — the user specifically\n // asked for every text element (not just headings) to read as white.\n // The custom heading components in `markdown/headings.tsx` already\n // hard-code `text-white`, so headers stay white through this change.\n return (\n <div\n data-testid=\"file-content-viewer-markdown\"\n className=\"h-full w-full overflow-auto bg-[var(--oh-surface)] text-white custom-scrollbar-always\"\n >\n <div className=\"prose prose-sm prose-invert max-w-none p-6 [--tw-prose-body:#fff] [--tw-prose-bold:#fff] [--tw-prose-headings:#fff] [--tw-prose-lead:#fff] [--tw-prose-counters:#fff] [--tw-prose-quotes:#fff] [--tw-prose-quote-borders:var(--oh-border-subtle)] [--tw-prose-bullets:var(--oh-muted)] [--tw-prose-hr:var(--oh-border-subtle)] [--tw-prose-captions:var(--oh-muted)] [--tw-prose-kbd:#fff]\">\n <MarkdownRenderer\n content={text ?? \"\"}\n includeStandard\n includeHeadings\n />\n </div>\n </div>\n );\n }\n\n // Rich mode for actual source code (.ts, .py, .yaml, .css, …): there\n // is no other \"rich\" rendering to fall back to, so highlighted source\n // IS the rich view. Identical to the plain-mode treatment — keeping\n // both branches reuse `HighlightedSourceView` means the toggle has the\n // same visual identity for source files in both modes (which is the\n // honest answer: source IS rendered code).\n if (kind === \"text\" && text !== null) {\n return (\n <HighlightedSourceView\n path={path}\n text={text}\n mimeType={mimeType ?? undefined}\n />\n );\n }\n\n // Truly unknown / empty payload — show a fallback so the pane is never\n // blank.\n return <UnpreviewableFallback path={path} />;\n}\n"],"mappings":";;;;;;;;AAiBA,IAAM,IAAiB,IAAI,IAAI;CAAC;CAAQ;CAAO;CAAM,CAAC,EAChD,IAAgB,IAAI,IAAI;CAAC;CAAM;CAAY;CAAM,CAAC,EAKlD,IAAiD;CACrD,MAAM;CACN,KAAK;CACL,MAAM;CACN,KAAK;CACL,MAAM;CACN,KAAK;CACN;AAED,SAAS,EAAa,GAAsB;CAC1C,IAAM,IAAM,EAAK,YAAY,IAAI;AACjC,QAAO,MAAQ,KAAK,KAAK,EAAK,MAAM,IAAM,EAAE,CAAC,aAAa;;AAQ5D,SAAS,EAAsB,EAAE,WAA0B;CACzD,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,IAAgB,EAAuB,EAAa,EAAK;AAC/D,QACE,kBAAC,OAAD;EACE,WAAU;EACV,eACE,IACI,6CACA;YAGL,IACG,EAAE,EAAQ,4BAA4B,EAAE,MAAM,GAAe,CAAC,GAC9D,EAAE,EAAQ,sBAAsB;EAChC,CAAA;;AAWV,SAAgB,EAAkB,EAAE,SAAM,eAAoC;CAC5E,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,IAAQ,EAAwB,EAAK,EAKrC,IAAkB,GAA6B,MAAU,EAAM,MAAM;AAE3E,KAAI,EAAM,UACR,QACE,kBAAC,OAAD;EAAK,WAAU;YACZ,EAAE,EAAQ,oBAAoB;EAC3B,CAAA;AAIV,KAAI,EAAM,WAAW,CAAC,EAAM,KAO1B,QACE,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;YAEV,EAAM,OAA6B,WACnC,EAAE,EAAQ,iBAAiB;EACzB,CAAA;CAIV,IAAM,EAAE,SAAM,SAAM,cAAW,gBAAa,EAAM,MAC5C,IAAkB,EAAyB,GAAW,EAAgB;AA0H5E,QApHI,MAAa,UACX,MAAS,UAAU,MAAS,OAE5B,kBAAC,GAAD;EACQ;EACA;EACN,UAAU,KAAY,KAAA;EACtB,CAAA,GAGC,kBAAC,GAAD,EAA6B,SAAQ,CAAA,GAI1C,MAAS,UAET,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;YAEZ,kBAAC,OAAD;GACE,KAAK;GACL,KAAK;GACL,WAAU;GACV,CAAA;EACE,CAAA,GAIN,MAAS,QAUT,kBAAC,UAAD;EACE,OAAO;EACP,KAAK;EACL,SAAQ;EACR,eAAY;EACZ,WAAU;EACV,CAAA,GAIF,MAAS,WACJ,kBAAC,GAAD,EAA6B,SAAQ,CAAA,GAI1C,MAAa,eAAe,EAAe,IAAI,EAAa,EAAK,CAAC,GASlE,kBAAC,UAAD;EACE,OAAO;EACP,KAAK;EACL,SAAQ;EACR,eAAY;EACZ,WAAU;EACV,CAAA,GAIF,MAAS,UAAU,EAAc,IAAI,EAAa,EAAK,CAAC,GAUxD,kBAAC,OAAD;EACE,eAAY;EACZ,WAAU;YAEV,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD;IACE,SAAS,KAAQ;IACjB,iBAAA;IACA,iBAAA;IACA,CAAA;GACE,CAAA;EACF,CAAA,GAUN,MAAS,UAAU,MAAS,OAE5B,kBAAC,GAAD;EACQ;EACA;EACN,UAAU,KAAY,KAAA;EACtB,CAAA,GAMC,kBAAC,GAAD,EAA6B,SAAQ,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Warns the user on the home screen when the active agent has no usable LLM —
3
+ * most notably after they skip onboarding, which persists no settings. Offers
4
+ * a single action that routes to LLM settings so the failure is communicated
5
+ * up front instead of surfacing only when a conversation attempt errors out.
6
+ *
7
+ * Renders nothing while settings load (avoids a flash) or once the LLM is
8
+ * configured; the settings query refetches after a key is saved, so the banner
9
+ * unmounts on its own.
10
+ */
11
+ export declare function LlmNotConfiguredBanner(): import("react/jsx-runtime").JSX.Element | null;
@@ -1,2 +1,2 @@
1
- const e=require(`../../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../../utils/utils.cjs`);let n=require(`react`);n=e.__toESM(n,1);let r=require(`react/jsx-runtime`);function i({item:e,index:n,isSelected:i,getItemProps:a,getDisplayText:o,getItemKey:s,isProviderDropdown:c=!1,renderIcon:l,itemClassName:u}){return(0,r.jsx)(`li`,{...a({index:n,item:e,className:t.cn(c?`px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center`:`px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5`,`text-white focus:outline-none font-normal`,{"bg-[var(--oh-interactive-selected)] text-white":i,"hover:bg-[var(--oh-interactive-hover)]":!i},u)}),children:(0,r.jsxs)(`div`,{className:`flex items-center gap-2`,children:[l?.(e),(0,r.jsx)(`span`,{className:`font-normal`,children:o(e)})]})},s(e))}exports.DropdownItem=i;
1
+ const e=require(`../../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../../utils/utils.cjs`),n=require(`../../../../utils/dropdown-classes.cjs`);let r=require(`react`);r=e.__toESM(r,1);let i=require(`react/jsx-runtime`);function a({item:e,index:r,isSelected:a,getItemProps:o,getDisplayText:s,getItemKey:c,isProviderDropdown:l=!1,renderIcon:u,itemClassName:d}){return(0,i.jsx)(`li`,{...o({index:r,item:e,className:t.cn(l?`group px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center`:`group px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5`,`text-white focus:outline-none font-normal`,n.dropdownInstantColorClassName,{"bg-[var(--oh-interactive-selected)] text-white":a,"hover:bg-[var(--oh-interactive-hover)]":!a},d)}),children:(0,i.jsxs)(`div`,{className:t.cn(`flex items-center`,n.dropdownMenuRowGapClassName),children:[u?(0,i.jsx)(`span`,{className:n.dropdownMenuRowIconWrapperClassName,children:u(e)}):null,(0,i.jsx)(`span`,{className:`font-normal`,children:s(e)})]})},c(e))}exports.DropdownItem=a;
2
2
  //# sourceMappingURL=dropdown-item.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-item.cjs","names":[],"sources":["../../../../../src/components/features/home/shared/dropdown-item.tsx"],"sourcesContent":["import React from \"react\";\nimport { cn } from \"#/utils/utils\";\n\ninterface DropdownItemProps<T> {\n item: T;\n index: number;\n isSelected: boolean;\n getItemProps: <Options>(options: any & Options) => any; // eslint-disable-line @typescript-eslint/no-explicit-any\n getDisplayText: (item: T) => string;\n getItemKey: (item: T) => string;\n isProviderDropdown?: boolean;\n renderIcon?: (item: T) => React.ReactNode;\n itemClassName?: string;\n}\n\nexport function DropdownItem<T>({\n item,\n index,\n isSelected,\n getItemProps,\n getDisplayText,\n getItemKey,\n isProviderDropdown = false,\n renderIcon,\n itemClassName,\n}: DropdownItemProps<T>) {\n const itemProps = getItemProps({\n index,\n item,\n className: cn(\n isProviderDropdown\n ? \"px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center\"\n : \"px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5\",\n \"text-white focus:outline-none font-normal\",\n {\n \"bg-[var(--oh-interactive-selected)] text-white\": isSelected,\n \"hover:bg-[var(--oh-interactive-hover)]\": !isSelected,\n },\n itemClassName,\n ),\n });\n\n return (\n <li key={getItemKey(item)} {...itemProps}>\n <div className=\"flex items-center gap-2\">\n {renderIcon?.(item)}\n <span className=\"font-normal\">{getDisplayText(item)}</span>\n </div>\n </li>\n );\n}\n"],"mappings":"kLAeA,SAAgB,EAAgB,CAC9B,OACA,QACA,aACA,eACA,iBACA,aACA,qBAAqB,GACrB,aACA,iBACuB,CAiBvB,OACE,EAAA,EAAA,KAAC,KAAD,CAA2B,GAjBX,EAAa,CAC7B,QACA,OACA,UAAW,EAAA,GACT,EACI,8EACA,0DACJ,4CACA,CACE,iDAAkD,EAClD,yCAA0C,CAAC,EAC5C,CACD,EACD,CACF,CAGgC,WAC7B,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mCAAf,CACG,IAAa,EAAK,EACnB,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,uBAAe,EAAe,EAAK,CAAQ,CAAA,CACvD,GACH,CALI,EAAW,EAAK,CAKpB"}
1
+ {"version":3,"file":"dropdown-item.cjs","names":[],"sources":["../../../../../src/components/features/home/shared/dropdown-item.tsx"],"sourcesContent":["import React from \"react\";\nimport { cn } from \"#/utils/utils\";\nimport {\n dropdownInstantColorClassName,\n dropdownMenuRowGapClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\n\ninterface DropdownItemProps<T> {\n item: T;\n index: number;\n isSelected: boolean;\n getItemProps: <Options>(options: any & Options) => any; // eslint-disable-line @typescript-eslint/no-explicit-any\n getDisplayText: (item: T) => string;\n getItemKey: (item: T) => string;\n isProviderDropdown?: boolean;\n renderIcon?: (item: T) => React.ReactNode;\n itemClassName?: string;\n}\n\nexport function DropdownItem<T>({\n item,\n index,\n isSelected,\n getItemProps,\n getDisplayText,\n getItemKey,\n isProviderDropdown = false,\n renderIcon,\n itemClassName,\n}: DropdownItemProps<T>) {\n const itemProps = getItemProps({\n index,\n item,\n className: cn(\n isProviderDropdown\n ? \"group px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center\"\n : \"group px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5\",\n \"text-white focus:outline-none font-normal\",\n dropdownInstantColorClassName,\n {\n \"bg-[var(--oh-interactive-selected)] text-white\": isSelected,\n \"hover:bg-[var(--oh-interactive-hover)]\": !isSelected,\n },\n itemClassName,\n ),\n });\n\n return (\n <li key={getItemKey(item)} {...itemProps}>\n <div className={cn(\"flex items-center\", dropdownMenuRowGapClassName)}>\n {renderIcon ? (\n <span className={dropdownMenuRowIconWrapperClassName}>\n {renderIcon(item)}\n </span>\n ) : null}\n <span className=\"font-normal\">{getDisplayText(item)}</span>\n </div>\n </li>\n );\n}\n"],"mappings":"sOAoBA,SAAgB,EAAgB,CAC9B,OACA,QACA,aACA,eACA,iBACA,aACA,qBAAqB,GACrB,aACA,iBACuB,CAkBvB,OACE,EAAA,EAAA,KAAC,KAAD,CAA2B,GAlBX,EAAa,CAC7B,QACA,OACA,UAAW,EAAA,GACT,EACI,oFACA,gEACJ,4CACA,EAAA,8BACA,CACE,iDAAkD,EAClD,yCAA0C,CAAC,EAC5C,CACD,EACD,CACF,CAGgC,WAC7B,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAA,GAAG,oBAAqB,EAAA,4BAA4B,UAApE,CACG,GACC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,6CACd,EAAW,EAAK,CACZ,CAAA,CACL,MACJ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,uBAAe,EAAe,EAAK,CAAQ,CAAA,CACvD,GACH,CATI,EAAW,EAAK,CASpB"}
@@ -1,27 +1,31 @@
1
1
  import { cn as e } from "../../../../utils/utils.js";
2
+ import { dropdownInstantColorClassName as t, dropdownMenuRowGapClassName as n, dropdownMenuRowIconWrapperClassName as r } from "../../../../utils/dropdown-classes.js";
2
3
  import "react";
3
- import { jsx as t, jsxs as n } from "react/jsx-runtime";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
4
5
  //#region src/components/features/home/shared/dropdown-item.tsx
5
- function r({ item: r, index: i, isSelected: a, getItemProps: o, getDisplayText: s, getItemKey: c, isProviderDropdown: l = !1, renderIcon: u, itemClassName: d }) {
6
- return /* @__PURE__ */ t("li", {
7
- ...o({
8
- index: i,
9
- item: r,
10
- className: e(l ? "px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center" : "px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5", "text-white focus:outline-none font-normal", {
11
- "bg-[var(--oh-interactive-selected)] text-white": a,
12
- "hover:bg-[var(--oh-interactive-hover)]": !a
13
- }, d)
6
+ function o({ item: o, index: s, isSelected: c, getItemProps: l, getDisplayText: u, getItemKey: d, isProviderDropdown: f = !1, renderIcon: p, itemClassName: m }) {
7
+ return /* @__PURE__ */ i("li", {
8
+ ...l({
9
+ index: s,
10
+ item: o,
11
+ className: e(f ? "group px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center" : "group px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5", "text-white focus:outline-none font-normal", t, {
12
+ "bg-[var(--oh-interactive-selected)] text-white": c,
13
+ "hover:bg-[var(--oh-interactive-hover)]": !c
14
+ }, m)
14
15
  }),
15
- children: /* @__PURE__ */ n("div", {
16
- className: "flex items-center gap-2",
17
- children: [u?.(r), /* @__PURE__ */ t("span", {
16
+ children: /* @__PURE__ */ a("div", {
17
+ className: e("flex items-center", n),
18
+ children: [p ? /* @__PURE__ */ i("span", {
19
+ className: r,
20
+ children: p(o)
21
+ }) : null, /* @__PURE__ */ i("span", {
18
22
  className: "font-normal",
19
- children: s(r)
23
+ children: u(o)
20
24
  })]
21
25
  })
22
- }, c(r));
26
+ }, d(o));
23
27
  }
24
28
  //#endregion
25
- export { r as DropdownItem };
29
+ export { o as DropdownItem };
26
30
 
27
31
  //# sourceMappingURL=dropdown-item.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-item.js","names":[],"sources":["../../../../../src/components/features/home/shared/dropdown-item.tsx"],"sourcesContent":["import React from \"react\";\nimport { cn } from \"#/utils/utils\";\n\ninterface DropdownItemProps<T> {\n item: T;\n index: number;\n isSelected: boolean;\n getItemProps: <Options>(options: any & Options) => any; // eslint-disable-line @typescript-eslint/no-explicit-any\n getDisplayText: (item: T) => string;\n getItemKey: (item: T) => string;\n isProviderDropdown?: boolean;\n renderIcon?: (item: T) => React.ReactNode;\n itemClassName?: string;\n}\n\nexport function DropdownItem<T>({\n item,\n index,\n isSelected,\n getItemProps,\n getDisplayText,\n getItemKey,\n isProviderDropdown = false,\n renderIcon,\n itemClassName,\n}: DropdownItemProps<T>) {\n const itemProps = getItemProps({\n index,\n item,\n className: cn(\n isProviderDropdown\n ? \"px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center\"\n : \"px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5\",\n \"text-white focus:outline-none font-normal\",\n {\n \"bg-[var(--oh-interactive-selected)] text-white\": isSelected,\n \"hover:bg-[var(--oh-interactive-hover)]\": !isSelected,\n },\n itemClassName,\n ),\n });\n\n return (\n <li key={getItemKey(item)} {...itemProps}>\n <div className=\"flex items-center gap-2\">\n {renderIcon?.(item)}\n <span className=\"font-normal\">{getDisplayText(item)}</span>\n </div>\n </li>\n );\n}\n"],"mappings":";;;;AAeA,SAAgB,EAAgB,EAC9B,SACA,UACA,eACA,iBACA,mBACA,eACA,wBAAqB,IACrB,eACA,oBACuB;AAiBvB,QACE,kBAAC,MAAD;EAA2B,GAjBX,EAAa;GAC7B;GACA;GACA,WAAW,EACT,IACI,gFACA,2DACJ,6CACA;IACE,kDAAkD;IAClD,0CAA0C,CAAC;IAC5C,EACD,EACD;GACF,CAGgC;YAC7B,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,IAAa,EAAK,EACnB,kBAAC,QAAD;IAAM,WAAU;cAAe,EAAe,EAAK;IAAQ,CAAA,CACvD;;EACH,EALI,EAAW,EAAK,CAKpB"}
1
+ {"version":3,"file":"dropdown-item.js","names":[],"sources":["../../../../../src/components/features/home/shared/dropdown-item.tsx"],"sourcesContent":["import React from \"react\";\nimport { cn } from \"#/utils/utils\";\nimport {\n dropdownInstantColorClassName,\n dropdownMenuRowGapClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\n\ninterface DropdownItemProps<T> {\n item: T;\n index: number;\n isSelected: boolean;\n getItemProps: <Options>(options: any & Options) => any; // eslint-disable-line @typescript-eslint/no-explicit-any\n getDisplayText: (item: T) => string;\n getItemKey: (item: T) => string;\n isProviderDropdown?: boolean;\n renderIcon?: (item: T) => React.ReactNode;\n itemClassName?: string;\n}\n\nexport function DropdownItem<T>({\n item,\n index,\n isSelected,\n getItemProps,\n getDisplayText,\n getItemKey,\n isProviderDropdown = false,\n renderIcon,\n itemClassName,\n}: DropdownItemProps<T>) {\n const itemProps = getItemProps({\n index,\n item,\n className: cn(\n isProviderDropdown\n ? \"group px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center\"\n : \"group px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5\",\n \"text-white focus:outline-none font-normal\",\n dropdownInstantColorClassName,\n {\n \"bg-[var(--oh-interactive-selected)] text-white\": isSelected,\n \"hover:bg-[var(--oh-interactive-hover)]\": !isSelected,\n },\n itemClassName,\n ),\n });\n\n return (\n <li key={getItemKey(item)} {...itemProps}>\n <div className={cn(\"flex items-center\", dropdownMenuRowGapClassName)}>\n {renderIcon ? (\n <span className={dropdownMenuRowIconWrapperClassName}>\n {renderIcon(item)}\n </span>\n ) : null}\n <span className=\"font-normal\">{getDisplayText(item)}</span>\n </div>\n </li>\n );\n}\n"],"mappings":";;;;;AAoBA,SAAgB,EAAgB,EAC9B,SACA,UACA,eACA,iBACA,mBACA,eACA,wBAAqB,IACrB,eACA,oBACuB;AAkBvB,QACE,kBAAC,MAAD;EAA2B,GAlBX,EAAa;GAC7B;GACA;GACA,WAAW,EACT,IACI,sFACA,iEACJ,6CACA,GACA;IACE,kDAAkD;IAClD,0CAA0C,CAAC;IAC5C,EACD,EACD;GACF,CAGgC;YAC7B,kBAAC,OAAD;GAAK,WAAW,EAAG,qBAAqB,EAA4B;aAApE,CACG,IACC,kBAAC,QAAD;IAAM,WAAW;cACd,EAAW,EAAK;IACZ,CAAA,GACL,MACJ,kBAAC,QAAD;IAAM,WAAU;cAAe,EAAe,EAAK;IAAQ,CAAA,CACvD;;EACH,EATI,EAAW,EAAK,CASpB"}