openclaw-multi-auto 1.3.7 → 1.3.8

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 (503) 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-preflight-5FEeDooz.js → audio-preflight-DDBLZBdb.js} +4 -4
  8. package/dist/{audio-transcription-runner-B-UvoDjZ.js → audio-transcription-runner-DZbSWT9E.js} +1 -1
  9. package/dist/{audio-transcription-runner-28fcRNNi.js → audio-transcription-runner-gLFfz8fr.js} +12 -12
  10. package/dist/{audit-membership-runtime-DWyHWAHM.js → audit-membership-runtime-Dntemq07.js} +4 -4
  11. package/dist/build-info.json +3 -3
  12. package/dist/bundled/boot-md/handler.js +51 -51
  13. package/dist/bundled/bootstrap-extra-files/handler.js +6 -6
  14. package/dist/bundled/command-logger/handler.js +2 -2
  15. package/dist/bundled/session-memory/handler.js +51 -51
  16. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  17. package/dist/{channel-activity-xHOMiarp.js → channel-activity-BDnjYF7B.js} +3 -3
  18. package/dist/{chrome-D45SyhQL.js → chrome-CMU2WVFh.js} +8 -8
  19. package/dist/{chrome-DwizpzOC.js → chrome-DxxEKrY7.js} +18 -18
  20. package/dist/{commands-registry-V1zZ5pPC.js → commands-registry-D5qXbFJn.js} +4 -4
  21. package/dist/{deliver-B9cys0EZ.js → deliver-BXVcFIHL.js} +1 -1
  22. package/dist/{deliver-D4o6VIur.js → deliver-DbdywYJE.js} +21 -21
  23. package/dist/deliver-runtime-BFs7iAZF.js +36 -0
  24. package/dist/{deliver-runtime-DhaQJ0pI.js → deliver-runtime-DTaIS-1i.js} +3 -3
  25. package/dist/deps-send-discord.runtime-DZUccI6Z.js +26 -0
  26. package/dist/deps-send-imessage.runtime-CF3OpoqY.js +25 -0
  27. package/dist/deps-send-signal.runtime-Cw4-ozeO.js +24 -0
  28. package/dist/deps-send-slack.runtime-BDsDhS1P.js +22 -0
  29. package/dist/deps-send-telegram.runtime-D_4xVasO.js +27 -0
  30. package/dist/{deps-send-whatsapp.runtime-DvTL2tzN.js → deps-send-whatsapp.runtime-CIZqFAqb.js} +7 -7
  31. package/dist/deps-send-whatsapp.runtime-DK8jqd14.js +60 -0
  32. package/dist/{diagnostic-Bn4PZjMZ.js → diagnostic-Co6Kghr-.js} +2 -2
  33. package/dist/{plugin-sdk/errors-CtMWwS2Z.js → errors-xt401nuk.js} +1 -1
  34. package/dist/extensionAPI.js +6 -6
  35. package/dist/{fetch-BlJWzEP6.js → fetch-DuraYswo.js} +5 -5
  36. package/dist/{fetch-guard-ChYBwfiy.js → fetch-guard-DWr0d00H.js} +2 -2
  37. package/dist/{frontmatter-CvaMP376.js → frontmatter-BkTfEZ93.js} +3 -3
  38. package/dist/{fs-safe-0jAo_Whb.js → fs-safe-CTYUrIgQ.js} +4 -4
  39. package/dist/{github-copilot-token-D13V9YBz.js → github-copilot-token-BDioPmd6.js} +7 -7
  40. package/dist/{image-DAOPwVXi.js → image-BCVLo0qw.js} +1 -1
  41. package/dist/{image-Bbn53mzj.js → image-eT7Y-nP5.js} +6 -6
  42. package/dist/{image-ops-CehkHxmW.js → image-ops-BuUnEOE0.js} +2 -2
  43. package/dist/image-runtime-BcAK3n8a.js +29 -0
  44. package/dist/{image-runtime-wlCLVvVv.js → image-runtime-DtCKpMPZ.js} +3 -3
  45. package/dist/{ir-DAP-B-Xw.js → ir-B83looB-.js} +8 -8
  46. package/dist/{legacy-names-TyzbVqa_.js → legacy-names-DOC03BkU.js} +1 -1
  47. package/dist/llm-slug-generator.js +51 -51
  48. package/dist/{logger-DMZQQtxK.js → logger-BfjWMCSD.js} +7 -7
  49. package/dist/{login-DiCctRo1.js → login-CrIwcrVI.js} +5 -5
  50. package/dist/{login-qr-MUbXgjtd.js → login-qr-BpPDZdl_.js} +10 -10
  51. package/dist/{manager-BW_NSIMl.js → manager-1bvuGrNR.js} +13 -13
  52. package/dist/manager-runtime-FO1Sx3W8.js +18 -0
  53. package/dist/{model-selection-idoqPmw0.js → model-selection-Dna0Gz1k.js} +43 -43
  54. package/dist/{outbound-C2kanETZ.js → outbound-ChDjtuD6.js} +6 -6
  55. package/dist/{outbound-attachment-DBrYWX8h.js → outbound-attachment-DqHlD21U.js} +2 -2
  56. package/dist/{path-alias-guards-DqXRZmsL.js → path-alias-guards-BzvdLvTI.js} +1 -1
  57. package/dist/{paths-CCxysrzL.js → paths-Bkr-BCxW.js} +4 -4
  58. package/dist/{paths-C6TxBCvO.js → paths-Cvc9EM8Y.js} +5 -5
  59. package/dist/{pi-embedded-BaGj07T0.js → pi-embedded-BQQa91aA.js} +158 -158
  60. package/dist/{pi-embedded-DYU79yGe.js → pi-embedded-CgQ_W6Xs.js} +24 -24
  61. package/dist/{pi-embedded-helpers-wy0DZvx1.js → pi-embedded-helpers-CLXm10bV.js} +52 -52
  62. package/dist/{pi-embedded-helpers-uTRAmQ4n.js → pi-embedded-helpers-CwuBTKza.js} +3 -3
  63. package/dist/{plugin-sdk/pi-model-discovery-v-XPUOOf.js → pi-model-discovery-Dymwdjt0.js} +2 -2
  64. package/dist/pi-model-discovery-runtime-BeY4EUPp.js +11 -0
  65. package/dist/{pi-tools.before-tool-call.runtime-BuLxSyx9.js → pi-tools.before-tool-call.runtime-Cwab_5W1.js} +9 -9
  66. package/dist/plugin-sdk/{accounts-DyFCXtHv.js → accounts-BslAlVYS.js} +2 -2
  67. package/dist/plugin-sdk/{accounts-BJAXxY46.js → accounts-C3m65--E.js} +2 -2
  68. package/dist/plugin-sdk/{accounts-C1j7HSL0.js → accounts-CNCCkdEF.js} +3 -3
  69. package/dist/plugin-sdk/{active-listener-B_sLJTXM.js → active-listener-CkPnMUkB.js} +2 -2
  70. package/dist/plugin-sdk/{api-key-rotation-8nyyt1kx.js → api-key-rotation-BXnNsojA.js} +2 -2
  71. package/dist/plugin-sdk/{audio-preflight-C_aSAPR1.js → audio-preflight-CtO4fFvp.js} +26 -26
  72. package/dist/plugin-sdk/{audio-transcription-runner-CB53F7_7.js → audio-transcription-runner-DnxvOS1-.js} +11 -11
  73. package/dist/plugin-sdk/{audit-membership-runtime-BXndI4LG.js → audit-membership-runtime-BpfoSk8M.js} +2 -2
  74. package/dist/plugin-sdk/{channel-activity-C5y8AgAV.js → channel-activity-WJYxcJ3S.js} +3 -3
  75. package/dist/plugin-sdk/{channel-web-DBTRO03V.js → channel-web-dO5k3ubM.js} +18 -18
  76. package/dist/plugin-sdk/{chrome-f00sZkDX.js → chrome-CjNTuJML.js} +6 -6
  77. package/dist/plugin-sdk/{commands-registry-BJ_NxG2F.js → commands-registry-CdYjoI0i.js} +4 -4
  78. package/dist/plugin-sdk/{common-Cf27Jwxu.js → common-oYc5vPFl.js} +2 -2
  79. package/dist/plugin-sdk/{config-CHQrpx-Q.js → config-B1z-UxQ3.js} +7 -7
  80. package/dist/plugin-sdk/{deliver-DNEuetST.js → deliver-D5_6T567.js} +10 -10
  81. package/dist/plugin-sdk/deliver-runtime-C5dgvvga.js +32 -0
  82. package/dist/plugin-sdk/deps-send-discord.runtime-Dg4N7PHJ.js +23 -0
  83. package/dist/plugin-sdk/deps-send-imessage.runtime-0OEwzMQm.js +22 -0
  84. package/dist/plugin-sdk/deps-send-signal.runtime-BM1jRt3G.js +21 -0
  85. package/dist/plugin-sdk/deps-send-slack.runtime-1E3BYRdF.js +19 -0
  86. package/dist/plugin-sdk/deps-send-telegram.runtime-DNCxIflA.js +24 -0
  87. package/dist/plugin-sdk/deps-send-whatsapp.runtime-OLwr-9c8.js +57 -0
  88. package/dist/plugin-sdk/{diagnostic-LYUUmjJ5.js → diagnostic-Bxxu0ig-.js} +2 -2
  89. package/dist/plugin-sdk/{errors-DaiAM-yU.js → errors-B3cHyZZA.js} +1 -1
  90. package/dist/plugin-sdk/{fetch-guard-CxYB5Kg6.js → fetch-guard-Dcgod0tg.js} +2 -2
  91. package/dist/plugin-sdk/{fs-safe-DtfhxbrI.js → fs-safe-BaKqI3G4.js} +3 -3
  92. package/dist/plugin-sdk/{image-BwjYjRHx.js → image-B2mQW9Rb.js} +6 -6
  93. package/dist/plugin-sdk/{image-ops-BnZKcbd6.js → image-ops-Cbzr4U9l.js} +2 -2
  94. package/dist/plugin-sdk/image-runtime-BFm45j49.js +25 -0
  95. package/dist/plugin-sdk/index.js +50 -50
  96. package/dist/plugin-sdk/{ir-Z4hX67TJ.js → ir-ZEmrTr4J.js} +7 -7
  97. package/dist/plugin-sdk/{local-roots-KhjQw04O.js → local-roots-CIPRxA-4.js} +4 -4
  98. package/dist/plugin-sdk/{logger-DHIIvMxj.js → logger-CvPFVOgT.js} +2 -2
  99. package/dist/plugin-sdk/{login-C31642Ld.js → login-CCTew9bt.js} +4 -4
  100. package/dist/plugin-sdk/{login-qr--y2SG_Ue.js → login-qr-BI3Vi_wJ.js} +5 -5
  101. package/dist/plugin-sdk/{manager-2UZBMCc7.js → manager-BEoYPn7R.js} +8 -8
  102. package/dist/plugin-sdk/manager-runtime-DxclHQ4U.js +15 -0
  103. package/dist/plugin-sdk/{outbound-Ba0QUI5h.js → outbound-ByOw1K6W.js} +5 -5
  104. package/dist/plugin-sdk/{outbound-attachment-B1Laso-8.js → outbound-attachment-BzVhxRRw.js} +2 -2
  105. package/dist/plugin-sdk/{path-alias-guards-C7Vm5DZ1.js → path-alias-guards-sWayacde.js} +1 -1
  106. package/dist/plugin-sdk/{paths-DopV9PQG.js → paths-Dpg3qxcl.js} +1 -1
  107. package/dist/plugin-sdk/{pi-embedded-helpers-DnA_OCzP.js → pi-embedded-helpers-DIxXkGJf.js} +16 -16
  108. package/dist/plugin-sdk/{pi-model-discovery-DdPqXk8f.js → pi-model-discovery-DM_2uFtj.js} +1 -1
  109. package/dist/plugin-sdk/pi-model-discovery-runtime-BuzvkvNR.js +8 -0
  110. package/dist/plugin-sdk/{pi-tools.before-tool-call.runtime-DxFHiLUE.js → pi-tools.before-tool-call.runtime-w1dqL_ty.js} +4 -4
  111. package/dist/plugin-sdk/{plugins-CbCt4osF.js → plugins-C4USiH29.js} +4 -4
  112. package/dist/plugin-sdk/{proxy-env-C63mMdas.js → proxy-env-ET-rp8eg.js} +1 -1
  113. package/dist/plugin-sdk/{proxy-fetch-ChxOhWF4.js → proxy-fetch-uDXGKG3Z.js} +1 -1
  114. package/dist/plugin-sdk/{pw-ai-DpJk62D4.js → pw-ai-CyOt3RDA.js} +9 -9
  115. package/dist/plugin-sdk/{qmd-manager-Ca-iSfEE.js → qmd-manager-BySdoVR7.js} +7 -7
  116. package/dist/plugin-sdk/{query-expansion-B_Xe41Ab.js → query-expansion-C6uS-7lj.js} +4 -4
  117. package/dist/plugin-sdk/{redact-DjVX-1N3.js → redact-Bvxt1T_Q.js} +1 -1
  118. package/dist/plugin-sdk/{reply-CovBlFea.js → reply-CTCSeQqW.js} +73 -73
  119. package/dist/plugin-sdk/{resolve-outbound-target-BbrHgyUk.js → resolve-outbound-target-Bw8YNANu.js} +2 -2
  120. package/dist/plugin-sdk/{run-with-concurrency-BR1DXa8T.js → run-with-concurrency-C_KCHwvf.js} +1 -1
  121. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-BxgRDkhc.js +10 -0
  122. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-elOqrkfg.js +19 -0
  123. package/dist/plugin-sdk/{send-BvAtLLPl.js → send-BZ6nYFZr.js} +5 -5
  124. package/dist/plugin-sdk/{send-BTztm3D2.js → send-C0w6xP2x.js} +6 -6
  125. package/dist/plugin-sdk/{send-CWJUuG0i.js → send-CFf-1V89.js} +8 -8
  126. package/dist/plugin-sdk/{send-EcglC4cG.js → send-CY-Qfwia.js} +7 -7
  127. package/dist/plugin-sdk/{send-BXpXBwM_.js → send-qPyNGSe4.js} +13 -13
  128. package/dist/plugin-sdk/{session-k256LJZT.js → session-COrvpvUQ.js} +3 -3
  129. package/dist/plugin-sdk/{skill-commands-DoRqLzxm.js → skill-commands-DZqhtmiv.js} +4 -4
  130. package/dist/plugin-sdk/{skills-QudILG6e.js → skills-Cw_vXEJb.js} +6 -6
  131. package/dist/plugin-sdk/slash-commands.runtime-D67JLweo.js +13 -0
  132. package/dist/plugin-sdk/slash-dispatch.runtime-DvcpvCJ0.js +52 -0
  133. package/dist/plugin-sdk/slash-skill-commands.runtime-BM1x3azR.js +16 -0
  134. package/dist/plugin-sdk/{store-BbDQw3g6.js → store-CMHj6IIw.js} +2 -2
  135. package/dist/plugin-sdk/subagent-registry-runtime-1lbDyRzz.js +52 -0
  136. package/dist/plugin-sdk/{tables-BhvloMKN.js → tables-CSqrHsKL.js} +1 -1
  137. package/dist/plugin-sdk/{thinking-URzkT-3p.js → thinking-DOnsR_A8.js} +7 -7
  138. package/dist/plugin-sdk/{tokens-DgNRBwIg.js → tokens-BDr0Z9o3.js} +1 -1
  139. package/dist/plugin-sdk/{tool-images-xpqbP6RR.js → tool-images-eEfOVkzf.js} +2 -2
  140. package/dist/plugin-sdk/web-BLyT64pW.js +56 -0
  141. package/dist/plugin-sdk/{whatsapp-actions-RcZ6vp61.js → whatsapp-actions-xcleMoMv.js} +17 -17
  142. package/dist/plugin-sdk/whatsapp.js +50 -50
  143. package/dist/plugin-sdk/zalo.js +2 -2
  144. package/dist/{plugins-CWkRQYDj.js → plugins-4Rj4OjLY.js} +11 -11
  145. package/dist/{proxy-env-Cq5gdrbj.js → proxy-env-DlmzDx8x.js} +1 -1
  146. package/dist/{plugin-sdk/proxy-fetch-Ch95c_Y2.js → proxy-fetch-B2pEfjbR.js} +1 -1
  147. package/dist/{pw-ai-GcYO6HPE.js → pw-ai-CmphSzHx.js} +1 -1
  148. package/dist/{pw-ai-Cl1Lc7RC.js → pw-ai-DNMjFMqH.js} +14 -14
  149. package/dist/{qmd-manager-BsYsO9Ii.js → qmd-manager-BtIKUaO9.js} +10 -10
  150. package/dist/{query-expansion-DtLc3wjL.js → query-expansion-CX-1fS52.js} +6 -6
  151. package/dist/{plugin-sdk/redact-hp9TOulW.js → redact-COik8ET1.js} +1 -1
  152. package/dist/{run-with-concurrency-D_ZpbgEG.js → run-with-concurrency-BgYfgkXT.js} +4 -4
  153. package/dist/runtime-whatsapp-login.runtime-DUb55byQ.js +13 -0
  154. package/dist/runtime-whatsapp-outbound.runtime-Bii_xSfI.js +22 -0
  155. package/dist/{send-Dx2RkUOZ.js → send-6lz6rNVP.js} +6 -6
  156. package/dist/{send-vmONuVgL.js → send-BHTiZcH3.js} +26 -26
  157. package/dist/{send-Bj776ESJ.js → send-L7gRiwyd.js} +7 -7
  158. package/dist/{send-DcxmcFi_.js → send-PE6cwoTe.js} +8 -8
  159. package/dist/{send-BQERFNyo.js → send-dfu6_rgf.js} +5 -5
  160. package/dist/{session-A4QhBRvH.js → session-D8ImowSs.js} +8 -8
  161. package/dist/{skill-commands-CMzBZKG2.js → skill-commands-DNqJ-kwn.js} +9 -9
  162. package/dist/{skills-CE_iqvM5.js → skills-7ODkHQYp.js} +22 -22
  163. package/dist/slash-commands.runtime-CVw6566g.js +16 -0
  164. package/dist/{slash-dispatch.runtime-Dh053pQK.js → slash-dispatch.runtime-131yup2e.js} +6 -6
  165. package/dist/slash-dispatch.runtime-B9Ygtzi4.js +56 -0
  166. package/dist/slash-skill-commands.runtime-DxZ4z5h6.js +20 -0
  167. package/dist/{store--eR1R_UX.js → store-D89wDcz9.js} +2 -2
  168. package/dist/subagent-registry-runtime-DL1Wv7nA.js +56 -0
  169. package/dist/{subagent-registry-runtime-DSi5mnCQ.js → subagent-registry-runtime-DbSf_Je6.js} +6 -6
  170. package/dist/{subsystem-Di1z8l0Z.js → subsystem-B45WV3qB.js} +14 -14
  171. package/dist/{tables-d739Y1xW.js → tables-mE4cJBN2.js} +1 -1
  172. package/dist/{target-errors-CBI2Ga0y.js → target-errors-mnlwhAjP.js} +2 -2
  173. package/dist/{thinking-DXYisHiZ.js → thinking-BeGmb5k6.js} +7 -7
  174. package/dist/{tokens-DxnY9ui_.js → tokens-q32vI39c.js} +1 -1
  175. package/dist/{tool-images-2cBx1W8h.js → tool-images-RZdHiZcG.js} +2 -2
  176. package/dist/{web-CzWRVmFt.js → web-Btj-e8kN.js} +55 -55
  177. package/dist/{web-1hWJDzNA.js → web-MR9d7KyB.js} +6 -6
  178. package/dist/{whatsapp-actions-iEArE_Ez.js → whatsapp-actions-BHbJJyqw.js} +21 -21
  179. package/dist/{workspace-CUVC6GX1.js → workspace-U-DyR64O.js} +20 -20
  180. package/package.json +6 -5
  181. package/scripts/create-instance.sh +18 -15
  182. package/scripts/install-maca.sh +1 -1
  183. package/ui/index.html +16 -0
  184. package/ui/node_modules/.bin/jiti +21 -0
  185. package/ui/node_modules/.bin/lessc +21 -0
  186. package/ui/node_modules/.bin/marked +21 -0
  187. package/ui/node_modules/.bin/playwright +21 -0
  188. package/ui/node_modules/.bin/sass +21 -0
  189. package/ui/node_modules/.bin/tsx +21 -0
  190. package/ui/node_modules/.bin/vite +21 -0
  191. package/ui/node_modules/.bin/vitest +21 -0
  192. package/ui/node_modules/.bin/yaml +21 -0
  193. package/ui/package.json +27 -0
  194. package/ui/public/apple-touch-icon.png +0 -0
  195. package/ui/public/favicon-32.png +0 -0
  196. package/ui/public/favicon.ico +0 -0
  197. package/ui/public/favicon.svg +22 -0
  198. package/ui/src/css.d.ts +1 -0
  199. package/ui/src/i18n/index.ts +3 -0
  200. package/ui/src/i18n/lib/lit-controller.ts +22 -0
  201. package/ui/src/i18n/lib/registry.ts +64 -0
  202. package/ui/src/i18n/lib/translate.ts +123 -0
  203. package/ui/src/i18n/lib/types.ts +9 -0
  204. package/ui/src/i18n/locales/de.ts +129 -0
  205. package/ui/src/i18n/locales/en.ts +337 -0
  206. package/ui/src/i18n/locales/pt-BR.ts +128 -0
  207. package/ui/src/i18n/locales/zh-CN.ts +330 -0
  208. package/ui/src/i18n/locales/zh-TW.ts +125 -0
  209. package/ui/src/i18n/test/translate.test.ts +56 -0
  210. package/ui/src/main.ts +2 -0
  211. package/ui/src/styles/base.css +385 -0
  212. package/ui/src/styles/chat/grouped.css +300 -0
  213. package/ui/src/styles/chat/layout.css +481 -0
  214. package/ui/src/styles/chat/sidebar.css +117 -0
  215. package/ui/src/styles/chat/text.css +146 -0
  216. package/ui/src/styles/chat/tool-cards.css +202 -0
  217. package/ui/src/styles/chat.css +5 -0
  218. package/ui/src/styles/components.css +2612 -0
  219. package/ui/src/styles/config.css +1658 -0
  220. package/ui/src/styles/layout.css +621 -0
  221. package/ui/src/styles/layout.mobile.css +374 -0
  222. package/ui/src/styles.css +5 -0
  223. package/ui/src/ui/__screenshots__/config-form.browser.test.ts/config-form-renderer-flags-unsupported-unions-1.png +0 -0
  224. package/ui/src/ui/__screenshots__/config-form.browser.test.ts/config-form-renderer-renders-inputs-and-patches-values-1.png +0 -0
  225. package/ui/src/ui/__screenshots__/config-form.browser.test.ts/config-form-renderer-renders-union-literals-as-select-options-1.png +0 -0
  226. package/ui/src/ui/__screenshots__/navigation.browser.test.ts/control-UI-routing-auto-scrolls-chat-history-to-the-latest-message-1.png +0 -0
  227. package/ui/src/ui/app-channels.ts +279 -0
  228. package/ui/src/ui/app-chat.ts +266 -0
  229. package/ui/src/ui/app-defaults.ts +50 -0
  230. package/ui/src/ui/app-events.ts +5 -0
  231. package/ui/src/ui/app-gateway.node.test.ts +229 -0
  232. package/ui/src/ui/app-gateway.ts +349 -0
  233. package/ui/src/ui/app-lifecycle.node.test.ts +44 -0
  234. package/ui/src/ui/app-lifecycle.ts +109 -0
  235. package/ui/src/ui/app-polling.ts +69 -0
  236. package/ui/src/ui/app-render-usage-tab.ts +273 -0
  237. package/ui/src/ui/app-render.helpers.node.test.ts +286 -0
  238. package/ui/src/ui/app-render.helpers.ts +574 -0
  239. package/ui/src/ui/app-render.ts +1168 -0
  240. package/ui/src/ui/app-scroll.test.ts +275 -0
  241. package/ui/src/ui/app-scroll.ts +179 -0
  242. package/ui/src/ui/app-settings.test.ts +70 -0
  243. package/ui/src/ui/app-settings.ts +440 -0
  244. package/ui/src/ui/app-tool-stream.node.test.ts +139 -0
  245. package/ui/src/ui/app-tool-stream.ts +455 -0
  246. package/ui/src/ui/app-view-state.ts +321 -0
  247. package/ui/src/ui/app.ts +621 -0
  248. package/ui/src/ui/assistant-identity.ts +23 -0
  249. package/ui/src/ui/chat/constants.ts +12 -0
  250. package/ui/src/ui/chat/copy-as-markdown.ts +97 -0
  251. package/ui/src/ui/chat/grouped-render.ts +287 -0
  252. package/ui/src/ui/chat/message-extract.test.ts +64 -0
  253. package/ui/src/ui/chat/message-extract.ts +122 -0
  254. package/ui/src/ui/chat/message-normalizer.test.ts +179 -0
  255. package/ui/src/ui/chat/message-normalizer.ts +101 -0
  256. package/ui/src/ui/chat/tool-cards.ts +156 -0
  257. package/ui/src/ui/chat/tool-helpers.test.ts +141 -0
  258. package/ui/src/ui/chat/tool-helpers.ts +37 -0
  259. package/ui/src/ui/chat-event-reload.test.ts +47 -0
  260. package/ui/src/ui/chat-event-reload.ts +16 -0
  261. package/ui/src/ui/chat-markdown.browser.test.ts +37 -0
  262. package/ui/src/ui/components/resizable-divider.ts +110 -0
  263. package/ui/src/ui/config-form.browser.test.ts +443 -0
  264. package/ui/src/ui/controllers/agent-files.ts +126 -0
  265. package/ui/src/ui/controllers/agent-identity.ts +59 -0
  266. package/ui/src/ui/controllers/agent-skills.ts +33 -0
  267. package/ui/src/ui/controllers/agents.test.ts +61 -0
  268. package/ui/src/ui/controllers/agents.ts +64 -0
  269. package/ui/src/ui/controllers/assistant-identity.ts +34 -0
  270. package/ui/src/ui/controllers/channels.ts +94 -0
  271. package/ui/src/ui/controllers/channels.types.ts +15 -0
  272. package/ui/src/ui/controllers/chat.test.ts +568 -0
  273. package/ui/src/ui/controllers/chat.ts +318 -0
  274. package/ui/src/ui/controllers/config/form-coerce.ts +160 -0
  275. package/ui/src/ui/controllers/config/form-utils.node.test.ts +455 -0
  276. package/ui/src/ui/controllers/config/form-utils.ts +90 -0
  277. package/ui/src/ui/controllers/config.test.ts +289 -0
  278. package/ui/src/ui/controllers/config.ts +219 -0
  279. package/ui/src/ui/controllers/control-ui-bootstrap.test.ts +82 -0
  280. package/ui/src/ui/controllers/control-ui-bootstrap.ts +49 -0
  281. package/ui/src/ui/controllers/cron-filters.test.ts +81 -0
  282. package/ui/src/ui/controllers/cron.test.ts +1070 -0
  283. package/ui/src/ui/controllers/cron.ts +921 -0
  284. package/ui/src/ui/controllers/debug.ts +60 -0
  285. package/ui/src/ui/controllers/devices.ts +159 -0
  286. package/ui/src/ui/controllers/exec-approval.ts +100 -0
  287. package/ui/src/ui/controllers/exec-approvals.ts +170 -0
  288. package/ui/src/ui/controllers/logs.ts +147 -0
  289. package/ui/src/ui/controllers/nodes.ts +32 -0
  290. package/ui/src/ui/controllers/presence.ts +37 -0
  291. package/ui/src/ui/controllers/sessions.test.ts +104 -0
  292. package/ui/src/ui/controllers/sessions.ts +127 -0
  293. package/ui/src/ui/controllers/skills.ts +157 -0
  294. package/ui/src/ui/controllers/usage.node.test.ts +181 -0
  295. package/ui/src/ui/controllers/usage.ts +315 -0
  296. package/ui/src/ui/data/moonshot-kimi-k2.ts +45 -0
  297. package/ui/src/ui/device-auth.ts +73 -0
  298. package/ui/src/ui/device-identity.ts +112 -0
  299. package/ui/src/ui/external-link.test.ts +18 -0
  300. package/ui/src/ui/external-link.ts +19 -0
  301. package/ui/src/ui/focus-mode.browser.test.ts +39 -0
  302. package/ui/src/ui/format.test.ts +101 -0
  303. package/ui/src/ui/format.ts +60 -0
  304. package/ui/src/ui/gateway.ts +360 -0
  305. package/ui/src/ui/icons.ts +256 -0
  306. package/ui/src/ui/markdown.test.ts +85 -0
  307. package/ui/src/ui/markdown.ts +139 -0
  308. package/ui/src/ui/navigation.browser.test.ts +188 -0
  309. package/ui/src/ui/navigation.test.ts +189 -0
  310. package/ui/src/ui/navigation.ts +165 -0
  311. package/ui/src/ui/open-external-url.test.ts +108 -0
  312. package/ui/src/ui/open-external-url.ts +73 -0
  313. package/ui/src/ui/presenter.ts +85 -0
  314. package/ui/src/ui/storage.node.test.ts +63 -0
  315. package/ui/src/ui/storage.ts +99 -0
  316. package/ui/src/ui/test-helpers/app-mount.ts +27 -0
  317. package/ui/src/ui/text-direction.test.ts +24 -0
  318. package/ui/src/ui/text-direction.ts +30 -0
  319. package/ui/src/ui/theme-transition.ts +109 -0
  320. package/ui/src/ui/theme.ts +16 -0
  321. package/ui/src/ui/tool-display.ts +159 -0
  322. package/ui/src/ui/types/chat-types.ts +44 -0
  323. package/ui/src/ui/types.ts +627 -0
  324. package/ui/src/ui/ui-types.ts +54 -0
  325. package/ui/src/ui/usage-helpers.node.test.ts +43 -0
  326. package/ui/src/ui/usage-helpers.ts +321 -0
  327. package/ui/src/ui/usage-types.ts +22 -0
  328. package/ui/src/ui/uuid.test.ts +41 -0
  329. package/ui/src/ui/uuid.ts +57 -0
  330. package/ui/src/ui/views/agents-panels-status-files.ts +461 -0
  331. package/ui/src/ui/views/agents-panels-tools-skills.browser.test.ts +102 -0
  332. package/ui/src/ui/views/agents-panels-tools-skills.ts +537 -0
  333. package/ui/src/ui/views/agents-utils.test.ts +100 -0
  334. package/ui/src/ui/views/agents-utils.ts +502 -0
  335. package/ui/src/ui/views/agents.ts +499 -0
  336. package/ui/src/ui/views/channel-config-extras.ts +49 -0
  337. package/ui/src/ui/views/channels.config.ts +155 -0
  338. package/ui/src/ui/views/channels.discord.ts +65 -0
  339. package/ui/src/ui/views/channels.googlechat.ts +79 -0
  340. package/ui/src/ui/views/channels.imessage.ts +65 -0
  341. package/ui/src/ui/views/channels.nostr-profile-form.ts +321 -0
  342. package/ui/src/ui/views/channels.nostr.ts +237 -0
  343. package/ui/src/ui/views/channels.shared.ts +38 -0
  344. package/ui/src/ui/views/channels.signal.ts +69 -0
  345. package/ui/src/ui/views/channels.slack.ts +65 -0
  346. package/ui/src/ui/views/channels.telegram.ts +120 -0
  347. package/ui/src/ui/views/channels.ts +325 -0
  348. package/ui/src/ui/views/channels.types.ts +62 -0
  349. package/ui/src/ui/views/channels.whatsapp.ts +118 -0
  350. package/ui/src/ui/views/chat-image-open.browser.test.ts +70 -0
  351. package/ui/src/ui/views/chat.test.ts +227 -0
  352. package/ui/src/ui/views/chat.ts +616 -0
  353. package/ui/src/ui/views/config-form.analyze.ts +267 -0
  354. package/ui/src/ui/views/config-form.node.ts +1073 -0
  355. package/ui/src/ui/views/config-form.render.ts +478 -0
  356. package/ui/src/ui/views/config-form.search.node.test.ts +69 -0
  357. package/ui/src/ui/views/config-form.shared.ts +96 -0
  358. package/ui/src/ui/views/config-form.ts +4 -0
  359. package/ui/src/ui/views/config-search.node.test.ts +50 -0
  360. package/ui/src/ui/views/config-search.ts +92 -0
  361. package/ui/src/ui/views/config.browser.test.ts +233 -0
  362. package/ui/src/ui/views/config.ts +820 -0
  363. package/ui/src/ui/views/cron.test.ts +741 -0
  364. package/ui/src/ui/views/cron.ts +1758 -0
  365. package/ui/src/ui/views/debug.ts +151 -0
  366. package/ui/src/ui/views/exec-approval.ts +89 -0
  367. package/ui/src/ui/views/gateway-url-confirmation.ts +40 -0
  368. package/ui/src/ui/views/instances.ts +89 -0
  369. package/ui/src/ui/views/logs.ts +155 -0
  370. package/ui/src/ui/views/markdown-sidebar.ts +40 -0
  371. package/ui/src/ui/views/nodes-exec-approvals.ts +617 -0
  372. package/ui/src/ui/views/nodes-shared.ts +67 -0
  373. package/ui/src/ui/views/nodes.ts +485 -0
  374. package/ui/src/ui/views/overview-hints.ts +16 -0
  375. package/ui/src/ui/views/overview.node.test.ts +39 -0
  376. package/ui/src/ui/views/overview.ts +361 -0
  377. package/ui/src/ui/views/sessions.test.ts +81 -0
  378. package/ui/src/ui/views/sessions.ts +321 -0
  379. package/ui/src/ui/views/skills-grouping.ts +40 -0
  380. package/ui/src/ui/views/skills-shared.ts +52 -0
  381. package/ui/src/ui/views/skills.ts +192 -0
  382. package/ui/src/ui/views/usage-metrics.ts +578 -0
  383. package/ui/src/ui/views/usage-query.ts +277 -0
  384. package/ui/src/ui/views/usage-render-details.test.ts +136 -0
  385. package/ui/src/ui/views/usage-render-details.ts +1083 -0
  386. package/ui/src/ui/views/usage-render-overview.ts +796 -0
  387. package/ui/src/ui/views/usage-styles/usageStyles-part1.ts +701 -0
  388. package/ui/src/ui/views/usage-styles/usageStyles-part2.ts +702 -0
  389. package/ui/src/ui/views/usage-styles/usageStyles-part3.ts +551 -0
  390. package/ui/src/ui/views/usage.ts +836 -0
  391. package/ui/src/ui/views/usageStyles.ts +5 -0
  392. package/ui/src/ui/views/usageTypes.ts +105 -0
  393. package/ui/vite.config.ts +43 -0
  394. package/ui/vitest.config.ts +15 -0
  395. package/ui/vitest.node.config.ts +10 -0
  396. package/dist/deliver-runtime-P-G3bPjW.js +0 -36
  397. package/dist/deps-send-discord.runtime-DnbhTFX9.js +0 -26
  398. package/dist/deps-send-imessage.runtime-BOiQ6mDx.js +0 -25
  399. package/dist/deps-send-signal.runtime-CTcl388M.js +0 -24
  400. package/dist/deps-send-slack.runtime-CCqBz4Kg.js +0 -22
  401. package/dist/deps-send-telegram.runtime-DGSKTCpH.js +0 -27
  402. package/dist/deps-send-whatsapp.runtime-CJkTHkah.js +0 -60
  403. package/dist/errors-CCLeFWAg.js +0 -54
  404. package/dist/image-runtime-CVv2ra9J.js +0 -29
  405. package/dist/manager-runtime-BN6VevdC.js +0 -18
  406. package/dist/pi-model-discovery-BGgOlX8N.js +0 -134
  407. package/dist/pi-model-discovery-runtime-Bwmi4Ev8.js +0 -11
  408. package/dist/plugin-sdk/accounts-CJWOBzwB.js +0 -35
  409. package/dist/plugin-sdk/accounts-DP1-L-QS.js +0 -288
  410. package/dist/plugin-sdk/accounts-DZhWlEg3.js +0 -46
  411. package/dist/plugin-sdk/active-listener-CftX5jLD.js +0 -50
  412. package/dist/plugin-sdk/api-key-rotation-BRE4X2tf.js +0 -181
  413. package/dist/plugin-sdk/audio-preflight-DGEUDxxR.js +0 -69
  414. package/dist/plugin-sdk/audio-transcription-runner-DkoPNPYt.js +0 -2176
  415. package/dist/plugin-sdk/audit-membership-runtime-DSBHHw7o.js +0 -58
  416. package/dist/plugin-sdk/channel-activity-F3d0yUwy.js +0 -94
  417. package/dist/plugin-sdk/channel-web-QF7EpjeP.js +0 -2256
  418. package/dist/plugin-sdk/chrome-BXoCyCkY.js +0 -2415
  419. package/dist/plugin-sdk/commands-registry-t7cXBTfN.js +0 -1125
  420. package/dist/plugin-sdk/config-BkEnz2Po.js +0 -17913
  421. package/dist/plugin-sdk/deliver-B6AG_l67.js +0 -1694
  422. package/dist/plugin-sdk/deliver-runtime-BFdqklJM.js +0 -32
  423. package/dist/plugin-sdk/deliver-runtime-D585kJZc.js +0 -32
  424. package/dist/plugin-sdk/deps-send-discord.runtime-DuqpYwU0.js +0 -23
  425. package/dist/plugin-sdk/deps-send-discord.runtime-a_OKY2js.js +0 -23
  426. package/dist/plugin-sdk/deps-send-imessage.runtime-Baxy9TD4.js +0 -22
  427. package/dist/plugin-sdk/deps-send-imessage.runtime-CZ2rS8Lb.js +0 -22
  428. package/dist/plugin-sdk/deps-send-signal.runtime-BdqiWhIh.js +0 -21
  429. package/dist/plugin-sdk/deps-send-signal.runtime-BwXoCrFl.js +0 -21
  430. package/dist/plugin-sdk/deps-send-slack.runtime-04s36qiC.js +0 -19
  431. package/dist/plugin-sdk/deps-send-slack.runtime-CLmKjgso.js +0 -19
  432. package/dist/plugin-sdk/deps-send-telegram.runtime-BKfdBKnZ.js +0 -24
  433. package/dist/plugin-sdk/deps-send-telegram.runtime-LE5tkPvr.js +0 -24
  434. package/dist/plugin-sdk/deps-send-whatsapp.runtime-BOTwkbx_.js +0 -57
  435. package/dist/plugin-sdk/deps-send-whatsapp.runtime-Bz57lobC.js +0 -57
  436. package/dist/plugin-sdk/diagnostic-CsP-lEkI.js +0 -319
  437. package/dist/plugin-sdk/fetch-guard-DETCcJzQ.js +0 -156
  438. package/dist/plugin-sdk/fs-safe-B8y811FR.js +0 -352
  439. package/dist/plugin-sdk/image-DjTEkYZE.js +0 -2310
  440. package/dist/plugin-sdk/image-ops-BSiMpAw4.js +0 -584
  441. package/dist/plugin-sdk/image-runtime-6xPp8m5a.js +0 -25
  442. package/dist/plugin-sdk/image-runtime-B8twoubs.js +0 -25
  443. package/dist/plugin-sdk/ir-DQ7_HbvK.js +0 -1296
  444. package/dist/plugin-sdk/local-roots-BUP4YBmR.js +0 -186
  445. package/dist/plugin-sdk/logger-CZY9KIoY.js +0 -1163
  446. package/dist/plugin-sdk/login-BxEKLlCo.js +0 -57
  447. package/dist/plugin-sdk/login-qr-BQIpMPr9.js +0 -320
  448. package/dist/plugin-sdk/manager-I6KbPihW.js +0 -3917
  449. package/dist/plugin-sdk/manager-runtime-CFfYYWIQ.js +0 -15
  450. package/dist/plugin-sdk/manager-runtime-CMeLwose.js +0 -15
  451. package/dist/plugin-sdk/outbound-NS6UHnB6.js +0 -212
  452. package/dist/plugin-sdk/outbound-attachment-Dy6fyf6H.js +0 -19
  453. package/dist/plugin-sdk/path-alias-guards-DBjLbIX_.js +0 -43
  454. package/dist/plugin-sdk/paths-vTM3Lh3X.js +0 -166
  455. package/dist/plugin-sdk/pi-embedded-helpers-1R1gu7eX.js +0 -9627
  456. package/dist/plugin-sdk/pi-model-discovery-runtime-D8CJhtJY.js +0 -8
  457. package/dist/plugin-sdk/pi-model-discovery-runtime-Do9o-dUd.js +0 -8
  458. package/dist/plugin-sdk/pi-tools.before-tool-call.runtime-D4sFsIks.js +0 -354
  459. package/dist/plugin-sdk/plugins-DeBZB9l_.js +0 -864
  460. package/dist/plugin-sdk/pw-ai-DEOmCSSC.js +0 -1938
  461. package/dist/plugin-sdk/qmd-manager-HyYKoEch.js +0 -1448
  462. package/dist/plugin-sdk/query-expansion-CeyKUeDW.js +0 -1011
  463. package/dist/plugin-sdk/reply-DAo_Jt8K.js +0 -97916
  464. package/dist/plugin-sdk/resolve-outbound-target-B42qgQS9.js +0 -40
  465. package/dist/plugin-sdk/run-with-concurrency-Bt_ks0Qa.js +0 -1994
  466. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-B6W989eF.js +0 -10
  467. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-SkO91TZH.js +0 -10
  468. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-B0VWK5hm.js +0 -19
  469. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-c_GDFy37.js +0 -19
  470. package/dist/plugin-sdk/send-CQpMudwO.js +0 -2587
  471. package/dist/plugin-sdk/send-DQHLzVyO.js +0 -414
  472. package/dist/plugin-sdk/send-DTB24bEF.js +0 -3135
  473. package/dist/plugin-sdk/send-DfHadjZ_.js +0 -503
  474. package/dist/plugin-sdk/send-XXlW2iny.js +0 -540
  475. package/dist/plugin-sdk/session-6TF6MyaC.js +0 -169
  476. package/dist/plugin-sdk/skill-commands-CkGeFUMl.js +0 -342
  477. package/dist/plugin-sdk/skills-CBkHBYPq.js +0 -1428
  478. package/dist/plugin-sdk/slash-commands.runtime-CxliuGaP.js +0 -13
  479. package/dist/plugin-sdk/slash-commands.runtime-DS6vCNSL.js +0 -13
  480. package/dist/plugin-sdk/slash-dispatch.runtime-BXrxb2wd.js +0 -52
  481. package/dist/plugin-sdk/slash-dispatch.runtime-DFaeYlJQ.js +0 -52
  482. package/dist/plugin-sdk/slash-skill-commands.runtime-0M0OLCxq.js +0 -16
  483. package/dist/plugin-sdk/slash-skill-commands.runtime-Bd6qQ2oT.js +0 -16
  484. package/dist/plugin-sdk/ssrf-cFtplYtS.js +0 -202
  485. package/dist/plugin-sdk/store-5nyxY3WU.js +0 -81
  486. package/dist/plugin-sdk/subagent-registry-runtime-1uwQbuXj.js +0 -52
  487. package/dist/plugin-sdk/subagent-registry-runtime-DCtmDwna.js +0 -52
  488. package/dist/plugin-sdk/tables-C47P4GTN.js +0 -55
  489. package/dist/plugin-sdk/target-errors-Blia4S69.js +0 -195
  490. package/dist/plugin-sdk/thinking-Bo2eosVa.js +0 -1206
  491. package/dist/plugin-sdk/tokens-B1PW5Ayy.js +0 -52
  492. package/dist/plugin-sdk/tool-images-Gk_-0y2N.js +0 -274
  493. package/dist/plugin-sdk/web-B74yhL2N.js +0 -56
  494. package/dist/plugin-sdk/web-CVxZbXyH.js +0 -56
  495. package/dist/plugin-sdk/whatsapp-actions-Bw0H9g-n.js +0 -80
  496. package/dist/proxy-fetch-CCjEYbFm.js +0 -38
  497. package/dist/redact-ClbcYG1J.js +0 -319
  498. package/dist/runtime-whatsapp-login.runtime-IeylZEl4.js +0 -13
  499. package/dist/runtime-whatsapp-outbound.runtime-ClBRuLsq.js +0 -22
  500. package/dist/slash-commands.runtime-Cpn2tYW4.js +0 -16
  501. package/dist/slash-dispatch.runtime-DoBAQBU5.js +0 -56
  502. package/dist/slash-skill-commands.runtime-DKMvvdDW.js +0 -20
  503. package/dist/subagent-registry-runtime-ppWS3tVu.js +0 -56
@@ -0,0 +1,315 @@
1
+ import type { GatewayBrowserClient } from "../gateway.ts";
2
+ import type { SessionsUsageResult, CostUsageSummary, SessionUsageTimeSeries } from "../types.ts";
3
+ import type { SessionLogEntry } from "../views/usage.ts";
4
+
5
+ export type UsageState = {
6
+ client: GatewayBrowserClient | null;
7
+ connected: boolean;
8
+ usageLoading: boolean;
9
+ usageResult: SessionsUsageResult | null;
10
+ usageCostSummary: CostUsageSummary | null;
11
+ usageError: string | null;
12
+ usageStartDate: string;
13
+ usageEndDate: string;
14
+ usageSelectedSessions: string[];
15
+ usageSelectedDays: string[];
16
+ usageTimeSeries: SessionUsageTimeSeries | null;
17
+ usageTimeSeriesLoading: boolean;
18
+ usageTimeSeriesCursorStart: number | null;
19
+ usageTimeSeriesCursorEnd: number | null;
20
+ usageSessionLogs: SessionLogEntry[] | null;
21
+ usageSessionLogsLoading: boolean;
22
+ usageTimeZone: "local" | "utc";
23
+ settings?: { gatewayUrl?: string };
24
+ };
25
+
26
+ type DateInterpretationMode = "utc" | "gateway" | "specific";
27
+
28
+ type UsageDateInterpretationParams = {
29
+ mode: DateInterpretationMode;
30
+ utcOffset?: string;
31
+ };
32
+
33
+ const LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY = "openclaw.control.usage.date-params.v1";
34
+ const LEGACY_USAGE_DATE_PARAMS_DEFAULT_GATEWAY_KEY = "__default__";
35
+ const LEGACY_USAGE_DATE_PARAMS_MODE_RE = /unexpected property ['"]mode['"]/i;
36
+ const LEGACY_USAGE_DATE_PARAMS_OFFSET_RE = /unexpected property ['"]utcoffset['"]/i;
37
+ const LEGACY_USAGE_DATE_PARAMS_INVALID_RE = /invalid sessions\.usage params/i;
38
+
39
+ let legacyUsageDateParamsCache: Set<string> | null = null;
40
+
41
+ function getLocalStorage(): Storage | null {
42
+ // Support browser runtime and node tests (when localStorage is stubbed globally).
43
+ if (typeof window !== "undefined" && window.localStorage) {
44
+ return window.localStorage;
45
+ }
46
+ if (typeof localStorage !== "undefined") {
47
+ return localStorage;
48
+ }
49
+ return null;
50
+ }
51
+
52
+ function loadLegacyUsageDateParamsCache(): Set<string> {
53
+ const storage = getLocalStorage();
54
+ if (!storage) {
55
+ return new Set<string>();
56
+ }
57
+ try {
58
+ const raw = storage.getItem(LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY);
59
+ if (!raw) {
60
+ return new Set<string>();
61
+ }
62
+ const parsed = JSON.parse(raw) as { unsupportedGatewayKeys?: unknown } | null;
63
+ if (!parsed || !Array.isArray(parsed.unsupportedGatewayKeys)) {
64
+ return new Set<string>();
65
+ }
66
+ return new Set(
67
+ parsed.unsupportedGatewayKeys
68
+ .filter((entry): entry is string => typeof entry === "string")
69
+ .map((entry) => entry.trim())
70
+ .filter(Boolean),
71
+ );
72
+ } catch {
73
+ return new Set<string>();
74
+ }
75
+ }
76
+
77
+ function persistLegacyUsageDateParamsCache(cache: Set<string>) {
78
+ const storage = getLocalStorage();
79
+ if (!storage) {
80
+ return;
81
+ }
82
+ try {
83
+ storage.setItem(
84
+ LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY,
85
+ JSON.stringify({ unsupportedGatewayKeys: Array.from(cache) }),
86
+ );
87
+ } catch {
88
+ // ignore quota/private-mode failures
89
+ }
90
+ }
91
+
92
+ function getLegacyUsageDateParamsCache(): Set<string> {
93
+ if (!legacyUsageDateParamsCache) {
94
+ legacyUsageDateParamsCache = loadLegacyUsageDateParamsCache();
95
+ }
96
+ return legacyUsageDateParamsCache;
97
+ }
98
+
99
+ function normalizeGatewayCompatibilityKey(gatewayUrl?: string): string {
100
+ const trimmed = gatewayUrl?.trim();
101
+ if (!trimmed) {
102
+ return LEGACY_USAGE_DATE_PARAMS_DEFAULT_GATEWAY_KEY;
103
+ }
104
+ try {
105
+ const parsed = new URL(trimmed);
106
+ const pathname = parsed.pathname === "/" ? "" : parsed.pathname;
107
+ return `${parsed.protocol}//${parsed.host}${pathname}`.toLowerCase();
108
+ } catch {
109
+ return trimmed.toLowerCase();
110
+ }
111
+ }
112
+
113
+ function resolveGatewayCompatibilityKey(state: UsageState): string {
114
+ return normalizeGatewayCompatibilityKey(state.settings?.gatewayUrl);
115
+ }
116
+
117
+ function shouldSendLegacyDateInterpretation(state: UsageState): boolean {
118
+ return !getLegacyUsageDateParamsCache().has(resolveGatewayCompatibilityKey(state));
119
+ }
120
+
121
+ function rememberLegacyDateInterpretation(state: UsageState) {
122
+ const cache = getLegacyUsageDateParamsCache();
123
+ cache.add(resolveGatewayCompatibilityKey(state));
124
+ persistLegacyUsageDateParamsCache(cache);
125
+ }
126
+
127
+ function isLegacyDateInterpretationUnsupportedError(err: unknown): boolean {
128
+ const message = toErrorMessage(err);
129
+ return (
130
+ LEGACY_USAGE_DATE_PARAMS_INVALID_RE.test(message) &&
131
+ (LEGACY_USAGE_DATE_PARAMS_MODE_RE.test(message) ||
132
+ LEGACY_USAGE_DATE_PARAMS_OFFSET_RE.test(message))
133
+ );
134
+ }
135
+
136
+ const formatUtcOffset = (timezoneOffsetMinutes: number): string => {
137
+ // `Date#getTimezoneOffset()` is minutes to add to local time to reach UTC.
138
+ // Convert to UTC±H[:MM] where positive means east of UTC.
139
+ const offsetFromUtcMinutes = -timezoneOffsetMinutes;
140
+ const sign = offsetFromUtcMinutes >= 0 ? "+" : "-";
141
+ const absMinutes = Math.abs(offsetFromUtcMinutes);
142
+ const hours = Math.floor(absMinutes / 60);
143
+ const minutes = absMinutes % 60;
144
+ return minutes === 0
145
+ ? `UTC${sign}${hours}`
146
+ : `UTC${sign}${hours}:${minutes.toString().padStart(2, "0")}`;
147
+ };
148
+
149
+ const buildDateInterpretationParams = (
150
+ timeZone: "local" | "utc",
151
+ includeDateInterpretation: boolean,
152
+ ): UsageDateInterpretationParams | undefined => {
153
+ if (!includeDateInterpretation) {
154
+ return undefined;
155
+ }
156
+ if (timeZone === "utc") {
157
+ return { mode: "utc" };
158
+ }
159
+ return {
160
+ mode: "specific",
161
+ utcOffset: formatUtcOffset(new Date().getTimezoneOffset()),
162
+ };
163
+ };
164
+
165
+ function toErrorMessage(err: unknown): string {
166
+ if (typeof err === "string") {
167
+ return err;
168
+ }
169
+ if (err instanceof Error && typeof err.message === "string" && err.message.trim()) {
170
+ return err.message;
171
+ }
172
+ if (err && typeof err === "object") {
173
+ try {
174
+ const serialized = JSON.stringify(err);
175
+ if (serialized) {
176
+ return serialized;
177
+ }
178
+ } catch {
179
+ // ignore
180
+ }
181
+ }
182
+ return "request failed";
183
+ }
184
+
185
+ export async function loadUsage(
186
+ state: UsageState,
187
+ overrides?: {
188
+ startDate?: string;
189
+ endDate?: string;
190
+ },
191
+ ) {
192
+ // Capture client for TS18047 work around on it being possibly null
193
+ const client = state.client;
194
+ if (!client || !state.connected) {
195
+ return;
196
+ }
197
+ if (state.usageLoading) {
198
+ return;
199
+ }
200
+ state.usageLoading = true;
201
+ state.usageError = null;
202
+ try {
203
+ const startDate = overrides?.startDate ?? state.usageStartDate;
204
+ const endDate = overrides?.endDate ?? state.usageEndDate;
205
+ const runUsageRequests = async (includeDateInterpretation: boolean) => {
206
+ const dateInterpretation = buildDateInterpretationParams(
207
+ state.usageTimeZone,
208
+ includeDateInterpretation,
209
+ );
210
+ return await Promise.all([
211
+ client.request("sessions.usage", {
212
+ startDate,
213
+ endDate,
214
+ ...dateInterpretation,
215
+ limit: 1000, // Cap at 1000 sessions
216
+ includeContextWeight: true,
217
+ }),
218
+ client.request("usage.cost", {
219
+ startDate,
220
+ endDate,
221
+ ...dateInterpretation,
222
+ }),
223
+ ]);
224
+ };
225
+
226
+ const applyUsageResults = (sessionsRes: unknown, costRes: unknown) => {
227
+ if (sessionsRes) {
228
+ state.usageResult = sessionsRes as SessionsUsageResult;
229
+ }
230
+ if (costRes) {
231
+ state.usageCostSummary = costRes as CostUsageSummary;
232
+ }
233
+ };
234
+
235
+ const includeDateInterpretation = shouldSendLegacyDateInterpretation(state);
236
+ try {
237
+ const [sessionsRes, costRes] = await runUsageRequests(includeDateInterpretation);
238
+ applyUsageResults(sessionsRes, costRes);
239
+ } catch (err) {
240
+ if (includeDateInterpretation && isLegacyDateInterpretationUnsupportedError(err)) {
241
+ // Older gateways reject `mode`/`utcOffset` in `sessions.usage`.
242
+ // Remember this per gateway and retry once without those fields.
243
+ rememberLegacyDateInterpretation(state);
244
+ const [sessionsRes, costRes] = await runUsageRequests(false);
245
+ applyUsageResults(sessionsRes, costRes);
246
+ } else {
247
+ throw err;
248
+ }
249
+ }
250
+ } catch (err) {
251
+ state.usageError = toErrorMessage(err);
252
+ } finally {
253
+ state.usageLoading = false;
254
+ }
255
+ }
256
+
257
+ export const __test = {
258
+ formatUtcOffset,
259
+ buildDateInterpretationParams,
260
+ toErrorMessage,
261
+ isLegacyDateInterpretationUnsupportedError,
262
+ normalizeGatewayCompatibilityKey,
263
+ shouldSendLegacyDateInterpretation,
264
+ rememberLegacyDateInterpretation,
265
+ resetLegacyUsageDateParamsCache: () => {
266
+ legacyUsageDateParamsCache = null;
267
+ },
268
+ };
269
+
270
+ export async function loadSessionTimeSeries(state: UsageState, sessionKey: string) {
271
+ if (!state.client || !state.connected) {
272
+ return;
273
+ }
274
+ if (state.usageTimeSeriesLoading) {
275
+ return;
276
+ }
277
+ state.usageTimeSeriesLoading = true;
278
+ state.usageTimeSeries = null;
279
+ try {
280
+ const res = await state.client.request("sessions.usage.timeseries", { key: sessionKey });
281
+ if (res) {
282
+ state.usageTimeSeries = res as SessionUsageTimeSeries;
283
+ }
284
+ } catch {
285
+ // Silently fail - time series is optional
286
+ state.usageTimeSeries = null;
287
+ } finally {
288
+ state.usageTimeSeriesLoading = false;
289
+ }
290
+ }
291
+
292
+ export async function loadSessionLogs(state: UsageState, sessionKey: string) {
293
+ if (!state.client || !state.connected) {
294
+ return;
295
+ }
296
+ if (state.usageSessionLogsLoading) {
297
+ return;
298
+ }
299
+ state.usageSessionLogsLoading = true;
300
+ state.usageSessionLogs = null;
301
+ try {
302
+ const res = await state.client.request("sessions.usage.logs", {
303
+ key: sessionKey,
304
+ limit: 1000,
305
+ });
306
+ if (res && Array.isArray((res as { logs: SessionLogEntry[] }).logs)) {
307
+ state.usageSessionLogs = (res as { logs: SessionLogEntry[] }).logs;
308
+ }
309
+ } catch {
310
+ // Silently fail - logs are optional
311
+ state.usageSessionLogs = null;
312
+ } finally {
313
+ state.usageSessionLogsLoading = false;
314
+ }
315
+ }
@@ -0,0 +1,45 @@
1
+ export const MOONSHOT_KIMI_K2_DEFAULT_ID = "kimi-k2.5";
2
+ export const MOONSHOT_KIMI_K2_CONTEXT_WINDOW = 256000;
3
+ export const MOONSHOT_KIMI_K2_MAX_TOKENS = 8192;
4
+ export const MOONSHOT_KIMI_K2_INPUT = ["text"] as const;
5
+ export const MOONSHOT_KIMI_K2_COST = {
6
+ input: 0,
7
+ output: 0,
8
+ cacheRead: 0,
9
+ cacheWrite: 0,
10
+ } as const;
11
+
12
+ export const MOONSHOT_KIMI_K2_MODELS = [
13
+ {
14
+ id: "kimi-k2.5",
15
+ name: "Kimi K2.5",
16
+ alias: "Kimi K2.5",
17
+ reasoning: false,
18
+ },
19
+ {
20
+ id: "kimi-k2-0905-preview",
21
+ name: "Kimi K2 0905 Preview",
22
+ alias: "Kimi K2",
23
+ reasoning: false,
24
+ },
25
+ {
26
+ id: "kimi-k2-turbo-preview",
27
+ name: "Kimi K2 Turbo",
28
+ alias: "Kimi K2 Turbo",
29
+ reasoning: false,
30
+ },
31
+ {
32
+ id: "kimi-k2-thinking",
33
+ name: "Kimi K2 Thinking",
34
+ alias: "Kimi K2 Thinking",
35
+ reasoning: true,
36
+ },
37
+ {
38
+ id: "kimi-k2-thinking-turbo",
39
+ name: "Kimi K2 Thinking Turbo",
40
+ alias: "Kimi K2 Thinking Turbo",
41
+ reasoning: true,
42
+ },
43
+ ] as const;
44
+
45
+ export type MoonshotKimiK2Model = (typeof MOONSHOT_KIMI_K2_MODELS)[number];
@@ -0,0 +1,73 @@
1
+ import {
2
+ clearDeviceAuthTokenFromStore,
3
+ type DeviceAuthEntry,
4
+ loadDeviceAuthTokenFromStore,
5
+ storeDeviceAuthTokenInStore,
6
+ } from "../../../src/shared/device-auth-store.js";
7
+ import type { DeviceAuthStore } from "../../../src/shared/device-auth.js";
8
+
9
+ const STORAGE_KEY = "openclaw.device.auth.v1";
10
+
11
+ function readStore(): DeviceAuthStore | null {
12
+ try {
13
+ const raw = window.localStorage.getItem(STORAGE_KEY);
14
+ if (!raw) {
15
+ return null;
16
+ }
17
+ const parsed = JSON.parse(raw) as DeviceAuthStore;
18
+ if (!parsed || parsed.version !== 1) {
19
+ return null;
20
+ }
21
+ if (!parsed.deviceId || typeof parsed.deviceId !== "string") {
22
+ return null;
23
+ }
24
+ if (!parsed.tokens || typeof parsed.tokens !== "object") {
25
+ return null;
26
+ }
27
+ return parsed;
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ function writeStore(store: DeviceAuthStore) {
34
+ try {
35
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(store));
36
+ } catch {
37
+ // best-effort
38
+ }
39
+ }
40
+
41
+ export function loadDeviceAuthToken(params: {
42
+ deviceId: string;
43
+ role: string;
44
+ }): DeviceAuthEntry | null {
45
+ return loadDeviceAuthTokenFromStore({
46
+ adapter: { readStore, writeStore },
47
+ deviceId: params.deviceId,
48
+ role: params.role,
49
+ });
50
+ }
51
+
52
+ export function storeDeviceAuthToken(params: {
53
+ deviceId: string;
54
+ role: string;
55
+ token: string;
56
+ scopes?: string[];
57
+ }): DeviceAuthEntry {
58
+ return storeDeviceAuthTokenInStore({
59
+ adapter: { readStore, writeStore },
60
+ deviceId: params.deviceId,
61
+ role: params.role,
62
+ token: params.token,
63
+ scopes: params.scopes,
64
+ });
65
+ }
66
+
67
+ export function clearDeviceAuthToken(params: { deviceId: string; role: string }) {
68
+ clearDeviceAuthTokenFromStore({
69
+ adapter: { readStore, writeStore },
70
+ deviceId: params.deviceId,
71
+ role: params.role,
72
+ });
73
+ }
@@ -0,0 +1,112 @@
1
+ import { getPublicKeyAsync, signAsync, utils } from "@noble/ed25519";
2
+
3
+ type StoredIdentity = {
4
+ version: 1;
5
+ deviceId: string;
6
+ publicKey: string;
7
+ privateKey: string;
8
+ createdAtMs: number;
9
+ };
10
+
11
+ export type DeviceIdentity = {
12
+ deviceId: string;
13
+ publicKey: string;
14
+ privateKey: string;
15
+ };
16
+
17
+ const STORAGE_KEY = "openclaw-device-identity-v1";
18
+
19
+ function base64UrlEncode(bytes: Uint8Array): string {
20
+ let binary = "";
21
+ for (const byte of bytes) {
22
+ binary += String.fromCharCode(byte);
23
+ }
24
+ return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/g, "");
25
+ }
26
+
27
+ function base64UrlDecode(input: string): Uint8Array {
28
+ const normalized = input.replaceAll("-", "+").replaceAll("_", "/");
29
+ const padded = normalized + "=".repeat((4 - (normalized.length % 4)) % 4);
30
+ const binary = atob(padded);
31
+ const out = new Uint8Array(binary.length);
32
+ for (let i = 0; i < binary.length; i += 1) {
33
+ out[i] = binary.charCodeAt(i);
34
+ }
35
+ return out;
36
+ }
37
+
38
+ function bytesToHex(bytes: Uint8Array): string {
39
+ return Array.from(bytes)
40
+ .map((b) => b.toString(16).padStart(2, "0"))
41
+ .join("");
42
+ }
43
+
44
+ async function fingerprintPublicKey(publicKey: Uint8Array): Promise<string> {
45
+ const hash = await crypto.subtle.digest("SHA-256", publicKey.slice().buffer);
46
+ return bytesToHex(new Uint8Array(hash));
47
+ }
48
+
49
+ async function generateIdentity(): Promise<DeviceIdentity> {
50
+ const privateKey = utils.randomSecretKey();
51
+ const publicKey = await getPublicKeyAsync(privateKey);
52
+ const deviceId = await fingerprintPublicKey(publicKey);
53
+ return {
54
+ deviceId,
55
+ publicKey: base64UrlEncode(publicKey),
56
+ privateKey: base64UrlEncode(privateKey),
57
+ };
58
+ }
59
+
60
+ export async function loadOrCreateDeviceIdentity(): Promise<DeviceIdentity> {
61
+ try {
62
+ const raw = localStorage.getItem(STORAGE_KEY);
63
+ if (raw) {
64
+ const parsed = JSON.parse(raw) as StoredIdentity;
65
+ if (
66
+ parsed?.version === 1 &&
67
+ typeof parsed.deviceId === "string" &&
68
+ typeof parsed.publicKey === "string" &&
69
+ typeof parsed.privateKey === "string"
70
+ ) {
71
+ const derivedId = await fingerprintPublicKey(base64UrlDecode(parsed.publicKey));
72
+ if (derivedId !== parsed.deviceId) {
73
+ const updated: StoredIdentity = {
74
+ ...parsed,
75
+ deviceId: derivedId,
76
+ };
77
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
78
+ return {
79
+ deviceId: derivedId,
80
+ publicKey: parsed.publicKey,
81
+ privateKey: parsed.privateKey,
82
+ };
83
+ }
84
+ return {
85
+ deviceId: parsed.deviceId,
86
+ publicKey: parsed.publicKey,
87
+ privateKey: parsed.privateKey,
88
+ };
89
+ }
90
+ }
91
+ } catch {
92
+ // fall through to regenerate
93
+ }
94
+
95
+ const identity = await generateIdentity();
96
+ const stored: StoredIdentity = {
97
+ version: 1,
98
+ deviceId: identity.deviceId,
99
+ publicKey: identity.publicKey,
100
+ privateKey: identity.privateKey,
101
+ createdAtMs: Date.now(),
102
+ };
103
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(stored));
104
+ return identity;
105
+ }
106
+
107
+ export async function signDevicePayload(privateKeyBase64Url: string, payload: string) {
108
+ const key = base64UrlDecode(privateKeyBase64Url);
109
+ const data = new TextEncoder().encode(payload);
110
+ const sig = await signAsync(data, key);
111
+ return base64UrlEncode(sig);
112
+ }
@@ -0,0 +1,18 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildExternalLinkRel } from "./external-link.ts";
3
+
4
+ describe("buildExternalLinkRel", () => {
5
+ it("always includes required security tokens", () => {
6
+ expect(buildExternalLinkRel()).toBe("noopener noreferrer");
7
+ });
8
+
9
+ it("preserves extra rel tokens while deduping required ones", () => {
10
+ expect(buildExternalLinkRel("noreferrer nofollow NOOPENER")).toBe(
11
+ "noopener noreferrer nofollow",
12
+ );
13
+ });
14
+
15
+ it("ignores whitespace-only rel input", () => {
16
+ expect(buildExternalLinkRel(" ")).toBe("noopener noreferrer");
17
+ });
18
+ });
@@ -0,0 +1,19 @@
1
+ const REQUIRED_EXTERNAL_REL_TOKENS = ["noopener", "noreferrer"] as const;
2
+
3
+ export const EXTERNAL_LINK_TARGET = "_blank";
4
+
5
+ export function buildExternalLinkRel(currentRel?: string): string {
6
+ const extraTokens: string[] = [];
7
+ const seen = new Set<string>(REQUIRED_EXTERNAL_REL_TOKENS);
8
+
9
+ for (const rawToken of (currentRel ?? "").split(/\s+/)) {
10
+ const token = rawToken.trim().toLowerCase();
11
+ if (!token || seen.has(token)) {
12
+ continue;
13
+ }
14
+ seen.add(token);
15
+ extraTokens.push(token);
16
+ }
17
+
18
+ return [...REQUIRED_EXTERNAL_REL_TOKENS, ...extraTokens].join(" ");
19
+ }
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { mountApp, registerAppMountHooks } from "./test-helpers/app-mount.ts";
3
+
4
+ registerAppMountHooks();
5
+
6
+ describe("chat focus mode", () => {
7
+ it("collapses header + sidebar on chat tab only", async () => {
8
+ const app = mountApp("/chat");
9
+ await app.updateComplete;
10
+
11
+ const shell = app.querySelector(".shell");
12
+ expect(shell).not.toBeNull();
13
+ expect(shell?.classList.contains("shell--chat-focus")).toBe(false);
14
+
15
+ const toggle = app.querySelector<HTMLButtonElement>('button[title^="Toggle focus mode"]');
16
+ expect(toggle).not.toBeNull();
17
+ toggle?.click();
18
+
19
+ await app.updateComplete;
20
+ expect(shell?.classList.contains("shell--chat-focus")).toBe(true);
21
+
22
+ const link = app.querySelector<HTMLAnchorElement>('a.nav-item[href="/channels"]');
23
+ expect(link).not.toBeNull();
24
+ link?.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true, button: 0 }));
25
+
26
+ await app.updateComplete;
27
+ expect(app.tab).toBe("channels");
28
+ expect(shell?.classList.contains("shell--chat-focus")).toBe(false);
29
+
30
+ const chatLink = app.querySelector<HTMLAnchorElement>('a.nav-item[href="/chat"]');
31
+ chatLink?.dispatchEvent(
32
+ new MouseEvent("click", { bubbles: true, cancelable: true, button: 0 }),
33
+ );
34
+
35
+ await app.updateComplete;
36
+ expect(app.tab).toBe("chat");
37
+ expect(shell?.classList.contains("shell--chat-focus")).toBe(true);
38
+ });
39
+ });