@openhands/agent-canvas 1.8.0 → 1.9.0

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 (492) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{Trans-B7lYw4uD.js → Trans-Bwpzk1wT.js} +1 -1
  4. package/build/assets/{acp-providers-WUD4tfSq.js → acp-providers-C921BlYB.js} +1 -1
  5. package/build/assets/active-backend-context-BiwzkzDy.js +2 -0
  6. package/build/assets/agent-context-settings-DXNT_dcw.js +1 -0
  7. package/build/assets/agent-profiles-settings-BymJf3EP.js +1 -0
  8. package/build/assets/agent-server-conversation-service.api-CYSWw-2g.js +41 -0
  9. package/build/assets/agent-settings-BjgQQe-_.js +1 -0
  10. package/build/assets/{agent-settings-BGTyoT6X.js → agent-settings-WzqXk6B4.js} +2 -2
  11. package/build/assets/{alert-banner-eRyIwDyU.js → alert-banner-DR8EVyZM.js} +1 -1
  12. package/build/assets/api-error-message-e16L1kwH.js +1 -0
  13. package/build/assets/{api-key-entry-screen-JOx3SH1-.js → api-key-entry-screen-DI0I04O3.js} +1 -1
  14. package/build/assets/{app-settings-D53QZy5p.js → app-settings-DGistSFV.js} +1 -1
  15. package/build/assets/automation-C_eCrGyP.js +1 -0
  16. package/build/assets/automation-detail-DY6x2FW1.js +2 -0
  17. package/build/assets/automation-export-C09f-Lua.js +2 -0
  18. package/build/assets/automation-setup-route-CqKp0717.js +1 -0
  19. package/build/assets/automations-list-CqWJ7qXW.js +1 -0
  20. package/build/assets/{back-nav-button-C02hGa8t.js → back-nav-button-D4ngzpSh.js} +1 -1
  21. package/build/assets/backend-form-modal-B8D5hBzK.js +1 -0
  22. package/build/assets/{backend-synced-settings-badge-CQ9xtNWm.js → backend-synced-settings-badge-BnzI8Ysj.js} +1 -1
  23. package/build/assets/{badge-CzXbf7tR.js → badge-1Mf1iPcX.js} +1 -1
  24. package/build/assets/{base-modal-DkVyzFMt.js → base-modal-BBuy0WQQ.js} +1 -1
  25. package/build/assets/{brand-button-BUlDL-mz.js → brand-button-DGN6Y9o6.js} +1 -1
  26. package/build/assets/browser-D_ekTlTS.js +6 -0
  27. package/build/assets/{browser-tab-BijpUbdt.js → browser-tab-D4a4Ou_w.js} +1 -1
  28. package/build/assets/{chat-send-button-BKsVjhtA.js → chat-send-button-CgbcjD97.js} +1 -1
  29. package/build/assets/check-CPLXgluF.js +1 -0
  30. package/build/assets/chevron-down-CP4QHvyc.js +1 -0
  31. package/build/assets/circle-check-Dpy2_xSI.js +1 -0
  32. package/build/assets/{circle-plus-check-toggle-DdjUiOo1.js → circle-plus-check-toggle-yTAS-nX3.js} +1 -1
  33. package/build/assets/cloud-funnel-analytics-CEOl5Gxr.js +1 -0
  34. package/build/assets/{combobox-caret-Dl9UtvD6.js → combobox-caret-Bd2yySnF.js} +1 -1
  35. package/build/assets/command-menu-Bj6X4ckE.js +1 -0
  36. package/build/assets/condenser-settings-EAXQNR2E.js +1 -0
  37. package/build/assets/{confirmation-modal-CRBJSllP.js → confirmation-modal-NCUPr2-O.js} +1 -1
  38. package/build/assets/{context-menu-list-item-FGaafXGh.js → context-menu-list-item-CrCrYuPF.js} +1 -1
  39. package/build/assets/conversation-BzyIcSwr.js +1 -0
  40. package/build/assets/conversation-CUJ0Vo8g.js +90 -0
  41. package/build/assets/conversation-panel-BzyIcSwr.js +1 -0
  42. package/build/assets/conversation-state-store-F62HvuI1.js +1 -0
  43. package/build/assets/{conversation-tab-empty-state-CDjvNgpG.js → conversation-tab-empty-state-BCZ7rUMH.js} +1 -1
  44. package/build/assets/{copy-Drwu97Gx.js → copy-DCmZtz6n.js} +1 -1
  45. package/build/assets/{copy-to-clipboard-button-NbN1clVr.js → copy-to-clipboard-button-D_Lp6-Fl.js} +1 -1
  46. package/build/assets/{device-verify-CDm_WrVu.js → device-verify-DLmolX8Q.js} +1 -1
  47. package/build/assets/{dropdown-classes-CqA2BTCL.js → dropdown-classes-BB8rzqXL.js} +1 -1
  48. package/build/assets/{entry.client-BO2KQj0y.js → entry.client-BbIYOsIg.js} +2 -2
  49. package/build/assets/{enum-filter-dropdown-DSqPZnsD.js → enum-filter-dropdown-C08-srev.js} +1 -1
  50. package/build/assets/{environment-switch-overlay-mGl2pqqx.js → environment-switch-overlay-BepBBX66.js} +1 -1
  51. package/build/assets/{extensions-hub-Br3Lgynp.js → extensions-hub-R3KNv-5V.js} +1 -1
  52. package/build/assets/{extensions-navigation-BQmstKDZ.js → extensions-navigation-CfWFmI1I.js} +1 -1
  53. package/build/assets/{external-link-D9B2QMPf.js → external-link-BdBSg8rk.js} +1 -1
  54. package/build/assets/files-tab-DEq8MbHu.js +1 -0
  55. package/build/assets/{form-control-classes-CtVAktAy.js → form-control-classes-DAfsCJTe.js} +1 -1
  56. package/build/assets/{format-time-delta-DICE64sz.js → format-time-delta-CxfPJpzC.js} +1 -1
  57. package/build/assets/git-provider-icon-BZqqUPlm.js +1 -0
  58. package/build/assets/git-repo-dropdown-9WKINV6J.js +1 -0
  59. package/build/assets/git-repo-dropdown-DEpOwUez.js +1 -0
  60. package/build/assets/{highlighted-source-view-KMsA9c4a.js → highlighted-source-view-CX9oIoVT.js} +1 -1
  61. package/build/assets/home-CY0JaxiY.js +1 -0
  62. package/build/assets/home-CaNWlVvB.js +1 -0
  63. package/build/assets/home-store-Ch1ErdBc.js +1 -0
  64. package/build/assets/index-home-CaNWlVvB.js +1 -0
  65. package/build/assets/info-CmWQXtRQ.js +1 -0
  66. package/build/assets/install-server-modal-BWrudmZU.js +1 -0
  67. package/build/assets/{launch-DjkKw55l.js → launch-B1POpHuP.js} +1 -1
  68. package/build/assets/{list-todo-BpAf7aOT.js → list-todo-DtiL3lTp.js} +1 -1
  69. package/build/assets/llm-not-configured-banner-3tMsM4K6.js +27 -0
  70. package/build/assets/{llm-settings-D8zNkIlP.js → llm-settings-CXo8iPNW.js} +1 -1
  71. package/build/assets/llm-settings-D0W8mJDk.js +1 -0
  72. package/build/assets/{llm-subscription-service-COTgZc1C.js → llm-subscription-service-DBJbfd8Z.js} +1 -1
  73. package/build/assets/loader-circle-B4QDBARx.js +1 -0
  74. package/build/assets/{loading-spinner-DRFyh6Iy.js → loading-spinner-DfZ_bhV7.js} +1 -1
  75. package/build/assets/{manage-backends-modal-DiRWE3tJ.js → manage-backends-modal-CwyWsiag.js} +1 -1
  76. package/build/assets/manifest-39f4789d.js +1 -0
  77. package/build/assets/markdown-renderer-DgiLLhW6.js +8 -0
  78. package/build/assets/mcp-DXG9LWrI.js +9 -0
  79. package/build/assets/mcp-marketplace-utils-DFmhKc5s.js +1 -0
  80. package/build/assets/messages-kBjKaAeA.js +40 -0
  81. package/build/assets/{modal-body-C3bGicn4.js → modal-body-CMsDpalT.js} +1 -1
  82. package/build/assets/{modal-classes-DFFO6BMU.js → modal-classes-B6PDrxXo.js} +1 -1
  83. package/build/assets/{modal-close-button-vxkAIRyZ.js → modal-close-button-DyxBZaAb.js} +1 -1
  84. package/build/assets/{onboarding-DWuFieEA.js → onboarding-47hh2IHA.js} +1 -1
  85. package/build/assets/{onboarding-modal-C8m72Dpb.js → onboarding-modal-9BuvvROo.js} +1 -1
  86. package/build/assets/{organization-service.api-CQ73CB-S.js → organization-service.api-UDy63-oC.js} +1 -1
  87. package/build/assets/{pencil-DzW2GB2M.js → pencil-BjgtZmWp.js} +1 -1
  88. package/build/assets/{planner-tab-YG0bGxDY.js → planner-tab-BWk8885v.js} +1 -1
  89. package/build/assets/{plugins-management-service-ijhH8OSh.js → plugins-management-service-CjkgF2dd.js} +1 -1
  90. package/build/assets/plus-DrKuuvMe.js +1 -0
  91. package/build/assets/{profiles-service.api-C32pPm70.js → profiles-service.api-CukSFLzz.js} +1 -1
  92. package/build/assets/{providers-DuSn9s2i.js → providers-CqUWC85T.js} +1 -1
  93. package/build/assets/{proxy-BiyDhMBd.js → proxy-BBUG3sd2.js} +1 -1
  94. package/build/assets/{puzzle-DlqT0yvr.js → puzzle-BoNc6zZ8.js} +1 -1
  95. package/build/assets/recommended-automations-launcher-ejxy1P27.js +1 -0
  96. package/build/assets/{refresh-cw-Br5254f4.js → refresh-cw-BrM5ZAZD.js} +1 -1
  97. package/build/assets/root-5S-M8SYa.js +2 -0
  98. package/build/assets/root-DZ39lS5f.css +1 -0
  99. package/build/assets/root-layout-BPqoa0gv.js +3 -0
  100. package/build/assets/{schema-field-htfNouTG.js → schema-field-nImDoY6-.js} +1 -1
  101. package/build/assets/{sdk-section-page-D0K1dBQY.js → sdk-section-page-BxMrtUNV.js} +1 -1
  102. package/build/assets/search-Dc2qR4O2.js +1 -0
  103. package/build/assets/{secrets-service-Dbv5Zb8G.js → secrets-service-Dhjh3HhH.js} +1 -1
  104. package/build/assets/{secrets-settings-Da4SSaX9.js → secrets-settings-CPdxceT_.js} +1 -1
  105. package/build/assets/segmented-toggle-Do6oyepX.js +1 -0
  106. package/build/assets/{settings-F4a09IxY.js → settings-BRbnfKEm.js} +1 -1
  107. package/build/assets/{settings-dropdown-input-jOiv5Yrk.js → settings-dropdown-input-DYCULKpp.js} +1 -1
  108. package/build/assets/{settings-index-CyJBf5NA.js → settings-index-C9o2NBO0.js} +1 -1
  109. package/build/assets/settings-input-B-q2gkVy.js +1 -0
  110. package/build/assets/{settings-list-classes-VqMzkYYt.js → settings-list-classes-WpQi0q1L.js} +1 -1
  111. package/build/assets/{settings-modal-C-S1NpbC.js → settings-modal-CEK0AIx6.js} +1 -1
  112. package/build/assets/{settings-service.api-CTJRrvMu.js → settings-service.api-CZiPD8__.js} +1 -1
  113. package/build/assets/{settings-switch-B405oU_v.js → settings-switch-LqKdGxHL.js} +1 -1
  114. package/build/assets/shared-conversation-Bu-dQlgp.js +1 -0
  115. package/build/assets/{sidebar-layout-BGMuyC86.js → sidebar-layout-oHBGQmLh.js} +1 -1
  116. package/build/assets/{sidebar-mobile-menu-toggle-xiKoUfGa.js → sidebar-mobile-menu-toggle-ND-hgygu.js} +1 -1
  117. package/build/assets/{sidebar-nav-link-DA4_ct9G.js → sidebar-nav-link-CrujNA09.js} +1 -1
  118. package/build/assets/{sidebar-store-FRJ3rADB.js → sidebar-store-Bui-WNEr.js} +1 -1
  119. package/build/assets/{skill-card-pill-row-BMdhr_sd.js → skill-card-pill-row-CZBI7OqH.js} +1 -1
  120. package/build/assets/{skill-icon-badge-CGUkgcVH.js → skill-icon-badge-BOov_phZ.js} +1 -1
  121. package/build/assets/{skills-plugins-C5eJnyft.js → skills-plugins-D0PiHWAD.js} +1 -1
  122. package/build/assets/{skills-settings-pUxMr6WZ.js → skills-settings-B43KArIz.js} +2 -2
  123. package/build/assets/{styled-tooltip-B3kIdVyH.js → styled-tooltip-C7grwnOX.js} +1 -1
  124. package/build/assets/{task-list-tab-B3k4W1cK.js → task-list-tab-R3ac6m7O.js} +1 -1
  125. package/build/assets/{terminal-CBI_41Zc.js → terminal-yqkNdEAx.js} +1 -1
  126. package/build/assets/{toggle-switch-DYRr9CAR.js → toggle-switch-BeSrbgCg.js} +1 -1
  127. package/build/assets/{trash-2-gZPlx23R.js → trash-2-wW5TWcdN.js} +1 -1
  128. package/build/assets/{typography-B1UxuuEC.js → typography-iYhzLlHO.js} +1 -1
  129. package/build/assets/{use-acp-credential-form-CjSvKWFH.js → use-acp-credential-form-DUxbxmbq.js} +1 -1
  130. package/build/assets/{use-activate-agent-profile-DCRf47e-.js → use-activate-agent-profile-CDHA52tC.js} +1 -1
  131. package/build/assets/use-agent-profiles-TsOdIyw5.js +1 -0
  132. package/build/assets/{use-can-manage-org-profiles-vBiP7rHF.js → use-can-manage-org-profiles-Bt1M71u5.js} +1 -1
  133. package/build/assets/{use-cloud-current-user-id-BMq9gw93.js → use-cloud-current-user-id-DWt7HCgf.js} +1 -1
  134. package/build/assets/use-config-CxlEdf_v.js +1 -0
  135. package/build/assets/{use-create-conversation-CakhLF0X.js → use-create-conversation-nOJ6Um5h.js} +1 -1
  136. package/build/assets/{use-create-secret-RT4QtSS9.js → use-create-secret-Dj5ang9x.js} +1 -1
  137. package/build/assets/use-is-authed-BT7Iud4U.js +1 -0
  138. package/build/assets/{use-is-creating-conversation-CIAcnd8M.js → use-is-creating-conversation-CAggrM75.js} +1 -1
  139. package/build/assets/use-llm-profiles-2Wc2db8u.js +1 -0
  140. package/build/assets/{use-onboarding-completion-CJU4MNAY.js → use-onboarding-completion-gxQlcEy2.js} +1 -1
  141. package/build/assets/{use-plugins-marketplace-D-93nqtJ.js → use-plugins-marketplace-CVO7sXYR.js} +1 -1
  142. package/build/assets/use-save-agent-profile-D0wC5ExW.js +1 -0
  143. package/build/assets/{use-save-settings--C6LZXfI.js → use-save-settings-L3aMaDeS.js} +1 -1
  144. package/build/assets/{use-settings-DIAo5KFk.js → use-settings-8nt3DGxW.js} +1 -1
  145. package/build/assets/use-settings-nav-items-DHAAD-zk.js +16 -0
  146. package/build/assets/{use-skills-D_mLhYNa.js → use-skills-CE6miQ3r.js} +1 -1
  147. package/build/assets/use-tracking-BGboadaZ.js +68 -0
  148. package/build/assets/{use-user-conversation-DhcAEyJX.js → use-user-conversation-BIIpGUgM.js} +1 -1
  149. package/build/assets/useInfiniteQuery-BLRVmVPU.js +1 -0
  150. package/build/assets/{useMutation-DHLpZ6J0.js → useMutation-CaSHLnX0.js} +1 -1
  151. package/build/assets/{useQueries-B3T1a7qt.js → useQueries--d_WWAzc.js} +1 -1
  152. package/build/assets/{useQuery-B38jBavx.js → useQuery-DiPh8LRJ.js} +1 -1
  153. package/build/assets/utils-BgGG1znF.js +1 -0
  154. package/build/assets/{vendor~browser-CIoZCqGs.js → vendor~browser-IVYgIgG1.js} +1 -1
  155. package/build/assets/{vendor~entry.client-Di4qO77Y.js → vendor~entry.client-BcYIVQvB.js} +1 -1
  156. package/build/assets/{vendor~entry.client-BfviqoVc.js → vendor~entry.client-CXM9oiAk.js} +1 -1
  157. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~g4xrpilz-CYPMCkX1.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0bpqexo-CbTboogo.js} +1 -1
  158. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~d4by102p-C2f0ZhS-.js} +1 -1
  159. package/build/assets/{vendor~files-tab-atebg0iG.js → vendor~files-tab-C7RmQJwN.js} +1 -1
  160. package/build/assets/{vendor~index-home~home~conversation-panel~conversation-G9DMrR7m.js → vendor~index-home~home~conversation-panel~conversation-Bqp1ZqJM.js} +1 -1
  161. package/build/assets/{vendor~root-layout~conversation-panel~conversation-DEhW1h3I.js → vendor~root-layout~conversation-panel~conversation-BCn8lzeG.js} +1 -1
  162. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~automation-setup-route-B_L-gcOG.js +1 -0
  163. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-sjx0x5ac.js +1 -0
  164. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~automation-setup-route~onboarding-modal-D7IDevqN.js +1 -0
  165. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~bi2r7bko-VFnwct3q.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~dfc8ddxy-tTyxnjXT.js} +1 -1
  166. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hakxo2tj-ClV0p9g3.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gy8zbn65-CGt6bWRT.js} +1 -1
  167. package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~eywn6ulz-BKxxr74w.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~dufan6ng-Dtdw8H0q.js} +17 -4
  168. package/build/assets/{verification-settings-Vr5cN4md.js → verification-settings-DBsnSXC3.js} +1 -1
  169. package/build/assets/x-omAzpXkl.js +1 -0
  170. package/build/index.html +4 -4
  171. package/build/locales/ar/openhands.json +37 -2
  172. package/build/locales/ca/openhands.json +37 -2
  173. package/build/locales/de/openhands.json +37 -2
  174. package/build/locales/en/openhands.json +38 -3
  175. package/build/locales/es/openhands.json +37 -2
  176. package/build/locales/fr/openhands.json +37 -2
  177. package/build/locales/it/openhands.json +37 -2
  178. package/build/locales/ja/openhands.json +37 -2
  179. package/build/locales/ko-KR/openhands.json +37 -2
  180. package/build/locales/no/openhands.json +37 -2
  181. package/build/locales/pt/openhands.json +37 -2
  182. package/build/locales/tr/openhands.json +37 -2
  183. package/build/locales/uk/openhands.json +37 -2
  184. package/build/locales/zh-CN/openhands.json +37 -2
  185. package/build/locales/zh-TW/openhands.json +37 -2
  186. package/config/defaults.json +1 -1
  187. package/dist/api/agent-server-adapter.cjs +3 -3
  188. package/dist/api/agent-server-adapter.cjs.map +1 -1
  189. package/dist/api/agent-server-adapter.d.ts +46 -6
  190. package/dist/api/agent-server-adapter.js +187 -168
  191. package/dist/api/agent-server-adapter.js.map +1 -1
  192. package/dist/api/agent-server-compatibility.cjs +1 -1
  193. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  194. package/dist/api/agent-server-compatibility.d.ts +4 -0
  195. package/dist/api/agent-server-compatibility.js +41 -38
  196. package/dist/api/agent-server-compatibility.js.map +1 -1
  197. package/dist/api/automation-service/automation-service.api.cjs +1 -1
  198. package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
  199. package/dist/api/automation-service/automation-service.api.d.ts +20 -0
  200. package/dist/api/automation-service/automation-service.api.js +99 -62
  201. package/dist/api/automation-service/automation-service.api.js.map +1 -1
  202. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs +2 -0
  203. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs.map +1 -0
  204. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.d.ts +12 -0
  205. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js +94 -0
  206. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js.map +1 -0
  207. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
  208. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
  209. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +31 -90
  210. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
  211. package/dist/components/features/automations/recommended-automations-launcher.d.ts +0 -7
  212. package/dist/components/features/automations/recommended-automations-section.d.ts +0 -6
  213. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  214. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  215. package/dist/components/features/backends/backend-form-modal.js +568 -358
  216. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  217. package/dist/components/features/backends/device-flow-auth.cjs +1 -1
  218. package/dist/components/features/backends/device-flow-auth.cjs.map +1 -1
  219. package/dist/components/features/backends/device-flow-auth.d.ts +9 -1
  220. package/dist/components/features/backends/device-flow-auth.js +56 -55
  221. package/dist/components/features/backends/device-flow-auth.js.map +1 -1
  222. package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
  223. package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
  224. package/dist/components/features/backends/manage-backends-modal.js +1 -1
  225. package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
  226. package/dist/components/features/chat/chat-interface.cjs +1 -1
  227. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  228. package/dist/components/features/chat/chat-interface.js +105 -105
  229. package/dist/components/features/chat/chat-interface.js.map +1 -1
  230. package/dist/components/features/chat/chat-message.cjs +1 -1
  231. package/dist/components/features/chat/chat-message.cjs.map +1 -1
  232. package/dist/components/features/chat/chat-message.d.ts +2 -1
  233. package/dist/components/features/chat/chat-message.js +59 -49
  234. package/dist/components/features/chat/chat-message.js.map +1 -1
  235. package/dist/components/features/chat/pending-user-messages.cjs +1 -1
  236. package/dist/components/features/chat/pending-user-messages.cjs.map +1 -1
  237. package/dist/components/features/chat/pending-user-messages.js +4 -1
  238. package/dist/components/features/chat/pending-user-messages.js.map +1 -1
  239. package/dist/components/features/chat/typing-indicator.cjs +1 -1
  240. package/dist/components/features/chat/typing-indicator.cjs.map +1 -1
  241. package/dist/components/features/chat/typing-indicator.d.ts +8 -1
  242. package/dist/components/features/chat/typing-indicator.js +94 -10
  243. package/dist/components/features/chat/typing-indicator.js.map +1 -1
  244. package/dist/components/features/command-menu/command-menu-items.d.ts +5 -1
  245. package/dist/components/features/files-tab/segmented-toggle.cjs +1 -1
  246. package/dist/components/features/files-tab/segmented-toggle.cjs.map +1 -1
  247. package/dist/components/features/files-tab/segmented-toggle.d.ts +2 -0
  248. package/dist/components/features/files-tab/segmented-toggle.js +17 -14
  249. package/dist/components/features/files-tab/segmented-toggle.js.map +1 -1
  250. package/dist/components/features/manifest/manifest-form-field.d.ts +27 -0
  251. package/dist/components/features/manifest/manifest-prerequisites-step.d.ts +11 -0
  252. package/dist/components/features/manifest/manifest-review-step.d.ts +14 -0
  253. package/dist/components/features/manifest/manifest-setup-dialog.d.ts +14 -0
  254. package/dist/components/features/settings/settings-input.cjs +1 -1
  255. package/dist/components/features/settings/settings-input.cjs.map +1 -1
  256. package/dist/components/features/settings/settings-input.d.ts +6 -0
  257. package/dist/components/features/settings/settings-input.js +13 -8
  258. package/dist/components/features/settings/settings-input.js.map +1 -1
  259. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  260. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  261. package/dist/components/features/sidebar/sidebar-rail-body.js +124 -123
  262. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  263. package/dist/config/defaults.cjs +1 -1
  264. package/dist/config/defaults.cjs.map +1 -1
  265. package/dist/config/defaults.js +1 -1
  266. package/dist/config/defaults.js.map +1 -1
  267. package/dist/hooks/query/query-keys.cjs.map +1 -1
  268. package/dist/hooks/query/query-keys.d.ts +4 -0
  269. package/dist/hooks/query/query-keys.js.map +1 -1
  270. package/dist/hooks/query/use-manifest-capabilities.d.ts +21 -0
  271. package/dist/hooks/query/use-manifest-prerequisites.d.ts +24 -0
  272. package/dist/hooks/use-llm-configured.cjs +1 -1
  273. package/dist/hooks/use-llm-configured.cjs.map +1 -1
  274. package/dist/hooks/use-llm-configured.js +2 -1
  275. package/dist/hooks/use-llm-configured.js.map +1 -1
  276. package/dist/hooks/use-manifest-preflight.d.ts +18 -0
  277. package/dist/hooks/use-tracking.cjs +1 -1
  278. package/dist/hooks/use-tracking.cjs.map +1 -1
  279. package/dist/hooks/use-tracking.d.ts +14 -0
  280. package/dist/hooks/use-tracking.js +19 -1
  281. package/dist/hooks/use-tracking.js.map +1 -1
  282. package/dist/i18n/declaration.cjs +1 -1
  283. package/dist/i18n/declaration.cjs.map +1 -1
  284. package/dist/i18n/declaration.d.ts +36 -1
  285. package/dist/i18n/declaration.js +1 -1
  286. package/dist/i18n/declaration.js.map +1 -1
  287. package/dist/i18n/translation.cjs +2 -2
  288. package/dist/i18n/translation.cjs.map +1 -1
  289. package/dist/i18n/translation.js +611 -16
  290. package/dist/i18n/translation.js.map +1 -1
  291. package/dist/icons/external-link.cjs +2 -0
  292. package/dist/icons/external-link.cjs.map +1 -0
  293. package/dist/icons/external-link.js +22 -0
  294. package/dist/icons/external-link.js.map +1 -0
  295. package/dist/icons/server.cjs +2 -0
  296. package/dist/icons/server.cjs.map +1 -0
  297. package/dist/icons/server.js +17 -0
  298. package/dist/icons/server.js.map +1 -0
  299. package/dist/locales/ar/openhands.json +37 -2
  300. package/dist/locales/ca/openhands.json +37 -2
  301. package/dist/locales/de/openhands.json +37 -2
  302. package/dist/locales/en/openhands.json +38 -3
  303. package/dist/locales/es/openhands.json +37 -2
  304. package/dist/locales/fr/openhands.json +37 -2
  305. package/dist/locales/it/openhands.json +37 -2
  306. package/dist/locales/ja/openhands.json +37 -2
  307. package/dist/locales/ko-KR/openhands.json +37 -2
  308. package/dist/locales/no/openhands.json +37 -2
  309. package/dist/locales/pt/openhands.json +37 -2
  310. package/dist/locales/tr/openhands.json +37 -2
  311. package/dist/locales/uk/openhands.json +37 -2
  312. package/dist/locales/zh-CN/openhands.json +37 -2
  313. package/dist/locales/zh-TW/openhands.json +37 -2
  314. package/dist/manifests/automation-interface.cjs +2 -0
  315. package/dist/manifests/automation-interface.cjs.map +1 -0
  316. package/dist/manifests/automation-interface.d.ts +44 -0
  317. package/dist/manifests/automation-interface.js +81 -0
  318. package/dist/manifests/automation-interface.js.map +1 -0
  319. package/dist/manifests/automation-setup.cjs +2 -0
  320. package/dist/manifests/automation-setup.cjs.map +1 -0
  321. package/dist/manifests/automation-setup.d.ts +52 -0
  322. package/dist/manifests/automation-setup.js +8 -0
  323. package/dist/manifests/automation-setup.js.map +1 -0
  324. package/dist/manifests/interface-validation.cjs +2 -0
  325. package/dist/manifests/interface-validation.cjs.map +1 -0
  326. package/dist/manifests/interface-validation.d.ts +27 -0
  327. package/dist/manifests/interface-validation.js +182 -0
  328. package/dist/manifests/interface-validation.js.map +1 -0
  329. package/dist/manifests/manifest-actions.d.ts +15 -0
  330. package/dist/manifests/manifest-capabilities.d.ts +25 -0
  331. package/dist/manifests/manifest-error-map.d.ts +40 -0
  332. package/dist/manifests/manifest-local-validation.d.ts +56 -0
  333. package/dist/manifests/manifest-registry.cjs +2 -0
  334. package/dist/manifests/manifest-registry.cjs.map +1 -0
  335. package/dist/manifests/manifest-registry.d.ts +15 -0
  336. package/dist/manifests/manifest-registry.js +26 -0
  337. package/dist/manifests/manifest-registry.js.map +1 -0
  338. package/dist/manifests/manifest-sources.cjs +2 -0
  339. package/dist/manifests/manifest-sources.cjs.map +1 -0
  340. package/dist/manifests/manifest-sources.d.ts +15 -0
  341. package/dist/manifests/manifest-sources.js +8 -0
  342. package/dist/manifests/manifest-sources.js.map +1 -0
  343. package/dist/manifests/manifest-template.d.ts +18 -0
  344. package/dist/manifests/manifest-validation.cjs +2 -0
  345. package/dist/manifests/manifest-validation.cjs.map +1 -0
  346. package/dist/manifests/manifest-validation.d.ts +30 -0
  347. package/dist/manifests/manifest-validation.js +145 -0
  348. package/dist/manifests/manifest-validation.js.map +1 -0
  349. package/dist/manifests/types.cjs +2 -0
  350. package/dist/manifests/types.cjs.map +1 -0
  351. package/dist/manifests/types.d.ts +227 -0
  352. package/dist/manifests/types.js +6 -0
  353. package/dist/manifests/types.js.map +1 -0
  354. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +9 -0
  355. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -0
  356. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +75 -0
  357. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -0
  358. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs +9 -0
  359. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs.map +1 -0
  360. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js +78 -0
  361. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js.map +1 -0
  362. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs +17 -0
  363. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs.map +1 -0
  364. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js +89 -0
  365. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js.map +1 -0
  366. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs +10 -0
  367. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs.map +1 -0
  368. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js +17 -0
  369. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js.map +1 -0
  370. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs +9 -0
  371. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs.map +1 -0
  372. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js +15 -0
  373. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js.map +1 -0
  374. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs +9 -0
  375. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs.map +1 -0
  376. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js +18 -0
  377. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js.map +1 -0
  378. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs +9 -0
  379. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs.map +1 -0
  380. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js +14 -0
  381. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js.map +1 -0
  382. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs +9 -0
  383. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs.map +1 -0
  384. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js +14 -0
  385. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js.map +1 -0
  386. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +2 -0
  387. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -0
  388. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +23 -0
  389. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -0
  390. package/dist/node_modules/@openhands/extensions/automations/index.cjs +2 -0
  391. package/dist/node_modules/@openhands/extensions/automations/index.cjs.map +1 -0
  392. package/dist/node_modules/@openhands/extensions/automations/index.js +18 -0
  393. package/dist/node_modules/@openhands/extensions/automations/index.js.map +1 -0
  394. package/dist/node_modules/@openhands/extensions/automations/interface.cjs +2 -0
  395. package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -0
  396. package/dist/node_modules/@openhands/extensions/automations/interface.js +89 -0
  397. package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -0
  398. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
  399. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
  400. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +3 -3
  401. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
  402. package/dist/node_modules/@openhands/extensions/skills/index.cjs +17 -4
  403. package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
  404. package/dist/node_modules/@openhands/extensions/skills/index.js +5 -5
  405. package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
  406. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs +2 -0
  407. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs.map +1 -0
  408. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js +29 -0
  409. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js.map +1 -0
  410. package/dist/package.cjs +1 -1
  411. package/dist/package.cjs.map +1 -1
  412. package/dist/package.js +2 -2
  413. package/dist/package.js.map +1 -1
  414. package/dist/types/agent-server/core/events/conversation-state-event.d.ts +2 -19
  415. package/dist/types/agent-server/core/events/observation-event.d.ts +2 -18
  416. package/dist/types/automation.d.ts +7 -3
  417. package/dist/utils/api-error-message.d.ts +6 -2
  418. package/dist/utils/automation-catalog.cjs +2 -0
  419. package/dist/utils/automation-catalog.cjs.map +1 -0
  420. package/dist/utils/automation-catalog.d.ts +28 -0
  421. package/dist/utils/automation-catalog.js +5 -0
  422. package/dist/utils/automation-catalog.js.map +1 -0
  423. package/dist/utils/automation-timeout.d.ts +3 -2
  424. package/dist/utils/responder-deployment.d.ts +5 -1
  425. package/dist/utils/transcript-export/index.cjs +5 -5
  426. package/dist/utils/transcript-export/index.js +12 -12
  427. package/package.json +2 -2
  428. package/scripts/check-translation-completeness.cjs +1 -0
  429. package/scripts/dev-safe.mjs +15 -10
  430. package/scripts/dev-static.mjs +17 -0
  431. package/scripts/dev-with-automation.mjs +12 -14
  432. package/scripts/ingress.mjs +22 -0
  433. package/scripts/proxy-utils.mjs +157 -2
  434. package/scripts/runtime-services-info.mjs +6 -6
  435. package/scripts/static-build.mjs +0 -7
  436. package/scripts/static-server.mjs +10 -0
  437. package/build/assets/active-backend-context-mY7Gff5c.js +0 -2
  438. package/build/assets/agent-context-settings-BTUmWEzL.js +0 -1
  439. package/build/assets/agent-profiles-settings-Ilqid_R5.js +0 -1
  440. package/build/assets/agent-server-conversation-service.api-C_7YnjzP.js +0 -41
  441. package/build/assets/agent-settings-CxfT4ksO.js +0 -1
  442. package/build/assets/automation-BGP_I1RR.js +0 -1
  443. package/build/assets/automation-detail-nEflClmc.js +0 -2
  444. package/build/assets/automation-export-BO_kfqC8.js +0 -2
  445. package/build/assets/automations-list-BYncC7gv.js +0 -1
  446. package/build/assets/backend-form-modal-CKrBF80P.js +0 -1
  447. package/build/assets/browser-3QjrEr1D.js +0 -6
  448. package/build/assets/check-CrxQfJZ2.js +0 -1
  449. package/build/assets/chevron-down-D_LsyTA7.js +0 -1
  450. package/build/assets/circle-check-DZn9HkLE.js +0 -1
  451. package/build/assets/cloud-funnel-analytics-NlmDoeo2.js +0 -1
  452. package/build/assets/command-menu-CvLPs7dg.js +0 -1
  453. package/build/assets/condenser-settings-C4Y9CzQV.js +0 -1
  454. package/build/assets/conversation-D_ORtpKC.js +0 -1
  455. package/build/assets/conversation-Dpc5nmGi.js +0 -90
  456. package/build/assets/conversation-panel-D_ORtpKC.js +0 -1
  457. package/build/assets/conversation-state-store-CGRQemtx.js +0 -1
  458. package/build/assets/files-tab-4c9HFSLo.js +0 -1
  459. package/build/assets/git-provider-icon-0PqmIS_S.js +0 -1
  460. package/build/assets/home-D9JsyEmE.js +0 -1
  461. package/build/assets/home-TFhnmZLx.js +0 -1
  462. package/build/assets/index-home-D9JsyEmE.js +0 -1
  463. package/build/assets/install-server-modal-BgGRnqA0.js +0 -1
  464. package/build/assets/llm-not-configured-banner-Y4W9-sar.js +0 -27
  465. package/build/assets/llm-settings-nPwv7hKu.js +0 -1
  466. package/build/assets/loader-circle-CGD6-Vak.js +0 -1
  467. package/build/assets/manifest-1cf33a7b.js +0 -1
  468. package/build/assets/markdown-renderer-U40HF0Ak.js +0 -8
  469. package/build/assets/mcp-xDMaHzOw.js +0 -9
  470. package/build/assets/messages-CdNfZPgd.js +0 -40
  471. package/build/assets/plus-CTGLo3aa.js +0 -1
  472. package/build/assets/recommended-automations-launcher-Dru1yN46.js +0 -58
  473. package/build/assets/root-B5JXKp1P.css +0 -1
  474. package/build/assets/root-DOLLQteU.js +0 -2
  475. package/build/assets/root-layout-xmylWoew.js +0 -3
  476. package/build/assets/search-BrpWXWUi.js +0 -1
  477. package/build/assets/segmented-toggle-CZKOdIly.js +0 -1
  478. package/build/assets/settings-input-BEaTCem1.js +0 -1
  479. package/build/assets/shared-conversation-BvWtTwES.js +0 -1
  480. package/build/assets/use-agent-profiles-DmT9zxAN.js +0 -1
  481. package/build/assets/use-config-C959QcRC.js +0 -1
  482. package/build/assets/use-is-authed-BsS4XwSL.js +0 -1
  483. package/build/assets/use-llm-profiles-CdaxVpyY.js +0 -1
  484. package/build/assets/use-save-agent-profile-DGJ3-u0M.js +0 -1
  485. package/build/assets/use-settings-nav-items-DPK5sxvR.js +0 -16
  486. package/build/assets/use-tracking-COqZLobY.js +0 -1
  487. package/build/assets/utils-DsWhWn2F.js +0 -1
  488. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation-Acmf1sKj.js +0 -1
  489. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-CmzCY1BT.js +0 -1
  490. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-C7Yh77RT.js +0 -1
  491. package/build/assets/x-Dx_JbpHA.js +0 -1
  492. /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f1hl7voa-BrmgjeOw.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~emdr2jt4-BrmgjeOw.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"pending-user-messages.js","names":[],"sources":["../../../../src/components/features/chat/pending-user-messages.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useOptimisticUserMessageStore } from \"#/stores/optimistic-user-message-store\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { useSendMessage } from \"#/hooks/use-send-message\";\nimport { createChatMessage } from \"#/services/chat-service\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { matchesPendingConversationId } from \"#/utils/pending-task-message-link\";\nimport { ImageCarousel } from \"#/components/features/images/image-carousel\";\nimport { ChatMessage } from \"./chat-message\";\n\n/**\n * Renders the queue of locally-tracked user messages that have been submitted\n * but not yet echoed back through the WebSocket. Each message shows a faded\n * \"sending\" treatment until the server echoes a real `UserMessageEvent`\n * (which removes it via `consumeMatchingPendingMessage`). If the API rejects the\n * send, the message switches to an \"error\" state with a retry button.\n *\n * The queue is global but each entry is tagged with the conversation id it\n * was enqueued from; this component filters to only entries belonging to the\n * active conversation, so switching conversations never carries pending\n * bubbles over.\n */\nexport function PendingUserMessages() {\n const { t } = useTranslation(\"openhands\");\n const { conversationId } = useOptionalConversationId();\n const pendingMessages = useOptimisticUserMessageStore(\n (state) => state.pendingMessages,\n );\n const markPendingMessageError = useOptimisticUserMessageStore(\n (state) => state.markPendingMessageError,\n );\n const markPendingMessageSending = useOptimisticUserMessageStore(\n (state) => state.markPendingMessageSending,\n );\n const removePendingMessage = useOptimisticUserMessageStore(\n (state) => state.removePendingMessage,\n );\n const restoreMessageToInputIfEmpty = useConversationStore(\n (state) => state.restoreMessageToInputIfEmpty,\n );\n const { send } = useSendMessage();\n\n const visibleMessages = React.useMemo(\n () =>\n conversationId\n ? pendingMessages.filter((message) =>\n matchesPendingConversationId(\n conversationId,\n message.conversationId,\n ),\n )\n : [],\n [pendingMessages, conversationId],\n );\n\n const handleRetry = React.useCallback(\n async (id: string) => {\n const message = useOptimisticUserMessageStore\n .getState()\n .pendingMessages.find((entry) => entry.id === id);\n if (!message) return;\n\n markPendingMessageSending(id);\n\n try {\n await send(\n createChatMessage(\n message.text,\n message.imageUrls,\n message.fileUrls,\n message.timestamp,\n ),\n );\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : t(I18nKey.CHAT_INTERFACE$FAILED_TO_SEND_MESSAGE);\n markPendingMessageError(id, errorMessage);\n }\n },\n [send, markPendingMessageError, markPendingMessageSending, t],\n );\n\n const handleStop = React.useCallback(\n (id: string, text: string) => {\n restoreMessageToInputIfEmpty(text);\n removePendingMessage(id);\n },\n [restoreMessageToInputIfEmpty, removePendingMessage],\n );\n\n if (visibleMessages.length === 0) {\n return null;\n }\n\n return (\n <>\n {visibleMessages.map((message) => (\n <ChatMessage\n key={message.id}\n type=\"user\"\n message={message.text}\n pendingStatus={message.status}\n onRetry={\n message.status === \"error\"\n ? () => handleRetry(message.id)\n : undefined\n }\n onStop={\n message.status === \"sending\"\n ? () => handleStop(message.id, message.text)\n : undefined\n }\n >\n {message.imageUrls.length > 0 && (\n <ImageCarousel size=\"small\" images={message.imageUrls} />\n )}\n </ChatMessage>\n ))}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAwBA,SAAgB,IAAsB;CACpC,IAAM,EAAE,SAAM,EAAe,WAAW,GAClC,EAAE,sBAAmB,EAA0B,GAC/C,IAAkB,GACrB,MAAU,EAAM,eACnB,GACM,IAA0B,GAC7B,MAAU,EAAM,uBACnB,GACM,IAA4B,GAC/B,MAAU,EAAM,yBACnB,GACM,IAAuB,GAC1B,MAAU,EAAM,oBACnB,GACM,IAA+B,GAClC,MAAU,EAAM,4BACnB,GACM,EAAE,YAAS,EAAe,GAE1B,IAAkB,EAAM,cAE1B,IACI,EAAgB,QAAQ,MACtB,EACE,GACA,EAAQ,cACV,CACF,IACA,CAAC,GACP,CAAC,GAAiB,CAAc,CAClC,GAEM,IAAc,EAAM,YACxB,OAAO,MAAe;EACpB,IAAM,IAAU,EACb,SAAS,EACT,gBAAgB,MAAM,MAAU,EAAM,OAAO,CAAE;EAC7C,OAEL;KAA0B,CAAE;GAE5B,IAAI;IACF,MAAM,EACJ,EACE,EAAQ,MACR,EAAQ,WACR,EAAQ,UACR,EAAQ,SACV,CACF;GACF,SAAS,GAAO;IAKd,EAAwB,GAHtB,aAAiB,QACb,EAAM,UACN,EAAE,EAAQ,qCAAqC,CACb;GAC1C;EAjB4B;CAkB9B,GACA;EAAC;EAAM;EAAyB;EAA2B;CAAC,CAC9D,GAEM,IAAa,EAAM,aACtB,GAAY,MAAiB;EAE5B,AADA,EAA6B,CAAI,GACjC,EAAqB,CAAE;CACzB,GACA,CAAC,GAA8B,CAAoB,CACrD;CAMA,OAJI,EAAgB,WAAW,IACtB,OAIP,kBAAA,GAAA,EAAA,UACG,EAAgB,KAAK,MACpB,kBAAC,GAAD;EAEE,MAAK;EACL,SAAS,EAAQ;EACjB,eAAe,EAAQ;EACvB,SACE,EAAQ,WAAW,gBACT,EAAY,EAAQ,EAAE,IAC5B,KAAA;EAEN,QACE,EAAQ,WAAW,kBACT,EAAW,EAAQ,IAAI,EAAQ,IAAI,IACzC,KAAA;YAGL,EAAQ,UAAU,SAAS,KAC1B,kBAAC,GAAD;GAAe,MAAK;GAAQ,QAAQ,EAAQ;EAAY,CAAA;CAE/C,GAlBN,EAAQ,EAkBF,CACd,EACD,CAAA;AAEN"}
1
+ {"version":3,"file":"pending-user-messages.js","names":[],"sources":["../../../../src/components/features/chat/pending-user-messages.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useOptimisticUserMessageStore } from \"#/stores/optimistic-user-message-store\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { useSendMessage } from \"#/hooks/use-send-message\";\nimport { createChatMessage } from \"#/services/chat-service\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { matchesPendingConversationId } from \"#/utils/pending-task-message-link\";\nimport { ImageCarousel } from \"#/components/features/images/image-carousel\";\nimport { ChatMessage } from \"./chat-message\";\n\n/**\n * Renders the queue of locally-tracked user messages that have been submitted\n * but not yet echoed back through the WebSocket. Each message shows a faded\n * \"sending\" treatment until the server echoes a real `UserMessageEvent`\n * (which removes it via `consumeMatchingPendingMessage`). If the API rejects the\n * send, the message switches to an \"error\" state with a retry button.\n *\n * The queue is global but each entry is tagged with the conversation id it\n * was enqueued from; this component filters to only entries belonging to the\n * active conversation, so switching conversations never carries pending\n * bubbles over.\n */\nexport function PendingUserMessages() {\n const { t } = useTranslation(\"openhands\");\n const { conversationId } = useOptionalConversationId();\n const pendingMessages = useOptimisticUserMessageStore(\n (state) => state.pendingMessages,\n );\n const markPendingMessageError = useOptimisticUserMessageStore(\n (state) => state.markPendingMessageError,\n );\n const markPendingMessageSending = useOptimisticUserMessageStore(\n (state) => state.markPendingMessageSending,\n );\n const removePendingMessage = useOptimisticUserMessageStore(\n (state) => state.removePendingMessage,\n );\n const restoreMessageToInputIfEmpty = useConversationStore(\n (state) => state.restoreMessageToInputIfEmpty,\n );\n const { send } = useSendMessage();\n\n const visibleMessages = React.useMemo(\n () =>\n conversationId\n ? pendingMessages.filter((message) =>\n matchesPendingConversationId(\n conversationId,\n message.conversationId,\n ),\n )\n : [],\n [pendingMessages, conversationId],\n );\n\n const handleRetry = React.useCallback(\n async (id: string) => {\n const message = useOptimisticUserMessageStore\n .getState()\n .pendingMessages.find((entry) => entry.id === id);\n if (!message) return;\n\n markPendingMessageSending(id);\n\n try {\n await send(\n createChatMessage(\n message.text,\n message.imageUrls,\n message.fileUrls,\n message.timestamp,\n ),\n );\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : t(I18nKey.CHAT_INTERFACE$FAILED_TO_SEND_MESSAGE);\n markPendingMessageError(id, errorMessage);\n }\n },\n [send, markPendingMessageError, markPendingMessageSending, t],\n );\n\n const handleStop = React.useCallback(\n (id: string, text: string) => {\n restoreMessageToInputIfEmpty(text);\n removePendingMessage(id);\n },\n [restoreMessageToInputIfEmpty, removePendingMessage],\n );\n\n const handleDismiss = React.useCallback(\n (id: string) => {\n removePendingMessage(id);\n },\n [removePendingMessage],\n );\n\n if (visibleMessages.length === 0) {\n return null;\n }\n\n return (\n <>\n {visibleMessages.map((message) => (\n <ChatMessage\n key={message.id}\n type=\"user\"\n message={message.text}\n pendingStatus={message.status}\n onRetry={\n message.status === \"error\"\n ? () => handleRetry(message.id)\n : undefined\n }\n onDismiss={\n message.status === \"error\"\n ? () => handleDismiss(message.id)\n : undefined\n }\n onStop={\n message.status === \"sending\"\n ? () => handleStop(message.id, message.text)\n : undefined\n }\n >\n {message.imageUrls.length > 0 && (\n <ImageCarousel size=\"small\" images={message.imageUrls} />\n )}\n </ChatMessage>\n ))}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAwBA,SAAgB,IAAsB;CACpC,IAAM,EAAE,SAAM,EAAe,WAAW,GAClC,EAAE,sBAAmB,EAA0B,GAC/C,IAAkB,GACrB,MAAU,EAAM,eACnB,GACM,IAA0B,GAC7B,MAAU,EAAM,uBACnB,GACM,IAA4B,GAC/B,MAAU,EAAM,yBACnB,GACM,IAAuB,GAC1B,MAAU,EAAM,oBACnB,GACM,IAA+B,GAClC,MAAU,EAAM,4BACnB,GACM,EAAE,YAAS,EAAe,GAE1B,IAAkB,EAAM,cAE1B,IACI,EAAgB,QAAQ,MACtB,EACE,GACA,EAAQ,cACV,CACF,IACA,CAAC,GACP,CAAC,GAAiB,CAAc,CAClC,GAEM,IAAc,EAAM,YACxB,OAAO,MAAe;EACpB,IAAM,IAAU,EACb,SAAS,EACT,gBAAgB,MAAM,MAAU,EAAM,OAAO,CAAE;EAC7C,OAEL;KAA0B,CAAE;GAE5B,IAAI;IACF,MAAM,EACJ,EACE,EAAQ,MACR,EAAQ,WACR,EAAQ,UACR,EAAQ,SACV,CACF;GACF,SAAS,GAAO;IAKd,EAAwB,GAHtB,aAAiB,QACb,EAAM,UACN,EAAE,EAAQ,qCAAqC,CACb;GAC1C;EAjB4B;CAkB9B,GACA;EAAC;EAAM;EAAyB;EAA2B;CAAC,CAC9D,GAEM,IAAa,EAAM,aACtB,GAAY,MAAiB;EAE5B,AADA,EAA6B,CAAI,GACjC,EAAqB,CAAE;CACzB,GACA,CAAC,GAA8B,CAAoB,CACrD,GAEM,IAAgB,EAAM,aACzB,MAAe;EACd,EAAqB,CAAE;CACzB,GACA,CAAC,CAAoB,CACvB;CAMA,OAJI,EAAgB,WAAW,IACtB,OAIP,kBAAA,GAAA,EAAA,UACG,EAAgB,KAAK,MACpB,kBAAC,GAAD;EAEE,MAAK;EACL,SAAS,EAAQ;EACjB,eAAe,EAAQ;EACvB,SACE,EAAQ,WAAW,gBACT,EAAY,EAAQ,EAAE,IAC5B,KAAA;EAEN,WACE,EAAQ,WAAW,gBACT,EAAc,EAAQ,EAAE,IAC9B,KAAA;EAEN,QACE,EAAQ,WAAW,kBACT,EAAW,EAAQ,IAAI,EAAQ,IAAI,IACzC,KAAA;YAGL,EAAQ,UAAU,SAAS,KAC1B,kBAAC,GAAD;GAAe,MAAK;GAAQ,QAAQ,EAAQ;EAAY,CAAA;CAE/C,GAvBN,EAAQ,EAuBF,CACd,EACD,CAAA;AAEN"}
@@ -1,2 +1,2 @@
1
- require("../../../_virtual/_rolldown/runtime.cjs");let e=require("react/jsx-runtime");function t(){return(0,e.jsxs)(`div`,{className:`flex items-center space-x-1.5 rounded-full bg-[var(--oh-surface)] px-3 py-1.5`,children:[(0,e.jsx)(`span`,{className:`h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:0ms]`}),(0,e.jsx)(`span`,{className:`h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:75ms]`}),(0,e.jsx)(`span`,{className:`h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:150ms]`})]})}exports.TypingIndicator=t;
1
+ require("../../../_virtual/_rolldown/runtime.cjs");const e=require("../../../node_modules/react-i18next/dist/es/Trans.cjs"),t=require("../../../types/agent-server/type-guards.cjs"),n=require("../../conversation-events/chat/event-content-helpers/get-acp-tool-call-content.cjs"),r=require("../../conversation-events/chat/event-content-helpers/get-action-event-title.cjs"),i=require("./mono-component.cjs"),a=require("./path-component.cjs");let o=require("react/jsx-runtime");var s={kind:`translation`,key:`ACTION_MESSAGE$THINK`,values:{}},c=new Set([`ExecuteBashAction`,`TerminalAction`,`FileEditorAction`,`StrReplaceEditorAction`,`MCPToolAction`,`InvokeSkillAction`,`TaskAction`,`ThinkAction`,`TaskTrackerAction`,`GrepAction`,`GlobAction`,`BrowserNavigateAction`,`BrowserClickAction`,`BrowserTypeAction`,`BrowserGetStateAction`,`BrowserGetContentAction`,`BrowserScrollAction`,`BrowserGoBackAction`,`BrowserListTabsAction`,`BrowserSwitchTabAction`,`BrowserCloseTabAction`]),l=e=>{if(!t.isActionEvent(e))return null;let n=r.getActionSummaryTitle(e);return n?{kind:`text`,text:n}:c.has(e.action.kind)?r.getActionEventTitleDescriptor(e):null},u=e=>e.source===`environment`&&`rejection_reason`in e,d=e=>{let r=new Set,i=new Set;for(let a=e.length-1;a>=0;--a){let o=e[a];if(!o.isFromPlanningAgent){if(t.isObservationEvent(o)||u(o)){r.add(o.action_id),i.add(o.tool_call_id);continue}if(t.isAgentErrorEvent(o)){i.add(o.tool_call_id);continue}if(t.isACPToolCallEvent(o)){if(!(o.status===`pending`||o.status===`in_progress`)){i.add(o.tool_call_id);continue}if(i.has(o.tool_call_id))continue;let e=n.stripRedundantTitlePrefix(o);return e?{kind:`translation`,key:n.getACPToolCallTitleKey(o),values:{title:e}}:s}if(t.isActionEvent(o)&&!r.has(o.id)&&!i.has(o.tool_call_id))return l(o)??s}}return s};function f({events:t}){let n=d(t);return(0,o.jsxs)(`div`,{className:`flex min-w-0 max-w-full items-center gap-2 rounded-full border border-[var(--oh-border)] bg-[var(--oh-surface)] px-3 py-1.5 text-xs text-[var(--oh-text-secondary)]`,"data-testid":`live-activity-chip`,role:`status`,"aria-live":`polite`,children:[(0,o.jsx)(`span`,{"aria-hidden":`true`,className:`size-1.5 shrink-0 animate-pulse rounded-full bg-[var(--oh-status-success)] motion-reduce:animate-none`}),(0,o.jsx)(`span`,{className:`min-w-0 truncate`,children:n.kind===`text`?n.text:(0,o.jsx)(e.Trans,{ns:`openhands`,i18nKey:n.key,values:n.values,components:{path:(0,o.jsx)(a.PathComponent,{}),cmd:(0,o.jsx)(i.MonoComponent,{})}})})]})}exports.TypingIndicator=f;
2
2
  //# sourceMappingURL=typing-indicator.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"typing-indicator.cjs","names":[],"sources":["../../../../src/components/features/chat/typing-indicator.tsx"],"sourcesContent":["export function TypingIndicator() {\n return (\n <div className=\"flex items-center space-x-1.5 rounded-full bg-[var(--oh-surface)] px-3 py-1.5\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:0ms]\" />\n <span className=\"h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:75ms]\" />\n <span className=\"h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:150ms]\" />\n </div>\n );\n}\n"],"mappings":"sFAAA,SAAgB,GAAkB,CAChC,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yFAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,sHAAwH,CAAA,GACxI,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,uHAAyH,CAAA,GACzI,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,wHAA0H,CAAA,CACvI,GAET"}
1
+ {"version":3,"file":"typing-indicator.cjs","names":[],"sources":["../../../../src/components/features/chat/typing-indicator.tsx"],"sourcesContent":["import { Trans } from \"react-i18next\";\nimport type { OHEvent } from \"#/stores/use-event-store\";\nimport type { UserRejectObservation } from \"#/types/agent-server/core\";\nimport {\n isACPToolCallEvent,\n isActionEvent,\n isAgentErrorEvent,\n isObservationEvent,\n} from \"#/types/agent-server/type-guards\";\nimport {\n getACPToolCallTitleKey,\n stripRedundantTitlePrefix,\n} from \"#/components/conversation-events/chat/event-content-helpers/get-acp-tool-call-content\";\nimport {\n getActionEventTitleDescriptor,\n getActionSummaryTitle,\n type EventTitleDescriptor,\n} from \"#/components/conversation-events/chat/event-content-helpers/get-action-event-title\";\nimport { MonoComponent } from \"./mono-component\";\nimport { PathComponent } from \"./path-component\";\n\nconst THINKING_ACTIVITY: EventTitleDescriptor = {\n kind: \"translation\",\n key: \"ACTION_MESSAGE$THINK\",\n values: {},\n};\n\nconst LIVE_ACTION_KINDS = new Set([\n \"ExecuteBashAction\",\n \"TerminalAction\",\n \"FileEditorAction\",\n \"StrReplaceEditorAction\",\n \"MCPToolAction\",\n \"InvokeSkillAction\",\n \"TaskAction\",\n \"ThinkAction\",\n \"TaskTrackerAction\",\n \"GrepAction\",\n \"GlobAction\",\n \"BrowserNavigateAction\",\n \"BrowserClickAction\",\n \"BrowserTypeAction\",\n \"BrowserGetStateAction\",\n \"BrowserGetContentAction\",\n \"BrowserScrollAction\",\n \"BrowserGoBackAction\",\n \"BrowserListTabsAction\",\n \"BrowserSwitchTabAction\",\n \"BrowserCloseTabAction\",\n]);\n\nconst getLiveActionTitle = (event: OHEvent): EventTitleDescriptor | null => {\n if (!isActionEvent(event)) return null;\n\n const summary = getActionSummaryTitle(event);\n if (summary) {\n return { kind: \"text\", text: summary };\n }\n\n return LIVE_ACTION_KINDS.has(event.action.kind)\n ? getActionEventTitleDescriptor(event)\n : null;\n};\n\nconst isUserRejectObservation = (\n event: OHEvent,\n): event is UserRejectObservation =>\n event.source === \"environment\" && \"rejection_reason\" in event;\n\nexport const deriveLiveActivity = (\n events: readonly OHEvent[],\n): EventTitleDescriptor => {\n const resolvedActionIds = new Set<string>();\n const resolvedToolCallIds = new Set<string>();\n\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index];\n if (event.isFromPlanningAgent) {\n continue;\n }\n\n if (isObservationEvent(event) || isUserRejectObservation(event)) {\n resolvedActionIds.add(event.action_id);\n resolvedToolCallIds.add(event.tool_call_id);\n continue;\n }\n\n if (isAgentErrorEvent(event)) {\n resolvedToolCallIds.add(event.tool_call_id);\n continue;\n }\n\n if (isACPToolCallEvent(event)) {\n const isInProgress =\n event.status === \"pending\" || event.status === \"in_progress\";\n if (!isInProgress) {\n resolvedToolCallIds.add(event.tool_call_id);\n continue;\n }\n if (resolvedToolCallIds.has(event.tool_call_id)) {\n continue;\n }\n\n const title = stripRedundantTitlePrefix(event);\n return title\n ? {\n kind: \"translation\",\n key: getACPToolCallTitleKey(event),\n values: { title },\n }\n : THINKING_ACTIVITY;\n }\n\n if (\n isActionEvent(event) &&\n !resolvedActionIds.has(event.id) &&\n !resolvedToolCallIds.has(event.tool_call_id)\n ) {\n return getLiveActionTitle(event) ?? THINKING_ACTIVITY;\n }\n }\n\n return THINKING_ACTIVITY;\n};\n\ninterface TypingIndicatorProps {\n readonly events: readonly OHEvent[];\n}\n\nexport function TypingIndicator({ events }: TypingIndicatorProps) {\n const activity = deriveLiveActivity(events);\n\n return (\n <div\n className=\"flex min-w-0 max-w-full items-center gap-2 rounded-full border border-[var(--oh-border)] bg-[var(--oh-surface)] px-3 py-1.5 text-xs text-[var(--oh-text-secondary)]\"\n data-testid=\"live-activity-chip\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <span\n aria-hidden=\"true\"\n className=\"size-1.5 shrink-0 animate-pulse rounded-full bg-[var(--oh-status-success)] motion-reduce:animate-none\"\n />\n <span className=\"min-w-0 truncate\">\n {activity.kind === \"text\" ? (\n activity.text\n ) : (\n <Trans\n ns=\"openhands\"\n i18nKey={activity.key}\n values={activity.values}\n components={{\n path: <PathComponent />,\n cmd: <MonoComponent />,\n }}\n />\n )}\n </span>\n </div>\n );\n}\n"],"mappings":"ydAqBA,IAAM,EAA0C,CAC9C,KAAM,cACN,IAAK,uBACL,OAAQ,CAAC,CACX,EAEM,EAAoB,IAAI,IAAI,CAChC,oBACA,iBACA,mBACA,yBACA,gBACA,oBACA,aACA,cACA,oBACA,aACA,aACA,wBACA,qBACA,oBACA,wBACA,0BACA,sBACA,sBACA,wBACA,yBACA,uBACF,CAAC,EAEK,EAAsB,GAAgD,CAC1E,GAAI,CAAC,EAAA,cAAc,CAAK,EAAG,OAAO,KAElC,IAAM,EAAU,EAAA,sBAAsB,CAAK,EAK3C,OAJI,EACK,CAAE,KAAM,OAAQ,KAAM,CAAQ,EAGhC,EAAkB,IAAI,EAAM,OAAO,IAAI,EAC1C,EAAA,8BAA8B,CAAK,EACnC,IACN,EAEM,EACJ,GAEA,EAAM,SAAW,eAAiB,qBAAsB,EAE7C,EACX,GACyB,CACzB,IAAM,EAAoB,IAAI,IACxB,EAAsB,IAAI,IAEhC,IAAK,IAAI,EAAQ,EAAO,OAAS,EAAG,GAAS,EAAG,IAAY,CAC1D,IAAM,EAAQ,EAAO,GACjB,MAAM,oBAIV,IAAI,EAAA,mBAAmB,CAAK,GAAK,EAAwB,CAAK,EAAG,CAC/D,EAAkB,IAAI,EAAM,SAAS,EACrC,EAAoB,IAAI,EAAM,YAAY,EAC1C,QACF,CAEA,GAAI,EAAA,kBAAkB,CAAK,EAAG,CAC5B,EAAoB,IAAI,EAAM,YAAY,EAC1C,QACF,CAEA,GAAI,EAAA,mBAAmB,CAAK,EAAG,CAG7B,GAAI,EADF,EAAM,SAAW,WAAa,EAAM,SAAW,eAC9B,CACjB,EAAoB,IAAI,EAAM,YAAY,EAC1C,QACF,CACA,GAAI,EAAoB,IAAI,EAAM,YAAY,EAC5C,SAGF,IAAM,EAAQ,EAAA,0BAA0B,CAAK,EAC7C,OAAO,EACH,CACE,KAAM,cACN,IAAK,EAAA,uBAAuB,CAAK,EACjC,OAAQ,CAAE,OAAM,CAClB,EACA,CACN,CAEA,GACE,EAAA,cAAc,CAAK,GACnB,CAAC,EAAkB,IAAI,EAAM,EAAE,GAC/B,CAAC,EAAoB,IAAI,EAAM,YAAY,EAE3C,OAAO,EAAmB,CAAK,GAAK,CAjCtC,CAmCF,CAEA,OAAO,CACT,EAMA,SAAgB,EAAgB,CAAE,UAAgC,CAChE,IAAM,EAAW,EAAmB,CAAM,EAE1C,OACE,EAAA,EAAA,MAAC,MAAD,CACE,UAAU,sKACV,cAAY,qBACZ,KAAK,SACL,YAAU,kBAJZ,EAME,EAAA,EAAA,KAAC,OAAD,CACE,cAAY,OACZ,UAAU,uGACX,CAAA,GACD,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,4BACb,EAAS,OAAS,OACjB,EAAS,MAET,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,GAAG,YACH,QAAS,EAAS,IAClB,OAAQ,EAAS,OACjB,WAAY,CACV,MAAM,EAAA,EAAA,KAAC,EAAA,cAAD,CAAgB,CAAA,EACtB,KAAK,EAAA,EAAA,KAAC,EAAA,cAAD,CAAgB,CAAA,CACvB,CACD,CAAA,CAEC,CAAA,CACH,GAET"}
@@ -1 +1,8 @@
1
- export declare function TypingIndicator(): import("react/jsx-runtime").JSX.Element;
1
+ import type { OHEvent } from "#/stores/use-event-store";
2
+ import { type EventTitleDescriptor } from "#/components/conversation-events/chat/event-content-helpers/get-action-event-title";
3
+ export declare const deriveLiveActivity: (events: readonly OHEvent[]) => EventTitleDescriptor;
4
+ interface TypingIndicatorProps {
5
+ readonly events: readonly OHEvent[];
6
+ }
7
+ export declare function TypingIndicator({ events }: TypingIndicatorProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -1,16 +1,100 @@
1
- import { jsx as e, jsxs as t } from "react/jsx-runtime";
1
+ import { Trans as e } from "../../../node_modules/react-i18next/dist/es/Trans.js";
2
+ import { isACPToolCallEvent as t, isActionEvent as n, isAgentErrorEvent as r, isObservationEvent as i } from "../../../types/agent-server/type-guards.js";
3
+ import { getACPToolCallTitleKey as a, stripRedundantTitlePrefix as o } from "../../conversation-events/chat/event-content-helpers/get-acp-tool-call-content.js";
4
+ import { getActionEventTitleDescriptor as s, getActionSummaryTitle as c } from "../../conversation-events/chat/event-content-helpers/get-action-event-title.js";
5
+ import { MonoComponent as l } from "./mono-component.js";
6
+ import { PathComponent as u } from "./path-component.js";
7
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
2
8
  //#region src/components/features/chat/typing-indicator.tsx
3
- function n() {
4
- return /* @__PURE__ */ t("div", {
5
- className: "flex items-center space-x-1.5 rounded-full bg-[var(--oh-surface)] px-3 py-1.5",
6
- children: [
7
- /* @__PURE__ */ e("span", { className: "h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:0ms]" }),
8
- /* @__PURE__ */ e("span", { className: "h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:75ms]" }),
9
- /* @__PURE__ */ e("span", { className: "h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:150ms]" })
10
- ]
9
+ var p = {
10
+ kind: "translation",
11
+ key: "ACTION_MESSAGE$THINK",
12
+ values: {}
13
+ }, m = new Set([
14
+ "ExecuteBashAction",
15
+ "TerminalAction",
16
+ "FileEditorAction",
17
+ "StrReplaceEditorAction",
18
+ "MCPToolAction",
19
+ "InvokeSkillAction",
20
+ "TaskAction",
21
+ "ThinkAction",
22
+ "TaskTrackerAction",
23
+ "GrepAction",
24
+ "GlobAction",
25
+ "BrowserNavigateAction",
26
+ "BrowserClickAction",
27
+ "BrowserTypeAction",
28
+ "BrowserGetStateAction",
29
+ "BrowserGetContentAction",
30
+ "BrowserScrollAction",
31
+ "BrowserGoBackAction",
32
+ "BrowserListTabsAction",
33
+ "BrowserSwitchTabAction",
34
+ "BrowserCloseTabAction"
35
+ ]), h = (e) => {
36
+ if (!n(e)) return null;
37
+ let t = c(e);
38
+ return t ? {
39
+ kind: "text",
40
+ text: t
41
+ } : m.has(e.action.kind) ? s(e) : null;
42
+ }, g = (e) => e.source === "environment" && "rejection_reason" in e, _ = (e) => {
43
+ let s = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Set();
44
+ for (let l = e.length - 1; l >= 0; --l) {
45
+ let u = e[l];
46
+ if (!u.isFromPlanningAgent) {
47
+ if (i(u) || g(u)) {
48
+ s.add(u.action_id), c.add(u.tool_call_id);
49
+ continue;
50
+ }
51
+ if (r(u)) {
52
+ c.add(u.tool_call_id);
53
+ continue;
54
+ }
55
+ if (t(u)) {
56
+ if (!(u.status === "pending" || u.status === "in_progress")) {
57
+ c.add(u.tool_call_id);
58
+ continue;
59
+ }
60
+ if (c.has(u.tool_call_id)) continue;
61
+ let e = o(u);
62
+ return e ? {
63
+ kind: "translation",
64
+ key: a(u),
65
+ values: { title: e }
66
+ } : p;
67
+ }
68
+ if (n(u) && !s.has(u.id) && !c.has(u.tool_call_id)) return h(u) ?? p;
69
+ }
70
+ }
71
+ return p;
72
+ };
73
+ function v({ events: t }) {
74
+ let n = _(t);
75
+ return /* @__PURE__ */ f("div", {
76
+ className: "flex min-w-0 max-w-full items-center gap-2 rounded-full border border-[var(--oh-border)] bg-[var(--oh-surface)] px-3 py-1.5 text-xs text-[var(--oh-text-secondary)]",
77
+ "data-testid": "live-activity-chip",
78
+ role: "status",
79
+ "aria-live": "polite",
80
+ children: [/* @__PURE__ */ d("span", {
81
+ "aria-hidden": "true",
82
+ className: "size-1.5 shrink-0 animate-pulse rounded-full bg-[var(--oh-status-success)] motion-reduce:animate-none"
83
+ }), /* @__PURE__ */ d("span", {
84
+ className: "min-w-0 truncate",
85
+ children: n.kind === "text" ? n.text : /* @__PURE__ */ d(e, {
86
+ ns: "openhands",
87
+ i18nKey: n.key,
88
+ values: n.values,
89
+ components: {
90
+ path: /* @__PURE__ */ d(u, {}),
91
+ cmd: /* @__PURE__ */ d(l, {})
92
+ }
93
+ })
94
+ })]
11
95
  });
12
96
  }
13
97
  //#endregion
14
- export { n as TypingIndicator };
98
+ export { v as TypingIndicator };
15
99
 
16
100
  //# sourceMappingURL=typing-indicator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"typing-indicator.js","names":[],"sources":["../../../../src/components/features/chat/typing-indicator.tsx"],"sourcesContent":["export function TypingIndicator() {\n return (\n <div className=\"flex items-center space-x-1.5 rounded-full bg-[var(--oh-surface)] px-3 py-1.5\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:0ms]\" />\n <span className=\"h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:75ms]\" />\n <span className=\"h-1.5 w-1.5 rounded-full bg-[var(--oh-muted)] animate-[bounce_0.5s_infinite] translate-y-[1px] [animation-delay:150ms]\" />\n </div>\n );\n}\n"],"mappings":";;AAAA,SAAgB,IAAkB;CAChC,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,QAAD,EAAM,WAAU,uHAAwH,CAAA;GACxI,kBAAC,QAAD,EAAM,WAAU,wHAAyH,CAAA;GACzI,kBAAC,QAAD,EAAM,WAAU,yHAA0H,CAAA;EACvI;;AAET"}
1
+ {"version":3,"file":"typing-indicator.js","names":[],"sources":["../../../../src/components/features/chat/typing-indicator.tsx"],"sourcesContent":["import { Trans } from \"react-i18next\";\nimport type { OHEvent } from \"#/stores/use-event-store\";\nimport type { UserRejectObservation } from \"#/types/agent-server/core\";\nimport {\n isACPToolCallEvent,\n isActionEvent,\n isAgentErrorEvent,\n isObservationEvent,\n} from \"#/types/agent-server/type-guards\";\nimport {\n getACPToolCallTitleKey,\n stripRedundantTitlePrefix,\n} from \"#/components/conversation-events/chat/event-content-helpers/get-acp-tool-call-content\";\nimport {\n getActionEventTitleDescriptor,\n getActionSummaryTitle,\n type EventTitleDescriptor,\n} from \"#/components/conversation-events/chat/event-content-helpers/get-action-event-title\";\nimport { MonoComponent } from \"./mono-component\";\nimport { PathComponent } from \"./path-component\";\n\nconst THINKING_ACTIVITY: EventTitleDescriptor = {\n kind: \"translation\",\n key: \"ACTION_MESSAGE$THINK\",\n values: {},\n};\n\nconst LIVE_ACTION_KINDS = new Set([\n \"ExecuteBashAction\",\n \"TerminalAction\",\n \"FileEditorAction\",\n \"StrReplaceEditorAction\",\n \"MCPToolAction\",\n \"InvokeSkillAction\",\n \"TaskAction\",\n \"ThinkAction\",\n \"TaskTrackerAction\",\n \"GrepAction\",\n \"GlobAction\",\n \"BrowserNavigateAction\",\n \"BrowserClickAction\",\n \"BrowserTypeAction\",\n \"BrowserGetStateAction\",\n \"BrowserGetContentAction\",\n \"BrowserScrollAction\",\n \"BrowserGoBackAction\",\n \"BrowserListTabsAction\",\n \"BrowserSwitchTabAction\",\n \"BrowserCloseTabAction\",\n]);\n\nconst getLiveActionTitle = (event: OHEvent): EventTitleDescriptor | null => {\n if (!isActionEvent(event)) return null;\n\n const summary = getActionSummaryTitle(event);\n if (summary) {\n return { kind: \"text\", text: summary };\n }\n\n return LIVE_ACTION_KINDS.has(event.action.kind)\n ? getActionEventTitleDescriptor(event)\n : null;\n};\n\nconst isUserRejectObservation = (\n event: OHEvent,\n): event is UserRejectObservation =>\n event.source === \"environment\" && \"rejection_reason\" in event;\n\nexport const deriveLiveActivity = (\n events: readonly OHEvent[],\n): EventTitleDescriptor => {\n const resolvedActionIds = new Set<string>();\n const resolvedToolCallIds = new Set<string>();\n\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index];\n if (event.isFromPlanningAgent) {\n continue;\n }\n\n if (isObservationEvent(event) || isUserRejectObservation(event)) {\n resolvedActionIds.add(event.action_id);\n resolvedToolCallIds.add(event.tool_call_id);\n continue;\n }\n\n if (isAgentErrorEvent(event)) {\n resolvedToolCallIds.add(event.tool_call_id);\n continue;\n }\n\n if (isACPToolCallEvent(event)) {\n const isInProgress =\n event.status === \"pending\" || event.status === \"in_progress\";\n if (!isInProgress) {\n resolvedToolCallIds.add(event.tool_call_id);\n continue;\n }\n if (resolvedToolCallIds.has(event.tool_call_id)) {\n continue;\n }\n\n const title = stripRedundantTitlePrefix(event);\n return title\n ? {\n kind: \"translation\",\n key: getACPToolCallTitleKey(event),\n values: { title },\n }\n : THINKING_ACTIVITY;\n }\n\n if (\n isActionEvent(event) &&\n !resolvedActionIds.has(event.id) &&\n !resolvedToolCallIds.has(event.tool_call_id)\n ) {\n return getLiveActionTitle(event) ?? THINKING_ACTIVITY;\n }\n }\n\n return THINKING_ACTIVITY;\n};\n\ninterface TypingIndicatorProps {\n readonly events: readonly OHEvent[];\n}\n\nexport function TypingIndicator({ events }: TypingIndicatorProps) {\n const activity = deriveLiveActivity(events);\n\n return (\n <div\n className=\"flex min-w-0 max-w-full items-center gap-2 rounded-full border border-[var(--oh-border)] bg-[var(--oh-surface)] px-3 py-1.5 text-xs text-[var(--oh-text-secondary)]\"\n data-testid=\"live-activity-chip\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <span\n aria-hidden=\"true\"\n className=\"size-1.5 shrink-0 animate-pulse rounded-full bg-[var(--oh-status-success)] motion-reduce:animate-none\"\n />\n <span className=\"min-w-0 truncate\">\n {activity.kind === \"text\" ? (\n activity.text\n ) : (\n <Trans\n ns=\"openhands\"\n i18nKey={activity.key}\n values={activity.values}\n components={{\n path: <PathComponent />,\n cmd: <MonoComponent />,\n }}\n />\n )}\n </span>\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAqBA,IAAM,IAA0C;CAC9C,MAAM;CACN,KAAK;CACL,QAAQ,CAAC;AACX,GAEM,IAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,GAEK,KAAsB,MAAgD;CAC1E,IAAI,CAAC,EAAc,CAAK,GAAG,OAAO;CAElC,IAAM,IAAU,EAAsB,CAAK;CAK3C,OAJI,IACK;EAAE,MAAM;EAAQ,MAAM;CAAQ,IAGhC,EAAkB,IAAI,EAAM,OAAO,IAAI,IAC1C,EAA8B,CAAK,IACnC;AACN,GAEM,KACJ,MAEA,EAAM,WAAW,iBAAiB,sBAAsB,GAE7C,KACX,MACyB;CACzB,IAAM,oBAAoB,IAAI,IAAY,GACpC,oBAAsB,IAAI,IAAY;CAE5C,KAAK,IAAI,IAAQ,EAAO,SAAS,GAAG,KAAS,GAAG,KAAY;EAC1D,IAAM,IAAQ,EAAO;EACjB,OAAM,qBAIV;OAAI,EAAmB,CAAK,KAAK,EAAwB,CAAK,GAAG;IAE/D,AADA,EAAkB,IAAI,EAAM,SAAS,GACrC,EAAoB,IAAI,EAAM,YAAY;IAC1C;GACF;GAEA,IAAI,EAAkB,CAAK,GAAG;IAC5B,EAAoB,IAAI,EAAM,YAAY;IAC1C;GACF;GAEA,IAAI,EAAmB,CAAK,GAAG;IAG7B,IAAI,EADF,EAAM,WAAW,aAAa,EAAM,WAAW,gBAC9B;KACjB,EAAoB,IAAI,EAAM,YAAY;KAC1C;IACF;IACA,IAAI,EAAoB,IAAI,EAAM,YAAY,GAC5C;IAGF,IAAM,IAAQ,EAA0B,CAAK;IAC7C,OAAO,IACH;KACE,MAAM;KACN,KAAK,EAAuB,CAAK;KACjC,QAAQ,EAAE,SAAM;IAClB,IACA;GACN;GAEA,IACE,EAAc,CAAK,KACnB,CAAC,EAAkB,IAAI,EAAM,EAAE,KAC/B,CAAC,EAAoB,IAAI,EAAM,YAAY,GAE3C,OAAO,EAAmB,CAAK,KAAK;EAjCtC;CAmCF;CAEA,OAAO;AACT;AAMA,SAAgB,EAAgB,EAAE,aAAgC;CAChE,IAAM,IAAW,EAAmB,CAAM;CAE1C,OACE,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;EACZ,MAAK;EACL,aAAU;YAJZ,CAME,kBAAC,QAAD;GACE,eAAY;GACZ,WAAU;EACX,CAAA,GACD,kBAAC,QAAD;GAAM,WAAU;aACb,EAAS,SAAS,SACjB,EAAS,OAET,kBAAC,GAAD;IACE,IAAG;IACH,SAAS,EAAS;IAClB,QAAQ,EAAS;IACjB,YAAY;KACV,MAAM,kBAAC,GAAD,CAAgB,CAAA;KACtB,KAAK,kBAAC,GAAD,CAAgB,CAAA;IACvB;GACD,CAAA;EAEC,CAAA,CACH;;AAET"}
@@ -3,7 +3,7 @@ import { I18nKey } from "#/i18n/declaration";
3
3
  export declare const COMMAND_MENU_ROUTE: {
4
4
  readonly conversations: "/conversations";
5
5
  readonly customize: "/customize";
6
- readonly automations: "/automations";
6
+ readonly automations: string;
7
7
  readonly mcp: "/mcp";
8
8
  readonly settings: "/settings";
9
9
  readonly agentSettings: "/settings/agents";
@@ -21,6 +21,10 @@ export interface CommandMenuItemDefinition {
21
21
  titleKey: I18nKey;
22
22
  descriptionKey: I18nKey;
23
23
  keywordsKey: I18nKey;
24
+ /** Literal copy overriding the i18n key, when a manifest owns it. */
25
+ title?: string;
26
+ description?: string;
27
+ keywords?: string;
24
28
  icon: React.ReactElement;
25
29
  to?: string;
26
30
  perform?: () => void;
@@ -1,2 +1,2 @@
1
- require("../../../_virtual/_rolldown/runtime.cjs");const e=require("../../../utils/utils.cjs");let t=require("react/jsx-runtime");function n({value:n,options:r,onChange:i,ariaLabel:a,testId:o}){return(0,t.jsx)(`div`,{role:`radiogroup`,"aria-label":a,"data-testid":o,className:`inline-flex items-center rounded-md bg-[var(--oh-surface-raised)] p-0.5 text-xs`,children:r.map(r=>{let a=r.value===n;return(0,t.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":a,"data-testid":o?`${o}-option-${r.value}`:void 0,onClick:()=>i(r.value),className:e.cn(`px-2 py-0.5 rounded cursor-pointer transition-colors`,a?`bg-[var(--oh-interactive-hover)] text-white`:`text-[var(--oh-muted)] hover:text-white`),children:r.label},r.value)})})}exports.SegmentedToggle=n;
1
+ require("../../../_virtual/_rolldown/runtime.cjs");const e=require("../../../utils/utils.cjs");let t=require("react/jsx-runtime");function n({value:n,options:r,onChange:i,ariaLabel:a,testId:o}){return(0,t.jsx)(`div`,{role:`radiogroup`,"aria-label":a,"data-testid":o,className:`inline-flex items-center rounded-md bg-[var(--oh-surface-raised)] p-0.5 text-xs`,children:r.map(r=>{let a=r.value===n;return(0,t.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":a,"data-testid":o?`${o}-option-${r.value}`:void 0,onClick:()=>i(r.value),className:e.cn(`inline-flex items-center gap-1.5 px-2.5 py-1 rounded cursor-pointer transition-colors`,a?`bg-[var(--oh-interactive-hover)] text-white`:`text-[var(--oh-muted)] hover:text-white`),children:[r.icon?(0,t.jsx)(`span`,{className:`inline-flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5`,children:r.icon}):null,r.label]},r.value)})})}exports.SegmentedToggle=n;
2
2
  //# sourceMappingURL=segmented-toggle.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"segmented-toggle.cjs","names":[],"sources":["../../../../src/components/features/files-tab/segmented-toggle.tsx"],"sourcesContent":["import { cn } from \"#/utils/utils\";\n\ninterface SegmentedToggleOption<T extends string> {\n value: T;\n label: string;\n}\n\ninterface SegmentedToggleProps<T extends string> {\n value: T;\n options: SegmentedToggleOption<T>[];\n onChange: (value: T) => void;\n ariaLabel: string;\n testId?: string;\n}\n\n/**\n * Lightweight 2-state segmented control used for the files-tab toggles\n * (\"Diff view\" on/off, \"Rich\"/\"Plain\"). Kept local because the existing\n * shared switch components are heavier than what we need here.\n */\nexport function SegmentedToggle<T extends string>({\n value,\n options,\n onChange,\n ariaLabel,\n testId,\n}: SegmentedToggleProps<T>) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={ariaLabel}\n data-testid={testId}\n className=\"inline-flex items-center rounded-md bg-[var(--oh-surface-raised)] p-0.5 text-xs\"\n >\n {options.map((option) => {\n const isActive = option.value === value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={isActive}\n data-testid={\n testId ? `${testId}-option-${option.value}` : undefined\n }\n onClick={() => onChange(option.value)}\n className={cn(\n \"px-2 py-0.5 rounded cursor-pointer transition-colors\",\n isActive\n ? \"bg-[var(--oh-interactive-hover)] text-white\"\n : \"text-[var(--oh-muted)] hover:text-white\",\n )}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":"kIAoBA,SAAgB,EAAkC,CAChD,QACA,UACA,WACA,YACA,UAC0B,CAC1B,OACE,EAAA,EAAA,KAAC,MAAD,CACE,KAAK,aACL,aAAY,EACZ,cAAa,EACb,UAAU,2FAET,EAAQ,IAAK,GAAW,CACvB,IAAM,EAAW,EAAO,QAAU,EAClC,OACE,EAAA,EAAA,KAAC,SAAD,CAEE,KAAK,SACL,KAAK,QACL,eAAc,EACd,cACE,EAAS,GAAG,EAAO,UAAU,EAAO,QAAU,IAAA,GAEhD,YAAe,EAAS,EAAO,KAAK,EACpC,UAAW,EAAA,GACT,uDACA,EACI,8CACA,yCACN,WAEC,EAAO,KACF,EAhBD,EAAO,KAgBN,CAEZ,CAAC,CACE,CAAA,CAET"}
1
+ {"version":3,"file":"segmented-toggle.cjs","names":[],"sources":["../../../../src/components/features/files-tab/segmented-toggle.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"#/utils/utils\";\n\ninterface SegmentedToggleOption<T extends string> {\n value: T;\n label: string;\n icon?: ReactNode;\n}\n\ninterface SegmentedToggleProps<T extends string> {\n value: T;\n options: SegmentedToggleOption<T>[];\n onChange: (value: T) => void;\n ariaLabel: string;\n testId?: string;\n}\n\n/**\n * Lightweight 2-state segmented control used for the files-tab toggles\n * (\"Diff view\" on/off, \"Rich\"/\"Plain\"). Kept local because the existing\n * shared switch components are heavier than what we need here.\n */\nexport function SegmentedToggle<T extends string>({\n value,\n options,\n onChange,\n ariaLabel,\n testId,\n}: SegmentedToggleProps<T>) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={ariaLabel}\n data-testid={testId}\n className=\"inline-flex items-center rounded-md bg-[var(--oh-surface-raised)] p-0.5 text-xs\"\n >\n {options.map((option) => {\n const isActive = option.value === value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={isActive}\n data-testid={\n testId ? `${testId}-option-${option.value}` : undefined\n }\n onClick={() => onChange(option.value)}\n className={cn(\n \"inline-flex items-center gap-1.5 px-2.5 py-1 rounded cursor-pointer transition-colors\",\n isActive\n ? \"bg-[var(--oh-interactive-hover)] text-white\"\n : \"text-[var(--oh-muted)] hover:text-white\",\n )}\n >\n {option.icon ? (\n <span className=\"inline-flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5\">\n {option.icon}\n </span>\n ) : null}\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":"kIAsBA,SAAgB,EAAkC,CAChD,QACA,UACA,WACA,YACA,UAC0B,CAC1B,OACE,EAAA,EAAA,KAAC,MAAD,CACE,KAAK,aACL,aAAY,EACZ,cAAa,EACb,UAAU,2FAET,EAAQ,IAAK,GAAW,CACvB,IAAM,EAAW,EAAO,QAAU,EAClC,OACE,EAAA,EAAA,MAAC,SAAD,CAEE,KAAK,SACL,KAAK,QACL,eAAc,EACd,cACE,EAAS,GAAG,EAAO,UAAU,EAAO,QAAU,IAAA,GAEhD,YAAe,EAAS,EAAO,KAAK,EACpC,UAAW,EAAA,GACT,wFACA,EACI,8CACA,yCACN,WAdF,CAgBG,EAAO,MACN,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,sFACb,EAAO,IACJ,CAAA,EACJ,KACH,EAAO,KACF,GArBD,EAAO,KAqBN,CAEZ,CAAC,CACE,CAAA,CAET"}
@@ -1,6 +1,8 @@
1
+ import type { ReactNode } from "react";
1
2
  interface SegmentedToggleOption<T extends string> {
2
3
  value: T;
3
4
  label: string;
5
+ icon?: ReactNode;
4
6
  }
5
7
  interface SegmentedToggleProps<T extends string> {
6
8
  value: T;
@@ -1,27 +1,30 @@
1
1
  import { cn as e } from "../../../utils/utils.js";
2
- import { jsx as t } from "react/jsx-runtime";
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
3
  //#region src/components/features/files-tab/segmented-toggle.tsx
4
- function n({ value: n, options: r, onChange: i, ariaLabel: a, testId: o }) {
4
+ function r({ value: r, options: i, onChange: a, ariaLabel: o, testId: s }) {
5
5
  return /* @__PURE__ */ t("div", {
6
6
  role: "radiogroup",
7
- "aria-label": a,
8
- "data-testid": o,
7
+ "aria-label": o,
8
+ "data-testid": s,
9
9
  className: "inline-flex items-center rounded-md bg-[var(--oh-surface-raised)] p-0.5 text-xs",
10
- children: r.map((r) => {
11
- let a = r.value === n;
12
- return /* @__PURE__ */ t("button", {
10
+ children: i.map((i) => {
11
+ let o = i.value === r;
12
+ return /* @__PURE__ */ n("button", {
13
13
  type: "button",
14
14
  role: "radio",
15
- "aria-checked": a,
16
- "data-testid": o ? `${o}-option-${r.value}` : void 0,
17
- onClick: () => i(r.value),
18
- className: e("px-2 py-0.5 rounded cursor-pointer transition-colors", a ? "bg-[var(--oh-interactive-hover)] text-white" : "text-[var(--oh-muted)] hover:text-white"),
19
- children: r.label
20
- }, r.value);
15
+ "aria-checked": o,
16
+ "data-testid": s ? `${s}-option-${i.value}` : void 0,
17
+ onClick: () => a(i.value),
18
+ className: e("inline-flex items-center gap-1.5 px-2.5 py-1 rounded cursor-pointer transition-colors", o ? "bg-[var(--oh-interactive-hover)] text-white" : "text-[var(--oh-muted)] hover:text-white"),
19
+ children: [i.icon ? /* @__PURE__ */ t("span", {
20
+ className: "inline-flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5",
21
+ children: i.icon
22
+ }) : null, i.label]
23
+ }, i.value);
21
24
  })
22
25
  });
23
26
  }
24
27
  //#endregion
25
- export { n as SegmentedToggle };
28
+ export { r as SegmentedToggle };
26
29
 
27
30
  //# sourceMappingURL=segmented-toggle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"segmented-toggle.js","names":[],"sources":["../../../../src/components/features/files-tab/segmented-toggle.tsx"],"sourcesContent":["import { cn } from \"#/utils/utils\";\n\ninterface SegmentedToggleOption<T extends string> {\n value: T;\n label: string;\n}\n\ninterface SegmentedToggleProps<T extends string> {\n value: T;\n options: SegmentedToggleOption<T>[];\n onChange: (value: T) => void;\n ariaLabel: string;\n testId?: string;\n}\n\n/**\n * Lightweight 2-state segmented control used for the files-tab toggles\n * (\"Diff view\" on/off, \"Rich\"/\"Plain\"). Kept local because the existing\n * shared switch components are heavier than what we need here.\n */\nexport function SegmentedToggle<T extends string>({\n value,\n options,\n onChange,\n ariaLabel,\n testId,\n}: SegmentedToggleProps<T>) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={ariaLabel}\n data-testid={testId}\n className=\"inline-flex items-center rounded-md bg-[var(--oh-surface-raised)] p-0.5 text-xs\"\n >\n {options.map((option) => {\n const isActive = option.value === value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={isActive}\n data-testid={\n testId ? `${testId}-option-${option.value}` : undefined\n }\n onClick={() => onChange(option.value)}\n className={cn(\n \"px-2 py-0.5 rounded cursor-pointer transition-colors\",\n isActive\n ? \"bg-[var(--oh-interactive-hover)] text-white\"\n : \"text-[var(--oh-muted)] hover:text-white\",\n )}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;AAoBA,SAAgB,EAAkC,EAChD,UACA,YACA,aACA,cACA,aAC0B;CAC1B,OACE,kBAAC,OAAD;EACE,MAAK;EACL,cAAY;EACZ,eAAa;EACb,WAAU;YAET,EAAQ,KAAK,MAAW;GACvB,IAAM,IAAW,EAAO,UAAU;GAClC,OACE,kBAAC,UAAD;IAEE,MAAK;IACL,MAAK;IACL,gBAAc;IACd,eACE,IAAS,GAAG,EAAO,UAAU,EAAO,UAAU,KAAA;IAEhD,eAAe,EAAS,EAAO,KAAK;IACpC,WAAW,EACT,wDACA,IACI,gDACA,yCACN;cAEC,EAAO;GACF,GAhBD,EAAO,KAgBN;EAEZ,CAAC;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"segmented-toggle.js","names":[],"sources":["../../../../src/components/features/files-tab/segmented-toggle.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"#/utils/utils\";\n\ninterface SegmentedToggleOption<T extends string> {\n value: T;\n label: string;\n icon?: ReactNode;\n}\n\ninterface SegmentedToggleProps<T extends string> {\n value: T;\n options: SegmentedToggleOption<T>[];\n onChange: (value: T) => void;\n ariaLabel: string;\n testId?: string;\n}\n\n/**\n * Lightweight 2-state segmented control used for the files-tab toggles\n * (\"Diff view\" on/off, \"Rich\"/\"Plain\"). Kept local because the existing\n * shared switch components are heavier than what we need here.\n */\nexport function SegmentedToggle<T extends string>({\n value,\n options,\n onChange,\n ariaLabel,\n testId,\n}: SegmentedToggleProps<T>) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={ariaLabel}\n data-testid={testId}\n className=\"inline-flex items-center rounded-md bg-[var(--oh-surface-raised)] p-0.5 text-xs\"\n >\n {options.map((option) => {\n const isActive = option.value === value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={isActive}\n data-testid={\n testId ? `${testId}-option-${option.value}` : undefined\n }\n onClick={() => onChange(option.value)}\n className={cn(\n \"inline-flex items-center gap-1.5 px-2.5 py-1 rounded cursor-pointer transition-colors\",\n isActive\n ? \"bg-[var(--oh-interactive-hover)] text-white\"\n : \"text-[var(--oh-muted)] hover:text-white\",\n )}\n >\n {option.icon ? (\n <span className=\"inline-flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5\">\n {option.icon}\n </span>\n ) : null}\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;AAsBA,SAAgB,EAAkC,EAChD,UACA,YACA,aACA,cACA,aAC0B;CAC1B,OACE,kBAAC,OAAD;EACE,MAAK;EACL,cAAY;EACZ,eAAa;EACb,WAAU;YAET,EAAQ,KAAK,MAAW;GACvB,IAAM,IAAW,EAAO,UAAU;GAClC,OACE,kBAAC,UAAD;IAEE,MAAK;IACL,MAAK;IACL,gBAAc;IACd,eACE,IAAS,GAAG,EAAO,UAAU,EAAO,UAAU,KAAA;IAEhD,eAAe,EAAS,EAAO,KAAK;IACpC,WAAW,EACT,yFACA,IACI,gDACA,yCACN;cAdF,CAgBG,EAAO,OACN,kBAAC,QAAD;KAAM,WAAU;eACb,EAAO;IACJ,CAAA,IACJ,MACH,EAAO,KACF;MArBD,EAAO,KAqBN;EAEZ,CAAC;CACE,CAAA;AAET"}
@@ -0,0 +1,27 @@
1
+ import type { GitRepository } from "#/types/git";
2
+ import type { SetupFieldOption, SetupFormField as SetupFormFieldDefinition } from "#/manifests/types";
3
+ export interface SetupFormFieldProps {
4
+ /** The record key the field is declared under, and what `{{form.x}}` reads. */
5
+ name: string;
6
+ field: SetupFormFieldDefinition;
7
+ value: string;
8
+ /** Already-resolved copy: local checks and service errors look the same here. */
9
+ error?: string;
10
+ /** Declared options, or the ones the deployment supplied. */
11
+ options: SetupFieldOption[];
12
+ /** The picked repository, kept so the picker can show what is selected. */
13
+ repository: GitRepository | null;
14
+ disabled: boolean;
15
+ onChange: (value: string) => void;
16
+ onRepositoryChange: (repository: GitRepository | null) => void;
17
+ onBlur: () => void;
18
+ }
19
+ /**
20
+ * Render one manifest-declared field.
21
+ *
22
+ * The host knows how to render a field *type*; what any field means is the
23
+ * manifest's business. Every field's own copy comes from the manifest and is
24
+ * never translated by the host; the only host string is the format hint the
25
+ * repository fallback below needs, because no manifest declares it.
26
+ */
27
+ export declare function SetupFormField({ name, field, value, error, options, repository, disabled, onChange, onRepositoryChange, onBlur, }: SetupFormFieldProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import type { SetupPrerequisitesResult } from "#/hooks/query/use-manifest-prerequisites";
2
+ export interface SetupPrerequisitesStepProps {
3
+ prerequisites: SetupPrerequisitesResult;
4
+ }
5
+ /**
6
+ * Stage 3 — what has to be connected before the form is worth filling in.
7
+ *
8
+ * Each integration is listed with the reason the manifest gives for needing it,
9
+ * so the user is told why rather than just what.
10
+ */
11
+ export declare function SetupPrerequisitesStep({ prerequisites, }: SetupPrerequisitesStepProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import type { SetupBlock, SetupFormValues } from "#/manifests/types";
2
+ export interface SetupReviewStepProps {
3
+ setup: SetupBlock;
4
+ values: SetupFormValues;
5
+ }
6
+ /**
7
+ * Stage 7 — the plain-language summary the user confirms.
8
+ *
9
+ * The last cheap moment to catch a wrong answer, and the last point at which
10
+ * nothing has been created yet. A manifest declares no summary of its own: one
11
+ * row per declared field, labelled the way the field was labelled, says the
12
+ * same thing without asking every entry to restate it.
13
+ */
14
+ export declare function SetupReviewStep({ setup, values }: SetupReviewStepProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import type { SetupEntry } from "#/manifests/types";
2
+ export interface SetupDialogProps {
3
+ entry: SetupEntry;
4
+ onClose: () => void;
5
+ }
6
+ /**
7
+ * The setup host: capabilities check, prerequisites, form, review, and the
8
+ * action the manifest's mode selects, rendered as a dialog.
9
+ *
10
+ * The host runs the stages and owns everything the same for every entry; the
11
+ * manifest supplies only what varies. Any string the user reads here is either
12
+ * manifest-authored or host chrome.
13
+ */
14
+ export declare function SetupDialog({ entry, onClose }: SetupDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
- require("../../../_virtual/_rolldown/runtime.cjs");const e=require("../../../utils/utils.cjs"),t=require("../../../utils/form-control-classes.cjs"),n=require("./optional-tag.cjs");let r=require("react"),i=require("react/jsx-runtime");var a=(0,r.forwardRef)(function({testId:r,name:a,label:o,type:s,defaultValue:c,value:l,placeholder:u,showOptionalTag:d,isDisabled:f,startContent:p,className:m,onChange:h,onKeyDown:g,required:_,min:v,max:y,step:b,pattern:x,title:S,labelClassName:C,ariaDescribedBy:w,ariaInvalid:T,error:E,showRequiredTag:D,onBlur:O,inputClassName:k},A){let j=E&&r?`${r}-error`:void 0;return(0,i.jsxs)(`label`,{className:e.cn(`flex flex-col gap-2.5 w-full min-w-0`,m),children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[p,(0,i.jsx)(`span`,{className:e.cn(`text-sm`,C),children:o}),D&&(0,i.jsx)(`span`,{className:`text-red-400 text-sm leading-none`,"aria-hidden":!0,children:`*`}),d&&(0,i.jsx)(n.OptionalTag,{})]}),(0,i.jsx)(`input`,{ref:A,"data-testid":r,onChange:e=>h?.(e.target.value),onKeyDown:g,onBlur:O,name:a,disabled:f,type:s,defaultValue:c,value:l,placeholder:u,min:v,max:y,step:b,required:_,pattern:x,title:S,"aria-describedby":j??w,"aria-invalid":!!E||T,className:e.cn(t.formControlSettingsFieldClassName,`disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]`,E&&`border-red-500`,k)}),E&&(0,i.jsx)(`p`,{id:j,role:`alert`,"data-testid":r?`${r}-error`:void 0,className:`text-xs text-red-400 -mt-1`,children:E})]})});exports.SettingsInput=a;
1
+ require("../../../_virtual/_rolldown/runtime.cjs");const e=require("../../../utils/utils.cjs"),t=require("../../../utils/form-control-classes.cjs"),n=require("./optional-tag.cjs");let r=require("react"),i=require("react/jsx-runtime");var a=(0,r.forwardRef)(function({testId:r,name:a,label:o,type:s,defaultValue:c,value:l,placeholder:u,showOptionalTag:d,isDisabled:f,startContent:p,className:m,onChange:h,onKeyDown:g,required:_,min:v,max:y,step:b,pattern:x,title:S,labelClassName:C,ariaDescribedBy:w,ariaInvalid:T,error:E,showRequiredTag:D,hint:O,onBlur:k,inputClassName:A},j){let M=E&&r?`${r}-error`:void 0;return(0,i.jsxs)(`label`,{className:e.cn(`flex flex-col gap-2.5 w-full min-w-0`,m),children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[p,(0,i.jsx)(`span`,{className:e.cn(`text-sm`,C),children:o}),D&&(0,i.jsx)(`span`,{className:`text-red-400 text-sm leading-none`,"aria-hidden":!0,children:`*`}),d&&(0,i.jsx)(n.OptionalTag,{}),O&&(0,i.jsx)(`span`,{"data-testid":r?`${r}-hint`:void 0,className:`min-w-0 text-xs text-[var(--oh-muted)]`,children:O})]}),(0,i.jsx)(`input`,{ref:j,"data-testid":r,onChange:e=>h?.(e.target.value),onKeyDown:g,onBlur:k,name:a,disabled:f,type:s,defaultValue:c,value:l,placeholder:u,min:v,max:y,step:b,required:_,pattern:x,title:S,"aria-describedby":M??w,"aria-invalid":!!E||T,className:e.cn(t.formControlSettingsFieldClassName,`disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]`,E&&`border-red-500`,A)}),E&&(0,i.jsx)(`p`,{id:M,role:`alert`,"data-testid":r?`${r}-error`:void 0,className:`text-xs text-red-400 -mt-1`,children:E})]})});exports.SettingsInput=a;
2
2
  //# sourceMappingURL=settings-input.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings-input.cjs","names":[],"sources":["../../../../src/components/features/settings/settings-input.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlSettingsFieldClassName } from \"#/utils/form-control-classes\";\nimport { OptionalTag } from \"./optional-tag\";\n\ninterface SettingsInputProps {\n testId?: string;\n name?: string;\n label: string;\n type: React.HTMLInputTypeAttribute;\n defaultValue?: string;\n value?: string;\n placeholder?: string;\n showOptionalTag?: boolean;\n isDisabled?: boolean;\n startContent?: React.ReactNode;\n className?: string;\n onChange?: (value: string) => void;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n required?: boolean;\n min?: number;\n max?: number;\n step?: number;\n pattern?: string;\n /** Validation message shown when pattern doesn't match */\n title?: string;\n labelClassName?: string;\n /** ARIA describedby attribute for accessibility */\n ariaDescribedBy?: string;\n /** ARIA invalid attribute for accessibility */\n ariaInvalid?: boolean;\n /**\n * Validation error message. When set, the input gets a red border and\n * the message is rendered below it. Also sets aria-invalid automatically.\n */\n error?: string;\n /** Renders a red asterisk next to the label to mark the field as required. */\n showRequiredTag?: boolean;\n onBlur?: () => void;\n /** Extra classes merged onto the `<input>` element. */\n inputClassName?: string;\n}\n\nexport const SettingsInput = forwardRef<HTMLInputElement, SettingsInputProps>(\n function SettingsInput(\n {\n testId,\n name,\n label,\n type,\n defaultValue,\n value,\n placeholder,\n showOptionalTag,\n isDisabled,\n startContent,\n className,\n onChange,\n onKeyDown,\n required,\n min,\n max,\n step,\n pattern,\n title,\n labelClassName,\n ariaDescribedBy,\n ariaInvalid,\n error,\n showRequiredTag,\n onBlur,\n inputClassName,\n },\n ref,\n ) {\n const errorId = error && testId ? `${testId}-error` : undefined;\n return (\n <label className={cn(\"flex flex-col gap-2.5 w-full min-w-0\", className)}>\n <div className=\"flex items-center gap-2\">\n {startContent}\n <span className={cn(\"text-sm\", labelClassName)}>{label}</span>\n {showRequiredTag && (\n <span className=\"text-red-400 text-sm leading-none\" aria-hidden>\n *\n </span>\n )}\n {showOptionalTag && <OptionalTag />}\n </div>\n <input\n ref={ref}\n data-testid={testId}\n onChange={(e) => onChange?.(e.target.value)}\n onKeyDown={onKeyDown}\n onBlur={onBlur}\n name={name}\n disabled={isDisabled}\n type={type}\n defaultValue={defaultValue}\n value={value}\n placeholder={placeholder}\n min={min}\n max={max}\n step={step}\n required={required}\n pattern={pattern}\n title={title}\n aria-describedby={errorId ?? ariaDescribedBy}\n aria-invalid={!!error || ariaInvalid}\n className={cn(\n formControlSettingsFieldClassName,\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n error && \"border-red-500\",\n inputClassName,\n )}\n />\n {error && (\n <p\n id={errorId}\n role=\"alert\"\n data-testid={testId ? `${testId}-error` : undefined}\n className=\"text-xs text-red-400 -mt-1\"\n >\n {error}\n </p>\n )}\n </label>\n );\n },\n);\n"],"mappings":"0OA2CA,IAAa,GAAA,EAAA,EAAA,YACX,SACE,CACE,SACA,OACA,QACA,OACA,eACA,QACA,cACA,kBACA,aACA,eACA,YACA,WACA,YACA,WACA,MACA,MACA,OACA,UACA,QACA,iBACA,kBACA,cACA,QACA,kBACA,SACA,kBAEF,EACA,CACA,IAAM,EAAU,GAAS,EAAS,GAAG,EAAO,QAAU,IAAA,GACtD,OACE,EAAA,EAAA,MAAC,QAAD,CAAO,UAAW,EAAA,GAAG,uCAAwC,CAAS,WAAtE,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mCAAf,CACG,GACD,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,GAAG,UAAW,CAAc,WAAI,CAAY,CAAA,EAC5D,IACC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oCAAoC,cAAA,YAAY,GAE1D,CAAA,EAEP,IAAmB,EAAA,EAAA,KAAC,EAAA,YAAD,CAAc,CAAA,CAC/B,KACL,EAAA,EAAA,KAAC,QAAD,CACO,MACL,cAAa,EACb,SAAW,GAAM,IAAW,EAAE,OAAO,KAAK,EAC/B,YACH,SACF,OACN,SAAU,EACJ,OACQ,eACP,QACM,cACR,MACA,MACC,OACI,WACD,UACF,QACP,mBAAkB,GAAW,EAC7B,eAAc,CAAC,CAAC,GAAS,EACzB,UAAW,EAAA,GACT,EAAA,kCACA,mFACA,GAAS,iBACT,CACF,CACD,CAAA,EACA,IACC,EAAA,EAAA,KAAC,IAAD,CACE,GAAI,EACJ,KAAK,QACL,cAAa,EAAS,GAAG,EAAO,QAAU,IAAA,GAC1C,UAAU,sCAET,CACA,CAAA,CAEA,GAEX,CACF"}
1
+ {"version":3,"file":"settings-input.cjs","names":[],"sources":["../../../../src/components/features/settings/settings-input.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlSettingsFieldClassName } from \"#/utils/form-control-classes\";\nimport { OptionalTag } from \"./optional-tag\";\n\ninterface SettingsInputProps {\n testId?: string;\n name?: string;\n label: string;\n type: React.HTMLInputTypeAttribute;\n defaultValue?: string;\n value?: string;\n placeholder?: string;\n showOptionalTag?: boolean;\n isDisabled?: boolean;\n startContent?: React.ReactNode;\n className?: string;\n onChange?: (value: string) => void;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n required?: boolean;\n min?: number;\n max?: number;\n step?: number;\n pattern?: string;\n /** Validation message shown when pattern doesn't match */\n title?: string;\n labelClassName?: string;\n /** ARIA describedby attribute for accessibility */\n ariaDescribedBy?: string;\n /** ARIA invalid attribute for accessibility */\n ariaInvalid?: boolean;\n /**\n * Validation error message. When set, the input gets a red border and\n * the message is rendered below it. Also sets aria-invalid automatically.\n */\n error?: string;\n /** Renders a red asterisk next to the label to mark the field as required. */\n showRequiredTag?: boolean;\n /**\n * Short guidance rendered next to the label, above the input. It sits inside\n * the `<label>`, so it is announced as part of the field's accessible name —\n * keep it to a phrase that reads well after the label text.\n */\n hint?: string;\n onBlur?: () => void;\n /** Extra classes merged onto the `<input>` element. */\n inputClassName?: string;\n}\n\nexport const SettingsInput = forwardRef<HTMLInputElement, SettingsInputProps>(\n function SettingsInput(\n {\n testId,\n name,\n label,\n type,\n defaultValue,\n value,\n placeholder,\n showOptionalTag,\n isDisabled,\n startContent,\n className,\n onChange,\n onKeyDown,\n required,\n min,\n max,\n step,\n pattern,\n title,\n labelClassName,\n ariaDescribedBy,\n ariaInvalid,\n error,\n showRequiredTag,\n hint,\n onBlur,\n inputClassName,\n },\n ref,\n ) {\n const errorId = error && testId ? `${testId}-error` : undefined;\n return (\n <label className={cn(\"flex flex-col gap-2.5 w-full min-w-0\", className)}>\n <div className=\"flex items-center gap-2\">\n {startContent}\n <span className={cn(\"text-sm\", labelClassName)}>{label}</span>\n {showRequiredTag && (\n <span className=\"text-red-400 text-sm leading-none\" aria-hidden>\n *\n </span>\n )}\n {showOptionalTag && <OptionalTag />}\n {hint && (\n <span\n data-testid={testId ? `${testId}-hint` : undefined}\n className=\"min-w-0 text-xs text-[var(--oh-muted)]\"\n >\n {hint}\n </span>\n )}\n </div>\n <input\n ref={ref}\n data-testid={testId}\n onChange={(e) => onChange?.(e.target.value)}\n onKeyDown={onKeyDown}\n onBlur={onBlur}\n name={name}\n disabled={isDisabled}\n type={type}\n defaultValue={defaultValue}\n value={value}\n placeholder={placeholder}\n min={min}\n max={max}\n step={step}\n required={required}\n pattern={pattern}\n title={title}\n aria-describedby={errorId ?? ariaDescribedBy}\n aria-invalid={!!error || ariaInvalid}\n className={cn(\n formControlSettingsFieldClassName,\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n error && \"border-red-500\",\n inputClassName,\n )}\n />\n {error && (\n <p\n id={errorId}\n role=\"alert\"\n data-testid={testId ? `${testId}-error` : undefined}\n className=\"text-xs text-red-400 -mt-1\"\n >\n {error}\n </p>\n )}\n </label>\n );\n },\n);\n"],"mappings":"0OAiDA,IAAa,GAAA,EAAA,EAAA,YACX,SACE,CACE,SACA,OACA,QACA,OACA,eACA,QACA,cACA,kBACA,aACA,eACA,YACA,WACA,YACA,WACA,MACA,MACA,OACA,UACA,QACA,iBACA,kBACA,cACA,QACA,kBACA,OACA,SACA,kBAEF,EACA,CACA,IAAM,EAAU,GAAS,EAAS,GAAG,EAAO,QAAU,IAAA,GACtD,OACE,EAAA,EAAA,MAAC,QAAD,CAAO,UAAW,EAAA,GAAG,uCAAwC,CAAS,WAAtE,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mCAAf,CACG,GACD,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,GAAG,UAAW,CAAc,WAAI,CAAY,CAAA,EAC5D,IACC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oCAAoC,cAAA,YAAY,GAE1D,CAAA,EAEP,IAAmB,EAAA,EAAA,KAAC,EAAA,YAAD,CAAc,CAAA,EACjC,IACC,EAAA,EAAA,KAAC,OAAD,CACE,cAAa,EAAS,GAAG,EAAO,OAAS,IAAA,GACzC,UAAU,kDAET,CACG,CAAA,CAEL,KACL,EAAA,EAAA,KAAC,QAAD,CACO,MACL,cAAa,EACb,SAAW,GAAM,IAAW,EAAE,OAAO,KAAK,EAC/B,YACH,SACF,OACN,SAAU,EACJ,OACQ,eACP,QACM,cACR,MACA,MACC,OACI,WACD,UACF,QACP,mBAAkB,GAAW,EAC7B,eAAc,CAAC,CAAC,GAAS,EACzB,UAAW,EAAA,GACT,EAAA,kCACA,mFACA,GAAS,iBACT,CACF,CACD,CAAA,EACA,IACC,EAAA,EAAA,KAAC,IAAD,CACE,GAAI,EACJ,KAAK,QACL,cAAa,EAAS,GAAG,EAAO,QAAU,IAAA,GAC1C,UAAU,sCAET,CACA,CAAA,CAEA,GAEX,CACF"}
@@ -31,6 +31,12 @@ interface SettingsInputProps {
31
31
  error?: string;
32
32
  /** Renders a red asterisk next to the label to mark the field as required. */
33
33
  showRequiredTag?: boolean;
34
+ /**
35
+ * Short guidance rendered next to the label, above the input. It sits inside
36
+ * the `<label>`, so it is announced as part of the field's accessible name —
37
+ * keep it to a phrase that reads well after the label text.
38
+ */
39
+ hint?: string;
34
40
  onBlur?: () => void;
35
41
  /** Extra classes merged onto the `<input>` element. */
36
42
  inputClassName?: string;
@@ -4,8 +4,8 @@ import { OptionalTag as n } from "./optional-tag.js";
4
4
  import { forwardRef as r } from "react";
5
5
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
6
  //#region src/components/features/settings/settings-input.tsx
7
- var o = r(function({ testId: r, name: o, label: s, type: c, defaultValue: l, value: u, placeholder: d, showOptionalTag: f, isDisabled: p, startContent: m, className: h, onChange: g, onKeyDown: _, required: v, min: y, max: b, step: x, pattern: S, title: C, labelClassName: w, ariaDescribedBy: T, ariaInvalid: E, error: D, showRequiredTag: O, onBlur: k, inputClassName: A }, j) {
8
- let M = D && r ? `${r}-error` : void 0;
7
+ var o = r(function({ testId: r, name: o, label: s, type: c, defaultValue: l, value: u, placeholder: d, showOptionalTag: f, isDisabled: p, startContent: m, className: h, onChange: g, onKeyDown: _, required: v, min: y, max: b, step: x, pattern: S, title: C, labelClassName: w, ariaDescribedBy: T, ariaInvalid: E, error: D, showRequiredTag: O, hint: k, onBlur: A, inputClassName: j }, M) {
8
+ let N = D && r ? `${r}-error` : void 0;
9
9
  return /* @__PURE__ */ a("label", {
10
10
  className: e("flex flex-col gap-2.5 w-full min-w-0", h),
11
11
  children: [
@@ -22,15 +22,20 @@ var o = r(function({ testId: r, name: o, label: s, type: c, defaultValue: l, val
22
22
  "aria-hidden": !0,
23
23
  children: "*"
24
24
  }),
25
- f && /* @__PURE__ */ i(n, {})
25
+ f && /* @__PURE__ */ i(n, {}),
26
+ k && /* @__PURE__ */ i("span", {
27
+ "data-testid": r ? `${r}-hint` : void 0,
28
+ className: "min-w-0 text-xs text-[var(--oh-muted)]",
29
+ children: k
30
+ })
26
31
  ]
27
32
  }),
28
33
  /* @__PURE__ */ i("input", {
29
- ref: j,
34
+ ref: M,
30
35
  "data-testid": r,
31
36
  onChange: (e) => g?.(e.target.value),
32
37
  onKeyDown: _,
33
- onBlur: k,
38
+ onBlur: A,
34
39
  name: o,
35
40
  disabled: p,
36
41
  type: c,
@@ -43,12 +48,12 @@ var o = r(function({ testId: r, name: o, label: s, type: c, defaultValue: l, val
43
48
  required: v,
44
49
  pattern: S,
45
50
  title: C,
46
- "aria-describedby": M ?? T,
51
+ "aria-describedby": N ?? T,
47
52
  "aria-invalid": !!D || E,
48
- className: e(t, "disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]", D && "border-red-500", A)
53
+ className: e(t, "disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]", D && "border-red-500", j)
49
54
  }),
50
55
  D && /* @__PURE__ */ i("p", {
51
- id: M,
56
+ id: N,
52
57
  role: "alert",
53
58
  "data-testid": r ? `${r}-error` : void 0,
54
59
  className: "text-xs text-red-400 -mt-1",
@@ -1 +1 @@
1
- {"version":3,"file":"settings-input.js","names":[],"sources":["../../../../src/components/features/settings/settings-input.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlSettingsFieldClassName } from \"#/utils/form-control-classes\";\nimport { OptionalTag } from \"./optional-tag\";\n\ninterface SettingsInputProps {\n testId?: string;\n name?: string;\n label: string;\n type: React.HTMLInputTypeAttribute;\n defaultValue?: string;\n value?: string;\n placeholder?: string;\n showOptionalTag?: boolean;\n isDisabled?: boolean;\n startContent?: React.ReactNode;\n className?: string;\n onChange?: (value: string) => void;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n required?: boolean;\n min?: number;\n max?: number;\n step?: number;\n pattern?: string;\n /** Validation message shown when pattern doesn't match */\n title?: string;\n labelClassName?: string;\n /** ARIA describedby attribute for accessibility */\n ariaDescribedBy?: string;\n /** ARIA invalid attribute for accessibility */\n ariaInvalid?: boolean;\n /**\n * Validation error message. When set, the input gets a red border and\n * the message is rendered below it. Also sets aria-invalid automatically.\n */\n error?: string;\n /** Renders a red asterisk next to the label to mark the field as required. */\n showRequiredTag?: boolean;\n onBlur?: () => void;\n /** Extra classes merged onto the `<input>` element. */\n inputClassName?: string;\n}\n\nexport const SettingsInput = forwardRef<HTMLInputElement, SettingsInputProps>(\n function SettingsInput(\n {\n testId,\n name,\n label,\n type,\n defaultValue,\n value,\n placeholder,\n showOptionalTag,\n isDisabled,\n startContent,\n className,\n onChange,\n onKeyDown,\n required,\n min,\n max,\n step,\n pattern,\n title,\n labelClassName,\n ariaDescribedBy,\n ariaInvalid,\n error,\n showRequiredTag,\n onBlur,\n inputClassName,\n },\n ref,\n ) {\n const errorId = error && testId ? `${testId}-error` : undefined;\n return (\n <label className={cn(\"flex flex-col gap-2.5 w-full min-w-0\", className)}>\n <div className=\"flex items-center gap-2\">\n {startContent}\n <span className={cn(\"text-sm\", labelClassName)}>{label}</span>\n {showRequiredTag && (\n <span className=\"text-red-400 text-sm leading-none\" aria-hidden>\n *\n </span>\n )}\n {showOptionalTag && <OptionalTag />}\n </div>\n <input\n ref={ref}\n data-testid={testId}\n onChange={(e) => onChange?.(e.target.value)}\n onKeyDown={onKeyDown}\n onBlur={onBlur}\n name={name}\n disabled={isDisabled}\n type={type}\n defaultValue={defaultValue}\n value={value}\n placeholder={placeholder}\n min={min}\n max={max}\n step={step}\n required={required}\n pattern={pattern}\n title={title}\n aria-describedby={errorId ?? ariaDescribedBy}\n aria-invalid={!!error || ariaInvalid}\n className={cn(\n formControlSettingsFieldClassName,\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n error && \"border-red-500\",\n inputClassName,\n )}\n />\n {error && (\n <p\n id={errorId}\n role=\"alert\"\n data-testid={testId ? `${testId}-error` : undefined}\n className=\"text-xs text-red-400 -mt-1\"\n >\n {error}\n </p>\n )}\n </label>\n );\n },\n);\n"],"mappings":";;;;;;AA2CA,IAAa,IAAgB,EAC3B,SACE,EACE,WACA,SACA,UACA,SACA,iBACA,UACA,gBACA,oBACA,eACA,iBACA,cACA,aACA,cACA,aACA,QACA,QACA,SACA,YACA,UACA,mBACA,oBACA,gBACA,UACA,oBACA,WACA,qBAEF,GACA;CACA,IAAM,IAAU,KAAS,IAAS,GAAG,EAAO,UAAU,KAAA;CACtD,OACE,kBAAC,SAAD;EAAO,WAAW,EAAG,wCAAwC,CAAS;YAAtE;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG;KACD,kBAAC,QAAD;MAAM,WAAW,EAAG,WAAW,CAAc;gBAAI;KAAY,CAAA;KAC5D,KACC,kBAAC,QAAD;MAAM,WAAU;MAAoC,eAAA;gBAAY;KAE1D,CAAA;KAEP,KAAmB,kBAAC,GAAD,CAAc,CAAA;IAC/B;;GACL,kBAAC,SAAD;IACO;IACL,eAAa;IACb,WAAW,MAAM,IAAW,EAAE,OAAO,KAAK;IAC/B;IACH;IACF;IACN,UAAU;IACJ;IACQ;IACP;IACM;IACR;IACA;IACC;IACI;IACD;IACF;IACP,oBAAkB,KAAW;IAC7B,gBAAc,CAAC,CAAC,KAAS;IACzB,WAAW,EACT,GACA,oFACA,KAAS,kBACT,CACF;GACD,CAAA;GACA,KACC,kBAAC,KAAD;IACE,IAAI;IACJ,MAAK;IACL,eAAa,IAAS,GAAG,EAAO,UAAU,KAAA;IAC1C,WAAU;cAET;GACA,CAAA;EAEA;;AAEX,CACF"}
1
+ {"version":3,"file":"settings-input.js","names":[],"sources":["../../../../src/components/features/settings/settings-input.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlSettingsFieldClassName } from \"#/utils/form-control-classes\";\nimport { OptionalTag } from \"./optional-tag\";\n\ninterface SettingsInputProps {\n testId?: string;\n name?: string;\n label: string;\n type: React.HTMLInputTypeAttribute;\n defaultValue?: string;\n value?: string;\n placeholder?: string;\n showOptionalTag?: boolean;\n isDisabled?: boolean;\n startContent?: React.ReactNode;\n className?: string;\n onChange?: (value: string) => void;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n required?: boolean;\n min?: number;\n max?: number;\n step?: number;\n pattern?: string;\n /** Validation message shown when pattern doesn't match */\n title?: string;\n labelClassName?: string;\n /** ARIA describedby attribute for accessibility */\n ariaDescribedBy?: string;\n /** ARIA invalid attribute for accessibility */\n ariaInvalid?: boolean;\n /**\n * Validation error message. When set, the input gets a red border and\n * the message is rendered below it. Also sets aria-invalid automatically.\n */\n error?: string;\n /** Renders a red asterisk next to the label to mark the field as required. */\n showRequiredTag?: boolean;\n /**\n * Short guidance rendered next to the label, above the input. It sits inside\n * the `<label>`, so it is announced as part of the field's accessible name —\n * keep it to a phrase that reads well after the label text.\n */\n hint?: string;\n onBlur?: () => void;\n /** Extra classes merged onto the `<input>` element. */\n inputClassName?: string;\n}\n\nexport const SettingsInput = forwardRef<HTMLInputElement, SettingsInputProps>(\n function SettingsInput(\n {\n testId,\n name,\n label,\n type,\n defaultValue,\n value,\n placeholder,\n showOptionalTag,\n isDisabled,\n startContent,\n className,\n onChange,\n onKeyDown,\n required,\n min,\n max,\n step,\n pattern,\n title,\n labelClassName,\n ariaDescribedBy,\n ariaInvalid,\n error,\n showRequiredTag,\n hint,\n onBlur,\n inputClassName,\n },\n ref,\n ) {\n const errorId = error && testId ? `${testId}-error` : undefined;\n return (\n <label className={cn(\"flex flex-col gap-2.5 w-full min-w-0\", className)}>\n <div className=\"flex items-center gap-2\">\n {startContent}\n <span className={cn(\"text-sm\", labelClassName)}>{label}</span>\n {showRequiredTag && (\n <span className=\"text-red-400 text-sm leading-none\" aria-hidden>\n *\n </span>\n )}\n {showOptionalTag && <OptionalTag />}\n {hint && (\n <span\n data-testid={testId ? `${testId}-hint` : undefined}\n className=\"min-w-0 text-xs text-[var(--oh-muted)]\"\n >\n {hint}\n </span>\n )}\n </div>\n <input\n ref={ref}\n data-testid={testId}\n onChange={(e) => onChange?.(e.target.value)}\n onKeyDown={onKeyDown}\n onBlur={onBlur}\n name={name}\n disabled={isDisabled}\n type={type}\n defaultValue={defaultValue}\n value={value}\n placeholder={placeholder}\n min={min}\n max={max}\n step={step}\n required={required}\n pattern={pattern}\n title={title}\n aria-describedby={errorId ?? ariaDescribedBy}\n aria-invalid={!!error || ariaInvalid}\n className={cn(\n formControlSettingsFieldClassName,\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n error && \"border-red-500\",\n inputClassName,\n )}\n />\n {error && (\n <p\n id={errorId}\n role=\"alert\"\n data-testid={testId ? `${testId}-error` : undefined}\n className=\"text-xs text-red-400 -mt-1\"\n >\n {error}\n </p>\n )}\n </label>\n );\n },\n);\n"],"mappings":";;;;;;AAiDA,IAAa,IAAgB,EAC3B,SACE,EACE,WACA,SACA,UACA,SACA,iBACA,UACA,gBACA,oBACA,eACA,iBACA,cACA,aACA,cACA,aACA,QACA,QACA,SACA,YACA,UACA,mBACA,oBACA,gBACA,UACA,oBACA,SACA,WACA,qBAEF,GACA;CACA,IAAM,IAAU,KAAS,IAAS,GAAG,EAAO,UAAU,KAAA;CACtD,OACE,kBAAC,SAAD;EAAO,WAAW,EAAG,wCAAwC,CAAS;YAAtE;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG;KACD,kBAAC,QAAD;MAAM,WAAW,EAAG,WAAW,CAAc;gBAAI;KAAY,CAAA;KAC5D,KACC,kBAAC,QAAD;MAAM,WAAU;MAAoC,eAAA;gBAAY;KAE1D,CAAA;KAEP,KAAmB,kBAAC,GAAD,CAAc,CAAA;KACjC,KACC,kBAAC,QAAD;MACE,eAAa,IAAS,GAAG,EAAO,SAAS,KAAA;MACzC,WAAU;gBAET;KACG,CAAA;IAEL;;GACL,kBAAC,SAAD;IACO;IACL,eAAa;IACb,WAAW,MAAM,IAAW,EAAE,OAAO,KAAK;IAC/B;IACH;IACF;IACN,UAAU;IACJ;IACQ;IACP;IACM;IACR;IACA;IACC;IACI;IACD;IACF;IACP,oBAAkB,KAAW;IAC7B,gBAAc,CAAC,CAAC,KAAS;IACzB,WAAW,EACT,GACA,oFACA,KAAS,kBACT,CACF;GACD,CAAA;GACA,KACC,kBAAC,KAAD;IACE,IAAI;IACJ,MAAK;IACL,eAAa,IAAS,GAAG,EAAO,UAAU,KAAA;IAC1C,WAAU;cAET;GACA,CAAA;EAEA;;AAEX,CACF"}
@@ -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("../../../node_modules/lucide-react/dist/esm/icons/chevron-left.cjs"),i=require("../../../node_modules/lucide-react/dist/esm/icons/chevron-right.cjs"),a=require("../../../node_modules/lucide-react/dist/esm/icons/plus.cjs"),o=require("../../../node_modules/lucide-react/dist/esm/icons/server.cjs"),s=require("../../../node_modules/lucide-react/dist/esm/icons/settings.cjs"),c=require("../../../utils/utils.cjs"),l=require("../../shared/buttons/styled-tooltip.cjs"),u=require("../../shared/navigation-link.cjs"),d=require("./sidebar-layout.cjs"),f=require("./sidebar-collapsed-icon-slot.cjs"),p=require("./sidebar-nav-link.cjs"),m=require("../../shared/buttons/openhands-logo-button.cjs"),h=require("../backends/backend-status-dot.cjs"),g=require("../backends/backend-selector.cjs"),_=require("../command-menu/command-menu-trigger.cjs"),v=require("./sidebar-conversation-list.cjs"),y=require("../../../icons/automations.cjs");let b=require("react");b=e.__toESM(b,1);let x=require("react/jsx-runtime");var S=18,C=34,w=Math.round(C*30/46);function T({collapsed:e,showCollapseToggle:b,showMobileCloseButton:T=!1,onCloseMobile:E,collapseToggleLabel:D,onCollapse:O,onExpand:k,showCollapsedExpandButton:A,isExtensionsActive:j,currentPath:M,activeBackendHealth:N,collapsedBackendPopoverOpen:P,setCollapsedBackendPopoverOpen:F,collapsedBackendPopoverRef:I,collapsedBackendCloseTimer:L,onOpenAddBackend:R,onOpenManageBackends:z}){let{t:B}=t.useTranslation(`openhands`),V=L;return(0,x.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col`,children:[(0,x.jsxs)(`div`,{className:d.sidebarHeaderRowClassName(e),children:[(0,x.jsxs)(`div`,{className:c.cn(e&&b?d.SIDEBAR_COLLAPSED_LOGO_WRAPPER_CLASS:`flex min-w-0 shrink-0 items-center`),children:[(0,x.jsx)(`div`,{className:c.cn(e&&b&&`flex h-full w-full items-center justify-start pl-2.5 transition-opacity duration-150`,e&&A&&`opacity-0`),children:(0,x.jsx)(m.OpenHandsLogoButton,{logoWidth:C,logoHeight:w,logoClassName:`max-w-none`,className:c.cn(d.SIDEBAR_ICON_SLOT_CLASS,`overflow-visible`)})}),e&&b?(0,x.jsx)(`button`,{type:`button`,"data-testid":`sidebar-collapse-toggle`,"aria-pressed":e,"aria-label":D,onClick:k,className:c.cn(d.SIDEBAR_COLLAPSE_TOGGLE_OVERLAY_CLASS,A?`opacity-100 pointer-events-auto`:`opacity-0 pointer-events-none`),children:(0,x.jsx)(i.ChevronRight,{width:14,height:14})}):null]}),!e&&b?(0,x.jsx)(`button`,{type:`button`,"data-testid":`sidebar-collapse-toggle`,"aria-pressed":e,"aria-label":D,onClick:O,className:c.cn(`hidden md:inline-flex ml-auto`,d.SIDEBAR_ICON_BUTTON_CLASS,`text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]`),children:(0,x.jsx)(r.ChevronLeft,{width:14,height:14})}):null,!e&&T?(0,x.jsx)(`button`,{type:`button`,"data-testid":`sidebar-mobile-drawer-close`,onClick:E,"aria-label":B(n.I18nKey.SIDEBAR$CLOSE_MENU),className:c.cn(`inline-flex ml-auto`,d.SIDEBAR_ICON_BUTTON_CLASS,`text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]`),children:(0,x.jsx)(r.ChevronLeft,{width:14,height:14})}):null]}),(0,x.jsxs)(`nav`,{className:d.sidebarNavListClassName(e),children:[(0,x.jsx)(_.CommandMenuTrigger,{collapsed:e}),(0,x.jsx)(p.SidebarNavLink,{to:`/conversations`,end:!0,label:B(n.I18nKey.SIDEBAR$NEW_CHAT),testId:`sidebar-conversations-link`,collapsed:e,icon:(0,x.jsx)(a.Plus,{width:S,height:S})}),(0,x.jsx)(p.SidebarNavLink,{to:`/customize`,label:B(n.I18nKey.NAV$CUSTOMIZE),testId:`sidebar-skills-link`,collapsed:e,forceActive:j,icon:(0,x.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:S,height:S,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[(0,x.jsx)(`path`,{d:`M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z`}),(0,x.jsx)(`path`,{d:`m7 16.5-4.74-2.85`}),(0,x.jsx)(`path`,{d:`m7 16.5 5-3`}),(0,x.jsx)(`path`,{d:`M7 16.5v5.17`}),(0,x.jsx)(`path`,{d:`M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z`}),(0,x.jsx)(`path`,{d:`m17 16.5-5-3`}),(0,x.jsx)(`path`,{d:`m17 16.5 4.74-2.85`}),(0,x.jsx)(`path`,{d:`m17 16.5v5.17`}),(0,x.jsx)(`path`,{d:`M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z`}),(0,x.jsx)(`path`,{d:`M12 8 7.26 5.15`}),(0,x.jsx)(`path`,{d:`m12 8 4.74-2.85`}),(0,x.jsx)(`path`,{d:`M12 13.5V8`})]})}),(0,x.jsx)(p.SidebarNavLink,{to:`/automations`,label:B(n.I18nKey.SIDEBAR$AUTOMATIONS),testId:`sidebar-automations-link`,collapsed:e,icon:(0,x.jsx)(y.default,{width:S,height:S})})]}),(0,x.jsx)(v.SidebarConversationList,{collapsed:e}),e&&b?(0,x.jsxs)(`nav`,{className:c.cn(d.sidebarNavListClassName(e),`mt-auto pb-2 cursor-pointer`),children:[(0,x.jsx)(l.StyledTooltip,{content:B(n.I18nKey.SIDEBAR$SETTINGS),placement:`right`,children:(0,x.jsxs)(u.NavigationLink,{to:`/settings`,"data-testid":`collapsed-settings-link`,"aria-label":B(n.I18nKey.SIDEBAR$SETTINGS),className:d.sidebarNavRowClassName({collapsed:!0}),children:[(0,x.jsx)(f.SidebarCollapsedIconSlot,{active:M.startsWith(`/settings`),children:(0,x.jsx)(s.Settings,{width:S,height:S})}),(0,x.jsx)(`span`,{className:d.sidebarNavLabelClassName(!0),children:B(n.I18nKey.SIDEBAR$SETTINGS)})]})}),(0,x.jsxs)(`div`,{className:`relative`,ref:I,onMouseEnter:()=>{V.current&&=(clearTimeout(V.current),null),F(!0)},onMouseLeave:()=>{V.current=setTimeout(()=>F(!1),150)},children:[(0,x.jsxs)(`button`,{type:`button`,"data-testid":`collapsed-backend-selector-link`,"aria-label":B(n.I18nKey.BACKEND$MANAGE),"aria-expanded":P,onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onMouseUp:e=>e.stopPropagation(),className:c.cn(d.sidebarNavRowClassName({collapsed:!0}),`relative`),children:[(0,x.jsx)(f.SidebarCollapsedIconSlot,{active:P,children:(0,x.jsxs)(`span`,{className:`relative inline-flex size-[18px] shrink-0 items-center justify-center`,children:[(0,x.jsx)(h.BackendStatusDot,{isConnected:N?.isConnected??null,className:`absolute -left-0.5 -top-0.5 z-[1] pointer-events-none`}),(0,x.jsx)(o.Server,{width:S,height:S})]})}),(0,x.jsx)(`span`,{className:d.sidebarNavLabelClassName(!0),children:B(n.I18nKey.BACKEND$MANAGE)})]}),P?(0,x.jsx)(`div`,{className:`absolute bottom-[-4px] left-full pl-2.5 z-40 w-[272px]`,onClick:e=>e.stopPropagation(),children:(0,x.jsx)(g.BackendSelector,{sidebarCollapsed:e,hideTrigger:!0,defaultOpen:!0,openUpward:!0,onSelectOption:()=>F(!1),onOpenAddBackend:R,onOpenManageBackends:z})}):null]})]}):null,e?null:(0,x.jsx)(`div`,{className:c.cn(`flex flex-col items-stretch max-w-none box-border shrink-0`,`-ml-2.5 w-[calc(100%+0.625rem)] border-t border-[var(--oh-border)] pt-2 px-2.5`),children:(0,x.jsx)(g.BackendSelector,{sidebarCollapsed:e,openUpward:!0})})]})}exports.SidebarRailBody=T;
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("../../../node_modules/lucide-react/dist/esm/icons/chevron-left.cjs"),i=require("../../../node_modules/lucide-react/dist/esm/icons/chevron-right.cjs"),a=require("../../../node_modules/lucide-react/dist/esm/icons/plus.cjs"),o=require("../../../node_modules/lucide-react/dist/esm/icons/server.cjs"),s=require("../../../node_modules/lucide-react/dist/esm/icons/settings.cjs"),c=require("../../../utils/utils.cjs"),l=require("../../../manifests/automation-interface.cjs"),u=require("../../shared/buttons/styled-tooltip.cjs"),d=require("../../shared/navigation-link.cjs"),f=require("./sidebar-layout.cjs"),p=require("./sidebar-collapsed-icon-slot.cjs"),m=require("./sidebar-nav-link.cjs"),h=require("../../shared/buttons/openhands-logo-button.cjs"),g=require("../backends/backend-status-dot.cjs"),_=require("../backends/backend-selector.cjs"),v=require("../command-menu/command-menu-trigger.cjs"),y=require("./sidebar-conversation-list.cjs"),b=require("../../../icons/automations.cjs");let x=require("react");x=e.__toESM(x,1);let S=require("react/jsx-runtime");var C=18,w=34,T=Math.round(w*30/46);function E({collapsed:e,showCollapseToggle:x,showMobileCloseButton:E=!1,onCloseMobile:D,collapseToggleLabel:O,onCollapse:k,onExpand:A,showCollapsedExpandButton:j,isExtensionsActive:M,currentPath:N,activeBackendHealth:P,collapsedBackendPopoverOpen:F,setCollapsedBackendPopoverOpen:I,collapsedBackendPopoverRef:L,collapsedBackendCloseTimer:R,onOpenAddBackend:z,onOpenManageBackends:B}){let{t:V}=t.useTranslation(`openhands`),H=R;return(0,S.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col`,children:[(0,S.jsxs)(`div`,{className:f.sidebarHeaderRowClassName(e),children:[(0,S.jsxs)(`div`,{className:c.cn(e&&x?f.SIDEBAR_COLLAPSED_LOGO_WRAPPER_CLASS:`flex min-w-0 shrink-0 items-center`),children:[(0,S.jsx)(`div`,{className:c.cn(e&&x&&`flex h-full w-full items-center justify-start pl-2.5 transition-opacity duration-150`,e&&j&&`opacity-0`),children:(0,S.jsx)(h.OpenHandsLogoButton,{logoWidth:w,logoHeight:T,logoClassName:`max-w-none`,className:c.cn(f.SIDEBAR_ICON_SLOT_CLASS,`overflow-visible`)})}),e&&x?(0,S.jsx)(`button`,{type:`button`,"data-testid":`sidebar-collapse-toggle`,"aria-pressed":e,"aria-label":O,onClick:A,className:c.cn(f.SIDEBAR_COLLAPSE_TOGGLE_OVERLAY_CLASS,j?`opacity-100 pointer-events-auto`:`opacity-0 pointer-events-none`),children:(0,S.jsx)(i.ChevronRight,{width:14,height:14})}):null]}),!e&&x?(0,S.jsx)(`button`,{type:`button`,"data-testid":`sidebar-collapse-toggle`,"aria-pressed":e,"aria-label":O,onClick:k,className:c.cn(`hidden md:inline-flex ml-auto`,f.SIDEBAR_ICON_BUTTON_CLASS,`text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]`),children:(0,S.jsx)(r.ChevronLeft,{width:14,height:14})}):null,!e&&E?(0,S.jsx)(`button`,{type:`button`,"data-testid":`sidebar-mobile-drawer-close`,onClick:D,"aria-label":V(n.I18nKey.SIDEBAR$CLOSE_MENU),className:c.cn(`inline-flex ml-auto`,f.SIDEBAR_ICON_BUTTON_CLASS,`text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)]`),children:(0,S.jsx)(r.ChevronLeft,{width:14,height:14})}):null]}),(0,S.jsxs)(`nav`,{className:f.sidebarNavListClassName(e),children:[(0,S.jsx)(v.CommandMenuTrigger,{collapsed:e}),(0,S.jsx)(m.SidebarNavLink,{to:`/conversations`,end:!0,label:V(n.I18nKey.SIDEBAR$NEW_CHAT),testId:`sidebar-conversations-link`,collapsed:e,icon:(0,S.jsx)(a.Plus,{width:C,height:C})}),(0,S.jsx)(m.SidebarNavLink,{to:`/customize`,label:V(n.I18nKey.NAV$CUSTOMIZE),testId:`sidebar-skills-link`,collapsed:e,forceActive:M,icon:(0,S.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:C,height:C,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[(0,S.jsx)(`path`,{d:`M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z`}),(0,S.jsx)(`path`,{d:`m7 16.5-4.74-2.85`}),(0,S.jsx)(`path`,{d:`m7 16.5 5-3`}),(0,S.jsx)(`path`,{d:`M7 16.5v5.17`}),(0,S.jsx)(`path`,{d:`M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z`}),(0,S.jsx)(`path`,{d:`m17 16.5-5-3`}),(0,S.jsx)(`path`,{d:`m17 16.5 4.74-2.85`}),(0,S.jsx)(`path`,{d:`m17 16.5v5.17`}),(0,S.jsx)(`path`,{d:`M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z`}),(0,S.jsx)(`path`,{d:`M12 8 7.26 5.15`}),(0,S.jsx)(`path`,{d:`m12 8 4.74-2.85`}),(0,S.jsx)(`path`,{d:`M12 13.5V8`})]})}),(0,S.jsx)(m.SidebarNavLink,{to:l.automationListPath(),label:l.getInterfaceCopy().sidebarLabel??V(n.I18nKey.SIDEBAR$AUTOMATIONS),testId:`sidebar-automations-link`,collapsed:e,icon:(0,S.jsx)(b.default,{width:C,height:C})})]}),(0,S.jsx)(y.SidebarConversationList,{collapsed:e}),e&&x?(0,S.jsxs)(`nav`,{className:c.cn(f.sidebarNavListClassName(e),`mt-auto pb-2 cursor-pointer`),children:[(0,S.jsx)(u.StyledTooltip,{content:V(n.I18nKey.SIDEBAR$SETTINGS),placement:`right`,children:(0,S.jsxs)(d.NavigationLink,{to:`/settings`,"data-testid":`collapsed-settings-link`,"aria-label":V(n.I18nKey.SIDEBAR$SETTINGS),className:f.sidebarNavRowClassName({collapsed:!0}),children:[(0,S.jsx)(p.SidebarCollapsedIconSlot,{active:N.startsWith(`/settings`),children:(0,S.jsx)(s.Settings,{width:C,height:C})}),(0,S.jsx)(`span`,{className:f.sidebarNavLabelClassName(!0),children:V(n.I18nKey.SIDEBAR$SETTINGS)})]})}),(0,S.jsxs)(`div`,{className:`relative`,ref:L,onMouseEnter:()=>{H.current&&=(clearTimeout(H.current),null),I(!0)},onMouseLeave:()=>{H.current=setTimeout(()=>I(!1),150)},children:[(0,S.jsxs)(`button`,{type:`button`,"data-testid":`collapsed-backend-selector-link`,"aria-label":V(n.I18nKey.BACKEND$MANAGE),"aria-expanded":F,onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onMouseUp:e=>e.stopPropagation(),className:c.cn(f.sidebarNavRowClassName({collapsed:!0}),`relative`),children:[(0,S.jsx)(p.SidebarCollapsedIconSlot,{active:F,children:(0,S.jsxs)(`span`,{className:`relative inline-flex size-[18px] shrink-0 items-center justify-center`,children:[(0,S.jsx)(g.BackendStatusDot,{isConnected:P?.isConnected??null,className:`absolute -left-0.5 -top-0.5 z-[1] pointer-events-none`}),(0,S.jsx)(o.Server,{width:C,height:C})]})}),(0,S.jsx)(`span`,{className:f.sidebarNavLabelClassName(!0),children:V(n.I18nKey.BACKEND$MANAGE)})]}),F?(0,S.jsx)(`div`,{className:`absolute bottom-[-4px] left-full pl-2.5 z-40 w-[272px]`,onClick:e=>e.stopPropagation(),children:(0,S.jsx)(_.BackendSelector,{sidebarCollapsed:e,hideTrigger:!0,defaultOpen:!0,openUpward:!0,onSelectOption:()=>I(!1),onOpenAddBackend:z,onOpenManageBackends:B})}):null]})]}):null,e?null:(0,S.jsx)(`div`,{className:c.cn(`flex flex-col items-stretch max-w-none box-border shrink-0`,`-ml-2.5 w-[calc(100%+0.625rem)] border-t border-[var(--oh-border)] pt-2 px-2.5`),children:(0,S.jsx)(_.BackendSelector,{sidebarCollapsed:e,openUpward:!0})})]})}exports.SidebarRailBody=E;
2
2
  //# sourceMappingURL=sidebar-rail-body.cjs.map