@openhands/agent-canvas 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1390) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/Trans-De9RwQhA.js +1 -0
  4. package/build/assets/__vite-browser-external-4xJsU2-u.js +1 -0
  5. package/build/assets/{acp-providers-B_ZxlEbx.js → acp-providers-D_D8VUpP.js} +1 -1
  6. package/build/assets/active-backend-context-u2tdYRgH.js +1 -0
  7. package/build/assets/add-backend-modal-DIEyAkA4.js +1 -0
  8. package/build/assets/agent-profiles-settings-BovdV4N8.js +1 -0
  9. package/build/assets/{agent-server-client-options-CxnCYyIW.js → agent-server-client-options-DVLRd9sw.js} +1 -1
  10. package/build/assets/agent-server-conversation-service.api-BP73yONA.js +5 -0
  11. package/build/assets/agent-settings-FGL3Yvkp.js +1 -0
  12. package/build/assets/agent-settings-Ofbh6UTD.js +2 -0
  13. package/build/assets/alert-banner-BW0wRYw6.js +1 -0
  14. package/build/assets/api-key-entry-screen-CZIdRmUJ.js +1 -0
  15. package/build/assets/app-settings-BHJ9nKti.js +1 -0
  16. package/build/assets/automation-detail-DwYGzLkp.js +2 -0
  17. package/build/assets/automations-list-CuAfJmMW.js +1 -0
  18. package/build/assets/back-nav-button-BYmxFxGt.js +1 -0
  19. package/build/assets/backend-form-modal-BiaOB2C4.js +1 -0
  20. package/build/assets/backend-synced-settings-badge-Bs3FSXsS.js +1 -0
  21. package/build/assets/base-modal-CC5Pp8CF.js +1 -0
  22. package/build/assets/bot-D7eUAuSB.js +1 -0
  23. package/build/assets/brand-button-DKPMEKcW.js +1 -0
  24. package/build/assets/{browser-CCwPzPsD.js → browser-B39N74jU.js} +2 -2
  25. package/build/assets/browser-store-BI6uklCG.js +1 -0
  26. package/build/assets/browser-tab-aiDg7aEn.js +1 -0
  27. package/build/assets/chat-send-button-DxuZIoW8.js +1 -0
  28. package/build/assets/check-Bvi71siz.js +1 -0
  29. package/build/assets/checkmark-h7udgXMM.js +1 -0
  30. package/build/assets/{chevron-down-BxZEAIv4.js → chevron-down-CI8A6tet.js} +1 -1
  31. package/build/assets/circle-plus-check-toggle-T3eAIuPQ.js +1 -0
  32. package/build/assets/close-p3Op5lxI.js +1 -0
  33. package/build/assets/code-tag-DYlAhEQY.js +1 -0
  34. package/build/assets/{color-themes-CTNRQd1a.js → color-themes-DPBzNtVg.js} +4 -4
  35. package/build/assets/combobox-caret-CLGvOs32.js +1 -0
  36. package/build/assets/command-menu-DKrLCRla.js +1 -0
  37. package/build/assets/{command-store-C-57Heey.js → command-store-D8J5LMW1.js} +1 -1
  38. package/build/assets/condenser-settings-D_5vY4m3.js +1 -0
  39. package/build/assets/confirmation-modal-BK1F0A68.js +1 -0
  40. package/build/assets/context-menu-list-item-DBFzplWW.js +1 -0
  41. package/build/assets/conversation-DnVC6vRV.js +1 -0
  42. package/build/assets/conversation-local-storage-F6zVMM--.js +1 -0
  43. package/build/assets/conversation-panel-ZEz-z3az.js +1 -0
  44. package/build/assets/conversation-service.api-CqZcHr1c.js +1 -0
  45. package/build/assets/conversation-state-store-B2Bp32XI.js +1 -0
  46. package/build/assets/conversation-store-LptbOvKa.js +1 -0
  47. package/build/assets/conversation-tab-empty-state-m8IUkfMj.js +1 -0
  48. package/build/assets/conversation-xkBS3AHC.js +19 -0
  49. package/build/assets/copy-3JCw_XFB.js +1 -0
  50. package/build/assets/copy-BLmGeJcd.js +1 -0
  51. package/build/assets/copy-to-clipboard-button-Aj9wFmt2.js +1 -0
  52. package/build/assets/createLucideIcon-CVAsW2Yo.js +1 -0
  53. package/build/assets/declaration-B9kpCaYl.js +1 -0
  54. package/build/assets/device-verify-B5YCrvSu.js +1 -0
  55. package/build/assets/dist-CodhvuAP.js +1 -0
  56. package/build/assets/dropdown-classes-CgQ45JmQ.js +1 -0
  57. package/build/assets/edit-automation-modal-B6U96gVV.js +1 -0
  58. package/build/assets/ellipsis-button-1BV9Sga8.js +1 -0
  59. package/build/assets/entry.client-Dy--3GeA.js +2 -0
  60. package/build/assets/enum-filter-dropdown-DCITiYVi.js +1 -0
  61. package/build/assets/environment-switch-overlay-DUnKILNH.js +1 -0
  62. package/build/assets/extensions-hub-CksKNpP9.js +1 -0
  63. package/build/assets/{extensions-navigation-DfLHdTUC.js → extensions-navigation-Di9rJ-b5.js} +1 -1
  64. package/build/assets/{external-link-D8njjDTk.js → external-link-D2zJjE9G.js} +1 -1
  65. package/build/assets/files-tab-61Vaihc6.js +1 -0
  66. package/build/assets/files-tab-store-DJsPxYdg.js +1 -0
  67. package/build/assets/folder-mMWFvaw0.js +1 -0
  68. package/build/assets/form-control-classes-9rkU4usZ.js +1 -0
  69. package/build/assets/get-language-from-path-CPNnuVhI.js +1 -0
  70. package/build/assets/git-provider-icon-aQRcUVI-.js +1 -0
  71. package/build/assets/home-5gOtUe-n.js +1 -0
  72. package/build/assets/iconBase-DaTRRUjy.js +1 -0
  73. package/build/assets/index-redirect-CUUJiNki.js +1 -0
  74. package/build/assets/install-server-modal-BRab9inF.js +1 -0
  75. package/build/assets/launch-1TJRKkkX.js +1 -0
  76. package/build/assets/lesson-plan-BtrZUCuj.js +4 -0
  77. package/build/assets/link-external-DfKQroKX.js +1 -0
  78. package/build/assets/{list-todo-B_Ts2JmZ.js → list-todo-BfH6yYUK.js} +1 -1
  79. package/build/assets/llm-not-configured-banner-BrU5uHto.js +27 -0
  80. package/build/assets/llm-settings-BpdU51Jo.js +1 -0
  81. package/build/assets/llm-settings-DsInf6yD.js +1 -0
  82. package/build/assets/{llm-subscription-service-BX_AtNlO.js → llm-subscription-service-CKyaV24y.js} +1 -1
  83. package/build/assets/loader-circle-BEykUKYG.js +1 -0
  84. package/build/assets/loading-spinner-DHAIPZkP.js +1 -0
  85. package/build/assets/manage-backends-modal-BREySP-J.js +1 -0
  86. package/build/assets/manifest-a5bb7568.js +1 -0
  87. package/build/assets/{markdown-renderer-DWy7Np7u.js → markdown-renderer-D8mayGjI.js} +1 -1
  88. package/build/assets/mcp-XXf8k6mb.js +9 -0
  89. package/build/assets/messages-D2oZb47Z.js +40 -0
  90. package/build/assets/middleware-DYHYNAnP.js +6 -0
  91. package/build/assets/modal-backdrop-zVwfOJZr.js +1 -0
  92. package/build/assets/modal-body-Dcu5McCa.js +1 -0
  93. package/build/assets/{modal-classes-C4kS6ib_.js → modal-classes-DPqxSyuP.js} +1 -1
  94. package/build/assets/modal-close-button-CTCX4nCH.js +1 -0
  95. package/build/assets/model-selector-VDHBytb6.js +1 -0
  96. package/build/assets/{mouse-pointer-click-CXAx4FyM.js → mouse-pointer-click-PdEQPL6v.js} +1 -1
  97. package/build/assets/navigation-context-DPs2G0X8.js +1 -0
  98. package/build/assets/navigation-link-D8hfwvxI.js +1 -0
  99. package/build/assets/onboarding-D32kiGME.js +1 -0
  100. package/build/assets/onboarding-modal-C084vkv7.js +1 -0
  101. package/build/assets/openhands-logo-bcNw5bkY.js +1 -0
  102. package/build/assets/option-service.api-Cl5VLGyw.js +1 -0
  103. package/build/assets/organization-service.api-CnynNoT-.js +1 -0
  104. package/build/assets/path-utils-BeOmjIcE.js +1 -0
  105. package/build/assets/{pencil-CsL0ns9y.js → pencil-Dj2XjKmI.js} +1 -1
  106. package/build/assets/plan-components-j9X4AxYM.js +1 -0
  107. package/build/assets/planner-tab-AZMjJx31.js +1 -0
  108. package/build/assets/plugins-management-service-BAp70KN7.js +1 -0
  109. package/build/assets/profiles-service.api-CeYEmSM3.js +1 -0
  110. package/build/assets/providers-vX9jk9Vy.js +1 -0
  111. package/build/assets/{proxy-TeteRRW5.js → proxy-CHmFkV16.js} +1 -1
  112. package/build/assets/react-DPDgL6du.js +1 -0
  113. package/build/assets/recommended-automations-launcher-Bk8tQ-Cn.js +58 -0
  114. package/build/assets/{refresh-cw-GkGYXsU-.js → refresh-cw-DM82EIyx.js} +1 -1
  115. package/build/assets/root-CxWZUXTQ.css +1 -0
  116. package/build/assets/root-layout-CoWw4kpz.js +2 -0
  117. package/build/assets/root-tuEPDx-i.js +2 -0
  118. package/build/assets/runtime-waiting-state-DkzLgvMn.js +1 -0
  119. package/build/assets/schema-field-nvq_Juo2.js +1 -0
  120. package/build/assets/sdk-section-page-CgT70FaZ.js +1 -0
  121. package/build/assets/sdk-settings-schema-BjBkMHzZ.js +1 -0
  122. package/build/assets/search-4DHskuhE.js +1 -0
  123. package/build/assets/search-BsjCEFNf.js +1 -0
  124. package/build/assets/secrets-service-CZYjNxFw.js +1 -0
  125. package/build/assets/secrets-settings-BCxk9p9s.js +1 -0
  126. package/build/assets/segmented-toggle-Cen5AMUc.js +1 -0
  127. package/build/assets/settings-CedTdtb5.js +1 -0
  128. package/build/assets/settings-dropdown-input-xzoZwgUe.js +1 -0
  129. package/build/assets/settings-gear-MXCyZW0x.js +1 -0
  130. package/build/assets/settings-index-Cct3PJSP.js +1 -0
  131. package/build/assets/settings-input-DYs7t3oK.js +1 -0
  132. package/build/assets/settings-list-classes-DvQr5jVS.js +1 -0
  133. package/build/assets/{settings-CN_HaPjH.js → settings-mQUckT0g.js} +1 -1
  134. package/build/assets/settings-modal-DwLybV_O.js +1 -0
  135. package/build/assets/settings-section-header-context-COMOIaxV.js +1 -0
  136. package/build/assets/settings-service.api-DldkFI1x.js +1 -0
  137. package/build/assets/settings-switch-C2N2xqEb.js +1 -0
  138. package/build/assets/{settings-utils-9-_6iVIn.js → settings-utils-BMdG65By.js} +1 -1
  139. package/build/assets/shared-conversation-DnDwfLgg.js +1 -0
  140. package/build/assets/sidebar-layout-BtpUSN3j.js +1 -0
  141. package/build/assets/sidebar-mobile-menu-toggle-B8k3qu84.js +1 -0
  142. package/build/assets/sidebar-nav-link-CIB3NBRW.js +1 -0
  143. package/build/assets/sidebar-store-CZuE8AH5.js +1 -0
  144. package/build/assets/skill-card-pill-row-D2bUe2kB.js +1 -0
  145. package/build/assets/skills-9cDZONKh.js +1 -0
  146. package/build/assets/skills-plugins-B68ay6Pu.js +1 -0
  147. package/build/assets/skills-settings-A6sUy0T7.js +2 -0
  148. package/build/assets/{square-chevron-right-Cfi-SUY0.js → square-chevron-right-Czw3FFWc.js} +1 -1
  149. package/build/assets/styled-tooltip-DsKsFjuq.js +1 -0
  150. package/build/assets/suspense-X5dBsJzn.js +1 -0
  151. package/build/assets/switch-skeleton-DqQwalyu.js +1 -0
  152. package/build/assets/task-list-tab-BAThr9Ex.js +1 -0
  153. package/build/assets/{terminal-HakoMrQX.js → terminal-BmT0_gIH.js} +2 -2
  154. package/build/assets/terminal-BuLtIrb9.js +1 -0
  155. package/build/assets/toggle-switch-DBlOOzBr.js +1 -0
  156. package/build/assets/{trash-2-Bq4hqiRH.js → trash-2-Be_7y3Mn.js} +1 -1
  157. package/build/assets/typography-YGPBGzOG.js +1 -0
  158. package/build/assets/u-check-circle-BqoIxNz_.js +1 -0
  159. package/build/assets/u-check-circle-half-LiwZkuFe.js +1 -0
  160. package/build/assets/u-edit-DJ90xc8Z.js +1 -0
  161. package/build/assets/use-acp-credential-form-Bs6s0DTU.js +1 -0
  162. package/build/assets/use-activate-agent-profile-CKtTToSx.js +1 -0
  163. package/build/assets/use-active-agent-profile-CWLPpOtK.js +1 -0
  164. package/build/assets/use-active-conversation-DI5S5M1w.js +1 -0
  165. package/build/assets/use-agent-profiles-DPcaYLpm.js +1 -0
  166. package/build/assets/use-agent-state-Buh3bQDh.js +1 -0
  167. package/build/assets/use-backends-health-CxkvJy2N.js +1 -0
  168. package/build/assets/use-breakpoint-B-O0lQ84.js +1 -0
  169. package/build/assets/use-can-manage-org-profiles-DeX2Mfje.js +1 -0
  170. package/build/assets/use-click-outside-element-Bf4Omzot.js +1 -0
  171. package/build/assets/use-cloud-current-user-id-D_PQGfmT.js +1 -0
  172. package/build/assets/use-config-ur0RbjCP.js +1 -0
  173. package/build/assets/use-create-conversation-D9OWYcte.js +1 -0
  174. package/build/assets/use-create-secret-CVFSlhlR.js +1 -0
  175. package/build/assets/use-event-store-YSOxy9FC.js +4 -0
  176. package/build/assets/use-handle-plan-click-Dug8egQl.js +1 -0
  177. package/build/assets/use-is-authed-_dhQ2Xuj.js +1 -0
  178. package/build/assets/use-launch-skill-in-chat-BnoDgvAy.js +1 -0
  179. package/build/assets/use-llm-profiles-DjackuP1.js +1 -0
  180. package/build/assets/use-onboarding-completion-C_Swglzp.js +1 -0
  181. package/build/assets/use-plugins-marketplace-BGb-KgfD.js +1 -0
  182. package/build/assets/use-runtime-is-ready-Diiq65Q-.js +1 -0
  183. package/build/assets/use-save-agent-profile-aKKLqDJM.js +1 -0
  184. package/build/assets/{use-save-settings-DErJDIDL.js → use-save-settings-CChDyjOB.js} +1 -1
  185. package/build/assets/use-settings-dX4fKUPF.js +1 -0
  186. package/build/assets/use-settings-nav-items-D6pHnvxg.js +16 -0
  187. package/build/assets/use-skills-Dqo-pDDx.js +1 -0
  188. package/build/assets/use-task-list-CmWGElgb.js +1 -0
  189. package/build/assets/use-tracking-GtXCHmTv.js +1 -0
  190. package/build/assets/use-user-conversation-6uOXFP95.js +1 -0
  191. package/build/assets/useMutation-DCE9RcgK.js +1 -0
  192. package/build/assets/useMutationState-BUab8Kxr.js +1 -0
  193. package/build/assets/useQueries-CRzaAqzH.js +1 -0
  194. package/build/assets/useQuery-CpjHYtZc.js +1 -0
  195. package/build/assets/useTranslation-Cgy4JA_g.js +1 -0
  196. package/build/assets/utils-CE0lDWtb.js +1 -0
  197. package/build/assets/vendor-styling-CI0PQ3ab.js +22 -0
  198. package/build/assets/{vendor~browser-BQU4C3CQ.js → vendor~browser-Cvg7jXCP.js} +1 -1
  199. package/build/assets/{vendor~browser-tab-Cim6xN2k.js → vendor~browser-tab-Di0kh5Zw.js} +1 -1
  200. package/build/assets/vendor~conversation-panel~conversation~alert-banner-DHDkknt5.js +1 -0
  201. package/build/assets/vendor~entry.client-9tWQ_Ugw.js +1 -0
  202. package/build/assets/{vendor~entry.client-lAMyAlBD.js → vendor~entry.client-D6BtSOtn.js} +1 -1
  203. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~d1e18dtv-5Q6lQJdE.js +177 -0
  204. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~i3v2mlbw-BrJQ3XZH.js +1 -0
  205. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~ncdxw0bh-ClHnt5lR.js +10 -0
  206. package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~t35o0b0f-Bss49YXv.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~k6tszsdc-Bb-xMtbv.js} +1 -1
  207. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~nn5zty47-Zl0G1QCy.js +1 -0
  208. package/build/assets/{vendor~entry.client~root~root-layout~index-redirect~home~conversation-panel~conversation~la~fpbtwbmk-DDSPtjxR.js → vendor~entry.client~root~root-layout~index-redirect~home~conversation-panel~conversation~la~byh8a1g4-XNPdpuO8.js} +1 -1
  209. package/build/assets/{vendor~files-tab-BvQLon-P.js → vendor~files-tab-B02k3xvx.js} +1 -1
  210. package/build/assets/{vendor~home~conversation-panel~conversation-DBPRU26Z.js → vendor~home~conversation-panel~conversation-CYMF9JYB.js} +1 -1
  211. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DnEBAp2W.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-9UMeuPV6.js} +1 -1
  212. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CzI-A-Gz.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BD0GaRGa.js} +1 -1
  213. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-ByET2Quf.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CqXiHwjU.js} +1 -1
  214. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DCYBrned.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D7EUmQ8Y.js} +1 -1
  215. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DnctfFZL.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DTzw2x50.js} +1 -1
  216. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-pSG7lnvH.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-d8aETPbZ.js} +1 -1
  217. package/build/assets/{vendor~launch-DqoOsAhA.js → vendor~launch-CHXA9cJu.js} +1 -1
  218. package/build/assets/vendor~root-layout~conversation-panel~conversation-CpiTHpHl.js +1 -0
  219. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-BJl81v7J.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-_TdZcNMD.js} +1 -1
  220. package/build/assets/vendor~root-layout~home~conversation-panel~conversation-Cn2jwSga.js +1 -0
  221. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~enjl5xdm-mMKDm94D.js +48 -0
  222. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~skills-settings~automations-~ki5qnp0d-DRld6s9c.js → vendor~root-layout~home~conversation-panel~conversation~launch~skills-settings~automations-~ki5qnp0d-rV6d1Iv_.js} +502 -43
  223. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-9d2kA26V.js → vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-CZM4hwUT.js} +1 -1
  224. package/build/assets/vendor~root-layout~home~mcp~automations-list~onboarding-modal-CXyYYvYh.js +1 -0
  225. package/build/assets/verification-settings-D_zsNB_c.js +1 -0
  226. package/build/assets/x-Cb0WAtak.js +1 -0
  227. package/build/assets/x-mark-Batp6gXa.js +1 -0
  228. package/build/index.html +4 -4
  229. package/build/locales/ar/openhands.json +138 -1
  230. package/build/locales/ca/openhands.json +138 -1
  231. package/build/locales/de/openhands.json +138 -1
  232. package/build/locales/en/openhands.json +138 -1
  233. package/build/locales/es/openhands.json +138 -1
  234. package/build/locales/fr/openhands.json +138 -1
  235. package/build/locales/it/openhands.json +138 -1
  236. package/build/locales/ja/openhands.json +138 -1
  237. package/build/locales/ko-KR/openhands.json +138 -1
  238. package/build/locales/no/openhands.json +138 -1
  239. package/build/locales/pt/openhands.json +138 -1
  240. package/build/locales/tr/openhands.json +138 -1
  241. package/build/locales/uk/openhands.json +138 -1
  242. package/build/locales/zh-CN/openhands.json +138 -1
  243. package/build/locales/zh-TW/openhands.json +138 -1
  244. package/config/defaults.json +7 -9
  245. package/dist/_virtual/__vite-browser-external.cjs +2 -0
  246. package/dist/_virtual/__vite-browser-external.cjs.map +1 -0
  247. package/dist/_virtual/__vite-browser-external.js +9 -0
  248. package/dist/_virtual/__vite-browser-external.js.map +1 -0
  249. package/dist/api/agent-profiles-service/agent-profiles-service.api.cjs +2 -0
  250. package/dist/api/agent-profiles-service/agent-profiles-service.api.cjs.map +1 -0
  251. package/dist/api/agent-profiles-service/agent-profiles-service.api.d.ts +22 -0
  252. package/dist/api/agent-profiles-service/agent-profiles-service.api.js +35 -0
  253. package/dist/api/agent-profiles-service/agent-profiles-service.api.js.map +1 -0
  254. package/dist/api/agent-server-adapter.cjs +2 -2
  255. package/dist/api/agent-server-adapter.cjs.map +1 -1
  256. package/dist/api/agent-server-adapter.d.ts +11 -1
  257. package/dist/api/agent-server-adapter.js +60 -60
  258. package/dist/api/agent-server-adapter.js.map +1 -1
  259. package/dist/api/agent-server-compatibility.cjs +1 -1
  260. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  261. package/dist/api/agent-server-compatibility.js +1 -0
  262. package/dist/api/agent-server-compatibility.js.map +1 -1
  263. package/dist/api/agent-server-home.cjs +1 -1
  264. package/dist/api/agent-server-home.cjs.map +1 -1
  265. package/dist/api/agent-server-home.js +1 -0
  266. package/dist/api/agent-server-home.js.map +1 -1
  267. package/dist/api/cloud/agent-profiles-service.api.cjs +2 -0
  268. package/dist/api/cloud/agent-profiles-service.api.cjs.map +1 -0
  269. package/dist/api/cloud/agent-profiles-service.api.d.ts +7 -0
  270. package/dist/api/cloud/agent-profiles-service.api.js +58 -0
  271. package/dist/api/cloud/agent-profiles-service.api.js.map +1 -0
  272. package/dist/api/cloud/organization-service.api.cjs +1 -1
  273. package/dist/api/cloud/organization-service.api.cjs.map +1 -1
  274. package/dist/api/cloud/organization-service.api.d.ts +8 -0
  275. package/dist/api/cloud/organization-service.api.js +3 -1
  276. package/dist/api/cloud/organization-service.api.js.map +1 -1
  277. package/dist/api/cloud/profiles-service.api.cjs +2 -0
  278. package/dist/api/cloud/profiles-service.api.cjs.map +1 -0
  279. package/dist/api/cloud/profiles-service.api.d.ts +7 -0
  280. package/dist/api/cloud/profiles-service.api.js +75 -0
  281. package/dist/api/cloud/profiles-service.api.js.map +1 -0
  282. package/dist/api/cloud/settings-service.api.cjs +1 -1
  283. package/dist/api/cloud/settings-service.api.cjs.map +1 -1
  284. package/dist/api/cloud/settings-service.api.js +1 -1
  285. package/dist/api/cloud/settings-service.api.js.map +1 -1
  286. package/dist/api/config-service/config-service.api.cjs +1 -1
  287. package/dist/api/config-service/config-service.api.cjs.map +1 -1
  288. package/dist/api/config-service/config-service.api.js +1 -0
  289. package/dist/api/config-service/config-service.api.js.map +1 -1
  290. package/dist/api/conversation-metadata-store.cjs.map +1 -1
  291. package/dist/api/conversation-metadata-store.d.ts +11 -0
  292. package/dist/api/conversation-metadata-store.js.map +1 -1
  293. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  294. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  295. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +20 -1
  296. package/dist/api/conversation-service/agent-server-conversation-service.api.js +134 -105
  297. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  298. package/dist/api/conversation-service/agent-server-conversation-service.types.d.ts +2 -0
  299. package/dist/api/conversation-service/conversation-service.api.cjs +1 -1
  300. package/dist/api/conversation-service/conversation-service.api.cjs.map +1 -1
  301. package/dist/api/conversation-service/conversation-service.api.d.ts +1 -0
  302. package/dist/api/conversation-service/conversation-service.api.js +4 -0
  303. package/dist/api/conversation-service/conversation-service.api.js.map +1 -1
  304. package/dist/api/device-flow-client.cjs +1 -1
  305. package/dist/api/device-flow-client.cjs.map +1 -1
  306. package/dist/api/device-flow-client.js +33 -25
  307. package/dist/api/device-flow-client.js.map +1 -1
  308. package/dist/api/event-service/event-service.api.cjs +1 -1
  309. package/dist/api/event-service/event-service.api.cjs.map +1 -1
  310. package/dist/api/event-service/event-service.api.js +1 -0
  311. package/dist/api/event-service/event-service.api.js.map +1 -1
  312. package/dist/api/mcp-service/mcp-redacted-credentials.cjs +1 -1
  313. package/dist/api/mcp-service/mcp-redacted-credentials.cjs.map +1 -1
  314. package/dist/api/mcp-service/mcp-redacted-credentials.d.ts +3 -3
  315. package/dist/api/mcp-service/mcp-redacted-credentials.js +29 -30
  316. package/dist/api/mcp-service/mcp-redacted-credentials.js.map +1 -1
  317. package/dist/api/mcp-service/mcp-service.api.cjs +1 -1
  318. package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -1
  319. package/dist/api/mcp-service/mcp-service.api.d.ts +8 -1
  320. package/dist/api/mcp-service/mcp-service.api.js +129 -23
  321. package/dist/api/mcp-service/mcp-service.api.js.map +1 -1
  322. package/dist/api/option-service/option-service.api.cjs +1 -1
  323. package/dist/api/option-service/option-service.api.cjs.map +1 -1
  324. package/dist/api/option-service/option-service.api.js +1 -0
  325. package/dist/api/option-service/option-service.api.js.map +1 -1
  326. package/dist/api/plugins-management-service.cjs +2 -0
  327. package/dist/api/plugins-management-service.cjs.map +1 -0
  328. package/dist/api/plugins-management-service.d.ts +50 -0
  329. package/dist/api/plugins-management-service.js +41 -0
  330. package/dist/api/plugins-management-service.js.map +1 -0
  331. package/dist/api/plugins-service.d.ts +49 -0
  332. package/dist/api/profiles-service/profiles-service.api.cjs +1 -1
  333. package/dist/api/profiles-service/profiles-service.api.cjs.map +1 -1
  334. package/dist/api/profiles-service/profiles-service.api.js +21 -14
  335. package/dist/api/profiles-service/profiles-service.api.js.map +1 -1
  336. package/dist/api/runtime-service/agent-server-runtime-service.cjs +1 -1
  337. package/dist/api/runtime-service/agent-server-runtime-service.cjs.map +1 -1
  338. package/dist/api/runtime-service/agent-server-runtime-service.js +1 -0
  339. package/dist/api/runtime-service/agent-server-runtime-service.js.map +1 -1
  340. package/dist/api/secrets-service.cjs +1 -1
  341. package/dist/api/secrets-service.cjs.map +1 -1
  342. package/dist/api/secrets-service.js +1 -0
  343. package/dist/api/secrets-service.js.map +1 -1
  344. package/dist/api/settings-service/settings-service.api.cjs +1 -1
  345. package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
  346. package/dist/api/settings-service/settings-service.api.js +92 -50
  347. package/dist/api/settings-service/settings-service.api.js.map +1 -1
  348. package/dist/api/skills-service.cjs +1 -1
  349. package/dist/api/skills-service.cjs.map +1 -1
  350. package/dist/api/skills-service.js +1 -0
  351. package/dist/api/skills-service.js.map +1 -1
  352. package/dist/api/workspaces-service/workspaces-service.api.cjs +1 -1
  353. package/dist/api/workspaces-service/workspaces-service.api.cjs.map +1 -1
  354. package/dist/api/workspaces-service/workspaces-service.api.js +1 -0
  355. package/dist/api/workspaces-service/workspaces-service.api.js.map +1 -1
  356. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
  357. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
  358. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +57 -38
  359. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
  360. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs +2 -1
  361. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs.map +1 -1
  362. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js +13 -9
  363. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js.map +1 -1
  364. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs +1 -1
  365. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs.map +1 -1
  366. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js +65 -26
  367. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js.map +1 -1
  368. package/dist/components/conversation-events/chat/event-message.cjs +2 -2
  369. package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
  370. package/dist/components/conversation-events/chat/event-message.js +78 -76
  371. package/dist/components/conversation-events/chat/event-message.js.map +1 -1
  372. package/dist/components/features/analytics/telemetry-consent-banner.cjs +1 -1
  373. package/dist/components/features/analytics/telemetry-consent-banner.cjs.map +1 -1
  374. package/dist/components/features/analytics/telemetry-consent-banner.js +1 -0
  375. package/dist/components/features/analytics/telemetry-consent-banner.js.map +1 -1
  376. package/dist/components/features/automations/detail/activity-log-item.d.ts +3 -2
  377. package/dist/components/features/automations/detail/activity-log-section.d.ts +3 -2
  378. package/dist/components/features/automations/detail/debug-automation-button.d.ts +17 -0
  379. package/dist/components/features/automations/detail/run-logs-modal.d.ts +6 -1
  380. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  381. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  382. package/dist/components/features/backends/backend-form-modal.d.ts +6 -2
  383. package/dist/components/features/backends/backend-form-modal.js +198 -161
  384. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  385. package/dist/components/features/backends/backend-row.cjs +1 -1
  386. package/dist/components/features/backends/backend-row.cjs.map +1 -1
  387. package/dist/components/features/backends/backend-row.d.ts +2 -1
  388. package/dist/components/features/backends/backend-row.js +60 -54
  389. package/dist/components/features/backends/backend-row.js.map +1 -1
  390. package/dist/components/features/backends/backend-selector.cjs +1 -1
  391. package/dist/components/features/backends/backend-selector.cjs.map +1 -1
  392. package/dist/components/features/backends/backend-selector.js +4 -4
  393. package/dist/components/features/backends/backend-version.cjs +1 -1
  394. package/dist/components/features/backends/backend-version.cjs.map +1 -1
  395. package/dist/components/features/backends/backend-version.js +1 -0
  396. package/dist/components/features/backends/backend-version.js.map +1 -1
  397. package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
  398. package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
  399. package/dist/components/features/backends/manage-backends-modal.js +72 -61
  400. package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
  401. package/dist/components/features/chat/change-agent-button.cjs +1 -1
  402. package/dist/components/features/chat/change-agent-button.js +9 -9
  403. package/dist/components/features/chat/chat-add-file-button.cjs +1 -1
  404. package/dist/components/features/chat/chat-add-file-button.cjs.map +1 -1
  405. package/dist/components/features/chat/chat-add-file-button.js +38 -34
  406. package/dist/components/features/chat/chat-add-file-button.js.map +1 -1
  407. package/dist/components/features/chat/chat-interface.cjs +2 -2
  408. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  409. package/dist/components/features/chat/chat-interface.js +136 -129
  410. package/dist/components/features/chat/chat-interface.js.map +1 -1
  411. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  412. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  413. package/dist/components/features/chat/components/chat-input-actions.js +100 -87
  414. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  415. package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs +2 -0
  416. package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs.map +1 -0
  417. package/dist/components/features/chat/components/chat-input-llm-profile-picker.d.ts +15 -0
  418. package/dist/components/features/chat/components/chat-input-llm-profile-picker.js +118 -0
  419. package/dist/components/features/chat/components/chat-input-llm-profile-picker.js.map +1 -0
  420. package/dist/components/features/chat/components/chat-input-model.cjs +1 -1
  421. package/dist/components/features/chat/components/chat-input-model.js +17 -17
  422. package/dist/components/features/chat/components/chat-input-profile-picker.cjs +2 -0
  423. package/dist/components/features/chat/components/chat-input-profile-picker.cjs.map +1 -0
  424. package/dist/components/features/chat/components/chat-input-profile-picker.d.ts +9 -0
  425. package/dist/components/features/chat/components/chat-input-profile-picker.js +112 -0
  426. package/dist/components/features/chat/components/chat-input-profile-picker.js.map +1 -0
  427. package/dist/components/features/chat/components/resolve-picker-kind.cjs +2 -0
  428. package/dist/components/features/chat/components/resolve-picker-kind.cjs.map +1 -0
  429. package/dist/components/features/chat/components/resolve-picker-kind.d.ts +29 -0
  430. package/dist/components/features/chat/components/resolve-picker-kind.js +8 -0
  431. package/dist/components/features/chat/components/resolve-picker-kind.js.map +1 -0
  432. package/dist/components/features/chat/goal-status-banner.cjs +2 -0
  433. package/dist/components/features/chat/goal-status-banner.cjs.map +1 -0
  434. package/dist/components/features/chat/goal-status-banner.d.ts +11 -0
  435. package/dist/components/features/chat/goal-status-banner.js +12 -0
  436. package/dist/components/features/chat/goal-status-banner.js.map +1 -0
  437. package/dist/components/features/chat/goal-status-content.cjs +2 -0
  438. package/dist/components/features/chat/goal-status-content.cjs.map +1 -0
  439. package/dist/components/features/chat/goal-status-content.d.ts +21 -0
  440. package/dist/components/features/chat/goal-status-content.js +98 -0
  441. package/dist/components/features/chat/goal-status-content.js.map +1 -0
  442. package/dist/components/features/chat/interactive-chat-box.cjs +1 -1
  443. package/dist/components/features/chat/interactive-chat-box.cjs.map +1 -1
  444. package/dist/components/features/chat/interactive-chat-box.js +20 -19
  445. package/dist/components/features/chat/interactive-chat-box.js.map +1 -1
  446. package/dist/components/features/chat/tool-visualizers/primitives/code-block.cjs +1 -1
  447. package/dist/components/features/chat/tool-visualizers/primitives/code-block.cjs.map +1 -1
  448. package/dist/components/features/chat/tool-visualizers/primitives/code-block.d.ts +10 -3
  449. package/dist/components/features/chat/tool-visualizers/primitives/code-block.js +29 -16
  450. package/dist/components/features/chat/tool-visualizers/primitives/code-block.js.map +1 -1
  451. package/dist/components/features/chat/tool-visualizers/primitives/output-pane.cjs +1 -1
  452. package/dist/components/features/chat/tool-visualizers/primitives/output-pane.cjs.map +1 -1
  453. package/dist/components/features/chat/tool-visualizers/primitives/output-pane.d.ts +2 -2
  454. package/dist/components/features/chat/tool-visualizers/primitives/output-pane.js +16 -16
  455. package/dist/components/features/chat/tool-visualizers/primitives/output-pane.js.map +1 -1
  456. package/dist/components/features/chat/user-message-body.cjs +1 -1
  457. package/dist/components/features/chat/user-message-body.cjs.map +1 -1
  458. package/dist/components/features/chat/user-message-body.js +20 -20
  459. package/dist/components/features/chat/user-message-body.js.map +1 -1
  460. package/dist/components/features/command-menu/command-menu-items.d.ts +32 -0
  461. package/dist/components/features/command-menu/command-menu-trigger.cjs +2 -0
  462. package/dist/components/features/command-menu/command-menu-trigger.cjs.map +1 -0
  463. package/dist/components/features/command-menu/command-menu-trigger.d.ts +5 -0
  464. package/dist/components/features/command-menu/command-menu-trigger.js +53 -0
  465. package/dist/components/features/command-menu/command-menu-trigger.js.map +1 -0
  466. package/dist/components/features/command-menu/command-menu.d.ts +2 -0
  467. package/dist/components/features/command-menu/index.d.ts +2 -0
  468. package/dist/components/features/controls/tools-context-menu.cjs +1 -1
  469. package/dist/components/features/controls/tools-context-menu.cjs.map +1 -1
  470. package/dist/components/features/controls/tools-context-menu.d.ts +3 -1
  471. package/dist/components/features/controls/tools-context-menu.js +94 -77
  472. package/dist/components/features/controls/tools-context-menu.js.map +1 -1
  473. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.cjs +1 -1
  474. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.cjs.map +1 -1
  475. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.js +8 -5
  476. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.js.map +1 -1
  477. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs.map +1 -1
  478. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.d.ts +1 -1
  479. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js.map +1 -1
  480. package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
  481. package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
  482. package/dist/components/features/conversation-panel/conversation-panel.js +2 -1
  483. package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
  484. package/dist/components/features/conversation-panel/local-new-conversation-menu.cjs +1 -1
  485. package/dist/components/features/conversation-panel/local-new-conversation-menu.cjs.map +1 -1
  486. package/dist/components/features/conversation-panel/local-new-conversation-menu.js +4 -1
  487. package/dist/components/features/conversation-panel/local-new-conversation-menu.js.map +1 -1
  488. package/dist/components/features/conversation-panel/plugins-modal.cjs +2 -0
  489. package/dist/components/features/conversation-panel/plugins-modal.cjs.map +1 -0
  490. package/dist/components/features/conversation-panel/plugins-modal.d.ts +12 -0
  491. package/dist/components/features/conversation-panel/plugins-modal.js +62 -0
  492. package/dist/components/features/conversation-panel/plugins-modal.js.map +1 -0
  493. package/dist/components/features/home/git-repo-dropdown/git-repo-dropdown.cjs +1 -1
  494. package/dist/components/features/home/git-repo-dropdown/git-repo-dropdown.cjs.map +1 -1
  495. package/dist/components/features/home/git-repo-dropdown/git-repo-dropdown.js +4 -4
  496. package/dist/components/features/mcp-logo-badge.cjs +1 -1
  497. package/dist/components/features/mcp-logo-badge.cjs.map +1 -1
  498. package/dist/components/features/mcp-logo-badge.js +17 -15
  499. package/dist/components/features/mcp-logo-badge.js.map +1 -1
  500. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  501. package/dist/components/features/mcp-page/custom-server-editor.cjs.map +1 -1
  502. package/dist/components/features/mcp-page/custom-server-editor.js +102 -59
  503. package/dist/components/features/mcp-page/custom-server-editor.js.map +1 -1
  504. package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
  505. package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
  506. package/dist/components/features/mcp-page/install-server-modal.js +284 -169
  507. package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
  508. package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
  509. package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
  510. package/dist/components/features/mcp-page/installed-server-card.js +16 -18
  511. package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
  512. package/dist/components/features/onboarding/onboarding-host.d.ts +3 -13
  513. package/dist/components/features/plugins/add-plugin-modal.d.ts +6 -0
  514. package/dist/components/features/plugins/build-plugins-view-model.d.ts +39 -0
  515. package/dist/components/features/plugins/plugin-card.d.ts +13 -0
  516. package/dist/components/features/plugins/plugin-detail-modal.d.ts +13 -0
  517. package/dist/components/features/plugins/plugin-picker-card.d.ts +10 -0
  518. package/dist/components/features/plugins/plugin-picker-modal.d.ts +9 -0
  519. package/dist/components/features/plugins/plugin-picker-trigger.d.ts +9 -0
  520. package/dist/components/features/plugins/plugin-picker.d.ts +18 -0
  521. package/dist/components/features/plugins/plugin-spec-identity.d.ts +28 -0
  522. package/dist/components/features/plugins/plugins-toolbar.d.ts +9 -0
  523. package/dist/components/features/settings/agent-profiles/agent-profile-actions-menu.d.ts +16 -0
  524. package/dist/components/features/settings/agent-profiles/agent-profile-row.d.ts +13 -0
  525. package/dist/components/features/settings/agent-profiles/agent-profiles-body.d.ts +15 -0
  526. package/dist/components/features/settings/agent-profiles/agent-profiles-local-view.d.ts +7 -0
  527. package/dist/components/features/settings/agent-profiles/agent-profiles-manager.d.ts +7 -0
  528. package/dist/components/features/settings/agent-profiles/delete-agent-profile-modal.d.ts +7 -0
  529. package/dist/components/features/settings/agent-profiles/index.d.ts +6 -0
  530. package/dist/components/features/settings/agent-profiles/merge-agent-profile-save-input.d.ts +18 -0
  531. package/dist/components/features/settings/llm-profiles/llm-profiles-manager.cjs +1 -1
  532. package/dist/components/features/settings/llm-profiles/llm-profiles-manager.js +1 -0
  533. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
  534. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +1 -1
  535. package/dist/components/features/settings/llm-profiles/profile-row.d.ts +3 -1
  536. package/dist/components/features/settings/llm-profiles/profiles-body.d.ts +3 -1
  537. package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.cjs +1 -1
  538. package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.cjs.map +1 -1
  539. package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.js +3 -2
  540. package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.js.map +1 -1
  541. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +7 -7
  542. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
  543. package/dist/components/features/settings/mcp-settings/mcp-server-form.js +279 -130
  544. package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
  545. package/dist/components/features/settings/mcp-settings/mcp-server-list-item.d.ts +1 -12
  546. package/dist/components/features/settings/mcp-settings/mcp-server-list.d.ts +1 -11
  547. package/dist/components/features/settings/settings-dropdown-input.cjs +1 -1
  548. package/dist/components/features/settings/settings-dropdown-input.js +6 -6
  549. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  550. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  551. package/dist/components/features/sidebar/sidebar-rail-body.d.ts +1 -2
  552. package/dist/components/features/sidebar/sidebar-rail-body.js +81 -82
  553. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  554. package/dist/components/features/sidebar/sidebar.cjs +1 -1
  555. package/dist/components/features/sidebar/sidebar.cjs.map +1 -1
  556. package/dist/components/features/sidebar/sidebar.js +45 -46
  557. package/dist/components/features/sidebar/sidebar.js.map +1 -1
  558. package/dist/components/features/skills/extensions-navigation.cjs +1 -1
  559. package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
  560. package/dist/components/features/skills/extensions-navigation.js +1 -2
  561. package/dist/components/features/skills/extensions-navigation.js.map +1 -1
  562. package/dist/components/shared/modals/modal-backdrop.cjs +1 -1
  563. package/dist/components/shared/modals/modal-backdrop.cjs.map +1 -1
  564. package/dist/components/shared/modals/modal-backdrop.d.ts +5 -1
  565. package/dist/components/shared/modals/modal-backdrop.js +3 -3
  566. package/dist/components/shared/modals/modal-backdrop.js.map +1 -1
  567. package/dist/components/shared/modals/settings/model-selector.cjs +1 -1
  568. package/dist/components/shared/modals/settings/model-selector.js +16 -16
  569. package/dist/config/defaults.cjs +1 -1
  570. package/dist/config/defaults.cjs.map +1 -1
  571. package/dist/config/defaults.js +7 -3
  572. package/dist/config/defaults.js.map +1 -1
  573. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  574. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  575. package/dist/contexts/conversation-websocket-context.js +200 -197
  576. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  577. package/dist/hooks/chat/use-goal-interceptor.cjs +2 -0
  578. package/dist/hooks/chat/use-goal-interceptor.cjs.map +1 -0
  579. package/dist/hooks/chat/use-goal-interceptor.d.ts +8 -0
  580. package/dist/hooks/chat/use-goal-interceptor.js +37 -0
  581. package/dist/hooks/chat/use-goal-interceptor.js.map +1 -0
  582. package/dist/hooks/chat/use-grip-resize.cjs +1 -1
  583. package/dist/hooks/chat/use-grip-resize.cjs.map +1 -1
  584. package/dist/hooks/chat/use-grip-resize.js +17 -16
  585. package/dist/hooks/chat/use-grip-resize.js.map +1 -1
  586. package/dist/hooks/chat/use-model-interceptor.cjs +1 -1
  587. package/dist/hooks/chat/use-model-interceptor.cjs.map +1 -1
  588. package/dist/hooks/chat/use-model-interceptor.d.ts +3 -3
  589. package/dist/hooks/chat/use-model-interceptor.js +8 -9
  590. package/dist/hooks/chat/use-model-interceptor.js.map +1 -1
  591. package/dist/hooks/chat/use-slash-command.cjs +1 -1
  592. package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
  593. package/dist/hooks/chat/use-slash-command.js +4 -4
  594. package/dist/hooks/chat/use-slash-command.js.map +1 -1
  595. package/dist/hooks/mutation/conversation-mutation-utils.cjs +1 -1
  596. package/dist/hooks/mutation/conversation-mutation-utils.cjs.map +1 -1
  597. package/dist/hooks/mutation/conversation-mutation-utils.d.ts +17 -0
  598. package/dist/hooks/mutation/conversation-mutation-utils.js +23 -4
  599. package/dist/hooks/mutation/conversation-mutation-utils.js.map +1 -1
  600. package/dist/hooks/mutation/use-activate-agent-profile.cjs +2 -0
  601. package/dist/hooks/mutation/use-activate-agent-profile.cjs.map +1 -0
  602. package/dist/hooks/mutation/use-activate-agent-profile.d.ts +23 -0
  603. package/dist/hooks/mutation/use-activate-agent-profile.js +34 -0
  604. package/dist/hooks/mutation/use-activate-agent-profile.js.map +1 -0
  605. package/dist/hooks/mutation/use-activate-llm-profile.cjs +1 -1
  606. package/dist/hooks/mutation/use-activate-llm-profile.js +1 -1
  607. package/dist/hooks/mutation/use-add-mcp-server.cjs +1 -1
  608. package/dist/hooks/mutation/use-add-mcp-server.cjs.map +1 -1
  609. package/dist/hooks/mutation/use-add-mcp-server.d.ts +1 -12
  610. package/dist/hooks/mutation/use-add-mcp-server.js +10 -34
  611. package/dist/hooks/mutation/use-add-mcp-server.js.map +1 -1
  612. package/dist/hooks/mutation/use-apply-onboarding-agent-profile.d.ts +20 -0
  613. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  614. package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
  615. package/dist/hooks/mutation/use-create-conversation.d.ts +2 -0
  616. package/dist/hooks/mutation/use-create-conversation.js +94 -25
  617. package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
  618. package/dist/hooks/mutation/use-delete-agent-profile.d.ts +1 -0
  619. package/dist/hooks/mutation/use-delete-llm-profile.cjs +1 -1
  620. package/dist/hooks/mutation/use-delete-llm-profile.js +1 -1
  621. package/dist/hooks/mutation/use-delete-mcp-server.cjs +1 -1
  622. package/dist/hooks/mutation/use-delete-mcp-server.js +4 -4
  623. package/dist/hooks/mutation/use-fork-conversation.cjs +2 -0
  624. package/dist/hooks/mutation/use-fork-conversation.cjs.map +1 -0
  625. package/dist/hooks/mutation/use-fork-conversation.d.ts +24 -0
  626. package/dist/hooks/mutation/use-fork-conversation.js +29 -0
  627. package/dist/hooks/mutation/use-fork-conversation.js.map +1 -0
  628. package/dist/hooks/mutation/use-install-plugin.d.ts +7 -0
  629. package/dist/hooks/mutation/use-new-conversation-command.cjs +1 -1
  630. package/dist/hooks/mutation/use-new-conversation-command.cjs.map +1 -1
  631. package/dist/hooks/mutation/use-new-conversation-command.d.ts +1 -0
  632. package/dist/hooks/mutation/use-new-conversation-command.js +20 -10
  633. package/dist/hooks/mutation/use-new-conversation-command.js.map +1 -1
  634. package/dist/hooks/mutation/use-rename-agent-profile.d.ts +6 -0
  635. package/dist/hooks/mutation/use-rename-llm-profile.cjs +1 -1
  636. package/dist/hooks/mutation/use-rename-llm-profile.js +1 -1
  637. package/dist/hooks/mutation/use-save-agent-profile.d.ts +5 -0
  638. package/dist/hooks/mutation/use-save-llm-profile.cjs +1 -1
  639. package/dist/hooks/mutation/use-save-llm-profile.js +1 -1
  640. package/dist/hooks/mutation/use-switch-acp-model.cjs.map +1 -1
  641. package/dist/hooks/mutation/use-switch-acp-model.js.map +1 -1
  642. package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs +1 -1
  643. package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs.map +1 -1
  644. package/dist/hooks/mutation/use-switch-llm-profile-and-log.d.ts +3 -4
  645. package/dist/hooks/mutation/use-switch-llm-profile-and-log.js +10 -35
  646. package/dist/hooks/mutation/use-switch-llm-profile-and-log.js.map +1 -1
  647. package/dist/hooks/mutation/use-switch-llm-profile.cjs +1 -1
  648. package/dist/hooks/mutation/use-switch-llm-profile.cjs.map +1 -1
  649. package/dist/hooks/mutation/use-switch-llm-profile.d.ts +20 -5
  650. package/dist/hooks/mutation/use-switch-llm-profile.js +38 -14
  651. package/dist/hooks/mutation/use-switch-llm-profile.js.map +1 -1
  652. package/dist/hooks/mutation/use-update-mcp-server.cjs +1 -1
  653. package/dist/hooks/mutation/use-update-mcp-server.cjs.map +1 -1
  654. package/dist/hooks/mutation/use-update-mcp-server.js +11 -37
  655. package/dist/hooks/mutation/use-update-mcp-server.js.map +1 -1
  656. package/dist/hooks/query/query-keys.cjs +1 -1
  657. package/dist/hooks/query/query-keys.cjs.map +1 -1
  658. package/dist/hooks/query/query-keys.d.ts +21 -0
  659. package/dist/hooks/query/query-keys.js +7 -3
  660. package/dist/hooks/query/query-keys.js.map +1 -1
  661. package/dist/hooks/query/use-active-conversation.cjs +1 -1
  662. package/dist/hooks/query/use-active-conversation.cjs.map +1 -1
  663. package/dist/hooks/query/use-active-conversation.js +17 -16
  664. package/dist/hooks/query/use-active-conversation.js.map +1 -1
  665. package/dist/hooks/query/use-agent-profiles.cjs +2 -0
  666. package/dist/hooks/query/use-agent-profiles.cjs.map +1 -0
  667. package/dist/hooks/query/use-agent-profiles.d.ts +13 -0
  668. package/dist/hooks/query/use-agent-profiles.js +24 -0
  669. package/dist/hooks/query/use-agent-profiles.js.map +1 -0
  670. package/dist/hooks/query/use-backends-health.cjs +1 -1
  671. package/dist/hooks/query/use-backends-health.cjs.map +1 -1
  672. package/dist/hooks/query/use-backends-health.js +18 -3
  673. package/dist/hooks/query/use-backends-health.js.map +1 -1
  674. package/dist/hooks/query/use-conversation-history.cjs +1 -1
  675. package/dist/hooks/query/use-conversation-history.cjs.map +1 -1
  676. package/dist/hooks/query/use-conversation-history.js +4 -2
  677. package/dist/hooks/query/use-conversation-history.js.map +1 -1
  678. package/dist/hooks/query/use-local-workspaces.cjs +1 -1
  679. package/dist/hooks/query/use-local-workspaces.cjs.map +1 -1
  680. package/dist/hooks/query/use-local-workspaces.js +1 -0
  681. package/dist/hooks/query/use-local-workspaces.js.map +1 -1
  682. package/dist/hooks/query/use-plugins-marketplace.d.ts +7 -0
  683. package/dist/hooks/query/use-resolved-workspaces.cjs +1 -1
  684. package/dist/hooks/query/use-resolved-workspaces.cjs.map +1 -1
  685. package/dist/hooks/query/use-resolved-workspaces.js +7 -6
  686. package/dist/hooks/query/use-resolved-workspaces.js.map +1 -1
  687. package/dist/hooks/query/use-search-subdirs.cjs +1 -1
  688. package/dist/hooks/query/use-search-subdirs.cjs.map +1 -1
  689. package/dist/hooks/query/use-search-subdirs.js +1 -0
  690. package/dist/hooks/query/use-search-subdirs.js.map +1 -1
  691. package/dist/hooks/query/use-settings.cjs +1 -1
  692. package/dist/hooks/query/use-settings.cjs.map +1 -1
  693. package/dist/hooks/query/use-settings.js +11 -11
  694. package/dist/hooks/query/use-settings.js.map +1 -1
  695. package/dist/hooks/query/use-verified-models.cjs +1 -1
  696. package/dist/hooks/query/use-verified-models.cjs.map +1 -1
  697. package/dist/hooks/query/use-verified-models.js +1 -0
  698. package/dist/hooks/query/use-verified-models.js.map +1 -1
  699. package/dist/hooks/use-acp-model-context.cjs +1 -1
  700. package/dist/hooks/use-acp-model-context.cjs.map +1 -1
  701. package/dist/hooks/use-acp-model-context.d.ts +1 -1
  702. package/dist/hooks/use-acp-model-context.js +9 -8
  703. package/dist/hooks/use-acp-model-context.js.map +1 -1
  704. package/dist/hooks/use-active-agent-profile.cjs +2 -0
  705. package/dist/hooks/use-active-agent-profile.cjs.map +1 -0
  706. package/dist/hooks/use-active-agent-profile.d.ts +20 -0
  707. package/dist/hooks/use-active-agent-profile.js +17 -0
  708. package/dist/hooks/use-active-agent-profile.js.map +1 -0
  709. package/dist/hooks/use-auto-resize.cjs +1 -1
  710. package/dist/hooks/use-auto-resize.cjs.map +1 -1
  711. package/dist/hooks/use-auto-resize.d.ts +2 -0
  712. package/dist/hooks/use-auto-resize.js +49 -45
  713. package/dist/hooks/use-auto-resize.js.map +1 -1
  714. package/dist/hooks/use-can-manage-org-profiles.cjs +1 -0
  715. package/dist/hooks/use-can-manage-org-profiles.d.ts +18 -0
  716. package/dist/hooks/use-can-manage-org-profiles.js +2 -0
  717. package/dist/hooks/use-chat-input-llm-profile-state.cjs +2 -0
  718. package/dist/hooks/use-chat-input-llm-profile-state.cjs.map +1 -0
  719. package/dist/hooks/use-chat-input-llm-profile-state.d.ts +23 -0
  720. package/dist/hooks/use-chat-input-llm-profile-state.js +30 -0
  721. package/dist/hooks/use-chat-input-llm-profile-state.js.map +1 -0
  722. package/dist/hooks/use-chat-input-model-state.cjs.map +1 -1
  723. package/dist/hooks/use-chat-input-model-state.d.ts +1 -1
  724. package/dist/hooks/use-chat-input-model-state.js.map +1 -1
  725. package/dist/hooks/use-chat-input-profile-state.cjs +2 -0
  726. package/dist/hooks/use-chat-input-profile-state.cjs.map +1 -0
  727. package/dist/hooks/use-chat-input-profile-state.d.ts +20 -0
  728. package/dist/hooks/use-chat-input-profile-state.js +22 -0
  729. package/dist/hooks/use-chat-input-profile-state.js.map +1 -0
  730. package/dist/hooks/use-conversation-name-context-menu.cjs +1 -1
  731. package/dist/hooks/use-conversation-name-context-menu.cjs.map +1 -1
  732. package/dist/hooks/use-conversation-name-context-menu.d.ts +4 -0
  733. package/dist/hooks/use-conversation-name-context-menu.js +44 -37
  734. package/dist/hooks/use-conversation-name-context-menu.js.map +1 -1
  735. package/dist/hooks/use-conversation-plugins.cjs +2 -0
  736. package/dist/hooks/use-conversation-plugins.cjs.map +1 -0
  737. package/dist/hooks/use-conversation-plugins.d.ts +9 -0
  738. package/dist/hooks/use-conversation-plugins.js +12 -0
  739. package/dist/hooks/use-conversation-plugins.js.map +1 -0
  740. package/dist/hooks/use-handle-plan-click.cjs +1 -1
  741. package/dist/hooks/use-handle-plan-click.cjs.map +1 -1
  742. package/dist/hooks/use-handle-plan-click.js +2 -1
  743. package/dist/hooks/use-handle-plan-click.js.map +1 -1
  744. package/dist/hooks/use-llm-configured.cjs +1 -1
  745. package/dist/hooks/use-llm-configured.cjs.map +1 -1
  746. package/dist/hooks/use-llm-configured.js +17 -16
  747. package/dist/hooks/use-llm-configured.js.map +1 -1
  748. package/dist/hooks/use-tracking.cjs +1 -1
  749. package/dist/hooks/use-tracking.cjs.map +1 -1
  750. package/dist/hooks/use-tracking.d.ts +51 -1
  751. package/dist/hooks/use-tracking.js +61 -2
  752. package/dist/hooks/use-tracking.js.map +1 -1
  753. package/dist/i18n/declaration.cjs +1 -1
  754. package/dist/i18n/declaration.cjs.map +1 -1
  755. package/dist/i18n/declaration.d.ts +138 -1
  756. package/dist/i18n/declaration.js +1 -1
  757. package/dist/i18n/declaration.js.map +1 -1
  758. package/dist/i18n/translation.cjs +18 -3
  759. package/dist/i18n/translation.cjs.map +1 -1
  760. package/dist/i18n/translation.js +2329 -0
  761. package/dist/i18n/translation.js.map +1 -1
  762. package/dist/icons/slack.cjs +2 -0
  763. package/dist/icons/slack.cjs.map +1 -0
  764. package/dist/icons/slack.js +19 -0
  765. package/dist/icons/slack.js.map +1 -0
  766. package/dist/icons/u-puzzle-piece.cjs +2 -0
  767. package/dist/icons/u-puzzle-piece.cjs.map +1 -0
  768. package/dist/icons/u-puzzle-piece.js +19 -0
  769. package/dist/icons/u-puzzle-piece.js.map +1 -0
  770. package/dist/icons/x-circle-solid.cjs +2 -0
  771. package/dist/icons/x-circle-solid.cjs.map +1 -0
  772. package/dist/icons/x-circle-solid.js +13 -0
  773. package/dist/icons/x-circle-solid.js.map +1 -0
  774. package/dist/locales/ar/openhands.json +138 -1
  775. package/dist/locales/ca/openhands.json +138 -1
  776. package/dist/locales/de/openhands.json +138 -1
  777. package/dist/locales/en/openhands.json +138 -1
  778. package/dist/locales/es/openhands.json +138 -1
  779. package/dist/locales/fr/openhands.json +138 -1
  780. package/dist/locales/it/openhands.json +138 -1
  781. package/dist/locales/ja/openhands.json +138 -1
  782. package/dist/locales/ko-KR/openhands.json +138 -1
  783. package/dist/locales/no/openhands.json +138 -1
  784. package/dist/locales/pt/openhands.json +138 -1
  785. package/dist/locales/tr/openhands.json +138 -1
  786. package/dist/locales/uk/openhands.json +138 -1
  787. package/dist/locales/zh-CN/openhands.json +138 -1
  788. package/dist/locales/zh-TW/openhands.json +138 -1
  789. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.cjs +1 -1
  790. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.cjs.map +1 -1
  791. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.js +0 -20
  792. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.js.map +1 -1
  793. package/dist/node_modules/@openhands/extensions/integrations/catalog/asana.cjs +1 -1
  794. package/dist/node_modules/@openhands/extensions/integrations/catalog/asana.cjs.map +1 -1
  795. package/dist/node_modules/@openhands/extensions/integrations/catalog/asana.js +1 -6
  796. package/dist/node_modules/@openhands/extensions/integrations/catalog/asana.js.map +1 -1
  797. package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.cjs +1 -1
  798. package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.cjs.map +1 -1
  799. package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.js +70 -3
  800. package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.js.map +1 -1
  801. package/dist/node_modules/@openhands/extensions/integrations/catalog/bitbucket.cjs +1 -1
  802. package/dist/node_modules/@openhands/extensions/integrations/catalog/bitbucket.cjs.map +1 -1
  803. package/dist/node_modules/@openhands/extensions/integrations/catalog/bitbucket.js +1 -6
  804. package/dist/node_modules/@openhands/extensions/integrations/catalog/bitbucket.js.map +1 -1
  805. package/dist/node_modules/@openhands/extensions/integrations/catalog/box.cjs +1 -1
  806. package/dist/node_modules/@openhands/extensions/integrations/catalog/box.cjs.map +1 -1
  807. package/dist/node_modules/@openhands/extensions/integrations/catalog/box.js +1 -6
  808. package/dist/node_modules/@openhands/extensions/integrations/catalog/box.js.map +1 -1
  809. package/dist/node_modules/@openhands/extensions/integrations/catalog/canva.cjs +1 -1
  810. package/dist/node_modules/@openhands/extensions/integrations/catalog/canva.cjs.map +1 -1
  811. package/dist/node_modules/@openhands/extensions/integrations/catalog/canva.js +3 -7
  812. package/dist/node_modules/@openhands/extensions/integrations/catalog/canva.js.map +1 -1
  813. package/dist/node_modules/@openhands/extensions/integrations/catalog/confluence.cjs +1 -1
  814. package/dist/node_modules/@openhands/extensions/integrations/catalog/confluence.cjs.map +1 -1
  815. package/dist/node_modules/@openhands/extensions/integrations/catalog/confluence.js +1 -6
  816. package/dist/node_modules/@openhands/extensions/integrations/catalog/confluence.js.map +1 -1
  817. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
  818. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
  819. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +27 -2
  820. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
  821. package/dist/node_modules/@openhands/extensions/integrations/catalog/discord.cjs +1 -1
  822. package/dist/node_modules/@openhands/extensions/integrations/catalog/discord.cjs.map +1 -1
  823. package/dist/node_modules/@openhands/extensions/integrations/catalog/discord.js +1 -6
  824. package/dist/node_modules/@openhands/extensions/integrations/catalog/discord.js.map +1 -1
  825. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.cjs +1 -1
  826. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.cjs.map +1 -1
  827. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.js +20 -26
  828. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.js.map +1 -1
  829. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.cjs +1 -1
  830. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.cjs.map +1 -1
  831. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.js +0 -9
  832. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.js.map +1 -1
  833. package/dist/node_modules/@openhands/extensions/integrations/catalog/gmail.cjs +1 -1
  834. package/dist/node_modules/@openhands/extensions/integrations/catalog/gmail.cjs.map +1 -1
  835. package/dist/node_modules/@openhands/extensions/integrations/catalog/gmail.js +1 -6
  836. package/dist/node_modules/@openhands/extensions/integrations/catalog/gmail.js.map +1 -1
  837. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-calendar.cjs +1 -1
  838. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-calendar.cjs.map +1 -1
  839. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-calendar.js +1 -6
  840. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-calendar.js.map +1 -1
  841. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-docs.cjs +1 -1
  842. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-docs.cjs.map +1 -1
  843. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-docs.js +1 -6
  844. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-docs.js.map +1 -1
  845. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-drive.cjs +1 -1
  846. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-drive.cjs.map +1 -1
  847. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-drive.js +1 -6
  848. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-drive.js.map +1 -1
  849. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-sheets.cjs +1 -1
  850. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-sheets.cjs.map +1 -1
  851. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-sheets.js +1 -6
  852. package/dist/node_modules/@openhands/extensions/integrations/catalog/google-sheets.js.map +1 -1
  853. package/dist/node_modules/@openhands/extensions/integrations/catalog/intercom.cjs +1 -1
  854. package/dist/node_modules/@openhands/extensions/integrations/catalog/intercom.cjs.map +1 -1
  855. package/dist/node_modules/@openhands/extensions/integrations/catalog/intercom.js +1 -6
  856. package/dist/node_modules/@openhands/extensions/integrations/catalog/intercom.js.map +1 -1
  857. package/dist/node_modules/@openhands/extensions/integrations/catalog/jira.cjs +1 -1
  858. package/dist/node_modules/@openhands/extensions/integrations/catalog/jira.cjs.map +1 -1
  859. package/dist/node_modules/@openhands/extensions/integrations/catalog/jira.js +1 -6
  860. package/dist/node_modules/@openhands/extensions/integrations/catalog/jira.js.map +1 -1
  861. package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.cjs +1 -1
  862. package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.cjs.map +1 -1
  863. package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.js +13 -13
  864. package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.js.map +1 -1
  865. package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-outlook.cjs +1 -1
  866. package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-outlook.cjs.map +1 -1
  867. package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-outlook.js +1 -6
  868. package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-outlook.js.map +1 -1
  869. package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-teams.cjs +1 -1
  870. package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-teams.cjs.map +1 -1
  871. package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-teams.js +1 -6
  872. package/dist/node_modules/@openhands/extensions/integrations/catalog/microsoft-teams.js.map +1 -1
  873. package/dist/node_modules/@openhands/extensions/integrations/catalog/miro.cjs +1 -1
  874. package/dist/node_modules/@openhands/extensions/integrations/catalog/miro.cjs.map +1 -1
  875. package/dist/node_modules/@openhands/extensions/integrations/catalog/miro.js +14 -10
  876. package/dist/node_modules/@openhands/extensions/integrations/catalog/miro.js.map +1 -1
  877. package/dist/node_modules/@openhands/extensions/integrations/catalog/monday.cjs +1 -1
  878. package/dist/node_modules/@openhands/extensions/integrations/catalog/monday.cjs.map +1 -1
  879. package/dist/node_modules/@openhands/extensions/integrations/catalog/monday.js +13 -10
  880. package/dist/node_modules/@openhands/extensions/integrations/catalog/monday.js.map +1 -1
  881. package/dist/node_modules/@openhands/extensions/integrations/catalog/netlify.cjs +1 -1
  882. package/dist/node_modules/@openhands/extensions/integrations/catalog/netlify.cjs.map +1 -1
  883. package/dist/node_modules/@openhands/extensions/integrations/catalog/netlify.js +1 -6
  884. package/dist/node_modules/@openhands/extensions/integrations/catalog/netlify.js.map +1 -1
  885. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs +1 -1
  886. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs.map +1 -1
  887. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js +1 -8
  888. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js.map +1 -1
  889. package/dist/node_modules/@openhands/extensions/integrations/catalog/okta.cjs +1 -1
  890. package/dist/node_modules/@openhands/extensions/integrations/catalog/okta.cjs.map +1 -1
  891. package/dist/node_modules/@openhands/extensions/integrations/catalog/okta.js +1 -6
  892. package/dist/node_modules/@openhands/extensions/integrations/catalog/okta.js.map +1 -1
  893. package/dist/node_modules/@openhands/extensions/integrations/catalog/onedrive.cjs +1 -1
  894. package/dist/node_modules/@openhands/extensions/integrations/catalog/onedrive.cjs.map +1 -1
  895. package/dist/node_modules/@openhands/extensions/integrations/catalog/onedrive.js +1 -6
  896. package/dist/node_modules/@openhands/extensions/integrations/catalog/onedrive.js.map +1 -1
  897. package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.cjs +1 -1
  898. package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.cjs.map +1 -1
  899. package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.js +20 -18
  900. package/dist/node_modules/@openhands/extensions/integrations/catalog/posthog.js.map +1 -1
  901. package/dist/node_modules/@openhands/extensions/integrations/catalog/quickbooks.cjs +1 -1
  902. package/dist/node_modules/@openhands/extensions/integrations/catalog/quickbooks.cjs.map +1 -1
  903. package/dist/node_modules/@openhands/extensions/integrations/catalog/quickbooks.js +66 -21
  904. package/dist/node_modules/@openhands/extensions/integrations/catalog/quickbooks.js.map +1 -1
  905. package/dist/node_modules/@openhands/extensions/integrations/catalog/salesforce.cjs +1 -1
  906. package/dist/node_modules/@openhands/extensions/integrations/catalog/salesforce.cjs.map +1 -1
  907. package/dist/node_modules/@openhands/extensions/integrations/catalog/salesforce.js +17 -11
  908. package/dist/node_modules/@openhands/extensions/integrations/catalog/salesforce.js.map +1 -1
  909. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.cjs +1 -1
  910. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.cjs.map +1 -1
  911. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.js +12 -17
  912. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.js.map +1 -1
  913. package/dist/node_modules/@openhands/extensions/integrations/catalog/sharepoint.cjs +1 -1
  914. package/dist/node_modules/@openhands/extensions/integrations/catalog/sharepoint.cjs.map +1 -1
  915. package/dist/node_modules/@openhands/extensions/integrations/catalog/sharepoint.js +1 -6
  916. package/dist/node_modules/@openhands/extensions/integrations/catalog/sharepoint.js.map +1 -1
  917. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.cjs +1 -1
  918. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.cjs.map +1 -1
  919. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.js +1 -1
  920. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.js.map +1 -1
  921. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.cjs +1 -1
  922. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.cjs.map +1 -1
  923. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.js +14 -19
  924. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.js.map +1 -1
  925. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.cjs +1 -1
  926. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.cjs.map +1 -1
  927. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.js +15 -20
  928. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.js.map +1 -1
  929. package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.cjs +2 -0
  930. package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.cjs.map +1 -0
  931. package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.js +33 -0
  932. package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.js.map +1 -0
  933. package/dist/node_modules/@openhands/extensions/integrations/catalog/trello.cjs +1 -1
  934. package/dist/node_modules/@openhands/extensions/integrations/catalog/trello.cjs.map +1 -1
  935. package/dist/node_modules/@openhands/extensions/integrations/catalog/trello.js +10 -8
  936. package/dist/node_modules/@openhands/extensions/integrations/catalog/trello.js.map +1 -1
  937. package/dist/node_modules/@openhands/extensions/integrations/catalog/vercel.cjs +1 -1
  938. package/dist/node_modules/@openhands/extensions/integrations/catalog/vercel.cjs.map +1 -1
  939. package/dist/node_modules/@openhands/extensions/integrations/catalog/vercel.js +1 -6
  940. package/dist/node_modules/@openhands/extensions/integrations/catalog/vercel.js.map +1 -1
  941. package/dist/node_modules/@openhands/extensions/integrations/catalog/xero.cjs +1 -1
  942. package/dist/node_modules/@openhands/extensions/integrations/catalog/xero.cjs.map +1 -1
  943. package/dist/node_modules/@openhands/extensions/integrations/catalog/xero.js +1 -6
  944. package/dist/node_modules/@openhands/extensions/integrations/catalog/xero.js.map +1 -1
  945. package/dist/node_modules/@openhands/extensions/integrations/catalog/zoom.cjs +1 -1
  946. package/dist/node_modules/@openhands/extensions/integrations/catalog/zoom.cjs.map +1 -1
  947. package/dist/node_modules/@openhands/extensions/integrations/catalog/zoom.js +1 -6
  948. package/dist/node_modules/@openhands/extensions/integrations/catalog/zoom.js.map +1 -1
  949. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs +1 -1
  950. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs.map +1 -1
  951. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js +71 -89
  952. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js.map +1 -1
  953. package/dist/node_modules/@openhands/extensions/integrations/index.cjs +1 -1
  954. package/dist/node_modules/@openhands/extensions/integrations/index.cjs.map +1 -1
  955. package/dist/node_modules/@openhands/extensions/integrations/index.js +4 -4
  956. package/dist/node_modules/@openhands/extensions/integrations/index.js.map +1 -1
  957. package/dist/node_modules/@openhands/extensions/skills/index.cjs +502 -43
  958. package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
  959. package/dist/node_modules/@openhands/extensions/skills/index.js +58 -33
  960. package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
  961. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-profiles-client.cjs +2 -0
  962. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-profiles-client.cjs.map +1 -0
  963. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-profiles-client.js +40 -0
  964. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-profiles-client.js.map +1 -0
  965. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.cjs +1 -1
  966. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.cjs.map +1 -1
  967. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js +4 -4
  968. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js.map +1 -1
  969. package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.cjs +1 -1
  970. package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.cjs.map +1 -1
  971. package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.js +3 -0
  972. package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.js.map +1 -1
  973. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs +1 -1
  974. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs.map +1 -1
  975. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js +3 -0
  976. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js.map +1 -1
  977. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs +1 -0
  978. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js +1 -0
  979. package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.cjs +1 -0
  980. package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.js +1 -0
  981. package/dist/node_modules/@openhands/typescript-client/dist/client/http-client.cjs +1 -1
  982. package/dist/node_modules/@openhands/typescript-client/dist/client/http-client.cjs.map +1 -1
  983. package/dist/node_modules/@openhands/typescript-client/dist/client/http-client.js +84 -27
  984. package/dist/node_modules/@openhands/typescript-client/dist/client/http-client.js.map +1 -1
  985. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.cjs +1 -1
  986. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.cjs.map +1 -1
  987. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.js +9 -0
  988. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.js.map +1 -1
  989. package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.cjs +1 -0
  990. package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.js +1 -0
  991. package/dist/node_modules/@openhands/typescript-client/dist/client/plugins-client.cjs +2 -0
  992. package/dist/node_modules/@openhands/typescript-client/dist/client/plugins-client.cjs.map +1 -0
  993. package/dist/node_modules/@openhands/typescript-client/dist/client/plugins-client.js +42 -0
  994. package/dist/node_modules/@openhands/typescript-client/dist/client/plugins-client.js.map +1 -0
  995. package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.cjs +1 -0
  996. package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.js +1 -0
  997. package/dist/node_modules/@openhands/typescript-client/dist/client/skills-client.cjs +1 -1
  998. package/dist/node_modules/@openhands/typescript-client/dist/client/skills-client.cjs.map +1 -1
  999. package/dist/node_modules/@openhands/typescript-client/dist/client/skills-client.js +1 -1
  1000. package/dist/node_modules/@openhands/typescript-client/dist/client/skills-client.js.map +1 -1
  1001. package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.cjs +1 -0
  1002. package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.js +1 -0
  1003. package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.cjs +1 -0
  1004. package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.js +1 -0
  1005. package/dist/node_modules/@openhands/typescript-client/dist/clients.cjs +1 -0
  1006. package/dist/node_modules/@openhands/typescript-client/dist/clients.js +20 -0
  1007. package/dist/node_modules/@openhands/typescript-client/dist/conversation/conversation-manager.cjs +1 -1
  1008. package/dist/node_modules/@openhands/typescript-client/dist/conversation/conversation-manager.js +18 -0
  1009. package/dist/node_modules/@openhands/typescript-client/dist/conversation/conversation.cjs +1 -1
  1010. package/dist/node_modules/@openhands/typescript-client/dist/conversation/conversation.js +1 -0
  1011. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-conversation.cjs +1 -1
  1012. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-conversation.js +2 -0
  1013. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.cjs +1 -1
  1014. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.cjs.map +1 -1
  1015. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.js +15 -17
  1016. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.js.map +1 -1
  1017. package/dist/node_modules/@openhands/typescript-client/dist/index.cjs +1 -1
  1018. package/dist/node_modules/@openhands/typescript-client/dist/index.js +3 -0
  1019. package/dist/node_modules/@openhands/typescript-client/dist/workspace/workspace.cjs +1 -0
  1020. package/dist/node_modules/@openhands/typescript-client/dist/workspace/workspace.js +1 -0
  1021. package/dist/package.cjs +1 -1
  1022. package/dist/package.cjs.map +1 -1
  1023. package/dist/package.js +7 -4
  1024. package/dist/package.js.map +1 -1
  1025. package/dist/routes/agent-settings.d.ts +106 -0
  1026. package/dist/routes/files-tab.cjs +1 -1
  1027. package/dist/routes/files-tab.js +23 -23
  1028. package/dist/routes/llm-settings.cjs +1 -1
  1029. package/dist/routes/llm-settings.cjs.map +1 -1
  1030. package/dist/routes/llm-settings.d.ts +6 -4
  1031. package/dist/routes/llm-settings.js +0 -1
  1032. package/dist/routes/llm-settings.js.map +1 -1
  1033. package/dist/routes/mcp.cjs.map +1 -1
  1034. package/dist/routes/mcp.js.map +1 -1
  1035. package/dist/services/settings.cjs +1 -1
  1036. package/dist/services/settings.cjs.map +1 -1
  1037. package/dist/services/settings.js +2 -6
  1038. package/dist/services/settings.js.map +1 -1
  1039. package/dist/stores/command-menu-store.cjs +2 -0
  1040. package/dist/stores/command-menu-store.cjs.map +1 -0
  1041. package/dist/stores/command-menu-store.d.ts +8 -0
  1042. package/dist/stores/command-menu-store.js +12 -0
  1043. package/dist/stores/command-menu-store.js.map +1 -0
  1044. package/dist/stores/conversation-panel-preferences-store.cjs +1 -1
  1045. package/dist/stores/conversation-panel-preferences-store.cjs.map +1 -1
  1046. package/dist/stores/conversation-panel-preferences-store.js +1 -1
  1047. package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
  1048. package/dist/stores/conversation-store.cjs +1 -1
  1049. package/dist/stores/conversation-store.cjs.map +1 -1
  1050. package/dist/stores/conversation-store.d.ts +1 -0
  1051. package/dist/stores/conversation-store.js +1 -0
  1052. package/dist/stores/conversation-store.js.map +1 -1
  1053. package/dist/stores/goal-store.cjs +2 -0
  1054. package/dist/stores/goal-store.cjs.map +1 -0
  1055. package/dist/stores/goal-store.d.ts +28 -0
  1056. package/dist/stores/goal-store.js +14 -0
  1057. package/dist/stores/goal-store.js.map +1 -0
  1058. package/dist/themes/color-themes.cjs +3 -3
  1059. package/dist/themes/color-themes.cjs.map +1 -1
  1060. package/dist/themes/color-themes.d.ts +13 -2
  1061. package/dist/themes/color-themes.js +2 -2
  1062. package/dist/themes/color-themes.js.map +1 -1
  1063. package/dist/types/agent-server/core/events/conversation-state-event.d.ts +39 -3
  1064. package/dist/types/agent-server/type-guards.cjs +1 -1
  1065. package/dist/types/agent-server/type-guards.cjs.map +1 -1
  1066. package/dist/types/agent-server/type-guards.d.ts +2 -1
  1067. package/dist/types/agent-server/type-guards.js +3 -3
  1068. package/dist/types/agent-server/type-guards.js.map +1 -1
  1069. package/dist/types/mcp-auth.cjs +2 -0
  1070. package/dist/types/mcp-auth.cjs.map +1 -0
  1071. package/dist/types/mcp-auth.d.ts +43 -0
  1072. package/dist/types/mcp-auth.js +13 -0
  1073. package/dist/types/mcp-auth.js.map +1 -0
  1074. package/dist/types/mcp-server.d.ts +22 -1
  1075. package/dist/types/settings.d.ts +6 -4
  1076. package/dist/ui/context-menu.d.ts +1 -1
  1077. package/dist/utils/acp-command.d.ts +64 -0
  1078. package/dist/utils/automation-debug-prompt.d.ts +18 -0
  1079. package/dist/utils/constants.cjs +1 -1
  1080. package/dist/utils/constants.cjs.map +1 -1
  1081. package/dist/utils/constants.d.ts +2 -0
  1082. package/dist/utils/constants.js +12 -3
  1083. package/dist/utils/constants.js.map +1 -1
  1084. package/dist/utils/dropdown-classes.cjs +1 -1
  1085. package/dist/utils/dropdown-classes.cjs.map +1 -1
  1086. package/dist/utils/dropdown-classes.js +4 -2
  1087. package/dist/utils/dropdown-classes.js.map +1 -1
  1088. package/dist/utils/form-control-classes.cjs +1 -1
  1089. package/dist/utils/form-control-classes.js +1 -1
  1090. package/dist/utils/handle-event-for-ui.cjs +1 -1
  1091. package/dist/utils/handle-event-for-ui.cjs.map +1 -1
  1092. package/dist/utils/handle-event-for-ui.js +72 -37
  1093. package/dist/utils/handle-event-for-ui.js.map +1 -1
  1094. package/dist/utils/mcp-config.cjs +1 -1
  1095. package/dist/utils/mcp-config.cjs.map +1 -1
  1096. package/dist/utils/mcp-config.d.ts +15 -9
  1097. package/dist/utils/mcp-config.js +124 -53
  1098. package/dist/utils/mcp-config.js.map +1 -1
  1099. package/dist/utils/mcp-installed-server-display.cjs +2 -0
  1100. package/dist/utils/mcp-installed-server-display.cjs.map +1 -0
  1101. package/dist/utils/mcp-installed-server-display.d.ts +8 -0
  1102. package/dist/utils/mcp-installed-server-display.js +12 -0
  1103. package/dist/utils/mcp-installed-server-display.js.map +1 -0
  1104. package/dist/utils/mcp-installed-servers.cjs +1 -1
  1105. package/dist/utils/mcp-installed-servers.cjs.map +1 -1
  1106. package/dist/utils/mcp-installed-servers.js +4 -4
  1107. package/dist/utils/mcp-installed-servers.js.map +1 -1
  1108. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  1109. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  1110. package/dist/utils/mcp-marketplace-utils.d.ts +2 -0
  1111. package/dist/utils/mcp-marketplace-utils.js +31 -16
  1112. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  1113. package/dist/utils/mcp-server-name.cjs +2 -0
  1114. package/dist/utils/mcp-server-name.cjs.map +1 -0
  1115. package/dist/utils/mcp-server-name.d.ts +3 -0
  1116. package/dist/utils/mcp-server-name.js +12 -0
  1117. package/dist/utils/mcp-server-name.js.map +1 -0
  1118. package/dist/utils/plugin-display.cjs +2 -0
  1119. package/dist/utils/plugin-display.cjs.map +1 -0
  1120. package/dist/utils/plugin-display.d.ts +20 -0
  1121. package/dist/utils/plugin-display.js +29 -0
  1122. package/dist/utils/plugin-display.js.map +1 -0
  1123. package/dist/utils/settings-utils.cjs.map +1 -1
  1124. package/dist/utils/settings-utils.js.map +1 -1
  1125. package/dist/utils/workspaces-compatibility.cjs +1 -1
  1126. package/dist/utils/workspaces-compatibility.cjs.map +1 -1
  1127. package/dist/utils/workspaces-compatibility.js +1 -0
  1128. package/dist/utils/workspaces-compatibility.js.map +1 -1
  1129. package/package.json +7 -4
  1130. package/scripts/check-sdk-version-sync.mjs +6 -6
  1131. package/scripts/check-translation-completeness.cjs +6 -0
  1132. package/scripts/dev-safe.mjs +14 -3
  1133. package/scripts/dev-with-automation.mjs +4 -0
  1134. package/scripts/gen-acp-docker-env.mjs +107 -0
  1135. package/scripts/ingress.mjs +66 -226
  1136. package/scripts/proxy-utils.mjs +171 -0
  1137. package/scripts/static-server.mjs +127 -283
  1138. package/build/assets/Trans-CiZR6eVI.js +0 -1
  1139. package/build/assets/active-backend-context-CEuva6ZJ.js +0 -1
  1140. package/build/assets/add-backend-modal-b_eiVk3A.js +0 -1
  1141. package/build/assets/agent-server-conversation-service.api-D_uJ7BKc.js +0 -5
  1142. package/build/assets/agent-settings-DyfziYyM.js +0 -2
  1143. package/build/assets/alert-banner-BFayS5vM.js +0 -1
  1144. package/build/assets/analytics-consent-form-modal-CQ22qlFF.js +0 -1
  1145. package/build/assets/api-key-entry-screen-KnIwP0vN.js +0 -1
  1146. package/build/assets/app-settings-CBaHJ5vJ.js +0 -1
  1147. package/build/assets/automation-detail-DgQswnXg.js +0 -1
  1148. package/build/assets/automations-list-D99p6CoQ.js +0 -1
  1149. package/build/assets/back-nav-button-Cp9z-wsG.js +0 -1
  1150. package/build/assets/backend-form-modal-BABAz-zH.js +0 -1
  1151. package/build/assets/backend-synced-settings-badge-DzwWQC4T.js +0 -1
  1152. package/build/assets/base-modal-1bHiB5Wf.js +0 -1
  1153. package/build/assets/brand-button-FHWgEb4Q.js +0 -1
  1154. package/build/assets/browser-store-B9h0eW79.js +0 -1
  1155. package/build/assets/browser-tab-JiCXo0Nc.js +0 -1
  1156. package/build/assets/chat-send-button-QtyofqFt.js +0 -1
  1157. package/build/assets/check-6ieIiPhW.js +0 -1
  1158. package/build/assets/checkmark-BfgRVMHK.js +0 -1
  1159. package/build/assets/circle-plus-check-toggle-CmINKfZj.js +0 -1
  1160. package/build/assets/close-DhH0uMa7.js +0 -1
  1161. package/build/assets/code-tag-CnORXDJj.js +0 -1
  1162. package/build/assets/combobox-caret-BB15S7zY.js +0 -1
  1163. package/build/assets/condenser-settings-BOKNShD9.js +0 -1
  1164. package/build/assets/confirmation-modal-CofmThy4.js +0 -1
  1165. package/build/assets/context-menu-list-item-DO12IEaK.js +0 -1
  1166. package/build/assets/conversation-DIzv-jq8.js +0 -1
  1167. package/build/assets/conversation-DV3odvMe.js +0 -19
  1168. package/build/assets/conversation-local-storage-DK7yJr5N.js +0 -1
  1169. package/build/assets/conversation-panel-CgCarTAn.js +0 -1
  1170. package/build/assets/conversation-service.api-RV_bOKNz.js +0 -1
  1171. package/build/assets/conversation-state-store-4obo4ZMf.js +0 -1
  1172. package/build/assets/conversation-store-CXrL0v-X.js +0 -6
  1173. package/build/assets/conversation-tab-empty-state-CqT5ur_H.js +0 -1
  1174. package/build/assets/copy-C5tBqfWu.js +0 -1
  1175. package/build/assets/copy-to-clipboard-button-BVFYcsg_.js +0 -1
  1176. package/build/assets/createLucideIcon-D3nkdIAN.js +0 -1
  1177. package/build/assets/declaration-B0yY_dkQ.js +0 -1
  1178. package/build/assets/device-verify-DRupI_hz.js +0 -1
  1179. package/build/assets/dist-D5d5zm8o.js +0 -1
  1180. package/build/assets/dist-fV7trlfb.js +0 -1
  1181. package/build/assets/dropdown-classes-5IsMjYYw.js +0 -1
  1182. package/build/assets/edit-automation-modal-BG-gd82b.js +0 -1
  1183. package/build/assets/ellipsis-button-DWvVZO_r.js +0 -1
  1184. package/build/assets/entry.client-uhbVfCtd.js +0 -2
  1185. package/build/assets/enum-filter-dropdown-CB2fqz_e.js +0 -1
  1186. package/build/assets/environment-switch-overlay-Oeal5TVq.js +0 -1
  1187. package/build/assets/extensions-hub-DxiE0AZR.js +0 -1
  1188. package/build/assets/files-tab-1F2OlNeH.js +0 -1
  1189. package/build/assets/files-tab-store-C1q5Rbx3.js +0 -1
  1190. package/build/assets/folder-C5tr7xyN.js +0 -1
  1191. package/build/assets/get-language-from-path-E1JKsbeE.js +0 -1
  1192. package/build/assets/git-provider-icon-CKs-22Ts.js +0 -1
  1193. package/build/assets/home-B3E0le0g.js +0 -1
  1194. package/build/assets/iconBase-DMoh3FEg.js +0 -1
  1195. package/build/assets/index-redirect-DhuK5mhS.js +0 -1
  1196. package/build/assets/install-server-modal-DjintV14.js +0 -1
  1197. package/build/assets/is-backend-llm-ready-Bj44pekN.js +0 -1
  1198. package/build/assets/launch-DCU3S84p.js +0 -1
  1199. package/build/assets/lesson-plan-BUUPKVsa.js +0 -3
  1200. package/build/assets/link-external-CF4KHxx-.js +0 -1
  1201. package/build/assets/llm-client-BakM_czF.js +0 -1
  1202. package/build/assets/llm-not-configured-banner-BV-NIjfR.js +0 -27
  1203. package/build/assets/llm-settings-B5d7PHzz.js +0 -1
  1204. package/build/assets/llm-settings-C5whb-0p.js +0 -1
  1205. package/build/assets/loader-circle-DyX8DmLg.js +0 -1
  1206. package/build/assets/loading-spinner-BvOAco8a.js +0 -1
  1207. package/build/assets/manage-backends-modal-D9ClxVpM.js +0 -1
  1208. package/build/assets/manifest-38a873aa.js +0 -1
  1209. package/build/assets/mcp-7rk44GRS.js +0 -9
  1210. package/build/assets/mcp-client-DxHXYNOw.js +0 -1
  1211. package/build/assets/messages-DgBEaXil.js +0 -43
  1212. package/build/assets/modal-backdrop-DjAC2zOZ.js +0 -1
  1213. package/build/assets/modal-body-OJdIUJ68.js +0 -1
  1214. package/build/assets/modal-close-button-BNjGesHc.js +0 -1
  1215. package/build/assets/model-selector-w2uGPM5y.js +0 -1
  1216. package/build/assets/navigation-context-CUJ60pLI.js +0 -1
  1217. package/build/assets/navigation-link-BiPKTOHF.js +0 -1
  1218. package/build/assets/onboarding-Cit87z8g.js +0 -1
  1219. package/build/assets/onboarding-modal-JPrzvr8W.js +0 -1
  1220. package/build/assets/openhands-logo-uNs9g6LY.js +0 -1
  1221. package/build/assets/option-service.api-BLYUhnCF.js +0 -1
  1222. package/build/assets/organization-service.api-DpSSwlZu.js +0 -1
  1223. package/build/assets/path-utils-B4WAVqvK.js +0 -1
  1224. package/build/assets/plan-components-DSOTFW2D.js +0 -1
  1225. package/build/assets/planner-tab-LmoxgKKe.js +0 -1
  1226. package/build/assets/preload-helper-D_sPnjeL.js +0 -1
  1227. package/build/assets/profiles-client-B4SJ4ZAf.js +0 -1
  1228. package/build/assets/providers-BGUAB8kf.js +0 -1
  1229. package/build/assets/react-Dn-iWFF5.js +0 -1
  1230. package/build/assets/react-dom-BBXlXOZX.js +0 -1
  1231. package/build/assets/react-uQK8du1l.js +0 -1
  1232. package/build/assets/recommended-automations-launcher-Df9MXUpX.js +0 -50
  1233. package/build/assets/root-BShAdYGY.css +0 -1
  1234. package/build/assets/root-C99reK-P.js +0 -2
  1235. package/build/assets/root-layout-BtH64XeC.js +0 -2
  1236. package/build/assets/runtime-waiting-state-C7MjXDeW.js +0 -1
  1237. package/build/assets/schema-field-BCDuEMrl.js +0 -1
  1238. package/build/assets/sdk-section-page-XJN9mGju.js +0 -1
  1239. package/build/assets/sdk-settings-schema-B15AE1GH.js +0 -1
  1240. package/build/assets/search-rob4u9f8.js +0 -1
  1241. package/build/assets/secrets-service-CrPyCR8u.js +0 -1
  1242. package/build/assets/secrets-settings-UJn15N7E.js +0 -1
  1243. package/build/assets/settings-C5aUD_sQ.js +0 -1
  1244. package/build/assets/settings-dropdown-input-DQRt2_RA.js +0 -1
  1245. package/build/assets/settings-gear-B7bZDo_8.js +0 -1
  1246. package/build/assets/settings-index-zP_rYIW1.js +0 -1
  1247. package/build/assets/settings-input-n8FzVso3.js +0 -1
  1248. package/build/assets/settings-list-classes-DquY3fwm.js +0 -1
  1249. package/build/assets/settings-modal-szlQ6LpE.js +0 -1
  1250. package/build/assets/settings-section-header-context-DrXgyNC-.js +0 -1
  1251. package/build/assets/settings-service.api-B4G8NzCM.js +0 -1
  1252. package/build/assets/settings-switch-DsbEm3ie.js +0 -1
  1253. package/build/assets/shared-conversation-BrAvqeaI.js +0 -1
  1254. package/build/assets/sidebar-mobile-menu-toggle-BRZGCe-l.js +0 -1
  1255. package/build/assets/sidebar-nav-link-B_EygIce.js +0 -1
  1256. package/build/assets/skill-card-pill-row-Bq9Imkdh.js +0 -1
  1257. package/build/assets/skills-Wg6i0kbu.js +0 -1
  1258. package/build/assets/skills-client-DNd444Bm.js +0 -1
  1259. package/build/assets/skills-plugins-DaGkVI7-.js +0 -1
  1260. package/build/assets/skills-settings-Dlp0WFaT.js +0 -2
  1261. package/build/assets/styled-tooltip-ulgpZDga.js +0 -1
  1262. package/build/assets/suspense-BqBQEuKs.js +0 -1
  1263. package/build/assets/switch-skeleton-C49gVWOQ.js +0 -1
  1264. package/build/assets/task-list-tab-Bz-UlCm2.js +0 -1
  1265. package/build/assets/telemetry-DD3HKMgf.js +0 -2
  1266. package/build/assets/terminal-BwLvVzyJ.js +0 -1
  1267. package/build/assets/toggle-switch-CxW8-lBI.js +0 -1
  1268. package/build/assets/typography-BLf_mRKH.js +0 -1
  1269. package/build/assets/u-check-circle-CxTAJuY9.js +0 -1
  1270. package/build/assets/u-check-circle-half-Bj73jfUG.js +0 -1
  1271. package/build/assets/u-circuit-C-6V9H9C.js +0 -1
  1272. package/build/assets/u-edit-C7OnK2sa.js +0 -1
  1273. package/build/assets/use-acp-credential-form-oehc057O.js +0 -1
  1274. package/build/assets/use-active-conversation-CFXVX2on.js +0 -1
  1275. package/build/assets/use-agent-state-D6xfZA4-.js +0 -1
  1276. package/build/assets/use-backends-health-93yRIOWs.js +0 -1
  1277. package/build/assets/use-breakpoint-Xdy_aZHE.js +0 -1
  1278. package/build/assets/use-click-outside-element-CADb_gCP.js +0 -1
  1279. package/build/assets/use-cloud-current-user-id-CzOXsy04.js +0 -1
  1280. package/build/assets/use-config-oXjEWyb6.js +0 -1
  1281. package/build/assets/use-create-conversation-D-YkgrxS.js +0 -1
  1282. package/build/assets/use-create-secret-CX7Ij7W4.js +0 -1
  1283. package/build/assets/use-event-store-DMRAQQi8.js +0 -1
  1284. package/build/assets/use-handle-plan-click-CwW2Ijc2.js +0 -1
  1285. package/build/assets/use-is-authed-CNbX1KMm.js +0 -1
  1286. package/build/assets/use-launch-skill-in-chat-xI9byRUw.js +0 -1
  1287. package/build/assets/use-llm-profiles-BXRZ2rBh.js +0 -1
  1288. package/build/assets/use-runtime-is-ready-Dwzs9_vp.js +0 -1
  1289. package/build/assets/use-settings-_usWr_qn.js +0 -1
  1290. package/build/assets/use-settings-nav-items-DoB5iH-7.js +0 -16
  1291. package/build/assets/use-skills-BtorhoCN.js +0 -1
  1292. package/build/assets/use-task-list-u46BhYBC.js +0 -1
  1293. package/build/assets/use-tracking-Ca7p71hH.js +0 -1
  1294. package/build/assets/use-user-conversation-U-16WF6G.js +0 -1
  1295. package/build/assets/useMutation-CseCrRRO.js +0 -1
  1296. package/build/assets/useQuery-bowvACed.js +0 -1
  1297. package/build/assets/useTranslation-KhTtKmnv.js +0 -1
  1298. package/build/assets/utils-cRyMoFbz.js +0 -1
  1299. package/build/assets/vendor~conversation-panel~conversation~alert-banner-CjfR7T3x.js +0 -1
  1300. package/build/assets/vendor~entry.client-_zl82x5T.js +0 -1
  1301. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~dj9x5fm9-CgCGB-3J.js +0 -177
  1302. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~jfvr34cq-BJdsUTJG.js +0 -1
  1303. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~m3df9r20-BynFAJ_S.js +0 -1
  1304. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~nk00xiud-MfCRtPrK.js +0 -9
  1305. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~ghtfhmuy-BHDILMe2.js +0 -1
  1306. package/build/assets/vendor~root-layout~conversation-panel~conversation-BFZmbXpq.js +0 -1
  1307. package/build/assets/vendor~root-layout~conversation-panel~conversation~index-BPY-kNjK.js +0 -1
  1308. package/build/assets/vendor~root-layout~home~conversation-panel~conversation-BhWqQNmF.js +0 -1
  1309. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~cfyi58ut-CnnEa0dP.js +0 -1
  1310. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~clac83qc-DMX6XUwI.js +0 -2
  1311. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~ldu51w4e-Cqp6k3RG.js +0 -1
  1312. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~ldu51w4e-DS4GWhCz.js +0 -9
  1313. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~ji28rqgb-DVffa9Ks.js +0 -48
  1314. package/build/assets/vendor~root-layout~home~mcp~automations-list~onboarding-modal-BzR6ypP3.js +0 -1
  1315. package/build/assets/vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~hzfcl1q6-BcvHZmEZ.js +0 -2
  1316. package/build/assets/vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~hzfcl1q6-Cuvp6wqR.js +0 -14
  1317. package/build/assets/verification-settings-DKZnUHD6.js +0 -1
  1318. package/build/assets/x-DpnGZyVW.js +0 -1
  1319. package/build/assets/x-mark-x3tvCZzc.js +0 -1
  1320. package/dist/components/features/analytics/analytics-consent-form-modal.d.ts +0 -5
  1321. package/dist/components/features/chat/switch-profile-button.cjs +0 -2
  1322. package/dist/components/features/chat/switch-profile-button.cjs.map +0 -1
  1323. package/dist/components/features/chat/switch-profile-button.d.ts +0 -1
  1324. package/dist/components/features/chat/switch-profile-button.js +0 -48
  1325. package/dist/components/features/chat/switch-profile-button.js.map +0 -1
  1326. package/dist/components/features/chat/switch-profile-context-menu.cjs +0 -2
  1327. package/dist/components/features/chat/switch-profile-context-menu.cjs.map +0 -1
  1328. package/dist/components/features/chat/switch-profile-context-menu.d.ts +0 -9
  1329. package/dist/components/features/chat/switch-profile-context-menu.js +0 -106
  1330. package/dist/components/features/chat/switch-profile-context-menu.js.map +0 -1
  1331. package/dist/components/features/onboarding/is-backend-llm-ready.d.ts +0 -30
  1332. package/dist/icons/u-circuit.cjs +0 -2
  1333. package/dist/icons/u-circuit.cjs.map +0 -1
  1334. package/dist/icons/u-circuit.js +0 -19
  1335. package/dist/icons/u-circuit.js.map +0 -1
  1336. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickup.cjs +0 -2
  1337. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickup.cjs.map +0 -1
  1338. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickup.js +0 -35
  1339. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickup.js.map +0 -1
  1340. package/dist/node_modules/@openhands/extensions/integrations/catalog/dropbox.cjs +0 -2
  1341. package/dist/node_modules/@openhands/extensions/integrations/catalog/dropbox.cjs.map +0 -1
  1342. package/dist/node_modules/@openhands/extensions/integrations/catalog/dropbox.js +0 -35
  1343. package/dist/node_modules/@openhands/extensions/integrations/catalog/dropbox.js.map +0 -1
  1344. package/dist/node_modules/@openhands/extensions/integrations/catalog/freshdesk.cjs +0 -2
  1345. package/dist/node_modules/@openhands/extensions/integrations/catalog/freshdesk.cjs.map +0 -1
  1346. package/dist/node_modules/@openhands/extensions/integrations/catalog/freshdesk.js +0 -35
  1347. package/dist/node_modules/@openhands/extensions/integrations/catalog/freshdesk.js.map +0 -1
  1348. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs +0 -2
  1349. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs.map +0 -1
  1350. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js +0 -35
  1351. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js.map +0 -1
  1352. package/dist/node_modules/@openhands/extensions/integrations/catalog/mailchimp.cjs +0 -2
  1353. package/dist/node_modules/@openhands/extensions/integrations/catalog/mailchimp.cjs.map +0 -1
  1354. package/dist/node_modules/@openhands/extensions/integrations/catalog/mailchimp.js +0 -35
  1355. package/dist/node_modules/@openhands/extensions/integrations/catalog/mailchimp.js.map +0 -1
  1356. package/dist/node_modules/@openhands/extensions/integrations/catalog/pipedrive.cjs +0 -2
  1357. package/dist/node_modules/@openhands/extensions/integrations/catalog/pipedrive.cjs.map +0 -1
  1358. package/dist/node_modules/@openhands/extensions/integrations/catalog/pipedrive.js +0 -35
  1359. package/dist/node_modules/@openhands/extensions/integrations/catalog/pipedrive.js.map +0 -1
  1360. package/dist/node_modules/@openhands/extensions/integrations/catalog/plaid.cjs +0 -2
  1361. package/dist/node_modules/@openhands/extensions/integrations/catalog/plaid.cjs.map +0 -1
  1362. package/dist/node_modules/@openhands/extensions/integrations/catalog/plaid.js +0 -28
  1363. package/dist/node_modules/@openhands/extensions/integrations/catalog/plaid.js.map +0 -1
  1364. package/dist/node_modules/@openhands/extensions/integrations/catalog/servicenow.cjs +0 -2
  1365. package/dist/node_modules/@openhands/extensions/integrations/catalog/servicenow.cjs.map +0 -1
  1366. package/dist/node_modules/@openhands/extensions/integrations/catalog/servicenow.js +0 -35
  1367. package/dist/node_modules/@openhands/extensions/integrations/catalog/servicenow.js.map +0 -1
  1368. package/dist/node_modules/@openhands/extensions/integrations/catalog/shopify.cjs +0 -2
  1369. package/dist/node_modules/@openhands/extensions/integrations/catalog/shopify.cjs.map +0 -1
  1370. package/dist/node_modules/@openhands/extensions/integrations/catalog/shopify.js +0 -35
  1371. package/dist/node_modules/@openhands/extensions/integrations/catalog/shopify.js.map +0 -1
  1372. package/dist/node_modules/@openhands/extensions/integrations/catalog/zendesk.cjs +0 -2
  1373. package/dist/node_modules/@openhands/extensions/integrations/catalog/zendesk.cjs.map +0 -1
  1374. package/dist/node_modules/@openhands/extensions/integrations/catalog/zendesk.js +0 -35
  1375. package/dist/node_modules/@openhands/extensions/integrations/catalog/zendesk.js.map +0 -1
  1376. /package/build/assets/{agent-server-ui-style-scope-CIDFDeQb.js → agent-server-ui-style-scope-COnDHTm5.js} +0 -0
  1377. /package/build/assets/{automation-DNgDxqtq.js → automation-BU8zu-FP.js} +0 -0
  1378. /package/build/assets/{common-KeiA2Rod.js → common-Dh7OqABE.js} +0 -0
  1379. /package/build/assets/{environment-switch-store-BpKxp6Xq.js → environment-switch-store-DkjlKWzN.js} +0 -0
  1380. /package/build/assets/{extension-module-card-classes-DvvyImGv.js → extension-module-card-classes-9V3J9J_b.js} +0 -0
  1381. /package/build/assets/{git-status-mapper-B3_HbzUT.js → git-status-mapper-BI8FyUVp.js} +0 -0
  1382. /package/build/assets/{handle-capture-consent-BChvj6mt.js → handle-capture-consent-CPMXU29K.js} +0 -0
  1383. /package/build/assets/{llm-subscription-C1xDoa3K.js → llm-subscription-DtsX5Lhg.js} +0 -0
  1384. /package/build/assets/{map-provider-MonJL5SS.js → map-provider-BM2SJarp.js} +0 -0
  1385. /package/build/assets/{objectWithoutPropertiesLoose-BRYudkUn.js → objectWithoutPropertiesLoose-BgYIAs2y.js} +0 -0
  1386. /package/build/assets/{rolldown-runtime-wFmyQBCi.js → rolldown-runtime-BFRubm34.js} +0 -0
  1387. /package/build/assets/{settings-like-page-layout-classes-DNg2vKSM.js → settings-like-page-layout-classes-DENKlZpD.js} +0 -0
  1388. /package/build/assets/{v4-BMWDcIWQ.js → v4-DbCkTSoU.js} +0 -0
  1389. /package/build/assets/{vendor~browser-yZEspfT9.js → vendor~browser-Dqd33JyP.js} +0 -0
  1390. /package/build/assets/{vendor~terminal-CcUoOdAH.js → vendor~terminal-aeP3PnKf.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-card-footer.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-footer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { formatTimeDelta } from \"#/utils/format-time-delta\";\nimport { cn } from \"#/utils/utils\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { RepositorySelection } from \"#/api/open-hands.types\";\nimport { ExecutionStatus } from \"#/types/agent-server/core/base/common\";\nimport { isExecutionPaused } from \"#/utils/status\";\nimport {\n getAcpProviderDisplayName,\n labelForAcpModel,\n resolveAcpProviderIcon,\n} from \"#/constants/acp-providers\";\nimport { formatNativeModelName } from \"#/utils/format-model-name\";\nimport {\n AgentBrandIcon,\n type AgentBrandIconKind,\n} from \"#/components/shared/agent-brand-icon\";\nimport { ConversationRepoLink } from \"./conversation-repo-link\";\nimport { NoRepository } from \"./no-repository\";\n\ninterface ConversationCardFooterProps {\n selectedRepository: RepositorySelection | null;\n lastUpdatedAt: string;\n createdAt?: string;\n executionStatus?: ExecutionStatus | null;\n workspaceWorkingDir?: string | null;\n showRepositoryMetadata?: boolean;\n showTimestamp?: boolean;\n llmModel?: string | null;\n /**\n * Whether to render the agent/model chip. Wired to the conversation\n * panel's \"LLM model\" toggle (off by default); gates the chip uniformly\n * for both ACP and OpenHands cards.\n */\n showAgentChip?: boolean;\n /**\n * High-level kind of the conversation's agent. Drives the chip's icon:\n * the OpenHands logo for native conversations and the resolved ACP brand\n * mark for ACP conversations. Defensive against stray ``acpServer``\n * values reaching an OpenHands card.\n */\n agentKind?: \"openhands\" | \"acp\" | null;\n /**\n * Registry key of the ACP CLI server (``\"claude-code\"`` / ``\"codex\"`` /\n * ``\"gemini-cli\"`` / unknown / null). Resolved to a human display name\n * via {@link getAcpProviderDisplayName}; unknown / null falls back to\n * a generic \"ACP\" label so a Custom-command preset still produces a\n * useful chip.\n */\n acpServer?: string | null;\n}\n\nexport function ConversationCardFooter({\n selectedRepository,\n lastUpdatedAt,\n createdAt,\n executionStatus,\n workspaceWorkingDir,\n showRepositoryMetadata = true,\n showTimestamp = true,\n llmModel,\n showAgentChip = false,\n agentKind = null,\n acpServer = null,\n}: ConversationCardFooterProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isPaused = isExecutionPaused(executionStatus);\n\n // Single inline chip per conversation: [brand mark] {model text}. Gated by\n // the conversation panel's \"LLM model\" toggle (off by default) and applied\n // uniformly to both kinds — OpenHands shows the logo + ``agent.llm.model``;\n // ACP shows the provider brand mark + model resolved through PR 730's\n // adapter chain, falling back to the provider display name when no model is\n // available so the chip never collapses to icon-only.\n let chip: {\n kind: AgentBrandIconKind;\n text: string;\n tooltip: string;\n } | null = null;\n if (showAgentChip) {\n if (agentKind === \"acp\") {\n const providerName =\n getAcpProviderDisplayName(acpServer) ??\n t(I18nKey.CONVERSATION$ACP_AGENT_GENERIC);\n // Prefer the provider's picker label (e.g. \"Claude Opus 4.7\") over the\n // raw ``acp_model`` ID; falls back to the raw ID for custom overrides\n // and to the provider name when there's no model at all.\n const modelLabel = labelForAcpModel(acpServer, llmModel);\n const text = modelLabel ?? providerName;\n chip = {\n kind: resolveAcpProviderIcon(acpServer),\n text,\n tooltip: modelLabel ? `${providerName} · ${modelLabel}` : providerName,\n };\n } else if (llmModel) {\n // Strip the routing prefix (e.g. \"anthropic/claude-…\" → \"claude-…\") for\n // the chip text; keep the full routing string in the tooltip.\n chip = {\n kind: \"openhands\",\n text: formatNativeModelName(llmModel) ?? llmModel,\n tooltip: llmModel,\n };\n }\n }\n\n // Match title text start: 18px status column + gap-2 (8px).\n const metadataIndentClass =\n executionStatus !== undefined ? \"pl-[26px]\" : undefined;\n\n return (\n <div\n className={cn(\n \"flex flex-col gap-0.5 mt-0.5 w-full min-w-0\",\n isPaused && \"opacity-60\",\n )}\n >\n {chip ? (\n <div className={metadataIndentClass}>\n <span\n data-testid=\"conversation-card-agent-chip\"\n className=\"inline-flex items-center gap-1 text-xs text-[var(--oh-muted)] max-w-full min-w-0\"\n title={chip.tooltip}\n >\n <AgentBrandIcon kind={chip.kind} />\n <span className=\"truncate\">{chip.text}</span>\n </span>\n </div>\n ) : null}\n <div\n className={cn(\n \"flex flex-row items-center gap-2 w-full min-w-0\",\n showRepositoryMetadata && metadataIndentClass,\n )}\n >\n {showRepositoryMetadata &&\n (selectedRepository?.selected_repository ? (\n <ConversationRepoLink selectedRepository={selectedRepository} />\n ) : (\n <NoRepository workspaceWorkingDir={workspaceWorkingDir} />\n ))}\n <div className=\"flex items-center gap-2 shrink-0 ml-auto\">\n {showTimestamp && (createdAt ?? lastUpdatedAt) && (\n <p className=\"text-xs text-[var(--oh-muted)] text-right\">\n <time>\n {`${formatTimeDelta(lastUpdatedAt ?? createdAt)} ${t(I18nKey.CONVERSATION$AGO)}`}\n </time>\n </p>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAoDA,SAAgB,EAAuB,EACrC,uBACA,kBACA,cACA,oBACA,wBACA,4BAAyB,IACzB,mBAAgB,IAChB,aACA,mBAAgB,IAChB,eAAY,MACZ,eAAY,QACkB;CAC9B,IAAM,EAAE,SAAM,EAAe,YAAY,EAEnC,IAAW,EAAkB,EAAgB,EAQ/C,IAIO;AACX,KAAI,OACE,MAAc,OAAO;EACvB,IAAM,IACJ,EAA0B,EAAU,IACpC,EAAE,EAAQ,+BAA+B,EAIrC,IAAa,EAAiB,GAAW,EAAS,EAClD,IAAO,KAAc;AAC3B,MAAO;GACL,MAAM,EAAuB,EAAU;GACvC;GACA,SAAS,IAAa,GAAG,EAAa,KAAK,MAAe;GAC3D;QACQ,MAGT,IAAO;EACL,MAAM;EACN,MAAM,EAAsB,EAAS,IAAI;EACzC,SAAS;EACV;CAKL,IAAM,IACJ,MAAoB,KAAA,IAA0B,KAAA,IAAd;AAElC,QACE,kBAAC,OAAD;EACE,WAAW,EACT,+CACA,KAAY,aACb;YAJH,CAMG,IACC,kBAAC,OAAD;GAAK,WAAW;aACd,kBAAC,QAAD;IACE,eAAY;IACZ,WAAU;IACV,OAAO,EAAK;cAHd,CAKE,kBAAC,GAAD,EAAgB,MAAM,EAAK,MAAQ,CAAA,EACnC,kBAAC,QAAD;KAAM,WAAU;eAAY,EAAK;KAAY,CAAA,CACxC;;GACH,CAAA,GACJ,MACJ,kBAAC,OAAD;GACE,WAAW,EACT,mDACA,KAA0B,EAC3B;aAJH,CAMG,MACE,GAAoB,sBACnB,kBAAC,GAAD,EAA0C,uBAAsB,CAAA,GAEhE,kBAAC,GAAD,EAAmC,wBAAuB,CAAA,GAE9D,kBAAC,OAAD;IAAK,WAAU;cACZ,MAAkB,KAAa,MAC9B,kBAAC,KAAD;KAAG,WAAU;eACX,kBAAC,QAAD,EAAA,UACG,GAAG,EAAgB,KAAiB,EAAU,CAAC,GAAG,EAAE,EAAQ,iBAAiB,IACzE,CAAA;KACL,CAAA;IAEF,CAAA,CACF;KACF"}
1
+ {"version":3,"file":"conversation-card-footer.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-footer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { formatTimeDelta } from \"#/utils/format-time-delta\";\nimport { cn } from \"#/utils/utils\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { RepositorySelection } from \"#/api/open-hands.types\";\nimport { ExecutionStatus } from \"#/types/agent-server/core/base/common\";\nimport { isExecutionPaused } from \"#/utils/status\";\nimport {\n getAcpProviderDisplayName,\n labelForAcpModel,\n resolveAcpProviderIcon,\n} from \"#/constants/acp-providers\";\nimport { formatNativeModelName } from \"#/utils/format-model-name\";\nimport {\n AgentBrandIcon,\n type AgentBrandIconKind,\n} from \"#/components/shared/agent-brand-icon\";\nimport { ConversationRepoLink } from \"./conversation-repo-link\";\nimport { NoRepository } from \"./no-repository\";\n\ninterface ConversationCardFooterProps {\n selectedRepository: RepositorySelection | null;\n lastUpdatedAt: string;\n createdAt?: string;\n executionStatus?: ExecutionStatus | null;\n workspaceWorkingDir?: string | null;\n showRepositoryMetadata?: boolean;\n showTimestamp?: boolean;\n llmModel?: string | null;\n /**\n * Whether to render the agent/model chip. Wired to the conversation\n * panel's \"LLM model\" toggle; gates the chip uniformly\n * for both ACP and OpenHands cards.\n */\n showAgentChip?: boolean;\n /**\n * High-level kind of the conversation's agent. Drives the chip's icon:\n * the OpenHands logo for native conversations and the resolved ACP brand\n * mark for ACP conversations. Defensive against stray ``acpServer``\n * values reaching an OpenHands card.\n */\n agentKind?: \"openhands\" | \"acp\" | null;\n /**\n * Registry key of the ACP CLI server (``\"claude-code\"`` / ``\"codex\"`` /\n * ``\"gemini-cli\"`` / unknown / null). Resolved to a human display name\n * via {@link getAcpProviderDisplayName}; unknown / null falls back to\n * a generic \"ACP\" label so a Custom-command preset still produces a\n * useful chip.\n */\n acpServer?: string | null;\n}\n\nexport function ConversationCardFooter({\n selectedRepository,\n lastUpdatedAt,\n createdAt,\n executionStatus,\n workspaceWorkingDir,\n showRepositoryMetadata = true,\n showTimestamp = true,\n llmModel,\n showAgentChip = false,\n agentKind = null,\n acpServer = null,\n}: ConversationCardFooterProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isPaused = isExecutionPaused(executionStatus);\n\n // Single inline chip per conversation: [brand mark] {model text}. Gated by\n // the conversation panel's \"LLM model\" toggle and applied\n // uniformly to both kinds — OpenHands shows the logo + ``agent.llm.model``;\n // ACP shows the provider brand mark + model resolved through PR 730's\n // adapter chain, falling back to the provider display name when no model is\n // available so the chip never collapses to icon-only.\n let chip: {\n kind: AgentBrandIconKind;\n text: string;\n tooltip: string;\n } | null = null;\n if (showAgentChip) {\n if (agentKind === \"acp\") {\n const providerName =\n getAcpProviderDisplayName(acpServer) ??\n t(I18nKey.CONVERSATION$ACP_AGENT_GENERIC);\n // Prefer the provider's picker label (e.g. \"Claude Opus 4.7\") over the\n // raw ``acp_model`` ID; falls back to the raw ID for custom overrides\n // and to the provider name when there's no model at all.\n const modelLabel = labelForAcpModel(acpServer, llmModel);\n const text = modelLabel ?? providerName;\n chip = {\n kind: resolveAcpProviderIcon(acpServer),\n text,\n tooltip: modelLabel ? `${providerName} · ${modelLabel}` : providerName,\n };\n } else if (llmModel) {\n // Strip the routing prefix (e.g. \"anthropic/claude-…\" → \"claude-…\") for\n // the chip text; keep the full routing string in the tooltip.\n chip = {\n kind: \"openhands\",\n text: formatNativeModelName(llmModel) ?? llmModel,\n tooltip: llmModel,\n };\n }\n }\n\n // Match title text start: 18px status column + gap-2 (8px).\n const metadataIndentClass =\n executionStatus !== undefined ? \"pl-[26px]\" : undefined;\n\n return (\n <div\n className={cn(\n \"flex flex-col gap-0.5 mt-0.5 w-full min-w-0\",\n isPaused && \"opacity-60\",\n )}\n >\n {chip ? (\n <div className={metadataIndentClass}>\n <span\n data-testid=\"conversation-card-agent-chip\"\n className=\"inline-flex items-center gap-1 text-xs text-[var(--oh-muted)] max-w-full min-w-0\"\n title={chip.tooltip}\n >\n <AgentBrandIcon kind={chip.kind} />\n <span className=\"truncate\">{chip.text}</span>\n </span>\n </div>\n ) : null}\n <div\n className={cn(\n \"flex flex-row items-center gap-2 w-full min-w-0\",\n showRepositoryMetadata && metadataIndentClass,\n )}\n >\n {showRepositoryMetadata &&\n (selectedRepository?.selected_repository ? (\n <ConversationRepoLink selectedRepository={selectedRepository} />\n ) : (\n <NoRepository workspaceWorkingDir={workspaceWorkingDir} />\n ))}\n <div className=\"flex items-center gap-2 shrink-0 ml-auto\">\n {showTimestamp && (createdAt ?? lastUpdatedAt) && (\n <p className=\"text-xs text-[var(--oh-muted)] text-right\">\n <time>\n {`${formatTimeDelta(lastUpdatedAt ?? createdAt)} ${t(I18nKey.CONVERSATION$AGO)}`}\n </time>\n </p>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAoDA,SAAgB,EAAuB,EACrC,uBACA,kBACA,cACA,oBACA,wBACA,4BAAyB,IACzB,mBAAgB,IAChB,aACA,mBAAgB,IAChB,eAAY,MACZ,eAAY,QACkB;CAC9B,IAAM,EAAE,SAAM,EAAe,YAAY,EAEnC,IAAW,EAAkB,EAAgB,EAQ/C,IAIO;AACX,KAAI,OACE,MAAc,OAAO;EACvB,IAAM,IACJ,EAA0B,EAAU,IACpC,EAAE,EAAQ,+BAA+B,EAIrC,IAAa,EAAiB,GAAW,EAAS,EAClD,IAAO,KAAc;AAC3B,MAAO;GACL,MAAM,EAAuB,EAAU;GACvC;GACA,SAAS,IAAa,GAAG,EAAa,KAAK,MAAe;GAC3D;QACQ,MAGT,IAAO;EACL,MAAM;EACN,MAAM,EAAsB,EAAS,IAAI;EACzC,SAAS;EACV;CAKL,IAAM,IACJ,MAAoB,KAAA,IAA0B,KAAA,IAAd;AAElC,QACE,kBAAC,OAAD;EACE,WAAW,EACT,+CACA,KAAY,aACb;YAJH,CAMG,IACC,kBAAC,OAAD;GAAK,WAAW;aACd,kBAAC,QAAD;IACE,eAAY;IACZ,WAAU;IACV,OAAO,EAAK;cAHd,CAKE,kBAAC,GAAD,EAAgB,MAAM,EAAK,MAAQ,CAAA,EACnC,kBAAC,QAAD;KAAM,WAAU;eAAY,EAAK;KAAY,CAAA,CACxC;;GACH,CAAA,GACJ,MACJ,kBAAC,OAAD;GACE,WAAW,EACT,mDACA,KAA0B,EAC3B;aAJH,CAMG,MACE,GAAoB,sBACnB,kBAAC,GAAD,EAA0C,uBAAsB,CAAA,GAEhE,kBAAC,GAAD,EAAmC,wBAAuB,CAAA,GAE9D,kBAAC,OAAD;IAAK,WAAU;cACZ,MAAkB,KAAa,MAC9B,kBAAC,KAAD;KAAG,WAAU;eACX,kBAAC,QAAD,EAAA,UACG,GAAG,EAAgB,KAAiB,EAAU,CAAC,GAAG,EAAE,EAAQ,iBAAiB,IACzE,CAAA;KACL,CAAA;IAEF,CAAA,CACF;KACF"}
@@ -1,2 +1,2 @@
1
- const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/status.cjs`),i=require(`../../../utils/utils.cjs`),ee=require(`../../../context/navigation-context.cjs`),te=require(`../../../utils/custom-toast-handlers.cjs`),ne=require(`../../../contexts/active-backend-context.cjs`),re=require(`../../../node_modules/@heroui/tooltip/dist/chunk-AUA5GDXN.cjs`),ie=require(`../../../hooks/use-click-outside-element.cjs`),ae=require(`../../../hooks/mutation/use-create-conversation.cjs`),oe=require(`../../shared/navigation-link.cjs`),se=require(`../../../hooks/mutation/use-delete-conversation.cjs`),ce=require(`../../../hooks/mutation/use-unified-stop-conversation.cjs`),le=require(`../../../hooks/mutation/use-update-conversation.cjs`),ue=require(`./confirm-delete-modal.cjs`),de=require(`./confirm-stop-modal.cjs`),fe=require(`../../../hooks/query/use-paginated-conversations.cjs`),pe=require(`../../../hooks/query/use-start-tasks.cjs`),me=require(`./exit-conversation-modal.cjs`),he=require(`../../../hooks/use-is-creating-conversation.cjs`),ge=require(`./conversation-card/conversation-card.cjs`),_e=require(`./conversation-card/conversation-card-preview.cjs`),ve=require(`./start-task-card/start-task-card.cjs`),ye=require(`./conversation-card/conversation-card-skeleton.cjs`),be=require(`./compact-conversation-row.cjs`),a=require(`../../../stores/conversation-panel-preferences-store.cjs`),xe=require(`./conversation-panel-filter-menu.cjs`),Se=require(`./conversation-panel-new-thread-picker.cjs`),o=require(`./conversation-panel-list-helpers.cjs`),Ce=require(`./conversation-group-folder-list.cjs`),we=require(`./conversation-panel-pinned-section.cjs`),s=require(`../../../stores/pinned-conversations-store.cjs`);let c=require(`react`);c=e.__toESM(c,1);let l=require(`react/jsx-runtime`);var Te=()=>{},Ee=[],u=3600*1e3,De=e=>{let t=Date.now()-u,n=[],r=[];for(let i of e){let e=i.updated_at?Date.parse(i.updated_at):NaN;Number.isFinite(e)&&e<t?r.push(i):n.push(i)}return{recent:n,older:r}};function d({onClose:e,compact:u=!1}){let{t:d}=t.useTranslation(`openhands`),{conversationId:f,navigate:p}=ee.useNavigation(),{backend:m}=ne.useActiveBackend(),Oe=ie.useClickOutsideElement(e??Te),[ke,h]=c.default.useState(!1),[Ae,g]=c.default.useState(!1),[je,Me]=c.default.useState(!1),[Ne,_]=c.default.useState(!1),v=a.useConversationPanelPreferencesStore(e=>e.showOlderConversations),Pe=a.useConversationPanelPreferencesStore(e=>e.toggleShowOlderConversations),y=a.useConversationPanelPreferencesStore(e=>e.showRepoBranchMetadata),Fe=a.useConversationPanelPreferencesStore(e=>e.toggleShowRepoBranchMetadata),b=a.useConversationPanelPreferencesStore(e=>e.showLlmProfiles),Ie=a.useConversationPanelPreferencesStore(e=>e.toggleShowLlmProfiles),x=a.useConversationPanelPreferencesStore(e=>e.showHoverMetadata),Le=a.useConversationPanelPreferencesStore(e=>e.toggleShowHoverMetadata),S=a.useConversationPanelPreferencesStore(e=>e.organizeMode),Re=a.useConversationPanelPreferencesStore(e=>e.setOrganizeMode),C=a.useConversationPanelPreferencesStore(e=>e.conversationSort),ze=a.useConversationPanelPreferencesStore(e=>e.setConversationSort),w=a.useConversationPanelPreferencesStore(e=>e.threadScope),Be=a.useConversationPanelPreferencesStore(e=>e.setThreadScope),T=a.useConversationPanelPreferencesStore(e=>e.groupFolderOrder),Ve=a.useConversationPanelPreferencesStore(e=>e.setGroupFolderOrder),[He,E]=c.default.useState(!1),[Ue,We]=c.default.useState(!1),Ge=ie.useClickOutsideElement(()=>{E(!1)}),[Ke,D]=c.default.useState(()=>new Set),[qe,O]=c.default.useState(()=>new Set),[Je,k]=c.default.useState(!1),A=s.usePinnedConversationsStore(e=>e.pinsByBackendId[m.id]??Ee),Ye=s.usePinnedConversationsStore(e=>e.togglePin),Xe=s.usePinnedConversationsStore(e=>e.pruneMissingConversations),Ze=c.default.useCallback(e=>{D(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),Qe=c.default.useCallback(e=>{O(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]);c.default.useEffect(()=>{S!==`grouped`&&(D(new Set),O(new Set))},[S]);let $e=c.default.useRef(null),[j,M]=c.default.useState(null),[et,N]=c.default.useState(null),[P,tt]=c.default.useState(null),{data:nt,isLoading:rt,isFetched:F,hasNextPage:I,isFetching:L,isFetchingNextPage:R,fetchNextPage:z}=fe.usePaginatedConversations(),{data:B}=pe.useStartTasks(),V=c.default.useMemo(()=>{let e=nt?.pages.flatMap(e=>e.items)??[],t=new Set;return e.filter(e=>t.has(e.id)?!1:(t.add(e.id),!0))},[nt]),H=c.default.useMemo(()=>o.resolvePinnedConversations(A,V),[V,A]);c.default.useEffect(()=>{F&&Xe(m.id,V.map(e=>e.id))},[m.id,V,F,Xe]),c.default.useEffect(()=>{A.length===0&&k(!1)},[A.length]);let U=c.default.useMemo(()=>{let e=w===`relevant`?V.filter(e=>r.isExecutionActive(e.execution_status)):V;return u?e:o.filterOutPinnedConversations(e,A)},[u,V,A,w]),{recent:W,older:G}=c.default.useMemo(()=>De(U),[U]),it=c.default.useMemo(()=>o.sortConversationsByField(v?[...W,...G]:W,C),[W,G,v,C]),at=c.default.useMemo(()=>({emptyWorkspace:d(n.I18nKey.CONVERSATION_PANEL$NO_WORKSPACE),emptyRepository:d(n.I18nKey.CONVERSATION_PANEL$NO_REPOSITORY)}),[d]),K=c.default.useMemo(()=>u||S!==`grouped`?null:o.groupConversations([...W,...v?G:[]],m.kind,C,at),[m.kind,u,C,at,G,S,W,v]),q=c.default.useMemo(()=>K?o.applyGroupFolderOrder(K,T):null,[K,T]),ot=c.default.useMemo(()=>K?.map(e=>e.id)??[],[K]),st=c.default.useMemo(()=>o.sortConversationsByField(W.filter(e=>r.isExecutionActive(e.execution_status)),C),[C,W]),ct=it.length,lt=c.default.useMemo(()=>q?q.reduce((e,t)=>e+t.conversations.length,0):0,[q]),ut=S===`grouped`&&!u?lt===0:ct===0,J=S===`grouped`&&!u?lt:ct,[Y,X]=c.default.useState(null),dt=c.default.useRef(J);dt.current=J;let ft=c.default.useCallback(()=>{I&&X(dt.current)},[I]);c.default.useEffect(()=>{if(Y!==null){if(J>Y){X(null);return}if(!I){X(null);return}L||R||z()}},[Y,J,I,L,R,z]);let pt=Y!==null||R,{mutate:mt,mutateAsync:ht}=se.useDeleteConversation(),{mutate:gt}=ce.useUnifiedPauseConversation(),{mutate:_t}=le.useUpdateConversation(),vt=G.length>0&&!v,yt=!!I&&!vt&&!u&&!ut,{mutate:bt}=ae.useCreateConversation(),Z=he.useIsCreatingConversation(),xt=c.default.useCallback(e=>{Z||bt({workingDir:e.workingDir,repository:e.repository},{onSuccess:e=>{p(`/conversations/${e.conversation_id}`)}})},[bt,Z,p]),St=c.default.useCallback((e,t)=>{h(!0),M(e),N(t)},[]),Ct=c.default.useCallback(e=>{g(!0),M(e)},[]),wt=c.default.useCallback((e,t)=>{_t({conversationId:e,newTitle:t},{onSuccess:()=>{te.displaySuccessToast(d(n.I18nKey.CONVERSATION$TITLE_UPDATED))}})},[d,_t]),Tt=()=>{j&&mt({conversationId:j},{onSuccess:()=>{j===f&&p(`/conversations`)}})},Et=()=>{j&&gt({conversationId:j})},Dt=async()=>{let e=V.map(e=>e.id),t=await Promise.allSettled(e.map(e=>ht({conversationId:e}))),n=t.flatMap((t,n)=>t.status===`fulfilled`?[e[n]]:[]),r=t.length-n.length;f!==null&&n.includes(f)&&p(`/conversations`),r>0&&te.displayErrorToast(`${r} conversation${r===1?``:`s`} could not be deleted.`)},Q=c.default.useCallback((t,n)=>{let r=A.includes(t.id);return u?(0,l.jsx)(be.CompactConversationRow,{conversationId:t.id,title:t.title??``,selectedRepository:{selected_repository:t.selected_repository,selected_branch:t.selected_branch,git_provider:t.git_provider},executionStatus:t.execution_status,sandboxStatus:t.sandbox_status,lastUpdatedAt:t.updated_at,createdAt:t.created_at,workspaceWorkingDir:t.selected_workspace??t.workspace?.working_dir,isActive:t.id===f,onClose:e,showRepositoryMetadata:y,llmModel:t.llm_model,showLlmProfiles:b,agentKind:t.agent_kind,acpServer:t.acp_server},t.id):(0,l.jsx)(re.tooltip_default,{placement:`right-start`,delay:1e3,closeDelay:100,isDisabled:!x||P===t.id,disableAnimation:!1,className:`rounded-xl border border-[var(--oh-border)] bg-base-secondary p-0 text-white shadow-xl`,content:(0,l.jsx)(_e.ConversationCardPreview,{title:t.title??``,executionStatus:t.execution_status,sandboxStatus:t.sandbox_status,selectedRepository:{selected_repository:t.selected_repository,selected_branch:t.selected_branch,git_provider:t.git_provider},workspaceWorkingDir:t.selected_workspace??t.workspace?.working_dir,llmModel:t.llm_model,createdAt:t.created_at}),children:(0,l.jsx)(oe.NavigationLink,{to:`/conversations/${t.id}`,onClick:e,className:i.cn(`block rounded-md transition-colors`,P!==t.id&&`hover:bg-[var(--oh-surface)]`,(t.id===f||P===t.id)&&`bg-[var(--oh-surface)]`),children:(0,l.jsx)(ge.ConversationCard,{onDelete:()=>St(t.id,t.title??``),onStop:()=>Ct(t.id),onChangeTitle:e=>wt(t.id,e),title:t.title??``,selectedRepository:{selected_repository:t.selected_repository,selected_branch:t.selected_branch,git_provider:t.git_provider},lastUpdatedAt:t.updated_at,createdAt:t.created_at,executionStatus:t.execution_status,sandboxStatus:t.sandbox_status,conversationId:t.id,contextMenuOpen:P===t.id,onContextMenuToggle:e=>tt(e?t.id:null),isActive:t.id===f,workspaceWorkingDir:t.selected_workspace??t.workspace?.working_dir,showRepositoryMetadata:y,llmModel:t.llm_model,showLlmProfiles:b,agentKind:t.agent_kind,acpServer:t.acp_server,isPinned:r,onTogglePin:()=>Ye(m.id,t.id),alwaysShowPinIcon:r&&!n?.inPinnedSection})})},t.id)},[m.id,u,f,wt,St,Ct,e,P,A,y,b,x,Ye]),$=rt||!F,Ot=!u&&!$&&H.length>0,kt=F&&!rt&&!u&&ut&&!Ot&&!B?.length;return(0,l.jsxs)(`div`,{ref:Oe,"data-testid":`conversation-panel`,className:`flex h-full min-h-0 w-full flex-col`,children:[!u&&(0,l.jsx)(`div`,{className:i.cn(`-ml-2.5 w-[calc(100%+0.625rem)] max-w-none box-border border-b`,Ue?`border-[var(--oh-border)]`:`border-transparent`),children:(0,l.jsxs)(`div`,{"data-testid":`older-conversations-summary`,className:`flex min-w-0 flex-nowrap items-center gap-x-2 py-2 pl-4 pr-2.5 text-[var(--oh-muted)]`,children:[(0,l.jsx)(`span`,{className:`min-w-0 truncate text-sm font-medium text-[var(--oh-muted)]`,children:d(n.I18nKey.SIDEBAR$CONVERSATIONS)}),(0,l.jsxs)(`div`,{className:`ml-auto flex shrink-0 items-center gap-0.5`,children:[(0,l.jsx)(Se.ConversationPanelNewThreadPicker,{backendKind:m.kind}),(0,l.jsx)(xe.ConversationPanelFilterMenu,{filterMenuOpen:He,setFilterMenuOpen:E,menuRef:Ge,backendKind:m.kind,organizeMode:S,setOrganizeMode:Re,conversationSort:C,setConversationSort:ze,threadScope:w,setThreadScope:Be,showOlderConversations:v,toggleShowOlderConversations:Pe,showRepoBranchMetadata:y,toggleShowRepoBranchMetadata:Fe,showLlmProfiles:b,toggleShowLlmProfiles:Ie,showHoverMetadata:x,toggleShowHoverMetadata:Le,totalConversationsCount:V.length,onRequestDeleteAll:()=>_(!0)})]})]})}),(0,l.jsxs)(`div`,{ref:$e,"data-testid":`conversation-panel-list-scroll`,onScroll:e=>{We(e.currentTarget.scrollTop>0)},className:i.cn(`flex min-h-0 flex-1 flex-col overflow-y-auto overflow-x-hidden overscroll-contain custom-scrollbar-always`,!u&&`conversation-panel-list-scroll`),children:[$&&(0,l.jsx)(ye.ConversationCardSkeleton,{compact:u}),!u&&kt&&(0,l.jsx)(`div`,{"data-testid":`conversation-panel-empty-state`,className:`flex min-h-0 flex-1 flex-col items-center justify-center px-4 py-8`,children:(0,l.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)]`,children:d(n.I18nKey.CONVERSATION$NO_CONVERSATIONS)})}),Ot?(0,l.jsx)(we.ConversationPanelPinnedSection,{pinnedConversations:H,isPreviewExpanded:Je,onTogglePreviewExpanded:()=>k(e=>!e),activeConversationId:f,showDivider:!u&&S===`chronological`,renderConversationCard:e=>Q(e,{inPinnedSection:!0})}):null,!u&&B?.map(t=>(0,l.jsx)(oe.NavigationLink,{to:`/conversations/task-${t.id}`,onClick:e,className:`block`,children:(0,l.jsx)(ve.StartTaskCard,{task:t})},t.id)),!$&&u?st.map(e=>Q(e)):null,!$&&!u&&S===`grouped`&&q&&q.length>0?(0,l.jsx)(Ce.ConversationGroupFolderList,{groups:q,groupIds:ot,groupFolderOrder:T,setGroupFolderOrder:Ve,collapsedGroupIds:Ke,expandedGroupPreviewIds:qe,onToggleGroupCollapsed:Ze,onToggleGroupPreviewExpanded:Qe,isCreatingConversationFlow:Z,activeConversationId:f,onLaunchFromGroup:xt,renderConversationCard:e=>Q(e)}):null,!$&&!u&&S===`chronological`?(0,l.jsx)(`div`,{className:`space-y-0.5`,children:it.map(e=>Q(e))}):null,yt&&(pt?(0,l.jsx)(`div`,{className:`py-1`,children:(0,l.jsx)(ye.ConversationCardSkeleton,{compact:u})}):(0,l.jsx)(`div`,{className:`flex justify-center py-4`,children:(0,l.jsx)(`button`,{type:`button`,"data-testid":`load-more-conversations`,onClick:ft,className:`text-xs text-[var(--oh-muted)] hover:text-white`,children:d(n.I18nKey.CONVERSATION$LOAD_MORE)})}))]}),ke&&(0,l.jsx)(ue.ConfirmDeleteModal,{onConfirm:()=>{Tt(),h(!1),N(null)},onCancel:()=>{h(!1),N(null)},conversationTitle:et??void 0}),Ne&&(0,l.jsx)(ue.ConfirmDeleteModal,{title:d(n.I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_TITLE),description:d(n.I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_DESC,{count:V.length}),onConfirm:async()=>{await Dt(),_(!1)},onCancel:()=>_(!1)}),Ae&&(0,l.jsx)(de.ConfirmStopModal,{onConfirm:()=>{Et(),g(!1)},onCancel:()=>g(!1)}),je&&(0,l.jsx)(me.ExitConversationModal,{onConfirm:()=>{e?.()},onClose:()=>Me(!1),onCancel:()=>Me(!1)})]})}exports.ConversationPanel=d;
1
+ const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/status.cjs`),i=require(`../../../utils/utils.cjs`),ee=require(`../../../context/navigation-context.cjs`),te=require(`../../../utils/custom-toast-handlers.cjs`),ne=require(`../../../contexts/active-backend-context.cjs`),re=require(`../../../node_modules/@heroui/tooltip/dist/chunk-AUA5GDXN.cjs`),ie=require(`../../../hooks/use-click-outside-element.cjs`),ae=require(`../../../hooks/mutation/use-create-conversation.cjs`),oe=require(`../../shared/navigation-link.cjs`),se=require(`../../../hooks/mutation/use-delete-conversation.cjs`),ce=require(`../../../hooks/mutation/use-unified-stop-conversation.cjs`),le=require(`../../../hooks/mutation/use-update-conversation.cjs`),ue=require(`./confirm-delete-modal.cjs`),de=require(`./confirm-stop-modal.cjs`),fe=require(`../../../hooks/query/use-paginated-conversations.cjs`),pe=require(`../../../hooks/query/use-start-tasks.cjs`),me=require(`./exit-conversation-modal.cjs`),he=require(`../../../hooks/use-is-creating-conversation.cjs`),ge=require(`./conversation-card/conversation-card.cjs`),_e=require(`./conversation-card/conversation-card-preview.cjs`),ve=require(`./start-task-card/start-task-card.cjs`),ye=require(`./conversation-card/conversation-card-skeleton.cjs`),be=require(`./compact-conversation-row.cjs`),a=require(`../../../stores/conversation-panel-preferences-store.cjs`),xe=require(`./conversation-panel-filter-menu.cjs`),Se=require(`./conversation-panel-new-thread-picker.cjs`),o=require(`./conversation-panel-list-helpers.cjs`),Ce=require(`./conversation-group-folder-list.cjs`),we=require(`./conversation-panel-pinned-section.cjs`),s=require(`../../../stores/pinned-conversations-store.cjs`);let c=require(`react`);c=e.__toESM(c,1);let l=require(`react/jsx-runtime`);var Te=()=>{},Ee=[],u=3600*1e3,De=e=>{let t=Date.now()-u,n=[],r=[];for(let i of e){let e=i.updated_at?Date.parse(i.updated_at):NaN;Number.isFinite(e)&&e<t?r.push(i):n.push(i)}return{recent:n,older:r}};function d({onClose:e,compact:u=!1}){let{t:d}=t.useTranslation(`openhands`),{conversationId:f,navigate:p}=ee.useNavigation(),{backend:m}=ne.useActiveBackend(),Oe=ie.useClickOutsideElement(e??Te),[ke,h]=c.default.useState(!1),[Ae,g]=c.default.useState(!1),[je,Me]=c.default.useState(!1),[Ne,_]=c.default.useState(!1),v=a.useConversationPanelPreferencesStore(e=>e.showOlderConversations),Pe=a.useConversationPanelPreferencesStore(e=>e.toggleShowOlderConversations),y=a.useConversationPanelPreferencesStore(e=>e.showRepoBranchMetadata),Fe=a.useConversationPanelPreferencesStore(e=>e.toggleShowRepoBranchMetadata),b=a.useConversationPanelPreferencesStore(e=>e.showLlmProfiles),Ie=a.useConversationPanelPreferencesStore(e=>e.toggleShowLlmProfiles),x=a.useConversationPanelPreferencesStore(e=>e.showHoverMetadata),Le=a.useConversationPanelPreferencesStore(e=>e.toggleShowHoverMetadata),S=a.useConversationPanelPreferencesStore(e=>e.organizeMode),Re=a.useConversationPanelPreferencesStore(e=>e.setOrganizeMode),C=a.useConversationPanelPreferencesStore(e=>e.conversationSort),ze=a.useConversationPanelPreferencesStore(e=>e.setConversationSort),w=a.useConversationPanelPreferencesStore(e=>e.threadScope),Be=a.useConversationPanelPreferencesStore(e=>e.setThreadScope),T=a.useConversationPanelPreferencesStore(e=>e.groupFolderOrder),Ve=a.useConversationPanelPreferencesStore(e=>e.setGroupFolderOrder),[He,E]=c.default.useState(!1),[Ue,We]=c.default.useState(!1),Ge=ie.useClickOutsideElement(()=>{E(!1)}),[Ke,D]=c.default.useState(()=>new Set),[qe,O]=c.default.useState(()=>new Set),[Je,k]=c.default.useState(!1),A=s.usePinnedConversationsStore(e=>e.pinsByBackendId[m.id]??Ee),Ye=s.usePinnedConversationsStore(e=>e.togglePin),Xe=s.usePinnedConversationsStore(e=>e.pruneMissingConversations),Ze=c.default.useCallback(e=>{D(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),Qe=c.default.useCallback(e=>{O(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]);c.default.useEffect(()=>{S!==`grouped`&&(D(new Set),O(new Set))},[S]);let $e=c.default.useRef(null),[j,M]=c.default.useState(null),[et,N]=c.default.useState(null),[P,tt]=c.default.useState(null),{data:nt,isLoading:rt,isFetched:F,hasNextPage:I,isFetching:L,isFetchingNextPage:R,fetchNextPage:z}=fe.usePaginatedConversations(),{data:B}=pe.useStartTasks(),V=c.default.useMemo(()=>{let e=nt?.pages.flatMap(e=>e.items)??[],t=new Set;return e.filter(e=>t.has(e.id)?!1:(t.add(e.id),!0))},[nt]),H=c.default.useMemo(()=>o.resolvePinnedConversations(A,V),[V,A]);c.default.useEffect(()=>{F&&Xe(m.id,V.map(e=>e.id))},[m.id,V,F,Xe]),c.default.useEffect(()=>{A.length===0&&k(!1)},[A.length]);let U=c.default.useMemo(()=>{let e=w===`relevant`?V.filter(e=>r.isExecutionActive(e.execution_status)):V;return u?e:o.filterOutPinnedConversations(e,A)},[u,V,A,w]),{recent:W,older:G}=c.default.useMemo(()=>De(U),[U]),it=c.default.useMemo(()=>o.sortConversationsByField(v?[...W,...G]:W,C),[W,G,v,C]),at=c.default.useMemo(()=>({emptyWorkspace:d(n.I18nKey.CONVERSATION_PANEL$NO_WORKSPACE),emptyRepository:d(n.I18nKey.CONVERSATION_PANEL$NO_REPOSITORY)}),[d]),K=c.default.useMemo(()=>u||S!==`grouped`?null:o.groupConversations([...W,...v?G:[]],m.kind,C,at),[m.kind,u,C,at,G,S,W,v]),q=c.default.useMemo(()=>K?o.applyGroupFolderOrder(K,T):null,[K,T]),ot=c.default.useMemo(()=>K?.map(e=>e.id)??[],[K]),st=c.default.useMemo(()=>o.sortConversationsByField(W.filter(e=>r.isExecutionActive(e.execution_status)),C),[C,W]),ct=it.length,lt=c.default.useMemo(()=>q?q.reduce((e,t)=>e+t.conversations.length,0):0,[q]),ut=S===`grouped`&&!u?lt===0:ct===0,J=S===`grouped`&&!u?lt:ct,[Y,X]=c.default.useState(null),dt=c.default.useRef(J);dt.current=J;let ft=c.default.useCallback(()=>{I&&X(dt.current)},[I]);c.default.useEffect(()=>{if(Y!==null){if(J>Y){X(null);return}if(!I){X(null);return}L||R||z()}},[Y,J,I,L,R,z]);let pt=Y!==null||R,{mutate:mt,mutateAsync:ht}=se.useDeleteConversation(),{mutate:gt}=ce.useUnifiedPauseConversation(),{mutate:_t}=le.useUpdateConversation(),vt=G.length>0&&!v,yt=!!I&&!vt&&!u&&!ut,{mutate:bt}=ae.useCreateConversation(),Z=he.useIsCreatingConversation(),xt=c.default.useCallback(e=>{Z||bt({workingDir:e.workingDir,repository:e.repository,entryPoint:`sidebar_relaunch_project`},{onSuccess:e=>{p(`/conversations/${e.conversation_id}`)}})},[bt,Z,p]),St=c.default.useCallback((e,t)=>{h(!0),M(e),N(t)},[]),Ct=c.default.useCallback(e=>{g(!0),M(e)},[]),wt=c.default.useCallback((e,t)=>{_t({conversationId:e,newTitle:t},{onSuccess:()=>{te.displaySuccessToast(d(n.I18nKey.CONVERSATION$TITLE_UPDATED))}})},[d,_t]),Tt=()=>{j&&mt({conversationId:j},{onSuccess:()=>{j===f&&p(`/conversations`)}})},Et=()=>{j&&gt({conversationId:j})},Dt=async()=>{let e=V.map(e=>e.id),t=await Promise.allSettled(e.map(e=>ht({conversationId:e}))),n=t.flatMap((t,n)=>t.status===`fulfilled`?[e[n]]:[]),r=t.length-n.length;f!==null&&n.includes(f)&&p(`/conversations`),r>0&&te.displayErrorToast(`${r} conversation${r===1?``:`s`} could not be deleted.`)},Q=c.default.useCallback((t,n)=>{let r=A.includes(t.id);return u?(0,l.jsx)(be.CompactConversationRow,{conversationId:t.id,title:t.title??``,selectedRepository:{selected_repository:t.selected_repository,selected_branch:t.selected_branch,git_provider:t.git_provider},executionStatus:t.execution_status,sandboxStatus:t.sandbox_status,lastUpdatedAt:t.updated_at,createdAt:t.created_at,workspaceWorkingDir:t.selected_workspace??t.workspace?.working_dir,isActive:t.id===f,onClose:e,showRepositoryMetadata:y,llmModel:t.llm_model,showLlmProfiles:b,agentKind:t.agent_kind,acpServer:t.acp_server},t.id):(0,l.jsx)(re.tooltip_default,{placement:`right-start`,delay:1e3,closeDelay:100,isDisabled:!x||P===t.id,disableAnimation:!1,className:`rounded-xl border border-[var(--oh-border)] bg-base-secondary p-0 text-white shadow-xl`,content:(0,l.jsx)(_e.ConversationCardPreview,{title:t.title??``,executionStatus:t.execution_status,sandboxStatus:t.sandbox_status,selectedRepository:{selected_repository:t.selected_repository,selected_branch:t.selected_branch,git_provider:t.git_provider},workspaceWorkingDir:t.selected_workspace??t.workspace?.working_dir,llmModel:t.llm_model,createdAt:t.created_at}),children:(0,l.jsx)(oe.NavigationLink,{to:`/conversations/${t.id}`,onClick:e,className:i.cn(`block rounded-md transition-colors`,P!==t.id&&`hover:bg-[var(--oh-surface)]`,(t.id===f||P===t.id)&&`bg-[var(--oh-surface)]`),children:(0,l.jsx)(ge.ConversationCard,{onDelete:()=>St(t.id,t.title??``),onStop:()=>Ct(t.id),onChangeTitle:e=>wt(t.id,e),title:t.title??``,selectedRepository:{selected_repository:t.selected_repository,selected_branch:t.selected_branch,git_provider:t.git_provider},lastUpdatedAt:t.updated_at,createdAt:t.created_at,executionStatus:t.execution_status,sandboxStatus:t.sandbox_status,conversationId:t.id,contextMenuOpen:P===t.id,onContextMenuToggle:e=>tt(e?t.id:null),isActive:t.id===f,workspaceWorkingDir:t.selected_workspace??t.workspace?.working_dir,showRepositoryMetadata:y,llmModel:t.llm_model,showLlmProfiles:b,agentKind:t.agent_kind,acpServer:t.acp_server,isPinned:r,onTogglePin:()=>Ye(m.id,t.id),alwaysShowPinIcon:r&&!n?.inPinnedSection})})},t.id)},[m.id,u,f,wt,St,Ct,e,P,A,y,b,x,Ye]),$=rt||!F,Ot=!u&&!$&&H.length>0,kt=F&&!rt&&!u&&ut&&!Ot&&!B?.length;return(0,l.jsxs)(`div`,{ref:Oe,"data-testid":`conversation-panel`,className:`flex h-full min-h-0 w-full flex-col`,children:[!u&&(0,l.jsx)(`div`,{className:i.cn(`-ml-2.5 w-[calc(100%+0.625rem)] max-w-none box-border border-b`,Ue?`border-[var(--oh-border)]`:`border-transparent`),children:(0,l.jsxs)(`div`,{"data-testid":`older-conversations-summary`,className:`flex min-w-0 flex-nowrap items-center gap-x-2 py-2 pl-4 pr-2.5 text-[var(--oh-muted)]`,children:[(0,l.jsx)(`span`,{className:`min-w-0 truncate text-sm font-medium text-[var(--oh-muted)]`,children:d(n.I18nKey.SIDEBAR$CONVERSATIONS)}),(0,l.jsxs)(`div`,{className:`ml-auto flex shrink-0 items-center gap-0.5`,children:[(0,l.jsx)(Se.ConversationPanelNewThreadPicker,{backendKind:m.kind}),(0,l.jsx)(xe.ConversationPanelFilterMenu,{filterMenuOpen:He,setFilterMenuOpen:E,menuRef:Ge,backendKind:m.kind,organizeMode:S,setOrganizeMode:Re,conversationSort:C,setConversationSort:ze,threadScope:w,setThreadScope:Be,showOlderConversations:v,toggleShowOlderConversations:Pe,showRepoBranchMetadata:y,toggleShowRepoBranchMetadata:Fe,showLlmProfiles:b,toggleShowLlmProfiles:Ie,showHoverMetadata:x,toggleShowHoverMetadata:Le,totalConversationsCount:V.length,onRequestDeleteAll:()=>_(!0)})]})]})}),(0,l.jsxs)(`div`,{ref:$e,"data-testid":`conversation-panel-list-scroll`,onScroll:e=>{We(e.currentTarget.scrollTop>0)},className:i.cn(`flex min-h-0 flex-1 flex-col overflow-y-auto overflow-x-hidden overscroll-contain custom-scrollbar-always`,!u&&`conversation-panel-list-scroll`),children:[$&&(0,l.jsx)(ye.ConversationCardSkeleton,{compact:u}),!u&&kt&&(0,l.jsx)(`div`,{"data-testid":`conversation-panel-empty-state`,className:`flex min-h-0 flex-1 flex-col items-center justify-center px-4 py-8`,children:(0,l.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)]`,children:d(n.I18nKey.CONVERSATION$NO_CONVERSATIONS)})}),Ot?(0,l.jsx)(we.ConversationPanelPinnedSection,{pinnedConversations:H,isPreviewExpanded:Je,onTogglePreviewExpanded:()=>k(e=>!e),activeConversationId:f,showDivider:!u&&S===`chronological`,renderConversationCard:e=>Q(e,{inPinnedSection:!0})}):null,!u&&B?.map(t=>(0,l.jsx)(oe.NavigationLink,{to:`/conversations/task-${t.id}`,onClick:e,className:`block`,children:(0,l.jsx)(ve.StartTaskCard,{task:t})},t.id)),!$&&u?st.map(e=>Q(e)):null,!$&&!u&&S===`grouped`&&q&&q.length>0?(0,l.jsx)(Ce.ConversationGroupFolderList,{groups:q,groupIds:ot,groupFolderOrder:T,setGroupFolderOrder:Ve,collapsedGroupIds:Ke,expandedGroupPreviewIds:qe,onToggleGroupCollapsed:Ze,onToggleGroupPreviewExpanded:Qe,isCreatingConversationFlow:Z,activeConversationId:f,onLaunchFromGroup:xt,renderConversationCard:e=>Q(e)}):null,!$&&!u&&S===`chronological`?(0,l.jsx)(`div`,{className:`space-y-0.5`,children:it.map(e=>Q(e))}):null,yt&&(pt?(0,l.jsx)(`div`,{className:`py-1`,children:(0,l.jsx)(ye.ConversationCardSkeleton,{compact:u})}):(0,l.jsx)(`div`,{className:`flex justify-center py-4`,children:(0,l.jsx)(`button`,{type:`button`,"data-testid":`load-more-conversations`,onClick:ft,className:`text-xs text-[var(--oh-muted)] hover:text-white`,children:d(n.I18nKey.CONVERSATION$LOAD_MORE)})}))]}),ke&&(0,l.jsx)(ue.ConfirmDeleteModal,{onConfirm:()=>{Tt(),h(!1),N(null)},onCancel:()=>{h(!1),N(null)},conversationTitle:et??void 0}),Ne&&(0,l.jsx)(ue.ConfirmDeleteModal,{title:d(n.I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_TITLE),description:d(n.I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_DESC,{count:V.length}),onConfirm:async()=>{await Dt(),_(!1)},onCancel:()=>_(!1)}),Ae&&(0,l.jsx)(de.ConfirmStopModal,{onConfirm:()=>{Et(),g(!1)},onCancel:()=>g(!1)}),je&&(0,l.jsx)(me.ExitConversationModal,{onConfirm:()=>{e?.()},onClose:()=>Me(!1),onCancel:()=>Me(!1)})]})}exports.ConversationPanel=d;
2
2
  //# sourceMappingURL=conversation-panel.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-panel.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/conversation-panel.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tooltip } from \"@heroui/react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { usePaginatedConversations } from \"#/hooks/query/use-paginated-conversations\";\nimport { useStartTasks } from \"#/hooks/query/use-start-tasks\";\nimport { useDeleteConversation } from \"#/hooks/mutation/use-delete-conversation\";\nimport { useUnifiedPauseConversation } from \"#/hooks/mutation/use-unified-stop-conversation\";\nimport { ConfirmDeleteModal } from \"./confirm-delete-modal\";\nimport { ConfirmStopModal } from \"./confirm-stop-modal\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ExitConversationModal } from \"./exit-conversation-modal\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { Provider } from \"#/types/settings\";\nimport { useUpdateConversation } from \"#/hooks/mutation/use-update-conversation\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { isExecutionActive } from \"#/utils/status\";\nimport { useCreateConversation } from \"#/hooks/mutation/use-create-conversation\";\nimport { useIsCreatingConversation } from \"#/hooks/use-is-creating-conversation\";\nimport { ConversationCard } from \"./conversation-card/conversation-card\";\nimport { ConversationCardPreview } from \"./conversation-card/conversation-card-preview\";\nimport { StartTaskCard } from \"./start-task-card/start-task-card\";\nimport { ConversationCardSkeleton } from \"./conversation-card/conversation-card-skeleton\";\nimport { CompactConversationRow } from \"./compact-conversation-row\";\nimport { useConversationPanelPreferencesStore } from \"#/stores/conversation-panel-preferences-store\";\nimport { cn } from \"#/utils/utils\";\nimport { ConversationPanelFilterMenu } from \"./conversation-panel-filter-menu\";\nimport { ConversationPanelNewThreadPicker } from \"./conversation-panel-new-thread-picker\";\nimport { ConversationGroupFolderList } from \"./conversation-group-folder-list\";\nimport { ConversationPanelPinnedSection } from \"./conversation-panel-pinned-section\";\nimport {\n applyGroupFolderOrder,\n filterOutPinnedConversations,\n groupConversations,\n resolvePinnedConversations,\n sortConversationsByField,\n type ConversationGroupLaunch,\n} from \"./conversation-panel-list-helpers\";\nimport { usePinnedConversationsStore } from \"#/stores/pinned-conversations-store\";\n\ninterface ConversationPanelProps {\n onClose?: () => void;\n /**\n * Render a minimal icon-only variant of each conversation row (used by the\n * collapsed sidebar). Each row is a single status dot with a hover preview\n * containing the full card content.\n */\n compact?: boolean;\n}\n\nconst noop = () => {};\n\nconst EMPTY_PINNED_CONVERSATION_IDS: readonly string[] = [];\n\nconst ONE_HOUR_MS = 60 * 60 * 1000;\n\nconst partitionByCutoff = <T extends { updated_at: string }>(\n items: readonly T[],\n): { recent: T[]; older: T[] } => {\n // The cutoff is intentionally relative to \"now\" each time the list is\n // recomputed, so conversations naturally age into the older bucket as the\n // conversations query refreshes.\n const cutoff = Date.now() - ONE_HOUR_MS;\n const recent: T[] = [];\n const older: T[] = [];\n for (const item of items) {\n const updatedAt = item.updated_at ? Date.parse(item.updated_at) : NaN;\n // Missing or unparseable timestamps stay in the \"recent\" bucket so we\n // do not accidentally hide them behind the older-conversations toggle.\n if (Number.isFinite(updatedAt) && updatedAt < cutoff) {\n older.push(item);\n } else {\n recent.push(item);\n }\n }\n return { recent, older };\n};\n\nexport function ConversationPanel({\n onClose,\n compact = false,\n}: ConversationPanelProps) {\n const { t } = useTranslation(\"openhands\");\n const { conversationId: currentConversationId, navigate } = useNavigation();\n const { backend: activeBackend } = useActiveBackend();\n // Click-outside is only relevant in the legacy drawer mode where an\n // onClose handler is provided. When the panel is rendered inline (e.g.\n // as the always-visible conversation list pane), clicking outside should\n // not dismiss the list, so we pass a no-op callback in that case.\n const ref = useClickOutsideElement<HTMLDivElement>(onClose ?? noop);\n\n const [confirmDeleteModalVisible, setConfirmDeleteModalVisible] =\n React.useState(false);\n const [confirmStopModalVisible, setConfirmStopModalVisible] =\n React.useState(false);\n const [\n confirmExitConversationModalVisible,\n setConfirmExitConversationModalVisible,\n ] = React.useState(false);\n const [confirmDeleteAllVisible, setConfirmDeleteAllVisible] =\n React.useState(false);\n const showOlderConversations = useConversationPanelPreferencesStore(\n (state) => state.showOlderConversations,\n );\n const toggleShowOlderConversations = useConversationPanelPreferencesStore(\n (state) => state.toggleShowOlderConversations,\n );\n const showRepoBranchMetadata = useConversationPanelPreferencesStore(\n (state) => state.showRepoBranchMetadata,\n );\n const toggleShowRepoBranchMetadata = useConversationPanelPreferencesStore(\n (state) => state.toggleShowRepoBranchMetadata,\n );\n const showLlmProfiles = useConversationPanelPreferencesStore(\n (state) => state.showLlmProfiles,\n );\n const toggleShowLlmProfiles = useConversationPanelPreferencesStore(\n (state) => state.toggleShowLlmProfiles,\n );\n const showHoverMetadata = useConversationPanelPreferencesStore(\n (state) => state.showHoverMetadata,\n );\n const toggleShowHoverMetadata = useConversationPanelPreferencesStore(\n (state) => state.toggleShowHoverMetadata,\n );\n const organizeMode = useConversationPanelPreferencesStore(\n (state) => state.organizeMode,\n );\n const setOrganizeMode = useConversationPanelPreferencesStore(\n (state) => state.setOrganizeMode,\n );\n const conversationSort = useConversationPanelPreferencesStore(\n (state) => state.conversationSort,\n );\n const setConversationSort = useConversationPanelPreferencesStore(\n (state) => state.setConversationSort,\n );\n const threadScope = useConversationPanelPreferencesStore(\n (state) => state.threadScope,\n );\n const setThreadScope = useConversationPanelPreferencesStore(\n (state) => state.setThreadScope,\n );\n const groupFolderOrder = useConversationPanelPreferencesStore(\n (state) => state.groupFolderOrder,\n );\n const setGroupFolderOrder = useConversationPanelPreferencesStore(\n (state) => state.setGroupFolderOrder,\n );\n const [filterMenuOpen, setFilterMenuOpen] = React.useState(false);\n const [isListScrolled, setIsListScrolled] = React.useState(false);\n const filterMenuRef = useClickOutsideElement<HTMLDivElement>(() => {\n setFilterMenuOpen(false);\n });\n const [collapsedGroupIds, setCollapsedGroupIds] = React.useState<\n ReadonlySet<string>\n >(() => new Set());\n const [expandedGroupPreviewIds, setExpandedGroupPreviewIds] = React.useState<\n ReadonlySet<string>\n >(() => new Set());\n const [expandedPinnedPreview, setExpandedPinnedPreview] =\n React.useState(false);\n\n const pinnedIds = usePinnedConversationsStore(\n (state) =>\n state.pinsByBackendId[activeBackend.id] ?? EMPTY_PINNED_CONVERSATION_IDS,\n );\n const togglePin = usePinnedConversationsStore((state) => state.togglePin);\n const pruneMissingPinnedConversations = usePinnedConversationsStore(\n (state) => state.pruneMissingConversations,\n );\n\n const toggleGroupCollapsed = React.useCallback((groupId: string) => {\n setCollapsedGroupIds((prev) => {\n const next = new Set(prev);\n if (next.has(groupId)) {\n next.delete(groupId);\n } else {\n next.add(groupId);\n }\n return next;\n });\n }, []);\n\n const toggleGroupPreviewExpanded = React.useCallback((groupId: string) => {\n setExpandedGroupPreviewIds((prev) => {\n const next = new Set(prev);\n if (next.has(groupId)) {\n next.delete(groupId);\n } else {\n next.add(groupId);\n }\n return next;\n });\n }, []);\n\n React.useEffect(() => {\n if (organizeMode !== \"grouped\") {\n setCollapsedGroupIds(new Set());\n setExpandedGroupPreviewIds(new Set());\n }\n }, [organizeMode]);\n\n const scrollContainerRef = React.useRef<HTMLDivElement>(null);\n\n const [selectedConversationId, setSelectedConversationId] = React.useState<\n string | null\n >(null);\n const [selectedConversationTitle, setSelectedConversationTitle] =\n React.useState<string | null>(null);\n const [openContextMenuId, setOpenContextMenuId] = React.useState<\n string | null\n >(null);\n\n const {\n data,\n isLoading,\n isFetched,\n hasNextPage,\n isFetching,\n isFetchingNextPage,\n fetchNextPage,\n } = usePaginatedConversations();\n\n // Fetch in-progress start tasks\n const { data: startTasks } = useStartTasks();\n\n const conversations = React.useMemo(() => {\n const all = data?.pages.flatMap((page) => page.items) ?? [];\n // The 10s background refetch re-fetches every loaded page with the\n // `UPDATED_AT_DESC` cursor. If a conversation's `updated_at` shifts between\n // page fetches, a later page can overlap an earlier one and surface the\n // same conversation twice. Dedupe by id (keeping the first/freshest copy)\n // so the rendered count reflects real growth and React keys stay unique.\n const seen = new Set<string>();\n return all.filter((conversation) => {\n if (seen.has(conversation.id)) {\n return false;\n }\n seen.add(conversation.id);\n return true;\n });\n }, [data]);\n\n const pinnedConversations = React.useMemo(\n () => resolvePinnedConversations(pinnedIds, conversations),\n [conversations, pinnedIds],\n );\n\n React.useEffect(() => {\n if (!isFetched) {\n return;\n }\n pruneMissingPinnedConversations(\n activeBackend.id,\n conversations.map((conversation) => conversation.id),\n );\n }, [\n activeBackend.id,\n conversations,\n isFetched,\n pruneMissingPinnedConversations,\n ]);\n\n React.useEffect(() => {\n if (pinnedIds.length === 0) {\n setExpandedPinnedPreview(false);\n }\n }, [pinnedIds.length]);\n\n const scopedConversations = React.useMemo(() => {\n const scopeFiltered =\n threadScope === \"relevant\"\n ? conversations.filter((c) => isExecutionActive(c.execution_status))\n : conversations;\n\n // In the expanded panel, pinned conversations should only appear inside\n // the dedicated pinned section (not duplicated in grouped/flat lists).\n if (compact) {\n return scopeFiltered;\n }\n\n return filterOutPinnedConversations(scopeFiltered, pinnedIds);\n }, [compact, conversations, pinnedIds, threadScope]);\n\n const { recent: recentScoped, older: olderScoped } = React.useMemo(\n () => partitionByCutoff(scopedConversations),\n [scopedConversations],\n );\n\n // Sort the full visible set as one list. The recent/older partition is\n // still computed (it gates the \"Show older\" toggle and \"Load more\"\n // visibility), but the rendering must not use it as a visual boundary —\n // when sorting by `created`, a stale-but-recently-touched conversation\n // would otherwise land in `recent` and render above an actually-newer-\n // by-`created_at` conversation sitting in `older`.\n const sortedVisibleConversations = React.useMemo(() => {\n const visible = showOlderConversations\n ? [...recentScoped, ...olderScoped]\n : recentScoped;\n return sortConversationsByField(visible, conversationSort);\n }, [recentScoped, olderScoped, showOlderConversations, conversationSort]);\n\n const groupLabels = React.useMemo(\n () => ({\n emptyWorkspace: t(I18nKey.CONVERSATION_PANEL$NO_WORKSPACE),\n emptyRepository: t(I18nKey.CONVERSATION_PANEL$NO_REPOSITORY),\n }),\n [t],\n );\n\n const conversationGroups = React.useMemo(() => {\n if (compact || organizeMode !== \"grouped\") {\n return null;\n }\n // Use the unsorted partitions: groupConversations sorts each bucket\n // internally by `sortField`, so pre-sorting the merged input is wasted\n // work in grouped mode (the per-group sort overrides any global order).\n const merged = [\n ...recentScoped,\n ...(showOlderConversations ? olderScoped : []),\n ];\n return groupConversations(\n merged,\n activeBackend.kind,\n conversationSort,\n groupLabels,\n );\n }, [\n activeBackend.kind,\n compact,\n conversationSort,\n groupLabels,\n olderScoped,\n organizeMode,\n recentScoped,\n showOlderConversations,\n ]);\n\n const orderedConversationGroups = React.useMemo(() => {\n if (!conversationGroups) {\n return null;\n }\n return applyGroupFolderOrder(conversationGroups, groupFolderOrder);\n }, [conversationGroups, groupFolderOrder]);\n\n const conversationGroupIds = React.useMemo(\n () => conversationGroups?.map((group) => group.id) ?? [],\n [conversationGroups],\n );\n\n const compactVisibleConversations = React.useMemo(\n () =>\n sortConversationsByField(\n recentScoped.filter((conversation) =>\n isExecutionActive(conversation.execution_status),\n ),\n conversationSort,\n ),\n [conversationSort, recentScoped],\n );\n\n const visibleFlatCount = sortedVisibleConversations.length;\n\n const visibleGroupedCount = React.useMemo(() => {\n if (!orderedConversationGroups) {\n return 0;\n }\n return orderedConversationGroups.reduce(\n (n, g) => n + g.conversations.length,\n 0,\n );\n }, [orderedConversationGroups]);\n\n const listIsEffectivelyEmpty =\n organizeMode === \"grouped\" && !compact\n ? visibleGroupedCount === 0\n : visibleFlatCount === 0;\n\n // Number of conversations actually rendered in the list right now, in the\n // current organize mode. \"Load more\" succeeds only when this number grows.\n const visibleCount =\n organizeMode === \"grouped\" && !compact\n ? visibleGroupedCount\n : visibleFlatCount;\n\n // KNOWN ISSUE (unresolved as of 2026-05-29): users still report that the\n // sidebar \"Load more\" sometimes requires two clicks before new conversations\n // appear. The mitigation below (dedupe by id in `conversations`, plus the\n // floor-tracking driver that keeps fetching until the visible count grows)\n // reduced but did NOT fully eliminate the symptom in manual testing. Likely\n // remaining suspects to investigate next: the agent-server cursor pagination\n // returning an overlapping/short page under `UPDATED_AT_DESC` while the 10s\n // `refetchInterval` reorders pages (see `usePaginatedConversations`), or a\n // React Query state lag where `hasNextPage`/`isFetching` settle a render\n // after the click. If you pick this up, reproduce against a backend with\n // >40 conversations and watch the `/api/conversations/search` cursors.\n //\n // Robust \"Load more\" driver. A single click can fail to surface new rows for\n // two reasons: (1) `fetchNextPage()` is silently dropped while the 10s\n // background refetch is in flight, and (2) a fetched page can yield zero\n // *visible* rows (filtered out by the active scope, or deduped as overlap),\n // so the list does not appear to grow. We capture the visible count at click\n // time and keep fetching pages — once the query is idle — until the visible\n // count actually increases or there are no more pages.\n const [loadMoreFloor, setLoadMoreFloor] = React.useState<number | null>(null);\n const visibleCountRef = React.useRef(visibleCount);\n visibleCountRef.current = visibleCount;\n\n const requestLoadMore = React.useCallback(() => {\n if (hasNextPage) {\n setLoadMoreFloor(visibleCountRef.current);\n }\n }, [hasNextPage]);\n\n React.useEffect(() => {\n if (loadMoreFloor === null) {\n return;\n }\n // Goal met: the visible list grew past where it was when the user clicked.\n if (visibleCount > loadMoreFloor) {\n setLoadMoreFloor(null);\n return;\n }\n // Nothing more to fetch — stop waiting even if the list did not grow.\n if (!hasNextPage) {\n setLoadMoreFloor(null);\n return;\n }\n // Wait for any in-flight fetch (including the background refetch) to settle\n // before requesting the next page, otherwise the request is dropped.\n if (isFetching || isFetchingNextPage) {\n return;\n }\n fetchNextPage();\n }, [\n loadMoreFloor,\n visibleCount,\n hasNextPage,\n isFetching,\n isFetchingNextPage,\n fetchNextPage,\n ]);\n\n const isLoadingMore = loadMoreFloor !== null || isFetchingNextPage;\n\n const { mutate: deleteConversation, mutateAsync: deleteConversationAsync } =\n useDeleteConversation();\n const { mutate: pauseConversation } = useUnifiedPauseConversation();\n const { mutate: updateConversation } = useUpdateConversation();\n\n // The next page of conversations is loaded only via the explicit \"Load\n // more\" link rendered at the end of the list — there is no scroll-driven\n // pagination, which previously caused the panel to feel like it had stray\n // scrollable space at the bottom.\n const olderHidden = olderScoped.length > 0 && !showOlderConversations;\n // Compact mode also hides \"Load more\" — paginating into archived\n // conversations contradicts the \"active only\" intent of the icon rail.\n // Do not show when the visible list is empty (e.g. filters hide every\n // loaded conversation) — that state already shows \"No conversations found\".\n const showLoadMore =\n !!hasNextPage && !olderHidden && !compact && !listIsEffectivelyEmpty;\n\n const { mutate: createConversation } = useCreateConversation();\n const isCreatingConversationFlow = useIsCreatingConversation();\n\n const launchFromGroup = React.useCallback(\n (launch: ConversationGroupLaunch) => {\n if (isCreatingConversationFlow) return;\n createConversation(\n {\n workingDir: launch.workingDir,\n repository: launch.repository,\n },\n {\n onSuccess: (data) => {\n navigate(`/conversations/${data.conversation_id}`);\n },\n },\n );\n },\n [createConversation, isCreatingConversationFlow, navigate],\n );\n\n const handleDeleteProject = React.useCallback(\n (conversationId: string, title: string) => {\n setConfirmDeleteModalVisible(true);\n setSelectedConversationId(conversationId);\n setSelectedConversationTitle(title);\n },\n [],\n );\n\n const handleStopConversation = React.useCallback((conversationId: string) => {\n setConfirmStopModalVisible(true);\n setSelectedConversationId(conversationId);\n }, []);\n\n const handleConversationTitleChange = React.useCallback(\n (conversationId: string, newTitle: string) => {\n updateConversation(\n { conversationId, newTitle },\n {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.CONVERSATION$TITLE_UPDATED));\n },\n },\n );\n },\n [t, updateConversation],\n );\n\n const handleConfirmDelete = () => {\n if (selectedConversationId) {\n deleteConversation(\n { conversationId: selectedConversationId },\n {\n onSuccess: () => {\n if (selectedConversationId === currentConversationId) {\n navigate(\"/conversations\");\n }\n },\n },\n );\n }\n };\n\n const handleConfirmStop = () => {\n if (selectedConversationId) {\n pauseConversation({\n conversationId: selectedConversationId,\n });\n }\n };\n\n const handleConfirmDeleteAll = async () => {\n const idsToDelete = conversations.map((c) => c.id);\n const results = await Promise.allSettled(\n idsToDelete.map((conversationId) =>\n deleteConversationAsync({ conversationId }),\n ),\n );\n\n const deletedIds = results.flatMap((result, index) =>\n result.status === \"fulfilled\" ? [idsToDelete[index]] : [],\n );\n const failedCount = results.length - deletedIds.length;\n\n if (\n currentConversationId !== null &&\n deletedIds.includes(currentConversationId)\n ) {\n navigate(\"/conversations\");\n }\n\n if (failedCount > 0) {\n displayErrorToast(\n `${failedCount} conversation${failedCount === 1 ? \"\" : \"s\"} could not be deleted.`,\n );\n }\n };\n\n const renderConversationCard = React.useCallback(\n (\n conversation: (typeof conversations)[number],\n options?: { inPinnedSection?: boolean },\n ) => {\n const isPinned = pinnedIds.includes(conversation.id);\n if (compact) {\n return (\n <CompactConversationRow\n key={conversation.id}\n conversationId={conversation.id}\n title={conversation.title ?? \"\"}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n lastUpdatedAt={conversation.updated_at}\n createdAt={conversation.created_at}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n isActive={conversation.id === currentConversationId}\n onClose={onClose}\n showRepositoryMetadata={showRepoBranchMetadata}\n llmModel={conversation.llm_model}\n showLlmProfiles={showLlmProfiles}\n agentKind={conversation.agent_kind}\n acpServer={conversation.acp_server}\n />\n );\n }\n return (\n <Tooltip\n key={conversation.id}\n placement=\"right-start\"\n delay={1000}\n closeDelay={100}\n isDisabled={\n !showHoverMetadata || openContextMenuId === conversation.id\n }\n disableAnimation={import.meta.env.MODE === \"test\"}\n className=\"rounded-xl border border-[var(--oh-border)] bg-base-secondary p-0 text-white shadow-xl\"\n content={\n <ConversationCardPreview\n title={conversation.title ?? \"\"}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n llmModel={conversation.llm_model}\n createdAt={conversation.created_at}\n />\n }\n >\n <NavigationLink\n to={`/conversations/${conversation.id}`}\n onClick={onClose}\n className={cn(\n \"block rounded-md transition-colors\",\n openContextMenuId !== conversation.id &&\n \"hover:bg-[var(--oh-surface)]\",\n (conversation.id === currentConversationId ||\n openContextMenuId === conversation.id) &&\n \"bg-[var(--oh-surface)]\",\n )}\n >\n <ConversationCard\n onDelete={() =>\n handleDeleteProject(conversation.id, conversation.title ?? \"\")\n }\n onStop={() => handleStopConversation(conversation.id)}\n onChangeTitle={(title) =>\n handleConversationTitleChange(conversation.id, title)\n }\n title={conversation.title ?? \"\"}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n lastUpdatedAt={conversation.updated_at}\n createdAt={conversation.created_at}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n conversationId={conversation.id}\n contextMenuOpen={openContextMenuId === conversation.id}\n onContextMenuToggle={(isOpen) =>\n setOpenContextMenuId(isOpen ? conversation.id : null)\n }\n isActive={conversation.id === currentConversationId}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n showRepositoryMetadata={showRepoBranchMetadata}\n llmModel={conversation.llm_model}\n showLlmProfiles={showLlmProfiles}\n agentKind={conversation.agent_kind}\n acpServer={conversation.acp_server}\n isPinned={isPinned}\n onTogglePin={() => togglePin(activeBackend.id, conversation.id)}\n alwaysShowPinIcon={isPinned && !options?.inPinnedSection}\n />\n </NavigationLink>\n </Tooltip>\n );\n },\n [\n activeBackend.id,\n compact,\n currentConversationId,\n handleConversationTitleChange,\n handleDeleteProject,\n handleStopConversation,\n onClose,\n openContextMenuId,\n pinnedIds,\n showRepoBranchMetadata,\n showLlmProfiles,\n showHoverMetadata,\n togglePin,\n ],\n );\n\n // Standard layout: panel fills its slot in the sidebar; the inner scroll\n // child fills the panel and scrolls when its content overflows. Modals are\n // siblings of the scroll element and are `position: fixed`, so they don't\n // participate in the panel's scroll geometry.\n // Gate on `isLoading` / `!isFetched` (true only until the first fetch settles),\n // not `isFetching` — the latter flips back to true on every 10s background\n // refetch, causing the skeleton/empty-state to flicker when the list is empty.\n const showInitialSkeleton = isLoading || !isFetched;\n const showPinnedSection =\n !compact && !showInitialSkeleton && pinnedConversations.length > 0;\n const showEmptyState =\n isFetched &&\n !isLoading &&\n !compact &&\n listIsEffectivelyEmpty &&\n !showPinnedSection &&\n !startTasks?.length;\n\n const showConversationHeader = !compact;\n\n return (\n <div\n ref={ref}\n data-testid=\"conversation-panel\"\n className=\"flex h-full min-h-0 w-full flex-col\"\n >\n {showConversationHeader && (\n <div\n className={cn(\n // Pull flush to the sidebar edges: `-ml-2.5` matches aside `pl-2.5`;\n // width extends by that inset on the right now that aside is `pr-0`.\n \"-ml-2.5 w-[calc(100%+0.625rem)] max-w-none box-border border-b\",\n isListScrolled ? \"border-[var(--oh-border)]\" : \"border-transparent\",\n )}\n >\n <div\n data-testid=\"older-conversations-summary\"\n className=\"flex min-w-0 flex-nowrap items-center gap-x-2 py-2 pl-4 pr-2.5 text-[var(--oh-muted)]\"\n >\n <span className=\"min-w-0 truncate text-sm font-medium text-[var(--oh-muted)]\">\n {t(I18nKey.SIDEBAR$CONVERSATIONS)}\n </span>\n <div className=\"ml-auto flex shrink-0 items-center gap-0.5\">\n <ConversationPanelNewThreadPicker\n backendKind={activeBackend.kind}\n />\n <ConversationPanelFilterMenu\n filterMenuOpen={filterMenuOpen}\n setFilterMenuOpen={setFilterMenuOpen}\n menuRef={filterMenuRef}\n backendKind={activeBackend.kind}\n organizeMode={organizeMode}\n setOrganizeMode={setOrganizeMode}\n conversationSort={conversationSort}\n setConversationSort={setConversationSort}\n threadScope={threadScope}\n setThreadScope={setThreadScope}\n showOlderConversations={showOlderConversations}\n toggleShowOlderConversations={toggleShowOlderConversations}\n showRepoBranchMetadata={showRepoBranchMetadata}\n toggleShowRepoBranchMetadata={toggleShowRepoBranchMetadata}\n showLlmProfiles={showLlmProfiles}\n toggleShowLlmProfiles={toggleShowLlmProfiles}\n showHoverMetadata={showHoverMetadata}\n toggleShowHoverMetadata={toggleShowHoverMetadata}\n totalConversationsCount={conversations.length}\n onRequestDeleteAll={() => setConfirmDeleteAllVisible(true)}\n />\n </div>\n </div>\n </div>\n )}\n\n <div\n ref={scrollContainerRef}\n data-testid=\"conversation-panel-list-scroll\"\n onScroll={(event) => {\n setIsListScrolled(event.currentTarget.scrollTop > 0);\n }}\n className={cn(\n \"flex min-h-0 flex-1 flex-col overflow-y-auto overflow-x-hidden overscroll-contain custom-scrollbar-always\",\n !compact && \"conversation-panel-list-scroll\",\n )}\n >\n {showInitialSkeleton && <ConversationCardSkeleton compact={compact} />}\n\n {!compact && showEmptyState && (\n <div\n data-testid=\"conversation-panel-empty-state\"\n className=\"flex min-h-0 flex-1 flex-col items-center justify-center px-4 py-8\"\n >\n <p className=\"text-xs text-[var(--oh-muted)]\">\n {t(I18nKey.CONVERSATION$NO_CONVERSATIONS)}\n </p>\n </div>\n )}\n\n {showPinnedSection ? (\n <ConversationPanelPinnedSection\n pinnedConversations={pinnedConversations}\n isPreviewExpanded={expandedPinnedPreview}\n onTogglePreviewExpanded={() =>\n setExpandedPinnedPreview((current) => !current)\n }\n activeConversationId={currentConversationId}\n showDivider={!compact && organizeMode === \"chronological\"}\n renderConversationCard={(conversation) =>\n renderConversationCard(conversation, { inPinnedSection: true })\n }\n />\n ) : null}\n\n {/* Render in-progress start tasks first (skipped in compact mode —\n their rich card layout doesn't fit in the icon rail). */}\n {!compact &&\n startTasks?.map((task) => (\n <NavigationLink\n key={task.id}\n to={`/conversations/task-${task.id}`}\n onClick={onClose}\n className=\"block\"\n >\n <StartTaskCard task={task} />\n </NavigationLink>\n ))}\n\n {!showInitialSkeleton && compact\n ? compactVisibleConversations.map((conversation) =>\n renderConversationCard(conversation),\n )\n : null}\n\n {!showInitialSkeleton &&\n !compact &&\n organizeMode === \"grouped\" &&\n orderedConversationGroups &&\n orderedConversationGroups.length > 0 ? (\n <ConversationGroupFolderList\n groups={orderedConversationGroups}\n groupIds={conversationGroupIds}\n groupFolderOrder={groupFolderOrder}\n setGroupFolderOrder={setGroupFolderOrder}\n collapsedGroupIds={collapsedGroupIds}\n expandedGroupPreviewIds={expandedGroupPreviewIds}\n onToggleGroupCollapsed={toggleGroupCollapsed}\n onToggleGroupPreviewExpanded={toggleGroupPreviewExpanded}\n isCreatingConversationFlow={isCreatingConversationFlow}\n activeConversationId={currentConversationId}\n onLaunchFromGroup={launchFromGroup}\n renderConversationCard={(conversation) =>\n renderConversationCard(conversation)\n }\n />\n ) : null}\n\n {!showInitialSkeleton &&\n !compact &&\n organizeMode === \"chronological\" ? (\n <div className=\"space-y-0.5\">\n {sortedVisibleConversations.map((conversation) =>\n renderConversationCard(conversation),\n )}\n </div>\n ) : null}\n\n {/* Explicit \"Load more\" trigger. Only shown when more pages exist\n *and* the older list is currently visible (or there are no older\n conversations to begin with) — otherwise the next page would be\n populated mostly with conversations the user has chosen to hide. */}\n {showLoadMore &&\n (isLoadingMore ? (\n <div className=\"py-1\">\n <ConversationCardSkeleton compact={compact} />\n </div>\n ) : (\n <div className=\"flex justify-center py-4\">\n <button\n type=\"button\"\n data-testid=\"load-more-conversations\"\n onClick={requestLoadMore}\n className=\"text-xs text-[var(--oh-muted)] hover:text-white\"\n >\n {t(I18nKey.CONVERSATION$LOAD_MORE)}\n </button>\n </div>\n ))}\n </div>\n\n {confirmDeleteModalVisible && (\n <ConfirmDeleteModal\n onConfirm={() => {\n handleConfirmDelete();\n setConfirmDeleteModalVisible(false);\n setSelectedConversationTitle(null);\n }}\n onCancel={() => {\n setConfirmDeleteModalVisible(false);\n setSelectedConversationTitle(null);\n }}\n conversationTitle={selectedConversationTitle ?? undefined}\n />\n )}\n\n {confirmDeleteAllVisible && (\n <ConfirmDeleteModal\n title={t(I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_TITLE)}\n description={t(I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_DESC, {\n count: conversations.length,\n })}\n onConfirm={async () => {\n await handleConfirmDeleteAll();\n setConfirmDeleteAllVisible(false);\n }}\n onCancel={() => setConfirmDeleteAllVisible(false)}\n />\n )}\n\n {confirmStopModalVisible && (\n <ConfirmStopModal\n onConfirm={() => {\n handleConfirmStop();\n setConfirmStopModalVisible(false);\n }}\n onCancel={() => setConfirmStopModalVisible(false)}\n />\n )}\n\n {confirmExitConversationModalVisible && (\n <ExitConversationModal\n onConfirm={() => {\n onClose?.();\n }}\n onClose={() => setConfirmExitConversationModalVisible(false)}\n onCancel={() => setConfirmExitConversationModalVisible(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"conversation-panel.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/conversation-panel.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tooltip } from \"@heroui/react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { usePaginatedConversations } from \"#/hooks/query/use-paginated-conversations\";\nimport { useStartTasks } from \"#/hooks/query/use-start-tasks\";\nimport { useDeleteConversation } from \"#/hooks/mutation/use-delete-conversation\";\nimport { useUnifiedPauseConversation } from \"#/hooks/mutation/use-unified-stop-conversation\";\nimport { ConfirmDeleteModal } from \"./confirm-delete-modal\";\nimport { ConfirmStopModal } from \"./confirm-stop-modal\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ExitConversationModal } from \"./exit-conversation-modal\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { Provider } from \"#/types/settings\";\nimport { useUpdateConversation } from \"#/hooks/mutation/use-update-conversation\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { isExecutionActive } from \"#/utils/status\";\nimport { useCreateConversation } from \"#/hooks/mutation/use-create-conversation\";\nimport { useIsCreatingConversation } from \"#/hooks/use-is-creating-conversation\";\nimport { ConversationCard } from \"./conversation-card/conversation-card\";\nimport { ConversationCardPreview } from \"./conversation-card/conversation-card-preview\";\nimport { StartTaskCard } from \"./start-task-card/start-task-card\";\nimport { ConversationCardSkeleton } from \"./conversation-card/conversation-card-skeleton\";\nimport { CompactConversationRow } from \"./compact-conversation-row\";\nimport { useConversationPanelPreferencesStore } from \"#/stores/conversation-panel-preferences-store\";\nimport { cn } from \"#/utils/utils\";\nimport { ConversationPanelFilterMenu } from \"./conversation-panel-filter-menu\";\nimport { ConversationPanelNewThreadPicker } from \"./conversation-panel-new-thread-picker\";\nimport { ConversationGroupFolderList } from \"./conversation-group-folder-list\";\nimport { ConversationPanelPinnedSection } from \"./conversation-panel-pinned-section\";\nimport {\n applyGroupFolderOrder,\n filterOutPinnedConversations,\n groupConversations,\n resolvePinnedConversations,\n sortConversationsByField,\n type ConversationGroupLaunch,\n} from \"./conversation-panel-list-helpers\";\nimport { usePinnedConversationsStore } from \"#/stores/pinned-conversations-store\";\n\ninterface ConversationPanelProps {\n onClose?: () => void;\n /**\n * Render a minimal icon-only variant of each conversation row (used by the\n * collapsed sidebar). Each row is a single status dot with a hover preview\n * containing the full card content.\n */\n compact?: boolean;\n}\n\nconst noop = () => {};\n\nconst EMPTY_PINNED_CONVERSATION_IDS: readonly string[] = [];\n\nconst ONE_HOUR_MS = 60 * 60 * 1000;\n\nconst partitionByCutoff = <T extends { updated_at: string }>(\n items: readonly T[],\n): { recent: T[]; older: T[] } => {\n // The cutoff is intentionally relative to \"now\" each time the list is\n // recomputed, so conversations naturally age into the older bucket as the\n // conversations query refreshes.\n const cutoff = Date.now() - ONE_HOUR_MS;\n const recent: T[] = [];\n const older: T[] = [];\n for (const item of items) {\n const updatedAt = item.updated_at ? Date.parse(item.updated_at) : NaN;\n // Missing or unparseable timestamps stay in the \"recent\" bucket so we\n // do not accidentally hide them behind the older-conversations toggle.\n if (Number.isFinite(updatedAt) && updatedAt < cutoff) {\n older.push(item);\n } else {\n recent.push(item);\n }\n }\n return { recent, older };\n};\n\nexport function ConversationPanel({\n onClose,\n compact = false,\n}: ConversationPanelProps) {\n const { t } = useTranslation(\"openhands\");\n const { conversationId: currentConversationId, navigate } = useNavigation();\n const { backend: activeBackend } = useActiveBackend();\n // Click-outside is only relevant in the legacy drawer mode where an\n // onClose handler is provided. When the panel is rendered inline (e.g.\n // as the always-visible conversation list pane), clicking outside should\n // not dismiss the list, so we pass a no-op callback in that case.\n const ref = useClickOutsideElement<HTMLDivElement>(onClose ?? noop);\n\n const [confirmDeleteModalVisible, setConfirmDeleteModalVisible] =\n React.useState(false);\n const [confirmStopModalVisible, setConfirmStopModalVisible] =\n React.useState(false);\n const [\n confirmExitConversationModalVisible,\n setConfirmExitConversationModalVisible,\n ] = React.useState(false);\n const [confirmDeleteAllVisible, setConfirmDeleteAllVisible] =\n React.useState(false);\n const showOlderConversations = useConversationPanelPreferencesStore(\n (state) => state.showOlderConversations,\n );\n const toggleShowOlderConversations = useConversationPanelPreferencesStore(\n (state) => state.toggleShowOlderConversations,\n );\n const showRepoBranchMetadata = useConversationPanelPreferencesStore(\n (state) => state.showRepoBranchMetadata,\n );\n const toggleShowRepoBranchMetadata = useConversationPanelPreferencesStore(\n (state) => state.toggleShowRepoBranchMetadata,\n );\n const showLlmProfiles = useConversationPanelPreferencesStore(\n (state) => state.showLlmProfiles,\n );\n const toggleShowLlmProfiles = useConversationPanelPreferencesStore(\n (state) => state.toggleShowLlmProfiles,\n );\n const showHoverMetadata = useConversationPanelPreferencesStore(\n (state) => state.showHoverMetadata,\n );\n const toggleShowHoverMetadata = useConversationPanelPreferencesStore(\n (state) => state.toggleShowHoverMetadata,\n );\n const organizeMode = useConversationPanelPreferencesStore(\n (state) => state.organizeMode,\n );\n const setOrganizeMode = useConversationPanelPreferencesStore(\n (state) => state.setOrganizeMode,\n );\n const conversationSort = useConversationPanelPreferencesStore(\n (state) => state.conversationSort,\n );\n const setConversationSort = useConversationPanelPreferencesStore(\n (state) => state.setConversationSort,\n );\n const threadScope = useConversationPanelPreferencesStore(\n (state) => state.threadScope,\n );\n const setThreadScope = useConversationPanelPreferencesStore(\n (state) => state.setThreadScope,\n );\n const groupFolderOrder = useConversationPanelPreferencesStore(\n (state) => state.groupFolderOrder,\n );\n const setGroupFolderOrder = useConversationPanelPreferencesStore(\n (state) => state.setGroupFolderOrder,\n );\n const [filterMenuOpen, setFilterMenuOpen] = React.useState(false);\n const [isListScrolled, setIsListScrolled] = React.useState(false);\n const filterMenuRef = useClickOutsideElement<HTMLDivElement>(() => {\n setFilterMenuOpen(false);\n });\n const [collapsedGroupIds, setCollapsedGroupIds] = React.useState<\n ReadonlySet<string>\n >(() => new Set());\n const [expandedGroupPreviewIds, setExpandedGroupPreviewIds] = React.useState<\n ReadonlySet<string>\n >(() => new Set());\n const [expandedPinnedPreview, setExpandedPinnedPreview] =\n React.useState(false);\n\n const pinnedIds = usePinnedConversationsStore(\n (state) =>\n state.pinsByBackendId[activeBackend.id] ?? EMPTY_PINNED_CONVERSATION_IDS,\n );\n const togglePin = usePinnedConversationsStore((state) => state.togglePin);\n const pruneMissingPinnedConversations = usePinnedConversationsStore(\n (state) => state.pruneMissingConversations,\n );\n\n const toggleGroupCollapsed = React.useCallback((groupId: string) => {\n setCollapsedGroupIds((prev) => {\n const next = new Set(prev);\n if (next.has(groupId)) {\n next.delete(groupId);\n } else {\n next.add(groupId);\n }\n return next;\n });\n }, []);\n\n const toggleGroupPreviewExpanded = React.useCallback((groupId: string) => {\n setExpandedGroupPreviewIds((prev) => {\n const next = new Set(prev);\n if (next.has(groupId)) {\n next.delete(groupId);\n } else {\n next.add(groupId);\n }\n return next;\n });\n }, []);\n\n React.useEffect(() => {\n if (organizeMode !== \"grouped\") {\n setCollapsedGroupIds(new Set());\n setExpandedGroupPreviewIds(new Set());\n }\n }, [organizeMode]);\n\n const scrollContainerRef = React.useRef<HTMLDivElement>(null);\n\n const [selectedConversationId, setSelectedConversationId] = React.useState<\n string | null\n >(null);\n const [selectedConversationTitle, setSelectedConversationTitle] =\n React.useState<string | null>(null);\n const [openContextMenuId, setOpenContextMenuId] = React.useState<\n string | null\n >(null);\n\n const {\n data,\n isLoading,\n isFetched,\n hasNextPage,\n isFetching,\n isFetchingNextPage,\n fetchNextPage,\n } = usePaginatedConversations();\n\n // Fetch in-progress start tasks\n const { data: startTasks } = useStartTasks();\n\n const conversations = React.useMemo(() => {\n const all = data?.pages.flatMap((page) => page.items) ?? [];\n // The 10s background refetch re-fetches every loaded page with the\n // `UPDATED_AT_DESC` cursor. If a conversation's `updated_at` shifts between\n // page fetches, a later page can overlap an earlier one and surface the\n // same conversation twice. Dedupe by id (keeping the first/freshest copy)\n // so the rendered count reflects real growth and React keys stay unique.\n const seen = new Set<string>();\n return all.filter((conversation) => {\n if (seen.has(conversation.id)) {\n return false;\n }\n seen.add(conversation.id);\n return true;\n });\n }, [data]);\n\n const pinnedConversations = React.useMemo(\n () => resolvePinnedConversations(pinnedIds, conversations),\n [conversations, pinnedIds],\n );\n\n React.useEffect(() => {\n if (!isFetched) {\n return;\n }\n pruneMissingPinnedConversations(\n activeBackend.id,\n conversations.map((conversation) => conversation.id),\n );\n }, [\n activeBackend.id,\n conversations,\n isFetched,\n pruneMissingPinnedConversations,\n ]);\n\n React.useEffect(() => {\n if (pinnedIds.length === 0) {\n setExpandedPinnedPreview(false);\n }\n }, [pinnedIds.length]);\n\n const scopedConversations = React.useMemo(() => {\n const scopeFiltered =\n threadScope === \"relevant\"\n ? conversations.filter((c) => isExecutionActive(c.execution_status))\n : conversations;\n\n // In the expanded panel, pinned conversations should only appear inside\n // the dedicated pinned section (not duplicated in grouped/flat lists).\n if (compact) {\n return scopeFiltered;\n }\n\n return filterOutPinnedConversations(scopeFiltered, pinnedIds);\n }, [compact, conversations, pinnedIds, threadScope]);\n\n const { recent: recentScoped, older: olderScoped } = React.useMemo(\n () => partitionByCutoff(scopedConversations),\n [scopedConversations],\n );\n\n // Sort the full visible set as one list. The recent/older partition is\n // still computed (it gates the \"Show older\" toggle and \"Load more\"\n // visibility), but the rendering must not use it as a visual boundary —\n // when sorting by `created`, a stale-but-recently-touched conversation\n // would otherwise land in `recent` and render above an actually-newer-\n // by-`created_at` conversation sitting in `older`.\n const sortedVisibleConversations = React.useMemo(() => {\n const visible = showOlderConversations\n ? [...recentScoped, ...olderScoped]\n : recentScoped;\n return sortConversationsByField(visible, conversationSort);\n }, [recentScoped, olderScoped, showOlderConversations, conversationSort]);\n\n const groupLabels = React.useMemo(\n () => ({\n emptyWorkspace: t(I18nKey.CONVERSATION_PANEL$NO_WORKSPACE),\n emptyRepository: t(I18nKey.CONVERSATION_PANEL$NO_REPOSITORY),\n }),\n [t],\n );\n\n const conversationGroups = React.useMemo(() => {\n if (compact || organizeMode !== \"grouped\") {\n return null;\n }\n // Use the unsorted partitions: groupConversations sorts each bucket\n // internally by `sortField`, so pre-sorting the merged input is wasted\n // work in grouped mode (the per-group sort overrides any global order).\n const merged = [\n ...recentScoped,\n ...(showOlderConversations ? olderScoped : []),\n ];\n return groupConversations(\n merged,\n activeBackend.kind,\n conversationSort,\n groupLabels,\n );\n }, [\n activeBackend.kind,\n compact,\n conversationSort,\n groupLabels,\n olderScoped,\n organizeMode,\n recentScoped,\n showOlderConversations,\n ]);\n\n const orderedConversationGroups = React.useMemo(() => {\n if (!conversationGroups) {\n return null;\n }\n return applyGroupFolderOrder(conversationGroups, groupFolderOrder);\n }, [conversationGroups, groupFolderOrder]);\n\n const conversationGroupIds = React.useMemo(\n () => conversationGroups?.map((group) => group.id) ?? [],\n [conversationGroups],\n );\n\n const compactVisibleConversations = React.useMemo(\n () =>\n sortConversationsByField(\n recentScoped.filter((conversation) =>\n isExecutionActive(conversation.execution_status),\n ),\n conversationSort,\n ),\n [conversationSort, recentScoped],\n );\n\n const visibleFlatCount = sortedVisibleConversations.length;\n\n const visibleGroupedCount = React.useMemo(() => {\n if (!orderedConversationGroups) {\n return 0;\n }\n return orderedConversationGroups.reduce(\n (n, g) => n + g.conversations.length,\n 0,\n );\n }, [orderedConversationGroups]);\n\n const listIsEffectivelyEmpty =\n organizeMode === \"grouped\" && !compact\n ? visibleGroupedCount === 0\n : visibleFlatCount === 0;\n\n // Number of conversations actually rendered in the list right now, in the\n // current organize mode. \"Load more\" succeeds only when this number grows.\n const visibleCount =\n organizeMode === \"grouped\" && !compact\n ? visibleGroupedCount\n : visibleFlatCount;\n\n // KNOWN ISSUE (unresolved as of 2026-05-29): users still report that the\n // sidebar \"Load more\" sometimes requires two clicks before new conversations\n // appear. The mitigation below (dedupe by id in `conversations`, plus the\n // floor-tracking driver that keeps fetching until the visible count grows)\n // reduced but did NOT fully eliminate the symptom in manual testing. Likely\n // remaining suspects to investigate next: the agent-server cursor pagination\n // returning an overlapping/short page under `UPDATED_AT_DESC` while the 10s\n // `refetchInterval` reorders pages (see `usePaginatedConversations`), or a\n // React Query state lag where `hasNextPage`/`isFetching` settle a render\n // after the click. If you pick this up, reproduce against a backend with\n // >40 conversations and watch the `/api/conversations/search` cursors.\n //\n // Robust \"Load more\" driver. A single click can fail to surface new rows for\n // two reasons: (1) `fetchNextPage()` is silently dropped while the 10s\n // background refetch is in flight, and (2) a fetched page can yield zero\n // *visible* rows (filtered out by the active scope, or deduped as overlap),\n // so the list does not appear to grow. We capture the visible count at click\n // time and keep fetching pages — once the query is idle — until the visible\n // count actually increases or there are no more pages.\n const [loadMoreFloor, setLoadMoreFloor] = React.useState<number | null>(null);\n const visibleCountRef = React.useRef(visibleCount);\n visibleCountRef.current = visibleCount;\n\n const requestLoadMore = React.useCallback(() => {\n if (hasNextPage) {\n setLoadMoreFloor(visibleCountRef.current);\n }\n }, [hasNextPage]);\n\n React.useEffect(() => {\n if (loadMoreFloor === null) {\n return;\n }\n // Goal met: the visible list grew past where it was when the user clicked.\n if (visibleCount > loadMoreFloor) {\n setLoadMoreFloor(null);\n return;\n }\n // Nothing more to fetch — stop waiting even if the list did not grow.\n if (!hasNextPage) {\n setLoadMoreFloor(null);\n return;\n }\n // Wait for any in-flight fetch (including the background refetch) to settle\n // before requesting the next page, otherwise the request is dropped.\n if (isFetching || isFetchingNextPage) {\n return;\n }\n fetchNextPage();\n }, [\n loadMoreFloor,\n visibleCount,\n hasNextPage,\n isFetching,\n isFetchingNextPage,\n fetchNextPage,\n ]);\n\n const isLoadingMore = loadMoreFloor !== null || isFetchingNextPage;\n\n const { mutate: deleteConversation, mutateAsync: deleteConversationAsync } =\n useDeleteConversation();\n const { mutate: pauseConversation } = useUnifiedPauseConversation();\n const { mutate: updateConversation } = useUpdateConversation();\n\n // The next page of conversations is loaded only via the explicit \"Load\n // more\" link rendered at the end of the list — there is no scroll-driven\n // pagination, which previously caused the panel to feel like it had stray\n // scrollable space at the bottom.\n const olderHidden = olderScoped.length > 0 && !showOlderConversations;\n // Compact mode also hides \"Load more\" — paginating into archived\n // conversations contradicts the \"active only\" intent of the icon rail.\n // Do not show when the visible list is empty (e.g. filters hide every\n // loaded conversation) — that state already shows \"No conversations found\".\n const showLoadMore =\n !!hasNextPage && !olderHidden && !compact && !listIsEffectivelyEmpty;\n\n const { mutate: createConversation } = useCreateConversation();\n const isCreatingConversationFlow = useIsCreatingConversation();\n\n const launchFromGroup = React.useCallback(\n (launch: ConversationGroupLaunch) => {\n if (isCreatingConversationFlow) return;\n createConversation(\n {\n workingDir: launch.workingDir,\n repository: launch.repository,\n entryPoint: \"sidebar_relaunch_project\",\n },\n {\n onSuccess: (data) => {\n navigate(`/conversations/${data.conversation_id}`);\n },\n },\n );\n },\n [createConversation, isCreatingConversationFlow, navigate],\n );\n\n const handleDeleteProject = React.useCallback(\n (conversationId: string, title: string) => {\n setConfirmDeleteModalVisible(true);\n setSelectedConversationId(conversationId);\n setSelectedConversationTitle(title);\n },\n [],\n );\n\n const handleStopConversation = React.useCallback((conversationId: string) => {\n setConfirmStopModalVisible(true);\n setSelectedConversationId(conversationId);\n }, []);\n\n const handleConversationTitleChange = React.useCallback(\n (conversationId: string, newTitle: string) => {\n updateConversation(\n { conversationId, newTitle },\n {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.CONVERSATION$TITLE_UPDATED));\n },\n },\n );\n },\n [t, updateConversation],\n );\n\n const handleConfirmDelete = () => {\n if (selectedConversationId) {\n deleteConversation(\n { conversationId: selectedConversationId },\n {\n onSuccess: () => {\n if (selectedConversationId === currentConversationId) {\n navigate(\"/conversations\");\n }\n },\n },\n );\n }\n };\n\n const handleConfirmStop = () => {\n if (selectedConversationId) {\n pauseConversation({\n conversationId: selectedConversationId,\n });\n }\n };\n\n const handleConfirmDeleteAll = async () => {\n const idsToDelete = conversations.map((c) => c.id);\n const results = await Promise.allSettled(\n idsToDelete.map((conversationId) =>\n deleteConversationAsync({ conversationId }),\n ),\n );\n\n const deletedIds = results.flatMap((result, index) =>\n result.status === \"fulfilled\" ? [idsToDelete[index]] : [],\n );\n const failedCount = results.length - deletedIds.length;\n\n if (\n currentConversationId !== null &&\n deletedIds.includes(currentConversationId)\n ) {\n navigate(\"/conversations\");\n }\n\n if (failedCount > 0) {\n displayErrorToast(\n `${failedCount} conversation${failedCount === 1 ? \"\" : \"s\"} could not be deleted.`,\n );\n }\n };\n\n const renderConversationCard = React.useCallback(\n (\n conversation: (typeof conversations)[number],\n options?: { inPinnedSection?: boolean },\n ) => {\n const isPinned = pinnedIds.includes(conversation.id);\n if (compact) {\n return (\n <CompactConversationRow\n key={conversation.id}\n conversationId={conversation.id}\n title={conversation.title ?? \"\"}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n lastUpdatedAt={conversation.updated_at}\n createdAt={conversation.created_at}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n isActive={conversation.id === currentConversationId}\n onClose={onClose}\n showRepositoryMetadata={showRepoBranchMetadata}\n llmModel={conversation.llm_model}\n showLlmProfiles={showLlmProfiles}\n agentKind={conversation.agent_kind}\n acpServer={conversation.acp_server}\n />\n );\n }\n return (\n <Tooltip\n key={conversation.id}\n placement=\"right-start\"\n delay={1000}\n closeDelay={100}\n isDisabled={\n !showHoverMetadata || openContextMenuId === conversation.id\n }\n disableAnimation={import.meta.env.MODE === \"test\"}\n className=\"rounded-xl border border-[var(--oh-border)] bg-base-secondary p-0 text-white shadow-xl\"\n content={\n <ConversationCardPreview\n title={conversation.title ?? \"\"}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n llmModel={conversation.llm_model}\n createdAt={conversation.created_at}\n />\n }\n >\n <NavigationLink\n to={`/conversations/${conversation.id}`}\n onClick={onClose}\n className={cn(\n \"block rounded-md transition-colors\",\n openContextMenuId !== conversation.id &&\n \"hover:bg-[var(--oh-surface)]\",\n (conversation.id === currentConversationId ||\n openContextMenuId === conversation.id) &&\n \"bg-[var(--oh-surface)]\",\n )}\n >\n <ConversationCard\n onDelete={() =>\n handleDeleteProject(conversation.id, conversation.title ?? \"\")\n }\n onStop={() => handleStopConversation(conversation.id)}\n onChangeTitle={(title) =>\n handleConversationTitleChange(conversation.id, title)\n }\n title={conversation.title ?? \"\"}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n lastUpdatedAt={conversation.updated_at}\n createdAt={conversation.created_at}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n conversationId={conversation.id}\n contextMenuOpen={openContextMenuId === conversation.id}\n onContextMenuToggle={(isOpen) =>\n setOpenContextMenuId(isOpen ? conversation.id : null)\n }\n isActive={conversation.id === currentConversationId}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n showRepositoryMetadata={showRepoBranchMetadata}\n llmModel={conversation.llm_model}\n showLlmProfiles={showLlmProfiles}\n agentKind={conversation.agent_kind}\n acpServer={conversation.acp_server}\n isPinned={isPinned}\n onTogglePin={() => togglePin(activeBackend.id, conversation.id)}\n alwaysShowPinIcon={isPinned && !options?.inPinnedSection}\n />\n </NavigationLink>\n </Tooltip>\n );\n },\n [\n activeBackend.id,\n compact,\n currentConversationId,\n handleConversationTitleChange,\n handleDeleteProject,\n handleStopConversation,\n onClose,\n openContextMenuId,\n pinnedIds,\n showRepoBranchMetadata,\n showLlmProfiles,\n showHoverMetadata,\n togglePin,\n ],\n );\n\n // Standard layout: panel fills its slot in the sidebar; the inner scroll\n // child fills the panel and scrolls when its content overflows. Modals are\n // siblings of the scroll element and are `position: fixed`, so they don't\n // participate in the panel's scroll geometry.\n // Gate on `isLoading` / `!isFetched` (true only until the first fetch settles),\n // not `isFetching` — the latter flips back to true on every 10s background\n // refetch, causing the skeleton/empty-state to flicker when the list is empty.\n const showInitialSkeleton = isLoading || !isFetched;\n const showPinnedSection =\n !compact && !showInitialSkeleton && pinnedConversations.length > 0;\n const showEmptyState =\n isFetched &&\n !isLoading &&\n !compact &&\n listIsEffectivelyEmpty &&\n !showPinnedSection &&\n !startTasks?.length;\n\n const showConversationHeader = !compact;\n\n return (\n <div\n ref={ref}\n data-testid=\"conversation-panel\"\n className=\"flex h-full min-h-0 w-full flex-col\"\n >\n {showConversationHeader && (\n <div\n className={cn(\n // Pull flush to the sidebar edges: `-ml-2.5` matches aside `pl-2.5`;\n // width extends by that inset on the right now that aside is `pr-0`.\n \"-ml-2.5 w-[calc(100%+0.625rem)] max-w-none box-border border-b\",\n isListScrolled ? \"border-[var(--oh-border)]\" : \"border-transparent\",\n )}\n >\n <div\n data-testid=\"older-conversations-summary\"\n className=\"flex min-w-0 flex-nowrap items-center gap-x-2 py-2 pl-4 pr-2.5 text-[var(--oh-muted)]\"\n >\n <span className=\"min-w-0 truncate text-sm font-medium text-[var(--oh-muted)]\">\n {t(I18nKey.SIDEBAR$CONVERSATIONS)}\n </span>\n <div className=\"ml-auto flex shrink-0 items-center gap-0.5\">\n <ConversationPanelNewThreadPicker\n backendKind={activeBackend.kind}\n />\n <ConversationPanelFilterMenu\n filterMenuOpen={filterMenuOpen}\n setFilterMenuOpen={setFilterMenuOpen}\n menuRef={filterMenuRef}\n backendKind={activeBackend.kind}\n organizeMode={organizeMode}\n setOrganizeMode={setOrganizeMode}\n conversationSort={conversationSort}\n setConversationSort={setConversationSort}\n threadScope={threadScope}\n setThreadScope={setThreadScope}\n showOlderConversations={showOlderConversations}\n toggleShowOlderConversations={toggleShowOlderConversations}\n showRepoBranchMetadata={showRepoBranchMetadata}\n toggleShowRepoBranchMetadata={toggleShowRepoBranchMetadata}\n showLlmProfiles={showLlmProfiles}\n toggleShowLlmProfiles={toggleShowLlmProfiles}\n showHoverMetadata={showHoverMetadata}\n toggleShowHoverMetadata={toggleShowHoverMetadata}\n totalConversationsCount={conversations.length}\n onRequestDeleteAll={() => setConfirmDeleteAllVisible(true)}\n />\n </div>\n </div>\n </div>\n )}\n\n <div\n ref={scrollContainerRef}\n data-testid=\"conversation-panel-list-scroll\"\n onScroll={(event) => {\n setIsListScrolled(event.currentTarget.scrollTop > 0);\n }}\n className={cn(\n \"flex min-h-0 flex-1 flex-col overflow-y-auto overflow-x-hidden overscroll-contain custom-scrollbar-always\",\n !compact && \"conversation-panel-list-scroll\",\n )}\n >\n {showInitialSkeleton && <ConversationCardSkeleton compact={compact} />}\n\n {!compact && showEmptyState && (\n <div\n data-testid=\"conversation-panel-empty-state\"\n className=\"flex min-h-0 flex-1 flex-col items-center justify-center px-4 py-8\"\n >\n <p className=\"text-xs text-[var(--oh-muted)]\">\n {t(I18nKey.CONVERSATION$NO_CONVERSATIONS)}\n </p>\n </div>\n )}\n\n {showPinnedSection ? (\n <ConversationPanelPinnedSection\n pinnedConversations={pinnedConversations}\n isPreviewExpanded={expandedPinnedPreview}\n onTogglePreviewExpanded={() =>\n setExpandedPinnedPreview((current) => !current)\n }\n activeConversationId={currentConversationId}\n showDivider={!compact && organizeMode === \"chronological\"}\n renderConversationCard={(conversation) =>\n renderConversationCard(conversation, { inPinnedSection: true })\n }\n />\n ) : null}\n\n {/* Render in-progress start tasks first (skipped in compact mode —\n their rich card layout doesn't fit in the icon rail). */}\n {!compact &&\n startTasks?.map((task) => (\n <NavigationLink\n key={task.id}\n to={`/conversations/task-${task.id}`}\n onClick={onClose}\n className=\"block\"\n >\n <StartTaskCard task={task} />\n </NavigationLink>\n ))}\n\n {!showInitialSkeleton && compact\n ? compactVisibleConversations.map((conversation) =>\n renderConversationCard(conversation),\n )\n : null}\n\n {!showInitialSkeleton &&\n !compact &&\n organizeMode === \"grouped\" &&\n orderedConversationGroups &&\n orderedConversationGroups.length > 0 ? (\n <ConversationGroupFolderList\n groups={orderedConversationGroups}\n groupIds={conversationGroupIds}\n groupFolderOrder={groupFolderOrder}\n setGroupFolderOrder={setGroupFolderOrder}\n collapsedGroupIds={collapsedGroupIds}\n expandedGroupPreviewIds={expandedGroupPreviewIds}\n onToggleGroupCollapsed={toggleGroupCollapsed}\n onToggleGroupPreviewExpanded={toggleGroupPreviewExpanded}\n isCreatingConversationFlow={isCreatingConversationFlow}\n activeConversationId={currentConversationId}\n onLaunchFromGroup={launchFromGroup}\n renderConversationCard={(conversation) =>\n renderConversationCard(conversation)\n }\n />\n ) : null}\n\n {!showInitialSkeleton &&\n !compact &&\n organizeMode === \"chronological\" ? (\n <div className=\"space-y-0.5\">\n {sortedVisibleConversations.map((conversation) =>\n renderConversationCard(conversation),\n )}\n </div>\n ) : null}\n\n {/* Explicit \"Load more\" trigger. Only shown when more pages exist\n *and* the older list is currently visible (or there are no older\n conversations to begin with) — otherwise the next page would be\n populated mostly with conversations the user has chosen to hide. */}\n {showLoadMore &&\n (isLoadingMore ? (\n <div className=\"py-1\">\n <ConversationCardSkeleton compact={compact} />\n </div>\n ) : (\n <div className=\"flex justify-center py-4\">\n <button\n type=\"button\"\n data-testid=\"load-more-conversations\"\n onClick={requestLoadMore}\n className=\"text-xs text-[var(--oh-muted)] hover:text-white\"\n >\n {t(I18nKey.CONVERSATION$LOAD_MORE)}\n </button>\n </div>\n ))}\n </div>\n\n {confirmDeleteModalVisible && (\n <ConfirmDeleteModal\n onConfirm={() => {\n handleConfirmDelete();\n setConfirmDeleteModalVisible(false);\n setSelectedConversationTitle(null);\n }}\n onCancel={() => {\n setConfirmDeleteModalVisible(false);\n setSelectedConversationTitle(null);\n }}\n conversationTitle={selectedConversationTitle ?? undefined}\n />\n )}\n\n {confirmDeleteAllVisible && (\n <ConfirmDeleteModal\n title={t(I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_TITLE)}\n description={t(I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_DESC, {\n count: conversations.length,\n })}\n onConfirm={async () => {\n await handleConfirmDeleteAll();\n setConfirmDeleteAllVisible(false);\n }}\n onCancel={() => setConfirmDeleteAllVisible(false)}\n />\n )}\n\n {confirmStopModalVisible && (\n <ConfirmStopModal\n onConfirm={() => {\n handleConfirmStop();\n setConfirmStopModalVisible(false);\n }}\n onCancel={() => setConfirmStopModalVisible(false)}\n />\n )}\n\n {confirmExitConversationModalVisible && (\n <ExitConversationModal\n onConfirm={() => {\n onClose?.();\n }}\n onClose={() => setConfirmExitConversationModalVisible(false)}\n onCancel={() => setConfirmExitConversationModalVisible(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -128,7 +128,8 @@ function p({ onClose: f, compact: p = !1 }) {
128
128
  let bt = J !== null || V, { mutate: xt, mutateAsync: St } = se(), { mutate: Ct } = ce(), { mutate: wt } = le(), Tt = W.length > 0 && !S, Et = !!B && !Tt && !p && !_t, { mutate: Dt } = ae(), X = me(), Ot = l.useCallback((e) => {
129
129
  X || Dt({
130
130
  workingDir: e.workingDir,
131
- repository: e.repository
131
+ repository: e.repository,
132
+ entryPoint: "sidebar_relaunch_project"
132
133
  }, { onSuccess: (e) => {
133
134
  g(`/conversations/${e.conversation_id}`);
134
135
  } });
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-panel.js","names":[],"sources":["../../../../src/components/features/conversation-panel/conversation-panel.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tooltip } from \"@heroui/react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { usePaginatedConversations } from \"#/hooks/query/use-paginated-conversations\";\nimport { useStartTasks } from \"#/hooks/query/use-start-tasks\";\nimport { useDeleteConversation } from \"#/hooks/mutation/use-delete-conversation\";\nimport { useUnifiedPauseConversation } from \"#/hooks/mutation/use-unified-stop-conversation\";\nimport { ConfirmDeleteModal } from \"./confirm-delete-modal\";\nimport { ConfirmStopModal } from \"./confirm-stop-modal\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ExitConversationModal } from \"./exit-conversation-modal\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { Provider } from \"#/types/settings\";\nimport { useUpdateConversation } from \"#/hooks/mutation/use-update-conversation\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { isExecutionActive } from \"#/utils/status\";\nimport { useCreateConversation } from \"#/hooks/mutation/use-create-conversation\";\nimport { useIsCreatingConversation } from \"#/hooks/use-is-creating-conversation\";\nimport { ConversationCard } from \"./conversation-card/conversation-card\";\nimport { ConversationCardPreview } from \"./conversation-card/conversation-card-preview\";\nimport { StartTaskCard } from \"./start-task-card/start-task-card\";\nimport { ConversationCardSkeleton } from \"./conversation-card/conversation-card-skeleton\";\nimport { CompactConversationRow } from \"./compact-conversation-row\";\nimport { useConversationPanelPreferencesStore } from \"#/stores/conversation-panel-preferences-store\";\nimport { cn } from \"#/utils/utils\";\nimport { ConversationPanelFilterMenu } from \"./conversation-panel-filter-menu\";\nimport { ConversationPanelNewThreadPicker } from \"./conversation-panel-new-thread-picker\";\nimport { ConversationGroupFolderList } from \"./conversation-group-folder-list\";\nimport { ConversationPanelPinnedSection } from \"./conversation-panel-pinned-section\";\nimport {\n applyGroupFolderOrder,\n filterOutPinnedConversations,\n groupConversations,\n resolvePinnedConversations,\n sortConversationsByField,\n type ConversationGroupLaunch,\n} from \"./conversation-panel-list-helpers\";\nimport { usePinnedConversationsStore } from \"#/stores/pinned-conversations-store\";\n\ninterface ConversationPanelProps {\n onClose?: () => void;\n /**\n * Render a minimal icon-only variant of each conversation row (used by the\n * collapsed sidebar). Each row is a single status dot with a hover preview\n * containing the full card content.\n */\n compact?: boolean;\n}\n\nconst noop = () => {};\n\nconst EMPTY_PINNED_CONVERSATION_IDS: readonly string[] = [];\n\nconst ONE_HOUR_MS = 60 * 60 * 1000;\n\nconst partitionByCutoff = <T extends { updated_at: string }>(\n items: readonly T[],\n): { recent: T[]; older: T[] } => {\n // The cutoff is intentionally relative to \"now\" each time the list is\n // recomputed, so conversations naturally age into the older bucket as the\n // conversations query refreshes.\n const cutoff = Date.now() - ONE_HOUR_MS;\n const recent: T[] = [];\n const older: T[] = [];\n for (const item of items) {\n const updatedAt = item.updated_at ? Date.parse(item.updated_at) : NaN;\n // Missing or unparseable timestamps stay in the \"recent\" bucket so we\n // do not accidentally hide them behind the older-conversations toggle.\n if (Number.isFinite(updatedAt) && updatedAt < cutoff) {\n older.push(item);\n } else {\n recent.push(item);\n }\n }\n return { recent, older };\n};\n\nexport function ConversationPanel({\n onClose,\n compact = false,\n}: ConversationPanelProps) {\n const { t } = useTranslation(\"openhands\");\n const { conversationId: currentConversationId, navigate } = useNavigation();\n const { backend: activeBackend } = useActiveBackend();\n // Click-outside is only relevant in the legacy drawer mode where an\n // onClose handler is provided. When the panel is rendered inline (e.g.\n // as the always-visible conversation list pane), clicking outside should\n // not dismiss the list, so we pass a no-op callback in that case.\n const ref = useClickOutsideElement<HTMLDivElement>(onClose ?? noop);\n\n const [confirmDeleteModalVisible, setConfirmDeleteModalVisible] =\n React.useState(false);\n const [confirmStopModalVisible, setConfirmStopModalVisible] =\n React.useState(false);\n const [\n confirmExitConversationModalVisible,\n setConfirmExitConversationModalVisible,\n ] = React.useState(false);\n const [confirmDeleteAllVisible, setConfirmDeleteAllVisible] =\n React.useState(false);\n const showOlderConversations = useConversationPanelPreferencesStore(\n (state) => state.showOlderConversations,\n );\n const toggleShowOlderConversations = useConversationPanelPreferencesStore(\n (state) => state.toggleShowOlderConversations,\n );\n const showRepoBranchMetadata = useConversationPanelPreferencesStore(\n (state) => state.showRepoBranchMetadata,\n );\n const toggleShowRepoBranchMetadata = useConversationPanelPreferencesStore(\n (state) => state.toggleShowRepoBranchMetadata,\n );\n const showLlmProfiles = useConversationPanelPreferencesStore(\n (state) => state.showLlmProfiles,\n );\n const toggleShowLlmProfiles = useConversationPanelPreferencesStore(\n (state) => state.toggleShowLlmProfiles,\n );\n const showHoverMetadata = useConversationPanelPreferencesStore(\n (state) => state.showHoverMetadata,\n );\n const toggleShowHoverMetadata = useConversationPanelPreferencesStore(\n (state) => state.toggleShowHoverMetadata,\n );\n const organizeMode = useConversationPanelPreferencesStore(\n (state) => state.organizeMode,\n );\n const setOrganizeMode = useConversationPanelPreferencesStore(\n (state) => state.setOrganizeMode,\n );\n const conversationSort = useConversationPanelPreferencesStore(\n (state) => state.conversationSort,\n );\n const setConversationSort = useConversationPanelPreferencesStore(\n (state) => state.setConversationSort,\n );\n const threadScope = useConversationPanelPreferencesStore(\n (state) => state.threadScope,\n );\n const setThreadScope = useConversationPanelPreferencesStore(\n (state) => state.setThreadScope,\n );\n const groupFolderOrder = useConversationPanelPreferencesStore(\n (state) => state.groupFolderOrder,\n );\n const setGroupFolderOrder = useConversationPanelPreferencesStore(\n (state) => state.setGroupFolderOrder,\n );\n const [filterMenuOpen, setFilterMenuOpen] = React.useState(false);\n const [isListScrolled, setIsListScrolled] = React.useState(false);\n const filterMenuRef = useClickOutsideElement<HTMLDivElement>(() => {\n setFilterMenuOpen(false);\n });\n const [collapsedGroupIds, setCollapsedGroupIds] = React.useState<\n ReadonlySet<string>\n >(() => new Set());\n const [expandedGroupPreviewIds, setExpandedGroupPreviewIds] = React.useState<\n ReadonlySet<string>\n >(() => new Set());\n const [expandedPinnedPreview, setExpandedPinnedPreview] =\n React.useState(false);\n\n const pinnedIds = usePinnedConversationsStore(\n (state) =>\n state.pinsByBackendId[activeBackend.id] ?? EMPTY_PINNED_CONVERSATION_IDS,\n );\n const togglePin = usePinnedConversationsStore((state) => state.togglePin);\n const pruneMissingPinnedConversations = usePinnedConversationsStore(\n (state) => state.pruneMissingConversations,\n );\n\n const toggleGroupCollapsed = React.useCallback((groupId: string) => {\n setCollapsedGroupIds((prev) => {\n const next = new Set(prev);\n if (next.has(groupId)) {\n next.delete(groupId);\n } else {\n next.add(groupId);\n }\n return next;\n });\n }, []);\n\n const toggleGroupPreviewExpanded = React.useCallback((groupId: string) => {\n setExpandedGroupPreviewIds((prev) => {\n const next = new Set(prev);\n if (next.has(groupId)) {\n next.delete(groupId);\n } else {\n next.add(groupId);\n }\n return next;\n });\n }, []);\n\n React.useEffect(() => {\n if (organizeMode !== \"grouped\") {\n setCollapsedGroupIds(new Set());\n setExpandedGroupPreviewIds(new Set());\n }\n }, [organizeMode]);\n\n const scrollContainerRef = React.useRef<HTMLDivElement>(null);\n\n const [selectedConversationId, setSelectedConversationId] = React.useState<\n string | null\n >(null);\n const [selectedConversationTitle, setSelectedConversationTitle] =\n React.useState<string | null>(null);\n const [openContextMenuId, setOpenContextMenuId] = React.useState<\n string | null\n >(null);\n\n const {\n data,\n isLoading,\n isFetched,\n hasNextPage,\n isFetching,\n isFetchingNextPage,\n fetchNextPage,\n } = usePaginatedConversations();\n\n // Fetch in-progress start tasks\n const { data: startTasks } = useStartTasks();\n\n const conversations = React.useMemo(() => {\n const all = data?.pages.flatMap((page) => page.items) ?? [];\n // The 10s background refetch re-fetches every loaded page with the\n // `UPDATED_AT_DESC` cursor. If a conversation's `updated_at` shifts between\n // page fetches, a later page can overlap an earlier one and surface the\n // same conversation twice. Dedupe by id (keeping the first/freshest copy)\n // so the rendered count reflects real growth and React keys stay unique.\n const seen = new Set<string>();\n return all.filter((conversation) => {\n if (seen.has(conversation.id)) {\n return false;\n }\n seen.add(conversation.id);\n return true;\n });\n }, [data]);\n\n const pinnedConversations = React.useMemo(\n () => resolvePinnedConversations(pinnedIds, conversations),\n [conversations, pinnedIds],\n );\n\n React.useEffect(() => {\n if (!isFetched) {\n return;\n }\n pruneMissingPinnedConversations(\n activeBackend.id,\n conversations.map((conversation) => conversation.id),\n );\n }, [\n activeBackend.id,\n conversations,\n isFetched,\n pruneMissingPinnedConversations,\n ]);\n\n React.useEffect(() => {\n if (pinnedIds.length === 0) {\n setExpandedPinnedPreview(false);\n }\n }, [pinnedIds.length]);\n\n const scopedConversations = React.useMemo(() => {\n const scopeFiltered =\n threadScope === \"relevant\"\n ? conversations.filter((c) => isExecutionActive(c.execution_status))\n : conversations;\n\n // In the expanded panel, pinned conversations should only appear inside\n // the dedicated pinned section (not duplicated in grouped/flat lists).\n if (compact) {\n return scopeFiltered;\n }\n\n return filterOutPinnedConversations(scopeFiltered, pinnedIds);\n }, [compact, conversations, pinnedIds, threadScope]);\n\n const { recent: recentScoped, older: olderScoped } = React.useMemo(\n () => partitionByCutoff(scopedConversations),\n [scopedConversations],\n );\n\n // Sort the full visible set as one list. The recent/older partition is\n // still computed (it gates the \"Show older\" toggle and \"Load more\"\n // visibility), but the rendering must not use it as a visual boundary —\n // when sorting by `created`, a stale-but-recently-touched conversation\n // would otherwise land in `recent` and render above an actually-newer-\n // by-`created_at` conversation sitting in `older`.\n const sortedVisibleConversations = React.useMemo(() => {\n const visible = showOlderConversations\n ? [...recentScoped, ...olderScoped]\n : recentScoped;\n return sortConversationsByField(visible, conversationSort);\n }, [recentScoped, olderScoped, showOlderConversations, conversationSort]);\n\n const groupLabels = React.useMemo(\n () => ({\n emptyWorkspace: t(I18nKey.CONVERSATION_PANEL$NO_WORKSPACE),\n emptyRepository: t(I18nKey.CONVERSATION_PANEL$NO_REPOSITORY),\n }),\n [t],\n );\n\n const conversationGroups = React.useMemo(() => {\n if (compact || organizeMode !== \"grouped\") {\n return null;\n }\n // Use the unsorted partitions: groupConversations sorts each bucket\n // internally by `sortField`, so pre-sorting the merged input is wasted\n // work in grouped mode (the per-group sort overrides any global order).\n const merged = [\n ...recentScoped,\n ...(showOlderConversations ? olderScoped : []),\n ];\n return groupConversations(\n merged,\n activeBackend.kind,\n conversationSort,\n groupLabels,\n );\n }, [\n activeBackend.kind,\n compact,\n conversationSort,\n groupLabels,\n olderScoped,\n organizeMode,\n recentScoped,\n showOlderConversations,\n ]);\n\n const orderedConversationGroups = React.useMemo(() => {\n if (!conversationGroups) {\n return null;\n }\n return applyGroupFolderOrder(conversationGroups, groupFolderOrder);\n }, [conversationGroups, groupFolderOrder]);\n\n const conversationGroupIds = React.useMemo(\n () => conversationGroups?.map((group) => group.id) ?? [],\n [conversationGroups],\n );\n\n const compactVisibleConversations = React.useMemo(\n () =>\n sortConversationsByField(\n recentScoped.filter((conversation) =>\n isExecutionActive(conversation.execution_status),\n ),\n conversationSort,\n ),\n [conversationSort, recentScoped],\n );\n\n const visibleFlatCount = sortedVisibleConversations.length;\n\n const visibleGroupedCount = React.useMemo(() => {\n if (!orderedConversationGroups) {\n return 0;\n }\n return orderedConversationGroups.reduce(\n (n, g) => n + g.conversations.length,\n 0,\n );\n }, [orderedConversationGroups]);\n\n const listIsEffectivelyEmpty =\n organizeMode === \"grouped\" && !compact\n ? visibleGroupedCount === 0\n : visibleFlatCount === 0;\n\n // Number of conversations actually rendered in the list right now, in the\n // current organize mode. \"Load more\" succeeds only when this number grows.\n const visibleCount =\n organizeMode === \"grouped\" && !compact\n ? visibleGroupedCount\n : visibleFlatCount;\n\n // KNOWN ISSUE (unresolved as of 2026-05-29): users still report that the\n // sidebar \"Load more\" sometimes requires two clicks before new conversations\n // appear. The mitigation below (dedupe by id in `conversations`, plus the\n // floor-tracking driver that keeps fetching until the visible count grows)\n // reduced but did NOT fully eliminate the symptom in manual testing. Likely\n // remaining suspects to investigate next: the agent-server cursor pagination\n // returning an overlapping/short page under `UPDATED_AT_DESC` while the 10s\n // `refetchInterval` reorders pages (see `usePaginatedConversations`), or a\n // React Query state lag where `hasNextPage`/`isFetching` settle a render\n // after the click. If you pick this up, reproduce against a backend with\n // >40 conversations and watch the `/api/conversations/search` cursors.\n //\n // Robust \"Load more\" driver. A single click can fail to surface new rows for\n // two reasons: (1) `fetchNextPage()` is silently dropped while the 10s\n // background refetch is in flight, and (2) a fetched page can yield zero\n // *visible* rows (filtered out by the active scope, or deduped as overlap),\n // so the list does not appear to grow. We capture the visible count at click\n // time and keep fetching pages — once the query is idle — until the visible\n // count actually increases or there are no more pages.\n const [loadMoreFloor, setLoadMoreFloor] = React.useState<number | null>(null);\n const visibleCountRef = React.useRef(visibleCount);\n visibleCountRef.current = visibleCount;\n\n const requestLoadMore = React.useCallback(() => {\n if (hasNextPage) {\n setLoadMoreFloor(visibleCountRef.current);\n }\n }, [hasNextPage]);\n\n React.useEffect(() => {\n if (loadMoreFloor === null) {\n return;\n }\n // Goal met: the visible list grew past where it was when the user clicked.\n if (visibleCount > loadMoreFloor) {\n setLoadMoreFloor(null);\n return;\n }\n // Nothing more to fetch — stop waiting even if the list did not grow.\n if (!hasNextPage) {\n setLoadMoreFloor(null);\n return;\n }\n // Wait for any in-flight fetch (including the background refetch) to settle\n // before requesting the next page, otherwise the request is dropped.\n if (isFetching || isFetchingNextPage) {\n return;\n }\n fetchNextPage();\n }, [\n loadMoreFloor,\n visibleCount,\n hasNextPage,\n isFetching,\n isFetchingNextPage,\n fetchNextPage,\n ]);\n\n const isLoadingMore = loadMoreFloor !== null || isFetchingNextPage;\n\n const { mutate: deleteConversation, mutateAsync: deleteConversationAsync } =\n useDeleteConversation();\n const { mutate: pauseConversation } = useUnifiedPauseConversation();\n const { mutate: updateConversation } = useUpdateConversation();\n\n // The next page of conversations is loaded only via the explicit \"Load\n // more\" link rendered at the end of the list — there is no scroll-driven\n // pagination, which previously caused the panel to feel like it had stray\n // scrollable space at the bottom.\n const olderHidden = olderScoped.length > 0 && !showOlderConversations;\n // Compact mode also hides \"Load more\" — paginating into archived\n // conversations contradicts the \"active only\" intent of the icon rail.\n // Do not show when the visible list is empty (e.g. filters hide every\n // loaded conversation) — that state already shows \"No conversations found\".\n const showLoadMore =\n !!hasNextPage && !olderHidden && !compact && !listIsEffectivelyEmpty;\n\n const { mutate: createConversation } = useCreateConversation();\n const isCreatingConversationFlow = useIsCreatingConversation();\n\n const launchFromGroup = React.useCallback(\n (launch: ConversationGroupLaunch) => {\n if (isCreatingConversationFlow) return;\n createConversation(\n {\n workingDir: launch.workingDir,\n repository: launch.repository,\n },\n {\n onSuccess: (data) => {\n navigate(`/conversations/${data.conversation_id}`);\n },\n },\n );\n },\n [createConversation, isCreatingConversationFlow, navigate],\n );\n\n const handleDeleteProject = React.useCallback(\n (conversationId: string, title: string) => {\n setConfirmDeleteModalVisible(true);\n setSelectedConversationId(conversationId);\n setSelectedConversationTitle(title);\n },\n [],\n );\n\n const handleStopConversation = React.useCallback((conversationId: string) => {\n setConfirmStopModalVisible(true);\n setSelectedConversationId(conversationId);\n }, []);\n\n const handleConversationTitleChange = React.useCallback(\n (conversationId: string, newTitle: string) => {\n updateConversation(\n { conversationId, newTitle },\n {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.CONVERSATION$TITLE_UPDATED));\n },\n },\n );\n },\n [t, updateConversation],\n );\n\n const handleConfirmDelete = () => {\n if (selectedConversationId) {\n deleteConversation(\n { conversationId: selectedConversationId },\n {\n onSuccess: () => {\n if (selectedConversationId === currentConversationId) {\n navigate(\"/conversations\");\n }\n },\n },\n );\n }\n };\n\n const handleConfirmStop = () => {\n if (selectedConversationId) {\n pauseConversation({\n conversationId: selectedConversationId,\n });\n }\n };\n\n const handleConfirmDeleteAll = async () => {\n const idsToDelete = conversations.map((c) => c.id);\n const results = await Promise.allSettled(\n idsToDelete.map((conversationId) =>\n deleteConversationAsync({ conversationId }),\n ),\n );\n\n const deletedIds = results.flatMap((result, index) =>\n result.status === \"fulfilled\" ? [idsToDelete[index]] : [],\n );\n const failedCount = results.length - deletedIds.length;\n\n if (\n currentConversationId !== null &&\n deletedIds.includes(currentConversationId)\n ) {\n navigate(\"/conversations\");\n }\n\n if (failedCount > 0) {\n displayErrorToast(\n `${failedCount} conversation${failedCount === 1 ? \"\" : \"s\"} could not be deleted.`,\n );\n }\n };\n\n const renderConversationCard = React.useCallback(\n (\n conversation: (typeof conversations)[number],\n options?: { inPinnedSection?: boolean },\n ) => {\n const isPinned = pinnedIds.includes(conversation.id);\n if (compact) {\n return (\n <CompactConversationRow\n key={conversation.id}\n conversationId={conversation.id}\n title={conversation.title ?? \"\"}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n lastUpdatedAt={conversation.updated_at}\n createdAt={conversation.created_at}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n isActive={conversation.id === currentConversationId}\n onClose={onClose}\n showRepositoryMetadata={showRepoBranchMetadata}\n llmModel={conversation.llm_model}\n showLlmProfiles={showLlmProfiles}\n agentKind={conversation.agent_kind}\n acpServer={conversation.acp_server}\n />\n );\n }\n return (\n <Tooltip\n key={conversation.id}\n placement=\"right-start\"\n delay={1000}\n closeDelay={100}\n isDisabled={\n !showHoverMetadata || openContextMenuId === conversation.id\n }\n disableAnimation={import.meta.env.MODE === \"test\"}\n className=\"rounded-xl border border-[var(--oh-border)] bg-base-secondary p-0 text-white shadow-xl\"\n content={\n <ConversationCardPreview\n title={conversation.title ?? \"\"}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n llmModel={conversation.llm_model}\n createdAt={conversation.created_at}\n />\n }\n >\n <NavigationLink\n to={`/conversations/${conversation.id}`}\n onClick={onClose}\n className={cn(\n \"block rounded-md transition-colors\",\n openContextMenuId !== conversation.id &&\n \"hover:bg-[var(--oh-surface)]\",\n (conversation.id === currentConversationId ||\n openContextMenuId === conversation.id) &&\n \"bg-[var(--oh-surface)]\",\n )}\n >\n <ConversationCard\n onDelete={() =>\n handleDeleteProject(conversation.id, conversation.title ?? \"\")\n }\n onStop={() => handleStopConversation(conversation.id)}\n onChangeTitle={(title) =>\n handleConversationTitleChange(conversation.id, title)\n }\n title={conversation.title ?? \"\"}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n lastUpdatedAt={conversation.updated_at}\n createdAt={conversation.created_at}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n conversationId={conversation.id}\n contextMenuOpen={openContextMenuId === conversation.id}\n onContextMenuToggle={(isOpen) =>\n setOpenContextMenuId(isOpen ? conversation.id : null)\n }\n isActive={conversation.id === currentConversationId}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n showRepositoryMetadata={showRepoBranchMetadata}\n llmModel={conversation.llm_model}\n showLlmProfiles={showLlmProfiles}\n agentKind={conversation.agent_kind}\n acpServer={conversation.acp_server}\n isPinned={isPinned}\n onTogglePin={() => togglePin(activeBackend.id, conversation.id)}\n alwaysShowPinIcon={isPinned && !options?.inPinnedSection}\n />\n </NavigationLink>\n </Tooltip>\n );\n },\n [\n activeBackend.id,\n compact,\n currentConversationId,\n handleConversationTitleChange,\n handleDeleteProject,\n handleStopConversation,\n onClose,\n openContextMenuId,\n pinnedIds,\n showRepoBranchMetadata,\n showLlmProfiles,\n showHoverMetadata,\n togglePin,\n ],\n );\n\n // Standard layout: panel fills its slot in the sidebar; the inner scroll\n // child fills the panel and scrolls when its content overflows. Modals are\n // siblings of the scroll element and are `position: fixed`, so they don't\n // participate in the panel's scroll geometry.\n // Gate on `isLoading` / `!isFetched` (true only until the first fetch settles),\n // not `isFetching` — the latter flips back to true on every 10s background\n // refetch, causing the skeleton/empty-state to flicker when the list is empty.\n const showInitialSkeleton = isLoading || !isFetched;\n const showPinnedSection =\n !compact && !showInitialSkeleton && pinnedConversations.length > 0;\n const showEmptyState =\n isFetched &&\n !isLoading &&\n !compact &&\n listIsEffectivelyEmpty &&\n !showPinnedSection &&\n !startTasks?.length;\n\n const showConversationHeader = !compact;\n\n return (\n <div\n ref={ref}\n data-testid=\"conversation-panel\"\n className=\"flex h-full min-h-0 w-full flex-col\"\n >\n {showConversationHeader && (\n <div\n className={cn(\n // Pull flush to the sidebar edges: `-ml-2.5` matches aside `pl-2.5`;\n // width extends by that inset on the right now that aside is `pr-0`.\n \"-ml-2.5 w-[calc(100%+0.625rem)] max-w-none box-border border-b\",\n isListScrolled ? \"border-[var(--oh-border)]\" : \"border-transparent\",\n )}\n >\n <div\n data-testid=\"older-conversations-summary\"\n className=\"flex min-w-0 flex-nowrap items-center gap-x-2 py-2 pl-4 pr-2.5 text-[var(--oh-muted)]\"\n >\n <span className=\"min-w-0 truncate text-sm font-medium text-[var(--oh-muted)]\">\n {t(I18nKey.SIDEBAR$CONVERSATIONS)}\n </span>\n <div className=\"ml-auto flex shrink-0 items-center gap-0.5\">\n <ConversationPanelNewThreadPicker\n backendKind={activeBackend.kind}\n />\n <ConversationPanelFilterMenu\n filterMenuOpen={filterMenuOpen}\n setFilterMenuOpen={setFilterMenuOpen}\n menuRef={filterMenuRef}\n backendKind={activeBackend.kind}\n organizeMode={organizeMode}\n setOrganizeMode={setOrganizeMode}\n conversationSort={conversationSort}\n setConversationSort={setConversationSort}\n threadScope={threadScope}\n setThreadScope={setThreadScope}\n showOlderConversations={showOlderConversations}\n toggleShowOlderConversations={toggleShowOlderConversations}\n showRepoBranchMetadata={showRepoBranchMetadata}\n toggleShowRepoBranchMetadata={toggleShowRepoBranchMetadata}\n showLlmProfiles={showLlmProfiles}\n toggleShowLlmProfiles={toggleShowLlmProfiles}\n showHoverMetadata={showHoverMetadata}\n toggleShowHoverMetadata={toggleShowHoverMetadata}\n totalConversationsCount={conversations.length}\n onRequestDeleteAll={() => setConfirmDeleteAllVisible(true)}\n />\n </div>\n </div>\n </div>\n )}\n\n <div\n ref={scrollContainerRef}\n data-testid=\"conversation-panel-list-scroll\"\n onScroll={(event) => {\n setIsListScrolled(event.currentTarget.scrollTop > 0);\n }}\n className={cn(\n \"flex min-h-0 flex-1 flex-col overflow-y-auto overflow-x-hidden overscroll-contain custom-scrollbar-always\",\n !compact && \"conversation-panel-list-scroll\",\n )}\n >\n {showInitialSkeleton && <ConversationCardSkeleton compact={compact} />}\n\n {!compact && showEmptyState && (\n <div\n data-testid=\"conversation-panel-empty-state\"\n className=\"flex min-h-0 flex-1 flex-col items-center justify-center px-4 py-8\"\n >\n <p className=\"text-xs text-[var(--oh-muted)]\">\n {t(I18nKey.CONVERSATION$NO_CONVERSATIONS)}\n </p>\n </div>\n )}\n\n {showPinnedSection ? (\n <ConversationPanelPinnedSection\n pinnedConversations={pinnedConversations}\n isPreviewExpanded={expandedPinnedPreview}\n onTogglePreviewExpanded={() =>\n setExpandedPinnedPreview((current) => !current)\n }\n activeConversationId={currentConversationId}\n showDivider={!compact && organizeMode === \"chronological\"}\n renderConversationCard={(conversation) =>\n renderConversationCard(conversation, { inPinnedSection: true })\n }\n />\n ) : null}\n\n {/* Render in-progress start tasks first (skipped in compact mode —\n their rich card layout doesn't fit in the icon rail). */}\n {!compact &&\n startTasks?.map((task) => (\n <NavigationLink\n key={task.id}\n to={`/conversations/task-${task.id}`}\n onClick={onClose}\n className=\"block\"\n >\n <StartTaskCard task={task} />\n </NavigationLink>\n ))}\n\n {!showInitialSkeleton && compact\n ? compactVisibleConversations.map((conversation) =>\n renderConversationCard(conversation),\n )\n : null}\n\n {!showInitialSkeleton &&\n !compact &&\n organizeMode === \"grouped\" &&\n orderedConversationGroups &&\n orderedConversationGroups.length > 0 ? (\n <ConversationGroupFolderList\n groups={orderedConversationGroups}\n groupIds={conversationGroupIds}\n groupFolderOrder={groupFolderOrder}\n setGroupFolderOrder={setGroupFolderOrder}\n collapsedGroupIds={collapsedGroupIds}\n expandedGroupPreviewIds={expandedGroupPreviewIds}\n onToggleGroupCollapsed={toggleGroupCollapsed}\n onToggleGroupPreviewExpanded={toggleGroupPreviewExpanded}\n isCreatingConversationFlow={isCreatingConversationFlow}\n activeConversationId={currentConversationId}\n onLaunchFromGroup={launchFromGroup}\n renderConversationCard={(conversation) =>\n renderConversationCard(conversation)\n }\n />\n ) : null}\n\n {!showInitialSkeleton &&\n !compact &&\n organizeMode === \"chronological\" ? (\n <div className=\"space-y-0.5\">\n {sortedVisibleConversations.map((conversation) =>\n renderConversationCard(conversation),\n )}\n </div>\n ) : null}\n\n {/* Explicit \"Load more\" trigger. Only shown when more pages exist\n *and* the older list is currently visible (or there are no older\n conversations to begin with) — otherwise the next page would be\n populated mostly with conversations the user has chosen to hide. */}\n {showLoadMore &&\n (isLoadingMore ? (\n <div className=\"py-1\">\n <ConversationCardSkeleton compact={compact} />\n </div>\n ) : (\n <div className=\"flex justify-center py-4\">\n <button\n type=\"button\"\n data-testid=\"load-more-conversations\"\n onClick={requestLoadMore}\n className=\"text-xs text-[var(--oh-muted)] hover:text-white\"\n >\n {t(I18nKey.CONVERSATION$LOAD_MORE)}\n </button>\n </div>\n ))}\n </div>\n\n {confirmDeleteModalVisible && (\n <ConfirmDeleteModal\n onConfirm={() => {\n handleConfirmDelete();\n setConfirmDeleteModalVisible(false);\n setSelectedConversationTitle(null);\n }}\n onCancel={() => {\n setConfirmDeleteModalVisible(false);\n setSelectedConversationTitle(null);\n }}\n conversationTitle={selectedConversationTitle ?? undefined}\n />\n )}\n\n {confirmDeleteAllVisible && (\n <ConfirmDeleteModal\n title={t(I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_TITLE)}\n description={t(I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_DESC, {\n count: conversations.length,\n })}\n onConfirm={async () => {\n await handleConfirmDeleteAll();\n setConfirmDeleteAllVisible(false);\n }}\n onCancel={() => setConfirmDeleteAllVisible(false)}\n />\n )}\n\n {confirmStopModalVisible && (\n <ConfirmStopModal\n onConfirm={() => {\n handleConfirmStop();\n setConfirmStopModalVisible(false);\n }}\n onCancel={() => setConfirmStopModalVisible(false)}\n />\n )}\n\n {confirmExitConversationModalVisible && (\n <ExitConversationModal\n onConfirm={() => {\n onClose?.();\n }}\n onClose={() => setConfirmExitConversationModalVisible(false)}\n onCancel={() => setConfirmExitConversationModalVisible(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"conversation-panel.js","names":[],"sources":["../../../../src/components/features/conversation-panel/conversation-panel.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tooltip } from \"@heroui/react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { usePaginatedConversations } from \"#/hooks/query/use-paginated-conversations\";\nimport { useStartTasks } from \"#/hooks/query/use-start-tasks\";\nimport { useDeleteConversation } from \"#/hooks/mutation/use-delete-conversation\";\nimport { useUnifiedPauseConversation } from \"#/hooks/mutation/use-unified-stop-conversation\";\nimport { ConfirmDeleteModal } from \"./confirm-delete-modal\";\nimport { ConfirmStopModal } from \"./confirm-stop-modal\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ExitConversationModal } from \"./exit-conversation-modal\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { Provider } from \"#/types/settings\";\nimport { useUpdateConversation } from \"#/hooks/mutation/use-update-conversation\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { isExecutionActive } from \"#/utils/status\";\nimport { useCreateConversation } from \"#/hooks/mutation/use-create-conversation\";\nimport { useIsCreatingConversation } from \"#/hooks/use-is-creating-conversation\";\nimport { ConversationCard } from \"./conversation-card/conversation-card\";\nimport { ConversationCardPreview } from \"./conversation-card/conversation-card-preview\";\nimport { StartTaskCard } from \"./start-task-card/start-task-card\";\nimport { ConversationCardSkeleton } from \"./conversation-card/conversation-card-skeleton\";\nimport { CompactConversationRow } from \"./compact-conversation-row\";\nimport { useConversationPanelPreferencesStore } from \"#/stores/conversation-panel-preferences-store\";\nimport { cn } from \"#/utils/utils\";\nimport { ConversationPanelFilterMenu } from \"./conversation-panel-filter-menu\";\nimport { ConversationPanelNewThreadPicker } from \"./conversation-panel-new-thread-picker\";\nimport { ConversationGroupFolderList } from \"./conversation-group-folder-list\";\nimport { ConversationPanelPinnedSection } from \"./conversation-panel-pinned-section\";\nimport {\n applyGroupFolderOrder,\n filterOutPinnedConversations,\n groupConversations,\n resolvePinnedConversations,\n sortConversationsByField,\n type ConversationGroupLaunch,\n} from \"./conversation-panel-list-helpers\";\nimport { usePinnedConversationsStore } from \"#/stores/pinned-conversations-store\";\n\ninterface ConversationPanelProps {\n onClose?: () => void;\n /**\n * Render a minimal icon-only variant of each conversation row (used by the\n * collapsed sidebar). Each row is a single status dot with a hover preview\n * containing the full card content.\n */\n compact?: boolean;\n}\n\nconst noop = () => {};\n\nconst EMPTY_PINNED_CONVERSATION_IDS: readonly string[] = [];\n\nconst ONE_HOUR_MS = 60 * 60 * 1000;\n\nconst partitionByCutoff = <T extends { updated_at: string }>(\n items: readonly T[],\n): { recent: T[]; older: T[] } => {\n // The cutoff is intentionally relative to \"now\" each time the list is\n // recomputed, so conversations naturally age into the older bucket as the\n // conversations query refreshes.\n const cutoff = Date.now() - ONE_HOUR_MS;\n const recent: T[] = [];\n const older: T[] = [];\n for (const item of items) {\n const updatedAt = item.updated_at ? Date.parse(item.updated_at) : NaN;\n // Missing or unparseable timestamps stay in the \"recent\" bucket so we\n // do not accidentally hide them behind the older-conversations toggle.\n if (Number.isFinite(updatedAt) && updatedAt < cutoff) {\n older.push(item);\n } else {\n recent.push(item);\n }\n }\n return { recent, older };\n};\n\nexport function ConversationPanel({\n onClose,\n compact = false,\n}: ConversationPanelProps) {\n const { t } = useTranslation(\"openhands\");\n const { conversationId: currentConversationId, navigate } = useNavigation();\n const { backend: activeBackend } = useActiveBackend();\n // Click-outside is only relevant in the legacy drawer mode where an\n // onClose handler is provided. When the panel is rendered inline (e.g.\n // as the always-visible conversation list pane), clicking outside should\n // not dismiss the list, so we pass a no-op callback in that case.\n const ref = useClickOutsideElement<HTMLDivElement>(onClose ?? noop);\n\n const [confirmDeleteModalVisible, setConfirmDeleteModalVisible] =\n React.useState(false);\n const [confirmStopModalVisible, setConfirmStopModalVisible] =\n React.useState(false);\n const [\n confirmExitConversationModalVisible,\n setConfirmExitConversationModalVisible,\n ] = React.useState(false);\n const [confirmDeleteAllVisible, setConfirmDeleteAllVisible] =\n React.useState(false);\n const showOlderConversations = useConversationPanelPreferencesStore(\n (state) => state.showOlderConversations,\n );\n const toggleShowOlderConversations = useConversationPanelPreferencesStore(\n (state) => state.toggleShowOlderConversations,\n );\n const showRepoBranchMetadata = useConversationPanelPreferencesStore(\n (state) => state.showRepoBranchMetadata,\n );\n const toggleShowRepoBranchMetadata = useConversationPanelPreferencesStore(\n (state) => state.toggleShowRepoBranchMetadata,\n );\n const showLlmProfiles = useConversationPanelPreferencesStore(\n (state) => state.showLlmProfiles,\n );\n const toggleShowLlmProfiles = useConversationPanelPreferencesStore(\n (state) => state.toggleShowLlmProfiles,\n );\n const showHoverMetadata = useConversationPanelPreferencesStore(\n (state) => state.showHoverMetadata,\n );\n const toggleShowHoverMetadata = useConversationPanelPreferencesStore(\n (state) => state.toggleShowHoverMetadata,\n );\n const organizeMode = useConversationPanelPreferencesStore(\n (state) => state.organizeMode,\n );\n const setOrganizeMode = useConversationPanelPreferencesStore(\n (state) => state.setOrganizeMode,\n );\n const conversationSort = useConversationPanelPreferencesStore(\n (state) => state.conversationSort,\n );\n const setConversationSort = useConversationPanelPreferencesStore(\n (state) => state.setConversationSort,\n );\n const threadScope = useConversationPanelPreferencesStore(\n (state) => state.threadScope,\n );\n const setThreadScope = useConversationPanelPreferencesStore(\n (state) => state.setThreadScope,\n );\n const groupFolderOrder = useConversationPanelPreferencesStore(\n (state) => state.groupFolderOrder,\n );\n const setGroupFolderOrder = useConversationPanelPreferencesStore(\n (state) => state.setGroupFolderOrder,\n );\n const [filterMenuOpen, setFilterMenuOpen] = React.useState(false);\n const [isListScrolled, setIsListScrolled] = React.useState(false);\n const filterMenuRef = useClickOutsideElement<HTMLDivElement>(() => {\n setFilterMenuOpen(false);\n });\n const [collapsedGroupIds, setCollapsedGroupIds] = React.useState<\n ReadonlySet<string>\n >(() => new Set());\n const [expandedGroupPreviewIds, setExpandedGroupPreviewIds] = React.useState<\n ReadonlySet<string>\n >(() => new Set());\n const [expandedPinnedPreview, setExpandedPinnedPreview] =\n React.useState(false);\n\n const pinnedIds = usePinnedConversationsStore(\n (state) =>\n state.pinsByBackendId[activeBackend.id] ?? EMPTY_PINNED_CONVERSATION_IDS,\n );\n const togglePin = usePinnedConversationsStore((state) => state.togglePin);\n const pruneMissingPinnedConversations = usePinnedConversationsStore(\n (state) => state.pruneMissingConversations,\n );\n\n const toggleGroupCollapsed = React.useCallback((groupId: string) => {\n setCollapsedGroupIds((prev) => {\n const next = new Set(prev);\n if (next.has(groupId)) {\n next.delete(groupId);\n } else {\n next.add(groupId);\n }\n return next;\n });\n }, []);\n\n const toggleGroupPreviewExpanded = React.useCallback((groupId: string) => {\n setExpandedGroupPreviewIds((prev) => {\n const next = new Set(prev);\n if (next.has(groupId)) {\n next.delete(groupId);\n } else {\n next.add(groupId);\n }\n return next;\n });\n }, []);\n\n React.useEffect(() => {\n if (organizeMode !== \"grouped\") {\n setCollapsedGroupIds(new Set());\n setExpandedGroupPreviewIds(new Set());\n }\n }, [organizeMode]);\n\n const scrollContainerRef = React.useRef<HTMLDivElement>(null);\n\n const [selectedConversationId, setSelectedConversationId] = React.useState<\n string | null\n >(null);\n const [selectedConversationTitle, setSelectedConversationTitle] =\n React.useState<string | null>(null);\n const [openContextMenuId, setOpenContextMenuId] = React.useState<\n string | null\n >(null);\n\n const {\n data,\n isLoading,\n isFetched,\n hasNextPage,\n isFetching,\n isFetchingNextPage,\n fetchNextPage,\n } = usePaginatedConversations();\n\n // Fetch in-progress start tasks\n const { data: startTasks } = useStartTasks();\n\n const conversations = React.useMemo(() => {\n const all = data?.pages.flatMap((page) => page.items) ?? [];\n // The 10s background refetch re-fetches every loaded page with the\n // `UPDATED_AT_DESC` cursor. If a conversation's `updated_at` shifts between\n // page fetches, a later page can overlap an earlier one and surface the\n // same conversation twice. Dedupe by id (keeping the first/freshest copy)\n // so the rendered count reflects real growth and React keys stay unique.\n const seen = new Set<string>();\n return all.filter((conversation) => {\n if (seen.has(conversation.id)) {\n return false;\n }\n seen.add(conversation.id);\n return true;\n });\n }, [data]);\n\n const pinnedConversations = React.useMemo(\n () => resolvePinnedConversations(pinnedIds, conversations),\n [conversations, pinnedIds],\n );\n\n React.useEffect(() => {\n if (!isFetched) {\n return;\n }\n pruneMissingPinnedConversations(\n activeBackend.id,\n conversations.map((conversation) => conversation.id),\n );\n }, [\n activeBackend.id,\n conversations,\n isFetched,\n pruneMissingPinnedConversations,\n ]);\n\n React.useEffect(() => {\n if (pinnedIds.length === 0) {\n setExpandedPinnedPreview(false);\n }\n }, [pinnedIds.length]);\n\n const scopedConversations = React.useMemo(() => {\n const scopeFiltered =\n threadScope === \"relevant\"\n ? conversations.filter((c) => isExecutionActive(c.execution_status))\n : conversations;\n\n // In the expanded panel, pinned conversations should only appear inside\n // the dedicated pinned section (not duplicated in grouped/flat lists).\n if (compact) {\n return scopeFiltered;\n }\n\n return filterOutPinnedConversations(scopeFiltered, pinnedIds);\n }, [compact, conversations, pinnedIds, threadScope]);\n\n const { recent: recentScoped, older: olderScoped } = React.useMemo(\n () => partitionByCutoff(scopedConversations),\n [scopedConversations],\n );\n\n // Sort the full visible set as one list. The recent/older partition is\n // still computed (it gates the \"Show older\" toggle and \"Load more\"\n // visibility), but the rendering must not use it as a visual boundary —\n // when sorting by `created`, a stale-but-recently-touched conversation\n // would otherwise land in `recent` and render above an actually-newer-\n // by-`created_at` conversation sitting in `older`.\n const sortedVisibleConversations = React.useMemo(() => {\n const visible = showOlderConversations\n ? [...recentScoped, ...olderScoped]\n : recentScoped;\n return sortConversationsByField(visible, conversationSort);\n }, [recentScoped, olderScoped, showOlderConversations, conversationSort]);\n\n const groupLabels = React.useMemo(\n () => ({\n emptyWorkspace: t(I18nKey.CONVERSATION_PANEL$NO_WORKSPACE),\n emptyRepository: t(I18nKey.CONVERSATION_PANEL$NO_REPOSITORY),\n }),\n [t],\n );\n\n const conversationGroups = React.useMemo(() => {\n if (compact || organizeMode !== \"grouped\") {\n return null;\n }\n // Use the unsorted partitions: groupConversations sorts each bucket\n // internally by `sortField`, so pre-sorting the merged input is wasted\n // work in grouped mode (the per-group sort overrides any global order).\n const merged = [\n ...recentScoped,\n ...(showOlderConversations ? olderScoped : []),\n ];\n return groupConversations(\n merged,\n activeBackend.kind,\n conversationSort,\n groupLabels,\n );\n }, [\n activeBackend.kind,\n compact,\n conversationSort,\n groupLabels,\n olderScoped,\n organizeMode,\n recentScoped,\n showOlderConversations,\n ]);\n\n const orderedConversationGroups = React.useMemo(() => {\n if (!conversationGroups) {\n return null;\n }\n return applyGroupFolderOrder(conversationGroups, groupFolderOrder);\n }, [conversationGroups, groupFolderOrder]);\n\n const conversationGroupIds = React.useMemo(\n () => conversationGroups?.map((group) => group.id) ?? [],\n [conversationGroups],\n );\n\n const compactVisibleConversations = React.useMemo(\n () =>\n sortConversationsByField(\n recentScoped.filter((conversation) =>\n isExecutionActive(conversation.execution_status),\n ),\n conversationSort,\n ),\n [conversationSort, recentScoped],\n );\n\n const visibleFlatCount = sortedVisibleConversations.length;\n\n const visibleGroupedCount = React.useMemo(() => {\n if (!orderedConversationGroups) {\n return 0;\n }\n return orderedConversationGroups.reduce(\n (n, g) => n + g.conversations.length,\n 0,\n );\n }, [orderedConversationGroups]);\n\n const listIsEffectivelyEmpty =\n organizeMode === \"grouped\" && !compact\n ? visibleGroupedCount === 0\n : visibleFlatCount === 0;\n\n // Number of conversations actually rendered in the list right now, in the\n // current organize mode. \"Load more\" succeeds only when this number grows.\n const visibleCount =\n organizeMode === \"grouped\" && !compact\n ? visibleGroupedCount\n : visibleFlatCount;\n\n // KNOWN ISSUE (unresolved as of 2026-05-29): users still report that the\n // sidebar \"Load more\" sometimes requires two clicks before new conversations\n // appear. The mitigation below (dedupe by id in `conversations`, plus the\n // floor-tracking driver that keeps fetching until the visible count grows)\n // reduced but did NOT fully eliminate the symptom in manual testing. Likely\n // remaining suspects to investigate next: the agent-server cursor pagination\n // returning an overlapping/short page under `UPDATED_AT_DESC` while the 10s\n // `refetchInterval` reorders pages (see `usePaginatedConversations`), or a\n // React Query state lag where `hasNextPage`/`isFetching` settle a render\n // after the click. If you pick this up, reproduce against a backend with\n // >40 conversations and watch the `/api/conversations/search` cursors.\n //\n // Robust \"Load more\" driver. A single click can fail to surface new rows for\n // two reasons: (1) `fetchNextPage()` is silently dropped while the 10s\n // background refetch is in flight, and (2) a fetched page can yield zero\n // *visible* rows (filtered out by the active scope, or deduped as overlap),\n // so the list does not appear to grow. We capture the visible count at click\n // time and keep fetching pages — once the query is idle — until the visible\n // count actually increases or there are no more pages.\n const [loadMoreFloor, setLoadMoreFloor] = React.useState<number | null>(null);\n const visibleCountRef = React.useRef(visibleCount);\n visibleCountRef.current = visibleCount;\n\n const requestLoadMore = React.useCallback(() => {\n if (hasNextPage) {\n setLoadMoreFloor(visibleCountRef.current);\n }\n }, [hasNextPage]);\n\n React.useEffect(() => {\n if (loadMoreFloor === null) {\n return;\n }\n // Goal met: the visible list grew past where it was when the user clicked.\n if (visibleCount > loadMoreFloor) {\n setLoadMoreFloor(null);\n return;\n }\n // Nothing more to fetch — stop waiting even if the list did not grow.\n if (!hasNextPage) {\n setLoadMoreFloor(null);\n return;\n }\n // Wait for any in-flight fetch (including the background refetch) to settle\n // before requesting the next page, otherwise the request is dropped.\n if (isFetching || isFetchingNextPage) {\n return;\n }\n fetchNextPage();\n }, [\n loadMoreFloor,\n visibleCount,\n hasNextPage,\n isFetching,\n isFetchingNextPage,\n fetchNextPage,\n ]);\n\n const isLoadingMore = loadMoreFloor !== null || isFetchingNextPage;\n\n const { mutate: deleteConversation, mutateAsync: deleteConversationAsync } =\n useDeleteConversation();\n const { mutate: pauseConversation } = useUnifiedPauseConversation();\n const { mutate: updateConversation } = useUpdateConversation();\n\n // The next page of conversations is loaded only via the explicit \"Load\n // more\" link rendered at the end of the list — there is no scroll-driven\n // pagination, which previously caused the panel to feel like it had stray\n // scrollable space at the bottom.\n const olderHidden = olderScoped.length > 0 && !showOlderConversations;\n // Compact mode also hides \"Load more\" — paginating into archived\n // conversations contradicts the \"active only\" intent of the icon rail.\n // Do not show when the visible list is empty (e.g. filters hide every\n // loaded conversation) — that state already shows \"No conversations found\".\n const showLoadMore =\n !!hasNextPage && !olderHidden && !compact && !listIsEffectivelyEmpty;\n\n const { mutate: createConversation } = useCreateConversation();\n const isCreatingConversationFlow = useIsCreatingConversation();\n\n const launchFromGroup = React.useCallback(\n (launch: ConversationGroupLaunch) => {\n if (isCreatingConversationFlow) return;\n createConversation(\n {\n workingDir: launch.workingDir,\n repository: launch.repository,\n entryPoint: \"sidebar_relaunch_project\",\n },\n {\n onSuccess: (data) => {\n navigate(`/conversations/${data.conversation_id}`);\n },\n },\n );\n },\n [createConversation, isCreatingConversationFlow, navigate],\n );\n\n const handleDeleteProject = React.useCallback(\n (conversationId: string, title: string) => {\n setConfirmDeleteModalVisible(true);\n setSelectedConversationId(conversationId);\n setSelectedConversationTitle(title);\n },\n [],\n );\n\n const handleStopConversation = React.useCallback((conversationId: string) => {\n setConfirmStopModalVisible(true);\n setSelectedConversationId(conversationId);\n }, []);\n\n const handleConversationTitleChange = React.useCallback(\n (conversationId: string, newTitle: string) => {\n updateConversation(\n { conversationId, newTitle },\n {\n onSuccess: () => {\n displaySuccessToast(t(I18nKey.CONVERSATION$TITLE_UPDATED));\n },\n },\n );\n },\n [t, updateConversation],\n );\n\n const handleConfirmDelete = () => {\n if (selectedConversationId) {\n deleteConversation(\n { conversationId: selectedConversationId },\n {\n onSuccess: () => {\n if (selectedConversationId === currentConversationId) {\n navigate(\"/conversations\");\n }\n },\n },\n );\n }\n };\n\n const handleConfirmStop = () => {\n if (selectedConversationId) {\n pauseConversation({\n conversationId: selectedConversationId,\n });\n }\n };\n\n const handleConfirmDeleteAll = async () => {\n const idsToDelete = conversations.map((c) => c.id);\n const results = await Promise.allSettled(\n idsToDelete.map((conversationId) =>\n deleteConversationAsync({ conversationId }),\n ),\n );\n\n const deletedIds = results.flatMap((result, index) =>\n result.status === \"fulfilled\" ? [idsToDelete[index]] : [],\n );\n const failedCount = results.length - deletedIds.length;\n\n if (\n currentConversationId !== null &&\n deletedIds.includes(currentConversationId)\n ) {\n navigate(\"/conversations\");\n }\n\n if (failedCount > 0) {\n displayErrorToast(\n `${failedCount} conversation${failedCount === 1 ? \"\" : \"s\"} could not be deleted.`,\n );\n }\n };\n\n const renderConversationCard = React.useCallback(\n (\n conversation: (typeof conversations)[number],\n options?: { inPinnedSection?: boolean },\n ) => {\n const isPinned = pinnedIds.includes(conversation.id);\n if (compact) {\n return (\n <CompactConversationRow\n key={conversation.id}\n conversationId={conversation.id}\n title={conversation.title ?? \"\"}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n lastUpdatedAt={conversation.updated_at}\n createdAt={conversation.created_at}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n isActive={conversation.id === currentConversationId}\n onClose={onClose}\n showRepositoryMetadata={showRepoBranchMetadata}\n llmModel={conversation.llm_model}\n showLlmProfiles={showLlmProfiles}\n agentKind={conversation.agent_kind}\n acpServer={conversation.acp_server}\n />\n );\n }\n return (\n <Tooltip\n key={conversation.id}\n placement=\"right-start\"\n delay={1000}\n closeDelay={100}\n isDisabled={\n !showHoverMetadata || openContextMenuId === conversation.id\n }\n disableAnimation={import.meta.env.MODE === \"test\"}\n className=\"rounded-xl border border-[var(--oh-border)] bg-base-secondary p-0 text-white shadow-xl\"\n content={\n <ConversationCardPreview\n title={conversation.title ?? \"\"}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n llmModel={conversation.llm_model}\n createdAt={conversation.created_at}\n />\n }\n >\n <NavigationLink\n to={`/conversations/${conversation.id}`}\n onClick={onClose}\n className={cn(\n \"block rounded-md transition-colors\",\n openContextMenuId !== conversation.id &&\n \"hover:bg-[var(--oh-surface)]\",\n (conversation.id === currentConversationId ||\n openContextMenuId === conversation.id) &&\n \"bg-[var(--oh-surface)]\",\n )}\n >\n <ConversationCard\n onDelete={() =>\n handleDeleteProject(conversation.id, conversation.title ?? \"\")\n }\n onStop={() => handleStopConversation(conversation.id)}\n onChangeTitle={(title) =>\n handleConversationTitleChange(conversation.id, title)\n }\n title={conversation.title ?? \"\"}\n selectedRepository={{\n selected_repository: conversation.selected_repository,\n selected_branch: conversation.selected_branch,\n git_provider: conversation.git_provider as Provider,\n }}\n lastUpdatedAt={conversation.updated_at}\n createdAt={conversation.created_at}\n executionStatus={conversation.execution_status}\n sandboxStatus={conversation.sandbox_status}\n conversationId={conversation.id}\n contextMenuOpen={openContextMenuId === conversation.id}\n onContextMenuToggle={(isOpen) =>\n setOpenContextMenuId(isOpen ? conversation.id : null)\n }\n isActive={conversation.id === currentConversationId}\n workspaceWorkingDir={\n conversation.selected_workspace ??\n conversation.workspace?.working_dir\n }\n showRepositoryMetadata={showRepoBranchMetadata}\n llmModel={conversation.llm_model}\n showLlmProfiles={showLlmProfiles}\n agentKind={conversation.agent_kind}\n acpServer={conversation.acp_server}\n isPinned={isPinned}\n onTogglePin={() => togglePin(activeBackend.id, conversation.id)}\n alwaysShowPinIcon={isPinned && !options?.inPinnedSection}\n />\n </NavigationLink>\n </Tooltip>\n );\n },\n [\n activeBackend.id,\n compact,\n currentConversationId,\n handleConversationTitleChange,\n handleDeleteProject,\n handleStopConversation,\n onClose,\n openContextMenuId,\n pinnedIds,\n showRepoBranchMetadata,\n showLlmProfiles,\n showHoverMetadata,\n togglePin,\n ],\n );\n\n // Standard layout: panel fills its slot in the sidebar; the inner scroll\n // child fills the panel and scrolls when its content overflows. Modals are\n // siblings of the scroll element and are `position: fixed`, so they don't\n // participate in the panel's scroll geometry.\n // Gate on `isLoading` / `!isFetched` (true only until the first fetch settles),\n // not `isFetching` — the latter flips back to true on every 10s background\n // refetch, causing the skeleton/empty-state to flicker when the list is empty.\n const showInitialSkeleton = isLoading || !isFetched;\n const showPinnedSection =\n !compact && !showInitialSkeleton && pinnedConversations.length > 0;\n const showEmptyState =\n isFetched &&\n !isLoading &&\n !compact &&\n listIsEffectivelyEmpty &&\n !showPinnedSection &&\n !startTasks?.length;\n\n const showConversationHeader = !compact;\n\n return (\n <div\n ref={ref}\n data-testid=\"conversation-panel\"\n className=\"flex h-full min-h-0 w-full flex-col\"\n >\n {showConversationHeader && (\n <div\n className={cn(\n // Pull flush to the sidebar edges: `-ml-2.5` matches aside `pl-2.5`;\n // width extends by that inset on the right now that aside is `pr-0`.\n \"-ml-2.5 w-[calc(100%+0.625rem)] max-w-none box-border border-b\",\n isListScrolled ? \"border-[var(--oh-border)]\" : \"border-transparent\",\n )}\n >\n <div\n data-testid=\"older-conversations-summary\"\n className=\"flex min-w-0 flex-nowrap items-center gap-x-2 py-2 pl-4 pr-2.5 text-[var(--oh-muted)]\"\n >\n <span className=\"min-w-0 truncate text-sm font-medium text-[var(--oh-muted)]\">\n {t(I18nKey.SIDEBAR$CONVERSATIONS)}\n </span>\n <div className=\"ml-auto flex shrink-0 items-center gap-0.5\">\n <ConversationPanelNewThreadPicker\n backendKind={activeBackend.kind}\n />\n <ConversationPanelFilterMenu\n filterMenuOpen={filterMenuOpen}\n setFilterMenuOpen={setFilterMenuOpen}\n menuRef={filterMenuRef}\n backendKind={activeBackend.kind}\n organizeMode={organizeMode}\n setOrganizeMode={setOrganizeMode}\n conversationSort={conversationSort}\n setConversationSort={setConversationSort}\n threadScope={threadScope}\n setThreadScope={setThreadScope}\n showOlderConversations={showOlderConversations}\n toggleShowOlderConversations={toggleShowOlderConversations}\n showRepoBranchMetadata={showRepoBranchMetadata}\n toggleShowRepoBranchMetadata={toggleShowRepoBranchMetadata}\n showLlmProfiles={showLlmProfiles}\n toggleShowLlmProfiles={toggleShowLlmProfiles}\n showHoverMetadata={showHoverMetadata}\n toggleShowHoverMetadata={toggleShowHoverMetadata}\n totalConversationsCount={conversations.length}\n onRequestDeleteAll={() => setConfirmDeleteAllVisible(true)}\n />\n </div>\n </div>\n </div>\n )}\n\n <div\n ref={scrollContainerRef}\n data-testid=\"conversation-panel-list-scroll\"\n onScroll={(event) => {\n setIsListScrolled(event.currentTarget.scrollTop > 0);\n }}\n className={cn(\n \"flex min-h-0 flex-1 flex-col overflow-y-auto overflow-x-hidden overscroll-contain custom-scrollbar-always\",\n !compact && \"conversation-panel-list-scroll\",\n )}\n >\n {showInitialSkeleton && <ConversationCardSkeleton compact={compact} />}\n\n {!compact && showEmptyState && (\n <div\n data-testid=\"conversation-panel-empty-state\"\n className=\"flex min-h-0 flex-1 flex-col items-center justify-center px-4 py-8\"\n >\n <p className=\"text-xs text-[var(--oh-muted)]\">\n {t(I18nKey.CONVERSATION$NO_CONVERSATIONS)}\n </p>\n </div>\n )}\n\n {showPinnedSection ? (\n <ConversationPanelPinnedSection\n pinnedConversations={pinnedConversations}\n isPreviewExpanded={expandedPinnedPreview}\n onTogglePreviewExpanded={() =>\n setExpandedPinnedPreview((current) => !current)\n }\n activeConversationId={currentConversationId}\n showDivider={!compact && organizeMode === \"chronological\"}\n renderConversationCard={(conversation) =>\n renderConversationCard(conversation, { inPinnedSection: true })\n }\n />\n ) : null}\n\n {/* Render in-progress start tasks first (skipped in compact mode —\n their rich card layout doesn't fit in the icon rail). */}\n {!compact &&\n startTasks?.map((task) => (\n <NavigationLink\n key={task.id}\n to={`/conversations/task-${task.id}`}\n onClick={onClose}\n className=\"block\"\n >\n <StartTaskCard task={task} />\n </NavigationLink>\n ))}\n\n {!showInitialSkeleton && compact\n ? compactVisibleConversations.map((conversation) =>\n renderConversationCard(conversation),\n )\n : null}\n\n {!showInitialSkeleton &&\n !compact &&\n organizeMode === \"grouped\" &&\n orderedConversationGroups &&\n orderedConversationGroups.length > 0 ? (\n <ConversationGroupFolderList\n groups={orderedConversationGroups}\n groupIds={conversationGroupIds}\n groupFolderOrder={groupFolderOrder}\n setGroupFolderOrder={setGroupFolderOrder}\n collapsedGroupIds={collapsedGroupIds}\n expandedGroupPreviewIds={expandedGroupPreviewIds}\n onToggleGroupCollapsed={toggleGroupCollapsed}\n onToggleGroupPreviewExpanded={toggleGroupPreviewExpanded}\n isCreatingConversationFlow={isCreatingConversationFlow}\n activeConversationId={currentConversationId}\n onLaunchFromGroup={launchFromGroup}\n renderConversationCard={(conversation) =>\n renderConversationCard(conversation)\n }\n />\n ) : null}\n\n {!showInitialSkeleton &&\n !compact &&\n organizeMode === \"chronological\" ? (\n <div className=\"space-y-0.5\">\n {sortedVisibleConversations.map((conversation) =>\n renderConversationCard(conversation),\n )}\n </div>\n ) : null}\n\n {/* Explicit \"Load more\" trigger. Only shown when more pages exist\n *and* the older list is currently visible (or there are no older\n conversations to begin with) — otherwise the next page would be\n populated mostly with conversations the user has chosen to hide. */}\n {showLoadMore &&\n (isLoadingMore ? (\n <div className=\"py-1\">\n <ConversationCardSkeleton compact={compact} />\n </div>\n ) : (\n <div className=\"flex justify-center py-4\">\n <button\n type=\"button\"\n data-testid=\"load-more-conversations\"\n onClick={requestLoadMore}\n className=\"text-xs text-[var(--oh-muted)] hover:text-white\"\n >\n {t(I18nKey.CONVERSATION$LOAD_MORE)}\n </button>\n </div>\n ))}\n </div>\n\n {confirmDeleteModalVisible && (\n <ConfirmDeleteModal\n onConfirm={() => {\n handleConfirmDelete();\n setConfirmDeleteModalVisible(false);\n setSelectedConversationTitle(null);\n }}\n onCancel={() => {\n setConfirmDeleteModalVisible(false);\n setSelectedConversationTitle(null);\n }}\n conversationTitle={selectedConversationTitle ?? undefined}\n />\n )}\n\n {confirmDeleteAllVisible && (\n <ConfirmDeleteModal\n title={t(I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_TITLE)}\n description={t(I18nKey.CONVERSATION$CONFIRM_DELETE_ALL_DESC, {\n count: conversations.length,\n })}\n onConfirm={async () => {\n await handleConfirmDeleteAll();\n setConfirmDeleteAllVisible(false);\n }}\n onCancel={() => setConfirmDeleteAllVisible(false)}\n />\n )}\n\n {confirmStopModalVisible && (\n <ConfirmStopModal\n onConfirm={() => {\n handleConfirmStop();\n setConfirmStopModalVisible(false);\n }}\n onCancel={() => setConfirmStopModalVisible(false)}\n />\n )}\n\n {confirmExitConversationModalVisible && (\n <ExitConversationModal\n onConfirm={() => {\n onClose?.();\n }}\n onClose={() => setConfirmExitConversationModalVisible(false)}\n onCancel={() => setConfirmExitConversationModalVisible(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}