@openhands/agent-canvas 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (710) hide show
  1. package/README.md +11 -12
  2. package/README.windows.md +4 -2
  3. package/build/assets/{Trans-Ch-OVWEA.js → Trans-DqF_OEZB.js} +1 -1
  4. package/build/assets/{acp-providers-Sy2LKyMa.js → acp-providers-DerAmTyY.js} +1 -1
  5. package/build/assets/active-backend-context-B8rMv0X9.js +1 -0
  6. package/build/assets/{add-backend-modal-Bgy8anoR.js → add-backend-modal-CxC7BNEc.js} +1 -1
  7. package/build/assets/{agent-profiles-settings-3mmXljZX.js → agent-profiles-settings-BJb8YXR1.js} +1 -1
  8. package/build/assets/agent-server-compatibility-BWN-EIQn.js +1 -0
  9. package/build/assets/agent-server-conversation-service.api-DSPIkMwJ.js +41 -0
  10. package/build/assets/{agent-settings-B-W10B4E.js → agent-settings-CgCnqaAA.js} +2 -2
  11. package/build/assets/agent-settings-DDkSavD7.js +1 -0
  12. package/build/assets/{alert-banner-Bpf2NQJq.js → alert-banner-Dh51WURQ.js} +1 -1
  13. package/build/assets/api-key-entry-screen-iZc7n8AI.js +1 -0
  14. package/build/assets/app-settings-B5zyipxJ.js +1 -0
  15. package/build/assets/automation-detail-CZsu2CoM.js +2 -0
  16. package/build/assets/automation-export-BwRX6H32.js +2 -0
  17. package/build/assets/automations-list-lHAVzMoA.js +1 -0
  18. package/build/assets/{back-nav-button-CUS2mi-U.js → back-nav-button-DVknCcSP.js} +1 -1
  19. package/build/assets/backend-form-modal-RGcu909r.js +1 -0
  20. package/build/assets/{backend-synced-settings-badge-D9hZx05w.js → backend-synced-settings-badge-BSfN0AZA.js} +1 -1
  21. package/build/assets/{base-modal-BuF2f0YL.js → base-modal-CIF_785P.js} +1 -1
  22. package/build/assets/{bot-D7eUAuSB.js → bot-C-EA6685.js} +1 -1
  23. package/build/assets/{brand-button-vMVuyDXu.js → brand-button-B1izLAdR.js} +1 -1
  24. package/build/assets/{browser-BifzWIBd.js → browser-DKaeq_sT.js} +3 -3
  25. package/build/assets/{browser-tab-CkkqJnqw.js → browser-tab-qb_ftCxW.js} +1 -1
  26. package/build/assets/canvas-ui-COgjltGz.js +1 -0
  27. package/build/assets/{chat-send-button-B_jc5z5C.js → chat-send-button-BZHG2hAW.js} +1 -1
  28. package/build/assets/check-TbOEtHKj.js +1 -0
  29. package/build/assets/{chevron-down-CI8A6tet.js → chevron-down-D7IvFMBM.js} +1 -1
  30. package/build/assets/{circle-plus-check-toggle-C5YxjxvI.js → circle-plus-check-toggle-DoFIjVE0.js} +1 -1
  31. package/build/assets/client-source-BZK8vRs2.js +1 -0
  32. package/build/assets/cloud-funnel-analytics-Zcv57hfT.js +1 -0
  33. package/build/assets/{color-themes-DPBzNtVg.js → color-themes-CHizm1xF.js} +1 -1
  34. package/build/assets/{combobox-caret-DoObzqf4.js → combobox-caret-CxZpqoSR.js} +1 -1
  35. package/build/assets/{command-menu-D-JV3Wqm.js → command-menu-oTvKDU3Y.js} +1 -1
  36. package/build/assets/condenser-settings-BGlWn93P.js +1 -0
  37. package/build/assets/{confirmation-modal-BGLu6XJN.js → confirmation-modal-DGBWM2Ls.js} +1 -1
  38. package/build/assets/{context-menu-list-item-BD5_EaKN.js → context-menu-list-item-6psNyl7X.js} +1 -1
  39. package/build/assets/conversation-BoCYx8n2.js +89 -0
  40. package/build/assets/conversation-DgHqMjnY.js +1 -0
  41. package/build/assets/conversation-panel-78Rxh_-I.js +1 -0
  42. package/build/assets/conversation-service.api-_f9GlIEi.js +1 -0
  43. package/build/assets/{conversation-tab-empty-state-B2dDYEwf.js → conversation-tab-empty-state-CNUmIms2.js} +1 -1
  44. package/build/assets/{copy-3JCw_XFB.js → copy-D1YGjP-C.js} +1 -1
  45. package/build/assets/{copy-to-clipboard-button-CaR52OnA.js → copy-to-clipboard-button-CFzH_NOX.js} +1 -1
  46. package/build/assets/declaration-BGsHjPEW.js +1 -0
  47. package/build/assets/{device-verify-Dj6I4Iqe.js → device-verify-WBSjJBLH.js} +1 -1
  48. package/build/assets/{dropdown-classes-DJSXeLqc.js → dropdown-classes-D3wMJlXT.js} +1 -1
  49. package/build/assets/{ellipsis-button-C5Z-tPFp.js → ellipsis-button-CbNnHlIq.js} +1 -1
  50. package/build/assets/{entry.client-2_3ePAm0.js → entry.client-DNlPGxsu.js} +2 -2
  51. package/build/assets/{enum-filter-dropdown-DXbVwiNZ.js → enum-filter-dropdown-JLYv1t8L.js} +1 -1
  52. package/build/assets/{environment-switch-overlay-DZQfRGTx.js → environment-switch-overlay-B1PFO8P8.js} +1 -1
  53. package/build/assets/{extensions-hub-CLjmOGqS.js → extensions-hub-CCbLA7IM.js} +1 -1
  54. package/build/assets/{extensions-navigation-B5MeUiMq.js → extensions-navigation-CPNjMNvR.js} +1 -1
  55. package/build/assets/{external-link-D2zJjE9G.js → external-link-lhdITPqq.js} +1 -1
  56. package/build/assets/files-tab-y4K7EXBO.js +1 -0
  57. package/build/assets/{form-control-classes-ChpNBe9n.js → form-control-classes-CbdN5aO3.js} +1 -1
  58. package/build/assets/format-time-delta-DhDbkD7V.js +1 -0
  59. package/build/assets/git-provider-icon-ITvsH4Ko.js +1 -0
  60. package/build/assets/home-BwbeOWwU.js +1 -0
  61. package/build/assets/home-DKPGQ5P3.js +1 -0
  62. package/build/assets/index-home-Bko2Itv5.js +1 -0
  63. package/build/assets/install-server-modal-Qk1gwyI8.js +1 -0
  64. package/build/assets/{launch-V_3Rp7WS.js → launch-CAGavYl-.js} +1 -1
  65. package/build/assets/lesson-plan-DMCPdtrf.js +4 -0
  66. package/build/assets/{list-todo-BfH6yYUK.js → list-todo-CAtvkzcy.js} +1 -1
  67. package/build/assets/llm-not-configured-banner-C1ktyb3C.js +27 -0
  68. package/build/assets/llm-settings-BBsZFi9l.js +1 -0
  69. package/build/assets/llm-settings-DFkJQr_w.js +1 -0
  70. package/build/assets/llm-subscription-service-Casyzgn1.js +1 -0
  71. package/build/assets/loader-circle-CsAsfLIs.js +1 -0
  72. package/build/assets/{loading-spinner-BLdswi6q.js → loading-spinner-BcdnT0mN.js} +1 -1
  73. package/build/assets/manage-backends-modal-CKQ46rvw.js +1 -0
  74. package/build/assets/manifest-03478bbf.js +1 -0
  75. package/build/assets/{map-provider-BM2SJarp.js → map-provider-BbIb12oh.js} +1 -1
  76. package/build/assets/{markdown-renderer-DMT7Zkpd.js → markdown-renderer-B4V2OMFP.js} +1 -1
  77. package/build/assets/{mcp-BQufNPZ6.js → mcp-BapoJsDc.js} +2 -2
  78. package/build/assets/{messages-BnJCqnFf.js → messages-CUBFMY5o.js} +26 -26
  79. package/build/assets/{modal-body-DouOE5KH.js → modal-body-Cc2zp0xb.js} +1 -1
  80. package/build/assets/{modal-classes-Cf-4tbHz.js → modal-classes-3qT9Ap7Q.js} +1 -1
  81. package/build/assets/{modal-close-button-B6CfxxJj.js → modal-close-button-BcIBUdSq.js} +1 -1
  82. package/build/assets/model-selector-DJrMrFAr.js +1 -0
  83. package/build/assets/onboarding-6NMkdNxV.js +1 -0
  84. package/build/assets/onboarding-modal-Q4AnpIdg.js +1 -0
  85. package/build/assets/organization-service.api-vrRNwOma.js +1 -0
  86. package/build/assets/path-utils-PNfCKQDV.js +1 -0
  87. package/build/assets/{pencil-Dj2XjKmI.js → pencil-CWhApFIT.js} +1 -1
  88. package/build/assets/{plan-components-CcCBmCzW.js → plan-components-BdZXPyZU.js} +1 -1
  89. package/build/assets/{planner-tab-Dhyqcqmb.js → planner-tab-ByOw1he8.js} +1 -1
  90. package/build/assets/plugins-management-service-B75jyC56.js +1 -0
  91. package/build/assets/profiles-service.api-BQTklD5D.js +1 -0
  92. package/build/assets/providers-DfTB2gPd.js +1 -0
  93. package/build/assets/proxy-B3tCGf0X.js +1 -0
  94. package/build/assets/{recommended-automations-launcher-CTcGTl4d.js → recommended-automations-launcher-Bj7PuHY1.js} +1 -1
  95. package/build/assets/{refresh-cw-DM82EIyx.js → refresh-cw-B9B7-vsy.js} +1 -1
  96. package/build/assets/root-CDnuTToz.js +2 -0
  97. package/build/assets/root-CYWeTrWE.css +1 -0
  98. package/build/assets/root-layout-DfYVlcRG.js +2 -0
  99. package/build/assets/{runtime-waiting-state-BsXLElvN.js → runtime-waiting-state-CnyVhX4T.js} +1 -1
  100. package/build/assets/schema-field-CUwk4wrQ.js +1 -0
  101. package/build/assets/sdk-section-page-DLLNrYjI.js +1 -0
  102. package/build/assets/{sdk-settings-schema-Cv7M9eSe.js → sdk-settings-schema-CLR01YIK.js} +1 -1
  103. package/build/assets/search-dIQ09UY2.js +1 -0
  104. package/build/assets/secrets-service-CvyPWJhg.js +1 -0
  105. package/build/assets/{secrets-settings-Cx6yJlyb.js → secrets-settings-CHy72A5C.js} +1 -1
  106. package/build/assets/{segmented-toggle-DyQqPhoD.js → segmented-toggle-kzwZkLaj.js} +1 -1
  107. package/build/assets/settings-B9S8UVQr.js +1 -0
  108. package/build/assets/{settings-dropdown-input-BjunGXJb.js → settings-dropdown-input-Dhx9ErGd.js} +1 -1
  109. package/build/assets/{settings-index-D6sxWSRk.js → settings-index-BKDl2CQ-.js} +1 -1
  110. package/build/assets/{settings-input-bD6npsDm.js → settings-input-BsgQWS5R.js} +1 -1
  111. package/build/assets/{settings-list-classes-Dp_OgzN0.js → settings-list-classes-DSJJX99U.js} +1 -1
  112. package/build/assets/settings-modal-DeK11CyT.js +1 -0
  113. package/build/assets/settings-service.api-DXk5TdeJ.js +1 -0
  114. package/build/assets/{settings-switch-5cuxl8Dc.js → settings-switch-Bes8dIlV.js} +1 -1
  115. package/build/assets/{settings-utils-BMdG65By.js → settings-utils-DzCVfiR3.js} +1 -1
  116. package/build/assets/shared-conversation-9atDzTR4.js +1 -0
  117. package/build/assets/{sidebar-layout-DuzJMMw-.js → sidebar-layout-Bm7pa3Vk.js} +1 -1
  118. package/build/assets/{sidebar-mobile-menu-toggle-VvvX32iF.js → sidebar-mobile-menu-toggle-giMMZctn.js} +1 -1
  119. package/build/assets/{sidebar-nav-link-5AlTT5-j.js → sidebar-nav-link-CHqyFXwV.js} +1 -1
  120. package/build/assets/{sidebar-store-CZuE8AH5.js → sidebar-store-uiUXBU1N.js} +1 -1
  121. package/build/assets/{skill-card-pill-row-eTIkE4nz.js → skill-card-pill-row-BPYKQ3IN.js} +1 -1
  122. package/build/assets/skills-plugins-Tropusio.js +1 -0
  123. package/build/assets/{skills-settings-BUv04tSc.js → skills-settings-BvzBBCWk.js} +2 -2
  124. package/build/assets/{square-chevron-right-Czw3FFWc.js → square-chevron-right-DE-JN-2Z.js} +1 -1
  125. package/build/assets/{styled-tooltip-CgX2oRaK.js → styled-tooltip-B14i_Uac.js} +1 -1
  126. package/build/assets/{suspense-BO1Tl_Vf.js → suspense-DmZ3MSSh.js} +1 -1
  127. package/build/assets/{task-list-tab-0k9PhuqO.js → task-list-tab-DyfgG4MC.js} +1 -1
  128. package/build/assets/telemetry-C5JMEfqB.js +2 -0
  129. package/build/assets/{terminal-B61WrJdS.js → terminal-DRXt2Lr4.js} +1 -1
  130. package/build/assets/{toggle-switch-2j5wwR85.js → toggle-switch-DX_k418f.js} +1 -1
  131. package/build/assets/{trash-2-Be_7y3Mn.js → trash-2-BU6BlW4i.js} +1 -1
  132. package/build/assets/{typography-D8mHDeNG.js → typography-CzfoD9DY.js} +1 -1
  133. package/build/assets/use-acp-credential-form-Bm8qXdlc.js +1 -0
  134. package/build/assets/{use-activate-agent-profile-20v1xU0H.js → use-activate-agent-profile-DlykqEfN.js} +1 -1
  135. package/build/assets/{use-active-agent-profile-BkJN7Xsy.js → use-active-agent-profile-hI-x-UBa.js} +1 -1
  136. package/build/assets/{use-active-conversation-DOZVSVtU.js → use-active-conversation-2qeez40F.js} +1 -1
  137. package/build/assets/use-agent-profiles-0pr5bLS7.js +1 -0
  138. package/build/assets/{use-agent-state-DHZO1obC.js → use-agent-state-C6peDXUm.js} +1 -1
  139. package/build/assets/use-backends-health-CLHPitJM.js +1 -0
  140. package/build/assets/{use-can-manage-org-profiles-C-OhWVBS.js → use-can-manage-org-profiles-Ck_bsNbH.js} +1 -1
  141. package/build/assets/use-cloud-current-user-id-DUCSxNjY.js +1 -0
  142. package/build/assets/use-config-B5r8erYt.js +1 -0
  143. package/build/assets/use-create-conversation-r1JHfKO5.js +1 -0
  144. package/build/assets/{use-create-secret-D0HCOZFu.js → use-create-secret-Cf2N11d2.js} +1 -1
  145. package/build/assets/{use-event-store-DjgU4wfO.js → use-event-store-Bbaz51GR.js} +1 -1
  146. package/build/assets/{use-handle-plan-click-DyRASKMC.js → use-handle-plan-click-CsAW3FlH.js} +1 -1
  147. package/build/assets/use-is-authed-BezEyfeh.js +1 -0
  148. package/build/assets/use-llm-profiles-Dr5__SlZ.js +1 -0
  149. package/build/assets/use-plugins-marketplace-BplU65ae.js +1 -0
  150. package/build/assets/use-runtime-is-ready-vCFOcLFa.js +1 -0
  151. package/build/assets/use-save-agent-profile-RqUGqTv6.js +1 -0
  152. package/build/assets/use-save-settings-Chvzeu2s.js +1 -0
  153. package/build/assets/use-settings-CyxSlyTQ.js +1 -0
  154. package/build/assets/use-settings-nav-items-zEkSO_Bf.js +16 -0
  155. package/build/assets/use-skills-xrVoKYrF.js +1 -0
  156. package/build/assets/{use-task-list-AVBLbbcR.js → use-task-list-CfisapBW.js} +1 -1
  157. package/build/assets/use-tracking-D2Qg5Lpd.js +1 -0
  158. package/build/assets/{use-user-conversation-zpx7I18x.js → use-user-conversation-CnE4zhOA.js} +1 -1
  159. package/build/assets/{useMutation-DrCAVg5w.js → useMutation-u8UgRgDK.js} +1 -1
  160. package/build/assets/{useMutationState-D8QN0ZCy.js → useMutationState-OnAsCLA_.js} +1 -1
  161. package/build/assets/{useQueries-DClgUTc7.js → useQueries-BpIlT8Mt.js} +1 -1
  162. package/build/assets/{useQuery-CRBP8vIS.js → useQuery-D5pEZbY0.js} +1 -1
  163. package/build/assets/{useTranslation-CDRCKC9-.js → useTranslation-Cbf5AGg_.js} +1 -1
  164. package/build/assets/{utils-D3U3rlqr.js → utils-DB9LsAzA.js} +1 -1
  165. package/build/assets/{vendor~browser-tab-Di0kh5Zw.js → vendor~browser-tab-CsMb-pta.js} +1 -1
  166. package/build/assets/{vendor~browser-Cvg7jXCP.js → vendor~browser-wXQ-WZEC.js} +1 -1
  167. package/build/assets/{vendor~entry.client-9tWQ_Ugw.js → vendor~entry.client-DDuH4--y.js} +1 -1
  168. package/build/assets/{vendor~entry.client-D6BtSOtn.js → vendor~entry.client-DQGrNspu.js} +1 -1
  169. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dhilvkxv-eGLBu60s.js +2 -0
  170. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~iztiaf2o-rqo6vRFz.js +185 -0
  171. package/build/assets/{vendor~files-tab-B02k3xvx.js → vendor~files-tab-B-5fBohe.js} +1 -1
  172. package/build/assets/{vendor~home~conversation-panel~conversation-CYMF9JYB.js → vendor~index-home~home~conversation-panel~conversation-ChmYLVgz.js} +1 -1
  173. package/build/assets/vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BD7v71DM.js +2 -0
  174. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BD0GaRGa.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BT05Osu4.js} +1 -1
  175. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D7EUmQ8Y.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DgzWSMRc.js} +1 -1
  176. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-d8aETPbZ.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DqZatR3B.js} +1 -1
  177. package/build/assets/{vendor~launch-CHXA9cJu.js → vendor~launch-_Km3J77E.js} +1 -1
  178. package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~ivvrgjsa-BlIZPCXX.js → vendor~module-D5a_AClf.js} +1 -1
  179. package/build/assets/{vendor~root-layout~conversation-panel~conversation-CpiTHpHl.js → vendor~root-layout~conversation-panel~conversation-8tIsyrPj.js} +1 -1
  180. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-_TdZcNMD.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-BrguKXCn.js} +1 -1
  181. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation-Cn2jwSga.js → vendor~root-layout~index-home~home~conversation-panel~conversation-BTvhGHHG.js} +1 -1
  182. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-CZM4hwUT.js → vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation~aler~gfu7qdtz-BOKQkbc6.js} +1 -1
  183. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~enjl5xdm-B0EIDu4M.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~ftka0fnu-cFNmfAE6.js} +2 -2
  184. package/build/assets/{verification-settings-D576N2xa.js → verification-settings-CfkrXoSa.js} +1 -1
  185. package/build/assets/x-ZE4iplpF.js +1 -0
  186. package/build/index.html +4 -4
  187. package/build/locales/ar/openhands.json +9 -0
  188. package/build/locales/ca/openhands.json +9 -0
  189. package/build/locales/de/openhands.json +9 -0
  190. package/build/locales/en/openhands.json +9 -0
  191. package/build/locales/es/openhands.json +9 -0
  192. package/build/locales/fr/openhands.json +9 -0
  193. package/build/locales/it/openhands.json +9 -0
  194. package/build/locales/ja/openhands.json +9 -0
  195. package/build/locales/ko-KR/openhands.json +9 -0
  196. package/build/locales/no/openhands.json +9 -0
  197. package/build/locales/pt/openhands.json +9 -0
  198. package/build/locales/tr/openhands.json +9 -0
  199. package/build/locales/uk/openhands.json +9 -0
  200. package/build/locales/zh-CN/openhands.json +9 -0
  201. package/build/locales/zh-TW/openhands.json +9 -0
  202. package/config/defaults.json +5 -4
  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.d.ts +9 -1
  206. package/dist/api/agent-server-adapter.js +105 -102
  207. package/dist/api/agent-server-adapter.js.map +1 -1
  208. package/dist/api/agent-server-config.cjs +1 -1
  209. package/dist/api/agent-server-config.cjs.map +1 -1
  210. package/dist/api/agent-server-config.d.ts +3 -0
  211. package/dist/api/agent-server-config.js +45 -23
  212. package/dist/api/agent-server-config.js.map +1 -1
  213. package/dist/api/backend-registry/auth.cjs +1 -1
  214. package/dist/api/backend-registry/auth.cjs.map +1 -1
  215. package/dist/api/backend-registry/auth.js +1 -1
  216. package/dist/api/backend-registry/auth.js.map +1 -1
  217. package/dist/api/backend-registry/default-backend.cjs +1 -1
  218. package/dist/api/backend-registry/default-backend.cjs.map +1 -1
  219. package/dist/api/backend-registry/default-backend.d.ts +3 -0
  220. package/dist/api/backend-registry/default-backend.js +22 -10
  221. package/dist/api/backend-registry/default-backend.js.map +1 -1
  222. package/dist/api/backend-registry/storage.cjs +1 -1
  223. package/dist/api/backend-registry/storage.cjs.map +1 -1
  224. package/dist/api/backend-registry/storage.js +38 -33
  225. package/dist/api/backend-registry/storage.js.map +1 -1
  226. package/dist/api/backend-registry/types.d.ts +2 -0
  227. package/dist/api/canvas-ui-client-tool.cjs +38 -0
  228. package/dist/api/canvas-ui-client-tool.cjs.map +1 -0
  229. package/dist/api/canvas-ui-client-tool.d.ts +14 -0
  230. package/dist/api/canvas-ui-client-tool.js +47 -0
  231. package/dist/api/canvas-ui-client-tool.js.map +1 -0
  232. package/dist/api/client-source.cjs +2 -0
  233. package/dist/api/client-source.cjs.map +1 -0
  234. package/dist/api/client-source.d.ts +9 -0
  235. package/dist/api/client-source.js +10 -0
  236. package/dist/api/client-source.js.map +1 -0
  237. package/dist/api/cloud/client.cjs +2 -0
  238. package/dist/api/cloud/client.cjs.map +1 -0
  239. package/dist/api/cloud/client.d.ts +4 -0
  240. package/dist/api/cloud/client.js +38 -0
  241. package/dist/api/cloud/client.js.map +1 -0
  242. package/dist/api/cloud/conversation-service.api.cjs +1 -1
  243. package/dist/api/cloud/conversation-service.api.cjs.map +1 -1
  244. package/dist/api/cloud/conversation-service.api.js +35 -33
  245. package/dist/api/cloud/conversation-service.api.js.map +1 -1
  246. package/dist/api/cloud/organization-service.api.cjs +1 -1
  247. package/dist/api/cloud/organization-service.api.cjs.map +1 -1
  248. package/dist/api/cloud/organization-service.api.js +11 -10
  249. package/dist/api/cloud/organization-service.api.js.map +1 -1
  250. package/dist/api/cloud/proxy.cjs +1 -1
  251. package/dist/api/cloud/proxy.cjs.map +1 -1
  252. package/dist/api/cloud/proxy.d.ts +2 -40
  253. package/dist/api/cloud/proxy.js +14 -39
  254. package/dist/api/cloud/proxy.js.map +1 -1
  255. package/dist/api/conversation-metadata-store.cjs +1 -1
  256. package/dist/api/conversation-metadata-store.cjs.map +1 -1
  257. package/dist/api/conversation-metadata-store.d.ts +2 -9
  258. package/dist/api/conversation-metadata-store.js +13 -9
  259. package/dist/api/conversation-metadata-store.js.map +1 -1
  260. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  261. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  262. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +2 -1
  263. package/dist/api/conversation-service/agent-server-conversation-service.api.js +98 -88
  264. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  265. package/dist/api/conversation-service/agent-server-conversation-service.types.d.ts +5 -0
  266. package/dist/api/device-flow-client.cjs +1 -1
  267. package/dist/api/device-flow-client.cjs.map +1 -1
  268. package/dist/api/device-flow-client.d.ts +4 -58
  269. package/dist/api/device-flow-client.js +8 -98
  270. package/dist/api/device-flow-client.js.map +1 -1
  271. package/dist/api/git-service/agent-server-git-service.api.cjs +1 -1
  272. package/dist/api/git-service/agent-server-git-service.api.cjs.map +1 -1
  273. package/dist/api/git-service/agent-server-git-service.api.d.ts +10 -2
  274. package/dist/api/git-service/agent-server-git-service.api.js +107 -40
  275. package/dist/api/git-service/agent-server-git-service.api.js.map +1 -1
  276. package/dist/api/open-hands.types.d.ts +11 -0
  277. package/dist/api/option-service/option-service.api.cjs +1 -1
  278. package/dist/api/option-service/option-service.api.cjs.map +1 -1
  279. package/dist/api/option-service/option-service.api.js +0 -1
  280. package/dist/api/option-service/option-service.api.js.map +1 -1
  281. package/dist/api/option-service/option.types.d.ts +0 -1
  282. package/dist/api/secrets-service.cjs +1 -1
  283. package/dist/api/secrets-service.cjs.map +1 -1
  284. package/dist/api/secrets-service.js +15 -14
  285. package/dist/api/secrets-service.js.map +1 -1
  286. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
  287. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
  288. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +73 -64
  289. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
  290. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-content.cjs +2 -2
  291. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-content.cjs.map +1 -1
  292. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-content.js +2 -0
  293. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-content.js.map +1 -1
  294. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  295. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  296. package/dist/components/features/backends/backend-form-modal.d.ts +4 -2
  297. package/dist/components/features/backends/backend-form-modal.js +108 -101
  298. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  299. package/dist/components/features/backends/backend-row.cjs +1 -1
  300. package/dist/components/features/backends/backend-row.cjs.map +1 -1
  301. package/dist/components/features/backends/backend-row.js +2 -1
  302. package/dist/components/features/backends/backend-row.js.map +1 -1
  303. package/dist/components/features/backends/backend-selector.cjs +1 -1
  304. package/dist/components/features/backends/backend-selector.cjs.map +1 -1
  305. package/dist/components/features/backends/backend-selector.js +51 -51
  306. package/dist/components/features/backends/backend-selector.js.map +1 -1
  307. package/dist/components/features/backends/device-flow-auth.cjs +1 -1
  308. package/dist/components/features/backends/device-flow-auth.cjs.map +1 -1
  309. package/dist/components/features/backends/device-flow-auth.d.ts +4 -1
  310. package/dist/components/features/backends/device-flow-auth.js +38 -38
  311. package/dist/components/features/backends/device-flow-auth.js.map +1 -1
  312. package/dist/components/features/chat/chat-interface.cjs +2 -2
  313. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  314. package/dist/components/features/chat/chat-interface.js +173 -165
  315. package/dist/components/features/chat/chat-interface.js.map +1 -1
  316. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  317. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  318. package/dist/components/features/chat/components/chat-input-actions.d.ts +2 -1
  319. package/dist/components/features/chat/components/chat-input-actions.js +44 -43
  320. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  321. package/dist/components/features/chat/components/chat-input-container.cjs +1 -1
  322. package/dist/components/features/chat/components/chat-input-container.cjs.map +1 -1
  323. package/dist/components/features/chat/components/chat-input-container.d.ts +2 -1
  324. package/dist/components/features/chat/components/chat-input-container.js +20 -19
  325. package/dist/components/features/chat/components/chat-input-container.js.map +1 -1
  326. package/dist/components/features/chat/components/chat-input-profile-picker.cjs +1 -1
  327. package/dist/components/features/chat/components/chat-input-profile-picker.cjs.map +1 -1
  328. package/dist/components/features/chat/components/chat-input-profile-picker.js +44 -32
  329. package/dist/components/features/chat/components/chat-input-profile-picker.js.map +1 -1
  330. package/dist/components/features/chat/components/resolve-picker-kind.cjs +1 -1
  331. package/dist/components/features/chat/components/resolve-picker-kind.cjs.map +1 -1
  332. package/dist/components/features/chat/components/resolve-picker-kind.d.ts +10 -22
  333. package/dist/components/features/chat/components/resolve-picker-kind.js +6 -3
  334. package/dist/components/features/chat/components/resolve-picker-kind.js.map +1 -1
  335. package/dist/components/features/chat/custom-chat-input.cjs +1 -1
  336. package/dist/components/features/chat/custom-chat-input.cjs.map +1 -1
  337. package/dist/components/features/chat/custom-chat-input.d.ts +2 -1
  338. package/dist/components/features/chat/custom-chat-input.js +52 -51
  339. package/dist/components/features/chat/custom-chat-input.js.map +1 -1
  340. package/dist/components/features/chat/interactive-chat-box.cjs +1 -1
  341. package/dist/components/features/chat/interactive-chat-box.cjs.map +1 -1
  342. package/dist/components/features/chat/interactive-chat-box.d.ts +2 -1
  343. package/dist/components/features/chat/interactive-chat-box.js +9 -8
  344. package/dist/components/features/chat/interactive-chat-box.js.map +1 -1
  345. package/dist/components/features/diff-viewer/commit-list.cjs +2 -0
  346. package/dist/components/features/diff-viewer/commit-list.cjs.map +1 -0
  347. package/dist/components/features/diff-viewer/commit-list.d.ts +13 -0
  348. package/dist/components/features/diff-viewer/commit-list.js +27 -0
  349. package/dist/components/features/diff-viewer/commit-list.js.map +1 -0
  350. package/dist/components/features/diff-viewer/commit-row.cjs +2 -0
  351. package/dist/components/features/diff-viewer/commit-row.cjs.map +1 -0
  352. package/dist/components/features/diff-viewer/commit-row.d.ts +14 -0
  353. package/dist/components/features/diff-viewer/commit-row.js +59 -0
  354. package/dist/components/features/diff-viewer/commit-row.js.map +1 -0
  355. package/dist/components/features/diff-viewer/file-diff-viewer.cjs +1 -1
  356. package/dist/components/features/diff-viewer/file-diff-viewer.cjs.map +1 -1
  357. package/dist/components/features/diff-viewer/file-diff-viewer.d.ts +7 -1
  358. package/dist/components/features/diff-viewer/file-diff-viewer.js +40 -39
  359. package/dist/components/features/diff-viewer/file-diff-viewer.js.map +1 -1
  360. package/dist/components/features/plugins/plugin-detail-modal.d.ts +2 -1
  361. package/dist/components/providers/agent-server-ui-providers.cjs +1 -1
  362. package/dist/components/providers/agent-server-ui-providers.cjs.map +1 -1
  363. package/dist/components/providers/agent-server-ui-providers.d.ts +4 -2
  364. package/dist/components/providers/agent-server-ui-providers.js +9 -2
  365. package/dist/components/providers/agent-server-ui-providers.js.map +1 -1
  366. package/dist/components/providers/index.cjs +1 -1
  367. package/dist/components/providers/index.d.ts +1 -2
  368. package/dist/components/providers/index.js +0 -1
  369. package/dist/components/providers/telemetry-provider.cjs +2 -0
  370. package/dist/components/providers/telemetry-provider.cjs.map +1 -0
  371. package/dist/components/providers/telemetry-provider.d.ts +6 -0
  372. package/dist/components/providers/telemetry-provider.js +64 -0
  373. package/dist/components/providers/telemetry-provider.js.map +1 -0
  374. package/dist/components/shared/modals/settings/settings-modal.cjs +1 -1
  375. package/dist/components/shared/modals/settings/settings-modal.cjs.map +1 -1
  376. package/dist/components/shared/modals/settings/settings-modal.js +23 -22
  377. package/dist/components/shared/modals/settings/settings-modal.js.map +1 -1
  378. package/dist/config/defaults.cjs +1 -1
  379. package/dist/config/defaults.cjs.map +1 -1
  380. package/dist/config/defaults.js +5 -4
  381. package/dist/config/defaults.js.map +1 -1
  382. package/dist/constants/acp-providers.cjs.map +1 -1
  383. package/dist/constants/acp-providers.d.ts +1 -1
  384. package/dist/constants/acp-providers.js.map +1 -1
  385. package/dist/constants/canvas-ui.cjs +2 -0
  386. package/dist/constants/canvas-ui.cjs.map +1 -0
  387. package/dist/constants/canvas-ui.d.ts +8 -0
  388. package/dist/constants/canvas-ui.js +6 -0
  389. package/dist/constants/canvas-ui.js.map +1 -0
  390. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  391. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  392. package/dist/contexts/conversation-websocket-context.js +197 -204
  393. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  394. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  395. package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
  396. package/dist/hooks/mutation/use-create-conversation.d.ts +2 -1
  397. package/dist/hooks/mutation/use-create-conversation.js +52 -52
  398. package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
  399. package/dist/hooks/mutation/use-save-settings.cjs +1 -1
  400. package/dist/hooks/mutation/use-save-settings.cjs.map +1 -1
  401. package/dist/hooks/mutation/use-save-settings.d.ts +3 -1
  402. package/dist/hooks/mutation/use-save-settings.js +6 -5
  403. package/dist/hooks/mutation/use-save-settings.js.map +1 -1
  404. package/dist/hooks/query/query-keys.cjs +1 -1
  405. package/dist/hooks/query/query-keys.cjs.map +1 -1
  406. package/dist/hooks/query/query-keys.d.ts +2 -0
  407. package/dist/hooks/query/query-keys.js +4 -1
  408. package/dist/hooks/query/query-keys.js.map +1 -1
  409. package/dist/hooks/query/use-backends-health.cjs +1 -1
  410. package/dist/hooks/query/use-backends-health.cjs.map +1 -1
  411. package/dist/hooks/query/use-backends-health.js +50 -48
  412. package/dist/hooks/query/use-backends-health.js.map +1 -1
  413. package/dist/hooks/query/use-cloud-organizations.cjs +1 -1
  414. package/dist/hooks/query/use-cloud-organizations.cjs.map +1 -1
  415. package/dist/hooks/query/use-cloud-organizations.d.ts +1 -0
  416. package/dist/hooks/query/use-cloud-organizations.js +5 -2
  417. package/dist/hooks/query/use-cloud-organizations.js.map +1 -1
  418. package/dist/hooks/query/use-commit-changes.cjs +2 -0
  419. package/dist/hooks/query/use-commit-changes.cjs.map +1 -0
  420. package/dist/hooks/query/use-commit-changes.d.ts +5 -0
  421. package/dist/hooks/query/use-commit-changes.js +34 -0
  422. package/dist/hooks/query/use-commit-changes.js.map +1 -0
  423. package/dist/hooks/query/use-task-polling.cjs +1 -1
  424. package/dist/hooks/query/use-task-polling.cjs.map +1 -1
  425. package/dist/hooks/query/use-task-polling.d.ts +3 -2
  426. package/dist/hooks/query/use-task-polling.js +53 -40
  427. package/dist/hooks/query/use-task-polling.js.map +1 -1
  428. package/dist/hooks/query/use-unified-git-commits.cjs +2 -0
  429. package/dist/hooks/query/use-unified-git-commits.cjs.map +1 -0
  430. package/dist/hooks/query/use-unified-git-commits.d.ts +10 -0
  431. package/dist/hooks/query/use-unified-git-commits.js +41 -0
  432. package/dist/hooks/query/use-unified-git-commits.js.map +1 -0
  433. package/dist/hooks/query/use-unified-git-diff.cjs +1 -1
  434. package/dist/hooks/query/use-unified-git-diff.cjs.map +1 -1
  435. package/dist/hooks/query/use-unified-git-diff.d.ts +5 -0
  436. package/dist/hooks/query/use-unified-git-diff.js +11 -4
  437. package/dist/hooks/query/use-unified-git-diff.js.map +1 -1
  438. package/dist/hooks/use-acp-model-context.cjs +1 -1
  439. package/dist/hooks/use-acp-model-context.cjs.map +1 -1
  440. package/dist/hooks/use-acp-model-context.d.ts +4 -1
  441. package/dist/hooks/use-acp-model-context.js +9 -8
  442. package/dist/hooks/use-acp-model-context.js.map +1 -1
  443. package/dist/hooks/use-auto-refresh-files-on-edit.cjs +1 -1
  444. package/dist/hooks/use-auto-refresh-files-on-edit.cjs.map +1 -1
  445. package/dist/hooks/use-auto-refresh-files-on-edit.js +1 -1
  446. package/dist/hooks/use-auto-refresh-files-on-edit.js.map +1 -1
  447. package/dist/hooks/use-chat-input-model-state.cjs.map +1 -1
  448. package/dist/hooks/use-chat-input-model-state.d.ts +2 -1
  449. package/dist/hooks/use-chat-input-model-state.js.map +1 -1
  450. package/dist/hooks/use-chat-input-profile-state.cjs +1 -1
  451. package/dist/hooks/use-chat-input-profile-state.cjs.map +1 -1
  452. package/dist/hooks/use-chat-input-profile-state.d.ts +1 -10
  453. package/dist/hooks/use-chat-input-profile-state.js +42 -15
  454. package/dist/hooks/use-chat-input-profile-state.js.map +1 -1
  455. package/dist/hooks/use-device-flow.cjs +1 -1
  456. package/dist/hooks/use-device-flow.cjs.map +1 -1
  457. package/dist/hooks/use-device-flow.d.ts +4 -1
  458. package/dist/hooks/use-device-flow.js +42 -40
  459. package/dist/hooks/use-device-flow.js.map +1 -1
  460. package/dist/hooks/use-telemetry.cjs +1 -1
  461. package/dist/hooks/use-telemetry.cjs.map +1 -1
  462. package/dist/hooks/use-telemetry.d.ts +3 -3
  463. package/dist/hooks/use-telemetry.js +16 -22
  464. package/dist/hooks/use-telemetry.js.map +1 -1
  465. package/dist/hooks/use-tracking.cjs +1 -1
  466. package/dist/hooks/use-tracking.cjs.map +1 -1
  467. package/dist/hooks/use-tracking.d.ts +5 -5
  468. package/dist/hooks/use-tracking.js +37 -37
  469. package/dist/hooks/use-tracking.js.map +1 -1
  470. package/dist/i18n/declaration.cjs +1 -1
  471. package/dist/i18n/declaration.cjs.map +1 -1
  472. package/dist/i18n/declaration.d.ts +9 -0
  473. package/dist/i18n/declaration.js +1 -1
  474. package/dist/i18n/declaration.js.map +1 -1
  475. package/dist/i18n/index.cjs +1 -1
  476. package/dist/i18n/index.cjs.map +1 -1
  477. package/dist/i18n/index.js +19 -18
  478. package/dist/i18n/index.js.map +1 -1
  479. package/dist/i18n/translation.cjs +2 -2
  480. package/dist/i18n/translation.cjs.map +1 -1
  481. package/dist/i18n/translation.js +153 -0
  482. package/dist/i18n/translation.js.map +1 -1
  483. package/dist/index.cjs +1 -1
  484. package/dist/index.js +32 -32
  485. package/dist/lib/index.cjs +1 -1
  486. package/dist/lib/index.d.ts +2 -2
  487. package/dist/lib/index.js +1 -1
  488. package/dist/locales/ar/openhands.json +9 -0
  489. package/dist/locales/ca/openhands.json +9 -0
  490. package/dist/locales/de/openhands.json +9 -0
  491. package/dist/locales/en/openhands.json +9 -0
  492. package/dist/locales/es/openhands.json +9 -0
  493. package/dist/locales/fr/openhands.json +9 -0
  494. package/dist/locales/it/openhands.json +9 -0
  495. package/dist/locales/ja/openhands.json +9 -0
  496. package/dist/locales/ko-KR/openhands.json +9 -0
  497. package/dist/locales/no/openhands.json +9 -0
  498. package/dist/locales/pt/openhands.json +9 -0
  499. package/dist/locales/tr/openhands.json +9 -0
  500. package/dist/locales/uk/openhands.json +9 -0
  501. package/dist/locales/zh-CN/openhands.json +9 -0
  502. package/dist/locales/zh-TW/openhands.json +9 -0
  503. package/dist/node_modules/@openhands/typescript-client/dist/client/cloud-client.cjs +2 -0
  504. package/dist/node_modules/@openhands/typescript-client/dist/client/cloud-client.cjs.map +1 -0
  505. package/dist/node_modules/@openhands/typescript-client/dist/client/cloud-client.js +351 -0
  506. package/dist/node_modules/@openhands/typescript-client/dist/client/cloud-client.js.map +1 -0
  507. package/dist/node_modules/@openhands/typescript-client/dist/client/device-flow-client.cjs +2 -0
  508. package/dist/node_modules/@openhands/typescript-client/dist/client/device-flow-client.cjs.map +1 -0
  509. package/dist/node_modules/@openhands/typescript-client/dist/client/device-flow-client.js +106 -0
  510. package/dist/node_modules/@openhands/typescript-client/dist/client/device-flow-client.js.map +1 -0
  511. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.cjs +2 -0
  512. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.cjs.map +1 -0
  513. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.js +69 -0
  514. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.js.map +1 -0
  515. package/dist/node_modules/@openhands/typescript-client/dist/clients.cjs +1 -1
  516. package/dist/node_modules/@openhands/typescript-client/dist/clients.js +3 -0
  517. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs +1 -1
  518. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs.map +1 -1
  519. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js +18 -2
  520. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js.map +1 -1
  521. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.cjs.map +1 -1
  522. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.js.map +1 -1
  523. package/dist/node_modules/axios/index.cjs +1 -1
  524. package/dist/node_modules/axios/index.js +1 -1
  525. package/dist/package.cjs +1 -1
  526. package/dist/package.cjs.map +1 -1
  527. package/dist/package.js +3 -3
  528. package/dist/package.js.map +1 -1
  529. package/dist/routes/app-settings.cjs +1 -1
  530. package/dist/routes/app-settings.cjs.map +1 -1
  531. package/dist/routes/app-settings.js +59 -60
  532. package/dist/routes/app-settings.js.map +1 -1
  533. package/dist/routes/commits-tab.cjs +2 -0
  534. package/dist/routes/commits-tab.cjs.map +1 -0
  535. package/dist/routes/commits-tab.d.ts +8 -0
  536. package/dist/routes/commits-tab.js +45 -0
  537. package/dist/routes/commits-tab.js.map +1 -0
  538. package/dist/routes/files-tab.cjs +1 -1
  539. package/dist/routes/files-tab.cjs.map +1 -1
  540. package/dist/routes/files-tab.js +148 -127
  541. package/dist/routes/files-tab.js.map +1 -1
  542. package/dist/routes/llm-settings.cjs +1 -1
  543. package/dist/routes/llm-settings.cjs.map +1 -1
  544. package/dist/routes/llm-settings.js +4 -1
  545. package/dist/routes/llm-settings.js.map +1 -1
  546. package/dist/services/cloud-funnel-analytics.cjs +2 -0
  547. package/dist/services/cloud-funnel-analytics.cjs.map +1 -0
  548. package/dist/services/cloud-funnel-analytics.d.ts +4 -0
  549. package/dist/services/cloud-funnel-analytics.js +39 -0
  550. package/dist/services/cloud-funnel-analytics.js.map +1 -0
  551. package/dist/services/telemetry.cjs +1 -1
  552. package/dist/services/telemetry.cjs.map +1 -1
  553. package/dist/services/telemetry.d.ts +46 -9
  554. package/dist/services/telemetry.js +182 -71
  555. package/dist/services/telemetry.js.map +1 -1
  556. package/dist/themes/color-themes.cjs.map +1 -1
  557. package/dist/themes/color-themes.d.ts +3 -6
  558. package/dist/themes/color-themes.js.map +1 -1
  559. package/dist/types/agent-server/core/base/action.d.ts +5 -4
  560. package/dist/types/agent-server/core/base/base.d.ts +3 -2
  561. package/dist/types/agent-server/core/base/observation.d.ts +1 -1
  562. package/dist/types/agent-server/type-guards.cjs +1 -1
  563. package/dist/types/agent-server/type-guards.cjs.map +1 -1
  564. package/dist/types/agent-server/type-guards.d.ts +3 -5
  565. package/dist/types/agent-server/type-guards.js +2 -1
  566. package/dist/types/agent-server/type-guards.js.map +1 -1
  567. package/dist/types/automation.d.ts +5 -0
  568. package/dist/utils/api-error-message.d.ts +11 -0
  569. package/dist/utils/automation-timeout.d.ts +19 -0
  570. package/dist/utils/base-path.cjs +2 -0
  571. package/dist/utils/base-path.cjs.map +1 -0
  572. package/dist/utils/base-path.d.ts +2 -0
  573. package/dist/utils/base-path.js +23 -0
  574. package/dist/utils/base-path.js.map +1 -0
  575. package/dist/utils/error-handler.cjs +1 -1
  576. package/dist/utils/error-handler.cjs.map +1 -1
  577. package/dist/utils/error-handler.d.ts +1 -4
  578. package/dist/utils/error-handler.js +6 -7
  579. package/dist/utils/error-handler.js.map +1 -1
  580. package/dist/utils/map-provider.cjs +1 -1
  581. package/dist/utils/map-provider.cjs.map +1 -1
  582. package/dist/utils/map-provider.d.ts +1 -0
  583. package/dist/utils/map-provider.js +2 -1
  584. package/dist/utils/map-provider.js.map +1 -1
  585. package/package.json +3 -3
  586. package/scripts/check-sdk-version-sync.mjs +6 -6
  587. package/scripts/dev-safe.mjs +7 -8
  588. package/scripts/dev-static.mjs +3 -0
  589. package/scripts/dev-with-automation.mjs +3 -0
  590. package/scripts/docker-build.mjs +4 -0
  591. package/scripts/static-server.mjs +93 -7
  592. package/tools/canvas_ui_tool.py +14 -8
  593. package/build/assets/active-backend-context-hxq31W25.js +0 -1
  594. package/build/assets/agent-server-client-options-DVLRd9sw.js +0 -1
  595. package/build/assets/agent-server-conversation-service.api-CuSdr4Qb.js +0 -5
  596. package/build/assets/agent-settings-D_yOy8XB.js +0 -1
  597. package/build/assets/api-key-entry-screen-Dl0qVYi4.js +0 -1
  598. package/build/assets/app-settings-yVizGXox.js +0 -1
  599. package/build/assets/automation-detail-dvJfLs5u.js +0 -2
  600. package/build/assets/automation-export-BPcgLqPD.js +0 -2
  601. package/build/assets/automations-list-CUXogTe0.js +0 -1
  602. package/build/assets/backend-form-modal-CQJGmItq.js +0 -1
  603. package/build/assets/check-Bvi71siz.js +0 -1
  604. package/build/assets/condenser-settings-Ca8fYZ_Z.js +0 -1
  605. package/build/assets/conversation-9NBSRoR9.js +0 -1
  606. package/build/assets/conversation-BXg6Oti2.js +0 -89
  607. package/build/assets/conversation-panel-CZri9Rup.js +0 -1
  608. package/build/assets/conversation-service.api-DPBQvTKD.js +0 -1
  609. package/build/assets/declaration-gq8V5eTU.js +0 -1
  610. package/build/assets/files-tab-UVoray88.js +0 -1
  611. package/build/assets/git-provider-icon-o6hdnJUB.js +0 -1
  612. package/build/assets/handle-capture-consent-CPMXU29K.js +0 -1
  613. package/build/assets/home-D1IHvGTN.js +0 -1
  614. package/build/assets/index-redirect-CUUJiNki.js +0 -1
  615. package/build/assets/install-server-modal-BbuQaA2w.js +0 -1
  616. package/build/assets/lesson-plan-jC0HBoe6.js +0 -4
  617. package/build/assets/llm-not-configured-banner-DoARbcdL.js +0 -27
  618. package/build/assets/llm-settings-4JMLV8mq.js +0 -1
  619. package/build/assets/llm-settings-D91gMw3U.js +0 -1
  620. package/build/assets/llm-subscription-service-CKyaV24y.js +0 -1
  621. package/build/assets/loader-circle-BEykUKYG.js +0 -1
  622. package/build/assets/manage-backends-modal-DkWAMSle.js +0 -1
  623. package/build/assets/manifest-aa5c29f6.js +0 -1
  624. package/build/assets/model-selector-BfqpMkSJ.js +0 -1
  625. package/build/assets/mouse-pointer-click-PdEQPL6v.js +0 -1
  626. package/build/assets/onboarding-Bu-HN1ze.js +0 -1
  627. package/build/assets/onboarding-modal-CZgjs5Bx.js +0 -1
  628. package/build/assets/option-service.api-BrZ5q87N.js +0 -1
  629. package/build/assets/organization-service.api-Bk4pCGU1.js +0 -1
  630. package/build/assets/path-utils-CSmuZoix.js +0 -1
  631. package/build/assets/plugins-management-service-BRBLxvUl.js +0 -1
  632. package/build/assets/profiles-service.api-BMXQ9pZC.js +0 -1
  633. package/build/assets/providers-BpO967xS.js +0 -1
  634. package/build/assets/proxy-BgJLtxu7.js +0 -1
  635. package/build/assets/root-BM5WgQ4_.js +0 -2
  636. package/build/assets/root-V8fkplMy.css +0 -1
  637. package/build/assets/root-layout-BdoyoobY.js +0 -2
  638. package/build/assets/schema-field-BSHrUMme.js +0 -1
  639. package/build/assets/sdk-section-page-t82gsOqa.js +0 -1
  640. package/build/assets/search-4DHskuhE.js +0 -1
  641. package/build/assets/secrets-service-B2GqPV0N.js +0 -1
  642. package/build/assets/settings-DmPLkgq0.js +0 -1
  643. package/build/assets/settings-modal-CwrZKrTq.js +0 -1
  644. package/build/assets/settings-service.api-Ce-ub11I.js +0 -1
  645. package/build/assets/shared-conversation-BDREQPnE.js +0 -1
  646. package/build/assets/skills-plugins-2Y44YHbO.js +0 -1
  647. package/build/assets/use-acp-credential-form-MzZM6D7D.js +0 -1
  648. package/build/assets/use-agent-profiles-DwZxnwO5.js +0 -1
  649. package/build/assets/use-backends-health-CRHzuvxO.js +0 -1
  650. package/build/assets/use-cloud-current-user-id-utFreJ0i.js +0 -1
  651. package/build/assets/use-config-mJrtZHP1.js +0 -1
  652. package/build/assets/use-create-conversation-DdqsP78F.js +0 -1
  653. package/build/assets/use-is-authed-B6M0mcGL.js +0 -1
  654. package/build/assets/use-llm-profiles-RC-PkpBl.js +0 -1
  655. package/build/assets/use-plugins-marketplace-FHlbeQ4c.js +0 -1
  656. package/build/assets/use-runtime-is-ready-RKj2WmEh.js +0 -1
  657. package/build/assets/use-save-agent-profile-tvDP15mh.js +0 -1
  658. package/build/assets/use-save-settings-BGlSfuYn.js +0 -1
  659. package/build/assets/use-settings-CH5LzXD8.js +0 -1
  660. package/build/assets/use-settings-nav-items-Dwktv8wo.js +0 -16
  661. package/build/assets/use-skills-CSzSL6HG.js +0 -1
  662. package/build/assets/use-tracking-BIXzagSI.js +0 -1
  663. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~lf310vj7-CSVPGId3.js +0 -10
  664. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~nfpll1wp-BCpa95De.js +0 -177
  665. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~jewnulst-C57fm7C-.js +0 -1
  666. package/build/assets/vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CqXiHwjU.js +0 -2
  667. package/build/assets/x-Cb0WAtak.js +0 -1
  668. package/dist/components/providers/posthog-wrapper.cjs +0 -2
  669. package/dist/components/providers/posthog-wrapper.cjs.map +0 -1
  670. package/dist/components/providers/posthog-wrapper.d.ts +0 -4
  671. package/dist/components/providers/posthog-wrapper.js +0 -49
  672. package/dist/components/providers/posthog-wrapper.js.map +0 -1
  673. package/dist/node_modules/posthog-js/react/dist/esm/index.cjs +0 -2
  674. package/dist/node_modules/posthog-js/react/dist/esm/index.cjs.map +0 -1
  675. package/dist/node_modules/posthog-js/react/dist/esm/index.js +0 -113
  676. package/dist/node_modules/posthog-js/react/dist/esm/index.js.map +0 -1
  677. package/dist/utils/handle-capture-consent.cjs +0 -2
  678. package/dist/utils/handle-capture-consent.cjs.map +0 -1
  679. package/dist/utils/handle-capture-consent.d.ts +0 -7
  680. package/dist/utils/handle-capture-consent.js +0 -8
  681. package/dist/utils/handle-capture-consent.js.map +0 -1
  682. /package/build/assets/{__vite-browser-external-4xJsU2-u.js → __vite-browser-external-BQUj0sYu.js} +0 -0
  683. /package/build/assets/{agent-server-ui-style-scope-COnDHTm5.js → agent-server-ui-style-scope-qhnhZHBV.js} +0 -0
  684. /package/build/assets/{automation-BU8zu-FP.js → automation-LZB0MjdV.js} +0 -0
  685. /package/build/assets/{close-p3Op5lxI.js → close-DLFb5kfv.js} +0 -0
  686. /package/build/assets/{common-Dh7OqABE.js → common-CxbUL3nR.js} +0 -0
  687. /package/build/assets/{createLucideIcon-CVAsW2Yo.js → createLucideIcon-D4Tak8A1.js} +0 -0
  688. /package/build/assets/{folder-mMWFvaw0.js → folder-Bk311brm.js} +0 -0
  689. /package/build/assets/{get-language-from-path-CPNnuVhI.js → get-language-from-path-DBqBsCWH.js} +0 -0
  690. /package/build/assets/{git-status-mapper-BI8FyUVp.js → git-status-mapper-DnL9OC8_.js} +0 -0
  691. /package/build/assets/{iconBase-DaTRRUjy.js → iconBase-Dz51Zn5x.js} +0 -0
  692. /package/build/assets/{link-external-DfKQroKX.js → link-external-CaBmUEs_.js} +0 -0
  693. /package/build/assets/{search-BsjCEFNf.js → search-BgOCR7_c.js} +0 -0
  694. /package/build/assets/{settings-like-page-layout-classes-DENKlZpD.js → settings-like-page-layout-classes-Cdl6jOe5.js} +0 -0
  695. /package/build/assets/{skills-9cDZONKh.js → skills-EqzxYBvT.js} +0 -0
  696. /package/build/assets/{terminal-BuLtIrb9.js → terminal-Cgf___rK.js} +0 -0
  697. /package/build/assets/{u-check-circle-half-LiwZkuFe.js → u-check-circle-half-MsShT8Ec.js} +0 -0
  698. /package/build/assets/{u-edit-DJ90xc8Z.js → u-edit-DL5LgKon.js} +0 -0
  699. /package/build/assets/{use-breakpoint-B-O0lQ84.js → use-breakpoint-BP3lqLMx.js} +0 -0
  700. /package/build/assets/{use-click-outside-element-Bf4Omzot.js → use-click-outside-element-D9BYdANT.js} +0 -0
  701. /package/build/assets/{use-launch-skill-in-chat-BnoDgvAy.js → use-launch-skill-in-chat-DJWEfVc5.js} +0 -0
  702. /package/build/assets/{vendor~browser-Dqd33JyP.js → vendor~browser-By2MVv_N.js} +0 -0
  703. /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-DHDkknt5.js → vendor~conversation-panel~conversation~alert-banner-CxfzCmkN.js} +0 -0
  704. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~epa72zsm-B4rXs7Zd.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~e0djk9ee-Cw6LUe8p.js} +0 -0
  705. /package/build/assets/{vendor~entry.client~root~root-layout~index-redirect~home~conversation-panel~conversation~la~byh8a1g4-XNPdpuO8.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~jkpzbynd-CkpBIhVe.js} +0 -0
  706. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-9UMeuPV6.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-COhHANvV.js} +0 -0
  707. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DTzw2x50.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-FghQ3Z1a.js} +0 -0
  708. /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~skills-settings~automations-~ki5qnp0d-rV6d1Iv_.js → vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~j2jlu22h-mC0v44WR.js} +0 -0
  709. /package/build/assets/{vendor~root-layout~home~mcp~automations-list~onboarding-modal-CXyYYvYh.js → vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-C4-GDgiF.js} +0 -0
  710. /package/build/assets/{vendor~terminal-aeP3PnKf.js → vendor~terminal-CnKZILnC.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"files-tab.cjs","names":[],"sources":["../../src/routes/files-tab.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useQueryClient } from \"@tanstack/react-query\";\n\nimport { NoFileSelectedMessage } from \"#/components/features/files-tab/no-file-selected-message\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useFilesTabStore } from \"#/stores/files-tab-store\";\nimport { useWorkspaceFiles } from \"#/hooks/query/use-workspace-files\";\nimport { useWorkspaceFileContent } from \"#/hooks/query/use-workspace-file-content\";\nimport { useHasAttachedSource } from \"#/hooks/use-has-attached-source\";\nimport { useHasGitCommits } from \"#/hooks/query/use-has-git-commits\";\nimport { useAutoRefreshFilesOnEdit } from \"#/hooks/use-auto-refresh-files-on-edit\";\nimport { useUnifiedGetGitChanges } from \"#/hooks/query/use-unified-get-git-changes\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useConversationLocalStorageState } from \"#/utils/conversation-local-storage\";\nimport {\n useWorkspaceMutationCounter,\n withWorkspaceCacheBuster,\n} from \"#/stores/use-workspace-mutation-counter\";\nimport { sortFilesByPriority } from \"#/utils/file-priority\";\nimport { FileQuickRow } from \"#/components/features/files-tab/file-quick-row\";\nimport { FileTreeView } from \"#/components/features/files-tab/file-tree-view\";\nimport { FileContentViewer } from \"#/components/features/files-tab/file-content-viewer\";\nimport { SegmentedToggle } from \"#/components/features/files-tab/segmented-toggle\";\nimport type { ViewMode } from \"#/components/features/files-tab/view-mode\";\nimport RefreshIcon from \"#/icons/u-refresh.svg?react\";\nimport LinkExternalIcon from \"#/icons/link-external.svg?react\";\nimport GitChanges from \"./changes-tab\";\n\nfunction FilesTab() {\n const { t } = useTranslation(\"openhands\");\n\n // Keep the list / content / diff caches fresh as the agent writes files.\n useAutoRefreshFilesOnEdit();\n\n const { hasAttachedSource, isLoading: isAttachedSourceLoading } =\n useHasAttachedSource();\n // A workspace with zero commits has no diff base to compare against, so\n // the diff view would just be empty / misleading. Only probe when we\n // already believe the user attached a source — saves a workspace round\n // trip on every plain (no-attachment) conversation.\n const { hasCommits } = useHasGitCommits({ enabled: hasAttachedSource });\n\n // Diff view defaults to ON when the user attached a source (repo or\n // local workspace) *and* there's at least one commit, OFF otherwise\n // (no attachment, or attachment with no commits yet).\n //\n // While the attachment / commit probes are still resolving we stay\n // optimistic — most attached conversations live in a real repo, so\n // defaulting to diff during the brief loading window avoids a\n // \"files → diff\" flash on initial load. We only flip to files-view\n // once `hasAttachedSource` *or* `hasCommits` definitively resolves\n // false. The user's persisted choice always wins.\n const { conversationId } = useOptionalConversationId();\n const {\n state: persistedState,\n setFilesTabDiffView,\n setFilesTabContentViewMode,\n } = useConversationLocalStorageState(conversationId ?? \"\");\n\n const diffViewDefault =\n (hasAttachedSource || isAttachedSourceLoading) && hasCommits !== false;\n const diffViewEnabled = persistedState.filesTabDiffView ?? diffViewDefault;\n const contentViewMode = persistedState.filesTabContentViewMode;\n\n // Collapsed by default — the quick-access pill row at the top is usually\n // enough; the user can expand the tree on demand.\n const [isTreeVisible, setIsTreeVisible] = useState(false);\n\n const filesQuery = useWorkspaceFiles();\n const paths = useMemo(() => filesQuery.data ?? [], [filesQuery.data]);\n\n const storedSelectedPath = useFilesTabStore((s) => s.selectedPath);\n const selectedConversationId = useFilesTabStore(\n (s) => s.selectedConversationId,\n );\n const setSelectedPath = useFilesTabStore((s) => s.setSelectedPath);\n\n // A selection is scoped to the conversation it was made in. Ignore a path\n // that belongs to a different conversation so we never try to open a file\n // that only exists in the previous conversation's workspace (issue #1350).\n // The auto-select effect below then picks this conversation's top file.\n const selectedPath =\n selectedConversationId === conversationId ? storedSelectedPath : null;\n\n // Tag every selection with the active conversation so it can't leak into\n // the next one. FileQuickRow / FileTreeView call this with just the path.\n const handleSelectFile = useCallback(\n (path: string) => setSelectedPath(path, conversationId),\n [conversationId, setSelectedPath],\n );\n\n // Pre-fetch the selected file's content here too so the toolbar's\n // \"open in new window\" link can reach for its `staticUrl`. react-query\n // dedupes against `FileContentViewer`'s identical call, so this costs\n // nothing extra.\n const selectedFileContent = useWorkspaceFileContent(selectedPath);\n const mutationCounter = useWorkspaceMutationCounter((state) => state.count);\n const selectedFileStaticUrl = withWorkspaceCacheBuster(\n selectedFileContent.data?.staticUrl ?? null,\n mutationCounter,\n );\n\n useEffect(() => {\n if (selectedConversationId === conversationId) return;\n setSelectedPath(null, conversationId);\n }, [selectedConversationId, conversationId, setSelectedPath]);\n\n // Auto-select the highest-priority file the first time we load the list,\n // so users see something useful immediately.\n useEffect(() => {\n if (selectedPath || paths.length === 0) return;\n const [first] = sortFilesByPriority(paths);\n if (first) setSelectedPath(first, conversationId);\n }, [paths, selectedPath, conversationId, setSelectedPath]);\n\n // Refresh button: covers the diff view (git changes) and the file viewer\n // (workspace listing + cached file contents). Lives in this toolbar — not\n // in the outer ConversationTabs bar — so it sits with the other\n // files-tab-local controls.\n const queryClient = useQueryClient();\n const { refetch: refetchGitChanges, isFetching: isFetchingGitChanges } =\n useUnifiedGetGitChanges();\n const refreshFiles = () => {\n refetchGitChanges();\n queryClient.invalidateQueries({ queryKey: [\"workspace-files\"] });\n queryClient.invalidateQueries({ queryKey: [\"workspace-file-content\"] });\n };\n\n return (\n <main\n className=\"h-full w-full flex flex-col items-stretch\"\n data-testid=\"files-tab\"\n >\n {/* Top toolbar: diff/files + rich/plain toggles (left-aligned) plus\n the refresh button on the right. */}\n <div className=\"flex items-center gap-3 px-3 py-1.5 border-b border-[var(--oh-border)]\">\n <SegmentedToggle<\"on\" | \"off\">\n ariaLabel={t(I18nKey.FILES$DIFF_VIEW)}\n testId=\"files-tab-diff-toggle\"\n value={diffViewEnabled ? \"on\" : \"off\"}\n options={[\n { value: \"on\", label: t(I18nKey.FILES$DIFF_VIEW) },\n { value: \"off\", label: t(I18nKey.COMMON$FILES) },\n ]}\n onChange={(value) => setFilesTabDiffView(value === \"on\")}\n />\n\n {!diffViewEnabled && (\n <SegmentedToggle<ViewMode>\n ariaLabel={t(I18nKey.FILES$RICH)}\n testId=\"files-tab-content-mode-toggle\"\n value={contentViewMode}\n options={[\n { value: \"rich\", label: t(I18nKey.FILES$RICH) },\n { value: \"plain\", label: t(I18nKey.FILES$PLAIN) },\n ]}\n onChange={setFilesTabContentViewMode}\n />\n )}\n\n <div className=\"ml-auto flex items-center gap-1\">\n {/* Open the currently-selected file in a new browser tab. Only\n meaningful while we're showing a file (not the diff view) and\n we've resolved its staticUrl from the workspace fileserver. */}\n {!diffViewEnabled && selectedFileStaticUrl && (\n <a\n href={selectedFileStaticUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={t(I18nKey.FILES$OPEN_IN_NEW_WINDOW)}\n title={t(I18nKey.FILES$OPEN_IN_NEW_WINDOW)}\n data-testid=\"files-tab-open-in-new-window\"\n className=\"flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:bg-[var(--oh-interactive-hover)] cursor-pointer text-white\"\n >\n <LinkExternalIcon width={14} height={14} />\n </a>\n )}\n <button\n type=\"button\"\n onClick={refreshFiles}\n disabled={isFetchingGitChanges}\n aria-label={t(I18nKey.FILES$REFRESH)}\n title={t(I18nKey.FILES$REFRESH)}\n data-testid=\"files-tab-refresh\"\n className=\"flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:enabled:bg-[var(--oh-interactive-hover)] cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <RefreshIcon\n width={12.75}\n height={15}\n color=\"#ffffff\"\n className={isFetchingGitChanges ? \"animate-spin\" : \"\"}\n />\n </button>\n </div>\n </div>\n\n {diffViewEnabled ? (\n <div className=\"flex-1 min-h-0\">\n <GitChanges />\n </div>\n ) : (\n <div className=\"flex flex-1 flex-col min-h-0\">\n {filesQuery.isLoading ? (\n <div className=\"flex flex-1 items-center justify-center text-sm text-[var(--oh-muted)]\">\n {t(I18nKey.FILES$LOADING_FILES)}\n </div>\n ) : (\n <>\n <FileQuickRow\n paths={paths}\n selectedPath={selectedPath}\n onSelectFile={handleSelectFile}\n isTreeVisible={isTreeVisible}\n onToggleTree={() => setIsTreeVisible((prev) => !prev)}\n />\n <div className=\"flex h-full min-h-0 flex-1\">\n {isTreeVisible && (\n <aside\n className=\"w-56 shrink-0 border-r border-[var(--oh-border)] overflow-y-auto custom-scrollbar-always\"\n data-testid=\"files-tab-tree\"\n >\n <FileTreeView\n paths={paths}\n selectedPath={selectedPath}\n onSelectFile={handleSelectFile}\n />\n </aside>\n )}\n <section\n className=\"flex h-full min-h-0 min-w-0 flex-1 flex-col\"\n data-testid=\"files-tab-content\"\n >\n {selectedPath ? (\n <FileContentViewer\n path={selectedPath}\n viewMode={contentViewMode}\n />\n ) : (\n <NoFileSelectedMessage />\n )}\n </section>\n </div>\n </>\n )}\n </div>\n )}\n </main>\n );\n}\n\nexport default FilesTab;\n"],"mappings":"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"}
1
+ {"version":3,"file":"files-tab.cjs","names":[],"sources":["../../src/routes/files-tab.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useQueryClient } from \"@tanstack/react-query\";\n\nimport { NoFileSelectedMessage } from \"#/components/features/files-tab/no-file-selected-message\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useFilesTabStore } from \"#/stores/files-tab-store\";\nimport { useWorkspaceFiles } from \"#/hooks/query/use-workspace-files\";\nimport { useWorkspaceFileContent } from \"#/hooks/query/use-workspace-file-content\";\nimport { useHasAttachedSource } from \"#/hooks/use-has-attached-source\";\nimport { useHasGitCommits } from \"#/hooks/query/use-has-git-commits\";\nimport { useAutoRefreshFilesOnEdit } from \"#/hooks/use-auto-refresh-files-on-edit\";\nimport { useUnifiedGetGitChanges } from \"#/hooks/query/use-unified-get-git-changes\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useConversationLocalStorageState } from \"#/utils/conversation-local-storage\";\nimport {\n useWorkspaceMutationCounter,\n withWorkspaceCacheBuster,\n} from \"#/stores/use-workspace-mutation-counter\";\nimport { sortFilesByPriority } from \"#/utils/file-priority\";\nimport { FileQuickRow } from \"#/components/features/files-tab/file-quick-row\";\nimport { FileTreeView } from \"#/components/features/files-tab/file-tree-view\";\nimport { FileContentViewer } from \"#/components/features/files-tab/file-content-viewer\";\nimport { SegmentedToggle } from \"#/components/features/files-tab/segmented-toggle\";\nimport type { ViewMode } from \"#/components/features/files-tab/view-mode\";\nimport RefreshIcon from \"#/icons/u-refresh.svg?react\";\nimport LinkExternalIcon from \"#/icons/link-external.svg?react\";\nimport { useUnifiedGitCommits } from \"#/hooks/query/use-unified-git-commits\";\nimport GitChanges from \"./changes-tab\";\nimport GitCommits from \"./commits-tab\";\n\nfunction FilesTab() {\n const { t } = useTranslation(\"openhands\");\n\n // Keep the list / content / diff caches fresh as the agent writes files.\n useAutoRefreshFilesOnEdit();\n\n const { hasAttachedSource, isLoading: isAttachedSourceLoading } =\n useHasAttachedSource();\n // A workspace with zero commits has no diff base to compare against, so\n // the diff view would just be empty / misleading. Only probe when we\n // already believe the user attached a source — saves a workspace round\n // trip on every plain (no-attachment) conversation.\n const { hasCommits } = useHasGitCommits({ enabled: hasAttachedSource });\n\n // Diff view defaults to ON when the user attached a source (repo or\n // local workspace) *and* there's at least one commit, OFF otherwise\n // (no attachment, or attachment with no commits yet).\n //\n // While the attachment / commit probes are still resolving we stay\n // optimistic — most attached conversations live in a real repo, so\n // defaulting to diff during the brief loading window avoids a\n // \"files → diff\" flash on initial load. We only flip to files-view\n // once `hasAttachedSource` *or* `hasCommits` definitively resolves\n // false. The user's persisted choice always wins.\n const { conversationId } = useOptionalConversationId();\n const {\n state: persistedState,\n setFilesTabDiffView,\n setFilesTabContentViewMode,\n } = useConversationLocalStorageState(conversationId ?? \"\");\n\n const diffViewDefault =\n (hasAttachedSource || isAttachedSourceLoading) && hasCommits !== false;\n const diffViewEnabled = persistedState.filesTabDiffView ?? diffViewDefault;\n const contentViewMode = persistedState.filesTabContentViewMode;\n\n // Commit history gets a third toggle segment, offered only when the\n // agent server supports the commits API (older servers 404 → the toggle\n // stays two-way and the tab looks exactly as it did before). The\n // selection is session-local; the persisted diff/files preference is\n // untouched so falling out of the commits view restores it.\n const { isSuccess: commitsIsSuccess, isUnsupported: commitsUnsupported } =\n useUnifiedGitCommits();\n const showCommitsOption = commitsIsSuccess && !commitsUnsupported;\n const [commitsViewSelected, setCommitsViewSelected] = useState(false);\n let activeView: \"on\" | \"off\" | \"commits\" = diffViewEnabled ? \"on\" : \"off\";\n if (commitsViewSelected && showCommitsOption) activeView = \"commits\";\n\n // Collapsed by default — the quick-access pill row at the top is usually\n // enough; the user can expand the tree on demand.\n const [isTreeVisible, setIsTreeVisible] = useState(false);\n\n const filesQuery = useWorkspaceFiles();\n const paths = useMemo(() => filesQuery.data ?? [], [filesQuery.data]);\n\n const storedSelectedPath = useFilesTabStore((s) => s.selectedPath);\n const selectedConversationId = useFilesTabStore(\n (s) => s.selectedConversationId,\n );\n const setSelectedPath = useFilesTabStore((s) => s.setSelectedPath);\n\n // A selection is scoped to the conversation it was made in. Ignore a path\n // that belongs to a different conversation so we never try to open a file\n // that only exists in the previous conversation's workspace (issue #1350).\n // The auto-select effect below then picks this conversation's top file.\n const selectedPath =\n selectedConversationId === conversationId ? storedSelectedPath : null;\n\n // Tag every selection with the active conversation so it can't leak into\n // the next one. FileQuickRow / FileTreeView call this with just the path.\n const handleSelectFile = useCallback(\n (path: string) => setSelectedPath(path, conversationId),\n [conversationId, setSelectedPath],\n );\n\n // Pre-fetch the selected file's content here too so the toolbar's\n // \"open in new window\" link can reach for its `staticUrl`. react-query\n // dedupes against `FileContentViewer`'s identical call, so this costs\n // nothing extra.\n const selectedFileContent = useWorkspaceFileContent(selectedPath);\n const mutationCounter = useWorkspaceMutationCounter((state) => state.count);\n const selectedFileStaticUrl = withWorkspaceCacheBuster(\n selectedFileContent.data?.staticUrl ?? null,\n mutationCounter,\n );\n\n useEffect(() => {\n if (selectedConversationId === conversationId) return;\n setSelectedPath(null, conversationId);\n }, [selectedConversationId, conversationId, setSelectedPath]);\n\n // Auto-select the highest-priority file the first time we load the list,\n // so users see something useful immediately.\n useEffect(() => {\n if (selectedPath || paths.length === 0) return;\n const [first] = sortFilesByPriority(paths);\n if (first) setSelectedPath(first, conversationId);\n }, [paths, selectedPath, conversationId, setSelectedPath]);\n\n // Refresh button: covers the diff view (git changes) and the file viewer\n // (workspace listing + cached file contents). Lives in this toolbar — not\n // in the outer ConversationTabs bar — so it sits with the other\n // files-tab-local controls.\n const queryClient = useQueryClient();\n const { refetch: refetchGitChanges, isFetching: isFetchingGitChanges } =\n useUnifiedGetGitChanges();\n const refreshFiles = () => {\n refetchGitChanges();\n queryClient.invalidateQueries({ queryKey: [\"workspace-files\"] });\n queryClient.invalidateQueries({ queryKey: [\"workspace-file-content\"] });\n queryClient.invalidateQueries({ queryKey: [\"git_commits\"] });\n };\n\n return (\n <main\n className=\"h-full w-full flex flex-col items-stretch\"\n data-testid=\"files-tab\"\n >\n {/* Top toolbar: diff/files + rich/plain toggles (left-aligned) plus\n the refresh button on the right. */}\n <div className=\"flex items-center gap-3 px-3 py-1.5 border-b border-[var(--oh-border)]\">\n <SegmentedToggle<\"on\" | \"off\" | \"commits\">\n ariaLabel={t(I18nKey.FILES$DIFF_VIEW)}\n testId=\"files-tab-diff-toggle\"\n value={activeView}\n options={[\n { value: \"on\", label: t(I18nKey.FILES$DIFF_VIEW) },\n ...(showCommitsOption\n ? [\n {\n value: \"commits\" as const,\n label: t(I18nKey.DIFF_VIEWER$COMMITS),\n },\n ]\n : []),\n { value: \"off\", label: t(I18nKey.COMMON$FILES) },\n ]}\n onChange={(value) => {\n if (value === \"commits\") {\n setCommitsViewSelected(true);\n } else {\n setCommitsViewSelected(false);\n setFilesTabDiffView(value === \"on\");\n }\n }}\n />\n\n {activeView === \"off\" && (\n <SegmentedToggle<ViewMode>\n ariaLabel={t(I18nKey.FILES$RICH)}\n testId=\"files-tab-content-mode-toggle\"\n value={contentViewMode}\n options={[\n { value: \"rich\", label: t(I18nKey.FILES$RICH) },\n { value: \"plain\", label: t(I18nKey.FILES$PLAIN) },\n ]}\n onChange={setFilesTabContentViewMode}\n />\n )}\n\n <div className=\"ml-auto flex items-center gap-1\">\n {/* Open the currently-selected file in a new browser tab. Only\n meaningful while we're showing a file (not the diff view) and\n we've resolved its staticUrl from the workspace fileserver. */}\n {activeView === \"off\" && selectedFileStaticUrl && (\n <a\n href={selectedFileStaticUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={t(I18nKey.FILES$OPEN_IN_NEW_WINDOW)}\n title={t(I18nKey.FILES$OPEN_IN_NEW_WINDOW)}\n data-testid=\"files-tab-open-in-new-window\"\n className=\"flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:bg-[var(--oh-interactive-hover)] cursor-pointer text-white\"\n >\n <LinkExternalIcon width={14} height={14} />\n </a>\n )}\n <button\n type=\"button\"\n onClick={refreshFiles}\n disabled={isFetchingGitChanges}\n aria-label={t(I18nKey.FILES$REFRESH)}\n title={t(I18nKey.FILES$REFRESH)}\n data-testid=\"files-tab-refresh\"\n className=\"flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:enabled:bg-[var(--oh-interactive-hover)] cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <RefreshIcon\n width={12.75}\n height={15}\n color=\"#ffffff\"\n className={isFetchingGitChanges ? \"animate-spin\" : \"\"}\n />\n </button>\n </div>\n </div>\n\n {activeView === \"on\" && (\n <div className=\"flex-1 min-h-0\">\n <GitChanges />\n </div>\n )}\n {activeView === \"commits\" && (\n <div className=\"flex-1 min-h-0\">\n <GitCommits />\n </div>\n )}\n {activeView === \"off\" && (\n <div className=\"flex flex-1 flex-col min-h-0\">\n {filesQuery.isLoading ? (\n <div className=\"flex flex-1 items-center justify-center text-sm text-[var(--oh-muted)]\">\n {t(I18nKey.FILES$LOADING_FILES)}\n </div>\n ) : (\n <>\n <FileQuickRow\n paths={paths}\n selectedPath={selectedPath}\n onSelectFile={handleSelectFile}\n isTreeVisible={isTreeVisible}\n onToggleTree={() => setIsTreeVisible((prev) => !prev)}\n />\n <div className=\"flex h-full min-h-0 flex-1\">\n {isTreeVisible && (\n <aside\n className=\"w-56 shrink-0 border-r border-[var(--oh-border)] overflow-y-auto custom-scrollbar-always\"\n data-testid=\"files-tab-tree\"\n >\n <FileTreeView\n paths={paths}\n selectedPath={selectedPath}\n onSelectFile={handleSelectFile}\n />\n </aside>\n )}\n <section\n className=\"flex h-full min-h-0 min-w-0 flex-1 flex-col\"\n data-testid=\"files-tab-content\"\n >\n {selectedPath ? (\n <FileContentViewer\n path={selectedPath}\n viewMode={contentViewMode}\n />\n ) : (\n <NoFileSelectedMessage />\n )}\n </section>\n </div>\n </>\n )}\n </div>\n )}\n </main>\n );\n}\n\nexport default FilesTab;\n"],"mappings":"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"}
@@ -9,143 +9,164 @@ import { SegmentedToggle as s } from "../components/features/files-tab/segmented
9
9
  import { NoFileSelectedMessage as c } from "../components/features/files-tab/no-file-selected-message.js";
10
10
  import { useUnifiedGetGitChanges as l } from "../hooks/query/use-unified-get-git-changes.js";
11
11
  import { useWorkspaceFiles as u } from "../hooks/query/use-workspace-files.js";
12
- import { useWorkspaceMutationCounter as d, withWorkspaceCacheBuster as f } from "../stores/use-workspace-mutation-counter.js";
13
- import { useWorkspaceFileContent as p } from "../hooks/query/use-workspace-file-content.js";
14
- import { useHasAttachedSource as m } from "../hooks/use-has-attached-source.js";
15
- import { useHasGitCommits as h } from "../hooks/query/use-has-git-commits.js";
16
- import { useAutoRefreshFilesOnEdit as g } from "../hooks/use-auto-refresh-files-on-edit.js";
17
- import { sortFilesByPriority as _ } from "../utils/file-priority.js";
18
- import { FileQuickRow as v } from "../components/features/files-tab/file-quick-row.js";
19
- import { FileTreeView as y } from "../components/features/files-tab/file-tree-view.js";
20
- import { FileContentViewer as b } from "../components/features/files-tab/file-content-viewer.js";
21
- import x from "../icons/u-refresh.js";
22
- import S from "./changes-tab.js";
23
- import { useCallback as ee, useEffect as C, useMemo as w, useState as T } from "react";
24
- import { Fragment as E, jsx as D, jsxs as O } from "react/jsx-runtime";
12
+ import { useWorkspaceMutationCounter as ee, withWorkspaceCacheBuster as te } from "../stores/use-workspace-mutation-counter.js";
13
+ import { useWorkspaceFileContent as ne } from "../hooks/query/use-workspace-file-content.js";
14
+ import { useHasAttachedSource as re } from "../hooks/use-has-attached-source.js";
15
+ import { useHasGitCommits as d } from "../hooks/query/use-has-git-commits.js";
16
+ import { useAutoRefreshFilesOnEdit as f } from "../hooks/use-auto-refresh-files-on-edit.js";
17
+ import { sortFilesByPriority as ie } from "../utils/file-priority.js";
18
+ import { FileQuickRow as p } from "../components/features/files-tab/file-quick-row.js";
19
+ import { FileTreeView as m } from "../components/features/files-tab/file-tree-view.js";
20
+ import { FileContentViewer as h } from "../components/features/files-tab/file-content-viewer.js";
21
+ import g from "../icons/u-refresh.js";
22
+ import { useUnifiedGitCommits as _ } from "../hooks/query/use-unified-git-commits.js";
23
+ import v from "./changes-tab.js";
24
+ import y from "./commits-tab.js";
25
+ import { useCallback as b, useEffect as x, useMemo as ae, useState as S } from "react";
26
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
25
27
  //#region src/routes/files-tab.tsx
26
- function k() {
27
- let { t: k } = e("openhands");
28
- g();
29
- let { hasAttachedSource: A, isLoading: j } = m(), { hasCommits: M } = h({ enabled: A }), { conversationId: N } = n(), { state: P, setFilesTabDiffView: F, setFilesTabContentViewMode: I } = r(N ?? ""), L = (A || j) && M !== !1, R = P.filesTabDiffView ?? L, z = P.filesTabContentViewMode, [B, V] = T(!1), H = u(), U = w(() => H.data ?? [], [H.data]), W = a((e) => e.selectedPath), G = a((e) => e.selectedConversationId), K = a((e) => e.setSelectedPath), q = G === N ? W : null, J = ee((e) => K(e, N), [N, K]), Y = p(q), X = d((e) => e.count), Z = f(Y.data?.staticUrl ?? null, X);
30
- C(() => {
31
- G !== N && K(null, N);
28
+ function E() {
29
+ let { t: E } = e("openhands");
30
+ f();
31
+ let { hasAttachedSource: D, isLoading: O } = re(), { hasCommits: k } = d({ enabled: D }), { conversationId: A } = n(), { state: j, setFilesTabDiffView: M, setFilesTabContentViewMode: N } = r(A ?? ""), P = (D || O) && k !== !1, F = j.filesTabDiffView ?? P, I = j.filesTabContentViewMode, { isSuccess: oe, isUnsupported: L } = _(), R = oe && !L, [z, B] = S(!1), V = F ? "on" : "off";
32
+ z && R && (V = "commits");
33
+ let [H, U] = S(!1), W = u(), G = ae(() => W.data ?? [], [W.data]), K = a((e) => e.selectedPath), q = a((e) => e.selectedConversationId), J = a((e) => e.setSelectedPath), Y = q === A ? K : null, X = b((e) => J(e, A), [A, J]), se = ne(Y), ce = ee((e) => e.count), Z = te(se.data?.staticUrl ?? null, ce);
34
+ x(() => {
35
+ q !== A && J(null, A);
32
36
  }, [
33
- G,
34
- N,
35
- K
36
- ]), C(() => {
37
- if (q || U.length === 0) return;
38
- let [e] = _(U);
39
- e && K(e, N);
40
- }, [
41
- U,
42
37
  q,
43
- N,
44
- K
38
+ A,
39
+ J
40
+ ]), x(() => {
41
+ if (Y || G.length === 0) return;
42
+ let [e] = ie(G);
43
+ e && J(e, A);
44
+ }, [
45
+ G,
46
+ Y,
47
+ A,
48
+ J
45
49
  ]);
46
- let Q = i(), { refetch: te, isFetching: $ } = l();
47
- return /* @__PURE__ */ O("main", {
50
+ let Q = i(), { refetch: le, isFetching: $ } = l(), ue = () => {
51
+ le(), Q.invalidateQueries({ queryKey: ["workspace-files"] }), Q.invalidateQueries({ queryKey: ["workspace-file-content"] }), Q.invalidateQueries({ queryKey: ["git_commits"] });
52
+ };
53
+ return /* @__PURE__ */ T("main", {
48
54
  className: "h-full w-full flex flex-col items-stretch",
49
55
  "data-testid": "files-tab",
50
- children: [/* @__PURE__ */ O("div", {
51
- className: "flex items-center gap-3 px-3 py-1.5 border-b border-[var(--oh-border)]",
52
- children: [
53
- /* @__PURE__ */ D(s, {
54
- ariaLabel: k(t.FILES$DIFF_VIEW),
55
- testId: "files-tab-diff-toggle",
56
- value: R ? "on" : "off",
57
- options: [{
58
- value: "on",
59
- label: k(t.FILES$DIFF_VIEW)
60
- }, {
61
- value: "off",
62
- label: k(t.COMMON$FILES)
63
- }],
64
- onChange: (e) => F(e === "on")
65
- }),
66
- !R && /* @__PURE__ */ D(s, {
67
- ariaLabel: k(t.FILES$RICH),
68
- testId: "files-tab-content-mode-toggle",
69
- value: z,
70
- options: [{
71
- value: "rich",
72
- label: k(t.FILES$RICH)
73
- }, {
74
- value: "plain",
75
- label: k(t.FILES$PLAIN)
76
- }],
77
- onChange: I
78
- }),
79
- /* @__PURE__ */ O("div", {
80
- className: "ml-auto flex items-center gap-1",
81
- children: [!R && Z && /* @__PURE__ */ D("a", {
82
- href: Z,
83
- target: "_blank",
84
- rel: "noopener noreferrer",
85
- "aria-label": k(t.FILES$OPEN_IN_NEW_WINDOW),
86
- title: k(t.FILES$OPEN_IN_NEW_WINDOW),
87
- "data-testid": "files-tab-open-in-new-window",
88
- className: "flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:bg-[var(--oh-interactive-hover)] cursor-pointer text-white",
89
- children: /* @__PURE__ */ D(o, {
90
- width: 14,
91
- height: 14
92
- })
93
- }), /* @__PURE__ */ D("button", {
94
- type: "button",
95
- onClick: () => {
96
- te(), Q.invalidateQueries({ queryKey: ["workspace-files"] }), Q.invalidateQueries({ queryKey: ["workspace-file-content"] });
97
- },
98
- disabled: $,
99
- "aria-label": k(t.FILES$REFRESH),
100
- title: k(t.FILES$REFRESH),
101
- "data-testid": "files-tab-refresh",
102
- className: "flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:enabled:bg-[var(--oh-interactive-hover)] cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed",
103
- children: /* @__PURE__ */ D(x, {
104
- width: 12.75,
105
- height: 15,
106
- color: "#ffffff",
107
- className: $ ? "animate-spin" : ""
56
+ children: [
57
+ /* @__PURE__ */ T("div", {
58
+ className: "flex items-center gap-3 px-3 py-1.5 border-b border-[var(--oh-border)]",
59
+ children: [
60
+ /* @__PURE__ */ w(s, {
61
+ ariaLabel: E(t.FILES$DIFF_VIEW),
62
+ testId: "files-tab-diff-toggle",
63
+ value: V,
64
+ options: [
65
+ {
66
+ value: "on",
67
+ label: E(t.FILES$DIFF_VIEW)
68
+ },
69
+ ...R ? [{
70
+ value: "commits",
71
+ label: E(t.DIFF_VIEWER$COMMITS)
72
+ }] : [],
73
+ {
74
+ value: "off",
75
+ label: E(t.COMMON$FILES)
76
+ }
77
+ ],
78
+ onChange: (e) => {
79
+ e === "commits" ? B(!0) : (B(!1), M(e === "on"));
80
+ }
81
+ }),
82
+ V === "off" && /* @__PURE__ */ w(s, {
83
+ ariaLabel: E(t.FILES$RICH),
84
+ testId: "files-tab-content-mode-toggle",
85
+ value: I,
86
+ options: [{
87
+ value: "rich",
88
+ label: E(t.FILES$RICH)
89
+ }, {
90
+ value: "plain",
91
+ label: E(t.FILES$PLAIN)
92
+ }],
93
+ onChange: N
94
+ }),
95
+ /* @__PURE__ */ T("div", {
96
+ className: "ml-auto flex items-center gap-1",
97
+ children: [V === "off" && Z && /* @__PURE__ */ w("a", {
98
+ href: Z,
99
+ target: "_blank",
100
+ rel: "noopener noreferrer",
101
+ "aria-label": E(t.FILES$OPEN_IN_NEW_WINDOW),
102
+ title: E(t.FILES$OPEN_IN_NEW_WINDOW),
103
+ "data-testid": "files-tab-open-in-new-window",
104
+ className: "flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:bg-[var(--oh-interactive-hover)] cursor-pointer text-white",
105
+ children: /* @__PURE__ */ w(o, {
106
+ width: 14,
107
+ height: 14
108
+ })
109
+ }), /* @__PURE__ */ w("button", {
110
+ type: "button",
111
+ onClick: ue,
112
+ disabled: $,
113
+ "aria-label": E(t.FILES$REFRESH),
114
+ title: E(t.FILES$REFRESH),
115
+ "data-testid": "files-tab-refresh",
116
+ className: "flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:enabled:bg-[var(--oh-interactive-hover)] cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed",
117
+ children: /* @__PURE__ */ w(g, {
118
+ width: 12.75,
119
+ height: 15,
120
+ color: "#ffffff",
121
+ className: $ ? "animate-spin" : ""
122
+ })
123
+ })]
124
+ })
125
+ ]
126
+ }),
127
+ V === "on" && /* @__PURE__ */ w("div", {
128
+ className: "flex-1 min-h-0",
129
+ children: /* @__PURE__ */ w(v, {})
130
+ }),
131
+ V === "commits" && /* @__PURE__ */ w("div", {
132
+ className: "flex-1 min-h-0",
133
+ children: /* @__PURE__ */ w(y, {})
134
+ }),
135
+ V === "off" && /* @__PURE__ */ w("div", {
136
+ className: "flex flex-1 flex-col min-h-0",
137
+ children: W.isLoading ? /* @__PURE__ */ w("div", {
138
+ className: "flex flex-1 items-center justify-center text-sm text-[var(--oh-muted)]",
139
+ children: E(t.FILES$LOADING_FILES)
140
+ }) : /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(p, {
141
+ paths: G,
142
+ selectedPath: Y,
143
+ onSelectFile: X,
144
+ isTreeVisible: H,
145
+ onToggleTree: () => U((e) => !e)
146
+ }), /* @__PURE__ */ T("div", {
147
+ className: "flex h-full min-h-0 flex-1",
148
+ children: [H && /* @__PURE__ */ w("aside", {
149
+ className: "w-56 shrink-0 border-r border-[var(--oh-border)] overflow-y-auto custom-scrollbar-always",
150
+ "data-testid": "files-tab-tree",
151
+ children: /* @__PURE__ */ w(m, {
152
+ paths: G,
153
+ selectedPath: Y,
154
+ onSelectFile: X
108
155
  })
156
+ }), /* @__PURE__ */ w("section", {
157
+ className: "flex h-full min-h-0 min-w-0 flex-1 flex-col",
158
+ "data-testid": "files-tab-content",
159
+ children: Y ? /* @__PURE__ */ w(h, {
160
+ path: Y,
161
+ viewMode: I
162
+ }) : /* @__PURE__ */ w(c, {})
109
163
  })]
110
- })
111
- ]
112
- }), R ? /* @__PURE__ */ D("div", {
113
- className: "flex-1 min-h-0",
114
- children: /* @__PURE__ */ D(S, {})
115
- }) : /* @__PURE__ */ D("div", {
116
- className: "flex flex-1 flex-col min-h-0",
117
- children: H.isLoading ? /* @__PURE__ */ D("div", {
118
- className: "flex flex-1 items-center justify-center text-sm text-[var(--oh-muted)]",
119
- children: k(t.FILES$LOADING_FILES)
120
- }) : /* @__PURE__ */ O(E, { children: [/* @__PURE__ */ D(v, {
121
- paths: U,
122
- selectedPath: q,
123
- onSelectFile: J,
124
- isTreeVisible: B,
125
- onToggleTree: () => V((e) => !e)
126
- }), /* @__PURE__ */ O("div", {
127
- className: "flex h-full min-h-0 flex-1",
128
- children: [B && /* @__PURE__ */ D("aside", {
129
- className: "w-56 shrink-0 border-r border-[var(--oh-border)] overflow-y-auto custom-scrollbar-always",
130
- "data-testid": "files-tab-tree",
131
- children: /* @__PURE__ */ D(y, {
132
- paths: U,
133
- selectedPath: q,
134
- onSelectFile: J
135
- })
136
- }), /* @__PURE__ */ D("section", {
137
- className: "flex h-full min-h-0 min-w-0 flex-1 flex-col",
138
- "data-testid": "files-tab-content",
139
- children: q ? /* @__PURE__ */ D(b, {
140
- path: q,
141
- viewMode: z
142
- }) : /* @__PURE__ */ D(c, {})
143
- })]
144
- })] })
145
- })]
164
+ })] })
165
+ })
166
+ ]
146
167
  });
147
168
  }
148
169
  //#endregion
149
- export { k as default };
170
+ export { E as default };
150
171
 
151
172
  //# sourceMappingURL=files-tab.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"files-tab.js","names":[],"sources":["../../src/routes/files-tab.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useQueryClient } from \"@tanstack/react-query\";\n\nimport { NoFileSelectedMessage } from \"#/components/features/files-tab/no-file-selected-message\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useFilesTabStore } from \"#/stores/files-tab-store\";\nimport { useWorkspaceFiles } from \"#/hooks/query/use-workspace-files\";\nimport { useWorkspaceFileContent } from \"#/hooks/query/use-workspace-file-content\";\nimport { useHasAttachedSource } from \"#/hooks/use-has-attached-source\";\nimport { useHasGitCommits } from \"#/hooks/query/use-has-git-commits\";\nimport { useAutoRefreshFilesOnEdit } from \"#/hooks/use-auto-refresh-files-on-edit\";\nimport { useUnifiedGetGitChanges } from \"#/hooks/query/use-unified-get-git-changes\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useConversationLocalStorageState } from \"#/utils/conversation-local-storage\";\nimport {\n useWorkspaceMutationCounter,\n withWorkspaceCacheBuster,\n} from \"#/stores/use-workspace-mutation-counter\";\nimport { sortFilesByPriority } from \"#/utils/file-priority\";\nimport { FileQuickRow } from \"#/components/features/files-tab/file-quick-row\";\nimport { FileTreeView } from \"#/components/features/files-tab/file-tree-view\";\nimport { FileContentViewer } from \"#/components/features/files-tab/file-content-viewer\";\nimport { SegmentedToggle } from \"#/components/features/files-tab/segmented-toggle\";\nimport type { ViewMode } from \"#/components/features/files-tab/view-mode\";\nimport RefreshIcon from \"#/icons/u-refresh.svg?react\";\nimport LinkExternalIcon from \"#/icons/link-external.svg?react\";\nimport GitChanges from \"./changes-tab\";\n\nfunction FilesTab() {\n const { t } = useTranslation(\"openhands\");\n\n // Keep the list / content / diff caches fresh as the agent writes files.\n useAutoRefreshFilesOnEdit();\n\n const { hasAttachedSource, isLoading: isAttachedSourceLoading } =\n useHasAttachedSource();\n // A workspace with zero commits has no diff base to compare against, so\n // the diff view would just be empty / misleading. Only probe when we\n // already believe the user attached a source — saves a workspace round\n // trip on every plain (no-attachment) conversation.\n const { hasCommits } = useHasGitCommits({ enabled: hasAttachedSource });\n\n // Diff view defaults to ON when the user attached a source (repo or\n // local workspace) *and* there's at least one commit, OFF otherwise\n // (no attachment, or attachment with no commits yet).\n //\n // While the attachment / commit probes are still resolving we stay\n // optimistic — most attached conversations live in a real repo, so\n // defaulting to diff during the brief loading window avoids a\n // \"files → diff\" flash on initial load. We only flip to files-view\n // once `hasAttachedSource` *or* `hasCommits` definitively resolves\n // false. The user's persisted choice always wins.\n const { conversationId } = useOptionalConversationId();\n const {\n state: persistedState,\n setFilesTabDiffView,\n setFilesTabContentViewMode,\n } = useConversationLocalStorageState(conversationId ?? \"\");\n\n const diffViewDefault =\n (hasAttachedSource || isAttachedSourceLoading) && hasCommits !== false;\n const diffViewEnabled = persistedState.filesTabDiffView ?? diffViewDefault;\n const contentViewMode = persistedState.filesTabContentViewMode;\n\n // Collapsed by default — the quick-access pill row at the top is usually\n // enough; the user can expand the tree on demand.\n const [isTreeVisible, setIsTreeVisible] = useState(false);\n\n const filesQuery = useWorkspaceFiles();\n const paths = useMemo(() => filesQuery.data ?? [], [filesQuery.data]);\n\n const storedSelectedPath = useFilesTabStore((s) => s.selectedPath);\n const selectedConversationId = useFilesTabStore(\n (s) => s.selectedConversationId,\n );\n const setSelectedPath = useFilesTabStore((s) => s.setSelectedPath);\n\n // A selection is scoped to the conversation it was made in. Ignore a path\n // that belongs to a different conversation so we never try to open a file\n // that only exists in the previous conversation's workspace (issue #1350).\n // The auto-select effect below then picks this conversation's top file.\n const selectedPath =\n selectedConversationId === conversationId ? storedSelectedPath : null;\n\n // Tag every selection with the active conversation so it can't leak into\n // the next one. FileQuickRow / FileTreeView call this with just the path.\n const handleSelectFile = useCallback(\n (path: string) => setSelectedPath(path, conversationId),\n [conversationId, setSelectedPath],\n );\n\n // Pre-fetch the selected file's content here too so the toolbar's\n // \"open in new window\" link can reach for its `staticUrl`. react-query\n // dedupes against `FileContentViewer`'s identical call, so this costs\n // nothing extra.\n const selectedFileContent = useWorkspaceFileContent(selectedPath);\n const mutationCounter = useWorkspaceMutationCounter((state) => state.count);\n const selectedFileStaticUrl = withWorkspaceCacheBuster(\n selectedFileContent.data?.staticUrl ?? null,\n mutationCounter,\n );\n\n useEffect(() => {\n if (selectedConversationId === conversationId) return;\n setSelectedPath(null, conversationId);\n }, [selectedConversationId, conversationId, setSelectedPath]);\n\n // Auto-select the highest-priority file the first time we load the list,\n // so users see something useful immediately.\n useEffect(() => {\n if (selectedPath || paths.length === 0) return;\n const [first] = sortFilesByPriority(paths);\n if (first) setSelectedPath(first, conversationId);\n }, [paths, selectedPath, conversationId, setSelectedPath]);\n\n // Refresh button: covers the diff view (git changes) and the file viewer\n // (workspace listing + cached file contents). Lives in this toolbar — not\n // in the outer ConversationTabs bar — so it sits with the other\n // files-tab-local controls.\n const queryClient = useQueryClient();\n const { refetch: refetchGitChanges, isFetching: isFetchingGitChanges } =\n useUnifiedGetGitChanges();\n const refreshFiles = () => {\n refetchGitChanges();\n queryClient.invalidateQueries({ queryKey: [\"workspace-files\"] });\n queryClient.invalidateQueries({ queryKey: [\"workspace-file-content\"] });\n };\n\n return (\n <main\n className=\"h-full w-full flex flex-col items-stretch\"\n data-testid=\"files-tab\"\n >\n {/* Top toolbar: diff/files + rich/plain toggles (left-aligned) plus\n the refresh button on the right. */}\n <div className=\"flex items-center gap-3 px-3 py-1.5 border-b border-[var(--oh-border)]\">\n <SegmentedToggle<\"on\" | \"off\">\n ariaLabel={t(I18nKey.FILES$DIFF_VIEW)}\n testId=\"files-tab-diff-toggle\"\n value={diffViewEnabled ? \"on\" : \"off\"}\n options={[\n { value: \"on\", label: t(I18nKey.FILES$DIFF_VIEW) },\n { value: \"off\", label: t(I18nKey.COMMON$FILES) },\n ]}\n onChange={(value) => setFilesTabDiffView(value === \"on\")}\n />\n\n {!diffViewEnabled && (\n <SegmentedToggle<ViewMode>\n ariaLabel={t(I18nKey.FILES$RICH)}\n testId=\"files-tab-content-mode-toggle\"\n value={contentViewMode}\n options={[\n { value: \"rich\", label: t(I18nKey.FILES$RICH) },\n { value: \"plain\", label: t(I18nKey.FILES$PLAIN) },\n ]}\n onChange={setFilesTabContentViewMode}\n />\n )}\n\n <div className=\"ml-auto flex items-center gap-1\">\n {/* Open the currently-selected file in a new browser tab. Only\n meaningful while we're showing a file (not the diff view) and\n we've resolved its staticUrl from the workspace fileserver. */}\n {!diffViewEnabled && selectedFileStaticUrl && (\n <a\n href={selectedFileStaticUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={t(I18nKey.FILES$OPEN_IN_NEW_WINDOW)}\n title={t(I18nKey.FILES$OPEN_IN_NEW_WINDOW)}\n data-testid=\"files-tab-open-in-new-window\"\n className=\"flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:bg-[var(--oh-interactive-hover)] cursor-pointer text-white\"\n >\n <LinkExternalIcon width={14} height={14} />\n </a>\n )}\n <button\n type=\"button\"\n onClick={refreshFiles}\n disabled={isFetchingGitChanges}\n aria-label={t(I18nKey.FILES$REFRESH)}\n title={t(I18nKey.FILES$REFRESH)}\n data-testid=\"files-tab-refresh\"\n className=\"flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:enabled:bg-[var(--oh-interactive-hover)] cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <RefreshIcon\n width={12.75}\n height={15}\n color=\"#ffffff\"\n className={isFetchingGitChanges ? \"animate-spin\" : \"\"}\n />\n </button>\n </div>\n </div>\n\n {diffViewEnabled ? (\n <div className=\"flex-1 min-h-0\">\n <GitChanges />\n </div>\n ) : (\n <div className=\"flex flex-1 flex-col min-h-0\">\n {filesQuery.isLoading ? (\n <div className=\"flex flex-1 items-center justify-center text-sm text-[var(--oh-muted)]\">\n {t(I18nKey.FILES$LOADING_FILES)}\n </div>\n ) : (\n <>\n <FileQuickRow\n paths={paths}\n selectedPath={selectedPath}\n onSelectFile={handleSelectFile}\n isTreeVisible={isTreeVisible}\n onToggleTree={() => setIsTreeVisible((prev) => !prev)}\n />\n <div className=\"flex h-full min-h-0 flex-1\">\n {isTreeVisible && (\n <aside\n className=\"w-56 shrink-0 border-r border-[var(--oh-border)] overflow-y-auto custom-scrollbar-always\"\n data-testid=\"files-tab-tree\"\n >\n <FileTreeView\n paths={paths}\n selectedPath={selectedPath}\n onSelectFile={handleSelectFile}\n />\n </aside>\n )}\n <section\n className=\"flex h-full min-h-0 min-w-0 flex-1 flex-col\"\n data-testid=\"files-tab-content\"\n >\n {selectedPath ? (\n <FileContentViewer\n path={selectedPath}\n viewMode={contentViewMode}\n />\n ) : (\n <NoFileSelectedMessage />\n )}\n </section>\n </div>\n </>\n )}\n </div>\n )}\n </main>\n );\n}\n\nexport default FilesTab;\n"],"mappings":"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"}
1
+ {"version":3,"file":"files-tab.js","names":[],"sources":["../../src/routes/files-tab.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useQueryClient } from \"@tanstack/react-query\";\n\nimport { NoFileSelectedMessage } from \"#/components/features/files-tab/no-file-selected-message\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useFilesTabStore } from \"#/stores/files-tab-store\";\nimport { useWorkspaceFiles } from \"#/hooks/query/use-workspace-files\";\nimport { useWorkspaceFileContent } from \"#/hooks/query/use-workspace-file-content\";\nimport { useHasAttachedSource } from \"#/hooks/use-has-attached-source\";\nimport { useHasGitCommits } from \"#/hooks/query/use-has-git-commits\";\nimport { useAutoRefreshFilesOnEdit } from \"#/hooks/use-auto-refresh-files-on-edit\";\nimport { useUnifiedGetGitChanges } from \"#/hooks/query/use-unified-get-git-changes\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useConversationLocalStorageState } from \"#/utils/conversation-local-storage\";\nimport {\n useWorkspaceMutationCounter,\n withWorkspaceCacheBuster,\n} from \"#/stores/use-workspace-mutation-counter\";\nimport { sortFilesByPriority } from \"#/utils/file-priority\";\nimport { FileQuickRow } from \"#/components/features/files-tab/file-quick-row\";\nimport { FileTreeView } from \"#/components/features/files-tab/file-tree-view\";\nimport { FileContentViewer } from \"#/components/features/files-tab/file-content-viewer\";\nimport { SegmentedToggle } from \"#/components/features/files-tab/segmented-toggle\";\nimport type { ViewMode } from \"#/components/features/files-tab/view-mode\";\nimport RefreshIcon from \"#/icons/u-refresh.svg?react\";\nimport LinkExternalIcon from \"#/icons/link-external.svg?react\";\nimport { useUnifiedGitCommits } from \"#/hooks/query/use-unified-git-commits\";\nimport GitChanges from \"./changes-tab\";\nimport GitCommits from \"./commits-tab\";\n\nfunction FilesTab() {\n const { t } = useTranslation(\"openhands\");\n\n // Keep the list / content / diff caches fresh as the agent writes files.\n useAutoRefreshFilesOnEdit();\n\n const { hasAttachedSource, isLoading: isAttachedSourceLoading } =\n useHasAttachedSource();\n // A workspace with zero commits has no diff base to compare against, so\n // the diff view would just be empty / misleading. Only probe when we\n // already believe the user attached a source — saves a workspace round\n // trip on every plain (no-attachment) conversation.\n const { hasCommits } = useHasGitCommits({ enabled: hasAttachedSource });\n\n // Diff view defaults to ON when the user attached a source (repo or\n // local workspace) *and* there's at least one commit, OFF otherwise\n // (no attachment, or attachment with no commits yet).\n //\n // While the attachment / commit probes are still resolving we stay\n // optimistic — most attached conversations live in a real repo, so\n // defaulting to diff during the brief loading window avoids a\n // \"files → diff\" flash on initial load. We only flip to files-view\n // once `hasAttachedSource` *or* `hasCommits` definitively resolves\n // false. The user's persisted choice always wins.\n const { conversationId } = useOptionalConversationId();\n const {\n state: persistedState,\n setFilesTabDiffView,\n setFilesTabContentViewMode,\n } = useConversationLocalStorageState(conversationId ?? \"\");\n\n const diffViewDefault =\n (hasAttachedSource || isAttachedSourceLoading) && hasCommits !== false;\n const diffViewEnabled = persistedState.filesTabDiffView ?? diffViewDefault;\n const contentViewMode = persistedState.filesTabContentViewMode;\n\n // Commit history gets a third toggle segment, offered only when the\n // agent server supports the commits API (older servers 404 → the toggle\n // stays two-way and the tab looks exactly as it did before). The\n // selection is session-local; the persisted diff/files preference is\n // untouched so falling out of the commits view restores it.\n const { isSuccess: commitsIsSuccess, isUnsupported: commitsUnsupported } =\n useUnifiedGitCommits();\n const showCommitsOption = commitsIsSuccess && !commitsUnsupported;\n const [commitsViewSelected, setCommitsViewSelected] = useState(false);\n let activeView: \"on\" | \"off\" | \"commits\" = diffViewEnabled ? \"on\" : \"off\";\n if (commitsViewSelected && showCommitsOption) activeView = \"commits\";\n\n // Collapsed by default — the quick-access pill row at the top is usually\n // enough; the user can expand the tree on demand.\n const [isTreeVisible, setIsTreeVisible] = useState(false);\n\n const filesQuery = useWorkspaceFiles();\n const paths = useMemo(() => filesQuery.data ?? [], [filesQuery.data]);\n\n const storedSelectedPath = useFilesTabStore((s) => s.selectedPath);\n const selectedConversationId = useFilesTabStore(\n (s) => s.selectedConversationId,\n );\n const setSelectedPath = useFilesTabStore((s) => s.setSelectedPath);\n\n // A selection is scoped to the conversation it was made in. Ignore a path\n // that belongs to a different conversation so we never try to open a file\n // that only exists in the previous conversation's workspace (issue #1350).\n // The auto-select effect below then picks this conversation's top file.\n const selectedPath =\n selectedConversationId === conversationId ? storedSelectedPath : null;\n\n // Tag every selection with the active conversation so it can't leak into\n // the next one. FileQuickRow / FileTreeView call this with just the path.\n const handleSelectFile = useCallback(\n (path: string) => setSelectedPath(path, conversationId),\n [conversationId, setSelectedPath],\n );\n\n // Pre-fetch the selected file's content here too so the toolbar's\n // \"open in new window\" link can reach for its `staticUrl`. react-query\n // dedupes against `FileContentViewer`'s identical call, so this costs\n // nothing extra.\n const selectedFileContent = useWorkspaceFileContent(selectedPath);\n const mutationCounter = useWorkspaceMutationCounter((state) => state.count);\n const selectedFileStaticUrl = withWorkspaceCacheBuster(\n selectedFileContent.data?.staticUrl ?? null,\n mutationCounter,\n );\n\n useEffect(() => {\n if (selectedConversationId === conversationId) return;\n setSelectedPath(null, conversationId);\n }, [selectedConversationId, conversationId, setSelectedPath]);\n\n // Auto-select the highest-priority file the first time we load the list,\n // so users see something useful immediately.\n useEffect(() => {\n if (selectedPath || paths.length === 0) return;\n const [first] = sortFilesByPriority(paths);\n if (first) setSelectedPath(first, conversationId);\n }, [paths, selectedPath, conversationId, setSelectedPath]);\n\n // Refresh button: covers the diff view (git changes) and the file viewer\n // (workspace listing + cached file contents). Lives in this toolbar — not\n // in the outer ConversationTabs bar — so it sits with the other\n // files-tab-local controls.\n const queryClient = useQueryClient();\n const { refetch: refetchGitChanges, isFetching: isFetchingGitChanges } =\n useUnifiedGetGitChanges();\n const refreshFiles = () => {\n refetchGitChanges();\n queryClient.invalidateQueries({ queryKey: [\"workspace-files\"] });\n queryClient.invalidateQueries({ queryKey: [\"workspace-file-content\"] });\n queryClient.invalidateQueries({ queryKey: [\"git_commits\"] });\n };\n\n return (\n <main\n className=\"h-full w-full flex flex-col items-stretch\"\n data-testid=\"files-tab\"\n >\n {/* Top toolbar: diff/files + rich/plain toggles (left-aligned) plus\n the refresh button on the right. */}\n <div className=\"flex items-center gap-3 px-3 py-1.5 border-b border-[var(--oh-border)]\">\n <SegmentedToggle<\"on\" | \"off\" | \"commits\">\n ariaLabel={t(I18nKey.FILES$DIFF_VIEW)}\n testId=\"files-tab-diff-toggle\"\n value={activeView}\n options={[\n { value: \"on\", label: t(I18nKey.FILES$DIFF_VIEW) },\n ...(showCommitsOption\n ? [\n {\n value: \"commits\" as const,\n label: t(I18nKey.DIFF_VIEWER$COMMITS),\n },\n ]\n : []),\n { value: \"off\", label: t(I18nKey.COMMON$FILES) },\n ]}\n onChange={(value) => {\n if (value === \"commits\") {\n setCommitsViewSelected(true);\n } else {\n setCommitsViewSelected(false);\n setFilesTabDiffView(value === \"on\");\n }\n }}\n />\n\n {activeView === \"off\" && (\n <SegmentedToggle<ViewMode>\n ariaLabel={t(I18nKey.FILES$RICH)}\n testId=\"files-tab-content-mode-toggle\"\n value={contentViewMode}\n options={[\n { value: \"rich\", label: t(I18nKey.FILES$RICH) },\n { value: \"plain\", label: t(I18nKey.FILES$PLAIN) },\n ]}\n onChange={setFilesTabContentViewMode}\n />\n )}\n\n <div className=\"ml-auto flex items-center gap-1\">\n {/* Open the currently-selected file in a new browser tab. Only\n meaningful while we're showing a file (not the diff view) and\n we've resolved its staticUrl from the workspace fileserver. */}\n {activeView === \"off\" && selectedFileStaticUrl && (\n <a\n href={selectedFileStaticUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={t(I18nKey.FILES$OPEN_IN_NEW_WINDOW)}\n title={t(I18nKey.FILES$OPEN_IN_NEW_WINDOW)}\n data-testid=\"files-tab-open-in-new-window\"\n className=\"flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:bg-[var(--oh-interactive-hover)] cursor-pointer text-white\"\n >\n <LinkExternalIcon width={14} height={14} />\n </a>\n )}\n <button\n type=\"button\"\n onClick={refreshFiles}\n disabled={isFetchingGitChanges}\n aria-label={t(I18nKey.FILES$REFRESH)}\n title={t(I18nKey.FILES$REFRESH)}\n data-testid=\"files-tab-refresh\"\n className=\"flex items-center justify-center w-[26px] py-1 rounded-[7px] hover:enabled:bg-[var(--oh-interactive-hover)] cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <RefreshIcon\n width={12.75}\n height={15}\n color=\"#ffffff\"\n className={isFetchingGitChanges ? \"animate-spin\" : \"\"}\n />\n </button>\n </div>\n </div>\n\n {activeView === \"on\" && (\n <div className=\"flex-1 min-h-0\">\n <GitChanges />\n </div>\n )}\n {activeView === \"commits\" && (\n <div className=\"flex-1 min-h-0\">\n <GitCommits />\n </div>\n )}\n {activeView === \"off\" && (\n <div className=\"flex flex-1 flex-col min-h-0\">\n {filesQuery.isLoading ? (\n <div className=\"flex flex-1 items-center justify-center text-sm text-[var(--oh-muted)]\">\n {t(I18nKey.FILES$LOADING_FILES)}\n </div>\n ) : (\n <>\n <FileQuickRow\n paths={paths}\n selectedPath={selectedPath}\n onSelectFile={handleSelectFile}\n isTreeVisible={isTreeVisible}\n onToggleTree={() => setIsTreeVisible((prev) => !prev)}\n />\n <div className=\"flex h-full min-h-0 flex-1\">\n {isTreeVisible && (\n <aside\n className=\"w-56 shrink-0 border-r border-[var(--oh-border)] overflow-y-auto custom-scrollbar-always\"\n data-testid=\"files-tab-tree\"\n >\n <FileTreeView\n paths={paths}\n selectedPath={selectedPath}\n onSelectFile={handleSelectFile}\n />\n </aside>\n )}\n <section\n className=\"flex h-full min-h-0 min-w-0 flex-1 flex-col\"\n data-testid=\"files-tab-content\"\n >\n {selectedPath ? (\n <FileContentViewer\n path={selectedPath}\n viewMode={contentViewMode}\n />\n ) : (\n <NoFileSelectedMessage />\n )}\n </section>\n </div>\n </>\n )}\n </div>\n )}\n </main>\n );\n}\n\nexport default FilesTab;\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../i18n/declaration.cjs`),r=require(`../services/settings.cjs`),i=require(`../constants/llm-subscription.cjs`),a=require(`../hooks/query/use-settings.cjs`),o=require(`../components/features/settings/settings-input.cjs`),s=require(`../components/features/settings/settings-dropdown-input.cjs`),c=require(`../utils/extract-model-and-provider.cjs`),l=require(`../ui/help-link.cjs`),u=require(`../components/shared/modals/settings/model-selector.cjs`),d=require(`../hooks/query/use-agent-settings-schema.cjs`),f=require(`../components/features/settings/llm-settings/openai-subscription-auth-card.cjs`),p=require(`../components/features/settings/key-status-icon.cjs`),m=require(`../utils/sdk-settings-schema.cjs`),h=require(`../components/features/settings/sdk-settings/sdk-section-page.cjs`);require(`../components/features/settings/llm-profiles/index.cjs`);const g=require(`../hooks/query/use-llm-subscription-models.cjs`);let _=require(`react`);_=e.__toESM(_,1);let v=require(`react/jsx-runtime`);var y=new Set([`llm.model`,`llm.api_key`,`llm.base_url`,i.LLM_AUTH_TYPE_KEY,i.LLM_SUBSCRIPTION_VENDOR_KEY]),b=(e,t)=>!e||!t?null:`${e}/${t}`,x=(e,t)=>e?.sections.flatMap(e=>e.fields).find(e=>e.key===t)?.default??null,S={openai:new Set([`https://api.openai.com`,`https://api.openai.com/v1`])},C=e=>{try{let t=new URL(e),n=t.pathname.replace(/\/+$/,``)||``;return`${t.origin}${n}`}catch{return e.trim().replace(/\/+$/,``)}},w=(e,t)=>{let n=C(t),{provider:r}=c.extractModelAndProvider(e);if(r){let e=S[r];if(e)return e.has(n)}return Object.values(S).some(e=>e?.has(n))};function T({testId:e}){let{t:r}=t.useTranslation(`openhands`);return(0,v.jsx)(l.HelpLink,{testId:e,text:r(n.I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_TEXT),linkText:r(n.I18nKey.SETTINGS$NAV_API_KEYS),href:`https://app.all-hands.dev/settings/api-keys`,suffix:` ${r(n.I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_SUFFIX)}`})}function E({scope:e=`personal`,onSaveSuccess:c,initialValueOverrides:S,embedded:C,hideSaveButton:E,suppressSuccessToast:D,onSaveControlChange:O}){let{t:k}=t.useTranslation(`openhands`),{data:A}=a.useSettings(e),{data:j}=d.useAgentSettingsSchema(A?.agent_settings_schema),M=A?.agent_settings?.llm,N=i.resolveLlmAuthType(S?.[`llm.auth_type`]??M?.auth_type),[P,F]=_.default.useState(N===i.LLM_AUTH_TYPE_SUBSCRIPTION),{data:I,isLoading:L,isFetching:R}=g.useOpenAISubscriptionModels({enabled:P}),z=P&&!I&&(L||R),B=_.default.useRef(null),V=_.default.useRef(null);_.default.useEffect(()=>{N===`subscription`&&F(!0)},[N]);let H=String(r.DEFAULT_SETTINGS.agent_settings?.llm?.model??``),U=_.default.useCallback((e,t)=>{let n=m.inferInitialView(e,t);if(n!==`basic`)return n;let r=e.llm_model??``,i=e.llm_base_url?.trim()??``;return i.length>0&&!w(r,i)?`all`:`basic`},[]),W=_.default.useCallback(({values:e,isDisabled:t,view:r,onChange:a})=>{let c=typeof e[`llm.model`]==`string`?e[`llm.model`]:``,d=typeof e[`llm.base_url`]==`string`?e[`llm.base_url`]:``,m=c.startsWith(`openhands/`),h=i.resolveLlmAuthType(e[i.LLM_AUTH_TYPE_KEY]),g=h===i.LLM_AUTH_TYPE_SUBSCRIPTION,_=t||g&&z,y=I?.includes(c)?c:I?.[0]??``,x=typeof e[`llm.api_key`]==`string`?e[`llm.api_key`]:``,S=C?x.length>0:!!A?.llm_api_key_set,w=(e,r)=>(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(o.SettingsInput,{testId:e,label:k(n.I18nKey.SETTINGS_FORM$API_KEY),type:`password`,className:`w-full`,value:x,placeholder:S?`<hidden>`:``,onChange:e=>a(`llm.api_key`,e),isDisabled:t,startContent:S?(0,v.jsx)(p.KeyStatusIcon,{isSet:S}):void 0}),(0,v.jsx)(l.HelpLink,{testId:r,text:k(n.I18nKey.SETTINGS$DONT_KNOW_API_KEY),linkText:k(n.I18nKey.SETTINGS$CLICK_FOR_INSTRUCTIONS),href:`https://docs.openhands.dev/usage/local-setup#getting-an-api-key`})]}),E=e=>{let t=e===`subscription`?i.LLM_AUTH_TYPE_SUBSCRIPTION:i.LLM_AUTH_TYPE_API_KEY;if(a(i.LLM_AUTH_TYPE_KEY,t),t===`subscription`){F(!0),c&&!I?.includes(c)&&(B.current=c);let e=V.current&&I?.includes(V.current)?V.current:I?.[0];a(i.LLM_SUBSCRIPTION_VENDOR_KEY,i.OPENAI_SUBSCRIPTION_VENDOR),!I?.includes(c)&&e&&a(`llm.model`,e);return}c&&I?.includes(c)&&(V.current=c,a(`llm.model`,B.current??H))},D=()=>(0,v.jsx)(s.SettingsDropdownInput,{testId:`llm-auth-type-input`,name:i.LLM_AUTH_TYPE_KEY,label:k(n.I18nKey.SETTINGS$LLM_AUTH_TYPE),items:[{key:i.LLM_AUTH_TYPE_API_KEY,label:k(n.I18nKey.SETTINGS$LLM_AUTH_TYPE_API_KEY)},{key:i.LLM_AUTH_TYPE_SUBSCRIPTION,label:k(n.I18nKey.SETTINGS$LLM_AUTH_TYPE_SUBSCRIPTION)}],selectedKey:h,isClearable:!1,required:!0,isDisabled:_,onSelectionChange:E}),O=()=>(0,v.jsxs)(`div`,{className:`flex flex-col gap-6`,"data-testid":`llm-subscription-settings`,children:[(0,v.jsx)(s.SettingsDropdownInput,{testId:`llm-subscription-model-input`,name:`llm.subscription_model`,label:k(n.I18nKey.SETTINGS$SUBSCRIPTION_MODEL),items:(I??[]).map(e=>({key:e,label:e})),selectedKey:y,isClearable:!1,required:!0,isDisabled:_||!I?.length,onSelectionChange:e=>{let t=typeof e==`string`?e:I?.[0];t&&a(`llm.model`,t)}}),(0,v.jsx)(f.OpenAISubscriptionAuthCard,{isDisabled:t})]});return(0,v.jsx)(`div`,{className:`flex flex-col gap-6`,children:r===`basic`?(0,v.jsxs)(`div`,{className:`flex flex-col gap-6`,"data-testid":`llm-settings-form-basic`,children:[D(),g?O():(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(u.ModelSelector,{currentModel:c||void 0,onChange:(e,t)=>{let n=b(e,t);n&&a(`llm.model`,n)},wrapperClassName:`!flex-col !gap-6`,isDisabled:t}),m?(0,v.jsx)(T,{testId:`openhands-api-key-help`}):null,w(`llm-api-key-input`,`llm-api-key-help-anchor`)]})]}):(0,v.jsxs)(`div`,{className:`flex flex-col gap-6`,"data-testid":`llm-settings-form-advanced`,children:[D(),g?O():(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(o.SettingsInput,{testId:`llm-custom-model-input`,label:k(n.I18nKey.SETTINGS$CUSTOM_MODEL),type:`text`,className:`w-full`,value:c,placeholder:H,onChange:e=>a(`llm.model`,e),isDisabled:t}),m?(0,v.jsx)(T,{testId:`openhands-api-key-help-2`}):null,(0,v.jsx)(o.SettingsInput,{testId:`base-url-input`,label:k(n.I18nKey.SETTINGS$BASE_URL),type:`text`,className:`w-full`,value:d,placeholder:`https://api.openai.com`,onChange:e=>a(`llm.base_url`,e),isDisabled:t}),w(`llm-api-key-input`,`llm-api-key-help-anchor-advanced`)]})]})})},[H,C,z,A?.llm_api_key_set,I,k]),G=_.default.useCallback((e,t)=>{let n=structuredClone(e.agent_settings_diff??{}),r=n.llm??{};if(i.resolveLlmAuthType(t.values[`llm.auth_type`])===`subscription`){r.auth_type=i.LLM_AUTH_TYPE_SUBSCRIPTION,r.subscription_vendor=i.OPENAI_SUBSCRIPTION_VENDOR;let e=typeof r.model==`string`?r.model:String(t.values[`llm.model`]??``),n=I?.[0];if(!I?.includes(e)&&!n)throw Error(`Subscription models are not loaded yet.`);r.model=I?.includes(e)?e:n,delete r.api_key,delete r.base_url}else t.dirty[`llm.auth_type`]&&(r.auth_type=i.LLM_AUTH_TYPE_API_KEY,r.subscription_vendor=null),t.view===`basic`&&r.model!==void 0&&(r.base_url=x(j,`llm.base_url`));return n.llm=r,{agent_settings_diff:n}},[j,I]);return(0,v.jsx)(h.SdkSectionPage,{scope:e,settingsSources:[{settingsSource:`agent_settings`,sectionKeys:[`llm`],excludeKeys:y}],header:W,buildPayload:G,getInitialView:U,forceShowAdvancedView:!0,allowAllView:!0,onSaveSuccess:c,initialValueOverrides:S,embedded:C,hideSaveButton:E,suppressSuccessToast:D,onSaveControlChange:O,testId:`llm-settings-screen`})}exports.LlmSettingsScreen=E;
1
+ const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../i18n/declaration.cjs`),r=require(`../services/settings.cjs`),i=require(`../constants/llm-subscription.cjs`),a=require(`../hooks/query/use-settings.cjs`),o=require(`../components/features/settings/settings-input.cjs`),s=require(`../components/features/settings/settings-dropdown-input.cjs`),c=require(`../utils/extract-model-and-provider.cjs`),l=require(`../ui/help-link.cjs`),u=require(`../components/shared/modals/settings/model-selector.cjs`),d=require(`../hooks/query/use-agent-settings-schema.cjs`),f=require(`../components/features/settings/llm-settings/openai-subscription-auth-card.cjs`),p=require(`../components/features/settings/key-status-icon.cjs`),m=require(`../utils/sdk-settings-schema.cjs`),h=require(`../components/features/settings/sdk-settings/sdk-section-page.cjs`);require(`../components/features/settings/llm-profiles/index.cjs`);const g=require(`../hooks/query/use-llm-subscription-models.cjs`);let _=require(`react`);_=e.__toESM(_,1);let v=require(`react/jsx-runtime`);var y=new Set([`llm.model`,`llm.api_key`,`llm.base_url`,i.LLM_AUTH_TYPE_KEY,i.LLM_SUBSCRIPTION_VENDOR_KEY]),b=(e,t)=>!e||!t?null:`${e}/${t}`,x=(e,t)=>e?.sections.flatMap(e=>e.fields).find(e=>e.key===t)?.default??null,S={openai:new Set([`https://api.openai.com`,`https://api.openai.com/v1`]),moonshot:new Set([`https://api.kimi.com/coding/v1`])},C=e=>{try{let t=new URL(e),n=t.pathname.replace(/\/+$/,``)||``;return`${t.origin}${n}`}catch{return e.trim().replace(/\/+$/,``)}},w=(e,t)=>{let n=C(t),{provider:r}=c.extractModelAndProvider(e);if(r){let e=S[r];if(e)return e.has(n)}return Object.values(S).some(e=>e?.has(n))};function T({testId:e}){let{t:r}=t.useTranslation(`openhands`);return(0,v.jsx)(l.HelpLink,{testId:e,text:r(n.I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_TEXT),linkText:r(n.I18nKey.SETTINGS$NAV_API_KEYS),href:`https://app.all-hands.dev/settings/api-keys`,suffix:` ${r(n.I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_SUFFIX)}`})}function E({scope:e=`personal`,onSaveSuccess:c,initialValueOverrides:S,embedded:C,hideSaveButton:E,suppressSuccessToast:D,onSaveControlChange:O}){let{t:k}=t.useTranslation(`openhands`),{data:A}=a.useSettings(e),{data:j}=d.useAgentSettingsSchema(A?.agent_settings_schema),M=A?.agent_settings?.llm,N=i.resolveLlmAuthType(S?.[`llm.auth_type`]??M?.auth_type),[P,F]=_.default.useState(N===i.LLM_AUTH_TYPE_SUBSCRIPTION),{data:I,isLoading:L,isFetching:R}=g.useOpenAISubscriptionModels({enabled:P}),z=P&&!I&&(L||R),B=_.default.useRef(null),V=_.default.useRef(null);_.default.useEffect(()=>{N===`subscription`&&F(!0)},[N]);let H=String(r.DEFAULT_SETTINGS.agent_settings?.llm?.model??``),U=_.default.useCallback((e,t)=>{let n=m.inferInitialView(e,t);if(n!==`basic`)return n;let r=e.llm_model??``,i=e.llm_base_url?.trim()??``;return i.length>0&&!w(r,i)?`all`:`basic`},[]),W=_.default.useCallback(({values:e,isDisabled:t,view:r,onChange:a})=>{let c=typeof e[`llm.model`]==`string`?e[`llm.model`]:``,d=typeof e[`llm.base_url`]==`string`?e[`llm.base_url`]:``,m=c.startsWith(`openhands/`),h=i.resolveLlmAuthType(e[i.LLM_AUTH_TYPE_KEY]),g=h===i.LLM_AUTH_TYPE_SUBSCRIPTION,_=t||g&&z,y=I?.includes(c)?c:I?.[0]??``,x=typeof e[`llm.api_key`]==`string`?e[`llm.api_key`]:``,S=C?x.length>0:!!A?.llm_api_key_set,w=(e,r)=>(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(o.SettingsInput,{testId:e,label:k(n.I18nKey.SETTINGS_FORM$API_KEY),type:`password`,className:`w-full`,value:x,placeholder:S?`<hidden>`:``,onChange:e=>a(`llm.api_key`,e),isDisabled:t,startContent:S?(0,v.jsx)(p.KeyStatusIcon,{isSet:S}):void 0}),(0,v.jsx)(l.HelpLink,{testId:r,text:k(n.I18nKey.SETTINGS$DONT_KNOW_API_KEY),linkText:k(n.I18nKey.SETTINGS$CLICK_FOR_INSTRUCTIONS),href:`https://docs.openhands.dev/usage/local-setup#getting-an-api-key`})]}),E=e=>{let t=e===`subscription`?i.LLM_AUTH_TYPE_SUBSCRIPTION:i.LLM_AUTH_TYPE_API_KEY;if(a(i.LLM_AUTH_TYPE_KEY,t),t===`subscription`){F(!0),c&&!I?.includes(c)&&(B.current=c);let e=V.current&&I?.includes(V.current)?V.current:I?.[0];a(i.LLM_SUBSCRIPTION_VENDOR_KEY,i.OPENAI_SUBSCRIPTION_VENDOR),!I?.includes(c)&&e&&a(`llm.model`,e);return}c&&I?.includes(c)&&(V.current=c,a(`llm.model`,B.current??H))},D=()=>(0,v.jsx)(s.SettingsDropdownInput,{testId:`llm-auth-type-input`,name:i.LLM_AUTH_TYPE_KEY,label:k(n.I18nKey.SETTINGS$LLM_AUTH_TYPE),items:[{key:i.LLM_AUTH_TYPE_API_KEY,label:k(n.I18nKey.SETTINGS$LLM_AUTH_TYPE_API_KEY)},{key:i.LLM_AUTH_TYPE_SUBSCRIPTION,label:k(n.I18nKey.SETTINGS$LLM_AUTH_TYPE_SUBSCRIPTION)}],selectedKey:h,isClearable:!1,required:!0,isDisabled:_,onSelectionChange:E}),O=()=>(0,v.jsxs)(`div`,{className:`flex flex-col gap-6`,"data-testid":`llm-subscription-settings`,children:[(0,v.jsx)(s.SettingsDropdownInput,{testId:`llm-subscription-model-input`,name:`llm.subscription_model`,label:k(n.I18nKey.SETTINGS$SUBSCRIPTION_MODEL),items:(I??[]).map(e=>({key:e,label:e})),selectedKey:y,isClearable:!1,required:!0,isDisabled:_||!I?.length,onSelectionChange:e=>{let t=typeof e==`string`?e:I?.[0];t&&a(`llm.model`,t)}}),(0,v.jsx)(f.OpenAISubscriptionAuthCard,{isDisabled:t})]});return(0,v.jsx)(`div`,{className:`flex flex-col gap-6`,children:r===`basic`?(0,v.jsxs)(`div`,{className:`flex flex-col gap-6`,"data-testid":`llm-settings-form-basic`,children:[D(),g?O():(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(u.ModelSelector,{currentModel:c||void 0,onChange:(e,t)=>{let n=b(e,t);n&&a(`llm.model`,n)},wrapperClassName:`!flex-col !gap-6`,isDisabled:t}),m?(0,v.jsx)(T,{testId:`openhands-api-key-help`}):null,w(`llm-api-key-input`,`llm-api-key-help-anchor`)]})]}):(0,v.jsxs)(`div`,{className:`flex flex-col gap-6`,"data-testid":`llm-settings-form-advanced`,children:[D(),g?O():(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(o.SettingsInput,{testId:`llm-custom-model-input`,label:k(n.I18nKey.SETTINGS$CUSTOM_MODEL),type:`text`,className:`w-full`,value:c,placeholder:H,onChange:e=>a(`llm.model`,e),isDisabled:t}),m?(0,v.jsx)(T,{testId:`openhands-api-key-help-2`}):null,(0,v.jsx)(o.SettingsInput,{testId:`base-url-input`,label:k(n.I18nKey.SETTINGS$BASE_URL),type:`text`,className:`w-full`,value:d,placeholder:`https://api.openai.com`,onChange:e=>a(`llm.base_url`,e),isDisabled:t}),w(`llm-api-key-input`,`llm-api-key-help-anchor-advanced`)]})]})})},[H,C,z,A?.llm_api_key_set,I,k]),G=_.default.useCallback((e,t)=>{let n=structuredClone(e.agent_settings_diff??{}),r=n.llm??{};if(i.resolveLlmAuthType(t.values[`llm.auth_type`])===`subscription`){r.auth_type=i.LLM_AUTH_TYPE_SUBSCRIPTION,r.subscription_vendor=i.OPENAI_SUBSCRIPTION_VENDOR;let e=typeof r.model==`string`?r.model:String(t.values[`llm.model`]??``),n=I?.[0];if(!I?.includes(e)&&!n)throw Error(`Subscription models are not loaded yet.`);r.model=I?.includes(e)?e:n,delete r.api_key,delete r.base_url}else t.dirty[`llm.auth_type`]&&(r.auth_type=i.LLM_AUTH_TYPE_API_KEY,r.subscription_vendor=null),t.view===`basic`&&r.model!==void 0&&(r.base_url=x(j,`llm.base_url`));return n.llm=r,{agent_settings_diff:n}},[j,I]);return(0,v.jsx)(h.SdkSectionPage,{scope:e,settingsSources:[{settingsSource:`agent_settings`,sectionKeys:[`llm`],excludeKeys:y}],header:W,buildPayload:G,getInitialView:U,forceShowAdvancedView:!0,allowAllView:!0,onSaveSuccess:c,initialValueOverrides:S,embedded:C,hideSaveButton:E,suppressSuccessToast:D,onSaveControlChange:O,testId:`llm-settings-screen`})}exports.LlmSettingsScreen=E;
2
2
  //# sourceMappingURL=llm-settings.cjs.map