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,151 @@
1
+ import { html, nothing } from "lit";
2
+ import type { EventLogEntry } from "../app-events.ts";
3
+ import { formatEventPayload } from "../presenter.ts";
4
+
5
+ export type DebugProps = {
6
+ loading: boolean;
7
+ status: Record<string, unknown> | null;
8
+ health: Record<string, unknown> | null;
9
+ models: unknown[];
10
+ heartbeat: unknown;
11
+ eventLog: EventLogEntry[];
12
+ callMethod: string;
13
+ callParams: string;
14
+ callResult: string | null;
15
+ callError: string | null;
16
+ onCallMethodChange: (next: string) => void;
17
+ onCallParamsChange: (next: string) => void;
18
+ onRefresh: () => void;
19
+ onCall: () => void;
20
+ };
21
+
22
+ export function renderDebug(props: DebugProps) {
23
+ const securityAudit =
24
+ props.status && typeof props.status === "object"
25
+ ? (props.status as { securityAudit?: { summary?: Record<string, number> } }).securityAudit
26
+ : null;
27
+ const securitySummary = securityAudit?.summary ?? null;
28
+ const critical = securitySummary?.critical ?? 0;
29
+ const warn = securitySummary?.warn ?? 0;
30
+ const info = securitySummary?.info ?? 0;
31
+ const securityTone = critical > 0 ? "danger" : warn > 0 ? "warn" : "success";
32
+ const securityLabel =
33
+ critical > 0 ? `${critical} critical` : warn > 0 ? `${warn} warnings` : "No critical issues";
34
+
35
+ return html`
36
+ <section class="grid grid-cols-2">
37
+ <div class="card">
38
+ <div class="row" style="justify-content: space-between;">
39
+ <div>
40
+ <div class="card-title">Snapshots</div>
41
+ <div class="card-sub">Status, health, and heartbeat data.</div>
42
+ </div>
43
+ <button class="btn" ?disabled=${props.loading} @click=${props.onRefresh}>
44
+ ${props.loading ? "Refreshing…" : "Refresh"}
45
+ </button>
46
+ </div>
47
+ <div class="stack" style="margin-top: 12px;">
48
+ <div>
49
+ <div class="muted">Status</div>
50
+ ${
51
+ securitySummary
52
+ ? html`<div class="callout ${securityTone}" style="margin-top: 8px;">
53
+ Security audit: ${securityLabel}${info > 0 ? ` · ${info} info` : ""}. Run
54
+ <span class="mono">openclaw security audit --deep</span> for details.
55
+ </div>`
56
+ : nothing
57
+ }
58
+ <pre class="code-block">${JSON.stringify(props.status ?? {}, null, 2)}</pre>
59
+ </div>
60
+ <div>
61
+ <div class="muted">Health</div>
62
+ <pre class="code-block">${JSON.stringify(props.health ?? {}, null, 2)}</pre>
63
+ </div>
64
+ <div>
65
+ <div class="muted">Last heartbeat</div>
66
+ <pre class="code-block">${JSON.stringify(props.heartbeat ?? {}, null, 2)}</pre>
67
+ </div>
68
+ </div>
69
+ </div>
70
+
71
+ <div class="card">
72
+ <div class="card-title">Manual RPC</div>
73
+ <div class="card-sub">Send a raw gateway method with JSON params.</div>
74
+ <div class="form-grid" style="margin-top: 16px;">
75
+ <label class="field">
76
+ <span>Method</span>
77
+ <input
78
+ .value=${props.callMethod}
79
+ @input=${(e: Event) => props.onCallMethodChange((e.target as HTMLInputElement).value)}
80
+ placeholder="system-presence"
81
+ />
82
+ </label>
83
+ <label class="field">
84
+ <span>Params (JSON)</span>
85
+ <textarea
86
+ .value=${props.callParams}
87
+ @input=${(e: Event) =>
88
+ props.onCallParamsChange((e.target as HTMLTextAreaElement).value)}
89
+ rows="6"
90
+ ></textarea>
91
+ </label>
92
+ </div>
93
+ <div class="row" style="margin-top: 12px;">
94
+ <button class="btn primary" @click=${props.onCall}>Call</button>
95
+ </div>
96
+ ${
97
+ props.callError
98
+ ? html`<div class="callout danger" style="margin-top: 12px;">
99
+ ${props.callError}
100
+ </div>`
101
+ : nothing
102
+ }
103
+ ${
104
+ props.callResult
105
+ ? html`<pre class="code-block" style="margin-top: 12px;">${props.callResult}</pre>`
106
+ : nothing
107
+ }
108
+ </div>
109
+ </section>
110
+
111
+ <section class="card" style="margin-top: 18px;">
112
+ <div class="card-title">Models</div>
113
+ <div class="card-sub">Catalog from models.list.</div>
114
+ <pre class="code-block" style="margin-top: 12px;">${JSON.stringify(
115
+ props.models ?? [],
116
+ null,
117
+ 2,
118
+ )}</pre>
119
+ </section>
120
+
121
+ <section class="card" style="margin-top: 18px;">
122
+ <div class="card-title">Event Log</div>
123
+ <div class="card-sub">Latest gateway events.</div>
124
+ ${
125
+ props.eventLog.length === 0
126
+ ? html`
127
+ <div class="muted" style="margin-top: 12px">No events yet.</div>
128
+ `
129
+ : html`
130
+ <div class="list debug-event-log" style="margin-top: 12px;">
131
+ ${props.eventLog.map(
132
+ (evt) => html`
133
+ <div class="list-item debug-event-log__item">
134
+ <div class="list-main">
135
+ <div class="list-title">${evt.event}</div>
136
+ <div class="list-sub">${new Date(evt.ts).toLocaleTimeString()}</div>
137
+ </div>
138
+ <div class="list-meta debug-event-log__meta">
139
+ <pre class="code-block debug-event-log__payload">${formatEventPayload(
140
+ evt.payload,
141
+ )}</pre>
142
+ </div>
143
+ </div>
144
+ `,
145
+ )}
146
+ </div>
147
+ `
148
+ }
149
+ </section>
150
+ `;
151
+ }
@@ -0,0 +1,89 @@
1
+ import { html, nothing } from "lit";
2
+ import type { AppViewState } from "../app-view-state.ts";
3
+
4
+ function formatRemaining(ms: number): string {
5
+ const remaining = Math.max(0, ms);
6
+ const totalSeconds = Math.floor(remaining / 1000);
7
+ if (totalSeconds < 60) {
8
+ return `${totalSeconds}s`;
9
+ }
10
+ const minutes = Math.floor(totalSeconds / 60);
11
+ if (minutes < 60) {
12
+ return `${minutes}m`;
13
+ }
14
+ const hours = Math.floor(minutes / 60);
15
+ return `${hours}h`;
16
+ }
17
+
18
+ function renderMetaRow(label: string, value?: string | null) {
19
+ if (!value) {
20
+ return nothing;
21
+ }
22
+ return html`<div class="exec-approval-meta-row"><span>${label}</span><span>${value}</span></div>`;
23
+ }
24
+
25
+ export function renderExecApprovalPrompt(state: AppViewState) {
26
+ const active = state.execApprovalQueue[0];
27
+ if (!active) {
28
+ return nothing;
29
+ }
30
+ const request = active.request;
31
+ const remainingMs = active.expiresAtMs - Date.now();
32
+ const remaining = remainingMs > 0 ? `expires in ${formatRemaining(remainingMs)}` : "expired";
33
+ const queueCount = state.execApprovalQueue.length;
34
+ return html`
35
+ <div class="exec-approval-overlay" role="dialog" aria-live="polite">
36
+ <div class="exec-approval-card">
37
+ <div class="exec-approval-header">
38
+ <div>
39
+ <div class="exec-approval-title">Exec approval needed</div>
40
+ <div class="exec-approval-sub">${remaining}</div>
41
+ </div>
42
+ ${
43
+ queueCount > 1
44
+ ? html`<div class="exec-approval-queue">${queueCount} pending</div>`
45
+ : nothing
46
+ }
47
+ </div>
48
+ <div class="exec-approval-command mono">${request.command}</div>
49
+ <div class="exec-approval-meta">
50
+ ${renderMetaRow("Host", request.host)}
51
+ ${renderMetaRow("Agent", request.agentId)}
52
+ ${renderMetaRow("Session", request.sessionKey)}
53
+ ${renderMetaRow("CWD", request.cwd)}
54
+ ${renderMetaRow("Resolved", request.resolvedPath)}
55
+ ${renderMetaRow("Security", request.security)}
56
+ ${renderMetaRow("Ask", request.ask)}
57
+ </div>
58
+ ${
59
+ state.execApprovalError
60
+ ? html`<div class="exec-approval-error">${state.execApprovalError}</div>`
61
+ : nothing
62
+ }
63
+ <div class="exec-approval-actions">
64
+ <button
65
+ class="btn primary"
66
+ ?disabled=${state.execApprovalBusy}
67
+ @click=${() => state.handleExecApprovalDecision("allow-once")}
68
+ >
69
+ Allow once
70
+ </button>
71
+ <button
72
+ class="btn"
73
+ ?disabled=${state.execApprovalBusy}
74
+ @click=${() => state.handleExecApprovalDecision("allow-always")}
75
+ >
76
+ Always allow
77
+ </button>
78
+ <button
79
+ class="btn danger"
80
+ ?disabled=${state.execApprovalBusy}
81
+ @click=${() => state.handleExecApprovalDecision("deny")}
82
+ >
83
+ Deny
84
+ </button>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ `;
89
+ }
@@ -0,0 +1,40 @@
1
+ import { html, nothing } from "lit";
2
+ import type { AppViewState } from "../app-view-state.ts";
3
+
4
+ export function renderGatewayUrlConfirmation(state: AppViewState) {
5
+ const { pendingGatewayUrl } = state;
6
+ if (!pendingGatewayUrl) {
7
+ return nothing;
8
+ }
9
+
10
+ return html`
11
+ <div class="exec-approval-overlay" role="dialog" aria-modal="true" aria-live="polite">
12
+ <div class="exec-approval-card">
13
+ <div class="exec-approval-header">
14
+ <div>
15
+ <div class="exec-approval-title">Change Gateway URL</div>
16
+ <div class="exec-approval-sub">This will reconnect to a different gateway server</div>
17
+ </div>
18
+ </div>
19
+ <div class="exec-approval-command mono">${pendingGatewayUrl}</div>
20
+ <div class="callout danger" style="margin-top: 12px;">
21
+ Only confirm if you trust this URL. Malicious URLs can compromise your system.
22
+ </div>
23
+ <div class="exec-approval-actions">
24
+ <button
25
+ class="btn primary"
26
+ @click=${() => state.handleGatewayUrlConfirm()}
27
+ >
28
+ Confirm
29
+ </button>
30
+ <button
31
+ class="btn"
32
+ @click=${() => state.handleGatewayUrlCancel()}
33
+ >
34
+ Cancel
35
+ </button>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ `;
40
+ }
@@ -0,0 +1,89 @@
1
+ import { html, nothing } from "lit";
2
+ import { formatPresenceAge, formatPresenceSummary } from "../presenter.ts";
3
+ import type { PresenceEntry } from "../types.ts";
4
+
5
+ export type InstancesProps = {
6
+ loading: boolean;
7
+ entries: PresenceEntry[];
8
+ lastError: string | null;
9
+ statusMessage: string | null;
10
+ onRefresh: () => void;
11
+ };
12
+
13
+ export function renderInstances(props: InstancesProps) {
14
+ return html`
15
+ <section class="card">
16
+ <div class="row" style="justify-content: space-between;">
17
+ <div>
18
+ <div class="card-title">Connected Instances</div>
19
+ <div class="card-sub">Presence beacons from the gateway and clients.</div>
20
+ </div>
21
+ <button class="btn" ?disabled=${props.loading} @click=${props.onRefresh}>
22
+ ${props.loading ? "Loading…" : "Refresh"}
23
+ </button>
24
+ </div>
25
+ ${
26
+ props.lastError
27
+ ? html`<div class="callout danger" style="margin-top: 12px;">
28
+ ${props.lastError}
29
+ </div>`
30
+ : nothing
31
+ }
32
+ ${
33
+ props.statusMessage
34
+ ? html`<div class="callout" style="margin-top: 12px;">
35
+ ${props.statusMessage}
36
+ </div>`
37
+ : nothing
38
+ }
39
+ <div class="list" style="margin-top: 16px;">
40
+ ${
41
+ props.entries.length === 0
42
+ ? html`
43
+ <div class="muted">No instances reported yet.</div>
44
+ `
45
+ : props.entries.map((entry) => renderEntry(entry))
46
+ }
47
+ </div>
48
+ </section>
49
+ `;
50
+ }
51
+
52
+ function renderEntry(entry: PresenceEntry) {
53
+ const lastInput = entry.lastInputSeconds != null ? `${entry.lastInputSeconds}s ago` : "n/a";
54
+ const mode = entry.mode ?? "unknown";
55
+ const roles = Array.isArray(entry.roles) ? entry.roles.filter(Boolean) : [];
56
+ const scopes = Array.isArray(entry.scopes) ? entry.scopes.filter(Boolean) : [];
57
+ const scopesLabel =
58
+ scopes.length > 0
59
+ ? scopes.length > 3
60
+ ? `${scopes.length} scopes`
61
+ : `scopes: ${scopes.join(", ")}`
62
+ : null;
63
+ return html`
64
+ <div class="list-item">
65
+ <div class="list-main">
66
+ <div class="list-title">${entry.host ?? "unknown host"}</div>
67
+ <div class="list-sub">${formatPresenceSummary(entry)}</div>
68
+ <div class="chip-row">
69
+ <span class="chip">${mode}</span>
70
+ ${roles.map((role) => html`<span class="chip">${role}</span>`)}
71
+ ${scopesLabel ? html`<span class="chip">${scopesLabel}</span>` : nothing}
72
+ ${entry.platform ? html`<span class="chip">${entry.platform}</span>` : nothing}
73
+ ${entry.deviceFamily ? html`<span class="chip">${entry.deviceFamily}</span>` : nothing}
74
+ ${
75
+ entry.modelIdentifier
76
+ ? html`<span class="chip">${entry.modelIdentifier}</span>`
77
+ : nothing
78
+ }
79
+ ${entry.version ? html`<span class="chip">${entry.version}</span>` : nothing}
80
+ </div>
81
+ </div>
82
+ <div class="list-meta">
83
+ <div>${formatPresenceAge(entry)}</div>
84
+ <div class="muted">Last input ${lastInput}</div>
85
+ <div class="muted">Reason ${entry.reason ?? ""}</div>
86
+ </div>
87
+ </div>
88
+ `;
89
+ }
@@ -0,0 +1,155 @@
1
+ import { html, nothing } from "lit";
2
+ import type { LogEntry, LogLevel } from "../types.ts";
3
+
4
+ const LEVELS: LogLevel[] = ["trace", "debug", "info", "warn", "error", "fatal"];
5
+
6
+ export type LogsProps = {
7
+ loading: boolean;
8
+ error: string | null;
9
+ file: string | null;
10
+ entries: LogEntry[];
11
+ filterText: string;
12
+ levelFilters: Record<LogLevel, boolean>;
13
+ autoFollow: boolean;
14
+ truncated: boolean;
15
+ onFilterTextChange: (next: string) => void;
16
+ onLevelToggle: (level: LogLevel, enabled: boolean) => void;
17
+ onToggleAutoFollow: (next: boolean) => void;
18
+ onRefresh: () => void;
19
+ onExport: (lines: string[], label: string) => void;
20
+ onScroll: (event: Event) => void;
21
+ };
22
+
23
+ function formatTime(value?: string | null) {
24
+ if (!value) {
25
+ return "";
26
+ }
27
+ const date = new Date(value);
28
+ if (Number.isNaN(date.getTime())) {
29
+ return value;
30
+ }
31
+ return date.toLocaleTimeString();
32
+ }
33
+
34
+ function matchesFilter(entry: LogEntry, needle: string) {
35
+ if (!needle) {
36
+ return true;
37
+ }
38
+ const haystack = [entry.message, entry.subsystem, entry.raw]
39
+ .filter(Boolean)
40
+ .join(" ")
41
+ .toLowerCase();
42
+ return haystack.includes(needle);
43
+ }
44
+
45
+ export function renderLogs(props: LogsProps) {
46
+ const needle = props.filterText.trim().toLowerCase();
47
+ const levelFiltered = LEVELS.some((level) => !props.levelFilters[level]);
48
+ const filtered = props.entries.filter((entry) => {
49
+ if (entry.level && !props.levelFilters[entry.level]) {
50
+ return false;
51
+ }
52
+ return matchesFilter(entry, needle);
53
+ });
54
+ const exportLabel = needle || levelFiltered ? "filtered" : "visible";
55
+
56
+ return html`
57
+ <section class="card">
58
+ <div class="row" style="justify-content: space-between;">
59
+ <div>
60
+ <div class="card-title">Logs</div>
61
+ <div class="card-sub">Gateway file logs (JSONL).</div>
62
+ </div>
63
+ <div class="row" style="gap: 8px;">
64
+ <button class="btn" ?disabled=${props.loading} @click=${props.onRefresh}>
65
+ ${props.loading ? "Loading…" : "Refresh"}
66
+ </button>
67
+ <button
68
+ class="btn"
69
+ ?disabled=${filtered.length === 0}
70
+ @click=${() =>
71
+ props.onExport(
72
+ filtered.map((entry) => entry.raw),
73
+ exportLabel,
74
+ )}
75
+ >
76
+ Export ${exportLabel}
77
+ </button>
78
+ </div>
79
+ </div>
80
+
81
+ <div class="filters" style="margin-top: 14px;">
82
+ <label class="field" style="min-width: 220px;">
83
+ <span>Filter</span>
84
+ <input
85
+ .value=${props.filterText}
86
+ @input=${(e: Event) => props.onFilterTextChange((e.target as HTMLInputElement).value)}
87
+ placeholder="Search logs"
88
+ />
89
+ </label>
90
+ <label class="field checkbox">
91
+ <span>Auto-follow</span>
92
+ <input
93
+ type="checkbox"
94
+ .checked=${props.autoFollow}
95
+ @change=${(e: Event) =>
96
+ props.onToggleAutoFollow((e.target as HTMLInputElement).checked)}
97
+ />
98
+ </label>
99
+ </div>
100
+
101
+ <div class="chip-row" style="margin-top: 12px;">
102
+ ${LEVELS.map(
103
+ (level) => html`
104
+ <label class="chip log-chip ${level}">
105
+ <input
106
+ type="checkbox"
107
+ .checked=${props.levelFilters[level]}
108
+ @change=${(e: Event) =>
109
+ props.onLevelToggle(level, (e.target as HTMLInputElement).checked)}
110
+ />
111
+ <span>${level}</span>
112
+ </label>
113
+ `,
114
+ )}
115
+ </div>
116
+
117
+ ${
118
+ props.file
119
+ ? html`<div class="muted" style="margin-top: 10px;">File: ${props.file}</div>`
120
+ : nothing
121
+ }
122
+ ${
123
+ props.truncated
124
+ ? html`
125
+ <div class="callout" style="margin-top: 10px">Log output truncated; showing latest chunk.</div>
126
+ `
127
+ : nothing
128
+ }
129
+ ${
130
+ props.error
131
+ ? html`<div class="callout danger" style="margin-top: 10px;">${props.error}</div>`
132
+ : nothing
133
+ }
134
+
135
+ <div class="log-stream" style="margin-top: 12px;" @scroll=${props.onScroll}>
136
+ ${
137
+ filtered.length === 0
138
+ ? html`
139
+ <div class="muted" style="padding: 12px">No log entries.</div>
140
+ `
141
+ : filtered.map(
142
+ (entry) => html`
143
+ <div class="log-row">
144
+ <div class="log-time mono">${formatTime(entry.time)}</div>
145
+ <div class="log-level ${entry.level ?? ""}">${entry.level ?? ""}</div>
146
+ <div class="log-subsystem mono">${entry.subsystem ?? ""}</div>
147
+ <div class="log-message mono">${entry.message ?? entry.raw}</div>
148
+ </div>
149
+ `,
150
+ )
151
+ }
152
+ </div>
153
+ </section>
154
+ `;
155
+ }
@@ -0,0 +1,40 @@
1
+ import { html } from "lit";
2
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
3
+ import { icons } from "../icons.ts";
4
+ import { toSanitizedMarkdownHtml } from "../markdown.ts";
5
+
6
+ export type MarkdownSidebarProps = {
7
+ content: string | null;
8
+ error: string | null;
9
+ onClose: () => void;
10
+ onViewRawText: () => void;
11
+ };
12
+
13
+ export function renderMarkdownSidebar(props: MarkdownSidebarProps) {
14
+ return html`
15
+ <div class="sidebar-panel">
16
+ <div class="sidebar-header">
17
+ <div class="sidebar-title">Tool Output</div>
18
+ <button @click=${props.onClose} class="btn" title="Close sidebar">
19
+ ${icons.x}
20
+ </button>
21
+ </div>
22
+ <div class="sidebar-content">
23
+ ${
24
+ props.error
25
+ ? html`
26
+ <div class="callout danger">${props.error}</div>
27
+ <button @click=${props.onViewRawText} class="btn" style="margin-top: 12px;">
28
+ View Raw Text
29
+ </button>
30
+ `
31
+ : props.content
32
+ ? html`<div class="sidebar-markdown">${unsafeHTML(toSanitizedMarkdownHtml(props.content))}</div>`
33
+ : html`
34
+ <div class="muted">No content available</div>
35
+ `
36
+ }
37
+ </div>
38
+ </div>
39
+ `;
40
+ }