@openhands/agent-canvas 1.0.0-rc.1 → 1.0.0-rc.3

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 (460) hide show
  1. package/README.md +2 -2
  2. package/README.windows.md +2 -2
  3. package/build/assets/{QueryClientProvider-w1cZWY41.js → QueryClientProvider-7oLZ1RtQ.js} +1 -1
  4. package/build/assets/{Trans-BJeYqz2A.js → Trans-rF21Jwln.js} +1 -1
  5. package/build/assets/acp-providers-C55k29rf.js +1 -0
  6. package/build/assets/active-backend-context-CQTk4wD8.js +1 -0
  7. package/build/assets/add-backend-modal-BdYxoUdL.js +1 -0
  8. package/build/assets/agent-server-client-options-Dvgeb3x4.js +1 -0
  9. package/build/assets/agent-server-compatibility-BANjmMTo.js +1 -0
  10. package/build/assets/agent-server-conversation-service.api-js3oYcdU.js +5 -0
  11. package/build/assets/{agent-settings-BXBaybB_.js → agent-settings-BNrffu3I.js} +1 -1
  12. package/build/assets/{alert-banner-NeUl1-PQ.js → alert-banner-BzU93oDh.js} +1 -1
  13. package/build/assets/{analytics-consent-form-modal-DxkThW4K.js → analytics-consent-form-modal-Ce-_Skcd.js} +1 -1
  14. package/build/assets/api-key-entry-screen-CGyS-Cna.js +1 -0
  15. package/build/assets/{app-settings-C-U6jONZ.js → app-settings-DmOs4oik.js} +1 -1
  16. package/build/assets/automation-detail-DLbCVJCw.js +1 -0
  17. package/build/assets/{automations-list-BLJzAd-p.js → automations-list-Ces5shz5.js} +1 -1
  18. package/build/assets/{back-nav-button-DgkK0Ka6.js → back-nav-button-BDM9vr_o.js} +1 -1
  19. package/build/assets/backend-form-modal-BUy-PzZN.js +1 -0
  20. package/build/assets/{backend-synced-settings-badge-BktJcGgH.js → backend-synced-settings-badge-1A63yxGs.js} +1 -1
  21. package/build/assets/{base-modal-DZCNv0A4.js → base-modal-Ba5WcNb6.js} +1 -1
  22. package/build/assets/{brand-button-LBFNic99.js → brand-button-BoiPxAGm.js} +1 -1
  23. package/build/assets/browser-B8bp1IqT.js +5 -0
  24. package/build/assets/browser-store-C5uQbbIi.js +1 -0
  25. package/build/assets/{browser-tab-be3QvXg9.js → browser-tab-CiBRWB4X.js} +1 -1
  26. package/build/assets/chat-send-button-qKFZuB9E.js +1 -0
  27. package/build/assets/check-BDAbW7je.js +1 -0
  28. package/build/assets/{checkmark-Rmpruj7q.js → checkmark-SEZPnU2I.js} +1 -1
  29. package/build/assets/{chevron-down-KhWYEjeW.js → chevron-down-DUxWwzTm.js} +1 -1
  30. package/build/assets/{chevron-left-small-6nyFCWVQ.js → chevron-left-small-x9_-ucHG.js} +1 -1
  31. package/build/assets/{circle-plus-check-toggle-DquBwJ_6.js → circle-plus-check-toggle-CboDp7XB.js} +1 -1
  32. package/build/assets/{close-D_o3d8QM.js → close-CbOsKMRg.js} +1 -1
  33. package/build/assets/{code-tag-DhsjDB-v.js → code-tag-C0vR_IQH.js} +1 -1
  34. package/build/assets/{color-themes-0biOprdo.js → color-themes-B9n7pBQl.js} +1 -1
  35. package/build/assets/{combobox-caret-CO7eozIY.js → combobox-caret-DwMmhrrA.js} +1 -1
  36. package/build/assets/{command-store-UzKGSUC2.js → command-store-BUWgE-vZ.js} +1 -1
  37. package/build/assets/{condenser-settings-BulzYEuW.js → condenser-settings-FCBjvqSo.js} +1 -1
  38. package/build/assets/{confirmation-modal-CMAtd9R0.js → confirmation-modal-BPgWqWRI.js} +1 -1
  39. package/build/assets/{context-menu-list-item-D0swnhFt.js → context-menu-list-item-CHWCx1Mc.js} +1 -1
  40. package/build/assets/conversation-CT8AvxEH.js +1 -0
  41. package/build/assets/conversation-panel-DqDDs4WZ.js +1 -0
  42. package/build/assets/conversation-service.api-y_eB_43m.js +1 -0
  43. package/build/assets/conversation-state-store-DpgQaK_O.js +1 -0
  44. package/build/assets/conversation-store-CiYGBud3.js +6 -0
  45. package/build/assets/{conversation-tab-empty-state-DYjKsg_c.js → conversation-tab-empty-state-Ba5hbJhn.js} +1 -1
  46. package/build/assets/conversation-vNuLKgz6.js +19 -0
  47. package/build/assets/conversation-websocket-context-Bb4XBXoc.js +3 -0
  48. package/build/assets/{copy-BM0RpLez.js → copy-CAxUvM-U.js} +1 -1
  49. package/build/assets/{custom-toast-handlers-BohXx7uh.js → custom-toast-handlers-fgD4IYsu.js} +1 -1
  50. package/build/assets/{declaration-DaUdB2Wg.js → declaration-IA661TBv.js} +1 -1
  51. package/build/assets/{device-verify-DiEJqpJb.js → device-verify-BOQz2LJQ.js} +1 -1
  52. package/build/assets/{dist-xtCm0O6P.js → dist-B-SKiGDl.js} +1 -1
  53. package/build/assets/dist-CeJSjcAI.js +1 -0
  54. package/build/assets/{dropdown-classes-Vqz86I0R.js → dropdown-classes-lT1LUsbO.js} +1 -1
  55. package/build/assets/edit-automation-modal-C-oC5tis.js +1 -0
  56. package/build/assets/ellipsis-button-CiLx8dqc.js +1 -0
  57. package/build/assets/{entry.client-BvKgdCQ9.js → entry.client-Db3BpFL_.js} +2 -2
  58. package/build/assets/{enum-filter-dropdown-DdFgk0EM.js → enum-filter-dropdown-DFwoVtOw.js} +1 -1
  59. package/build/assets/{environment-switch-overlay-CuBuZOaa.js → environment-switch-overlay-Cow6h62p.js} +1 -1
  60. package/build/assets/{extensions-hub-Dayqvv0n.js → extensions-hub-BxZbAtjP.js} +1 -1
  61. package/build/assets/extensions-navigation-BIb-vAa2.js +1 -0
  62. package/build/assets/{file-DwHCkWZT.js → file-BJCSojij.js} +1 -1
  63. package/build/assets/files-tab-DpulQlIo.js +1 -0
  64. package/build/assets/files-tab-store-CZAEwv3x.js +1 -0
  65. package/build/assets/{folder-2h1hR1Qb.js → folder-wShAU0y7.js} +1 -1
  66. package/build/assets/git-control-bar-branch-button-D1uam-nI.js +27 -0
  67. package/build/assets/{globe-qFjFNG6J.js → globe-CQ_5xwpo.js} +1 -1
  68. package/build/assets/home-sJAFzI6v.js +1 -0
  69. package/build/assets/{i18n-zDndR1Ne.js → i18n-CyvU1o95.js} +1 -1
  70. package/build/assets/install-server-modal-BjEzlLF5.js +1 -0
  71. package/build/assets/{launch-I00QV8YT.js → launch-DgtB1JTX.js} +1 -1
  72. package/build/assets/{lesson-plan-C18uB_56.js → lesson-plan-B607buca.js} +1 -1
  73. package/build/assets/{link-external-DtcdPFbw.js → link-external-DCsHkAj4.js} +1 -1
  74. package/build/assets/llm-client-BnqeDPua.js +1 -0
  75. package/build/assets/llm-settings-B8kPJ0Of.js +1 -0
  76. package/build/assets/llm-settings-CjUpPsvA.js +1 -0
  77. package/build/assets/{loading-spinner-DNwR4--Z.js → loading-spinner-CFuA0UNt.js} +1 -1
  78. package/build/assets/manage-backends-modal-CTA-2x4F.js +1 -0
  79. package/build/assets/manifest-d3e8504d.js +1 -0
  80. package/build/assets/{markdown-renderer-D6B-u2nM.js → markdown-renderer-oOUs3tw5.js} +1 -1
  81. package/build/assets/mcp-client-xEdbDxOL.js +1 -0
  82. package/build/assets/mcp-kJYdM8aJ.js +9 -0
  83. package/build/assets/messages-BFJXB6MW.js +36 -0
  84. package/build/assets/{modal-backdrop-BDqI1zBV.js → modal-backdrop-B1si6TUd.js} +1 -1
  85. package/build/assets/{modal-body-CCLCqX1J.js → modal-body-2Po2nl1e.js} +1 -1
  86. package/build/assets/{modal-classes-DwTdT3IK.js → modal-classes-9XTtWCtF.js} +1 -1
  87. package/build/assets/{modal-close-button-gQgKqUf-.js → modal-close-button-DY-rVmld.js} +1 -1
  88. package/build/assets/model-selector-z_QOzaRV.js +1 -0
  89. package/build/assets/{navigation-context-aNGUUtdq.js → navigation-context-CszaA-CJ.js} +1 -1
  90. package/build/assets/{navigation-link-CYkF2y3K.js → navigation-link-DXg4oo29.js} +1 -1
  91. package/build/assets/onboarding-CZ_7nd-M.js +1 -0
  92. package/build/assets/{openhands-logo-CHmtDV-t.js → openhands-logo-B-IDE1ER.js} +1 -1
  93. package/build/assets/{option-service.api-CGNANEcT.js → option-service.api-DHOGfYKh.js} +1 -1
  94. package/build/assets/organization-service.api-D79cdERN.js +1 -0
  95. package/build/assets/path-utils-0KWEiRs9.js +1 -0
  96. package/build/assets/{pencil-Dr0b2jL1.js → pencil-COslZGUC.js} +1 -1
  97. package/build/assets/{plan-components--aLlpASH.js → plan-components-DsiDjcDi.js} +1 -1
  98. package/build/assets/{planner-tab-B-5EeCEm.js → planner-tab-CNmJiZ22.js} +1 -1
  99. package/build/assets/plus-D8aJZRkD.js +1 -0
  100. package/build/assets/profiles-client-CesbAK-7.js +1 -0
  101. package/build/assets/{providers-DknP6O2g.js → providers-Bpq3xFRA.js} +1 -1
  102. package/build/assets/proxy-wIasY2Po.js +1 -0
  103. package/build/assets/{query-client-config-CWWGQWvw.js → query-client-config-CITeuHD7.js} +1 -1
  104. package/build/assets/{recommended-automations-launcher-BIul0osB.js → recommended-automations-launcher-B1kfmFTQ.js} +8 -10
  105. package/build/assets/root-CIZ7Rv1X.js +2 -0
  106. package/build/assets/root-layout-B5ijp9At.js +2 -0
  107. package/build/assets/{sdk-section-page-VmtJWH3A.js → sdk-section-page-DTyvCc52.js} +1 -1
  108. package/build/assets/{sdk-settings-schema-DFievvEK.js → sdk-settings-schema-B0KrqqPX.js} +1 -1
  109. package/build/assets/{search-BeVRXvX7.js → search-BqXT2Ied.js} +1 -1
  110. package/build/assets/secrets-service-rJqZtDmI.js +1 -0
  111. package/build/assets/{secrets-settings-BLMvCkKm.js → secrets-settings-BQNSDLKS.js} +1 -1
  112. package/build/assets/server-client-Cz8PyIbN.js +1 -0
  113. package/build/assets/settings-BUlJrO_h.js +1 -0
  114. package/build/assets/settings-client-BUlG0Gzq.js +1 -0
  115. package/build/assets/{settings-dropdown-input-DA_pzHWE.js → settings-dropdown-input-BUk4m23x.js} +1 -1
  116. package/build/assets/{settings-gear-aNebYlCy.js → settings-gear-DFmoMp-6.js} +1 -1
  117. package/build/assets/{settings-index-CycvkOoq.js → settings-index-DE91Eahc.js} +1 -1
  118. package/build/assets/{settings-input-8y5p4kze.js → settings-input-DsoZj8Dm.js} +1 -1
  119. package/build/assets/{settings-list-classes-Qk7zl0Wu.js → settings-list-classes-D8VAVZmi.js} +1 -1
  120. package/build/assets/{settings-modal-DdntdOGP.js → settings-modal-CCaPYVqW.js} +1 -1
  121. package/build/assets/{settings-section-header-context-B77tsYlx.js → settings-section-header-context-D61smD-W.js} +1 -1
  122. package/build/assets/settings-service.api-4u2RKC8k.js +1 -0
  123. package/build/assets/{settings-switch-ba4DuiNO.js → settings-switch-BQiAS9ga.js} +1 -1
  124. package/build/assets/{settings-utils-BxzHqLmZ.js → settings-utils-chxTa1vn.js} +1 -1
  125. package/build/assets/shared-conversation-sBPLAawM.js +1 -0
  126. package/build/assets/{sidebar-mobile-menu-toggle-C0mmabKj.js → sidebar-mobile-menu-toggle-BDXWzhyB.js} +1 -1
  127. package/build/assets/{sidebar-nav-link-BsYdDFfb.js → sidebar-nav-link-Bhlzlhp8.js} +1 -1
  128. package/build/assets/{skill-card-pill-row-BhUlGcYB.js → skill-card-pill-row-Bg5joQf6.js} +1 -1
  129. package/build/assets/{skills-TYjOUQ2d.js → skills-BDOWVle-.js} +1 -1
  130. package/build/assets/skills-client-Cr9F5306.js +1 -0
  131. package/build/assets/{skills-plugins-D0pdqgKa.js → skills-plugins-fihjo1KZ.js} +1 -1
  132. package/build/assets/{skills-settings-VqKTkmVl.js → skills-settings-NQnuMwZP.js} +1 -1
  133. package/build/assets/{styled-tooltip-TCp7svY3.js → styled-tooltip-GXy1qxsO.js} +1 -1
  134. package/build/assets/suspense-C9MBE_9N.js +1 -0
  135. package/build/assets/{switch-skeleton-cKrdaYGj.js → switch-skeleton-QpdcdxRP.js} +1 -1
  136. package/build/assets/{task-list-tab-BiizRsY3.js → task-list-tab-Hl9BuVfq.js} +1 -1
  137. package/build/assets/telemetry-j9SLrtY7.js +2 -0
  138. package/build/assets/{terminal-BSYITdM0.js → terminal-BUww3Ssl.js} +1 -1
  139. package/build/assets/{terminal-CpgZx6go.js → terminal-DRwe8--D.js} +1 -1
  140. package/build/assets/{toggle-switch-CUgOZqZu.js → toggle-switch-DDr-DnEc.js} +1 -1
  141. package/build/assets/{trash-2-CbVljPko.js → trash-2-DAKXV2Wm.js} +1 -1
  142. package/build/assets/{typography-Bvw0IxaN.js → typography-Cx7uw7z3.js} +1 -1
  143. package/build/assets/{u-check-circle-u9QiS4Fr.js → u-check-circle-CftRwky1.js} +1 -1
  144. package/build/assets/{u-check-circle-half-DjpjzWu3.js → u-check-circle-half-sGVk0BtL.js} +1 -1
  145. package/build/assets/{u-circuit-DlBlOwx9.js → u-circuit-Cg9tH5qb.js} +1 -1
  146. package/build/assets/{u-edit-BIYzjs3v.js → u-edit-foF02hwH.js} +1 -1
  147. package/build/assets/{use-active-conversation-q1wT8LI5.js → use-active-conversation-DJGoI9Mc.js} +1 -1
  148. package/build/assets/use-agent-settings-schema-DtusObuC.js +1 -0
  149. package/build/assets/{use-agent-state-CCHlVqvY.js → use-agent-state-BXgWhFh6.js} +1 -1
  150. package/build/assets/{use-cloud-current-user-id-BAKf91Zx.js → use-cloud-current-user-id-e1Pk7NxQ.js} +1 -1
  151. package/build/assets/use-config-DSzkljTq.js +1 -0
  152. package/build/assets/use-create-conversation-CzvaVA5A.js +1 -0
  153. package/build/assets/use-event-store-DSpvASbC.js +1 -0
  154. package/build/assets/use-get-secrets-DiLgP147.js +1 -0
  155. package/build/assets/use-handle-plan-click-CUZwmKIk.js +1 -0
  156. package/build/assets/use-is-authed-fNsj-Adj.js +1 -0
  157. package/build/assets/{use-launch-skill-in-chat-3ydwpi_M.js → use-launch-skill-in-chat-ClRJlIx7.js} +1 -1
  158. package/build/assets/use-llm-profiles-CyNVoVqm.js +1 -0
  159. package/build/assets/use-runtime-is-ready-CWkGQFsb.js +1 -0
  160. package/build/assets/{use-save-settings-rE9aA29R.js → use-save-settings-CP23emUY.js} +1 -1
  161. package/build/assets/use-settings-0qFqC-r6.js +1 -0
  162. package/build/assets/{use-settings-nav-items-C7MOWj09.js → use-settings-nav-items-C6YxUn4h.js} +1 -1
  163. package/build/assets/use-skills-BWHATXK-.js +1 -0
  164. package/build/assets/{use-task-list-YMkSzdDv.js → use-task-list-JPudBRv3.js} +1 -1
  165. package/build/assets/{use-tracking-DQYdZpxi.js → use-tracking-CjLZgh8X.js} +1 -1
  166. package/build/assets/use-unified-vscode-url-DSn2tT08.js +1 -0
  167. package/build/assets/use-user-conversation-CQ5IwnZk.js +1 -0
  168. package/build/assets/{useMutation-DDo48A8t.js → useMutation-7hG0GuPx.js} +1 -1
  169. package/build/assets/useQuery-JDs8UaWj.js +1 -0
  170. package/build/assets/{useTranslation-CEcjrme-.js → useTranslation-CbJtty1g.js} +1 -1
  171. package/build/assets/{utils-CdgBzLA7.js → utils-CVcuFUYj.js} +1 -1
  172. package/build/assets/{vendor~browser-DWk6fNtJ.js → vendor~browser-Dwwc84Zf.js} +1 -1
  173. package/build/assets/{vendor~browser-tab-NZdVoI2Z.js → vendor~browser-tab-Bhohe29F.js} +1 -1
  174. package/build/assets/{vendor~conversation-panel~conversation-gp03cWZW.js → vendor~conversation-panel~conversation-DYHL7QoY.js} +1 -1
  175. package/build/assets/{vendor~conversation-panel~conversation~index-BZ5C6Xpz.js → vendor~conversation-panel~conversation~index-Be58Romv.js} +1 -1
  176. package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~oli4dvxu-BodGsxSf.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~oli4dvxu-CBEOG8NF.js} +1 -1
  177. package/build/assets/{vendor~files-tab-Buz36Y-q.js → vendor~files-tab-B447_Zns.js} +1 -1
  178. package/build/assets/{vendor~home~conversation-panel~conversation-DG0H5SkJ.js → vendor~home~conversation-panel~conversation-DZ-F7J6T.js} +1 -1
  179. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CXivI4Ym.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-B4oeCCli.js} +1 -1
  180. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-9Il_wz8U.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CQQAW8hY.js} +1 -1
  181. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-1pTajrpX.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DFsI4CLy.js} +1 -1
  182. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Ceeqkj0k.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DcvlNgbn.js} +1 -1
  183. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-B7I1ZxCx.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-ojk_J4bB.js} +1 -1
  184. package/build/assets/{vendor~launch-DXL78kBf.js → vendor~launch-BdXJCmwc.js} +1 -1
  185. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-CfAc3nMS.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-DToubnIU.js} +1 -1
  186. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation-DkwcKRtv.js → vendor~root-layout~home~conversation-panel~conversation-Cg0nXqVs.js} +1 -1
  187. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-DSqEbr0N.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~bok0tgtf-Dr8Ly0at.js} +1 -1
  188. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-BC9XTECT.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~bok0tgtf-DveauQfg.js} +1 -1
  189. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-D0XUSHNN.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~jpfhx3ls-zdl_Rltz.js} +2 -2
  190. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~jxrvuot9-BaCzvZac.js +48 -0
  191. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-CcFtthyg.js → vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-BwbkftxT.js} +1 -1
  192. package/build/assets/{vendor~root-layout~home~mcp~automations-list-cNHi83v_.js → vendor~root-layout~home~mcp~automations-list-CtdIEhjQ.js} +1 -1
  193. package/build/assets/{vendor~root-layout~home~mcp~automations-list-BnIlGhjl.js → vendor~root-layout~home~mcp~automations-list-DGOI7kQz.js} +1 -1
  194. package/build/assets/{vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-BGWUbqUq.js → vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-CbuXadI-.js} +1 -1
  195. package/build/assets/{vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-BuCSnjsW.js → vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-iPAfRWNQ.js} +2 -2
  196. package/build/assets/{verification-settings-CIqtxWat.js → verification-settings-Cm02KmeI.js} +1 -1
  197. package/build/assets/{vscode-tab-DEt72yJX.js → vscode-tab-AF70Yke0.js} +1 -1
  198. package/build/assets/{waiting-for-runtime-message-DSjJfeoj.js → waiting-for-runtime-message-Bg27u9JB.js} +1 -1
  199. package/build/assets/x-8AbJWTbX.js +1 -0
  200. package/build/assets/{x-mark-DsJ9tDD0.js → x-mark-Cn-YJVbN.js} +1 -1
  201. package/build/index.html +4 -4
  202. package/build/locales/ar/openhands.json +2 -1
  203. package/build/locales/ca/openhands.json +2 -1
  204. package/build/locales/de/openhands.json +2 -1
  205. package/build/locales/en/openhands.json +2 -1
  206. package/build/locales/es/openhands.json +2 -1
  207. package/build/locales/fr/openhands.json +2 -1
  208. package/build/locales/it/openhands.json +2 -1
  209. package/build/locales/ja/openhands.json +2 -1
  210. package/build/locales/ko-KR/openhands.json +2 -1
  211. package/build/locales/no/openhands.json +2 -1
  212. package/build/locales/pt/openhands.json +2 -1
  213. package/build/locales/tr/openhands.json +2 -1
  214. package/build/locales/uk/openhands.json +2 -1
  215. package/build/locales/zh-CN/openhands.json +2 -1
  216. package/build/locales/zh-TW/openhands.json +2 -1
  217. package/config/defaults.json +1 -1
  218. package/dist/api/agent-server-adapter.cjs +3 -3
  219. package/dist/api/agent-server-adapter.cjs.map +1 -1
  220. package/dist/api/agent-server-adapter.js +94 -86
  221. package/dist/api/agent-server-adapter.js.map +1 -1
  222. package/dist/api/app-preferences-store.cjs.map +1 -1
  223. package/dist/api/app-preferences-store.d.ts +6 -2
  224. package/dist/api/app-preferences-store.js.map +1 -1
  225. package/dist/api/cloud/proxy.cjs +1 -1
  226. package/dist/api/cloud/proxy.cjs.map +1 -1
  227. package/dist/api/cloud/proxy.d.ts +18 -6
  228. package/dist/api/cloud/proxy.js +1 -1
  229. package/dist/api/cloud/proxy.js.map +1 -1
  230. package/dist/api/conversation-metadata-store.cjs.map +1 -1
  231. package/dist/api/conversation-metadata-store.d.ts +8 -0
  232. package/dist/api/conversation-metadata-store.js.map +1 -1
  233. package/dist/api/conversation-service/agent-server-conversation-service.types.d.ts +9 -0
  234. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs +1 -1
  235. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs.map +1 -1
  236. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js +9 -9
  237. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js.map +1 -1
  238. package/dist/components/conversation-events/chat/event-message.cjs +1 -1
  239. package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
  240. package/dist/components/conversation-events/chat/event-message.js +80 -71
  241. package/dist/components/conversation-events/chat/event-message.js.map +1 -1
  242. package/dist/components/features/automations/recommended-automations-launcher.d.ts +7 -1
  243. package/dist/components/features/chat/switch-profile-button.cjs +1 -1
  244. package/dist/components/features/chat/switch-profile-button.cjs.map +1 -1
  245. package/dist/components/features/chat/switch-profile-button.js +5 -5
  246. package/dist/components/features/chat/switch-profile-button.js.map +1 -1
  247. package/dist/components/features/conversation-panel/skills-modal.cjs +1 -1
  248. package/dist/components/features/conversation-panel/skills-modal.cjs.map +1 -1
  249. package/dist/components/features/conversation-panel/skills-modal.js +34 -37
  250. package/dist/components/features/conversation-panel/skills-modal.js.map +1 -1
  251. package/dist/components/features/home/workspace-selection-form.d.ts +1 -0
  252. package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +8 -0
  253. package/dist/components/features/settings/llm-profiles/profile-actions-menu.cjs +1 -1
  254. package/dist/components/features/settings/llm-profiles/profile-actions-menu.js +1 -0
  255. package/dist/components/features/sidebar/sidebar.cjs +1 -1
  256. package/dist/components/features/sidebar/sidebar.js +6 -6
  257. package/dist/components/features/skills/extensions-navigation.cjs +1 -1
  258. package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
  259. package/dist/components/features/skills/extensions-navigation.d.ts +1 -9
  260. package/dist/components/features/skills/extensions-navigation.js +31 -50
  261. package/dist/components/features/skills/extensions-navigation.js.map +1 -1
  262. package/dist/constants/acp-providers.cjs +1 -1
  263. package/dist/constants/acp-providers.js +1 -1
  264. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  265. package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
  266. package/dist/hooks/mutation/use-create-conversation.js +26 -14
  267. package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
  268. package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs +1 -1
  269. package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs.map +1 -1
  270. package/dist/hooks/mutation/use-switch-llm-profile-and-log.js +26 -15
  271. package/dist/hooks/mutation/use-switch-llm-profile-and-log.js.map +1 -1
  272. package/dist/i18n/declaration.cjs +1 -1
  273. package/dist/i18n/declaration.cjs.map +1 -1
  274. package/dist/i18n/declaration.d.ts +1 -0
  275. package/dist/i18n/declaration.js +1 -1
  276. package/dist/i18n/declaration.js.map +1 -1
  277. package/dist/i18n/translation.cjs +1 -1
  278. package/dist/i18n/translation.cjs.map +1 -1
  279. package/dist/i18n/translation.js +32 -15
  280. package/dist/i18n/translation.js.map +1 -1
  281. package/dist/index.cjs +1 -1
  282. package/dist/index.js +10 -10
  283. package/dist/lib/index.cjs +1 -1
  284. package/dist/lib/index.js +1 -1
  285. package/dist/locales/ar/openhands.json +2 -1
  286. package/dist/locales/ca/openhands.json +2 -1
  287. package/dist/locales/de/openhands.json +2 -1
  288. package/dist/locales/en/openhands.json +2 -1
  289. package/dist/locales/es/openhands.json +2 -1
  290. package/dist/locales/fr/openhands.json +2 -1
  291. package/dist/locales/it/openhands.json +2 -1
  292. package/dist/locales/ja/openhands.json +2 -1
  293. package/dist/locales/ko-KR/openhands.json +2 -1
  294. package/dist/locales/no/openhands.json +2 -1
  295. package/dist/locales/pt/openhands.json +2 -1
  296. package/dist/locales/tr/openhands.json +2 -1
  297. package/dist/locales/uk/openhands.json +2 -1
  298. package/dist/locales/zh-CN/openhands.json +2 -1
  299. package/dist/locales/zh-TW/openhands.json +2 -1
  300. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.cjs +1 -1
  301. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.cjs.map +1 -1
  302. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.js +10 -1
  303. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.js.map +1 -1
  304. package/dist/package.cjs +1 -1
  305. package/dist/package.cjs.map +1 -1
  306. package/dist/package.js +2 -2
  307. package/dist/package.js.map +1 -1
  308. package/dist/routes/llm-settings.cjs +1 -1
  309. package/dist/routes/llm-settings.cjs.map +1 -1
  310. package/dist/routes/llm-settings.js +21 -21
  311. package/dist/routes/llm-settings.js.map +1 -1
  312. package/dist/routes/mcp.cjs +1 -1
  313. package/dist/routes/mcp.cjs.map +1 -1
  314. package/dist/routes/mcp.d.ts +0 -1
  315. package/dist/routes/mcp.js +0 -1
  316. package/dist/routes/mcp.js.map +1 -1
  317. package/dist/types/agent-server/core/events/index.d.ts +1 -0
  318. package/dist/types/agent-server/core/events/streaming-delta-event.d.ts +7 -0
  319. package/dist/types/agent-server/core/openhands-event.d.ts +2 -2
  320. package/dist/types/agent-server/type-guards.cjs +1 -1
  321. package/dist/types/agent-server/type-guards.cjs.map +1 -1
  322. package/dist/types/agent-server/type-guards.d.ts +2 -0
  323. package/dist/types/agent-server/type-guards.js +3 -3
  324. package/dist/types/agent-server/type-guards.js.map +1 -1
  325. package/dist/utils/handle-event-for-ui.cjs +1 -1
  326. package/dist/utils/handle-event-for-ui.cjs.map +1 -1
  327. package/dist/utils/handle-event-for-ui.js +69 -13
  328. package/dist/utils/handle-event-for-ui.js.map +1 -1
  329. package/dist/utils/mcp-config.cjs +1 -1
  330. package/dist/utils/mcp-config.cjs.map +1 -1
  331. package/dist/utils/mcp-config.js +27 -19
  332. package/dist/utils/mcp-config.js.map +1 -1
  333. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  334. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  335. package/dist/utils/mcp-marketplace-utils.js +38 -18
  336. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  337. package/dist/utils/normalize-display-model.cjs +1 -1
  338. package/dist/utils/normalize-display-model.cjs.map +1 -1
  339. package/dist/utils/normalize-display-model.js +8 -7
  340. package/dist/utils/normalize-display-model.js.map +1 -1
  341. package/dist/utils/openhands-llm.cjs +1 -1
  342. package/dist/utils/openhands-llm.cjs.map +1 -1
  343. package/dist/utils/openhands-llm.d.ts +13 -0
  344. package/dist/utils/openhands-llm.js +9 -3
  345. package/dist/utils/openhands-llm.js.map +1 -1
  346. package/package.json +2 -2
  347. package/scripts/check-sdk-version-sync.mjs +6 -6
  348. package/scripts/dev-safe.mjs +71 -120
  349. package/scripts/dev-with-automation.mjs +58 -4
  350. package/scripts/runtime-services-info.mjs +199 -0
  351. package/scripts/static-server.mjs +42 -4
  352. package/build/assets/acp-providers-DJr8DlNG.js +0 -1
  353. package/build/assets/acp-route-guard-A__sWgbc.js +0 -1
  354. package/build/assets/active-backend-context-I2w666XY.js +0 -1
  355. package/build/assets/add-backend-modal-BDBDBXsJ.js +0 -1
  356. package/build/assets/agent-server-client-options-9agOSarV.js +0 -1
  357. package/build/assets/agent-server-compatibility-B7QStIcH.js +0 -1
  358. package/build/assets/agent-server-conversation-service.api-Cagoqq1V.js +0 -5
  359. package/build/assets/api-key-entry-screen-ByXA4hXH.js +0 -1
  360. package/build/assets/automation-detail-Dbmgt974.js +0 -1
  361. package/build/assets/backend-form-modal-CeB983Sj.js +0 -1
  362. package/build/assets/browser-D08Sp3ZY.js +0 -5
  363. package/build/assets/browser-store-JRrcGdlk.js +0 -1
  364. package/build/assets/chat-send-button-5qz0zj6R.js +0 -1
  365. package/build/assets/check-CZhEL6rP.js +0 -1
  366. package/build/assets/conversation-BrjF2-Ky.js +0 -1
  367. package/build/assets/conversation-HgR_TTPE.js +0 -19
  368. package/build/assets/conversation-panel-BlRcO5AC.js +0 -1
  369. package/build/assets/conversation-service.api-B_Pdmwsa.js +0 -1
  370. package/build/assets/conversation-state-store-D-w0uurj.js +0 -1
  371. package/build/assets/conversation-store-CC-isCnP.js +0 -1
  372. package/build/assets/conversation-websocket-context-G95yfL81.js +0 -3
  373. package/build/assets/dist-Bl-1K5Tv.js +0 -1
  374. package/build/assets/edit-automation-modal-CNZgSSiH.js +0 -1
  375. package/build/assets/extensions-navigation-yFLAU06N.js +0 -1
  376. package/build/assets/files-tab-CMredyYX.js +0 -1
  377. package/build/assets/files-tab-store-DLU28g8C.js +0 -1
  378. package/build/assets/git-control-bar-branch-button-D8blTNXh.js +0 -27
  379. package/build/assets/home-CWw845Rz.js +0 -1
  380. package/build/assets/install-server-modal-D8Q0xZcN.js +0 -1
  381. package/build/assets/llm-client-BqyLKgUN.js +0 -1
  382. package/build/assets/llm-settings-CAnFYAEG.js +0 -1
  383. package/build/assets/llm-settings-DotqpmCF.js +0 -1
  384. package/build/assets/manage-backends-modal-Ceo_SOcf.js +0 -1
  385. package/build/assets/manifest-61ec2d68.js +0 -1
  386. package/build/assets/mcp-EvrLVTla.js +0 -9
  387. package/build/assets/messages-Bz9TWjlh.js +0 -36
  388. package/build/assets/middleware-CfatjPYZ.js +0 -6
  389. package/build/assets/model-selector-CZOi4V7r.js +0 -1
  390. package/build/assets/onboarding-CPCKYvFh.js +0 -1
  391. package/build/assets/organization-service.api-Dn74hBTH.js +0 -1
  392. package/build/assets/path-utils-BjxzIGLp.js +0 -1
  393. package/build/assets/plus-DT-M0FA1.js +0 -1
  394. package/build/assets/profiles-client-BrqNmaDV.js +0 -1
  395. package/build/assets/proxy-sRh0WKI7.js +0 -1
  396. package/build/assets/root-CklXEh3W.js +0 -2
  397. package/build/assets/root-layout-BCA_X8XL.js +0 -2
  398. package/build/assets/secrets-service-DVtlLWY8.js +0 -1
  399. package/build/assets/server-client-DYv_GHPl.js +0 -1
  400. package/build/assets/settings-CXvJUx_j.js +0 -1
  401. package/build/assets/settings-service.api-DxIEtvx6.js +0 -1
  402. package/build/assets/shared-conversation-x41nZQi7.js +0 -1
  403. package/build/assets/sidebar-store-DnQAJAE5.js +0 -1
  404. package/build/assets/telemetry-fQFd-8V3.js +0 -2
  405. package/build/assets/use-agent-settings-schema-Yxf7KGyG.js +0 -1
  406. package/build/assets/use-config-DwfigQ_Y.js +0 -1
  407. package/build/assets/use-create-conversation-BEzddjXn.js +0 -1
  408. package/build/assets/use-event-store-Cxqc45Sw.js +0 -1
  409. package/build/assets/use-get-secrets-BlO1BfUo.js +0 -1
  410. package/build/assets/use-handle-plan-click-Bfl0zIBr.js +0 -1
  411. package/build/assets/use-is-authed-hHndEep7.js +0 -1
  412. package/build/assets/use-llm-profiles-E-jjZMZw.js +0 -1
  413. package/build/assets/use-runtime-is-ready-DBWzvAmc.js +0 -1
  414. package/build/assets/use-settings-BPTbE7lg.js +0 -1
  415. package/build/assets/use-skills-QhoaIYGF.js +0 -1
  416. package/build/assets/use-unified-vscode-url-DFtNIC1Q.js +0 -1
  417. package/build/assets/use-user-conversation-BRAseenw.js +0 -1
  418. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-D8soyAAx.js +0 -48
  419. package/build/assets/vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~jaomi49z-Cw89stA6.js +0 -1
  420. package/build/assets/x-JOBEVLW0.js +0 -1
  421. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.cjs +0 -2
  422. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.cjs.map +0 -1
  423. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.d.ts +0 -1
  424. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.js +0 -21
  425. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.js.map +0 -1
  426. package/dist/utils/acp-route-guard.cjs +0 -1
  427. package/dist/utils/acp-route-guard.d.ts +0 -26
  428. package/dist/utils/acp-route-guard.js +0 -4
  429. /package/build/assets/{agent-server-ui-style-scope-BwIZYdC1.js → agent-server-ui-style-scope-Bhc5vpWO.js} +0 -0
  430. /package/build/assets/{automation-DJ_3GeXD.js → automation-BzmydDjr.js} +0 -0
  431. /package/build/assets/{common-DqjLSBOt.js → common-Cfviy7yT.js} +0 -0
  432. /package/build/assets/{context-CEQZwATj.js → context-BBqptpXX.js} +0 -0
  433. /package/build/assets/{conversation-local-storage-YmOVXxxW.js → conversation-local-storage-D5Tre_GA.js} +0 -0
  434. /package/build/assets/{createLucideIcon-Ddu8jDOQ.js → createLucideIcon-C9OEnwvX.js} +0 -0
  435. /package/build/assets/{environment-switch-store-CiurvTtK.js → environment-switch-store-BpKxp6Xq.js} +0 -0
  436. /package/build/assets/{git-status-mapper-DnL9OC8_.js → git-status-mapper-C3rfzUex.js} +0 -0
  437. /package/build/assets/{handle-capture-consent-3XrjZ8wi.js → handle-capture-consent-DDnXMC9Y.js} +0 -0
  438. /package/build/assets/{health-store-B5f0S2FY.js → health-store-d-d2ssv4.js} +0 -0
  439. /package/build/assets/{iconBase-BVhFI-0E.js → iconBase-1A_WRQ4E.js} +0 -0
  440. /package/build/assets/{map-provider-C3Z5Dx2J.js → map-provider-XSFHmdDs.js} +0 -0
  441. /package/build/assets/{objectWithoutPropertiesLoose-DSQKyRhw.js → objectWithoutPropertiesLoose-B-IA9dU9.js} +0 -0
  442. /package/build/assets/{query-keys-tAsQcc_9.js → query-keys-CQaji0wJ.js} +0 -0
  443. /package/build/assets/{react-Dy05vyj5.js → react-CuAHzoGi.js} +0 -0
  444. /package/build/assets/{retrieve-axios-error-message-BY-yIkIq.js → retrieve-axios-error-message-DbnSBc_1.js} +0 -0
  445. /package/build/assets/{sdk-settings-field-metadata-C6KMD-jZ.js → sdk-settings-field-metadata-CETNItbo.js} +0 -0
  446. /package/build/assets/{settings-DGY6n4J2.js → settings-BgL2HUsU.js} +0 -0
  447. /package/build/assets/{settings-like-page-layout-classes-DNg2vKSM.js → settings-like-page-layout-classes-DENKlZpD.js} +0 -0
  448. /package/build/assets/{use-breakpoint-DpxHDmuH.js → use-breakpoint-Dt2knceC.js} +0 -0
  449. /package/build/assets/{use-click-outside-element-DhxCUyWl.js → use-click-outside-element-Bu2A3s59.js} +0 -0
  450. /package/build/assets/{v4-khGvL7i2.js → v4-BygpdDmc.js} +0 -0
  451. /package/build/assets/{vendor~browser-BDNLFng6.js → vendor~browser-BYEwwJqV.js} +0 -0
  452. /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-D_hRW_zc.js → vendor~conversation-panel~conversation~alert-banner-BnHToS5O.js} +0 -0
  453. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~j8sdb9mk-OFpe9fX_.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~j8sdb9mk-oCzr0-9g.js} +0 -0
  454. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~lpdshwee-BPuuVEqr.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~lpdshwee-CTmh4bwd.js} +0 -0
  455. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~skills-settings~m~o9nrx3fm-D44TR8hL.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~skills-settings~m~o9nrx3fm-87v-LliW.js} +0 -0
  456. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Dr3Ow7Ms.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D8cqyq4k.js} +0 -0
  457. /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~i4kjfqhl-B1TKKuuH.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~ntycl9e1-DspdqGPW.js} +0 -0
  458. /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~e9ykmtgh-Fa-nXZ4M.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~e9ykmtgh-DMH1jSwL.js} +0 -0
  459. /package/build/assets/{vendor~terminal-0ObOedYm.js → vendor~terminal-aeP3PnKf.js} +0 -0
  460. /package/build/assets/{vscode-url-helper-BMq8JBhB.js → vscode-url-helper-DOCkV_-G.js} +0 -0
@@ -16,47 +16,67 @@ function r(t) {
16
16
  function i(e) {
17
17
  return t(e)?.transport;
18
18
  }
19
- function a(e) {
20
- return e.filter((e) => !!t(e));
19
+ var a = "https://mcp.linear.app/sse", o = "https://mcp.linear.app/mcp", s = "https://linear.app/docs/mcp";
20
+ function c(e) {
21
+ return e.id === "linear" ? {
22
+ ...e,
23
+ docsUrl: s,
24
+ installHint: "Authenticate with a Linear API key (Linear → Settings → Security & access) — sent as a Bearer token. Optional when the endpoint accepts your OAuth session.",
25
+ connectionOptions: e.connectionOptions.map((e) => e.transport?.kind === "sse" && d(e.transport.url, a) ? {
26
+ ...e,
27
+ auth: {
28
+ ...e.auth,
29
+ strategy: "bearer"
30
+ },
31
+ transport: {
32
+ kind: "shttp",
33
+ url: o,
34
+ apiKeyOptional: e.transport.apiKeyOptional
35
+ }
36
+ } : e)
37
+ } : e;
21
38
  }
22
- var o = (e) => {
39
+ function l(e) {
40
+ return e.map(c).filter((e) => !!t(e));
41
+ }
42
+ var u = (e) => {
23
43
  try {
24
44
  return new URL(e);
25
45
  } catch {
26
46
  return null;
27
47
  }
28
48
  };
29
- function s(e, t) {
49
+ function d(e, t) {
30
50
  let n = typeof e == "string" ? e : "", r = typeof t == "string" ? t : "";
31
51
  if (!n || !r) return !1;
32
- let i = o(n), a = o(r);
52
+ let i = u(n), a = u(r);
33
53
  return !i || !a ? n.replace(/\/+$/, "") === r.replace(/\/+$/, "") : i.protocol === a.protocol && i.host === a.host && i.pathname.replace(/\/+$/, "") === a.pathname.replace(/\/+$/, "");
34
54
  }
35
- function c(e, t) {
55
+ function f(e, t) {
36
56
  if (e.kind === "shttp") {
37
57
  let n = e.url;
38
- return t.type === "shttp" && !!t.url && s(t.url, n);
58
+ return t.type === "shttp" && !!t.url && d(t.url, n);
39
59
  }
40
60
  if (e.kind === "sse") {
41
61
  let n = e.url;
42
- return t.type === "sse" && !!t.url && s(t.url, n);
62
+ return t.type === "sse" && !!t.url && d(t.url, n);
43
63
  }
44
64
  return t.type === "stdio" && t.name === e.serverName;
45
65
  }
46
- function l(e, t) {
66
+ function p(e, t) {
47
67
  return !e.runtimeAvailability || e.runtimeAvailability === "all" ? !0 : e.runtimeAvailability === t;
48
68
  }
49
- function u(e) {
69
+ function m(e) {
50
70
  return e.trim().toLowerCase();
51
71
  }
52
- function d(e) {
72
+ function h(e) {
53
73
  return e.map((e, t) => ({
54
74
  entry: e,
55
75
  index: t
56
76
  })).sort((e, t) => (t.entry.popularityRank ?? 0) - (e.entry.popularityRank ?? 0) || e.index - t.index).map(({ entry: e }) => e);
57
77
  }
58
- function f(e, t) {
59
- let n = u(t);
78
+ function g(e, t) {
79
+ let n = m(t);
60
80
  return n ? [
61
81
  e.name,
62
82
  e.description,
@@ -64,8 +84,8 @@ function f(e, t) {
64
84
  ...e.keywords ?? []
65
85
  ].join(" ").toLowerCase().includes(n) : !0;
66
86
  }
67
- function p(e, t, n) {
68
- let r = u(n);
87
+ function _(e, t, n) {
88
+ let r = m(n);
69
89
  return r ? [
70
90
  e.type,
71
91
  "name" in e ? e.name : void 0,
@@ -78,10 +98,10 @@ function p(e, t, n) {
78
98
  ...t?.keywords ?? []
79
99
  ].filter(Boolean).join(" ").toLowerCase().includes(r) : !0;
80
100
  }
81
- function m(t, n) {
82
- return n.find((n) => e(n).some((e) => c(e.transport, t)));
101
+ function v(t, n) {
102
+ return n.find((n) => e(n).some((e) => f(e.transport, t)));
83
103
  }
84
104
  //#endregion
85
- export { m as findCatalogEntryForServer, i as getDefaultMcpTransport, r as getInstallableMcpConnectionOption, d as getMarketplaceEntriesByPopularity, a as getMcpMarketplaceCatalog, p as installedServerMatchesQuery, l as isMarketplaceEntryAvailable, f as marketplaceEntryMatchesQuery };
105
+ export { v as findCatalogEntryForServer, i as getDefaultMcpTransport, r as getInstallableMcpConnectionOption, h as getMarketplaceEntriesByPopularity, l as getMcpMarketplaceCatalog, _ as installedServerMatchesQuery, p as isMarketplaceEntryAvailable, g as marketplaceEntryMatchesQuery };
86
106
 
87
107
  //# sourceMappingURL=mcp-marketplace-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-marketplace-utils.js","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\nexport type McpMarketplaceConnectionOption = IntegrationConnectionOption & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n const options = getMcpConnectionOptions(entry);\n return (\n options.find((option) => option.id === entry.defaultConnectionOptionId) ??\n options[0]\n );\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n // The local install modal writes static MCP server config. OAuth options\n // describe hosted redirect flows, so prefer an API/stdio fallback when one\n // exists and leave OAuth as the default connection for hosted integrations.\n return option.auth.strategy !== \"oauth2\";\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n const options = getMcpConnectionOptions(entry);\n const defaultOption = options.find(\n (option) => option.id === entry.defaultConnectionOptionId,\n );\n if (defaultOption && isLocallyInstallableMcpOption(defaultOption)) {\n return defaultOption;\n }\n return options.find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter((entry) => !!getDefaultMcpConnectionOption(entry));\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nexport function isMarketplaceEntryAvailable(\n entry: MarketplaceEntry,\n backendKind: \"local\" | \"cloud\",\n): boolean {\n if (!entry.runtimeAvailability || entry.runtimeAvailability === \"all\")\n return true;\n return entry.runtimeAvailability === backendKind;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp-marketplace-utils.js","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\nexport type McpMarketplaceConnectionOption = IntegrationConnectionOption & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n const options = getMcpConnectionOptions(entry);\n return (\n options.find((option) => option.id === entry.defaultConnectionOptionId) ??\n options[0]\n );\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n // The local install modal writes static MCP server config. OAuth options\n // describe hosted redirect flows, so prefer an API/stdio fallback when one\n // exists and leave OAuth as the default connection for hosted integrations.\n return option.auth.strategy !== \"oauth2\";\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n const options = getMcpConnectionOptions(entry);\n const defaultOption = options.find(\n (option) => option.id === entry.defaultConnectionOptionId,\n );\n if (defaultOption && isLocallyInstallableMcpOption(defaultOption)) {\n return defaultOption;\n }\n return options.find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nconst LINEAR_DEPRECATED_SSE_URL = \"https://mcp.linear.app/sse\";\nconst LINEAR_SHTTP_URL = \"https://mcp.linear.app/mcp\";\nconst LINEAR_DOCS_URL = \"https://linear.app/docs/mcp\";\n\n/**\n * Upstream @openhands/extensions still ships Linear's deprecated SSE\n * transport (removed upstream on 2026-04-08; the /sse endpoint now\n * rejects every call). Rewrite the entry to streamable HTTP at the\n * /mcp replacement endpoint until the pinned dependency catches up.\n *\n * The /mcp endpoint authenticates via OAuth 2.1 or a Linear API key\n * sent as \"Authorization: Bearer <token>\". This client has no\n * interactive OAuth flow for MCP installs, so switch the auth\n * strategy from \"none\" to \"bearer\" — the install modal then offers\n * an (optional) API key field and the agent server forwards it as a\n * Bearer header.\n *\n * Patches immutably — the imported catalog JSON is shared module\n * state and must not be mutated.\n */\nfunction patchLinearEntry(entry: MarketplaceEntry): MarketplaceEntry {\n if (entry.id !== \"linear\") return entry;\n return {\n ...entry,\n docsUrl: LINEAR_DOCS_URL,\n installHint:\n \"Authenticate with a Linear API key (Linear → Settings → Security & access) — sent as a Bearer token. Optional when the endpoint accepts your OAuth session.\",\n connectionOptions: entry.connectionOptions.map((option) =>\n option.transport?.kind === \"sse\" &&\n urlsMatch(option.transport.url, LINEAR_DEPRECATED_SSE_URL)\n ? {\n ...option,\n auth: { ...option.auth, strategy: \"bearer\" as const },\n transport: {\n kind: \"shttp\" as const,\n url: LINEAR_SHTTP_URL,\n apiKeyOptional: option.transport.apiKeyOptional,\n },\n }\n : option,\n ),\n };\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map(patchLinearEntry)\n .filter((entry) => !!getDefaultMcpConnectionOption(entry));\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nexport function isMarketplaceEntryAvailable(\n entry: MarketplaceEntry,\n backendKind: \"local\" | \"cloud\",\n): boolean {\n if (!entry.runtimeAvailability || entry.runtimeAvailability === \"all\")\n return true;\n return entry.runtimeAvailability === backendKind;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- require(`../_virtual/_rolldown/runtime.cjs`);var e=new Set([`https://llm-proxy.app.all-hands.dev`,`https://llm-proxy.app.all-hands.dev/v1`]),t=`litellm_proxy/`,n=e=>e.trim().replace(/\/+$/,``);function r(r,i,a){if(!r)return``;if(!r.startsWith(t)||!i||!e.has(n(i)))return r;let o=r.slice(14);return a.includes(o)?`openhands/${o}`:r}exports.normalizeDisplayModel=r;
1
+ require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./openhands-llm.cjs`);var t=`litellm_proxy/`;function n(n,r,i){if(!n)return``;if(!n.startsWith(t)||!e.isOpenHandsProxyBaseUrl(r))return n;let a=n.slice(14);return i.includes(a)?`openhands/${a}`:n}exports.normalizeDisplayModel=n;
2
2
  //# sourceMappingURL=normalize-display-model.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalize-display-model.cjs","names":[],"sources":["../../src/utils/normalize-display-model.ts"],"sourcesContent":["const OPENHANDS_PROXY_BASE_URLS = new Set([\n \"https://llm-proxy.app.all-hands.dev\",\n \"https://llm-proxy.app.all-hands.dev/v1\",\n]);\n\nconst LITELLM_PROXY_PREFIX = \"litellm_proxy/\";\n\nconst stripTrailingSlashes = (value: string) =>\n value.trim().replace(/\\/+$/, \"\");\n\n/**\n * Reverse the SDK's `openhands/* -> litellm_proxy/*` rewrite for display.\n *\n * The agent-server's LLM validator stores curated OpenHands models as\n * `litellm_proxy/<m>` against the All-Hands proxy base URL. Without\n * normalization the GUI re-loads such settings as `litellm_proxy`, so the\n * provider dropdown silently switches off \"OpenHands\" after every save.\n */\nexport function normalizeDisplayModel(\n rawModel: string | null | undefined,\n baseUrl: string | null | undefined,\n openhandsVerifiedModels: readonly string[],\n): string {\n if (!rawModel) return \"\";\n if (!rawModel.startsWith(LITELLM_PROXY_PREFIX)) return rawModel;\n if (!baseUrl) return rawModel;\n if (!OPENHANDS_PROXY_BASE_URLS.has(stripTrailingSlashes(baseUrl))) {\n return rawModel;\n }\n const modelName = rawModel.slice(LITELLM_PROXY_PREFIX.length);\n if (!openhandsVerifiedModels.includes(modelName)) return rawModel;\n return `openhands/${modelName}`;\n}\n"],"mappings":"6CAAA,IAAM,EAA4B,IAAI,IAAI,CACxC,sCACA,yCACD,CAAC,CAEI,EAAuB,iBAEvB,EAAwB,GAC5B,EAAM,MAAM,CAAC,QAAQ,OAAQ,GAAG,CAUlC,SAAgB,EACd,EACA,EACA,EACQ,CACR,GAAI,CAAC,EAAU,MAAO,GAGtB,GAFI,CAAC,EAAS,WAAW,EAAqB,EAC1C,CAAC,GACD,CAAC,EAA0B,IAAI,EAAqB,EAAQ,CAAC,CAC/D,OAAO,EAET,IAAM,EAAY,EAAS,MAAM,GAA4B,CAE7D,OADK,EAAwB,SAAS,EAAU,CACzC,aAAa,IADqC"}
1
+ {"version":3,"file":"normalize-display-model.cjs","names":[],"sources":["../../src/utils/normalize-display-model.ts"],"sourcesContent":["import { isOpenHandsProxyBaseUrl } from \"#/utils/openhands-llm\";\n\nconst LITELLM_PROXY_PREFIX = \"litellm_proxy/\";\n\n/**\n * Reverse the SDK's `openhands/* -> litellm_proxy/*` rewrite for display.\n *\n * The agent-server's LLM validator stores curated OpenHands models as\n * `litellm_proxy/<m>` against the All-Hands proxy base URL. Without\n * normalization the GUI re-loads such settings as `litellm_proxy`, so the\n * provider dropdown silently switches off \"OpenHands\" after every save.\n */\nexport function normalizeDisplayModel(\n rawModel: string | null | undefined,\n baseUrl: string | null | undefined,\n openhandsVerifiedModels: readonly string[],\n): string {\n if (!rawModel) return \"\";\n if (!rawModel.startsWith(LITELLM_PROXY_PREFIX)) return rawModel;\n if (!isOpenHandsProxyBaseUrl(baseUrl)) return rawModel;\n const modelName = rawModel.slice(LITELLM_PROXY_PREFIX.length);\n if (!openhandsVerifiedModels.includes(modelName)) return rawModel;\n return `openhands/${modelName}`;\n}\n"],"mappings":"oFAEA,IAAM,EAAuB,iBAU7B,SAAgB,EACd,EACA,EACA,EACQ,CACR,GAAI,CAAC,EAAU,MAAO,GAEtB,GADI,CAAC,EAAS,WAAW,EAAqB,EAC1C,CAAC,EAAA,wBAAwB,EAAQ,CAAE,OAAO,EAC9C,IAAM,EAAY,EAAS,MAAM,GAA4B,CAE7D,OADK,EAAwB,SAAS,EAAU,CACzC,aAAa,IADqC"}
@@ -1,12 +1,13 @@
1
+ import { isOpenHandsProxyBaseUrl as e } from "./openhands-llm.js";
1
2
  //#region src/utils/normalize-display-model.ts
2
- var e = new Set(["https://llm-proxy.app.all-hands.dev", "https://llm-proxy.app.all-hands.dev/v1"]), t = "litellm_proxy/", n = (e) => e.trim().replace(/\/+$/, "");
3
- function r(r, i, a) {
4
- if (!r) return "";
5
- if (!r.startsWith(t) || !i || !e.has(n(i))) return r;
6
- let o = r.slice(14);
7
- return a.includes(o) ? `openhands/${o}` : r;
3
+ var t = "litellm_proxy/";
4
+ function n(n, r, i) {
5
+ if (!n) return "";
6
+ if (!n.startsWith(t) || !e(r)) return n;
7
+ let a = n.slice(14);
8
+ return i.includes(a) ? `openhands/${a}` : n;
8
9
  }
9
10
  //#endregion
10
- export { r as normalizeDisplayModel };
11
+ export { n as normalizeDisplayModel };
11
12
 
12
13
  //# sourceMappingURL=normalize-display-model.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalize-display-model.js","names":[],"sources":["../../src/utils/normalize-display-model.ts"],"sourcesContent":["const OPENHANDS_PROXY_BASE_URLS = new Set([\n \"https://llm-proxy.app.all-hands.dev\",\n \"https://llm-proxy.app.all-hands.dev/v1\",\n]);\n\nconst LITELLM_PROXY_PREFIX = \"litellm_proxy/\";\n\nconst stripTrailingSlashes = (value: string) =>\n value.trim().replace(/\\/+$/, \"\");\n\n/**\n * Reverse the SDK's `openhands/* -> litellm_proxy/*` rewrite for display.\n *\n * The agent-server's LLM validator stores curated OpenHands models as\n * `litellm_proxy/<m>` against the All-Hands proxy base URL. Without\n * normalization the GUI re-loads such settings as `litellm_proxy`, so the\n * provider dropdown silently switches off \"OpenHands\" after every save.\n */\nexport function normalizeDisplayModel(\n rawModel: string | null | undefined,\n baseUrl: string | null | undefined,\n openhandsVerifiedModels: readonly string[],\n): string {\n if (!rawModel) return \"\";\n if (!rawModel.startsWith(LITELLM_PROXY_PREFIX)) return rawModel;\n if (!baseUrl) return rawModel;\n if (!OPENHANDS_PROXY_BASE_URLS.has(stripTrailingSlashes(baseUrl))) {\n return rawModel;\n }\n const modelName = rawModel.slice(LITELLM_PROXY_PREFIX.length);\n if (!openhandsVerifiedModels.includes(modelName)) return rawModel;\n return `openhands/${modelName}`;\n}\n"],"mappings":";AAAA,IAAM,IAA4B,IAAI,IAAI,CACxC,uCACA,yCACD,CAAC,EAEI,IAAuB,kBAEvB,KAAwB,MAC5B,EAAM,MAAM,CAAC,QAAQ,QAAQ,GAAG;AAUlC,SAAgB,EACd,GACA,GACA,GACQ;AACR,KAAI,CAAC,EAAU,QAAO;AAGtB,KAFI,CAAC,EAAS,WAAW,EAAqB,IAC1C,CAAC,KACD,CAAC,EAA0B,IAAI,EAAqB,EAAQ,CAAC,CAC/D,QAAO;CAET,IAAM,IAAY,EAAS,MAAM,GAA4B;AAE7D,QADK,EAAwB,SAAS,EAAU,GACzC,aAAa,MADqC"}
1
+ {"version":3,"file":"normalize-display-model.js","names":[],"sources":["../../src/utils/normalize-display-model.ts"],"sourcesContent":["import { isOpenHandsProxyBaseUrl } from \"#/utils/openhands-llm\";\n\nconst LITELLM_PROXY_PREFIX = \"litellm_proxy/\";\n\n/**\n * Reverse the SDK's `openhands/* -> litellm_proxy/*` rewrite for display.\n *\n * The agent-server's LLM validator stores curated OpenHands models as\n * `litellm_proxy/<m>` against the All-Hands proxy base URL. Without\n * normalization the GUI re-loads such settings as `litellm_proxy`, so the\n * provider dropdown silently switches off \"OpenHands\" after every save.\n */\nexport function normalizeDisplayModel(\n rawModel: string | null | undefined,\n baseUrl: string | null | undefined,\n openhandsVerifiedModels: readonly string[],\n): string {\n if (!rawModel) return \"\";\n if (!rawModel.startsWith(LITELLM_PROXY_PREFIX)) return rawModel;\n if (!isOpenHandsProxyBaseUrl(baseUrl)) return rawModel;\n const modelName = rawModel.slice(LITELLM_PROXY_PREFIX.length);\n if (!openhandsVerifiedModels.includes(modelName)) return rawModel;\n return `openhands/${modelName}`;\n}\n"],"mappings":";;AAEA,IAAM,IAAuB;AAU7B,SAAgB,EACd,GACA,GACA,GACQ;AACR,KAAI,CAAC,EAAU,QAAO;AAEtB,KADI,CAAC,EAAS,WAAW,EAAqB,IAC1C,CAAC,EAAwB,EAAQ,CAAE,QAAO;CAC9C,IAAM,IAAY,EAAS,MAAM,GAA4B;AAE7D,QADK,EAAwB,SAAS,EAAU,GACzC,aAAa,MADqC"}
@@ -1,2 +1,2 @@
1
- require(`../_virtual/_rolldown/runtime.cjs`);var e=`https://llm-proxy.app.all-hands.dev/`;function t(e){return typeof e==`string`&&e.startsWith(`openhands/`)}exports.OPENHANDS_LLM_PROXY_BASE_URL=e,exports.isOpenHandsProviderModel=t;
1
+ require(`../_virtual/_rolldown/runtime.cjs`);var e=`https://llm-proxy.app.all-hands.dev/`,t=new Set([`https://llm-proxy.app.all-hands.dev`,`https://llm-proxy.app.all-hands.dev/v1`]),n=`litellm_proxy/`;function r(e){return typeof e==`string`&&e.startsWith(`openhands/`)}function i(e){return typeof e==`string`&&t.has(e.trim().replace(/\/+$/,``))}function a(e,t){return r(e)?!0:typeof e==`string`&&e.startsWith(n)&&i(t)}exports.OPENHANDS_LLM_PROXY_BASE_URL=e,exports.isOpenHandsProxyBaseUrl=i,exports.isOpenHandsProxyModel=a;
2
2
  //# sourceMappingURL=openhands-llm.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"openhands-llm.cjs","names":[],"sources":["../../src/utils/openhands-llm.ts"],"sourcesContent":["export const OPENHANDS_LLM_PROXY_BASE_URL =\n \"https://llm-proxy.app.all-hands.dev/\";\n\nexport function isOpenHandsProviderModel(model: unknown): model is string {\n return typeof model === \"string\" && model.startsWith(\"openhands/\");\n}\n"],"mappings":"6CAAA,IAAa,EACX,uCAEF,SAAgB,EAAyB,EAAiC,CACxE,OAAO,OAAO,GAAU,UAAY,EAAM,WAAW,aAAa"}
1
+ {"version":3,"file":"openhands-llm.cjs","names":[],"sources":["../../src/utils/openhands-llm.ts"],"sourcesContent":["export const OPENHANDS_LLM_PROXY_BASE_URL =\n \"https://llm-proxy.app.all-hands.dev/\";\n\n// Accepted spellings of the All-Hands LiteLLM proxy base URL, normalized\n// without a trailing slash. The agent-server stores curated OpenHands models\n// against one of these once its validator rewrites `openhands/*` to\n// `litellm_proxy/*`.\nconst OPENHANDS_LLM_PROXY_BASE_URLS = new Set([\n \"https://llm-proxy.app.all-hands.dev\",\n \"https://llm-proxy.app.all-hands.dev/v1\",\n]);\n\nconst LITELLM_PROXY_PREFIX = \"litellm_proxy/\";\n\nexport function isOpenHandsProviderModel(model: unknown): model is string {\n return typeof model === \"string\" && model.startsWith(\"openhands/\");\n}\n\n/**\n * True when `baseUrl` points at the All-Hands LiteLLM proxy, ignoring any\n * trailing slash.\n */\nexport function isOpenHandsProxyBaseUrl(baseUrl: unknown): baseUrl is string {\n return (\n typeof baseUrl === \"string\" &&\n OPENHANDS_LLM_PROXY_BASE_URLS.has(baseUrl.trim().replace(/\\/+$/, \"\"))\n );\n}\n\n/**\n * True for any OpenHands-backed model: the `openhands/*` id the GUI submits, or\n * the `litellm_proxy/*` id the SDK rewrites it to once it is paired with the\n * OpenHands proxy base URL. Both forms must keep the proxy `base_url` on save —\n * dropping it strips the api_base and silently reroutes the request to the\n * default OpenAI endpoint, leaving an unusable profile (issue #1146).\n */\nexport function isOpenHandsProxyModel(\n model: unknown,\n baseUrl: unknown,\n): model is string {\n if (isOpenHandsProviderModel(model)) return true;\n return (\n typeof model === \"string\" &&\n model.startsWith(LITELLM_PROXY_PREFIX) &&\n isOpenHandsProxyBaseUrl(baseUrl)\n );\n}\n"],"mappings":"6CAAA,IAAa,EACX,uCAMI,EAAgC,IAAI,IAAI,CAC5C,sCACA,yCACD,CAAC,CAEI,EAAuB,iBAE7B,SAAgB,EAAyB,EAAiC,CACxE,OAAO,OAAO,GAAU,UAAY,EAAM,WAAW,aAAa,CAOpE,SAAgB,EAAwB,EAAqC,CAC3E,OACE,OAAO,GAAY,UACnB,EAA8B,IAAI,EAAQ,MAAM,CAAC,QAAQ,OAAQ,GAAG,CAAC,CAWzE,SAAgB,EACd,EACA,EACiB,CAEjB,OADI,EAAyB,EAAM,CAAS,GAE1C,OAAO,GAAU,UACjB,EAAM,WAAW,EAAqB,EACtC,EAAwB,EAAQ"}
@@ -1,2 +1,15 @@
1
1
  export declare const OPENHANDS_LLM_PROXY_BASE_URL = "https://llm-proxy.app.all-hands.dev/";
2
2
  export declare function isOpenHandsProviderModel(model: unknown): model is string;
3
+ /**
4
+ * True when `baseUrl` points at the All-Hands LiteLLM proxy, ignoring any
5
+ * trailing slash.
6
+ */
7
+ export declare function isOpenHandsProxyBaseUrl(baseUrl: unknown): baseUrl is string;
8
+ /**
9
+ * True for any OpenHands-backed model: the `openhands/*` id the GUI submits, or
10
+ * the `litellm_proxy/*` id the SDK rewrites it to once it is paired with the
11
+ * OpenHands proxy base URL. Both forms must keep the proxy `base_url` on save —
12
+ * dropping it strips the api_base and silently reroutes the request to the
13
+ * default OpenAI endpoint, leaving an unusable profile (issue #1146).
14
+ */
15
+ export declare function isOpenHandsProxyModel(model: unknown, baseUrl: unknown): model is string;
@@ -1,9 +1,15 @@
1
1
  //#region src/utils/openhands-llm.ts
2
- var e = "https://llm-proxy.app.all-hands.dev/";
3
- function t(e) {
2
+ var e = "https://llm-proxy.app.all-hands.dev/", t = new Set(["https://llm-proxy.app.all-hands.dev", "https://llm-proxy.app.all-hands.dev/v1"]), n = "litellm_proxy/";
3
+ function r(e) {
4
4
  return typeof e == "string" && e.startsWith("openhands/");
5
5
  }
6
+ function i(e) {
7
+ return typeof e == "string" && t.has(e.trim().replace(/\/+$/, ""));
8
+ }
9
+ function a(e, t) {
10
+ return r(e) ? !0 : typeof e == "string" && e.startsWith(n) && i(t);
11
+ }
6
12
  //#endregion
7
- export { e as OPENHANDS_LLM_PROXY_BASE_URL, t as isOpenHandsProviderModel };
13
+ export { e as OPENHANDS_LLM_PROXY_BASE_URL, i as isOpenHandsProxyBaseUrl, a as isOpenHandsProxyModel };
8
14
 
9
15
  //# sourceMappingURL=openhands-llm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openhands-llm.js","names":[],"sources":["../../src/utils/openhands-llm.ts"],"sourcesContent":["export const OPENHANDS_LLM_PROXY_BASE_URL =\n \"https://llm-proxy.app.all-hands.dev/\";\n\nexport function isOpenHandsProviderModel(model: unknown): model is string {\n return typeof model === \"string\" && model.startsWith(\"openhands/\");\n}\n"],"mappings":";AAAA,IAAa,IACX;AAEF,SAAgB,EAAyB,GAAiC;AACxE,QAAO,OAAO,KAAU,YAAY,EAAM,WAAW,aAAa"}
1
+ {"version":3,"file":"openhands-llm.js","names":[],"sources":["../../src/utils/openhands-llm.ts"],"sourcesContent":["export const OPENHANDS_LLM_PROXY_BASE_URL =\n \"https://llm-proxy.app.all-hands.dev/\";\n\n// Accepted spellings of the All-Hands LiteLLM proxy base URL, normalized\n// without a trailing slash. The agent-server stores curated OpenHands models\n// against one of these once its validator rewrites `openhands/*` to\n// `litellm_proxy/*`.\nconst OPENHANDS_LLM_PROXY_BASE_URLS = new Set([\n \"https://llm-proxy.app.all-hands.dev\",\n \"https://llm-proxy.app.all-hands.dev/v1\",\n]);\n\nconst LITELLM_PROXY_PREFIX = \"litellm_proxy/\";\n\nexport function isOpenHandsProviderModel(model: unknown): model is string {\n return typeof model === \"string\" && model.startsWith(\"openhands/\");\n}\n\n/**\n * True when `baseUrl` points at the All-Hands LiteLLM proxy, ignoring any\n * trailing slash.\n */\nexport function isOpenHandsProxyBaseUrl(baseUrl: unknown): baseUrl is string {\n return (\n typeof baseUrl === \"string\" &&\n OPENHANDS_LLM_PROXY_BASE_URLS.has(baseUrl.trim().replace(/\\/+$/, \"\"))\n );\n}\n\n/**\n * True for any OpenHands-backed model: the `openhands/*` id the GUI submits, or\n * the `litellm_proxy/*` id the SDK rewrites it to once it is paired with the\n * OpenHands proxy base URL. Both forms must keep the proxy `base_url` on save —\n * dropping it strips the api_base and silently reroutes the request to the\n * default OpenAI endpoint, leaving an unusable profile (issue #1146).\n */\nexport function isOpenHandsProxyModel(\n model: unknown,\n baseUrl: unknown,\n): model is string {\n if (isOpenHandsProviderModel(model)) return true;\n return (\n typeof model === \"string\" &&\n model.startsWith(LITELLM_PROXY_PREFIX) &&\n isOpenHandsProxyBaseUrl(baseUrl)\n );\n}\n"],"mappings":";AAAA,IAAa,IACX,wCAMI,IAAgC,IAAI,IAAI,CAC5C,uCACA,yCACD,CAAC,EAEI,IAAuB;AAE7B,SAAgB,EAAyB,GAAiC;AACxE,QAAO,OAAO,KAAU,YAAY,EAAM,WAAW,aAAa;;AAOpE,SAAgB,EAAwB,GAAqC;AAC3E,QACE,OAAO,KAAY,YACnB,EAA8B,IAAI,EAAQ,MAAM,CAAC,QAAQ,QAAQ,GAAG,CAAC;;AAWzE,SAAgB,EACd,GACA,GACiB;AAEjB,QADI,EAAyB,EAAM,GAAS,KAE1C,OAAO,KAAU,YACjB,EAAM,WAAW,EAAqB,IACtC,EAAwB,EAAQ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openhands/agent-canvas",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.3",
4
4
  "description": "Agent Canvas UI for OpenHands - run AI coding agents with a visual interface",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -23,7 +23,7 @@
23
23
  "@heroui/react": "2.8.10",
24
24
  "@microlink/react-json-view": "1.31.20",
25
25
  "@monaco-editor/react": "4.7.0",
26
- "@openhands/extensions": "git+https://github.com/OpenHands/extensions.git#62594156a187722344736bc2ff5edfb12c0cc75c",
26
+ "@openhands/extensions": "github:OpenHands/extensions#8a6690071e0e9229ae70b30ff0352aff9e6fca21",
27
27
  "@openhands/typescript-client": "1.24.3",
28
28
  "@react-router/node": "7.14.2",
29
29
  "@react-router/serve": "7.14.2",
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * Usage:
21
21
  * node scripts/check-sdk-version-sync.mjs
22
- * EXPECTED_SDK_VERSION=1.24.0 node scripts/check-sdk-version-sync.mjs
22
+ * EXPECTED_SDK_VERSION=1.25.0 node scripts/check-sdk-version-sync.mjs
23
23
  * node scripts/check-sdk-version-sync.mjs --check-pypi
24
24
  *
25
25
  * Environment variables:
@@ -79,7 +79,7 @@ Triggering from other repos:
79
79
  -H "Authorization: token \$GITHUB_TOKEN" \\
80
80
  -H "Accept: application/vnd.github.v3+json" \\
81
81
  https://api.github.com/repos/OpenHands/agent-canvas/dispatches \\
82
- -d '{"event_type": "sdk-version-check", "client_payload": {"version": "1.24.0"}}'
82
+ -d '{"event_type": "sdk-version-check", "client_payload": {"version": "1.25.0"}}'
83
83
  `);
84
84
  process.exit(0);
85
85
  }
@@ -268,9 +268,9 @@ async function fetchPyPIDependencies(packageName, version) {
268
268
  * Parse PyPI requires_dist array and extract SDK package versions
269
269
  *
270
270
  * PyPI returns dependencies in PEP 508 format like:
271
- * "openhands-sdk>=1.24.0,<2.0.0"
272
- * "openhands-tools==1.24.0"
273
- * "openhands-workspace (>=1.24.0)"
271
+ * "openhands-sdk>=1.25.0,<2.0.0"
272
+ * "openhands-tools==1.25.0"
273
+ * "openhands-workspace (>=1.25.0)"
274
274
  */
275
275
  function parseSdkVersionsFromRequiresDist(requiresDist) {
276
276
  const versions = {};
@@ -284,7 +284,7 @@ function parseSdkVersionsFromRequiresDist(requiresDist) {
284
284
  }
285
285
 
286
286
  // Extract the version number - look for patterns like:
287
- // ">=1.24.0", "==1.24.0", "(>=1.24.0)", "~=1.24.0"
287
+ // ">=1.25.0", "==1.25.0", "(>=1.25.0)", "~=1.25.0"
288
288
  // After the package name and before any comma or closing paren
289
289
  const versionPattern = /[><=~!]+\s*([0-9]+(?:\.[0-9]+)*)/;
290
290
  const match = dep.match(versionPattern);
@@ -10,7 +10,7 @@ import {
10
10
  writeFileSync,
11
11
  } from "node:fs";
12
12
  import net from "node:net";
13
- import { homedir, tmpdir } from "node:os";
13
+ import { homedir } from "node:os";
14
14
  import path from "node:path";
15
15
  import process from "node:process";
16
16
  import { setTimeout as delay } from "node:timers/promises";
@@ -21,6 +21,10 @@ import {
21
21
  isProcessRunning,
22
22
  signalProcessTree,
23
23
  } from "./dev-process-utils.mjs";
24
+ // buildRuntimeServicesInfo moved to its own dependency-free module so the
25
+ // Docker entrypoint can run it as a CLI. Re-exported below for back-compat
26
+ // (dev-with-automation.mjs and tests still import it from here).
27
+ import { buildRuntimeServicesInfo } from "./runtime-services-info.mjs";
24
28
 
25
29
  // ── Centralized config (single source of truth for versions, ports, etc.) ───
26
30
  const __dev_safe_dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -31,6 +35,32 @@ const SHARED_DEFAULTS = JSON.parse(
31
35
  ),
32
36
  );
33
37
 
38
+ /**
39
+ * Extract the pinned commit SHA for @openhands/extensions from package.json.
40
+ * Returns the 40-char hex SHA when the dependency is a git+https URL with a
41
+ * commit hash fragment (e.g. "git+https://…#62594156…"), null otherwise.
42
+ * @returns {string | null}
43
+ */
44
+ function getExtensionsRef() {
45
+ try {
46
+ const pkg = JSON.parse(
47
+ readFileSync(
48
+ path.join(__dev_safe_dirname, "..", "package.json"),
49
+ "utf-8",
50
+ ),
51
+ );
52
+ const url =
53
+ (pkg.dependencies ?? pkg.devDependencies ?? {})["@openhands/extensions"] ??
54
+ "";
55
+ return url.match(/#([0-9a-f]{40})$/i)?.[1] ?? null;
56
+ } catch {
57
+ return null;
58
+ }
59
+ }
60
+
61
+ /** Pinned extensions commit SHA derived from package.json, or null if not pinned. */
62
+ export const DEFAULT_EXTENSIONS_REF = getExtensionsRef();
63
+
34
64
  const DEFAULT_BACKEND_PORT = SHARED_DEFAULTS.ports.agentServer;
35
65
  const DEFAULT_VITE_PORT = 3001;
36
66
  const DEFAULT_WAIT_TIMEOUT_MS = 30_000;
@@ -389,7 +419,7 @@ export function validateFrontendDependencies(
389
419
  * edits are picked up without a manual reinstall. The agent-server itself
390
420
  * is rebuilt from local source on each invocation (--reinstall).
391
421
  * - OH_AGENT_SERVER_GIT_REF: Git commit SHA or branch name
392
- * - OH_AGENT_SERVER_VERSION: Specific PyPI version (e.g., "1.24.0")
422
+ * - OH_AGENT_SERVER_VERSION: Specific PyPI version (e.g., "1.25.0")
393
423
  *
394
424
  * If none are set, defaults to the released version specified by
395
425
  * DEFAULT_AGENT_SERVER_VERSION. Set OH_AGENT_SERVER_GIT_REF to use a
@@ -426,14 +456,23 @@ export function buildAgentServerCommand(env = process.env) {
426
456
  );
427
457
  source = `local (${localPath})`;
428
458
  } else if (gitRef) {
429
- // Use git ref with subdirectory syntax for uv workspace monorepo
459
+ // Use git ref with subdirectory syntax for uv workspace monorepo.
430
460
  // The software-agent-sdk repo has packages in subdirectories:
431
- // openhands-agent-server/, openhands-tools/, openhands-workspace/
461
+ // openhands-agent-server/, openhands-sdk/, openhands-tools/, openhands-workspace/
462
+ // All four must come from the same ref so inter-package APIs stay in sync.
463
+ //
464
+ // --reinstall is required because the git branch may carry the same version
465
+ // string as the current PyPI release (e.g. both "1.25.0"). Without it, uv
466
+ // silently reuses the cached PyPI wheels and the git ref is never actually
467
+ // used, even though it was explicitly requested.
432
468
  const baseGitUrl = `git+${AGENT_SERVER_GIT_REPO}@${gitRef}`;
433
469
  uvxArgs.push(
470
+ "--reinstall",
434
471
  "--from",
435
472
  `${baseGitUrl}#subdirectory=openhands-agent-server`,
436
473
  "--with",
474
+ `${baseGitUrl}#subdirectory=openhands-sdk`,
475
+ "--with",
437
476
  `${baseGitUrl}#subdirectory=openhands-tools`,
438
477
  "--with",
439
478
  `${baseGitUrl}#subdirectory=openhands-workspace`,
@@ -622,7 +661,23 @@ function buildConfigFromPorts(ports, cwd, env) {
622
661
  backendPort,
623
662
  vscodePort,
624
663
  stateDir,
625
- tmuxTmpDir: path.join(tmpdir(), "openhands-agent-canvas-tmux"),
664
+ // tmux socket directory. Defaults to <stateDir>/tmux (under
665
+ // ~/.openhands/agent-canvas), matching where the rest of dev state lives
666
+ // and persisting across restarts.
667
+ //
668
+ // Do NOT use os.tmpdir() here: on macOS it resolves to the per-user
669
+ // $TMPDIR (/var/folders/.../T), which the OS periodically reaps
670
+ // (com.apple.bsd.dirhelper deletes entries untouched for a few days).
671
+ // Reaping deletes the live tmux socket while the server process keeps
672
+ // running, orphaning it — every later new-window then fails with
673
+ // "error connecting to .../openhands (No such file or directory)".
674
+ //
675
+ // The only hosts where <stateDir>/tmux can't hold the socket are those
676
+ // whose $HOME is a network/overlay mount without Unix-domain-socket
677
+ // support (some devcontainers, NFS/CIFS homes). Those rare cases can point
678
+ // tmux at a local, socket-capable path with the standard TMUX_TMPDIR env
679
+ // var (e.g. TMUX_TMPDIR=/tmp), which we honor and pass through below.
680
+ tmuxTmpDir: env.TMUX_TMPDIR || path.join(stateDir, "tmux"),
626
681
  conversationsPath,
627
682
  workspacesPath,
628
683
  bashEventsDir: path.join(stateDir, "bash_events"),
@@ -681,124 +736,20 @@ export function buildAgentServerEnv(config) {
681
736
  // Make the host tools/ directory importable so the agent-server can
682
737
  // resolve modules listed in tool_module_qualnames (e.g. canvas_ui_tool).
683
738
  OH_EXTRA_PYTHON_PATH: config.canvasToolsDir,
739
+ // Tell the agent-server which extensions commit to use for the public
740
+ // skills catalog. Derived from the @openhands/extensions pin in
741
+ // package.json; the SDK skips network polling when it already has this
742
+ // SHA cached. Only injected when the caller has not already set it.
743
+ ...(DEFAULT_EXTENSIONS_REF && !process.env.EXTENSIONS_REF
744
+ ? { EXTENSIONS_REF: DEFAULT_EXTENSIONS_REF }
745
+ : {}),
684
746
  };
685
747
  }
686
748
 
687
- /**
688
- * Build a structured description of the dev-stack services that are
689
- * reachable from inside the agent's sandbox. The frontend forwards this
690
- * (verbatim, as a JSON string in `VITE_RUNTIME_SERVICES_INFO`) and renders
691
- * it into the system prompt via `AgentContext.system_message_suffix`, so
692
- * the agent sees a `<RUNTIME_SERVICES>` block listing what's available
693
- * without having to probe.
694
- *
695
- * URLs are written from the *agent's* point of view. The agent-server
696
- * runs on the host, so the host alias is "localhost".
697
- *
698
- * @param {object} options
699
- * @param {string} [options.mode] - Human-readable dev mode label (e.g. "dev:safe").
700
- * @param {string} [options.agentHostAlias="localhost"] - Hostname the agent
701
- * uses to reach services running on the host machine.
702
- * @param {number} [options.agentServerPort] - Port the agent-server listens on.
703
- * Required at runtime; the function throws if missing because the resulting
704
- * URL would otherwise bake `undefined` into the agent's system prompt.
705
- * Typed as optional only so TypeScript callers can negative-test the guard.
706
- * @param {number} [options.ingressPort] - Ingress port (omit if no ingress).
707
- * @param {number} [options.frontendPort] - Frontend port (Vite dev server
708
- * or static-file server). Omit if no frontend is exposed.
709
- * @param {number} [options.vitePort] - Deprecated alias for `frontendPort`,
710
- * accepted for backward compat with older launchers. Remove after one release.
711
- * @param {"vite"|"static"} [options.frontendKind="vite"] - Whether the
712
- * frontend port hosts Vite or a static build. Only affects the
713
- * description shown to the agent.
714
- * @param {object} [options.automation] - Automation backend info. Skipped
715
- * entirely if `.port` is missing, so passing `{}` is safe.
716
- * @param {number} [options.automation.port] - Automation backend port.
717
- * @param {string} [options.automation.apiPrefix="/api/automation"] - Path
718
- * prefix all automation routes are mounted under.
719
- * @param {string} [options.automation.authEnvVar="OPENHANDS_AUTOMATION_API_KEY"]
720
- * - Env var holding the API key.
721
- * @returns {object} A JSON-serializable runtime services info object.
722
- */
723
- export function buildRuntimeServicesInfo(options) {
724
- const {
725
- mode,
726
- agentHostAlias = "localhost",
727
- agentServerPort,
728
- ingressPort,
729
- // Accept legacy `vitePort` for one release so external callers keep working.
730
- vitePort,
731
- frontendPort = vitePort,
732
- frontendKind = "vite",
733
- automation,
734
- } = options;
735
-
736
- if (agentServerPort === undefined || agentServerPort === null) {
737
- // Without this the URL becomes `http://localhost:undefined` and ends up
738
- // verbatim in the agent's system prompt, which is worse than failing fast.
739
- throw new Error(
740
- "buildRuntimeServicesInfo: agentServerPort is required " +
741
- "(otherwise the agent_server URL would be `http://localhost:undefined`).",
742
- );
743
- }
744
-
745
- const services = {
746
- agent_server: {
747
- description:
748
- "The OpenHands Agent Server this agent is running inside. " +
749
- "Tool calls (terminal, file_editor, browser, etc.) execute here.",
750
- // From the agent's POV, the agent-server it's *inside* is on
751
- // localhost, regardless of where the host is.
752
- url_from_agent: `http://localhost:${agentServerPort}`,
753
- },
754
- };
755
-
756
- if (ingressPort !== undefined) {
757
- services.ingress = {
758
- description:
759
- "Unified entry point. Routes /api/automation/* to the automation " +
760
- "backend, /api/* and /sockets to the agent-server, and /* to the " +
761
- "frontend.",
762
- url_from_agent: `http://${agentHostAlias}:${ingressPort}`,
763
- };
764
- }
765
-
766
- if (frontendPort !== undefined) {
767
- services.frontend = {
768
- kind: frontendKind,
769
- description:
770
- frontendKind === "static"
771
- ? "Static-file server hosting the agent-canvas production build."
772
- : "Vite dev server hosting the agent-canvas frontend.",
773
- url_from_agent: `http://${agentHostAlias}:${frontendPort}`,
774
- };
775
- }
776
-
777
- // Require an explicit port so we don't bake `:undefined` into the
778
- // automation URL when the caller passes `automation: {}`.
779
- if (automation?.port !== undefined && automation.port !== null) {
780
- const apiPrefix = automation.apiPrefix ?? "/api/automation";
781
- const authEnvVar = automation.authEnvVar ?? "OPENHANDS_AUTOMATION_API_KEY";
782
- const baseUrl = `http://${agentHostAlias}:${automation.port}`;
783
- services.automation = {
784
- description:
785
- "OpenHands Automations service. All routes are mounted under " +
786
- `'${apiPrefix}'. Authenticate with header ` +
787
- `'X-Session-API-Key: $${authEnvVar}'.`,
788
- url_from_agent: baseUrl,
789
- api_prefix: apiPrefix,
790
- docs_url: `${baseUrl}${apiPrefix}/docs`,
791
- openapi_url: `${baseUrl}${apiPrefix}/openapi.json`,
792
- auth_env_var: authEnvVar,
793
- };
794
- }
795
-
796
- return {
797
- mode,
798
- agent_host_alias: agentHostAlias,
799
- services,
800
- };
801
- }
749
+ // Re-export so existing importers (dev-with-automation.mjs, tests) keep
750
+ // resolving `buildRuntimeServicesInfo` from this module. The implementation
751
+ // now lives in ./runtime-services-info.mjs (imported at the top of this file).
752
+ export { buildRuntimeServicesInfo };
802
753
 
803
754
  export function buildNpmScriptCommand(
804
755
  scriptName,