openclaw-multi-auto 1.3.7 → 1.3.9

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 (414) hide show
  1. package/dist/{accounts-L9ByEpnP.js → accounts-C9HcPI9h.js} +2 -2
  2. package/dist/{accounts-BOzyfwW4.js → accounts-C_lW3Ag9.js} +2 -2
  3. package/dist/{accounts-yfBeCZtS.js → accounts-Tgelvk0C.js} +17 -17
  4. package/dist/{active-listener-D1yqT1cw.js → active-listener-BEdprTkn.js} +2 -2
  5. package/dist/{api-key-rotation-DtsNS2Nb.js → api-key-rotation-BJpKWXy0.js} +2 -2
  6. package/dist/{audio-preflight-DpxQCpsA.js → audio-preflight-BMvgEQ5j.js} +32 -32
  7. package/dist/{audio-transcription-runner-28fcRNNi.js → audio-transcription-runner-gLFfz8fr.js} +12 -12
  8. package/dist/{audit-membership-runtime-DWyHWAHM.js → audit-membership-runtime-Dntemq07.js} +4 -4
  9. package/dist/build-info.json +3 -3
  10. package/dist/bundled/boot-md/handler.js +51 -51
  11. package/dist/bundled/bootstrap-extra-files/handler.js +6 -6
  12. package/dist/bundled/command-logger/handler.js +2 -2
  13. package/dist/bundled/session-memory/handler.js +51 -51
  14. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  15. package/dist/{channel-activity-xHOMiarp.js → channel-activity-BDnjYF7B.js} +3 -3
  16. package/dist/{chrome-DwizpzOC.js → chrome-DxxEKrY7.js} +18 -18
  17. package/dist/{commands-registry-V1zZ5pPC.js → commands-registry-D5qXbFJn.js} +4 -4
  18. package/dist/control-ui/apple-touch-icon.png +0 -0
  19. package/dist/control-ui/assets/de-Bm0iuKxz.js +2 -0
  20. package/dist/control-ui/assets/de-Bm0iuKxz.js.map +1 -0
  21. package/dist/control-ui/assets/index-7XbUBC_m.js +8380 -0
  22. package/dist/control-ui/assets/index-7XbUBC_m.js.map +1 -0
  23. package/dist/control-ui/assets/index-E0j6Tkrc.css +1 -0
  24. package/dist/control-ui/assets/pt-BR-C2uaHesk.js +2 -0
  25. package/dist/control-ui/assets/pt-BR-C2uaHesk.js.map +1 -0
  26. package/dist/control-ui/assets/zh-CN-CqPGpAps.js +2 -0
  27. package/dist/control-ui/assets/zh-CN-CqPGpAps.js.map +1 -0
  28. package/dist/control-ui/assets/zh-TW-Cyl5GDQh.js +2 -0
  29. package/dist/control-ui/assets/zh-TW-Cyl5GDQh.js.map +1 -0
  30. package/dist/control-ui/favicon-32.png +0 -0
  31. package/dist/control-ui/favicon.ico +0 -0
  32. package/dist/control-ui/favicon.svg +22 -0
  33. package/dist/control-ui/index.html +17 -0
  34. package/dist/{deliver-D4o6VIur.js → deliver-DbdywYJE.js} +21 -21
  35. package/dist/deliver-runtime-BFs7iAZF.js +36 -0
  36. package/dist/deps-send-discord.runtime-DZUccI6Z.js +26 -0
  37. package/dist/deps-send-imessage.runtime-CF3OpoqY.js +25 -0
  38. package/dist/deps-send-signal.runtime-Cw4-ozeO.js +24 -0
  39. package/dist/deps-send-slack.runtime-BDsDhS1P.js +22 -0
  40. package/dist/deps-send-telegram.runtime-D_4xVasO.js +27 -0
  41. package/dist/deps-send-whatsapp.runtime-DK8jqd14.js +60 -0
  42. package/dist/{diagnostic-Bn4PZjMZ.js → diagnostic-Co6Kghr-.js} +2 -2
  43. package/dist/{errors-CCLeFWAg.js → errors-xt401nuk.js} +1 -1
  44. package/dist/{fetch-BlJWzEP6.js → fetch-DuraYswo.js} +5 -5
  45. package/dist/{fetch-guard-ChYBwfiy.js → fetch-guard-DWr0d00H.js} +2 -2
  46. package/dist/{frontmatter-CvaMP376.js → frontmatter-BkTfEZ93.js} +3 -3
  47. package/dist/{fs-safe-0jAo_Whb.js → fs-safe-CTYUrIgQ.js} +4 -4
  48. package/dist/{github-copilot-token-D13V9YBz.js → github-copilot-token-BDioPmd6.js} +7 -7
  49. package/dist/{image-Bbn53mzj.js → image-eT7Y-nP5.js} +6 -6
  50. package/dist/{image-ops-CehkHxmW.js → image-ops-BuUnEOE0.js} +2 -2
  51. package/dist/image-runtime-BcAK3n8a.js +29 -0
  52. package/dist/{ir-DAP-B-Xw.js → ir-B83looB-.js} +8 -8
  53. package/dist/{legacy-names-TyzbVqa_.js → legacy-names-DOC03BkU.js} +1 -1
  54. package/dist/llm-slug-generator.js +51 -51
  55. package/dist/{logger-DMZQQtxK.js → logger-BfjWMCSD.js} +7 -7
  56. package/dist/{login-DiCctRo1.js → login-CrIwcrVI.js} +5 -5
  57. package/dist/{login-qr-MUbXgjtd.js → login-qr-BpPDZdl_.js} +10 -10
  58. package/dist/{manager-BW_NSIMl.js → manager-1bvuGrNR.js} +13 -13
  59. package/dist/manager-runtime-FO1Sx3W8.js +18 -0
  60. package/dist/{model-selection-idoqPmw0.js → model-selection-Dna0Gz1k.js} +43 -43
  61. package/dist/{outbound-C2kanETZ.js → outbound-ChDjtuD6.js} +6 -6
  62. package/dist/{outbound-attachment-DBrYWX8h.js → outbound-attachment-DqHlD21U.js} +2 -2
  63. package/dist/{path-alias-guards-DqXRZmsL.js → path-alias-guards-BzvdLvTI.js} +1 -1
  64. package/dist/{paths-CCxysrzL.js → paths-Bkr-BCxW.js} +4 -4
  65. package/dist/{paths-C6TxBCvO.js → paths-Cvc9EM8Y.js} +5 -5
  66. package/dist/{pi-embedded-BaGj07T0.js → pi-embedded-BQQa91aA.js} +158 -158
  67. package/dist/{pi-embedded-helpers-wy0DZvx1.js → pi-embedded-helpers-CLXm10bV.js} +52 -52
  68. package/dist/{plugin-sdk/pi-model-discovery-v-XPUOOf.js → pi-model-discovery-Dymwdjt0.js} +2 -2
  69. package/dist/pi-model-discovery-runtime-BeY4EUPp.js +11 -0
  70. package/dist/{pi-tools.before-tool-call.runtime-BuLxSyx9.js → pi-tools.before-tool-call.runtime-Cwab_5W1.js} +9 -9
  71. package/dist/plugin-sdk/index.js +50 -50
  72. package/dist/plugin-sdk/mattermost.js +3 -3
  73. package/dist/plugin-sdk/signal.js +2 -2
  74. package/dist/plugin-sdk/zalo.js +2 -2
  75. package/dist/{plugins-CWkRQYDj.js → plugins-4Rj4OjLY.js} +11 -11
  76. package/dist/{proxy-env-Cq5gdrbj.js → proxy-env-DlmzDx8x.js} +1 -1
  77. package/dist/{proxy-fetch-CCjEYbFm.js → proxy-fetch-B2pEfjbR.js} +1 -1
  78. package/dist/{pw-ai-Cl1Lc7RC.js → pw-ai-DNMjFMqH.js} +14 -14
  79. package/dist/{qmd-manager-BsYsO9Ii.js → qmd-manager-BtIKUaO9.js} +10 -10
  80. package/dist/{query-expansion-DtLc3wjL.js → query-expansion-CX-1fS52.js} +6 -6
  81. package/dist/{plugin-sdk/redact-DjVX-1N3.js → redact-COik8ET1.js} +1 -1
  82. package/dist/{run-with-concurrency-D_ZpbgEG.js → run-with-concurrency-BgYfgkXT.js} +4 -4
  83. package/dist/runtime-whatsapp-login.runtime-DUb55byQ.js +13 -0
  84. package/dist/runtime-whatsapp-outbound.runtime-Bii_xSfI.js +22 -0
  85. package/dist/{send-Dx2RkUOZ.js → send-6lz6rNVP.js} +6 -6
  86. package/dist/{send-vmONuVgL.js → send-BHTiZcH3.js} +26 -26
  87. package/dist/{send-Bj776ESJ.js → send-L7gRiwyd.js} +7 -7
  88. package/dist/{send-DcxmcFi_.js → send-PE6cwoTe.js} +8 -8
  89. package/dist/{send-BQERFNyo.js → send-dfu6_rgf.js} +5 -5
  90. package/dist/{session-A4QhBRvH.js → session-D8ImowSs.js} +8 -8
  91. package/dist/{skill-commands-CMzBZKG2.js → skill-commands-DNqJ-kwn.js} +9 -9
  92. package/dist/{skills-CE_iqvM5.js → skills-7ODkHQYp.js} +22 -22
  93. package/dist/slash-commands.runtime-CVw6566g.js +16 -0
  94. package/dist/slash-dispatch.runtime-B9Ygtzi4.js +56 -0
  95. package/dist/slash-skill-commands.runtime-DxZ4z5h6.js +20 -0
  96. package/dist/{store--eR1R_UX.js → store-D89wDcz9.js} +2 -2
  97. package/dist/subagent-registry-runtime-DL1Wv7nA.js +56 -0
  98. package/dist/{subsystem-Di1z8l0Z.js → subsystem-B45WV3qB.js} +14 -14
  99. package/dist/{tables-d739Y1xW.js → tables-mE4cJBN2.js} +1 -1
  100. package/dist/{plugin-sdk/target-errors-Blia4S69.js → target-errors-mnlwhAjP.js} +2 -2
  101. package/dist/{thinking-DXYisHiZ.js → thinking-BeGmb5k6.js} +7 -7
  102. package/dist/{tokens-DxnY9ui_.js → tokens-q32vI39c.js} +1 -1
  103. package/dist/{tool-images-2cBx1W8h.js → tool-images-RZdHiZcG.js} +2 -2
  104. package/dist/{web-CzWRVmFt.js → web-Btj-e8kN.js} +55 -55
  105. package/dist/{whatsapp-actions-iEArE_Ez.js → whatsapp-actions-BHbJJyqw.js} +21 -21
  106. package/dist/{workspace-CUVC6GX1.js → workspace-U-DyR64O.js} +20 -20
  107. package/package.json +7 -5
  108. package/scripts/create-instance.sh +66 -27
  109. package/scripts/install-maca.sh +1 -1
  110. package/scripts/npm_publish.sh +5 -1
  111. package/ui/index.html +16 -0
  112. package/ui/node_modules/.bin/jiti +21 -0
  113. package/ui/node_modules/.bin/lessc +21 -0
  114. package/ui/node_modules/.bin/marked +21 -0
  115. package/ui/node_modules/.bin/playwright +21 -0
  116. package/ui/node_modules/.bin/sass +21 -0
  117. package/ui/node_modules/.bin/tsx +21 -0
  118. package/ui/node_modules/.bin/vite +21 -0
  119. package/ui/node_modules/.bin/vitest +21 -0
  120. package/ui/node_modules/.bin/yaml +21 -0
  121. package/ui/package.json +27 -0
  122. package/ui/public/apple-touch-icon.png +0 -0
  123. package/ui/public/favicon-32.png +0 -0
  124. package/ui/public/favicon.ico +0 -0
  125. package/ui/public/favicon.svg +22 -0
  126. package/ui/src/css.d.ts +1 -0
  127. package/ui/src/i18n/index.ts +3 -0
  128. package/ui/src/i18n/lib/lit-controller.ts +22 -0
  129. package/ui/src/i18n/lib/registry.ts +64 -0
  130. package/ui/src/i18n/lib/translate.ts +123 -0
  131. package/ui/src/i18n/lib/types.ts +9 -0
  132. package/ui/src/i18n/locales/de.ts +129 -0
  133. package/ui/src/i18n/locales/en.ts +337 -0
  134. package/ui/src/i18n/locales/pt-BR.ts +128 -0
  135. package/ui/src/i18n/locales/zh-CN.ts +330 -0
  136. package/ui/src/i18n/locales/zh-TW.ts +125 -0
  137. package/ui/src/i18n/test/translate.test.ts +56 -0
  138. package/ui/src/main.ts +2 -0
  139. package/ui/src/styles/base.css +385 -0
  140. package/ui/src/styles/chat/grouped.css +300 -0
  141. package/ui/src/styles/chat/layout.css +481 -0
  142. package/ui/src/styles/chat/sidebar.css +117 -0
  143. package/ui/src/styles/chat/text.css +146 -0
  144. package/ui/src/styles/chat/tool-cards.css +202 -0
  145. package/ui/src/styles/chat.css +5 -0
  146. package/ui/src/styles/components.css +2612 -0
  147. package/ui/src/styles/config.css +1658 -0
  148. package/ui/src/styles/layout.css +621 -0
  149. package/ui/src/styles/layout.mobile.css +374 -0
  150. package/ui/src/styles.css +5 -0
  151. package/ui/src/ui/__screenshots__/config-form.browser.test.ts/config-form-renderer-flags-unsupported-unions-1.png +0 -0
  152. package/ui/src/ui/__screenshots__/config-form.browser.test.ts/config-form-renderer-renders-inputs-and-patches-values-1.png +0 -0
  153. package/ui/src/ui/__screenshots__/config-form.browser.test.ts/config-form-renderer-renders-union-literals-as-select-options-1.png +0 -0
  154. package/ui/src/ui/__screenshots__/navigation.browser.test.ts/control-UI-routing-auto-scrolls-chat-history-to-the-latest-message-1.png +0 -0
  155. package/ui/src/ui/app-channels.ts +279 -0
  156. package/ui/src/ui/app-chat.ts +266 -0
  157. package/ui/src/ui/app-defaults.ts +50 -0
  158. package/ui/src/ui/app-events.ts +5 -0
  159. package/ui/src/ui/app-gateway.node.test.ts +229 -0
  160. package/ui/src/ui/app-gateway.ts +349 -0
  161. package/ui/src/ui/app-lifecycle.node.test.ts +44 -0
  162. package/ui/src/ui/app-lifecycle.ts +109 -0
  163. package/ui/src/ui/app-polling.ts +69 -0
  164. package/ui/src/ui/app-render-usage-tab.ts +273 -0
  165. package/ui/src/ui/app-render.helpers.node.test.ts +286 -0
  166. package/ui/src/ui/app-render.helpers.ts +574 -0
  167. package/ui/src/ui/app-render.ts +1168 -0
  168. package/ui/src/ui/app-scroll.test.ts +275 -0
  169. package/ui/src/ui/app-scroll.ts +179 -0
  170. package/ui/src/ui/app-settings.test.ts +70 -0
  171. package/ui/src/ui/app-settings.ts +440 -0
  172. package/ui/src/ui/app-tool-stream.node.test.ts +139 -0
  173. package/ui/src/ui/app-tool-stream.ts +455 -0
  174. package/ui/src/ui/app-view-state.ts +321 -0
  175. package/ui/src/ui/app.ts +621 -0
  176. package/ui/src/ui/assistant-identity.ts +23 -0
  177. package/ui/src/ui/chat/constants.ts +12 -0
  178. package/ui/src/ui/chat/copy-as-markdown.ts +97 -0
  179. package/ui/src/ui/chat/grouped-render.ts +287 -0
  180. package/ui/src/ui/chat/message-extract.test.ts +64 -0
  181. package/ui/src/ui/chat/message-extract.ts +122 -0
  182. package/ui/src/ui/chat/message-normalizer.test.ts +179 -0
  183. package/ui/src/ui/chat/message-normalizer.ts +101 -0
  184. package/ui/src/ui/chat/tool-cards.ts +156 -0
  185. package/ui/src/ui/chat/tool-helpers.test.ts +141 -0
  186. package/ui/src/ui/chat/tool-helpers.ts +37 -0
  187. package/ui/src/ui/chat-event-reload.test.ts +47 -0
  188. package/ui/src/ui/chat-event-reload.ts +16 -0
  189. package/ui/src/ui/chat-markdown.browser.test.ts +37 -0
  190. package/ui/src/ui/components/resizable-divider.ts +110 -0
  191. package/ui/src/ui/config-form.browser.test.ts +443 -0
  192. package/ui/src/ui/controllers/agent-files.ts +126 -0
  193. package/ui/src/ui/controllers/agent-identity.ts +59 -0
  194. package/ui/src/ui/controllers/agent-skills.ts +33 -0
  195. package/ui/src/ui/controllers/agents.test.ts +61 -0
  196. package/ui/src/ui/controllers/agents.ts +64 -0
  197. package/ui/src/ui/controllers/assistant-identity.ts +34 -0
  198. package/ui/src/ui/controllers/channels.ts +94 -0
  199. package/ui/src/ui/controllers/channels.types.ts +15 -0
  200. package/ui/src/ui/controllers/chat.test.ts +568 -0
  201. package/ui/src/ui/controllers/chat.ts +318 -0
  202. package/ui/src/ui/controllers/config/form-coerce.ts +160 -0
  203. package/ui/src/ui/controllers/config/form-utils.node.test.ts +455 -0
  204. package/ui/src/ui/controllers/config/form-utils.ts +90 -0
  205. package/ui/src/ui/controllers/config.test.ts +289 -0
  206. package/ui/src/ui/controllers/config.ts +219 -0
  207. package/ui/src/ui/controllers/control-ui-bootstrap.test.ts +82 -0
  208. package/ui/src/ui/controllers/control-ui-bootstrap.ts +49 -0
  209. package/ui/src/ui/controllers/cron-filters.test.ts +81 -0
  210. package/ui/src/ui/controllers/cron.test.ts +1070 -0
  211. package/ui/src/ui/controllers/cron.ts +921 -0
  212. package/ui/src/ui/controllers/debug.ts +60 -0
  213. package/ui/src/ui/controllers/devices.ts +159 -0
  214. package/ui/src/ui/controllers/exec-approval.ts +100 -0
  215. package/ui/src/ui/controllers/exec-approvals.ts +170 -0
  216. package/ui/src/ui/controllers/logs.ts +147 -0
  217. package/ui/src/ui/controllers/nodes.ts +32 -0
  218. package/ui/src/ui/controllers/presence.ts +37 -0
  219. package/ui/src/ui/controllers/sessions.test.ts +104 -0
  220. package/ui/src/ui/controllers/sessions.ts +127 -0
  221. package/ui/src/ui/controllers/skills.ts +157 -0
  222. package/ui/src/ui/controllers/usage.node.test.ts +181 -0
  223. package/ui/src/ui/controllers/usage.ts +315 -0
  224. package/ui/src/ui/data/moonshot-kimi-k2.ts +45 -0
  225. package/ui/src/ui/device-auth.ts +73 -0
  226. package/ui/src/ui/device-identity.ts +112 -0
  227. package/ui/src/ui/external-link.test.ts +18 -0
  228. package/ui/src/ui/external-link.ts +19 -0
  229. package/ui/src/ui/focus-mode.browser.test.ts +39 -0
  230. package/ui/src/ui/format.test.ts +101 -0
  231. package/ui/src/ui/format.ts +60 -0
  232. package/ui/src/ui/gateway.ts +360 -0
  233. package/ui/src/ui/icons.ts +256 -0
  234. package/ui/src/ui/markdown.test.ts +85 -0
  235. package/ui/src/ui/markdown.ts +139 -0
  236. package/ui/src/ui/navigation.browser.test.ts +188 -0
  237. package/ui/src/ui/navigation.test.ts +189 -0
  238. package/ui/src/ui/navigation.ts +165 -0
  239. package/ui/src/ui/open-external-url.test.ts +108 -0
  240. package/ui/src/ui/open-external-url.ts +73 -0
  241. package/ui/src/ui/presenter.ts +85 -0
  242. package/ui/src/ui/storage.node.test.ts +63 -0
  243. package/ui/src/ui/storage.ts +99 -0
  244. package/ui/src/ui/test-helpers/app-mount.ts +27 -0
  245. package/ui/src/ui/text-direction.test.ts +24 -0
  246. package/ui/src/ui/text-direction.ts +30 -0
  247. package/ui/src/ui/theme-transition.ts +109 -0
  248. package/ui/src/ui/theme.ts +16 -0
  249. package/ui/src/ui/tool-display.ts +159 -0
  250. package/ui/src/ui/types/chat-types.ts +44 -0
  251. package/ui/src/ui/types.ts +627 -0
  252. package/ui/src/ui/ui-types.ts +54 -0
  253. package/ui/src/ui/usage-helpers.node.test.ts +43 -0
  254. package/ui/src/ui/usage-helpers.ts +321 -0
  255. package/ui/src/ui/usage-types.ts +22 -0
  256. package/ui/src/ui/uuid.test.ts +41 -0
  257. package/ui/src/ui/uuid.ts +57 -0
  258. package/ui/src/ui/views/agents-panels-status-files.ts +461 -0
  259. package/ui/src/ui/views/agents-panels-tools-skills.browser.test.ts +102 -0
  260. package/ui/src/ui/views/agents-panels-tools-skills.ts +537 -0
  261. package/ui/src/ui/views/agents-utils.test.ts +100 -0
  262. package/ui/src/ui/views/agents-utils.ts +502 -0
  263. package/ui/src/ui/views/agents.ts +499 -0
  264. package/ui/src/ui/views/channel-config-extras.ts +49 -0
  265. package/ui/src/ui/views/channels.config.ts +155 -0
  266. package/ui/src/ui/views/channels.discord.ts +65 -0
  267. package/ui/src/ui/views/channels.googlechat.ts +79 -0
  268. package/ui/src/ui/views/channels.imessage.ts +65 -0
  269. package/ui/src/ui/views/channels.nostr-profile-form.ts +321 -0
  270. package/ui/src/ui/views/channels.nostr.ts +237 -0
  271. package/ui/src/ui/views/channels.shared.ts +38 -0
  272. package/ui/src/ui/views/channels.signal.ts +69 -0
  273. package/ui/src/ui/views/channels.slack.ts +65 -0
  274. package/ui/src/ui/views/channels.telegram.ts +120 -0
  275. package/ui/src/ui/views/channels.ts +325 -0
  276. package/ui/src/ui/views/channels.types.ts +62 -0
  277. package/ui/src/ui/views/channels.whatsapp.ts +118 -0
  278. package/ui/src/ui/views/chat-image-open.browser.test.ts +70 -0
  279. package/ui/src/ui/views/chat.test.ts +227 -0
  280. package/ui/src/ui/views/chat.ts +616 -0
  281. package/ui/src/ui/views/config-form.analyze.ts +267 -0
  282. package/ui/src/ui/views/config-form.node.ts +1073 -0
  283. package/ui/src/ui/views/config-form.render.ts +478 -0
  284. package/ui/src/ui/views/config-form.search.node.test.ts +69 -0
  285. package/ui/src/ui/views/config-form.shared.ts +96 -0
  286. package/ui/src/ui/views/config-form.ts +4 -0
  287. package/ui/src/ui/views/config-search.node.test.ts +50 -0
  288. package/ui/src/ui/views/config-search.ts +92 -0
  289. package/ui/src/ui/views/config.browser.test.ts +233 -0
  290. package/ui/src/ui/views/config.ts +820 -0
  291. package/ui/src/ui/views/cron.test.ts +741 -0
  292. package/ui/src/ui/views/cron.ts +1758 -0
  293. package/ui/src/ui/views/debug.ts +151 -0
  294. package/ui/src/ui/views/exec-approval.ts +89 -0
  295. package/ui/src/ui/views/gateway-url-confirmation.ts +40 -0
  296. package/ui/src/ui/views/instances.ts +89 -0
  297. package/ui/src/ui/views/logs.ts +155 -0
  298. package/ui/src/ui/views/markdown-sidebar.ts +40 -0
  299. package/ui/src/ui/views/nodes-exec-approvals.ts +617 -0
  300. package/ui/src/ui/views/nodes-shared.ts +67 -0
  301. package/ui/src/ui/views/nodes.ts +485 -0
  302. package/ui/src/ui/views/overview-hints.ts +16 -0
  303. package/ui/src/ui/views/overview.node.test.ts +39 -0
  304. package/ui/src/ui/views/overview.ts +361 -0
  305. package/ui/src/ui/views/sessions.test.ts +81 -0
  306. package/ui/src/ui/views/sessions.ts +321 -0
  307. package/ui/src/ui/views/skills-grouping.ts +40 -0
  308. package/ui/src/ui/views/skills-shared.ts +52 -0
  309. package/ui/src/ui/views/skills.ts +192 -0
  310. package/ui/src/ui/views/usage-metrics.ts +578 -0
  311. package/ui/src/ui/views/usage-query.ts +277 -0
  312. package/ui/src/ui/views/usage-render-details.test.ts +136 -0
  313. package/ui/src/ui/views/usage-render-details.ts +1083 -0
  314. package/ui/src/ui/views/usage-render-overview.ts +796 -0
  315. package/ui/src/ui/views/usage-styles/usageStyles-part1.ts +701 -0
  316. package/ui/src/ui/views/usage-styles/usageStyles-part2.ts +702 -0
  317. package/ui/src/ui/views/usage-styles/usageStyles-part3.ts +551 -0
  318. package/ui/src/ui/views/usage.ts +836 -0
  319. package/ui/src/ui/views/usageStyles.ts +5 -0
  320. package/ui/src/ui/views/usageTypes.ts +105 -0
  321. package/ui/vite.config.ts +43 -0
  322. package/ui/vitest.config.ts +15 -0
  323. package/ui/vitest.node.config.ts +10 -0
  324. package/dist/deliver-runtime-P-G3bPjW.js +0 -36
  325. package/dist/deps-send-discord.runtime-DnbhTFX9.js +0 -26
  326. package/dist/deps-send-imessage.runtime-BOiQ6mDx.js +0 -25
  327. package/dist/deps-send-signal.runtime-CTcl388M.js +0 -24
  328. package/dist/deps-send-slack.runtime-CCqBz4Kg.js +0 -22
  329. package/dist/deps-send-telegram.runtime-DGSKTCpH.js +0 -27
  330. package/dist/deps-send-whatsapp.runtime-CJkTHkah.js +0 -60
  331. package/dist/image-runtime-CVv2ra9J.js +0 -29
  332. package/dist/manager-runtime-BN6VevdC.js +0 -18
  333. package/dist/pi-model-discovery-BGgOlX8N.js +0 -134
  334. package/dist/pi-model-discovery-runtime-Bwmi4Ev8.js +0 -11
  335. package/dist/plugin-sdk/accounts-CJWOBzwB.js +0 -35
  336. package/dist/plugin-sdk/accounts-DP1-L-QS.js +0 -288
  337. package/dist/plugin-sdk/accounts-DZhWlEg3.js +0 -46
  338. package/dist/plugin-sdk/active-listener-B_sLJTXM.js +0 -50
  339. package/dist/plugin-sdk/api-key-rotation-BRE4X2tf.js +0 -181
  340. package/dist/plugin-sdk/audio-preflight-DGEUDxxR.js +0 -69
  341. package/dist/plugin-sdk/audio-transcription-runner-DkoPNPYt.js +0 -2176
  342. package/dist/plugin-sdk/audit-membership-runtime-DSBHHw7o.js +0 -58
  343. package/dist/plugin-sdk/channel-activity-F3d0yUwy.js +0 -94
  344. package/dist/plugin-sdk/channel-web-QF7EpjeP.js +0 -2256
  345. package/dist/plugin-sdk/chrome-BXoCyCkY.js +0 -2415
  346. package/dist/plugin-sdk/commands-registry-t7cXBTfN.js +0 -1125
  347. package/dist/plugin-sdk/config-BkEnz2Po.js +0 -17913
  348. package/dist/plugin-sdk/deliver-B6AG_l67.js +0 -1694
  349. package/dist/plugin-sdk/deliver-runtime-D585kJZc.js +0 -32
  350. package/dist/plugin-sdk/deps-send-discord.runtime-a_OKY2js.js +0 -23
  351. package/dist/plugin-sdk/deps-send-imessage.runtime-Baxy9TD4.js +0 -22
  352. package/dist/plugin-sdk/deps-send-signal.runtime-BwXoCrFl.js +0 -21
  353. package/dist/plugin-sdk/deps-send-slack.runtime-CLmKjgso.js +0 -19
  354. package/dist/plugin-sdk/deps-send-telegram.runtime-BKfdBKnZ.js +0 -24
  355. package/dist/plugin-sdk/deps-send-whatsapp.runtime-BOTwkbx_.js +0 -57
  356. package/dist/plugin-sdk/diagnostic-CsP-lEkI.js +0 -319
  357. package/dist/plugin-sdk/errors-DaiAM-yU.js +0 -54
  358. package/dist/plugin-sdk/fetch-guard-DETCcJzQ.js +0 -156
  359. package/dist/plugin-sdk/fs-safe-B8y811FR.js +0 -352
  360. package/dist/plugin-sdk/image-DjTEkYZE.js +0 -2310
  361. package/dist/plugin-sdk/image-ops-BSiMpAw4.js +0 -584
  362. package/dist/plugin-sdk/image-runtime-6xPp8m5a.js +0 -25
  363. package/dist/plugin-sdk/ir-DQ7_HbvK.js +0 -1296
  364. package/dist/plugin-sdk/local-roots-BUP4YBmR.js +0 -186
  365. package/dist/plugin-sdk/logger-CZY9KIoY.js +0 -1163
  366. package/dist/plugin-sdk/login-BxEKLlCo.js +0 -57
  367. package/dist/plugin-sdk/login-qr-BQIpMPr9.js +0 -320
  368. package/dist/plugin-sdk/manager-I6KbPihW.js +0 -3917
  369. package/dist/plugin-sdk/manager-runtime-CFfYYWIQ.js +0 -15
  370. package/dist/plugin-sdk/outbound-NS6UHnB6.js +0 -212
  371. package/dist/plugin-sdk/outbound-attachment-Dy6fyf6H.js +0 -19
  372. package/dist/plugin-sdk/path-alias-guards-DBjLbIX_.js +0 -43
  373. package/dist/plugin-sdk/paths-vTM3Lh3X.js +0 -166
  374. package/dist/plugin-sdk/pi-embedded-helpers-1R1gu7eX.js +0 -9627
  375. package/dist/plugin-sdk/pi-model-discovery-runtime-Do9o-dUd.js +0 -8
  376. package/dist/plugin-sdk/pi-tools.before-tool-call.runtime-D4sFsIks.js +0 -354
  377. package/dist/plugin-sdk/plugins-DeBZB9l_.js +0 -864
  378. package/dist/plugin-sdk/proxy-fetch-ChxOhWF4.js +0 -38
  379. package/dist/plugin-sdk/pw-ai-DEOmCSSC.js +0 -1938
  380. package/dist/plugin-sdk/qmd-manager-HyYKoEch.js +0 -1448
  381. package/dist/plugin-sdk/query-expansion-CeyKUeDW.js +0 -1011
  382. package/dist/plugin-sdk/reply-DAo_Jt8K.js +0 -97916
  383. package/dist/plugin-sdk/resolve-outbound-target-B42qgQS9.js +0 -40
  384. package/dist/plugin-sdk/run-with-concurrency-Bt_ks0Qa.js +0 -1994
  385. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-B6W989eF.js +0 -10
  386. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-c_GDFy37.js +0 -19
  387. package/dist/plugin-sdk/send-CQpMudwO.js +0 -2587
  388. package/dist/plugin-sdk/send-DQHLzVyO.js +0 -414
  389. package/dist/plugin-sdk/send-DTB24bEF.js +0 -3135
  390. package/dist/plugin-sdk/send-DfHadjZ_.js +0 -503
  391. package/dist/plugin-sdk/send-XXlW2iny.js +0 -540
  392. package/dist/plugin-sdk/session-6TF6MyaC.js +0 -169
  393. package/dist/plugin-sdk/skill-commands-CkGeFUMl.js +0 -342
  394. package/dist/plugin-sdk/skills-CBkHBYPq.js +0 -1428
  395. package/dist/plugin-sdk/slash-commands.runtime-CxliuGaP.js +0 -13
  396. package/dist/plugin-sdk/slash-dispatch.runtime-DFaeYlJQ.js +0 -52
  397. package/dist/plugin-sdk/slash-skill-commands.runtime-0M0OLCxq.js +0 -16
  398. package/dist/plugin-sdk/ssrf-cFtplYtS.js +0 -202
  399. package/dist/plugin-sdk/store-5nyxY3WU.js +0 -81
  400. package/dist/plugin-sdk/subagent-registry-runtime-DCtmDwna.js +0 -52
  401. package/dist/plugin-sdk/tables-C47P4GTN.js +0 -55
  402. package/dist/plugin-sdk/thinking-Bo2eosVa.js +0 -1206
  403. package/dist/plugin-sdk/tokens-DgNRBwIg.js +0 -52
  404. package/dist/plugin-sdk/tool-images-Gk_-0y2N.js +0 -274
  405. package/dist/plugin-sdk/web-CVxZbXyH.js +0 -56
  406. package/dist/plugin-sdk/whatsapp-actions-Bw0H9g-n.js +0 -80
  407. package/dist/redact-ClbcYG1J.js +0 -319
  408. package/dist/runtime-whatsapp-login.runtime-IeylZEl4.js +0 -13
  409. package/dist/runtime-whatsapp-outbound.runtime-ClBRuLsq.js +0 -22
  410. package/dist/slash-commands.runtime-Cpn2tYW4.js +0 -16
  411. package/dist/slash-dispatch.runtime-DoBAQBU5.js +0 -56
  412. package/dist/slash-skill-commands.runtime-DKMvvdDW.js +0 -20
  413. package/dist/subagent-registry-runtime-ppWS3tVu.js +0 -56
  414. package/dist/target-errors-CBI2Ga0y.js +0 -195
@@ -0,0 +1,440 @@
1
+ import { refreshChat } from "./app-chat.ts";
2
+ import {
3
+ startLogsPolling,
4
+ stopLogsPolling,
5
+ startDebugPolling,
6
+ stopDebugPolling,
7
+ } from "./app-polling.ts";
8
+ import { scheduleChatScroll, scheduleLogsScroll } from "./app-scroll.ts";
9
+ import type { OpenClawApp } from "./app.ts";
10
+ import { loadAgentIdentities, loadAgentIdentity } from "./controllers/agent-identity.ts";
11
+ import { loadAgentSkills } from "./controllers/agent-skills.ts";
12
+ import { loadAgents, loadToolsCatalog } from "./controllers/agents.ts";
13
+ import { loadChannels } from "./controllers/channels.ts";
14
+ import { loadConfig, loadConfigSchema } from "./controllers/config.ts";
15
+ import {
16
+ loadCronJobs,
17
+ loadCronModelSuggestions,
18
+ loadCronRuns,
19
+ loadCronStatus,
20
+ } from "./controllers/cron.ts";
21
+ import { loadDebug } from "./controllers/debug.ts";
22
+ import { loadDevices } from "./controllers/devices.ts";
23
+ import { loadExecApprovals } from "./controllers/exec-approvals.ts";
24
+ import { loadLogs } from "./controllers/logs.ts";
25
+ import { loadNodes } from "./controllers/nodes.ts";
26
+ import { loadPresence } from "./controllers/presence.ts";
27
+ import { loadSessions } from "./controllers/sessions.ts";
28
+ import { loadSkills } from "./controllers/skills.ts";
29
+ import {
30
+ inferBasePathFromPathname,
31
+ normalizeBasePath,
32
+ normalizePath,
33
+ pathForTab,
34
+ tabFromPath,
35
+ type Tab,
36
+ } from "./navigation.ts";
37
+ import { saveSettings, type UiSettings } from "./storage.ts";
38
+ import { startThemeTransition, type ThemeTransitionContext } from "./theme-transition.ts";
39
+ import { resolveTheme, type ResolvedTheme, type ThemeMode } from "./theme.ts";
40
+ import type { AgentsListResult } from "./types.ts";
41
+
42
+ type SettingsHost = {
43
+ settings: UiSettings;
44
+ password?: string;
45
+ theme: ThemeMode;
46
+ themeResolved: ResolvedTheme;
47
+ applySessionKey: string;
48
+ sessionKey: string;
49
+ tab: Tab;
50
+ connected: boolean;
51
+ chatHasAutoScrolled: boolean;
52
+ logsAtBottom: boolean;
53
+ eventLog: unknown[];
54
+ eventLogBuffer: unknown[];
55
+ basePath: string;
56
+ agentsList?: AgentsListResult | null;
57
+ agentsSelectedId?: string | null;
58
+ agentsPanel?: "overview" | "files" | "tools" | "skills" | "channels" | "cron";
59
+ themeMedia: MediaQueryList | null;
60
+ themeMediaHandler: ((event: MediaQueryListEvent) => void) | null;
61
+ pendingGatewayUrl?: string | null;
62
+ };
63
+
64
+ export function applySettings(host: SettingsHost, next: UiSettings) {
65
+ const normalized = {
66
+ ...next,
67
+ lastActiveSessionKey: next.lastActiveSessionKey?.trim() || next.sessionKey.trim() || "main",
68
+ };
69
+ host.settings = normalized;
70
+ saveSettings(normalized);
71
+ if (next.theme !== host.theme) {
72
+ host.theme = next.theme;
73
+ applyResolvedTheme(host, resolveTheme(next.theme));
74
+ }
75
+ host.applySessionKey = host.settings.lastActiveSessionKey;
76
+ }
77
+
78
+ export function setLastActiveSessionKey(host: SettingsHost, next: string) {
79
+ const trimmed = next.trim();
80
+ if (!trimmed) {
81
+ return;
82
+ }
83
+ if (host.settings.lastActiveSessionKey === trimmed) {
84
+ return;
85
+ }
86
+ applySettings(host, { ...host.settings, lastActiveSessionKey: trimmed });
87
+ }
88
+
89
+ export function applySettingsFromUrl(host: SettingsHost) {
90
+ if (!window.location.search && !window.location.hash) {
91
+ return;
92
+ }
93
+ const url = new URL(window.location.href);
94
+ const params = new URLSearchParams(url.search);
95
+ const hashParams = new URLSearchParams(url.hash.startsWith("#") ? url.hash.slice(1) : url.hash);
96
+
97
+ const tokenRaw = params.get("token") ?? hashParams.get("token");
98
+ const passwordRaw = params.get("password") ?? hashParams.get("password");
99
+ const sessionRaw = params.get("session") ?? hashParams.get("session");
100
+ const gatewayUrlRaw = params.get("gatewayUrl") ?? hashParams.get("gatewayUrl");
101
+ let shouldCleanUrl = false;
102
+
103
+ if (tokenRaw != null) {
104
+ const token = tokenRaw.trim();
105
+ if (token && token !== host.settings.token) {
106
+ applySettings(host, { ...host.settings, token });
107
+ }
108
+ params.delete("token");
109
+ hashParams.delete("token");
110
+ shouldCleanUrl = true;
111
+ }
112
+
113
+ if (passwordRaw != null) {
114
+ // Never hydrate password from URL params; strip only.
115
+ params.delete("password");
116
+ hashParams.delete("password");
117
+ shouldCleanUrl = true;
118
+ }
119
+
120
+ if (sessionRaw != null) {
121
+ const session = sessionRaw.trim();
122
+ if (session) {
123
+ host.sessionKey = session;
124
+ applySettings(host, {
125
+ ...host.settings,
126
+ sessionKey: session,
127
+ lastActiveSessionKey: session,
128
+ });
129
+ }
130
+ }
131
+
132
+ if (gatewayUrlRaw != null) {
133
+ const gatewayUrl = gatewayUrlRaw.trim();
134
+ if (gatewayUrl && gatewayUrl !== host.settings.gatewayUrl) {
135
+ host.pendingGatewayUrl = gatewayUrl;
136
+ }
137
+ params.delete("gatewayUrl");
138
+ hashParams.delete("gatewayUrl");
139
+ shouldCleanUrl = true;
140
+ }
141
+
142
+ if (!shouldCleanUrl) {
143
+ return;
144
+ }
145
+ url.search = params.toString();
146
+ const nextHash = hashParams.toString();
147
+ url.hash = nextHash ? `#${nextHash}` : "";
148
+ window.history.replaceState({}, "", url.toString());
149
+ }
150
+
151
+ export function setTab(host: SettingsHost, next: Tab) {
152
+ applyTabSelection(host, next, { refreshPolicy: "always", syncUrl: true });
153
+ }
154
+
155
+ export function setTheme(host: SettingsHost, next: ThemeMode, context?: ThemeTransitionContext) {
156
+ const applyTheme = () => {
157
+ host.theme = next;
158
+ applySettings(host, { ...host.settings, theme: next });
159
+ applyResolvedTheme(host, resolveTheme(next));
160
+ };
161
+ startThemeTransition({
162
+ nextTheme: next,
163
+ applyTheme,
164
+ context,
165
+ currentTheme: host.theme,
166
+ });
167
+ }
168
+
169
+ export async function refreshActiveTab(host: SettingsHost) {
170
+ if (host.tab === "overview") {
171
+ await loadOverview(host);
172
+ }
173
+ if (host.tab === "channels") {
174
+ await loadChannelsTab(host);
175
+ }
176
+ if (host.tab === "instances") {
177
+ await loadPresence(host as unknown as OpenClawApp);
178
+ }
179
+ if (host.tab === "sessions") {
180
+ await loadSessions(host as unknown as OpenClawApp);
181
+ }
182
+ if (host.tab === "cron") {
183
+ await loadCron(host);
184
+ }
185
+ if (host.tab === "skills") {
186
+ await loadSkills(host as unknown as OpenClawApp);
187
+ }
188
+ if (host.tab === "agents") {
189
+ await loadAgents(host as unknown as OpenClawApp);
190
+ await loadToolsCatalog(host as unknown as OpenClawApp);
191
+ await loadConfig(host as unknown as OpenClawApp);
192
+ const agentIds = host.agentsList?.agents?.map((entry) => entry.id) ?? [];
193
+ if (agentIds.length > 0) {
194
+ void loadAgentIdentities(host as unknown as OpenClawApp, agentIds);
195
+ }
196
+ const agentId =
197
+ host.agentsSelectedId ?? host.agentsList?.defaultId ?? host.agentsList?.agents?.[0]?.id;
198
+ if (agentId) {
199
+ void loadAgentIdentity(host as unknown as OpenClawApp, agentId);
200
+ if (host.agentsPanel === "skills") {
201
+ void loadAgentSkills(host as unknown as OpenClawApp, agentId);
202
+ }
203
+ if (host.agentsPanel === "channels") {
204
+ void loadChannels(host as unknown as OpenClawApp, false);
205
+ }
206
+ if (host.agentsPanel === "cron") {
207
+ void loadCron(host);
208
+ }
209
+ }
210
+ }
211
+ if (host.tab === "nodes") {
212
+ await loadNodes(host as unknown as OpenClawApp);
213
+ await loadDevices(host as unknown as OpenClawApp);
214
+ await loadConfig(host as unknown as OpenClawApp);
215
+ await loadExecApprovals(host as unknown as OpenClawApp);
216
+ }
217
+ if (host.tab === "chat") {
218
+ await refreshChat(host as unknown as Parameters<typeof refreshChat>[0]);
219
+ scheduleChatScroll(
220
+ host as unknown as Parameters<typeof scheduleChatScroll>[0],
221
+ !host.chatHasAutoScrolled,
222
+ );
223
+ }
224
+ if (host.tab === "config") {
225
+ await loadConfigSchema(host as unknown as OpenClawApp);
226
+ await loadConfig(host as unknown as OpenClawApp);
227
+ }
228
+ if (host.tab === "debug") {
229
+ await loadDebug(host as unknown as OpenClawApp);
230
+ host.eventLog = host.eventLogBuffer;
231
+ }
232
+ if (host.tab === "logs") {
233
+ host.logsAtBottom = true;
234
+ await loadLogs(host as unknown as OpenClawApp, { reset: true });
235
+ scheduleLogsScroll(host as unknown as Parameters<typeof scheduleLogsScroll>[0], true);
236
+ }
237
+ }
238
+
239
+ export function inferBasePath() {
240
+ if (typeof window === "undefined") {
241
+ return "";
242
+ }
243
+ const configured = window.__OPENCLAW_CONTROL_UI_BASE_PATH__;
244
+ if (typeof configured === "string" && configured.trim()) {
245
+ return normalizeBasePath(configured);
246
+ }
247
+ return inferBasePathFromPathname(window.location.pathname);
248
+ }
249
+
250
+ export function syncThemeWithSettings(host: SettingsHost) {
251
+ host.theme = host.settings.theme ?? "system";
252
+ applyResolvedTheme(host, resolveTheme(host.theme));
253
+ }
254
+
255
+ export function applyResolvedTheme(host: SettingsHost, resolved: ResolvedTheme) {
256
+ host.themeResolved = resolved;
257
+ if (typeof document === "undefined") {
258
+ return;
259
+ }
260
+ const root = document.documentElement;
261
+ root.dataset.theme = resolved;
262
+ root.style.colorScheme = resolved;
263
+ }
264
+
265
+ export function attachThemeListener(host: SettingsHost) {
266
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
267
+ return;
268
+ }
269
+ host.themeMedia = window.matchMedia("(prefers-color-scheme: dark)");
270
+ host.themeMediaHandler = (event) => {
271
+ if (host.theme !== "system") {
272
+ return;
273
+ }
274
+ applyResolvedTheme(host, event.matches ? "dark" : "light");
275
+ };
276
+ if (typeof host.themeMedia.addEventListener === "function") {
277
+ host.themeMedia.addEventListener("change", host.themeMediaHandler);
278
+ return;
279
+ }
280
+ const legacy = host.themeMedia as MediaQueryList & {
281
+ addListener: (cb: (event: MediaQueryListEvent) => void) => void;
282
+ };
283
+ legacy.addListener(host.themeMediaHandler);
284
+ }
285
+
286
+ export function detachThemeListener(host: SettingsHost) {
287
+ if (!host.themeMedia || !host.themeMediaHandler) {
288
+ return;
289
+ }
290
+ if (typeof host.themeMedia.removeEventListener === "function") {
291
+ host.themeMedia.removeEventListener("change", host.themeMediaHandler);
292
+ return;
293
+ }
294
+ const legacy = host.themeMedia as MediaQueryList & {
295
+ removeListener: (cb: (event: MediaQueryListEvent) => void) => void;
296
+ };
297
+ legacy.removeListener(host.themeMediaHandler);
298
+ host.themeMedia = null;
299
+ host.themeMediaHandler = null;
300
+ }
301
+
302
+ export function syncTabWithLocation(host: SettingsHost, replace: boolean) {
303
+ if (typeof window === "undefined") {
304
+ return;
305
+ }
306
+ const resolved = tabFromPath(window.location.pathname, host.basePath) ?? "chat";
307
+ setTabFromRoute(host, resolved);
308
+ syncUrlWithTab(host, resolved, replace);
309
+ }
310
+
311
+ export function onPopState(host: SettingsHost) {
312
+ if (typeof window === "undefined") {
313
+ return;
314
+ }
315
+ const resolved = tabFromPath(window.location.pathname, host.basePath);
316
+ if (!resolved) {
317
+ return;
318
+ }
319
+
320
+ const url = new URL(window.location.href);
321
+ const session = url.searchParams.get("session")?.trim();
322
+ if (session) {
323
+ host.sessionKey = session;
324
+ applySettings(host, {
325
+ ...host.settings,
326
+ sessionKey: session,
327
+ lastActiveSessionKey: session,
328
+ });
329
+ }
330
+
331
+ setTabFromRoute(host, resolved);
332
+ }
333
+
334
+ export function setTabFromRoute(host: SettingsHost, next: Tab) {
335
+ applyTabSelection(host, next, { refreshPolicy: "connected" });
336
+ }
337
+
338
+ function applyTabSelection(
339
+ host: SettingsHost,
340
+ next: Tab,
341
+ options: { refreshPolicy: "always" | "connected"; syncUrl?: boolean },
342
+ ) {
343
+ if (host.tab !== next) {
344
+ host.tab = next;
345
+ }
346
+ if (next === "chat") {
347
+ host.chatHasAutoScrolled = false;
348
+ }
349
+ if (next === "logs") {
350
+ startLogsPolling(host as unknown as Parameters<typeof startLogsPolling>[0]);
351
+ } else {
352
+ stopLogsPolling(host as unknown as Parameters<typeof stopLogsPolling>[0]);
353
+ }
354
+ if (next === "debug") {
355
+ startDebugPolling(host as unknown as Parameters<typeof startDebugPolling>[0]);
356
+ } else {
357
+ stopDebugPolling(host as unknown as Parameters<typeof stopDebugPolling>[0]);
358
+ }
359
+
360
+ if (options.refreshPolicy === "always" || host.connected) {
361
+ void refreshActiveTab(host);
362
+ }
363
+
364
+ if (options.syncUrl) {
365
+ syncUrlWithTab(host, next, false);
366
+ }
367
+ }
368
+
369
+ export function syncUrlWithTab(host: SettingsHost, tab: Tab, replace: boolean) {
370
+ if (typeof window === "undefined") {
371
+ return;
372
+ }
373
+ const targetPath = normalizePath(pathForTab(tab, host.basePath));
374
+ const currentPath = normalizePath(window.location.pathname);
375
+ const url = new URL(window.location.href);
376
+
377
+ if (tab === "chat" && host.sessionKey) {
378
+ url.searchParams.set("session", host.sessionKey);
379
+ } else {
380
+ url.searchParams.delete("session");
381
+ }
382
+
383
+ if (currentPath !== targetPath) {
384
+ url.pathname = targetPath;
385
+ }
386
+
387
+ if (replace) {
388
+ window.history.replaceState({}, "", url.toString());
389
+ } else {
390
+ window.history.pushState({}, "", url.toString());
391
+ }
392
+ }
393
+
394
+ export function syncUrlWithSessionKey(host: SettingsHost, sessionKey: string, replace: boolean) {
395
+ if (typeof window === "undefined") {
396
+ return;
397
+ }
398
+ const url = new URL(window.location.href);
399
+ url.searchParams.set("session", sessionKey);
400
+ if (replace) {
401
+ window.history.replaceState({}, "", url.toString());
402
+ } else {
403
+ window.history.pushState({}, "", url.toString());
404
+ }
405
+ }
406
+
407
+ export async function loadOverview(host: SettingsHost) {
408
+ await Promise.all([
409
+ loadChannels(host as unknown as OpenClawApp, false),
410
+ loadPresence(host as unknown as OpenClawApp),
411
+ loadSessions(host as unknown as OpenClawApp),
412
+ loadCronStatus(host as unknown as OpenClawApp),
413
+ loadDebug(host as unknown as OpenClawApp),
414
+ ]);
415
+ }
416
+
417
+ export async function loadChannelsTab(host: SettingsHost) {
418
+ await Promise.all([
419
+ loadChannels(host as unknown as OpenClawApp, true),
420
+ loadConfigSchema(host as unknown as OpenClawApp),
421
+ loadConfig(host as unknown as OpenClawApp),
422
+ ]);
423
+ }
424
+
425
+ export async function loadCron(host: SettingsHost) {
426
+ const cronHost = host as unknown as OpenClawApp;
427
+ await Promise.all([
428
+ loadChannels(host as unknown as OpenClawApp, false),
429
+ loadCronStatus(cronHost),
430
+ loadCronJobs(cronHost),
431
+ loadCronModelSuggestions(cronHost),
432
+ ]);
433
+ if (cronHost.cronRunsScope === "all") {
434
+ await loadCronRuns(cronHost, null);
435
+ return;
436
+ }
437
+ if (cronHost.cronRunsJobId) {
438
+ await loadCronRuns(cronHost, cronHost.cronRunsJobId);
439
+ }
440
+ }
@@ -0,0 +1,139 @@
1
+ import { beforeAll, describe, expect, it, vi } from "vitest";
2
+ import { handleAgentEvent, type FallbackStatus, type ToolStreamEntry } from "./app-tool-stream.ts";
3
+
4
+ type ToolStreamHost = Parameters<typeof handleAgentEvent>[0];
5
+ type MutableHost = ToolStreamHost & {
6
+ compactionStatus?: unknown;
7
+ compactionClearTimer?: number | null;
8
+ fallbackStatus?: FallbackStatus | null;
9
+ fallbackClearTimer?: number | null;
10
+ };
11
+
12
+ function createHost(overrides?: Partial<MutableHost>): MutableHost {
13
+ return {
14
+ sessionKey: "main",
15
+ chatRunId: null,
16
+ toolStreamById: new Map<string, ToolStreamEntry>(),
17
+ toolStreamOrder: [],
18
+ chatToolMessages: [],
19
+ toolStreamSyncTimer: null,
20
+ compactionStatus: null,
21
+ compactionClearTimer: null,
22
+ fallbackStatus: null,
23
+ fallbackClearTimer: null,
24
+ ...overrides,
25
+ };
26
+ }
27
+
28
+ describe("app-tool-stream fallback lifecycle handling", () => {
29
+ beforeAll(() => {
30
+ const globalWithWindow = globalThis as typeof globalThis & {
31
+ window?: Window & typeof globalThis;
32
+ };
33
+ if (!globalWithWindow.window) {
34
+ globalWithWindow.window = globalThis as unknown as Window & typeof globalThis;
35
+ }
36
+ });
37
+
38
+ it("accepts session-scoped fallback lifecycle events when no run is active", () => {
39
+ vi.useFakeTimers();
40
+ const host = createHost();
41
+
42
+ handleAgentEvent(host, {
43
+ runId: "run-1",
44
+ seq: 1,
45
+ stream: "lifecycle",
46
+ ts: Date.now(),
47
+ sessionKey: "main",
48
+ data: {
49
+ phase: "fallback",
50
+ selectedProvider: "fireworks",
51
+ selectedModel: "fireworks/minimax-m2p5",
52
+ activeProvider: "deepinfra",
53
+ activeModel: "moonshotai/Kimi-K2.5",
54
+ reasonSummary: "rate limit",
55
+ },
56
+ });
57
+
58
+ expect(host.fallbackStatus?.selected).toBe("fireworks/minimax-m2p5");
59
+ expect(host.fallbackStatus?.active).toBe("deepinfra/moonshotai/Kimi-K2.5");
60
+ expect(host.fallbackStatus?.reason).toBe("rate limit");
61
+ vi.useRealTimers();
62
+ });
63
+
64
+ it("rejects idle fallback lifecycle events for other sessions", () => {
65
+ vi.useFakeTimers();
66
+ const host = createHost();
67
+
68
+ handleAgentEvent(host, {
69
+ runId: "run-1",
70
+ seq: 1,
71
+ stream: "lifecycle",
72
+ ts: Date.now(),
73
+ sessionKey: "agent:other:main",
74
+ data: {
75
+ phase: "fallback",
76
+ selectedProvider: "fireworks",
77
+ selectedModel: "fireworks/minimax-m2p5",
78
+ activeProvider: "deepinfra",
79
+ activeModel: "moonshotai/Kimi-K2.5",
80
+ },
81
+ });
82
+
83
+ expect(host.fallbackStatus).toBeNull();
84
+ vi.useRealTimers();
85
+ });
86
+
87
+ it("auto-clears fallback status after toast duration", () => {
88
+ vi.useFakeTimers();
89
+ const host = createHost();
90
+
91
+ handleAgentEvent(host, {
92
+ runId: "run-1",
93
+ seq: 1,
94
+ stream: "lifecycle",
95
+ ts: Date.now(),
96
+ sessionKey: "main",
97
+ data: {
98
+ phase: "fallback",
99
+ selectedProvider: "fireworks",
100
+ selectedModel: "fireworks/minimax-m2p5",
101
+ activeProvider: "deepinfra",
102
+ activeModel: "moonshotai/Kimi-K2.5",
103
+ },
104
+ });
105
+
106
+ expect(host.fallbackStatus).not.toBeNull();
107
+ vi.advanceTimersByTime(7_999);
108
+ expect(host.fallbackStatus).not.toBeNull();
109
+ vi.advanceTimersByTime(1);
110
+ expect(host.fallbackStatus).toBeNull();
111
+ vi.useRealTimers();
112
+ });
113
+
114
+ it("builds previous fallback label from provider + model on fallback_cleared", () => {
115
+ vi.useFakeTimers();
116
+ const host = createHost();
117
+
118
+ handleAgentEvent(host, {
119
+ runId: "run-1",
120
+ seq: 1,
121
+ stream: "lifecycle",
122
+ ts: Date.now(),
123
+ sessionKey: "main",
124
+ data: {
125
+ phase: "fallback_cleared",
126
+ selectedProvider: "fireworks",
127
+ selectedModel: "fireworks/minimax-m2p5",
128
+ activeProvider: "fireworks",
129
+ activeModel: "fireworks/minimax-m2p5",
130
+ previousActiveProvider: "deepinfra",
131
+ previousActiveModel: "moonshotai/Kimi-K2.5",
132
+ },
133
+ });
134
+
135
+ expect(host.fallbackStatus?.phase).toBe("cleared");
136
+ expect(host.fallbackStatus?.previous).toBe("deepinfra/moonshotai/Kimi-K2.5");
137
+ vi.useRealTimers();
138
+ });
139
+ });