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,349 @@
1
+ import {
2
+ GATEWAY_EVENT_UPDATE_AVAILABLE,
3
+ type GatewayUpdateAvailableEventPayload,
4
+ } from "../../../src/gateway/events.js";
5
+ import { CHAT_SESSIONS_ACTIVE_MINUTES, flushChatQueueForEvent } from "./app-chat.ts";
6
+ import type { EventLogEntry } from "./app-events.ts";
7
+ import {
8
+ applySettings,
9
+ loadCron,
10
+ refreshActiveTab,
11
+ setLastActiveSessionKey,
12
+ } from "./app-settings.ts";
13
+ import { handleAgentEvent, resetToolStream, type AgentEventPayload } from "./app-tool-stream.ts";
14
+ import type { OpenClawApp } from "./app.ts";
15
+ import { shouldReloadHistoryForFinalEvent } from "./chat-event-reload.ts";
16
+ import { loadAgents, loadToolsCatalog } from "./controllers/agents.ts";
17
+ import { loadAssistantIdentity } from "./controllers/assistant-identity.ts";
18
+ import { loadChatHistory } from "./controllers/chat.ts";
19
+ import { handleChatEvent, type ChatEventPayload } from "./controllers/chat.ts";
20
+ import { loadDevices } from "./controllers/devices.ts";
21
+ import type { ExecApprovalRequest } from "./controllers/exec-approval.ts";
22
+ import {
23
+ addExecApproval,
24
+ parseExecApprovalRequested,
25
+ parseExecApprovalResolved,
26
+ removeExecApproval,
27
+ } from "./controllers/exec-approval.ts";
28
+ import { loadNodes } from "./controllers/nodes.ts";
29
+ import { loadSessions } from "./controllers/sessions.ts";
30
+ import {
31
+ resolveGatewayErrorDetailCode,
32
+ type GatewayEventFrame,
33
+ type GatewayHelloOk,
34
+ } from "./gateway.ts";
35
+ import { GatewayBrowserClient } from "./gateway.ts";
36
+ import type { Tab } from "./navigation.ts";
37
+ import type { UiSettings } from "./storage.ts";
38
+ import type {
39
+ AgentsListResult,
40
+ PresenceEntry,
41
+ HealthSnapshot,
42
+ StatusSummary,
43
+ UpdateAvailable,
44
+ } from "./types.ts";
45
+
46
+ type GatewayHost = {
47
+ settings: UiSettings;
48
+ password: string;
49
+ clientInstanceId: string;
50
+ client: GatewayBrowserClient | null;
51
+ connected: boolean;
52
+ hello: GatewayHelloOk | null;
53
+ lastError: string | null;
54
+ lastErrorCode: string | null;
55
+ onboarding?: boolean;
56
+ eventLogBuffer: EventLogEntry[];
57
+ eventLog: EventLogEntry[];
58
+ tab: Tab;
59
+ presenceEntries: PresenceEntry[];
60
+ presenceError: string | null;
61
+ presenceStatus: StatusSummary | null;
62
+ agentsLoading: boolean;
63
+ agentsList: AgentsListResult | null;
64
+ agentsError: string | null;
65
+ toolsCatalogLoading: boolean;
66
+ toolsCatalogError: string | null;
67
+ toolsCatalogResult: import("./types.ts").ToolsCatalogResult | null;
68
+ debugHealth: HealthSnapshot | null;
69
+ assistantName: string;
70
+ assistantAvatar: string | null;
71
+ assistantAgentId: string | null;
72
+ sessionKey: string;
73
+ chatRunId: string | null;
74
+ refreshSessionsAfterChat: Set<string>;
75
+ execApprovalQueue: ExecApprovalRequest[];
76
+ execApprovalError: string | null;
77
+ updateAvailable: UpdateAvailable | null;
78
+ };
79
+
80
+ type SessionDefaultsSnapshot = {
81
+ defaultAgentId?: string;
82
+ mainKey?: string;
83
+ mainSessionKey?: string;
84
+ scope?: string;
85
+ };
86
+
87
+ function normalizeSessionKeyForDefaults(
88
+ value: string | undefined,
89
+ defaults: SessionDefaultsSnapshot,
90
+ ): string {
91
+ const raw = (value ?? "").trim();
92
+ const mainSessionKey = defaults.mainSessionKey?.trim();
93
+ if (!mainSessionKey) {
94
+ return raw;
95
+ }
96
+ if (!raw) {
97
+ return mainSessionKey;
98
+ }
99
+ const mainKey = defaults.mainKey?.trim() || "main";
100
+ const defaultAgentId = defaults.defaultAgentId?.trim();
101
+ const isAlias =
102
+ raw === "main" ||
103
+ raw === mainKey ||
104
+ (defaultAgentId &&
105
+ (raw === `agent:${defaultAgentId}:main` || raw === `agent:${defaultAgentId}:${mainKey}`));
106
+ return isAlias ? mainSessionKey : raw;
107
+ }
108
+
109
+ function applySessionDefaults(host: GatewayHost, defaults?: SessionDefaultsSnapshot) {
110
+ if (!defaults?.mainSessionKey) {
111
+ return;
112
+ }
113
+ const resolvedSessionKey = normalizeSessionKeyForDefaults(host.sessionKey, defaults);
114
+ const resolvedSettingsSessionKey = normalizeSessionKeyForDefaults(
115
+ host.settings.sessionKey,
116
+ defaults,
117
+ );
118
+ const resolvedLastActiveSessionKey = normalizeSessionKeyForDefaults(
119
+ host.settings.lastActiveSessionKey,
120
+ defaults,
121
+ );
122
+ const nextSessionKey = resolvedSessionKey || resolvedSettingsSessionKey || host.sessionKey;
123
+ const nextSettings = {
124
+ ...host.settings,
125
+ sessionKey: resolvedSettingsSessionKey || nextSessionKey,
126
+ lastActiveSessionKey: resolvedLastActiveSessionKey || nextSessionKey,
127
+ };
128
+ const shouldUpdateSettings =
129
+ nextSettings.sessionKey !== host.settings.sessionKey ||
130
+ nextSettings.lastActiveSessionKey !== host.settings.lastActiveSessionKey;
131
+ if (nextSessionKey !== host.sessionKey) {
132
+ host.sessionKey = nextSessionKey;
133
+ }
134
+ if (shouldUpdateSettings) {
135
+ applySettings(host as unknown as Parameters<typeof applySettings>[0], nextSettings);
136
+ }
137
+ }
138
+
139
+ export function connectGateway(host: GatewayHost) {
140
+ host.lastError = null;
141
+ host.lastErrorCode = null;
142
+ host.hello = null;
143
+ host.connected = false;
144
+ host.execApprovalQueue = [];
145
+ host.execApprovalError = null;
146
+
147
+ const previousClient = host.client;
148
+ const client = new GatewayBrowserClient({
149
+ url: host.settings.gatewayUrl,
150
+ token: host.settings.token.trim() ? host.settings.token : undefined,
151
+ password: host.password.trim() ? host.password : undefined,
152
+ clientName: "openclaw-control-ui",
153
+ mode: "webchat",
154
+ instanceId: host.clientInstanceId,
155
+ onHello: (hello) => {
156
+ if (host.client !== client) {
157
+ return;
158
+ }
159
+ host.connected = true;
160
+ host.lastError = null;
161
+ host.lastErrorCode = null;
162
+ host.hello = hello;
163
+ applySnapshot(host, hello);
164
+ // Reset orphaned chat run state from before disconnect.
165
+ // Any in-flight run's final event was lost during the disconnect window.
166
+ host.chatRunId = null;
167
+ (host as unknown as { chatStream: string | null }).chatStream = null;
168
+ (host as unknown as { chatStreamStartedAt: number | null }).chatStreamStartedAt = null;
169
+ resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);
170
+ void loadAssistantIdentity(host as unknown as OpenClawApp);
171
+ void loadAgents(host as unknown as OpenClawApp);
172
+ void loadToolsCatalog(host as unknown as OpenClawApp);
173
+ void loadNodes(host as unknown as OpenClawApp, { quiet: true });
174
+ void loadDevices(host as unknown as OpenClawApp, { quiet: true });
175
+ void refreshActiveTab(host as unknown as Parameters<typeof refreshActiveTab>[0]);
176
+ },
177
+ onClose: ({ code, reason, error }) => {
178
+ if (host.client !== client) {
179
+ return;
180
+ }
181
+ host.connected = false;
182
+ // Code 1012 = Service Restart (expected during config saves, don't show as error)
183
+ host.lastErrorCode =
184
+ resolveGatewayErrorDetailCode(error) ??
185
+ (typeof error?.code === "string" ? error.code : null);
186
+ if (code !== 1012) {
187
+ if (error?.message) {
188
+ host.lastError = error.message;
189
+ return;
190
+ }
191
+ host.lastError = `disconnected (${code}): ${reason || "no reason"}`;
192
+ } else {
193
+ host.lastError = null;
194
+ host.lastErrorCode = null;
195
+ }
196
+ },
197
+ onEvent: (evt) => {
198
+ if (host.client !== client) {
199
+ return;
200
+ }
201
+ handleGatewayEvent(host, evt);
202
+ },
203
+ onGap: ({ expected, received }) => {
204
+ if (host.client !== client) {
205
+ return;
206
+ }
207
+ host.lastError = `event gap detected (expected seq ${expected}, got ${received}); refresh recommended`;
208
+ host.lastErrorCode = null;
209
+ },
210
+ });
211
+ host.client = client;
212
+ previousClient?.stop();
213
+ client.start();
214
+ }
215
+
216
+ export function handleGatewayEvent(host: GatewayHost, evt: GatewayEventFrame) {
217
+ try {
218
+ handleGatewayEventUnsafe(host, evt);
219
+ } catch (err) {
220
+ console.error("[gateway] handleGatewayEvent error:", evt.event, err);
221
+ }
222
+ }
223
+
224
+ function handleTerminalChatEvent(
225
+ host: GatewayHost,
226
+ payload: ChatEventPayload | undefined,
227
+ state: ReturnType<typeof handleChatEvent>,
228
+ ) {
229
+ if (state !== "final" && state !== "error" && state !== "aborted") {
230
+ return;
231
+ }
232
+ resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);
233
+ void flushChatQueueForEvent(host as unknown as Parameters<typeof flushChatQueueForEvent>[0]);
234
+ const runId = payload?.runId;
235
+ if (!runId || !host.refreshSessionsAfterChat.has(runId)) {
236
+ return;
237
+ }
238
+ host.refreshSessionsAfterChat.delete(runId);
239
+ if (state === "final") {
240
+ void loadSessions(host as unknown as OpenClawApp, {
241
+ activeMinutes: CHAT_SESSIONS_ACTIVE_MINUTES,
242
+ });
243
+ }
244
+ }
245
+
246
+ function handleChatGatewayEvent(host: GatewayHost, payload: ChatEventPayload | undefined) {
247
+ if (payload?.sessionKey) {
248
+ setLastActiveSessionKey(
249
+ host as unknown as Parameters<typeof setLastActiveSessionKey>[0],
250
+ payload.sessionKey,
251
+ );
252
+ }
253
+ const state = handleChatEvent(host as unknown as OpenClawApp, payload);
254
+ handleTerminalChatEvent(host, payload, state);
255
+ if (state === "final" && shouldReloadHistoryForFinalEvent(payload)) {
256
+ void loadChatHistory(host as unknown as OpenClawApp);
257
+ }
258
+ }
259
+
260
+ function handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {
261
+ host.eventLogBuffer = [
262
+ { ts: Date.now(), event: evt.event, payload: evt.payload },
263
+ ...host.eventLogBuffer,
264
+ ].slice(0, 250);
265
+ if (host.tab === "debug") {
266
+ host.eventLog = host.eventLogBuffer;
267
+ }
268
+
269
+ if (evt.event === "agent") {
270
+ if (host.onboarding) {
271
+ return;
272
+ }
273
+ handleAgentEvent(
274
+ host as unknown as Parameters<typeof handleAgentEvent>[0],
275
+ evt.payload as AgentEventPayload | undefined,
276
+ );
277
+ return;
278
+ }
279
+
280
+ if (evt.event === "chat") {
281
+ handleChatGatewayEvent(host, evt.payload as ChatEventPayload | undefined);
282
+ return;
283
+ }
284
+
285
+ if (evt.event === "presence") {
286
+ const payload = evt.payload as { presence?: PresenceEntry[] } | undefined;
287
+ if (payload?.presence && Array.isArray(payload.presence)) {
288
+ host.presenceEntries = payload.presence;
289
+ host.presenceError = null;
290
+ host.presenceStatus = null;
291
+ }
292
+ return;
293
+ }
294
+
295
+ if (evt.event === "cron" && host.tab === "cron") {
296
+ void loadCron(host as unknown as Parameters<typeof loadCron>[0]);
297
+ }
298
+
299
+ if (evt.event === "device.pair.requested" || evt.event === "device.pair.resolved") {
300
+ void loadDevices(host as unknown as OpenClawApp, { quiet: true });
301
+ }
302
+
303
+ if (evt.event === "exec.approval.requested") {
304
+ const entry = parseExecApprovalRequested(evt.payload);
305
+ if (entry) {
306
+ host.execApprovalQueue = addExecApproval(host.execApprovalQueue, entry);
307
+ host.execApprovalError = null;
308
+ const delay = Math.max(0, entry.expiresAtMs - Date.now() + 500);
309
+ window.setTimeout(() => {
310
+ host.execApprovalQueue = removeExecApproval(host.execApprovalQueue, entry.id);
311
+ }, delay);
312
+ }
313
+ return;
314
+ }
315
+
316
+ if (evt.event === "exec.approval.resolved") {
317
+ const resolved = parseExecApprovalResolved(evt.payload);
318
+ if (resolved) {
319
+ host.execApprovalQueue = removeExecApproval(host.execApprovalQueue, resolved.id);
320
+ }
321
+ return;
322
+ }
323
+
324
+ if (evt.event === GATEWAY_EVENT_UPDATE_AVAILABLE) {
325
+ const payload = evt.payload as GatewayUpdateAvailableEventPayload | undefined;
326
+ host.updateAvailable = payload?.updateAvailable ?? null;
327
+ }
328
+ }
329
+
330
+ export function applySnapshot(host: GatewayHost, hello: GatewayHelloOk) {
331
+ const snapshot = hello.snapshot as
332
+ | {
333
+ presence?: PresenceEntry[];
334
+ health?: HealthSnapshot;
335
+ sessionDefaults?: SessionDefaultsSnapshot;
336
+ updateAvailable?: UpdateAvailable;
337
+ }
338
+ | undefined;
339
+ if (snapshot?.presence && Array.isArray(snapshot.presence)) {
340
+ host.presenceEntries = snapshot.presence;
341
+ }
342
+ if (snapshot?.health) {
343
+ host.debugHealth = snapshot.health;
344
+ }
345
+ if (snapshot?.sessionDefaults) {
346
+ applySessionDefaults(host, snapshot.sessionDefaults);
347
+ }
348
+ host.updateAvailable = snapshot?.updateAvailable ?? null;
349
+ }
@@ -0,0 +1,44 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { handleDisconnected } from "./app-lifecycle.ts";
3
+
4
+ function createHost() {
5
+ return {
6
+ basePath: "",
7
+ client: { stop: vi.fn() },
8
+ connected: true,
9
+ tab: "chat",
10
+ assistantName: "OpenClaw",
11
+ assistantAvatar: null,
12
+ assistantAgentId: null,
13
+ chatHasAutoScrolled: false,
14
+ chatManualRefreshInFlight: false,
15
+ chatLoading: false,
16
+ chatMessages: [],
17
+ chatToolMessages: [],
18
+ chatStream: null,
19
+ logsAutoFollow: false,
20
+ logsAtBottom: true,
21
+ logsEntries: [],
22
+ popStateHandler: vi.fn(),
23
+ topbarObserver: { disconnect: vi.fn() } as unknown as ResizeObserver,
24
+ };
25
+ }
26
+
27
+ describe("handleDisconnected", () => {
28
+ it("stops and clears gateway client on teardown", () => {
29
+ const removeSpy = vi.spyOn(window, "removeEventListener").mockImplementation(() => undefined);
30
+ const host = createHost();
31
+ const disconnectSpy = (
32
+ host.topbarObserver as unknown as { disconnect: ReturnType<typeof vi.fn> }
33
+ ).disconnect;
34
+
35
+ handleDisconnected(host as unknown as Parameters<typeof handleDisconnected>[0]);
36
+
37
+ expect(removeSpy).toHaveBeenCalledWith("popstate", host.popStateHandler);
38
+ expect(host.client).toBeNull();
39
+ expect(host.connected).toBe(false);
40
+ expect(disconnectSpy).toHaveBeenCalledTimes(1);
41
+ expect(host.topbarObserver).toBeNull();
42
+ removeSpy.mockRestore();
43
+ });
44
+ });
@@ -0,0 +1,109 @@
1
+ import { connectGateway } from "./app-gateway.ts";
2
+ import {
3
+ startLogsPolling,
4
+ startNodesPolling,
5
+ stopLogsPolling,
6
+ stopNodesPolling,
7
+ startDebugPolling,
8
+ stopDebugPolling,
9
+ } from "./app-polling.ts";
10
+ import { observeTopbar, scheduleChatScroll, scheduleLogsScroll } from "./app-scroll.ts";
11
+ import {
12
+ applySettingsFromUrl,
13
+ attachThemeListener,
14
+ detachThemeListener,
15
+ inferBasePath,
16
+ syncTabWithLocation,
17
+ syncThemeWithSettings,
18
+ } from "./app-settings.ts";
19
+ import { loadControlUiBootstrapConfig } from "./controllers/control-ui-bootstrap.ts";
20
+ import type { Tab } from "./navigation.ts";
21
+
22
+ type LifecycleHost = {
23
+ basePath: string;
24
+ client?: { stop: () => void } | null;
25
+ connected?: boolean;
26
+ tab: Tab;
27
+ assistantName: string;
28
+ assistantAvatar: string | null;
29
+ assistantAgentId: string | null;
30
+ chatHasAutoScrolled: boolean;
31
+ chatManualRefreshInFlight: boolean;
32
+ chatLoading: boolean;
33
+ chatMessages: unknown[];
34
+ chatToolMessages: unknown[];
35
+ chatStream: string;
36
+ logsAutoFollow: boolean;
37
+ logsAtBottom: boolean;
38
+ logsEntries: unknown[];
39
+ popStateHandler: () => void;
40
+ topbarObserver: ResizeObserver | null;
41
+ };
42
+
43
+ export function handleConnected(host: LifecycleHost) {
44
+ host.basePath = inferBasePath();
45
+ void loadControlUiBootstrapConfig(host);
46
+ applySettingsFromUrl(host as unknown as Parameters<typeof applySettingsFromUrl>[0]);
47
+ syncTabWithLocation(host as unknown as Parameters<typeof syncTabWithLocation>[0], true);
48
+ syncThemeWithSettings(host as unknown as Parameters<typeof syncThemeWithSettings>[0]);
49
+ attachThemeListener(host as unknown as Parameters<typeof attachThemeListener>[0]);
50
+ window.addEventListener("popstate", host.popStateHandler);
51
+ connectGateway(host as unknown as Parameters<typeof connectGateway>[0]);
52
+ startNodesPolling(host as unknown as Parameters<typeof startNodesPolling>[0]);
53
+ if (host.tab === "logs") {
54
+ startLogsPolling(host as unknown as Parameters<typeof startLogsPolling>[0]);
55
+ }
56
+ if (host.tab === "debug") {
57
+ startDebugPolling(host as unknown as Parameters<typeof startDebugPolling>[0]);
58
+ }
59
+ }
60
+
61
+ export function handleFirstUpdated(host: LifecycleHost) {
62
+ observeTopbar(host as unknown as Parameters<typeof observeTopbar>[0]);
63
+ }
64
+
65
+ export function handleDisconnected(host: LifecycleHost) {
66
+ window.removeEventListener("popstate", host.popStateHandler);
67
+ stopNodesPolling(host as unknown as Parameters<typeof stopNodesPolling>[0]);
68
+ stopLogsPolling(host as unknown as Parameters<typeof stopLogsPolling>[0]);
69
+ stopDebugPolling(host as unknown as Parameters<typeof stopDebugPolling>[0]);
70
+ host.client?.stop();
71
+ host.client = null;
72
+ host.connected = false;
73
+ detachThemeListener(host as unknown as Parameters<typeof detachThemeListener>[0]);
74
+ host.topbarObserver?.disconnect();
75
+ host.topbarObserver = null;
76
+ }
77
+
78
+ export function handleUpdated(host: LifecycleHost, changed: Map<PropertyKey, unknown>) {
79
+ if (host.tab === "chat" && host.chatManualRefreshInFlight) {
80
+ return;
81
+ }
82
+ if (
83
+ host.tab === "chat" &&
84
+ (changed.has("chatMessages") ||
85
+ changed.has("chatToolMessages") ||
86
+ changed.has("chatStream") ||
87
+ changed.has("chatLoading") ||
88
+ changed.has("tab"))
89
+ ) {
90
+ const forcedByTab = changed.has("tab");
91
+ const forcedByLoad =
92
+ changed.has("chatLoading") && changed.get("chatLoading") === true && !host.chatLoading;
93
+ scheduleChatScroll(
94
+ host as unknown as Parameters<typeof scheduleChatScroll>[0],
95
+ forcedByTab || forcedByLoad || !host.chatHasAutoScrolled,
96
+ );
97
+ }
98
+ if (
99
+ host.tab === "logs" &&
100
+ (changed.has("logsEntries") || changed.has("logsAutoFollow") || changed.has("tab"))
101
+ ) {
102
+ if (host.logsAutoFollow && host.logsAtBottom) {
103
+ scheduleLogsScroll(
104
+ host as unknown as Parameters<typeof scheduleLogsScroll>[0],
105
+ changed.has("tab") || changed.has("logsAutoFollow"),
106
+ );
107
+ }
108
+ }
109
+ }
@@ -0,0 +1,69 @@
1
+ import type { OpenClawApp } from "./app.ts";
2
+ import { loadDebug } from "./controllers/debug.ts";
3
+ import { loadLogs } from "./controllers/logs.ts";
4
+ import { loadNodes } from "./controllers/nodes.ts";
5
+
6
+ type PollingHost = {
7
+ nodesPollInterval: number | null;
8
+ logsPollInterval: number | null;
9
+ debugPollInterval: number | null;
10
+ tab: string;
11
+ };
12
+
13
+ export function startNodesPolling(host: PollingHost) {
14
+ if (host.nodesPollInterval != null) {
15
+ return;
16
+ }
17
+ host.nodesPollInterval = window.setInterval(
18
+ () => void loadNodes(host as unknown as OpenClawApp, { quiet: true }),
19
+ 5000,
20
+ );
21
+ }
22
+
23
+ export function stopNodesPolling(host: PollingHost) {
24
+ if (host.nodesPollInterval == null) {
25
+ return;
26
+ }
27
+ clearInterval(host.nodesPollInterval);
28
+ host.nodesPollInterval = null;
29
+ }
30
+
31
+ export function startLogsPolling(host: PollingHost) {
32
+ if (host.logsPollInterval != null) {
33
+ return;
34
+ }
35
+ host.logsPollInterval = window.setInterval(() => {
36
+ if (host.tab !== "logs") {
37
+ return;
38
+ }
39
+ void loadLogs(host as unknown as OpenClawApp, { quiet: true });
40
+ }, 2000);
41
+ }
42
+
43
+ export function stopLogsPolling(host: PollingHost) {
44
+ if (host.logsPollInterval == null) {
45
+ return;
46
+ }
47
+ clearInterval(host.logsPollInterval);
48
+ host.logsPollInterval = null;
49
+ }
50
+
51
+ export function startDebugPolling(host: PollingHost) {
52
+ if (host.debugPollInterval != null) {
53
+ return;
54
+ }
55
+ host.debugPollInterval = window.setInterval(() => {
56
+ if (host.tab !== "debug") {
57
+ return;
58
+ }
59
+ void loadDebug(host as unknown as OpenClawApp);
60
+ }, 3000);
61
+ }
62
+
63
+ export function stopDebugPolling(host: PollingHost) {
64
+ if (host.debugPollInterval == null) {
65
+ return;
66
+ }
67
+ clearInterval(host.debugPollInterval);
68
+ host.debugPollInterval = null;
69
+ }