wednesdayai 0.5.1-dev.21 → 0.5.1-dev.23
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.
- package/dist/{acp-cli-BmhbACSZ.js → acp-cli-D7pT9Bao.js} +2 -2
- package/dist/{acp-cli-Dblp7m2Z.js → acp-cli-DFqeyWQJ.js} +2 -2
- package/dist/{agent-scope-CeLIuOpq.js → agent-scope-DCgndASv.js} +3 -3
- package/dist/{agent-turn-enqueue-IiwTs8II.js → agent-turn-enqueue-B30hT0x-.js} +5 -5
- package/dist/{agent-turn-enqueue-DK8QApSV.js → agent-turn-enqueue-CI-A0Cuo.js} +5 -5
- package/dist/{agent-turn-execute-3cc3W1hp.js → agent-turn-execute-CFwfJKy2.js} +39 -37
- package/dist/{agent-turn-recovery-adapter-BkoX8bcd.js → agent-turn-recovery-adapter-DWGzJ2s-.js} +1 -1
- package/dist/{agent-turn-recovery-adapter-B909sIMD.js → agent-turn-recovery-adapter-TKOtg3bA.js} +1 -1
- package/dist/{agent-turn-runner-DUKUxZcn.js → agent-turn-runner-12Exv9CB.js} +1 -1
- package/dist/{agent-turn-runner-C3Buntbu.js → agent-turn-runner-Btk5sBH0.js} +1 -1
- package/dist/{agent-turn-runner-BglHs_p0.js → agent-turn-runner-CpsTt9uv.js} +6 -6
- package/dist/{agent-turn-runner-BTBy1i8Z.js → agent-turn-runner-XPJ75h7l.js} +4 -4
- package/dist/{agents-DJ_ssbNO.js → agents-BcHFvOHE.js} +6 -6
- package/dist/{agents.config-D-yD07v8.js → agents.config-C_4HsmOy.js} +1 -1
- package/dist/{agents.config-BcBusEWj.js → agents.config-DwW88u5f.js} +1 -1
- package/dist/{api-key-rotation-DQY1fynd.js → api-key-rotation-dv2YbGr8.js} +2 -2
- package/dist/{audio-preflight-DMq3PMsW.js → audio-preflight-Cv1eSuSU.js} +6 -6
- package/dist/{audio-preflight-DZdCHEnu.js → audio-preflight-DGyrDCsN.js} +7 -7
- package/dist/{audio-preflight-C0VnQEEN.js → audio-preflight-DKR8c6Qw.js} +7 -7
- package/dist/{audio-preflight-BTQmKMCZ.js → audio-preflight-DnuyzcBj.js} +29 -29
- package/dist/{audio-transcription-runner-C_DRSo6Z.js → audio-transcription-runner-BnmmtXUh.js} +1 -1
- package/dist/{audio-transcription-runner-C9Ld3zXw.js → audio-transcription-runner-CRxHRlMX.js} +1 -1
- package/dist/{audio-transcription-runner-BeC-knyy.js → audio-transcription-runner-DZa96tEn.js} +26 -26
- package/dist/{audio-transcription-runner-9GXPmTBK.js → audio-transcription-runner-DsqwKJ49.js} +1 -1
- package/dist/{audit-CmZAI3_9.js → audit-Dk69ufby.js} +6 -6
- package/dist/{audit-CH1D3iBG.js → audit-DkY9yUsn.js} +6 -6
- package/dist/{auth-choice-dWGUA_8g.js → auth-choice-BkWEr-Pe.js} +2 -2
- package/dist/{auth-choice-CEOnAk7f.js → auth-choice-kkL-bZp9.js} +2 -2
- package/dist/{banner-DWHiEk1H.js → banner-DOesQn79.js} +1 -1
- package/dist/{browser-cli-CfoUYSxy.js → browser-cli-Cy6LJQhv.js} +3 -3
- package/dist/{browser-cli-P7SKIutx.js → browser-cli-Mbn8pYZZ.js} +3 -3
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +60 -60
- package/dist/bundled/bootstrap-extra-files/handler.js +6 -6
- package/dist/bundled/command-logger/handler.js +2 -2
- package/dist/bundled/session-journal/handler.js +60 -60
- package/dist/bundled/session-memory/handler.js +60 -60
- package/dist/{call-xB0MOQUF.js → call-B1surxJJ.js} +3 -1
- package/dist/{call-CUY8VoHh.js → call-CsmPnXmY.js} +3 -1
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-activity-DoBHFita.js → channel-activity-Kn1_ykXE.js} +3 -3
- package/dist/{channel-options-DCKEbe7Z.js → channel-options-Am9ZvwKB.js} +1 -1
- package/dist/{channel-options-DfjYj7oi.js → channel-options-TBxP7o5K.js} +1 -1
- package/dist/{channels-cli-DrcS29Pk.js → channels-cli-3ihKjjtq.js} +33 -33
- package/dist/{channels-cli-DHvavLcJ.js → channels-cli-CGWblqhQ.js} +32 -32
- package/dist/{chat-content-hesA0q3j.js → chat-content-B_nVIplC.js} +4 -4
- package/dist/{chat-content-BZeW5ciD.js → chat-content-C7_U4hJq.js} +34 -34
- package/dist/{chrome-DZ6ejAmp.js → chrome-Bukcguhv.js} +23 -23
- package/dist/{chrome-C2xK35m5.js → chrome-DNh94Pjx.js} +8 -8
- package/dist/{chunk-DOckmOyp.js → chunk-CEygNI3g.js} +3 -3
- package/dist/{clawbot-cli-CLz6KuWz.js → clawbot-cli-BRicu1s1.js} +5 -5
- package/dist/{clawbot-cli-CzDwX-gU.js → clawbot-cli-Be313PY0.js} +5 -5
- package/dist/cli/daemon-cli.js +1 -1
- package/dist/{cli-D2tBPn1z.js → cli-BFoMFw-E.js} +28 -28
- package/dist/{cli-DBqTAu56.js → cli-BcIWokUA.js} +29 -29
- package/dist/{client-CIDXfGgo.js → client-DA6hPHoC.js} +4 -1
- package/dist/{client-BCYzc-y7.js → client-MNdGt1bC.js} +4 -1
- package/dist/{client-profiles-BaJqyqVb.js → client-profiles-BkQpgWwd.js} +1 -1
- package/dist/{client-profiles-DGW7rrdk.js → client-profiles-CZqoxT_J.js} +1 -1
- package/dist/{command-queue-uNIrlK4C.js → command-queue-BiT79iw_.js} +1 -1
- package/dist/{command-queue-3hrr088f.js → command-queue-C4uOOl0Z.js} +1 -1
- package/dist/{command-queue-D360YW1L.js → command-queue-Cd0AajLX.js} +1 -1
- package/dist/{command-queue-D2t-RCzv.js → command-queue-DnPEEtOJ.js} +1 -1
- package/dist/{command-registry-DuGYq06B.js → command-registry-CKhdmVgi.js} +13 -13
- package/dist/{command-secret-targets-DAtwJ6C7.js → command-secret-targets-9z88Sdd9.js} +2 -2
- package/dist/{command-secret-targets-j8KBmpix.js → command-secret-targets-r25GrCux.js} +2 -2
- package/dist/{commands-registry-CZGO6Zk0.js → commands-registry-Cof4HjvY.js} +2 -2
- package/dist/{completion-cli-BmLGd23K.js → completion-cli-DCm06gIy.js} +2 -2
- package/dist/{completion-cli-DuJJOsOD.js → completion-cli-DPC7jSts.js} +1 -1
- package/dist/{config-cli-DmPS8dHv.js → config-cli-DSSYHC1h.js} +1 -1
- package/dist/{config-cli-D7Km0W0t.js → config-cli-DzKCSgly.js} +1 -1
- package/dist/{configure-Cv8WHggj.js → configure-c7eXMXPC.js} +6 -6
- package/dist/{configure-Dp_BDe0p.js → configure-ev80kp3h.js} +6 -6
- package/dist/contracts/gateway-protocol.schema.json +23 -0
- package/dist/control-ui/assets/{dreams-5cpOLdgU.js → dreams-CFX8_iO7.js} +2 -2
- package/dist/control-ui/assets/{dreams-5cpOLdgU.js.map → dreams-CFX8_iO7.js.map} +1 -1
- package/dist/control-ui/assets/{index-D6XwnS7I.js → index-CambJeDO.js} +4 -4
- package/dist/control-ui/assets/{index-D6XwnS7I.js.map → index-CambJeDO.js.map} +1 -1
- package/dist/control-ui/assets/{learning-BORaiTQ4.js → learning-XJj58fEK.js} +2 -2
- package/dist/control-ui/assets/{learning-BORaiTQ4.js.map → learning-XJj58fEK.js.map} +1 -1
- package/dist/control-ui/assets/{view-chat-ByDyhnLw.js → view-chat-DCakYJRB.js} +3 -3
- package/dist/control-ui/assets/{view-chat-ByDyhnLw.js.map → view-chat-DCakYJRB.js.map} +1 -1
- package/dist/control-ui/index.html +1 -1
- package/dist/{cron-cli-DcatymNM.js → cron-cli-B7av_Qj-.js} +3 -3
- package/dist/{cron-cli-Bxd1ztzh.js → cron-cli-D-MXQLbx.js} +3 -3
- package/dist/{daemon-cli-P_665VBl.js → daemon-cli-C0X7BA3B.js} +2 -2
- package/dist/{daemon-cli-sdDY3Rkr.js → daemon-cli-D-zUFs16.js} +2 -2
- package/dist/daemon-cli.js +5 -0
- package/dist/{deliver-BGZedjpd.js → deliver-CD-qJ08p.js} +7 -5
- package/dist/{deliver-C0DKFL-c.js → deliver-CpY1AlyA.js} +29 -29
- package/dist/{deliver-Lga2gynK.js → deliver-Czj8jts5.js} +5 -5
- package/dist/{deliver-6pCupDgE.js → deliver-D3zKg0i3.js} +4 -4
- package/dist/{devices-cli-5NqagsuD.js → devices-cli-Bx1kF97H.js} +2 -2
- package/dist/{devices-cli-D6FG7yBy.js → devices-cli-D55ggw6F.js} +2 -2
- package/dist/{diagnostic-DBospa-B.js → diagnostic-Bu6Kxc66.js} +1 -1
- package/dist/{diagnostic-CdJb6i0b.js → diagnostic-BzGocbak.js} +1 -1
- package/dist/{diagnostic-uYRm3RAs.js → diagnostic-CKFgwhkU.js} +5 -5
- package/dist/{diagnostic-BP20aK6Y.js → diagnostic-CWdhJ9KR.js} +1 -1
- package/dist/{dm-policy-shared-C8iB_a-f.js → dm-policy-shared-JZebmiY8.js} +1 -1
- package/dist/{doctor-completion-BtJqYgVS.js → doctor-completion-Bx2Vu53y.js} +1 -1
- package/dist/{doctor-completion-Br2pHonN.js → doctor-completion-C1c_Fm0b.js} +1 -1
- package/dist/entry.js +2 -2
- package/dist/{errors-83K08uTq.js → errors-COs_vQr3.js} +1 -1
- package/dist/{exec-approvals-cli-DzJlH70p.js → exec-approvals-cli-RX2L6dhB.js} +4 -4
- package/dist/{exec-approvals-cli-D61d8hgT.js → exec-approvals-cli-U1avv2dD.js} +4 -4
- package/dist/extensionAPI.js +16 -16
- package/dist/{fetch-fObya4WR.js → fetch-B1ohBh6A.js} +8 -8
- package/dist/{fetch-guard-BucfWGi8.js → fetch-guard-BXzVwvnJ.js} +3 -3
- package/dist/{frontmatter-IfoWyoLV.js → frontmatter-Cw_6jMAR.js} +5 -5
- package/dist/{fs-safe-joAzTKB9.js → fs-safe-BK5ALzKD.js} +26 -26
- package/dist/{gateway-cli-BZFHtE2A.js → gateway-cli-CrFsVy3G.js} +53 -50
- package/dist/{gateway-cli-CzrTOBz5.js → gateway-cli-rJFjYA1c.js} +54 -51
- package/dist/{gateway-rpc-D36kXOsx.js → gateway-rpc-BArMTxJU.js} +1 -1
- package/dist/{gateway-rpc-hfUfa0T-.js → gateway-rpc-k1CUY-d7.js} +1 -1
- package/dist/github-copilot-token-DYYKoDuV.js +106 -0
- package/dist/{health-CVUuZRpQ.js → health-DjlQU_Tv.js} +4 -4
- package/dist/{health-K3ylOag4.js → health-jZPF8weC.js} +4 -4
- package/dist/{hooks-cli-CNlH_Ckf.js → hooks-cli-CVygK2yq.js} +30 -30
- package/dist/{hooks-cli-BTxvzxSG.js → hooks-cli-b4k2GboY.js} +29 -29
- package/dist/{image-ops-DlAa1zGf.js → image-ops-C-5VgbLB.js} +1 -1
- package/dist/index.js +32 -32
- package/dist/{ir-Cs9qeaeL.js → ir-DioI2VyB.js} +5 -5
- package/dist/{legacy-names-Dh4RlQMQ.js → legacy-names-CghFcfry.js} +1 -1
- package/dist/llm-slug-generator.js +60 -60
- package/dist/{logger-vVASmiVr.js → logger-J4xjy-6D.js} +1 -1
- package/dist/{logs-cli-ZXfvpQn5.js → logs-cli-BeLB-Xck.js} +3 -3
- package/dist/{logs-cli-DwpuZXwp.js → logs-cli-CvF3EIE2.js} +3 -3
- package/dist/{manager-CTeCpzGz.js → manager-D728Thsn.js} +18 -18
- package/dist/{manager-CsTeZuhu.js → manager-DCXdygsq.js} +1 -1
- package/dist/{manager-d_jLZwIa.js → manager-gw84UdyQ.js} +1 -1
- package/dist/{markdown-tables-BQLg3bjX.js → markdown-tables-DfLMw9ti.js} +2 -2
- package/dist/{memory-cli-C6IsfNdf.js → memory-cli-BcjjHcwL.js} +2 -2
- package/dist/{memory-cli-Dm4vpHAU.js → memory-cli-H4nCh_8v.js} +2 -2
- package/dist/{model-selection-UX4A5pdj.js → model-selection-BHGpQSa9.js} +87 -87
- package/dist/{models-FSASF0m5.js → models-BBZ_Tvpf.js} +3 -3
- package/dist/{models-cli-CqhUy9E-.js → models-cli-7V9N158Z.js} +30 -30
- package/dist/{models-cli-BIWkA9C9.js → models-cli-BJK0d_IM.js} +28 -28
- package/dist/{models-config-CNw9rdH1.js → models-config-CJUMccZW.js} +2 -2
- package/dist/{node-cli-BsB2z4rN.js → node-cli-BUV9i73l.js} +4 -4
- package/dist/{node-cli-DFxjiUT-.js → node-cli-DEVZws2K.js} +4 -4
- package/dist/{node-command-policy-BG0trkgo.js → node-command-policy-C0OmboTh.js} +1 -1
- package/dist/{node-command-policy-CVGtgIFJ.js → node-command-policy-Dbm2r7IP.js} +1 -1
- package/dist/{nodes-cli-BbRJxfod.js → nodes-cli-CYpc3Yvq.js} +3 -3
- package/dist/{nodes-cli-Cos0b-Pr.js → nodes-cli-Chp9WqRe.js} +3 -3
- package/dist/{npm-resolution-CwoZ0zIw.js → npm-resolution-BNpY_aOs.js} +1 -1
- package/dist/{npm-resolution-BKhZg_qE.js → npm-resolution-DaXE7ULy.js} +1 -1
- package/dist/{onboard-Bhpqg04u.js → onboard-BOhVuXUR.js} +3 -3
- package/dist/{onboard-qzS9Ex3E.js → onboard-C-KqZZqX.js} +3 -3
- package/dist/{onboard-channels-CdETO6vp.js → onboard-channels-B89jrN2Y.js} +2 -2
- package/dist/{onboard-channels-DqqM-gZ4.js → onboard-channels-DmJGOEPI.js} +2 -2
- package/dist/{onboard-helpers-CyLVkn7p.js → onboard-helpers-BHTSdqFW.js} +1 -1
- package/dist/{onboard-helpers-BjlBFVLF.js → onboard-helpers-DFWV67fv.js} +1 -1
- package/dist/{onboard-remote-BoobabMS.js → onboard-remote-BL2_Vzie.js} +1 -1
- package/dist/{onboard-remote-CGfCa4Gn.js → onboard-remote-aFlQukcN.js} +1 -1
- package/dist/{onboard-skills-qXATWBbv.js → onboard-skills-DBsUD_Fs.js} +1 -1
- package/dist/{onboard-skills-CA3vVftf.js → onboard-skills-fb0X7sb5.js} +1 -1
- package/dist/{onboarding-9F7Zrfos.js → onboarding-C6Xs7G9Y.js} +7 -7
- package/dist/{onboarding-B0tWDl2D.js → onboarding-DjYLPv7p.js} +7 -7
- package/dist/{onboarding.finalize-D-GEVbwy.js → onboarding.finalize-BzPTRheS.js} +35 -35
- package/dist/{onboarding.finalize-DZaf33cl.js → onboarding.finalize-Sx0H879S.js} +33 -33
- package/dist/{onboarding.gateway-config-D2JKnTD-.js → onboarding.gateway-config-CkoaBZS4.js} +5 -5
- package/dist/{onboarding.gateway-config-BjNFm5qL.js → onboarding.gateway-config-DFk1lZ7k.js} +5 -5
- package/dist/{operator-commands-Cak1KHXQ.js → operator-commands-CMLC3NdV.js} +2 -2
- package/dist/{operator-commands-QumqWQQg.js → operator-commands-DWyDwJ5E.js} +2 -2
- package/dist/{outbound-attachment-CFHAAdf4.js → outbound-attachment-DtVXUXnX.js} +2 -2
- package/dist/{outbound-message-hooks-DD51nZnK.js → outbound-message-hooks-8LGAoYF_.js} +1 -1
- package/dist/{outbound-message-hooks-ZPwBUN_R.js → outbound-message-hooks-CsYq3_vL.js} +1 -1
- package/dist/{outbound-message-hooks-WWLXsRwc.js → outbound-message-hooks-DUHpZ2aL.js} +5 -5
- package/dist/{outbound-message-hooks-DC75UHT4.js → outbound-message-hooks-tjGZZOYq.js} +1 -1
- package/dist/{path-alias-guards-BzCkdlOk.js → path-alias-guards-E9ntDORB.js} +1 -1
- package/dist/paths-BIDPYPVC.js +233 -0
- package/dist/{pi-embedded-BSXEJok2.js → pi-embedded--18wTN8q.js} +279 -272
- package/dist/{pi-embedded-helpers-D7uD-CgK.js → pi-embedded-helpers-Brv2iTWi.js} +2 -2
- package/dist/{pi-embedded-helpers-StwgdB31.js → pi-embedded-helpers-ClJpdsSV.js} +2 -2
- package/dist/{pi-embedded-recovery-adapter-D7px7ESy.js → pi-embedded-recovery-adapter-BEKLsxLt.js} +10 -10
- package/dist/{pi-embedded-recovery-adapter-CfgLn9QF.js → pi-embedded-recovery-adapter-dQZ-gtY4.js} +10 -10
- package/dist/{pi-embedded-utils-DjVnTKKi.js → pi-embedded-utils-C-FQE63E.js} +1 -1
- package/dist/{pi-embedded-utils-BjqdCUkA.js → pi-embedded-utils-C7ErjdjF.js} +3 -3
- package/dist/{pi-embedded-utils-B8Raycd6.js → pi-embedded-utils-CKxA8dqZ.js} +1 -1
- package/dist/{pi-embedded-utils-CR3tST8r.js → pi-embedded-utils-D7vaAoE6.js} +1 -1
- package/dist/{pi-embedded-BhsFkp5Y.js → pi-embedded-vIZchQTO.js} +42 -35
- package/dist/{pi-model-discovery-CQdUMRm4.js → pi-model-discovery-BaH_6win.js} +7 -7
- package/dist/{pi-tools.policy-DXLQHQAj.js → pi-tools.policy-BSgFR5ag.js} +1 -1
- package/dist/{plugin-registry-DH7Hnw6l.js → plugin-registry-CDj1s2Qo.js} +1 -1
- package/dist/{plugin-registry-DgIkh9ii.js → plugin-registry-CmiGMpCp.js} +1 -1
- package/dist/plugin-sdk/{agent-turn-execute-CW7LtXMC.js → agent-turn-execute-DRGUpyj_.js} +15 -15
- package/dist/plugin-sdk/{agent-turn-execute-BxdAt_ht.js → agent-turn-execute-vNMPaEsb.js} +15 -15
- package/dist/plugin-sdk/{agent-turn-runner-orbrCxRO.js → agent-turn-runner-B48Ac2Mq.js} +5 -5
- package/dist/plugin-sdk/{agent-turn-runner-sOn9sAG9.js → agent-turn-runner-CJ061NAh.js} +4 -4
- package/dist/plugin-sdk/{agent-turn-runner-CRaNFFTm.js → agent-turn-runner-xP1KK6u-.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-CBBGdhe1.js → audio-preflight-BDZ7cLko.js} +5 -5
- package/dist/plugin-sdk/{audio-preflight-BZXIHlnM.js → audio-preflight-COb5kXAH.js} +6 -6
- package/dist/plugin-sdk/{audio-preflight-CNU5kpWj.js → audio-preflight-DpIgQPUE.js} +1 -1
- package/dist/plugin-sdk/{audio-transcription-runner-D5dYI82C.js → audio-transcription-runner-DqbgqKuA.js} +1 -1
- package/dist/plugin-sdk/{audio-transcription-runner-D8y2D8k8.js → audio-transcription-runner-tMxFDdPy.js} +1 -1
- package/dist/plugin-sdk/{chat-content-DB5Wz2lG.js → chat-content-B4kExRGx.js} +1 -1
- package/dist/plugin-sdk/{chat-content-aOAkouil.js → chat-content-CmG6uniC.js} +1 -1
- package/dist/plugin-sdk/{command-detection-AlAuh3r9.js → command-detection-Cx5GspTs.js} +37 -30
- package/dist/plugin-sdk/{command-queue-JvIhb__x.js → command-queue-BrpT-5Sy.js} +1 -1
- package/dist/plugin-sdk/{command-queue-J8WWtdem.js → command-queue-mdn12mZN.js} +2 -2
- package/dist/plugin-sdk/{command-queue-DMJXMFU-.js → command-queue-uRF0EuVO.js} +1 -1
- package/dist/plugin-sdk/{deliver-D77qfyGv.js → deliver-CckI3OJ8.js} +4 -4
- package/dist/plugin-sdk/{deliver-46BXvvk5.js → deliver-D3X61EfY.js} +4 -4
- package/dist/plugin-sdk/{deliver-tcGRRL8s.js → deliver-DOj7WTIw.js} +5 -5
- package/dist/plugin-sdk/{deliver-BOyf6UPp.js → deliver-qMYtKe1O.js} +5 -5
- package/dist/plugin-sdk/{diagnostic-DVk1j05H.js → diagnostic-BQhPQdFK.js} +1 -1
- package/dist/plugin-sdk/{diagnostic-C-BgFx1S.js → diagnostic-CcNUspD1.js} +1 -1
- package/dist/plugin-sdk/{diagnostic-CLyicI69.js → diagnostic-I0XYqjlG.js} +1 -1
- package/dist/plugin-sdk/index.js +16 -16
- package/dist/plugin-sdk/{monitor-D9AzoNHs.js → monitor-CjGR673h.js} +36 -29
- package/dist/plugin-sdk/{pi-embedded-utils-Bj86frFf.js → pi-embedded-utils-BeDAZIRN.js} +1 -1
- package/dist/plugin-sdk/{pi-embedded-utils-gWjx_FJu.js → pi-embedded-utils-CXRILg4X.js} +1 -1
- package/dist/plugin-sdk/{provider-dispatcher-BkgqrySb.js → provider-dispatcher-CaEeja4a.js} +15 -15
- package/dist/plugin-sdk/{provider-dispatcher-RG1EJhMg.js → provider-dispatcher-CwOOkcSh.js} +15 -15
- package/dist/plugin-sdk/{provider-image-CK8PByo3.js → provider-image-1--b__Rf.js} +1 -1
- package/dist/plugin-sdk/{provider-image-BRuhIUH4.js → provider-image-CWR1baFo.js} +4 -4
- package/dist/plugin-sdk/{provider-image-BsvAEUj7.js → provider-image-D3L7uRQL.js} +4 -4
- package/dist/plugin-sdk/{provider-image-BRiO1hJO.js → provider-image-DfMOZvCj.js} +1 -1
- package/dist/plugin-sdk/{replies-CNJcNn1X.js → replies-Bvgbr4Gl.js} +2 -2
- package/dist/plugin-sdk/{replies-CmfWsSdE.js → replies-DpAL4lju.js} +2 -2
- package/dist/plugin-sdk/{replies-Diq1jozB.js → replies-K0SP92k3.js} +3 -3
- package/dist/plugin-sdk/{replies-3-6UUC2y.js → replies-S7-hIwEu.js} +3 -3
- package/dist/plugin-sdk/{reply-directives-C_nV536z.js → reply-directives-3w5Sb0-K.js} +1 -1
- package/dist/plugin-sdk/{reply-directives--THCb2vc.js → reply-directives-CCmYO5TU.js} +1 -1
- package/dist/plugin-sdk/{runs-CmbFSwOD.js → runs-Bh-TSTul.js} +6 -6
- package/dist/plugin-sdk/{runs-nP6hONs2.js → runs-Ciq2OtzT.js} +5 -5
- package/dist/plugin-sdk/{runs-Cu-M6Lh7.js → runs-DgLRRHnl.js} +6 -6
- package/dist/plugin-sdk/{runs-BU1Eppml.js → runs-lzwgSAQQ.js} +5 -5
- package/dist/plugin-sdk/{send-LkmFhgsK.js → send-4L6l04nt.js} +2 -2
- package/dist/plugin-sdk/{send-D7UktRfh.js → send-DKVsq9M4.js} +1 -1
- package/dist/plugin-sdk/{send-C2QGhDII.js → send-RnIEnr9s.js} +2 -2
- package/dist/plugin-sdk/{send-aiyKj-5V.js → send-T7FFZ4GT.js} +1 -1
- package/dist/plugin-sdk/{session-context-DLi5r0L8.js → session-context-Ct8StxcQ.js} +1 -1
- package/dist/plugin-sdk/{session-context-D79uWb-f.js → session-context-DLVW1kjd.js} +1 -1
- package/dist/plugin-sdk/{session-meta-DwqjC-No.js → session-meta-CjpVFrUg.js} +1 -1
- package/dist/plugin-sdk/{sessions-D9WFZu21.js → sessions-55u1Rz4h.js} +1 -0
- package/dist/plugin-sdk/{sessions-CmLCbwdv.js → sessions-DgJUTr39.js} +1 -0
- package/dist/plugin-sdk/src/agents/tool-display-common.d.ts +10 -0
- package/dist/plugin-sdk/src/gateway/protocol/index.d.ts +3 -0
- package/dist/plugin-sdk/src/gateway/protocol/schema/protocol-schemas.d.ts +6 -0
- package/dist/plugin-sdk/src/gateway/protocol/schema/sessions.d.ts +6 -0
- package/dist/plugin-sdk/src/gateway/protocol/schema/types.d.ts +2 -0
- package/dist/plugin-sdk/src/gateway/session-utils.types.d.ts +2 -0
- package/dist/plugin-sdk/src/shared/session-visibility.d.ts +1 -1
- package/dist/plugin-sdk/src/tts/tts.d.ts +2 -0
- package/dist/plugin-sdk/{subagent-registry-D-9HI-_X.js → subagent-registry-CfMU3EOY.js} +15 -15
- package/dist/plugin-sdk/{subagent-registry-CuACJDRa.js → subagent-registry-n7onkQYC.js} +15 -15
- package/dist/plugin-sdk/testing.js +15 -15
- package/dist/{plugins-cli-D2epBFli.js → plugins-cli-BfVyfDVB.js} +30 -30
- package/dist/{plugins-cli-YMB3dwun.js → plugins-cli-RYPupoUU.js} +29 -29
- package/dist/{program-context-C0OAcdai.js → program-context-Bd6intne.js} +37 -37
- package/dist/{program-DhncJMbr.js → program-vHNIwjM_.js} +35 -35
- package/dist/{prompt-select-styled-pBLBu3w7.js → prompt-select-styled-BwIQiRks.js} +11 -11
- package/dist/{prompt-select-styled-B0HZWrVy.js → prompt-select-styled-CvmUNFDK.js} +11 -11
- package/dist/{provider-image-CApPjEsW.js → provider-image-BvBYtGGJ.js} +1 -1
- package/dist/{provider-image-D2FrDW-X.js → provider-image-DVTuOv92.js} +6 -6
- package/dist/{provider-image-CAWS0JMV.js → provider-image-KmAZWQje.js} +1 -1
- package/dist/{provider-image-B-KFl1me.js → provider-image-n0L8CIDm.js} +1 -1
- package/dist/{proxy-CPi-EHQf.js → proxy-CrSpy5Aw.js} +1 -1
- package/dist/{proxy-env-1eta-137.js → proxy-env-BxR4m86L.js} +1 -1
- package/dist/{proxy-fetch-SAeVJOzX.js → proxy-fetch-g109vqdt.js} +1 -1
- package/dist/{push-apns-BAZsfMOy.js → push-apns--0fj47Qj.js} +2 -2
- package/dist/{push-apns-PAONdNH4.js → push-apns-Cb0sjE90.js} +2 -2
- package/dist/{pw-ai-DtPiMDW2.js → pw-ai-BJiiE3V8.js} +1 -1
- package/dist/{pw-ai-Czj8Ud3z.js → pw-ai-CC8qsp4R.js} +1 -1
- package/dist/{pw-ai-D9Y__zb9.js → pw-ai-CNTt9O_x.js} +14 -14
- package/dist/{pw-ai-BZjpW2LJ.js → pw-ai-DMPGyJxJ.js} +1 -1
- package/dist/{qmd-manager-C0SNPJNQ.js → qmd-manager-CU9iEql0.js} +12 -12
- package/dist/{qr-cli-DAghVVtT.js → qr-cli-B1vszJrL.js} +3 -3
- package/dist/{qr-cli-C8WFS-12.js → qr-cli-BZy4AXuc.js} +3 -3
- package/dist/{query-expansion-lPFsJzxE.js → query-expansion-B_2rETEo.js} +13 -13
- package/dist/{recorder-Dtl7MFGH.js → recorder-Clg9Kbqu.js} +2 -2
- package/dist/{recovery-adapter-CZUNVpQO.js → recovery-adapter-D3YllPfB.js} +2 -2
- package/dist/{recovery-adapter-CRSPS8I2.js → recovery-adapter-Dyk72MfJ.js} +2 -2
- package/dist/{recovery-adapter-BSdwo2OS.js → recovery-adapter-Hdhf6HDW.js} +1 -1
- package/dist/{recovery-adapter-BpJ8BscF.js → recovery-adapter-y0rKMaw8.js} +1 -1
- package/dist/{redact-Da2jd8m8.js → redact-DpE5Tg36.js} +1 -1
- package/dist/{register.agent-FDTmtEUr.js → register.agent-CgPP5ADX.js} +31 -31
- package/dist/{register.agent-C4f6rhJo.js → register.agent-DfScK2hV.js} +33 -33
- package/dist/{register.configure-Dv5O2Xb5.js → register.configure-C8uYH0Yy.js} +35 -35
- package/dist/{register.configure-Hw_sXK-z.js → register.configure-dflFJ7N_.js} +34 -34
- package/dist/{register.maintenance-D8jjjhHB.js → register.maintenance-DYrx2td9.js} +35 -35
- package/dist/{register.maintenance-DK1PJ9oQ.js → register.maintenance-DplgYMC9.js} +37 -37
- package/dist/{register.message-D2APO70t.js → register.message-BBQ6Wdt9.js} +29 -29
- package/dist/{register.message-GNpuxvGM.js → register.message-jvrIPxVV.js} +30 -30
- package/dist/{register.onboard-0G3JduCW.js → register.onboard-eC1JSQFQ.js} +6 -6
- package/dist/{register.onboard-DONtll3f.js → register.onboard-mi8eEWxH.js} +6 -6
- package/dist/{register.setup-Ru94mK0C.js → register.setup-DZYxFj5L.js} +6 -6
- package/dist/{register.setup-BhN2hAJ-.js → register.setup-F0XMwrOq.js} +6 -6
- package/dist/{register.status-health-sessions-cUGfN2jZ.js → register.status-health-sessions-B-IdUdif.js} +33 -33
- package/dist/{register.status-health-sessions-BugOGdEq.js → register.status-health-sessions-DbjCFLPT.js} +35 -35
- package/dist/{register.subclis-BXGoL8Qv.js → register.subclis-Dobk1vvB.js} +25 -25
- package/dist/{replies-qljs_NZI.js → replies-B7XXdKjN.js} +2 -2
- package/dist/{replies-DS1VGy4W.js → replies-BKdOqGC9.js} +5 -5
- package/dist/{replies-CHagfAgN.js → replies-DrGGa5se.js} +2 -2
- package/dist/{replies-BuO733xx.js → replies-gGgLXY8D.js} +2 -2
- package/dist/{reply-CqYQeNjd.js → reply-BSMDupOw.js} +38 -36
- package/dist/{reply-directives-CJoSirgd.js → reply-directives-Bz18fvJe.js} +1 -1
- package/dist/{reply-directives-DBZR0dTg.js → reply-directives-CtSqkSzr.js} +2 -2
- package/dist/{reply-directives-B9hX-LBz.js → reply-directives-bPMJNW1Q.js} +1 -1
- package/dist/{reply-directives-GcBlocvi.js → reply-directives-tE0PyBK-.js} +1 -1
- package/dist/{reply-prefix-DfeMrD4g.js → reply-prefix-C-DjHvQK.js} +1 -1
- package/dist/{resolve-route-CAuL1p_4.js → resolve-route-DKZiteo6.js} +5 -5
- package/dist/{rpc-DJ9VPO9A.js → rpc-BZtZb4-6.js} +1 -1
- package/dist/{rpc-BoZa3Ve8.js → rpc-Ft_DUdSG.js} +1 -1
- package/dist/{run-main-08KWAl9e.js → run-main-BJFVebkS.js} +44 -44
- package/dist/{runs-DRxbDl12.js → runs-BIt97Q-K.js} +9 -9
- package/dist/{runs-CoWBHyeo.js → runs-BUywHXga.js} +4 -4
- package/dist/{runs-vCw_F2ZO.js → runs-TPOj4wqX.js} +4 -4
- package/dist/{runs-yIaQUPae.js → runs-wDxw0TX4.js} +5 -5
- package/dist/{sandbox-BijP-jd2.js → sandbox-389fAlDt.js} +2 -2
- package/dist/{sandbox-Cf0p0qcn.js → sandbox-CEDb7iCz.js} +2 -2
- package/dist/{sandbox-cli-DFLg4dmY.js → sandbox-cli-BJ4Z1CEE.js} +6 -6
- package/dist/{sandbox-cli-B0TGsg0B.js → sandbox-cli-kfxS44rH.js} +6 -6
- package/dist/{secrets-cli-BoYG9Zi_.js → secrets-cli-CgpBwEA_.js} +3 -3
- package/dist/{secrets-cli-CL3R38dk.js → secrets-cli-DFuIPeQ8.js} +3 -3
- package/dist/{security-cli-BuOut78W.js → security-cli-bxcpjEyc.js} +8 -8
- package/dist/{security-cli-DFTi9A0s.js → security-cli-zcQ5Hc8L.js} +8 -8
- package/dist/{send-Bmp8wi9T.js → send-Bf4geLyV.js} +8 -8
- package/dist/{send-DRJrureq.js → send-Ch1ruPj9.js} +1 -1
- package/dist/{send-DFasc8l1.js → send-CsDSBjFo.js} +6 -6
- package/dist/{send-CtSLexxo.js → send-DBqe2mPq.js} +30 -30
- package/dist/{send-DFAmNsWX.js → send-DQvfLvpJ.js} +6 -6
- package/dist/{send-DSRl6F0O.js → send-bwKTbNlJ.js} +7 -7
- package/dist/{send-DxkjyjYg.js → send-cRef_6f-.js} +1 -1
- package/dist/{send-7pf6IvCv.js → send-xXKNMsLi.js} +1 -1
- package/dist/{server-CRI0-vWV.js → server-CggrpKmd.js} +4 -4
- package/dist/{server-ks1TmG7W.js → server-D7EeBwPd.js} +4 -4
- package/dist/{server-context-DgKj77jj.js → server-context-CV1udh3Y.js} +2 -2
- package/dist/{server-context-BIoSfzI_.js → server-context-Dv15RG_H.js} +2 -2
- package/dist/{server-lifecycle-fJG-u89x.js → server-lifecycle-BIH58Hoe.js} +1 -1
- package/dist/{server-lifecycle-Cd0b010a.js → server-lifecycle-D8mfFIYf.js} +1 -1
- package/dist/{server-node-events-Ba1YD79n.js → server-node-events-C_xoK9Xb.js} +29 -29
- package/dist/{server-node-events-CqQhTT1T.js → server-node-events-mxzClNCx.js} +30 -30
- package/dist/{session-meta-BlSJMcbU.js → session-meta-5XI6vLtM.js} +1 -1
- package/dist/{session-storage-B-ES9i1k.js → session-storage-269JGGQ0.js} +1 -1
- package/dist/{session-storage-7x9X6Db3.js → session-storage-BbpL12Su.js} +1 -1
- package/dist/{session-storage-owner-DLQ3vsAz.js → session-storage-owner-ClZPCWep.js} +2 -2
- package/dist/{session-storage-owner-1-cQlOCZ.js → session-storage-owner-M7vbUIWw.js} +2 -2
- package/dist/{session-utils-BeYzkx__.js → session-utils-Be7zx7oZ.js} +4 -2
- package/dist/{sessions-BIgPumZV.js → sessions-BV1UJJsg.js} +37 -11
- package/dist/{sessions-rMRfoN3f.js → sessions-CIWeBs1M.js} +1 -0
- package/dist/{sessions-9SvxsXWP.js → sessions-CLcDtAGY.js} +1 -0
- package/dist/{sessions-bZHjdfaW.js → sessions-C_dBu7XC.js} +6 -5
- package/dist/{sessions-CLXwtR8F.js → sessions-CpqHo_Lm.js} +37 -11
- package/dist/{sessions-B03PIf-m.js → sessions-D4geZIf4.js} +1 -0
- package/dist/{sessions-DvCgCqqN.js → sessions-DR_ebiSs.js} +2 -2
- package/dist/{sessions-claims-status-DMdo7H9e.js → sessions-claims-status-CCWxZ_uS.js} +2 -2
- package/dist/{sessions-claims-status-CJ4Z16C-.js → sessions-claims-status-DcgKqzSM.js} +2 -2
- package/dist/{skill-commands-RBvFNztU.js → skill-commands-CAOvM2sb.js} +8 -8
- package/dist/{skills-Dj2sTIvh.js → skills-VN1CJK6W.js} +21 -21
- package/dist/{status-D_sJaQfK.js → status-B8Al6FzI.js} +18 -18
- package/dist/{status-Ccz-BtS_.js → status-Cuo3rz1n.js} +18 -18
- package/dist/{store-WpdMrmch.js → store-HgGweM4u.js} +7 -7
- package/dist/{subsystem-D_zHSy02.js → subsystem-BZy3aWdW.js} +71 -71
- package/dist/{system-cli-BGa0j96s.js → system-cli-Ba9jGCiM.js} +3 -3
- package/dist/{system-cli-CnsRY21W.js → system-cli-DcjUJVa8.js} +3 -3
- package/dist/{tables--lm0TIoo.js → tables-DkwNUhx1.js} +1 -1
- package/dist/{task-pipeline-boot-BMwRQ8Fe.js → task-pipeline-boot-C1v58b1_.js} +30 -30
- package/dist/{task-pipeline-boot-D5tuNVHj.js → task-pipeline-boot-Kxi1hpUn.js} +29 -29
- package/dist/{task-runlog-retention-D0XabfJk.js → task-runlog-retention-BdLkqRCi.js} +3 -3
- package/dist/{task-runlog-retention-vP8bhD14.js → task-runlog-retention-CJeUxN8v.js} +3 -3
- package/dist/{tasks-DEye0RYH.js → tasks-BIqKTj4l.js} +2 -2
- package/dist/{tasks-DIa6KmEw.js → tasks-nrh4KjHH.js} +2 -2
- package/dist/{tokens-B3OPeQh5.js → tokens-PMai9bNL.js} +1 -1
- package/dist/{tool-loop-detection-ST5jhih3.js → tool-loop-detection-BqyMjpvr.js} +2 -2
- package/dist/{tui-YpVnb92B.js → tui-DC-J_38B.js} +3 -3
- package/dist/{tui-DvN9w3dz.js → tui-DrLsIQv0.js} +3 -3
- package/dist/{tui-cli-B9yDRbjk.js → tui-cli-CAtLTzIA.js} +7 -7
- package/dist/{tui-cli-DoocDTJG.js → tui-cli-De9rMj3R.js} +7 -7
- package/dist/{update-cli-CUltMNat.js → update-cli-BEm9qrlV.js} +38 -38
- package/dist/{update-cli-DzokCnPQ.js → update-cli-CGSSTKTT.js} +36 -36
- package/dist/{update-runner-BOwq67Zr.js → update-runner-BMCWrif2.js} +1 -1
- package/dist/{update-runner-B2S-ijWA.js → update-runner-BUO6D2tP.js} +1 -1
- package/dist/{user-run-recording--_IhK-gN.js → user-run-recording-B1HujJiT.js} +2 -2
- package/dist/{validation-cli-C3tmcqKI.js → validation-cli-DHwddKWw.js} +29 -29
- package/dist/{validation-cli-BVO3QQdD.js → validation-cli-IGbMryvI.js} +30 -30
- package/dist/{with-timeout-BWtea6IA.js → with-timeout-BBKlU1es.js} +2 -2
- package/dist/{with-timeout-i0aj653V.js → with-timeout-CkVVKMZ5.js} +2 -2
- package/dist/{workspace-rViTESnr.js → workspace-Bj1Jegt-.js} +27 -27
- package/extensions/acpx/package.json +1 -1
- package/extensions/anthropic/package.json +1 -1
- package/extensions/bifrost/package.json +1 -1
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/deepgram/package.json +1 -1
- package/extensions/deepinfra/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/diffs/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/dream-cycle/package.json +1 -1
- package/extensions/elevenlabs/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/gemini-search/package.json +1 -1
- package/extensions/google/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/grok-search/package.json +1 -1
- package/extensions/groq/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/kimi-search/package.json +1 -1
- package/extensions/learning-core/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +1 -1
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/mistral/package.json +1 -1
- package/extensions/moonshot/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +1 -1
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +1 -1
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai/package.json +1 -1
- package/extensions/openai-realtime/package.json +1 -1
- package/extensions/openrouter/package.json +1 -1
- package/extensions/perplexity-search/package.json +1 -1
- package/extensions/searxng-search/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/synology-chat/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +1 -1
- package/extensions/twitch/package.json +1 -1
- package/extensions/ui-surfaces/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +1 -1
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zai/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +1 -1
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +1 -1
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"mappings":"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C7B,GAAa,gBACA,GAAa,gBAsBzB,YACA,2BACE,GAAsB,iBACvB,cACO,KAAK,SAAS,OAAS,4BACX,kBACA,oBACJ,wBACI,mBACH,CAAC,sBACI,CAAC,2BACE,4BACF,wBAElB,GAAsB,0BACpB,GAAsB,6BACrB,GAAsB,SAAW,sBACvB,qBAEhB,KAAK,SAAS,4BACb,oBACA,oBACA,qBACY,CAAC,wBACG,CAAC,kBACH,8BACS,oBACV,2BACiB,yBACJ,wBACT,4BACI,oBACN,CAAC,uBACM,CAAC,iCACT,oBAEd,uBACkB,uBACF,qBACjB,KAAK,SAAS,6BAEZ,cACyB,CAAC,sBACxB,qBACa,sBACU,+BACjB,4BACD,2BACD,8BACiC,4BACR,qCACF,8BACF,yCACC,4BACA,CAAC,wBACzB,0BACgB,4BACA,wBAEnB,kBACJ;;yBACQ,oBACU,uBACJ,CAAC,oBACZ,uBACE,sBACD,wBACE,KAAK,SAAS,yCACQ,uBAChB,8BACa,8BACf,sBACS,CAAC,kBACa,6BACQ,0BACnC,uBACe,8BACb,4BACiB,iCACG,0BAEtB,yBACgC,wBACnB,8BACM,+BACC,iCACE,iCACC,uBAC1B,8BACuC,gCACf,0BAErB,wBACiB,CAAC,qBACL,yBACC,wBAEhB,mBACsB,sBACT,2BACK,8BACZ,0BACa,6BACa,sBAEvD,kCAC2B,wBACa,yBACc,4BACH,CAAC,uBACH,CAAC,uBACV,0BACf,6BACK,2BACa,4BACqB,CAAC,0BACrC,yBACa,4BACY,6BACV,0BAElB,uBAC0B,wBACb,+BACR,4BACD,iCACE,+BACC,0BACqB,2BACZ,+BACpB,0BACF,iCACgD,kCACnB,oCACtB,oCACW,IAAI,+BAC8B,CAAC,2BACpD,IAAI,yBACiD,CAAC,qBACpC,yBACd,IAAI,gCACL,yBACG,qBAEJ,oBACgD,2BACE,qBACrC,8BACJ,CAC/B,IAAM,EAAI,IAAI,KACd,MAAO,GAAG,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,SAAS,EAAI,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,GAC/G,GAAG,yBAC4B,CAC7B,IAAM,EAAI,IAAI,KACd,MAAO,GAAG,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,SAAS,EAAI,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,GAC/G,GAAG,6BACwC,CAAC,yBACL,CAAC,0BACA,CAAC,sBACI,kCACO,mCACM,6CACG,+BACkB,iCAC7C,mCACmB,mCACF,2BAC8B,kCAC9C,iCACC,mBAEd,wBAEK,yBACuD,kCACnC,gCACN,CAAC,qBACA,kCACV,0BACH,yBACiB,+BACL,CACvC,UACA,QACA,WACA,QACA,WACA,QACA,SACA,UACF,2BAC4E,CAAC,2BACpC,CAAC,8BACR,4BACH,gCAGU,sBAElB,4BACQ,iBACA,CAAC,qBACP,uBACE,2BACkB,wBACpB,sBACA,8BACoD,sCAE3E,oCAEA,0BAC6D,mCACF,sBACpB,oBACL,mBACD,CAAE,GAAG,CAAkB,uBACd,CAAC,wBACF,0BAChB,sBACa,8BACT,iBACQ,CAAC,qBACf,uBACE,2BACkB,wBACpB,sBACmC,4BACY,CAAC,gCACM,CAAC,4BACL,yBAClD,wBACoC,iCACnB,CAAC,gBACvB,8BAC4B,2BACL,2BACA,0BAGhB,sBACa,mBACyC,oBACD,CAAC,eACL,CAAC,wBAE3E,uBACsB,wBAC4B,wCACH,iBAGd,GAAyB,wBACzC,mBACL,4BACuB,gCACb,6BACc,6BACF,0BAEoC,wBAE/C,qBACyB,sBACZ,uBACd,mBACsB,CAAC,qBACP,wBACe,CAAC,oBAEhC,oBACqB,sBACC,sBACZ,CAAC,sBACA,0BACR,wBACA,0BACe,yBACD,sBAElB,kBACa,mBACD,sBACA,CAAC,sBACV,yBAC6B,CACrD,GAAG,CACL,sBAC0B,sBACD,mBACY,0BACK,oBACrB,sBACG,uBACA,kBACQ,GAAuB,cAEjB,0BAGG,4BACE,8BACb,2BACD,6BACG,0BACW,2BACD,4BACC,kCACM,kCACA,0BACR,yBAChB,IAAI,yB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","names":["module","exports","bytesToHex"],"ignoreList":[4,17],"sources":["../../../packages/talk-client/src/audio-capture.ts","../../../packages/talk-client/src/audio-playback.ts","../../../packages/talk-client/src/talk-session-client.ts","../../../ui/src/ui/controllers/channels.ts","../../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/dist/index.js","../../../ui/src/ui/controllers/config/form-coerce.ts","../../../ui/src/ui/controllers/config/form-utils.ts","../../../ui/src/ui/controllers/config.ts","../../../ui/src/ui/app-channels.ts","../../../src/sessions/session-key-utils.ts","../../../ui/src/ui/app-scroll.ts","../../../ui/src/ui/controllers/debug.ts","../../../src/gateway/device-auth.ts","../../../src/gateway/protocol/client-info.ts","../../../src/shared/device-auth.ts","../../../src/shared/device-auth-store.ts","../../../ui/src/ui/device-auth.ts","../../../node_modules/.pnpm/@noble+ed25519@3.1.0/node_modules/@noble/ed25519/index.js","../../../ui/src/ui/device-identity.ts","../../../ui/src/ui/uuid.ts","../../../ui/src/ui/gateway.ts","../../../ui/src/ui/controllers/dreams.ts","../../../ui/src/ui/controllers/logs.ts","../../../ui/src/ui/controllers/nodes.ts","../../../ui/src/ui/controllers/sessions.ts","../../../ui/src/ui/app-polling.ts","../../../ui/src/ui/controllers/agent-identity.ts","../../../ui/src/ui/controllers/agent-skills.ts","../../../ui/src/ui/controllers/agents.ts","../../../ui/src/ui/controllers/devices.ts","../../../ui/src/ui/controllers/exec-approvals.ts","../../../ui/src/ui/controllers/presence.ts","../../../ui/src/ui/controllers/skills.ts","../../../ui/src/ui/storage.ts","../../../ui/src/ui/theme-transition.ts","../../../ui/src/ui/theme.ts","../../../ui/src/ui/app-settings.ts","../../../ui/src/ui/app-tool-stream.ts","../../../ui/src/ui/controllers/chat.ts","../../../ui/src/ui/app-chat.ts","../../../ui/src/ui/chat-event-reload.ts","../../../src/shared/assistant-identity-values.ts","../../../ui/src/ui/assistant-identity.ts","../../../ui/src/ui/controllers/assistant-identity.ts","../../../ui/src/ui/controllers/exec-approval.ts","../../../ui/src/ui/app-gateway.ts","../../../src/gateway/control-ui-contract.ts","../../../ui/src/ui/controllers/control-ui-bootstrap.ts","../../../ui/src/ui/app-lifecycle.ts","../../../ui/src/ui/lazy-view.ts","../../../ui/src/ui/app-view-dispatcher.ts","../../../ui/src/ui/controllers/usage.ts","../../../ui/src/ui/app-render-usage-tab.ts","../../../ui/src/ui/app-render.helpers.ts","../../../ui/src/ui/controllers/agent-files.ts","../../../ui/src/ui/views/exec-approval.ts","../../../ui/src/ui/views/gateway-url-confirmation.ts","../../../ui/src/ui/app-render.ts","../../../ui/src/ui/controllers/learning.ts","../../../ui/src/ui/controllers/talk.ts","../../../ui/src/ui/app.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport audioCaptureWorkletUrl from \"./audio-capture-worklet.ts?worker&url\";\n\nconst mediaConstraints: MediaStreamConstraints = {\n audio: {\n // The capture worklet downmixes to mono, so mono is a preference rather\n // than a hard constraint that could fail device selection outright.\n channelCount: { ideal: 1 },\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n};\n\nconst DEFAULT_TARGET_SAMPLE_RATE_HZ = 24_000;\n\n// How long stop() waits for the worklet's final flushed batch to arrive after\n// posting \"stop\" before removing the message listener and tearing down.\nconst STOP_FLUSH_DRAIN_MS = 50;\n\nexport function createTalkAudioCapture(options: {\n onPcm16: (frame: Uint8Array) => void;\n /** Resample target for the worklet's output; the OpenAI realtime console uses 24 kHz, the\n * ADR 0087 streaming STT seam uses 16 kHz. Defaults to 24 kHz (console behaviour unchanged). */\n targetSampleRateHz?: number;\n}) {\n const targetSampleRateHz = options.targetSampleRateHz ?? DEFAULT_TARGET_SAMPLE_RATE_HZ;\n let stream: MediaStream | null = null;\n let context: AudioContext | null = null;\n let source: MediaStreamAudioSourceNode | null = null;\n let worklet: AudioWorkletNode | null = null;\n let gain: GainNode | null = null;\n let messageListener: ((event: MessageEvent<unknown>) => void) | null = null;\n let lifecycle = 0;\n let startPromise: Promise<void> | null = null;\n\n async function stop(): Promise<void> {\n lifecycle += 1;\n startPromise = null;\n const ownedStream = stream;\n const ownedContext = context;\n const ownedSource = source;\n const ownedWorklet = worklet;\n const ownedGain = gain;\n const ownedMessageListener = messageListener;\n\n stream = null;\n context = null;\n source = null;\n worklet = null;\n gain = null;\n messageListener = null;\n\n if (ownedWorklet && ownedMessageListener) {\n // Post the stop flush while a message listener is still attached so the\n // worklet's final batch is delivered, then give it a bounded moment to\n // arrive before removing the listeners and tearing the graph down.\n let settleFlush!: () => void;\n const flushed = new Promise<void>((resolveFlush) => {\n settleFlush = resolveFlush;\n });\n const flushAck = (event: MessageEvent<unknown>) => {\n // Only the worklet's explicit flush acknowledgement settles the drain;\n // a PCM batch queued ahead of the \"stop\" message must not.\n if (event.data === \"flushed\") {\n settleFlush();\n }\n };\n ownedWorklet.port.addEventListener(\"message\", flushAck);\n try {\n ownedWorklet.port.postMessage?.(\"stop\");\n } catch {\n // Flushing is best effort; teardown continues on a broken port.\n }\n await Promise.race([\n flushed,\n new Promise<void>((resolveTimeout) => {\n setTimeout(resolveTimeout, STOP_FLUSH_DRAIN_MS);\n }),\n ]);\n ownedWorklet.port.removeEventListener(\"message\", ownedMessageListener);\n ownedWorklet.port.removeEventListener(\"message\", flushAck);\n }\n ownedSource?.disconnect();\n ownedWorklet?.disconnect();\n ownedGain?.disconnect();\n for (const track of ownedStream?.getTracks() ?? []) {\n track.stop();\n }\n await ownedContext?.close();\n }\n\n async function startCapture(startup: number): Promise<void> {\n try {\n const acquiredStream = await navigator.mediaDevices.getUserMedia(mediaConstraints);\n if (startup !== lifecycle) {\n for (const track of acquiredStream.getTracks()) {\n track.stop();\n }\n return;\n }\n stream = acquiredStream;\n const acquiredContext = new AudioContext();\n context = acquiredContext;\n await acquiredContext.audioWorklet.addModule(audioCaptureWorkletUrl);\n if (startup !== lifecycle) {\n return;\n }\n source = acquiredContext.createMediaStreamSource(acquiredStream);\n worklet = new AudioWorkletNode(acquiredContext, \"wednesdayai-audio-capture\", {\n processorOptions: { targetSampleRateHz },\n });\n messageListener = (event: MessageEvent<unknown>) => {\n const buffer = event.data;\n if (buffer instanceof ArrayBuffer && buffer.byteLength % 2 === 0) {\n options.onPcm16(new Uint8Array(buffer));\n }\n };\n worklet.port.addEventListener(\"message\", messageListener);\n worklet.port.start();\n gain = acquiredContext.createGain();\n gain.gain.value = 0;\n source.connect(worklet);\n worklet.connect(gain);\n gain.connect(acquiredContext.destination);\n } catch (error) {\n if (startup !== lifecycle) {\n return;\n }\n await stop();\n throw error;\n }\n }\n\n return {\n start(): Promise<void> {\n if (startPromise) {\n return startPromise;\n }\n const pending = startCapture(++lifecycle);\n startPromise = pending;\n void pending.catch(() => {\n if (startPromise === pending) {\n startPromise = null;\n }\n });\n return pending;\n },\n async suspend(): Promise<void> {\n await context?.suspend();\n },\n async resume(): Promise<void> {\n await context?.resume();\n },\n stop,\n };\n}\n","type PlaybackSource = {\n node: AudioBufferSourceNode;\n generation: number;\n sequence: number;\n};\n\ntype PlaybackMark = {\n name: string;\n generation: number;\n barrier: number;\n};\n\nexport function createTalkAudioPlayback(options: {\n sampleRateHz: number;\n onMarkPlayed: (name: string, monotonicMs: number) => void;\n now: () => number;\n onOverflow?: () => void;\n /** Lookahead applied only when starting fresh (no audio currently scheduled), so the very first\n * chunk of an utterance has a buffer against a late-arriving next chunk. 0 (the default) keeps\n * the operator console's existing back-to-back scheduling unchanged. */\n preRollMs?: number;\n /** Route output through a `MediaStreamAudioDestinationNode` into an `<audio>` element instead of\n * `context.destination` directly, so the stream has a real media element for the browser's echo\n * cancellation to reference. Defaults to false (console's existing direct-destination sink). */\n echoSafeSink?: boolean;\n}) {\n const context = new AudioContext();\n const preRollSec = (options.preRollMs ?? 0) / 1000;\n const sinkNode: AudioNode = options.echoSafeSink\n ? context.createMediaStreamDestination()\n : context.destination;\n let audioElement: HTMLAudioElement | null = null;\n if (options.echoSafeSink) {\n const mediaStreamDestination = sinkNode as MediaStreamAudioDestinationNode;\n audioElement = document.createElement(\"audio\");\n audioElement.srcObject = mediaStreamDestination.stream;\n audioElement.autoplay = true;\n audioElement.muted = false;\n document.body.appendChild(audioElement);\n }\n const sources = new Set<PlaybackSource>();\n let marks: PlaybackMark[] = [];\n let generation = 0;\n let sourceSequence = 0;\n let nextPlayAt = 0;\n let closePromise: Promise<void> | null = null;\n let lastPlaybackEndedAt: number | null = null;\n\n function acknowledgeReadyMarks(endedGeneration: number, endedAt?: number) {\n const ready: PlaybackMark[] = [];\n const waiting: PlaybackMark[] = [];\n\n for (const mark of marks) {\n let blocked = false;\n for (const source of sources) {\n if (source.generation === mark.generation && source.sequence <= mark.barrier) {\n blocked = true;\n break;\n }\n }\n if (mark.generation === endedGeneration && !blocked) {\n ready.push(mark);\n } else {\n waiting.push(mark);\n }\n }\n marks = waiting;\n\n for (const mark of ready) {\n if (mark.generation !== generation) {\n break;\n }\n options.onMarkPlayed(mark.name, endedAt ?? options.now());\n }\n }\n\n function clear() {\n generation += 1;\n const scheduled = [...sources];\n sources.clear();\n marks = [];\n sourceSequence = 0;\n nextPlayAt = 0;\n\n for (const source of scheduled) {\n source.node.stop();\n }\n }\n\n return {\n enqueuePcm16(pcm16: Uint8Array) {\n const frameCount = Math.floor(pcm16.byteLength / 2);\n const buffer = context.createBuffer(1, frameCount, options.sampleRateHz);\n const samples = buffer.getChannelData(0);\n const view = new DataView(pcm16.buffer, pcm16.byteOffset, pcm16.byteLength);\n for (let index = 0; index < frameCount; index += 1) {\n samples[index] = view.getInt16(index * 2, true) / 32_768;\n }\n\n const node = context.createBufferSource();\n node.buffer = buffer;\n node.connect(sinkNode);\n // A pre-roll lookahead applies only when nothing is currently scheduled (fresh start or an\n // underrun) — once a run of chunks is already ahead of currentTime, back-to-back scheduling\n // continues from nextPlayAt exactly as before.\n const floor =\n nextPlayAt <= context.currentTime ? context.currentTime + preRollSec : nextPlayAt;\n const startAt = Math.max(context.currentTime, floor);\n nextPlayAt = startAt + frameCount / options.sampleRateHz;\n const source: PlaybackSource = {\n node,\n generation,\n sequence: ++sourceSequence,\n };\n sources.add(source);\n node.addEventListener(\"ended\", () => {\n if (source.generation !== generation) {\n return;\n }\n sources.delete(source);\n if (sources.size === 0) {\n const endedAt = options.now();\n lastPlaybackEndedAt = endedAt;\n acknowledgeReadyMarks(source.generation, endedAt);\n return;\n }\n acknowledgeReadyMarks(source.generation);\n });\n node.start(startAt);\n },\n attachMark(name: string) {\n if (marks.length >= 256) {\n clear();\n options.onOverflow?.();\n return;\n }\n marks.push({ name, generation, barrier: sourceSequence });\n acknowledgeReadyMarks(generation);\n },\n clear,\n stop(): Promise<void> {\n if (!closePromise) {\n clear();\n audioElement?.remove();\n closePromise = context.close();\n }\n return closePromise;\n },\n isPlaying() {\n return sources.size > 0;\n },\n suspend(): Promise<void> | undefined {\n if (closePromise) {\n return undefined;\n }\n return context.suspend();\n },\n resume(): Promise<void> | undefined {\n if (closePromise) {\n return undefined;\n }\n return context.resume();\n },\n get lastPlaybackEndedAt() {\n return lastPlaybackEndedAt;\n },\n };\n}\n","import type { TalkRealtimeRelayEvent, TalkRealtimeRelaySessionResult } from \"./types.ts\";\n\nexport type TalkLifecycle = \"idle\" | \"starting\" | \"active\" | \"interrupting\" | \"stopping\";\n\nexport type TalkRequest = <T>(method: string, params?: unknown) => Promise<T>;\n\nexport type TalkAudioCapture = {\n start(): Promise<void>;\n suspend(): Promise<void>;\n resume(): Promise<void>;\n stop(): Promise<void>;\n};\n\nexport type TalkAudioPlayback = {\n enqueuePcm16(frame: Uint8Array): void;\n attachMark(name: string): void;\n clear(): void;\n stop(): Promise<void>;\n isPlaying(): boolean;\n suspend?(): Promise<void> | undefined;\n resume?(): Promise<void> | undefined;\n readonly lastPlaybackEndedAt?: number | null;\n};\n\nexport type TalkSessionClientState = {\n lifecycle: TalkLifecycle;\n relaySessionId: string | null;\n provider: string | null;\n recording: boolean;\n playing: boolean;\n droppedAudioFrames: number;\n};\n\nexport type TalkSessionClientOptions = {\n request: TalkRequest;\n capture: (options: { onPcm16: (frame: Uint8Array) => void }) => TalkAudioCapture;\n playback: (options: {\n sampleRateHz: number;\n onMarkPlayed: (name: string, monotonicMs: number) => void;\n now: () => number;\n onOverflow?: () => void;\n }) => TalkAudioPlayback;\n onState: (state: TalkSessionClientState) => void;\n onEvent: (event: TalkRealtimeRelayEvent) => void;\n now?: () => number;\n};\n\nexport type TalkSessionClient = {\n start(): Promise<void>;\n handleRelayEvent(event: TalkRealtimeRelayEvent): void;\n handleGatewayClose(): void;\n stop(): Promise<void>;\n};\n\nconst MAX_IN_FLIGHT_AUDIO_REQUESTS = 4;\nconst ECHO_TAIL_SUPPRESS_MS = 500;\nconst RELAY_READY_TIMEOUT_MS = 10_000;\n\nfunction encodeBase64(bytes: Uint8Array): string {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n return btoa(binary);\n}\n\nfunction decodeBase64(value: string): Uint8Array {\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nexport function createTalkSessionClient(options: TalkSessionClientOptions): TalkSessionClient {\n const now = options.now ?? (() => performance.now());\n const inFlightAudioRequests = new Set<Promise<unknown>>();\n const remoteStopRequests = new Map<string, Promise<void>>();\n let lifecycle: TalkLifecycle = \"idle\";\n let relaySessionId: string | null = null;\n let provider: string | null = null;\n let capture: TalkAudioCapture | null = null;\n let playback: TalkAudioPlayback | null = null;\n let droppedAudioFrames = 0;\n let generation = 0;\n let startPromise: Promise<void> | null = null;\n let stopPromise: Promise<void> | null = null;\n let visibilityHandler: (() => void) | null = null;\n let visibilityHandlerGeneration: number | null = null;\n let readyWaiter: {\n relaySessionId: string;\n generation: number;\n resolve: () => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n } | null = null;\n let readySeen: { relaySessionId: string; generation: number } | null = null;\n\n function emitState() {\n options.onState({\n lifecycle,\n relaySessionId,\n provider,\n recording: capture !== null && (lifecycle === \"active\" || lifecycle === \"interrupting\"),\n playing: playback?.isPlaying() ?? false,\n droppedAudioFrames,\n });\n }\n\n function setLifecycle(next: TalkLifecycle) {\n lifecycle = next;\n emitState();\n }\n\n function stopRemoteOnce(id: string): Promise<void> {\n const existing = remoteStopRequests.get(id);\n if (existing) {\n return existing;\n }\n let pending: Promise<void>;\n try {\n pending = options\n .request<void>(\"talk.realtime.stop\", { relaySessionId: id })\n .catch(() => undefined);\n } catch {\n pending = Promise.resolve();\n }\n remoteStopRequests.set(id, pending);\n // Only the entry this call installed may be dropped; a later stop for the\n // same relay id owns the map from the moment it replaces this one.\n void pending\n .finally(() => {\n if (remoteStopRequests.get(id) === pending) {\n remoteStopRequests.delete(id);\n }\n })\n .catch(() => undefined);\n return pending;\n }\n\n function quietResource(promise: Promise<void> | undefined) {\n if (promise) {\n void promise.catch(() => undefined);\n }\n }\n\n function removeVisibilityHandler() {\n const handler = visibilityHandler;\n visibilityHandler = null;\n visibilityHandlerGeneration = null;\n if (!handler || typeof document === \"undefined\") {\n return;\n }\n document.removeEventListener(\"visibilitychange\", handler);\n }\n\n function clearReadyWaiter() {\n const waiter = readyWaiter;\n if (!waiter) {\n return;\n }\n readyWaiter = null;\n clearTimeout(waiter.timer);\n // Settle the abandoned waiter so the start continuation awaiting relay\n // readiness unblocks and its cleanup path (or stop()) can complete.\n waiter.reject(new Error(\"Relay readiness aborted\"));\n }\n\n function waitForRelayReady(ownerGeneration: number, ownerRelaySessionId: string): Promise<void> {\n if (\n readySeen?.relaySessionId === ownerRelaySessionId &&\n readySeen.generation === ownerGeneration\n ) {\n return Promise.resolve();\n }\n clearReadyWaiter();\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n if (readyWaiter?.generation === ownerGeneration) {\n readyWaiter = null;\n }\n resolve();\n }, RELAY_READY_TIMEOUT_MS);\n readyWaiter = {\n relaySessionId: ownerRelaySessionId,\n generation: ownerGeneration,\n resolve: () => {\n clearTimeout(timer);\n readyWaiter = null;\n resolve();\n },\n reject: (error: Error) => {\n clearTimeout(timer);\n readyWaiter = null;\n reject(error);\n },\n timer,\n };\n });\n }\n\n function installVisibilityHandler(ownerGeneration: number) {\n if (typeof document === \"undefined\") {\n return;\n }\n if (visibilityHandler !== null && visibilityHandlerGeneration === ownerGeneration) {\n return;\n }\n removeVisibilityHandler();\n // The handler is owned by the generation that installed it; a stale\n // handler from a torn-down session must never touch live resources.\n // relaySessionId is written exactly once per generation (at resource\n // install), so the generation fence also pins the relay identity.\n const handler = () => {\n if (generation !== ownerGeneration) {\n return;\n }\n const ownedCapture = capture;\n const ownedPlayback = playback;\n const ownedRelaySessionId = relaySessionId;\n if (!ownedCapture && !ownedPlayback) {\n return;\n }\n if (document.hidden) {\n try {\n quietResource(ownedCapture?.suspend());\n } catch {\n // Visibility suspension is best effort.\n }\n quietResource(ownedPlayback?.suspend?.());\n return;\n }\n if (ownedRelaySessionId === null) {\n return;\n }\n try {\n quietResource(ownedCapture?.resume());\n } catch {\n // See suspend above.\n }\n quietResource(ownedPlayback?.resume?.());\n };\n visibilityHandler = handler;\n visibilityHandlerGeneration = ownerGeneration;\n document.addEventListener(\"visibilitychange\", handler);\n }\n\n function failClosedOnPlaybackOverflow(ownerGeneration: number, ownerRelaySessionId: string) {\n if (generation !== ownerGeneration || relaySessionId !== ownerRelaySessionId) {\n return;\n }\n generation += 1;\n // Unblock a startOwned still waiting for relay readiness; its stale fence\n // then routes the continuation into cleanup instead of the 10s fallback.\n clearReadyWaiter();\n readySeen = null;\n inFlightAudioRequests.clear();\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n const localRelease = releaseLocal();\n setLifecycle(\"idle\");\n void (async () => {\n await localRelease;\n await stopRemoteOnce(ownerRelaySessionId);\n })();\n }\n\n function releaseLocal(): Promise<void> {\n const ownedCapture = capture;\n const ownedPlayback = playback;\n capture = null;\n playback = null;\n const releases: Promise<unknown>[] = [];\n\n if (ownedCapture) {\n try {\n releases.push(ownedCapture.stop());\n } catch {\n // Local release is best effort, but every owned resource still gets its stop call.\n }\n }\n if (ownedPlayback) {\n try {\n releases.push(ownedPlayback.stop());\n } catch {\n // See capture teardown above.\n }\n }\n return Promise.allSettled(releases).then(() => undefined);\n }\n\n function sendAudio(frame: Uint8Array, ownerGeneration: number, ownerRelaySessionId: string) {\n if (\n generation !== ownerGeneration ||\n relaySessionId !== ownerRelaySessionId ||\n (lifecycle !== \"active\" && lifecycle !== \"interrupting\")\n ) {\n return;\n }\n // Echo tail: the microphone can still carry assistant audio shortly after playback ends.\n // The generation/relay fence above guarantees any observable playback end belongs to the\n // current session, so a recent end suppresses the frame silently while playback is idle.\n if (playback !== null && !playback.isPlaying()) {\n const playbackEndedAt = playback.lastPlaybackEndedAt;\n if (\n playbackEndedAt !== null &&\n playbackEndedAt !== undefined &&\n now() - playbackEndedAt < ECHO_TAIL_SUPPRESS_MS\n ) {\n return;\n }\n }\n if (inFlightAudioRequests.size >= MAX_IN_FLIGHT_AUDIO_REQUESTS) {\n droppedAudioFrames += 1;\n emitState();\n return;\n }\n\n let pending: Promise<unknown>;\n try {\n pending = options.request<void>(\"talk.realtime.audio\", {\n relaySessionId: ownerRelaySessionId,\n audioBase64: encodeBase64(frame),\n timestamp: now(),\n });\n } catch {\n return;\n }\n inFlightAudioRequests.add(pending);\n const releaseIfCurrent = () => {\n if (generation === ownerGeneration && relaySessionId === ownerRelaySessionId) {\n inFlightAudioRequests.delete(pending);\n }\n };\n void pending.then(releaseIfCurrent, releaseIfCurrent);\n }\n\n function acknowledgeMark(\n name: string,\n monotonicMs: number,\n ownerGeneration: number,\n ownerRelaySessionId: string,\n ) {\n if (generation !== ownerGeneration || relaySessionId !== ownerRelaySessionId) {\n return;\n }\n try {\n void options\n .request<void>(\"talk.realtime.mark\", {\n relaySessionId: ownerRelaySessionId,\n markName: name,\n timestamp: monotonicMs,\n })\n .catch(() => undefined);\n } catch {\n // Playback acknowledgement is best effort after local playback has completed.\n }\n emitState();\n }\n\n async function startOwned(ownerGeneration: number): Promise<void> {\n let session: TalkRealtimeRelaySessionResult;\n try {\n session = await options.request<TalkRealtimeRelaySessionResult>(\"talk.realtime.session\", {\n transport: \"gateway-relay\",\n });\n } catch (error) {\n if (generation !== ownerGeneration) {\n return;\n }\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n setLifecycle(\"idle\");\n throw error;\n }\n\n if (generation !== ownerGeneration) {\n await stopRemoteOnce(session.relaySessionId);\n return;\n }\n\n relaySessionId = session.relaySessionId;\n provider = session.provider;\n try {\n const playbackOptions: {\n sampleRateHz: number;\n onMarkPlayed: (name: string, monotonicMs: number) => void;\n now: () => number;\n onOverflow?: () => void;\n } = {\n sampleRateHz: session.audio.outputSampleRateHz,\n onMarkPlayed: (name, monotonicMs) =>\n acknowledgeMark(name, monotonicMs, ownerGeneration, session.relaySessionId),\n now,\n onOverflow: () => failClosedOnPlaybackOverflow(ownerGeneration, session.relaySessionId),\n };\n playback = options.playback(playbackOptions);\n try {\n await playback.resume?.();\n } catch {\n // Autoplay resume is best effort; capture startup must still proceed.\n }\n if (generation !== ownerGeneration) {\n throw new Error(\"Talk start aborted: session superseded during playback resume\");\n }\n capture = options.capture({\n onPcm16: (frame) => sendAudio(frame, ownerGeneration, session.relaySessionId),\n });\n await waitForRelayReady(ownerGeneration, session.relaySessionId);\n if (generation !== ownerGeneration) {\n throw new Error(\"Talk start aborted: session superseded before capture start\");\n }\n await capture.start();\n } catch (error) {\n const isCurrent = generation === ownerGeneration;\n if (isCurrent) {\n generation += 1;\n clearReadyWaiter();\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n }\n await releaseLocal();\n await stopRemoteOnce(session.relaySessionId);\n if (isCurrent) {\n setLifecycle(\"idle\");\n throw error;\n }\n return;\n }\n\n if (generation !== ownerGeneration || relaySessionId !== session.relaySessionId) {\n await releaseLocal();\n await stopRemoteOnce(session.relaySessionId);\n return;\n }\n if (typeof document !== \"undefined\" && document.hidden) {\n // A session that becomes active while hidden starts suspended; the fence\n // above guarantees these resources still belong to the current generation.\n try {\n quietResource(capture?.suspend());\n } catch {\n // Visibility suspension is best effort.\n }\n quietResource(playback?.suspend?.());\n }\n setLifecycle(\"active\");\n }\n\n function start(): Promise<void> {\n if (stopPromise) {\n return stopPromise.then(() => start());\n }\n if (startPromise) {\n return startPromise;\n }\n if (relaySessionId) {\n return Promise.resolve();\n }\n\n const ownerGeneration = ++generation;\n droppedAudioFrames = 0;\n // Armed at claim time so a hide during the pending session request is not\n // lost; resources installing later suspend themselves while hidden.\n installVisibilityHandler(ownerGeneration);\n setLifecycle(\"starting\");\n const pending = startOwned(ownerGeneration);\n startPromise = pending;\n void pending.then(\n () => {\n if (startPromise === pending) {\n startPromise = null;\n }\n },\n () => {\n if (startPromise === pending) {\n startPromise = null;\n }\n },\n );\n return pending;\n }\n\n function stop(): Promise<void> {\n if (stopPromise) {\n return stopPromise;\n }\n\n const stopGeneration = ++generation;\n clearReadyWaiter();\n readySeen = null;\n const ownedRelaySessionId = relaySessionId;\n const ownedStart = startPromise;\n inFlightAudioRequests.clear();\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n const localRelease = releaseLocal();\n setLifecycle(\"stopping\");\n\n const pending = (async () => {\n await localRelease;\n if (ownedRelaySessionId) {\n await stopRemoteOnce(ownedRelaySessionId);\n }\n if (ownedStart) {\n await ownedStart.catch(() => undefined);\n }\n if (generation === stopGeneration) {\n setLifecycle(\"idle\");\n }\n })();\n stopPromise = pending;\n void pending.then(\n () => {\n if (stopPromise === pending) {\n stopPromise = null;\n }\n },\n () => {\n if (stopPromise === pending) {\n stopPromise = null;\n }\n },\n );\n return pending;\n }\n\n function handleRelayEvent(event: TalkRealtimeRelayEvent) {\n if (event.relaySessionId !== relaySessionId) {\n return;\n }\n\n switch (event.type) {\n case \"audio\":\n playback?.enqueuePcm16(decodeBase64(event.audioBase64));\n if (lifecycle === \"interrupting\") {\n setLifecycle(\"active\");\n } else {\n emitState();\n }\n break;\n case \"mark\":\n playback?.attachMark(event.markName);\n emitState();\n break;\n case \"clear\":\n case \"vadBargeIn\": {\n if (lifecycle === \"interrupting\") {\n break;\n }\n playback?.clear();\n setLifecycle(\"interrupting\");\n break;\n }\n case \"ready\":\n // Latch readiness for this generation so a ready event that arrives\n // while the start continuation is still awaiting playback resume is\n // not dropped in front of the waiter installation.\n readySeen = { relaySessionId: event.relaySessionId, generation };\n if (\n readyWaiter?.relaySessionId === event.relaySessionId &&\n readyWaiter.generation === generation\n ) {\n readyWaiter.resolve();\n }\n if (lifecycle === \"interrupting\") {\n setLifecycle(\"active\");\n }\n break;\n case \"transcript\":\n if (event.role === \"assistant\" && lifecycle === \"interrupting\") {\n setLifecycle(\"active\");\n }\n break;\n case \"close\": {\n generation += 1;\n clearReadyWaiter();\n readySeen = null;\n inFlightAudioRequests.clear();\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n const localRelease = releaseLocal();\n setLifecycle(\"idle\");\n void localRelease;\n break;\n }\n default:\n break;\n }\n options.onEvent(event);\n }\n\n return {\n start,\n handleRelayEvent,\n handleGatewayClose() {\n void stop();\n },\n stop,\n };\n}\n\nexport type { TalkRealtimeRelayEvent, TalkRealtimeRelaySessionResult };\n","import { ChannelsStatusSnapshot } from \"../types.ts\";\nimport type { ChannelsState } from \"./channels.types.ts\";\n\nexport type { ChannelsState };\n\nexport async function loadChannels(state: ChannelsState, probe: boolean) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.channelsLoading) {\n return;\n }\n state.channelsLoading = true;\n state.channelsError = null;\n try {\n const res = await state.client.request<ChannelsStatusSnapshot | null>(\"channels.status\", {\n probe,\n timeoutMs: 8000,\n });\n state.channelsSnapshot = res;\n state.channelsLastSuccess = Date.now();\n } catch (err) {\n state.channelsError = String(err);\n } finally {\n state.channelsLoading = false;\n }\n}\n\nexport async function startWhatsAppLogin(state: ChannelsState, force: boolean) {\n if (!state.client || !state.connected || state.whatsappBusy) {\n return;\n }\n state.whatsappBusy = true;\n try {\n const res = await state.client.request<{ message?: string; qrDataUrl?: string }>(\n \"web.login.start\",\n {\n force,\n timeoutMs: 30000,\n },\n );\n state.whatsappLoginMessage = res.message ?? null;\n state.whatsappLoginQrDataUrl = res.qrDataUrl ?? null;\n state.whatsappLoginConnected = null;\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n state.whatsappLoginQrDataUrl = null;\n state.whatsappLoginConnected = null;\n } finally {\n state.whatsappBusy = false;\n }\n}\n\nexport async function waitWhatsAppLogin(state: ChannelsState) {\n if (!state.client || !state.connected || state.whatsappBusy) {\n return;\n }\n state.whatsappBusy = true;\n try {\n const res = await state.client.request<{ message?: string; connected?: boolean }>(\n \"web.login.wait\",\n {\n timeoutMs: 120000,\n },\n );\n state.whatsappLoginMessage = res.message ?? null;\n state.whatsappLoginConnected = res.connected ?? null;\n if (res.connected) {\n state.whatsappLoginQrDataUrl = null;\n }\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n state.whatsappLoginConnected = null;\n } finally {\n state.whatsappBusy = false;\n }\n}\n\nexport async function logoutWhatsApp(state: ChannelsState) {\n if (!state.client || !state.connected || state.whatsappBusy) {\n return;\n }\n state.whatsappBusy = true;\n try {\n await state.client.request(\"channels.logout\", { channel: \"whatsapp\" });\n state.whatsappLoginMessage = \"Logged out.\";\n state.whatsappLoginQrDataUrl = null;\n state.whatsappLoginConnected = null;\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n } finally {\n state.whatsappBusy = false;\n }\n}\n","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(global.JSON5 = factory());\n}(this, (function () { 'use strict';\n\n\tfunction createCommonjsModule(fn, module) {\n\t\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n\t}\n\n\tvar _global = createCommonjsModule(function (module) {\n\t// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\n\tvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n\t ? window : typeof self != 'undefined' && self.Math == Math ? self\n\t // eslint-disable-next-line no-new-func\n\t : Function('return this')();\n\tif (typeof __g == 'number') { __g = global; } // eslint-disable-line no-undef\n\t});\n\n\tvar _core = createCommonjsModule(function (module) {\n\tvar core = module.exports = { version: '2.6.5' };\n\tif (typeof __e == 'number') { __e = core; } // eslint-disable-line no-undef\n\t});\n\tvar _core_1 = _core.version;\n\n\tvar _isObject = function (it) {\n\t return typeof it === 'object' ? it !== null : typeof it === 'function';\n\t};\n\n\tvar _anObject = function (it) {\n\t if (!_isObject(it)) { throw TypeError(it + ' is not an object!'); }\n\t return it;\n\t};\n\n\tvar _fails = function (exec) {\n\t try {\n\t return !!exec();\n\t } catch (e) {\n\t return true;\n\t }\n\t};\n\n\t// Thank's IE8 for his funny defineProperty\n\tvar _descriptors = !_fails(function () {\n\t return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n\t});\n\n\tvar document = _global.document;\n\t// typeof document.createElement is 'object' in old IE\n\tvar is = _isObject(document) && _isObject(document.createElement);\n\tvar _domCreate = function (it) {\n\t return is ? document.createElement(it) : {};\n\t};\n\n\tvar _ie8DomDefine = !_descriptors && !_fails(function () {\n\t return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7;\n\t});\n\n\t// 7.1.1 ToPrimitive(input [, PreferredType])\n\n\t// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n\t// and the second argument - flag - preferred type is a string\n\tvar _toPrimitive = function (it, S) {\n\t if (!_isObject(it)) { return it; }\n\t var fn, val;\n\t if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; }\n\t if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) { return val; }\n\t if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; }\n\t throw TypeError(\"Can't convert object to primitive value\");\n\t};\n\n\tvar dP = Object.defineProperty;\n\n\tvar f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n\t _anObject(O);\n\t P = _toPrimitive(P, true);\n\t _anObject(Attributes);\n\t if (_ie8DomDefine) { try {\n\t return dP(O, P, Attributes);\n\t } catch (e) { /* empty */ } }\n\t if ('get' in Attributes || 'set' in Attributes) { throw TypeError('Accessors not supported!'); }\n\t if ('value' in Attributes) { O[P] = Attributes.value; }\n\t return O;\n\t};\n\n\tvar _objectDp = {\n\t\tf: f\n\t};\n\n\tvar _propertyDesc = function (bitmap, value) {\n\t return {\n\t enumerable: !(bitmap & 1),\n\t configurable: !(bitmap & 2),\n\t writable: !(bitmap & 4),\n\t value: value\n\t };\n\t};\n\n\tvar _hide = _descriptors ? function (object, key, value) {\n\t return _objectDp.f(object, key, _propertyDesc(1, value));\n\t} : function (object, key, value) {\n\t object[key] = value;\n\t return object;\n\t};\n\n\tvar hasOwnProperty = {}.hasOwnProperty;\n\tvar _has = function (it, key) {\n\t return hasOwnProperty.call(it, key);\n\t};\n\n\tvar id = 0;\n\tvar px = Math.random();\n\tvar _uid = function (key) {\n\t return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n\t};\n\n\tvar _library = false;\n\n\tvar _shared = createCommonjsModule(function (module) {\n\tvar SHARED = '__core-js_shared__';\n\tvar store = _global[SHARED] || (_global[SHARED] = {});\n\n\t(module.exports = function (key, value) {\n\t return store[key] || (store[key] = value !== undefined ? value : {});\n\t})('versions', []).push({\n\t version: _core.version,\n\t mode: _library ? 'pure' : 'global',\n\t copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n\t});\n\t});\n\n\tvar _functionToString = _shared('native-function-to-string', Function.toString);\n\n\tvar _redefine = createCommonjsModule(function (module) {\n\tvar SRC = _uid('src');\n\n\tvar TO_STRING = 'toString';\n\tvar TPL = ('' + _functionToString).split(TO_STRING);\n\n\t_core.inspectSource = function (it) {\n\t return _functionToString.call(it);\n\t};\n\n\t(module.exports = function (O, key, val, safe) {\n\t var isFunction = typeof val == 'function';\n\t if (isFunction) { _has(val, 'name') || _hide(val, 'name', key); }\n\t if (O[key] === val) { return; }\n\t if (isFunction) { _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); }\n\t if (O === _global) {\n\t O[key] = val;\n\t } else if (!safe) {\n\t delete O[key];\n\t _hide(O, key, val);\n\t } else if (O[key]) {\n\t O[key] = val;\n\t } else {\n\t _hide(O, key, val);\n\t }\n\t// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n\t})(Function.prototype, TO_STRING, function toString() {\n\t return typeof this == 'function' && this[SRC] || _functionToString.call(this);\n\t});\n\t});\n\n\tvar _aFunction = function (it) {\n\t if (typeof it != 'function') { throw TypeError(it + ' is not a function!'); }\n\t return it;\n\t};\n\n\t// optional / simple context binding\n\n\tvar _ctx = function (fn, that, length) {\n\t _aFunction(fn);\n\t if (that === undefined) { return fn; }\n\t switch (length) {\n\t case 1: return function (a) {\n\t return fn.call(that, a);\n\t };\n\t case 2: return function (a, b) {\n\t return fn.call(that, a, b);\n\t };\n\t case 3: return function (a, b, c) {\n\t return fn.call(that, a, b, c);\n\t };\n\t }\n\t return function (/* ...args */) {\n\t return fn.apply(that, arguments);\n\t };\n\t};\n\n\tvar PROTOTYPE = 'prototype';\n\n\tvar $export = function (type, name, source) {\n\t var IS_FORCED = type & $export.F;\n\t var IS_GLOBAL = type & $export.G;\n\t var IS_STATIC = type & $export.S;\n\t var IS_PROTO = type & $export.P;\n\t var IS_BIND = type & $export.B;\n\t var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];\n\t var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});\n\t var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n\t var key, own, out, exp;\n\t if (IS_GLOBAL) { source = name; }\n\t for (key in source) {\n\t // contains in native\n\t own = !IS_FORCED && target && target[key] !== undefined;\n\t // export native or passed\n\t out = (own ? target : source)[key];\n\t // bind timers to global for call from export context\n\t exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;\n\t // extend global\n\t if (target) { _redefine(target, key, out, type & $export.U); }\n\t // export\n\t if (exports[key] != out) { _hide(exports, key, exp); }\n\t if (IS_PROTO && expProto[key] != out) { expProto[key] = out; }\n\t }\n\t};\n\t_global.core = _core;\n\t// type bitmap\n\t$export.F = 1; // forced\n\t$export.G = 2; // global\n\t$export.S = 4; // static\n\t$export.P = 8; // proto\n\t$export.B = 16; // bind\n\t$export.W = 32; // wrap\n\t$export.U = 64; // safe\n\t$export.R = 128; // real proto method for `library`\n\tvar _export = $export;\n\n\t// 7.1.4 ToInteger\n\tvar ceil = Math.ceil;\n\tvar floor = Math.floor;\n\tvar _toInteger = function (it) {\n\t return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n\t};\n\n\t// 7.2.1 RequireObjectCoercible(argument)\n\tvar _defined = function (it) {\n\t if (it == undefined) { throw TypeError(\"Can't call method on \" + it); }\n\t return it;\n\t};\n\n\t// true -> String#at\n\t// false -> String#codePointAt\n\tvar _stringAt = function (TO_STRING) {\n\t return function (that, pos) {\n\t var s = String(_defined(that));\n\t var i = _toInteger(pos);\n\t var l = s.length;\n\t var a, b;\n\t if (i < 0 || i >= l) { return TO_STRING ? '' : undefined; }\n\t a = s.charCodeAt(i);\n\t return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n\t ? TO_STRING ? s.charAt(i) : a\n\t : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n\t };\n\t};\n\n\tvar $at = _stringAt(false);\n\t_export(_export.P, 'String', {\n\t // 21.1.3.3 String.prototype.codePointAt(pos)\n\t codePointAt: function codePointAt(pos) {\n\t return $at(this, pos);\n\t }\n\t});\n\n\tvar codePointAt = _core.String.codePointAt;\n\n\tvar max = Math.max;\n\tvar min = Math.min;\n\tvar _toAbsoluteIndex = function (index, length) {\n\t index = _toInteger(index);\n\t return index < 0 ? max(index + length, 0) : min(index, length);\n\t};\n\n\tvar fromCharCode = String.fromCharCode;\n\tvar $fromCodePoint = String.fromCodePoint;\n\n\t// length should be 1, old FF problem\n\t_export(_export.S + _export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {\n\t // 21.1.2.2 String.fromCodePoint(...codePoints)\n\t fromCodePoint: function fromCodePoint(x) {\n\t var arguments$1 = arguments;\n\t // eslint-disable-line no-unused-vars\n\t var res = [];\n\t var aLen = arguments.length;\n\t var i = 0;\n\t var code;\n\t while (aLen > i) {\n\t code = +arguments$1[i++];\n\t if (_toAbsoluteIndex(code, 0x10ffff) !== code) { throw RangeError(code + ' is not a valid code point'); }\n\t res.push(code < 0x10000\n\t ? fromCharCode(code)\n\t : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)\n\t );\n\t } return res.join('');\n\t }\n\t});\n\n\tvar fromCodePoint = _core.String.fromCodePoint;\n\n\t// This is a generated file. Do not edit.\n\tvar Space_Separator = /[\\u1680\\u2000-\\u200A\\u202F\\u205F\\u3000]/;\n\tvar ID_Start = /[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u08A0-\\u08B4\\u08B6-\\u08BD\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312E\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FEA\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7AE\\uA7B0-\\uA7B7\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB65\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDD40-\\uDD74\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF4A\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF\\uDFD1-\\uDFD5]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE33\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2]|\\uD804[\\uDC03-\\uDC37\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDF00-\\uDF19]|\\uD806[\\uDCA0-\\uDCDF\\uDCFF\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE83\\uDE86-\\uDE89\\uDEC0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC00-\\uDC6E\\uDC80-\\uDD43]|[\\uD80C\\uD81C-\\uD820\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDF00-\\uDF44\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1]|\\uD821[\\uDC00-\\uDFEC]|\\uD822[\\uDC00-\\uDEF2]|\\uD82C[\\uDC00-\\uDD1E\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDED6\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF34\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]/;\n\tvar ID_Continue = /[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u0860-\\u086A\\u08A0-\\u08B4\\u08B6-\\u08BD\\u08D4-\\u08E1\\u08E3-\\u0963\\u0966-\\u096F\\u0971-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u09FC\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0AF9-\\u0AFF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C00-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58-\\u0C5A\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C80-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D00-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D54-\\u0D57\\u0D5F-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DE6-\\u0DEF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19D9\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1AB0-\\u1ABD\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1C80-\\u1C88\\u1CD0-\\u1CD2\\u1CD4-\\u1CF9\\u1D00-\\u1DF9\\u1DFB-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u2E2F\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099\\u309A\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312E\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FEA\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7AE\\uA7B0-\\uA7B7\\uA7F7-\\uA827\\uA840-\\uA873\\uA880-\\uA8C5\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA8FD\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uA9E0-\\uA9FE\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB65\\uAB70-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE2F\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDD40-\\uDD74\\uDDFD\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDEE0\\uDF00-\\uDF1F\\uDF2D-\\uDF4A\\uDF50-\\uDF7A\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF\\uDFD1-\\uDFD5]|\\uD801[\\uDC00-\\uDC9D\\uDCA0-\\uDCA9\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00-\\uDE03\\uDE05\\uDE06\\uDE0C-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE33\\uDE38-\\uDE3A\\uDE3F\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE6\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2]|\\uD804[\\uDC00-\\uDC46\\uDC66-\\uDC6F\\uDC7F-\\uDCBA\\uDCD0-\\uDCE8\\uDCF0-\\uDCF9\\uDD00-\\uDD34\\uDD36-\\uDD3F\\uDD50-\\uDD73\\uDD76\\uDD80-\\uDDC4\\uDDCA-\\uDDCC\\uDDD0-\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE37\\uDE3E\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEEA\\uDEF0-\\uDEF9\\uDF00-\\uDF03\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3C-\\uDF44\\uDF47\\uDF48\\uDF4B-\\uDF4D\\uDF50\\uDF57\\uDF5D-\\uDF63\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDC00-\\uDC4A\\uDC50-\\uDC59\\uDC80-\\uDCC5\\uDCC7\\uDCD0-\\uDCD9\\uDD80-\\uDDB5\\uDDB8-\\uDDC0\\uDDD8-\\uDDDD\\uDE00-\\uDE40\\uDE44\\uDE50-\\uDE59\\uDE80-\\uDEB7\\uDEC0-\\uDEC9\\uDF00-\\uDF19\\uDF1D-\\uDF2B\\uDF30-\\uDF39]|\\uD806[\\uDCA0-\\uDCE9\\uDCFF\\uDE00-\\uDE3E\\uDE47\\uDE50-\\uDE83\\uDE86-\\uDE99\\uDEC0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC36\\uDC38-\\uDC40\\uDC50-\\uDC59\\uDC72-\\uDC8F\\uDC92-\\uDCA7\\uDCA9-\\uDCB6\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD36\\uDD3A\\uDD3C\\uDD3D\\uDD3F-\\uDD47\\uDD50-\\uDD59]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC00-\\uDC6E\\uDC80-\\uDD43]|[\\uD80C\\uD81C-\\uD820\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE60-\\uDE69\\uDED0-\\uDEED\\uDEF0-\\uDEF4\\uDF00-\\uDF36\\uDF40-\\uDF43\\uDF50-\\uDF59\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDF00-\\uDF44\\uDF50-\\uDF7E\\uDF8F-\\uDF9F\\uDFE0\\uDFE1]|\\uD821[\\uDC00-\\uDFEC]|\\uD822[\\uDC00-\\uDEF2]|\\uD82C[\\uDC00-\\uDD1E\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99\\uDC9D\\uDC9E]|\\uD834[\\uDD65-\\uDD69\\uDD6D-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB\\uDFCE-\\uDFFF]|\\uD836[\\uDE00-\\uDE36\\uDE3B-\\uDE6C\\uDE75\\uDE84\\uDE9B-\\uDE9F\\uDEA1-\\uDEAF]|\\uD838[\\uDC00-\\uDC06\\uDC08-\\uDC18\\uDC1B-\\uDC21\\uDC23\\uDC24\\uDC26-\\uDC2A]|\\uD83A[\\uDC00-\\uDCC4\\uDCD0-\\uDCD6\\uDD00-\\uDD4A\\uDD50-\\uDD59]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDED6\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF34\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uDB40[\\uDD00-\\uDDEF]/;\n\n\tvar unicode = {\n\t\tSpace_Separator: Space_Separator,\n\t\tID_Start: ID_Start,\n\t\tID_Continue: ID_Continue\n\t};\n\n\tvar util = {\n\t isSpaceSeparator: function isSpaceSeparator (c) {\n\t return typeof c === 'string' && unicode.Space_Separator.test(c)\n\t },\n\n\t isIdStartChar: function isIdStartChar (c) {\n\t return typeof c === 'string' && (\n\t (c >= 'a' && c <= 'z') ||\n\t (c >= 'A' && c <= 'Z') ||\n\t (c === '$') || (c === '_') ||\n\t unicode.ID_Start.test(c)\n\t )\n\t },\n\n\t isIdContinueChar: function isIdContinueChar (c) {\n\t return typeof c === 'string' && (\n\t (c >= 'a' && c <= 'z') ||\n\t (c >= 'A' && c <= 'Z') ||\n\t (c >= '0' && c <= '9') ||\n\t (c === '$') || (c === '_') ||\n\t (c === '\\u200C') || (c === '\\u200D') ||\n\t unicode.ID_Continue.test(c)\n\t )\n\t },\n\n\t isDigit: function isDigit (c) {\n\t return typeof c === 'string' && /[0-9]/.test(c)\n\t },\n\n\t isHexDigit: function isHexDigit (c) {\n\t return typeof c === 'string' && /[0-9A-Fa-f]/.test(c)\n\t },\n\t};\n\n\tvar source;\n\tvar parseState;\n\tvar stack;\n\tvar pos;\n\tvar line;\n\tvar column;\n\tvar token;\n\tvar key;\n\tvar root;\n\n\tvar parse = function parse (text, reviver) {\n\t source = String(text);\n\t parseState = 'start';\n\t stack = [];\n\t pos = 0;\n\t line = 1;\n\t column = 0;\n\t token = undefined;\n\t key = undefined;\n\t root = undefined;\n\n\t do {\n\t token = lex();\n\n\t // This code is unreachable.\n\t // if (!parseStates[parseState]) {\n\t // throw invalidParseState()\n\t // }\n\n\t parseStates[parseState]();\n\t } while (token.type !== 'eof')\n\n\t if (typeof reviver === 'function') {\n\t return internalize({'': root}, '', reviver)\n\t }\n\n\t return root\n\t};\n\n\tfunction internalize (holder, name, reviver) {\n\t var value = holder[name];\n\t if (value != null && typeof value === 'object') {\n\t if (Array.isArray(value)) {\n\t for (var i = 0; i < value.length; i++) {\n\t var key = String(i);\n\t var replacement = internalize(value, key, reviver);\n\t if (replacement === undefined) {\n\t delete value[key];\n\t } else {\n\t Object.defineProperty(value, key, {\n\t value: replacement,\n\t writable: true,\n\t enumerable: true,\n\t configurable: true,\n\t });\n\t }\n\t }\n\t } else {\n\t for (var key$1 in value) {\n\t var replacement$1 = internalize(value, key$1, reviver);\n\t if (replacement$1 === undefined) {\n\t delete value[key$1];\n\t } else {\n\t Object.defineProperty(value, key$1, {\n\t value: replacement$1,\n\t writable: true,\n\t enumerable: true,\n\t configurable: true,\n\t });\n\t }\n\t }\n\t }\n\t }\n\n\t return reviver.call(holder, name, value)\n\t}\n\n\tvar lexState;\n\tvar buffer;\n\tvar doubleQuote;\n\tvar sign;\n\tvar c;\n\n\tfunction lex () {\n\t lexState = 'default';\n\t buffer = '';\n\t doubleQuote = false;\n\t sign = 1;\n\n\t for (;;) {\n\t c = peek();\n\n\t // This code is unreachable.\n\t // if (!lexStates[lexState]) {\n\t // throw invalidLexState(lexState)\n\t // }\n\n\t var token = lexStates[lexState]();\n\t if (token) {\n\t return token\n\t }\n\t }\n\t}\n\n\tfunction peek () {\n\t if (source[pos]) {\n\t return String.fromCodePoint(source.codePointAt(pos))\n\t }\n\t}\n\n\tfunction read () {\n\t var c = peek();\n\n\t if (c === '\\n') {\n\t line++;\n\t column = 0;\n\t } else if (c) {\n\t column += c.length;\n\t } else {\n\t column++;\n\t }\n\n\t if (c) {\n\t pos += c.length;\n\t }\n\n\t return c\n\t}\n\n\tvar lexStates = {\n\t default: function default$1 () {\n\t switch (c) {\n\t case '\\t':\n\t case '\\v':\n\t case '\\f':\n\t case ' ':\n\t case '\\u00A0':\n\t case '\\uFEFF':\n\t case '\\n':\n\t case '\\r':\n\t case '\\u2028':\n\t case '\\u2029':\n\t read();\n\t return\n\n\t case '/':\n\t read();\n\t lexState = 'comment';\n\t return\n\n\t case undefined:\n\t read();\n\t return newToken('eof')\n\t }\n\n\t if (util.isSpaceSeparator(c)) {\n\t read();\n\t return\n\t }\n\n\t // This code is unreachable.\n\t // if (!lexStates[parseState]) {\n\t // throw invalidLexState(parseState)\n\t // }\n\n\t return lexStates[parseState]()\n\t },\n\n\t comment: function comment () {\n\t switch (c) {\n\t case '*':\n\t read();\n\t lexState = 'multiLineComment';\n\t return\n\n\t case '/':\n\t read();\n\t lexState = 'singleLineComment';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t multiLineComment: function multiLineComment () {\n\t switch (c) {\n\t case '*':\n\t read();\n\t lexState = 'multiLineCommentAsterisk';\n\t return\n\n\t case undefined:\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t },\n\n\t multiLineCommentAsterisk: function multiLineCommentAsterisk () {\n\t switch (c) {\n\t case '*':\n\t read();\n\t return\n\n\t case '/':\n\t read();\n\t lexState = 'default';\n\t return\n\n\t case undefined:\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t lexState = 'multiLineComment';\n\t },\n\n\t singleLineComment: function singleLineComment () {\n\t switch (c) {\n\t case '\\n':\n\t case '\\r':\n\t case '\\u2028':\n\t case '\\u2029':\n\t read();\n\t lexState = 'default';\n\t return\n\n\t case undefined:\n\t read();\n\t return newToken('eof')\n\t }\n\n\t read();\n\t },\n\n\t value: function value () {\n\t switch (c) {\n\t case '{':\n\t case '[':\n\t return newToken('punctuator', read())\n\n\t case 'n':\n\t read();\n\t literal('ull');\n\t return newToken('null', null)\n\n\t case 't':\n\t read();\n\t literal('rue');\n\t return newToken('boolean', true)\n\n\t case 'f':\n\t read();\n\t literal('alse');\n\t return newToken('boolean', false)\n\n\t case '-':\n\t case '+':\n\t if (read() === '-') {\n\t sign = -1;\n\t }\n\n\t lexState = 'sign';\n\t return\n\n\t case '.':\n\t buffer = read();\n\t lexState = 'decimalPointLeading';\n\t return\n\n\t case '0':\n\t buffer = read();\n\t lexState = 'zero';\n\t return\n\n\t case '1':\n\t case '2':\n\t case '3':\n\t case '4':\n\t case '5':\n\t case '6':\n\t case '7':\n\t case '8':\n\t case '9':\n\t buffer = read();\n\t lexState = 'decimalInteger';\n\t return\n\n\t case 'I':\n\t read();\n\t literal('nfinity');\n\t return newToken('numeric', Infinity)\n\n\t case 'N':\n\t read();\n\t literal('aN');\n\t return newToken('numeric', NaN)\n\n\t case '\"':\n\t case \"'\":\n\t doubleQuote = (read() === '\"');\n\t buffer = '';\n\t lexState = 'string';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t identifierNameStartEscape: function identifierNameStartEscape () {\n\t if (c !== 'u') {\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t var u = unicodeEscape();\n\t switch (u) {\n\t case '$':\n\t case '_':\n\t break\n\n\t default:\n\t if (!util.isIdStartChar(u)) {\n\t throw invalidIdentifier()\n\t }\n\n\t break\n\t }\n\n\t buffer += u;\n\t lexState = 'identifierName';\n\t },\n\n\t identifierName: function identifierName () {\n\t switch (c) {\n\t case '$':\n\t case '_':\n\t case '\\u200C':\n\t case '\\u200D':\n\t buffer += read();\n\t return\n\n\t case '\\\\':\n\t read();\n\t lexState = 'identifierNameEscape';\n\t return\n\t }\n\n\t if (util.isIdContinueChar(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('identifier', buffer)\n\t },\n\n\t identifierNameEscape: function identifierNameEscape () {\n\t if (c !== 'u') {\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t var u = unicodeEscape();\n\t switch (u) {\n\t case '$':\n\t case '_':\n\t case '\\u200C':\n\t case '\\u200D':\n\t break\n\n\t default:\n\t if (!util.isIdContinueChar(u)) {\n\t throw invalidIdentifier()\n\t }\n\n\t break\n\t }\n\n\t buffer += u;\n\t lexState = 'identifierName';\n\t },\n\n\t sign: function sign$1 () {\n\t switch (c) {\n\t case '.':\n\t buffer = read();\n\t lexState = 'decimalPointLeading';\n\t return\n\n\t case '0':\n\t buffer = read();\n\t lexState = 'zero';\n\t return\n\n\t case '1':\n\t case '2':\n\t case '3':\n\t case '4':\n\t case '5':\n\t case '6':\n\t case '7':\n\t case '8':\n\t case '9':\n\t buffer = read();\n\t lexState = 'decimalInteger';\n\t return\n\n\t case 'I':\n\t read();\n\t literal('nfinity');\n\t return newToken('numeric', sign * Infinity)\n\n\t case 'N':\n\t read();\n\t literal('aN');\n\t return newToken('numeric', NaN)\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t zero: function zero () {\n\t switch (c) {\n\t case '.':\n\t buffer += read();\n\t lexState = 'decimalPoint';\n\t return\n\n\t case 'e':\n\t case 'E':\n\t buffer += read();\n\t lexState = 'decimalExponent';\n\t return\n\n\t case 'x':\n\t case 'X':\n\t buffer += read();\n\t lexState = 'hexadecimal';\n\t return\n\t }\n\n\t return newToken('numeric', sign * 0)\n\t },\n\n\t decimalInteger: function decimalInteger () {\n\t switch (c) {\n\t case '.':\n\t buffer += read();\n\t lexState = 'decimalPoint';\n\t return\n\n\t case 'e':\n\t case 'E':\n\t buffer += read();\n\t lexState = 'decimalExponent';\n\t return\n\t }\n\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t decimalPointLeading: function decimalPointLeading () {\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t lexState = 'decimalFraction';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t decimalPoint: function decimalPoint () {\n\t switch (c) {\n\t case 'e':\n\t case 'E':\n\t buffer += read();\n\t lexState = 'decimalExponent';\n\t return\n\t }\n\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t lexState = 'decimalFraction';\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t decimalFraction: function decimalFraction () {\n\t switch (c) {\n\t case 'e':\n\t case 'E':\n\t buffer += read();\n\t lexState = 'decimalExponent';\n\t return\n\t }\n\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t decimalExponent: function decimalExponent () {\n\t switch (c) {\n\t case '+':\n\t case '-':\n\t buffer += read();\n\t lexState = 'decimalExponentSign';\n\t return\n\t }\n\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t lexState = 'decimalExponentInteger';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t decimalExponentSign: function decimalExponentSign () {\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t lexState = 'decimalExponentInteger';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t decimalExponentInteger: function decimalExponentInteger () {\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t hexadecimal: function hexadecimal () {\n\t if (util.isHexDigit(c)) {\n\t buffer += read();\n\t lexState = 'hexadecimalInteger';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t hexadecimalInteger: function hexadecimalInteger () {\n\t if (util.isHexDigit(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t string: function string () {\n\t switch (c) {\n\t case '\\\\':\n\t read();\n\t buffer += escape();\n\t return\n\n\t case '\"':\n\t if (doubleQuote) {\n\t read();\n\t return newToken('string', buffer)\n\t }\n\n\t buffer += read();\n\t return\n\n\t case \"'\":\n\t if (!doubleQuote) {\n\t read();\n\t return newToken('string', buffer)\n\t }\n\n\t buffer += read();\n\t return\n\n\t case '\\n':\n\t case '\\r':\n\t throw invalidChar(read())\n\n\t case '\\u2028':\n\t case '\\u2029':\n\t separatorChar(c);\n\t break\n\n\t case undefined:\n\t throw invalidChar(read())\n\t }\n\n\t buffer += read();\n\t },\n\n\t start: function start () {\n\t switch (c) {\n\t case '{':\n\t case '[':\n\t return newToken('punctuator', read())\n\n\t // This code is unreachable since the default lexState handles eof.\n\t // case undefined:\n\t // return newToken('eof')\n\t }\n\n\t lexState = 'value';\n\t },\n\n\t beforePropertyName: function beforePropertyName () {\n\t switch (c) {\n\t case '$':\n\t case '_':\n\t buffer = read();\n\t lexState = 'identifierName';\n\t return\n\n\t case '\\\\':\n\t read();\n\t lexState = 'identifierNameStartEscape';\n\t return\n\n\t case '}':\n\t return newToken('punctuator', read())\n\n\t case '\"':\n\t case \"'\":\n\t doubleQuote = (read() === '\"');\n\t lexState = 'string';\n\t return\n\t }\n\n\t if (util.isIdStartChar(c)) {\n\t buffer += read();\n\t lexState = 'identifierName';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t afterPropertyName: function afterPropertyName () {\n\t if (c === ':') {\n\t return newToken('punctuator', read())\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t beforePropertyValue: function beforePropertyValue () {\n\t lexState = 'value';\n\t },\n\n\t afterPropertyValue: function afterPropertyValue () {\n\t switch (c) {\n\t case ',':\n\t case '}':\n\t return newToken('punctuator', read())\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t beforeArrayValue: function beforeArrayValue () {\n\t if (c === ']') {\n\t return newToken('punctuator', read())\n\t }\n\n\t lexState = 'value';\n\t },\n\n\t afterArrayValue: function afterArrayValue () {\n\t switch (c) {\n\t case ',':\n\t case ']':\n\t return newToken('punctuator', read())\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t end: function end () {\n\t // This code is unreachable since it's handled by the default lexState.\n\t // if (c === undefined) {\n\t // read()\n\t // return newToken('eof')\n\t // }\n\n\t throw invalidChar(read())\n\t },\n\t};\n\n\tfunction newToken (type, value) {\n\t return {\n\t type: type,\n\t value: value,\n\t line: line,\n\t column: column,\n\t }\n\t}\n\n\tfunction literal (s) {\n\t for (var i = 0, list = s; i < list.length; i += 1) {\n\t var c = list[i];\n\n\t var p = peek();\n\n\t if (p !== c) {\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t }\n\t}\n\n\tfunction escape () {\n\t var c = peek();\n\t switch (c) {\n\t case 'b':\n\t read();\n\t return '\\b'\n\n\t case 'f':\n\t read();\n\t return '\\f'\n\n\t case 'n':\n\t read();\n\t return '\\n'\n\n\t case 'r':\n\t read();\n\t return '\\r'\n\n\t case 't':\n\t read();\n\t return '\\t'\n\n\t case 'v':\n\t read();\n\t return '\\v'\n\n\t case '0':\n\t read();\n\t if (util.isDigit(peek())) {\n\t throw invalidChar(read())\n\t }\n\n\t return '\\0'\n\n\t case 'x':\n\t read();\n\t return hexEscape()\n\n\t case 'u':\n\t read();\n\t return unicodeEscape()\n\n\t case '\\n':\n\t case '\\u2028':\n\t case '\\u2029':\n\t read();\n\t return ''\n\n\t case '\\r':\n\t read();\n\t if (peek() === '\\n') {\n\t read();\n\t }\n\n\t return ''\n\n\t case '1':\n\t case '2':\n\t case '3':\n\t case '4':\n\t case '5':\n\t case '6':\n\t case '7':\n\t case '8':\n\t case '9':\n\t throw invalidChar(read())\n\n\t case undefined:\n\t throw invalidChar(read())\n\t }\n\n\t return read()\n\t}\n\n\tfunction hexEscape () {\n\t var buffer = '';\n\t var c = peek();\n\n\t if (!util.isHexDigit(c)) {\n\t throw invalidChar(read())\n\t }\n\n\t buffer += read();\n\n\t c = peek();\n\t if (!util.isHexDigit(c)) {\n\t throw invalidChar(read())\n\t }\n\n\t buffer += read();\n\n\t return String.fromCodePoint(parseInt(buffer, 16))\n\t}\n\n\tfunction unicodeEscape () {\n\t var buffer = '';\n\t var count = 4;\n\n\t while (count-- > 0) {\n\t var c = peek();\n\t if (!util.isHexDigit(c)) {\n\t throw invalidChar(read())\n\t }\n\n\t buffer += read();\n\t }\n\n\t return String.fromCodePoint(parseInt(buffer, 16))\n\t}\n\n\tvar parseStates = {\n\t start: function start () {\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t push();\n\t },\n\n\t beforePropertyName: function beforePropertyName () {\n\t switch (token.type) {\n\t case 'identifier':\n\t case 'string':\n\t key = token.value;\n\t parseState = 'afterPropertyName';\n\t return\n\n\t case 'punctuator':\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.value !== '}') {\n\t // throw invalidToken()\n\t // }\n\n\t pop();\n\t return\n\n\t case 'eof':\n\t throw invalidEOF()\n\t }\n\n\t // This code is unreachable since it's handled by the lexState.\n\t // throw invalidToken()\n\t },\n\n\t afterPropertyName: function afterPropertyName () {\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.type !== 'punctuator' || token.value !== ':') {\n\t // throw invalidToken()\n\t // }\n\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t parseState = 'beforePropertyValue';\n\t },\n\n\t beforePropertyValue: function beforePropertyValue () {\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t push();\n\t },\n\n\t beforeArrayValue: function beforeArrayValue () {\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t if (token.type === 'punctuator' && token.value === ']') {\n\t pop();\n\t return\n\t }\n\n\t push();\n\t },\n\n\t afterPropertyValue: function afterPropertyValue () {\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.type !== 'punctuator') {\n\t // throw invalidToken()\n\t // }\n\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t switch (token.value) {\n\t case ',':\n\t parseState = 'beforePropertyName';\n\t return\n\n\t case '}':\n\t pop();\n\t }\n\n\t // This code is unreachable since it's handled by the lexState.\n\t // throw invalidToken()\n\t },\n\n\t afterArrayValue: function afterArrayValue () {\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.type !== 'punctuator') {\n\t // throw invalidToken()\n\t // }\n\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t switch (token.value) {\n\t case ',':\n\t parseState = 'beforeArrayValue';\n\t return\n\n\t case ']':\n\t pop();\n\t }\n\n\t // This code is unreachable since it's handled by the lexState.\n\t // throw invalidToken()\n\t },\n\n\t end: function end () {\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.type !== 'eof') {\n\t // throw invalidToken()\n\t // }\n\t },\n\t};\n\n\tfunction push () {\n\t var value;\n\n\t switch (token.type) {\n\t case 'punctuator':\n\t switch (token.value) {\n\t case '{':\n\t value = {};\n\t break\n\n\t case '[':\n\t value = [];\n\t break\n\t }\n\n\t break\n\n\t case 'null':\n\t case 'boolean':\n\t case 'numeric':\n\t case 'string':\n\t value = token.value;\n\t break\n\n\t // This code is unreachable.\n\t // default:\n\t // throw invalidToken()\n\t }\n\n\t if (root === undefined) {\n\t root = value;\n\t } else {\n\t var parent = stack[stack.length - 1];\n\t if (Array.isArray(parent)) {\n\t parent.push(value);\n\t } else {\n\t Object.defineProperty(parent, key, {\n\t value: value,\n\t writable: true,\n\t enumerable: true,\n\t configurable: true,\n\t });\n\t }\n\t }\n\n\t if (value !== null && typeof value === 'object') {\n\t stack.push(value);\n\n\t if (Array.isArray(value)) {\n\t parseState = 'beforeArrayValue';\n\t } else {\n\t parseState = 'beforePropertyName';\n\t }\n\t } else {\n\t var current = stack[stack.length - 1];\n\t if (current == null) {\n\t parseState = 'end';\n\t } else if (Array.isArray(current)) {\n\t parseState = 'afterArrayValue';\n\t } else {\n\t parseState = 'afterPropertyValue';\n\t }\n\t }\n\t}\n\n\tfunction pop () {\n\t stack.pop();\n\n\t var current = stack[stack.length - 1];\n\t if (current == null) {\n\t parseState = 'end';\n\t } else if (Array.isArray(current)) {\n\t parseState = 'afterArrayValue';\n\t } else {\n\t parseState = 'afterPropertyValue';\n\t }\n\t}\n\n\t// This code is unreachable.\n\t// function invalidParseState () {\n\t// return new Error(`JSON5: invalid parse state '${parseState}'`)\n\t// }\n\n\t// This code is unreachable.\n\t// function invalidLexState (state) {\n\t// return new Error(`JSON5: invalid lex state '${state}'`)\n\t// }\n\n\tfunction invalidChar (c) {\n\t if (c === undefined) {\n\t return syntaxError((\"JSON5: invalid end of input at \" + line + \":\" + column))\n\t }\n\n\t return syntaxError((\"JSON5: invalid character '\" + (formatChar(c)) + \"' at \" + line + \":\" + column))\n\t}\n\n\tfunction invalidEOF () {\n\t return syntaxError((\"JSON5: invalid end of input at \" + line + \":\" + column))\n\t}\n\n\t// This code is unreachable.\n\t// function invalidToken () {\n\t// if (token.type === 'eof') {\n\t// return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)\n\t// }\n\n\t// const c = String.fromCodePoint(token.value.codePointAt(0))\n\t// return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`)\n\t// }\n\n\tfunction invalidIdentifier () {\n\t column -= 5;\n\t return syntaxError((\"JSON5: invalid identifier character at \" + line + \":\" + column))\n\t}\n\n\tfunction separatorChar (c) {\n\t console.warn((\"JSON5: '\" + (formatChar(c)) + \"' in strings is not valid ECMAScript; consider escaping\"));\n\t}\n\n\tfunction formatChar (c) {\n\t var replacements = {\n\t \"'\": \"\\\\'\",\n\t '\"': '\\\\\"',\n\t '\\\\': '\\\\\\\\',\n\t '\\b': '\\\\b',\n\t '\\f': '\\\\f',\n\t '\\n': '\\\\n',\n\t '\\r': '\\\\r',\n\t '\\t': '\\\\t',\n\t '\\v': '\\\\v',\n\t '\\0': '\\\\0',\n\t '\\u2028': '\\\\u2028',\n\t '\\u2029': '\\\\u2029',\n\t };\n\n\t if (replacements[c]) {\n\t return replacements[c]\n\t }\n\n\t if (c < ' ') {\n\t var hexString = c.charCodeAt(0).toString(16);\n\t return '\\\\x' + ('00' + hexString).substring(hexString.length)\n\t }\n\n\t return c\n\t}\n\n\tfunction syntaxError (message) {\n\t var err = new SyntaxError(message);\n\t err.lineNumber = line;\n\t err.columnNumber = column;\n\t return err\n\t}\n\n\tvar stringify = function stringify (value, replacer, space) {\n\t var stack = [];\n\t var indent = '';\n\t var propertyList;\n\t var replacerFunc;\n\t var gap = '';\n\t var quote;\n\n\t if (\n\t replacer != null &&\n\t typeof replacer === 'object' &&\n\t !Array.isArray(replacer)\n\t ) {\n\t space = replacer.space;\n\t quote = replacer.quote;\n\t replacer = replacer.replacer;\n\t }\n\n\t if (typeof replacer === 'function') {\n\t replacerFunc = replacer;\n\t } else if (Array.isArray(replacer)) {\n\t propertyList = [];\n\t for (var i = 0, list = replacer; i < list.length; i += 1) {\n\t var v = list[i];\n\n\t var item = (void 0);\n\n\t if (typeof v === 'string') {\n\t item = v;\n\t } else if (\n\t typeof v === 'number' ||\n\t v instanceof String ||\n\t v instanceof Number\n\t ) {\n\t item = String(v);\n\t }\n\n\t if (item !== undefined && propertyList.indexOf(item) < 0) {\n\t propertyList.push(item);\n\t }\n\t }\n\t }\n\n\t if (space instanceof Number) {\n\t space = Number(space);\n\t } else if (space instanceof String) {\n\t space = String(space);\n\t }\n\n\t if (typeof space === 'number') {\n\t if (space > 0) {\n\t space = Math.min(10, Math.floor(space));\n\t gap = ' '.substr(0, space);\n\t }\n\t } else if (typeof space === 'string') {\n\t gap = space.substr(0, 10);\n\t }\n\n\t return serializeProperty('', {'': value})\n\n\t function serializeProperty (key, holder) {\n\t var value = holder[key];\n\t if (value != null) {\n\t if (typeof value.toJSON5 === 'function') {\n\t value = value.toJSON5(key);\n\t } else if (typeof value.toJSON === 'function') {\n\t value = value.toJSON(key);\n\t }\n\t }\n\n\t if (replacerFunc) {\n\t value = replacerFunc.call(holder, key, value);\n\t }\n\n\t if (value instanceof Number) {\n\t value = Number(value);\n\t } else if (value instanceof String) {\n\t value = String(value);\n\t } else if (value instanceof Boolean) {\n\t value = value.valueOf();\n\t }\n\n\t switch (value) {\n\t case null: return 'null'\n\t case true: return 'true'\n\t case false: return 'false'\n\t }\n\n\t if (typeof value === 'string') {\n\t return quoteString(value, false)\n\t }\n\n\t if (typeof value === 'number') {\n\t return String(value)\n\t }\n\n\t if (typeof value === 'object') {\n\t return Array.isArray(value) ? serializeArray(value) : serializeObject(value)\n\t }\n\n\t return undefined\n\t }\n\n\t function quoteString (value) {\n\t var quotes = {\n\t \"'\": 0.1,\n\t '\"': 0.2,\n\t };\n\n\t var replacements = {\n\t \"'\": \"\\\\'\",\n\t '\"': '\\\\\"',\n\t '\\\\': '\\\\\\\\',\n\t '\\b': '\\\\b',\n\t '\\f': '\\\\f',\n\t '\\n': '\\\\n',\n\t '\\r': '\\\\r',\n\t '\\t': '\\\\t',\n\t '\\v': '\\\\v',\n\t '\\0': '\\\\0',\n\t '\\u2028': '\\\\u2028',\n\t '\\u2029': '\\\\u2029',\n\t };\n\n\t var product = '';\n\n\t for (var i = 0; i < value.length; i++) {\n\t var c = value[i];\n\t switch (c) {\n\t case \"'\":\n\t case '\"':\n\t quotes[c]++;\n\t product += c;\n\t continue\n\n\t case '\\0':\n\t if (util.isDigit(value[i + 1])) {\n\t product += '\\\\x00';\n\t continue\n\t }\n\t }\n\n\t if (replacements[c]) {\n\t product += replacements[c];\n\t continue\n\t }\n\n\t if (c < ' ') {\n\t var hexString = c.charCodeAt(0).toString(16);\n\t product += '\\\\x' + ('00' + hexString).substring(hexString.length);\n\t continue\n\t }\n\n\t product += c;\n\t }\n\n\t var quoteChar = quote || Object.keys(quotes).reduce(function (a, b) { return (quotes[a] < quotes[b]) ? a : b; });\n\n\t product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]);\n\n\t return quoteChar + product + quoteChar\n\t }\n\n\t function serializeObject (value) {\n\t if (stack.indexOf(value) >= 0) {\n\t throw TypeError('Converting circular structure to JSON5')\n\t }\n\n\t stack.push(value);\n\n\t var stepback = indent;\n\t indent = indent + gap;\n\n\t var keys = propertyList || Object.keys(value);\n\t var partial = [];\n\t for (var i = 0, list = keys; i < list.length; i += 1) {\n\t var key = list[i];\n\n\t var propertyString = serializeProperty(key, value);\n\t if (propertyString !== undefined) {\n\t var member = serializeKey(key) + ':';\n\t if (gap !== '') {\n\t member += ' ';\n\t }\n\t member += propertyString;\n\t partial.push(member);\n\t }\n\t }\n\n\t var final;\n\t if (partial.length === 0) {\n\t final = '{}';\n\t } else {\n\t var properties;\n\t if (gap === '') {\n\t properties = partial.join(',');\n\t final = '{' + properties + '}';\n\t } else {\n\t var separator = ',\\n' + indent;\n\t properties = partial.join(separator);\n\t final = '{\\n' + indent + properties + ',\\n' + stepback + '}';\n\t }\n\t }\n\n\t stack.pop();\n\t indent = stepback;\n\t return final\n\t }\n\n\t function serializeKey (key) {\n\t if (key.length === 0) {\n\t return quoteString(key, true)\n\t }\n\n\t var firstChar = String.fromCodePoint(key.codePointAt(0));\n\t if (!util.isIdStartChar(firstChar)) {\n\t return quoteString(key, true)\n\t }\n\n\t for (var i = firstChar.length; i < key.length; i++) {\n\t if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) {\n\t return quoteString(key, true)\n\t }\n\t }\n\n\t return key\n\t }\n\n\t function serializeArray (value) {\n\t if (stack.indexOf(value) >= 0) {\n\t throw TypeError('Converting circular structure to JSON5')\n\t }\n\n\t stack.push(value);\n\n\t var stepback = indent;\n\t indent = indent + gap;\n\n\t var partial = [];\n\t for (var i = 0; i < value.length; i++) {\n\t var propertyString = serializeProperty(String(i), value);\n\t partial.push((propertyString !== undefined) ? propertyString : 'null');\n\t }\n\n\t var final;\n\t if (partial.length === 0) {\n\t final = '[]';\n\t } else {\n\t if (gap === '') {\n\t var properties = partial.join(',');\n\t final = '[' + properties + ']';\n\t } else {\n\t var separator = ',\\n' + indent;\n\t var properties$1 = partial.join(separator);\n\t final = '[\\n' + indent + properties$1 + ',\\n' + stepback + ']';\n\t }\n\t }\n\n\t stack.pop();\n\t indent = stepback;\n\t return final\n\t }\n\t};\n\n\tvar JSON5 = {\n\t parse: parse,\n\t stringify: stringify,\n\t};\n\n\tvar lib = JSON5;\n\n\tvar es5 = lib;\n\n\treturn es5;\n\n})));\n","import { schemaType, type JsonSchema } from \"../../views/config-form.shared.ts\";\n\nfunction coerceNumberString(value: string, integer: boolean): number | undefined | string {\n const trimmed = value.trim();\n if (trimmed === \"\") {\n return undefined;\n }\n const parsed = Number(trimmed);\n if (!Number.isFinite(parsed)) {\n return value;\n }\n if (integer && !Number.isInteger(parsed)) {\n return value;\n }\n return parsed;\n}\n\nfunction coerceBooleanString(value: string): boolean | string {\n const trimmed = value.trim();\n if (trimmed === \"true\") {\n return true;\n }\n if (trimmed === \"false\") {\n return false;\n }\n return value;\n}\n\n/**\n * Walk a form value tree alongside its JSON Schema and coerce string values\n * to their schema-defined types (number, boolean).\n *\n * HTML `<input>` elements always produce string `.value` properties. Even\n * though the form rendering code converts values correctly for most paths,\n * some interactions (map-field repopulation, re-renders, paste, etc.) can\n * leak raw strings into the config form state. This utility acts as a\n * safety net before serialization so that `config.set` always receives\n * correctly typed JSON.\n */\nexport function coerceFormValues(value: unknown, schema: JsonSchema): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (schema.allOf && schema.allOf.length > 0) {\n let next: unknown = value;\n for (const segment of schema.allOf) {\n next = coerceFormValues(next, segment);\n }\n return next;\n }\n\n const type = schemaType(schema);\n\n // Handle anyOf/oneOf — try to match the value against a variant\n if (schema.anyOf || schema.oneOf) {\n const variants = (schema.anyOf ?? schema.oneOf ?? []).filter(\n (v) => !(v.type === \"null\" || (Array.isArray(v.type) && v.type.includes(\"null\"))),\n );\n\n if (variants.length === 1) {\n return coerceFormValues(value, variants[0]);\n }\n\n // Try number/boolean coercion for string values\n if (typeof value === \"string\") {\n for (const variant of variants) {\n const variantType = schemaType(variant);\n if (variantType === \"number\" || variantType === \"integer\") {\n const coerced = coerceNumberString(value, variantType === \"integer\");\n if (coerced === undefined || typeof coerced === \"number\") {\n return coerced;\n }\n }\n if (variantType === \"boolean\") {\n const coerced = coerceBooleanString(value);\n if (typeof coerced === \"boolean\") {\n return coerced;\n }\n }\n }\n }\n\n // For non-string values (objects, arrays), try to recurse into matching variant\n for (const variant of variants) {\n const variantType = schemaType(variant);\n if (variantType === \"object\" && typeof value === \"object\" && !Array.isArray(value)) {\n return coerceFormValues(value, variant);\n }\n if (variantType === \"array\" && Array.isArray(value)) {\n return coerceFormValues(value, variant);\n }\n }\n\n return value;\n }\n\n if (type === \"number\" || type === \"integer\") {\n if (typeof value === \"string\") {\n const coerced = coerceNumberString(value, type === \"integer\");\n if (coerced === undefined || typeof coerced === \"number\") {\n return coerced;\n }\n }\n return value;\n }\n\n if (type === \"boolean\") {\n if (typeof value === \"string\") {\n const coerced = coerceBooleanString(value);\n if (typeof coerced === \"boolean\") {\n return coerced;\n }\n }\n return value;\n }\n\n if (type === \"object\") {\n if (typeof value !== \"object\" || Array.isArray(value)) {\n return value;\n }\n const obj = value as Record<string, unknown>;\n const props = schema.properties ?? {};\n const additional =\n schema.additionalProperties && typeof schema.additionalProperties === \"object\"\n ? schema.additionalProperties\n : null;\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(obj)) {\n const propSchema = props[key] ?? additional;\n const coerced = propSchema ? coerceFormValues(val, propSchema) : val;\n // Omit undefined — \"clear field = unset\" for optional properties\n if (coerced !== undefined) {\n result[key] = coerced;\n }\n }\n return result;\n }\n\n if (type === \"array\") {\n if (!Array.isArray(value)) {\n return value;\n }\n if (Array.isArray(schema.items)) {\n // Tuple form: each index has its own schema\n const tuple = schema.items;\n return value.map((item, i) => {\n const s = i < tuple.length ? tuple[i] : undefined;\n return s ? coerceFormValues(item, s) : item;\n });\n }\n const itemsSchema = schema.items;\n if (!itemsSchema) {\n return value;\n }\n return value.map((item) => coerceFormValues(item, itemsSchema)).filter((v) => v !== undefined);\n }\n\n return value;\n}\n","export function cloneConfigObject<T>(value: T): T {\n if (typeof structuredClone === \"function\") {\n return structuredClone(value);\n }\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function serializeConfigForm(form: Record<string, unknown>): string {\n return `${JSON.stringify(form, null, 2).trimEnd()}\\n`;\n}\n\nexport function setPathValue(\n obj: Record<string, unknown> | unknown[],\n path: Array<string | number>,\n value: unknown,\n) {\n if (path.length === 0) {\n return;\n }\n let current: Record<string, unknown> | unknown[] = obj;\n for (let i = 0; i < path.length - 1; i += 1) {\n const key = path[i];\n const nextKey = path[i + 1];\n if (typeof key === \"number\") {\n if (!Array.isArray(current)) {\n return;\n }\n if (current[key] == null) {\n current[key] = typeof nextKey === \"number\" ? [] : ({} as Record<string, unknown>);\n }\n current = current[key] as Record<string, unknown> | unknown[];\n } else {\n if (typeof current !== \"object\" || current == null) {\n return;\n }\n const record = current as Record<string, unknown>;\n if (record[key] == null) {\n record[key] = typeof nextKey === \"number\" ? [] : ({} as Record<string, unknown>);\n }\n current = record[key] as Record<string, unknown> | unknown[];\n }\n }\n const lastKey = path[path.length - 1];\n if (typeof lastKey === \"number\") {\n if (Array.isArray(current)) {\n current[lastKey] = value;\n }\n return;\n }\n if (typeof current === \"object\" && current != null) {\n (current as Record<string, unknown>)[lastKey] = value;\n }\n}\n\nexport function removePathValue(\n obj: Record<string, unknown> | unknown[],\n path: Array<string | number>,\n) {\n if (path.length === 0) {\n return;\n }\n let current: Record<string, unknown> | unknown[] = obj;\n for (let i = 0; i < path.length - 1; i += 1) {\n const key = path[i];\n if (typeof key === \"number\") {\n if (!Array.isArray(current)) {\n return;\n }\n current = current[key] as Record<string, unknown> | unknown[];\n } else {\n if (typeof current !== \"object\" || current == null) {\n return;\n }\n current = (current as Record<string, unknown>)[key] as Record<string, unknown> | unknown[];\n }\n if (current == null) {\n return;\n }\n }\n const lastKey = path[path.length - 1];\n if (typeof lastKey === \"number\") {\n if (Array.isArray(current)) {\n current.splice(lastKey, 1);\n }\n return;\n }\n if (typeof current === \"object\" && current != null) {\n delete (current as Record<string, unknown>)[lastKey];\n }\n}\n","import JSON5 from \"json5\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { ConfigSchemaResponse, ConfigSnapshot, ConfigUiHints } from \"../types.ts\";\nimport type { JsonSchema } from \"../views/config-form.shared.ts\";\nimport { coerceFormValues } from \"./config/form-coerce.ts\";\nimport {\n cloneConfigObject,\n removePathValue,\n serializeConfigForm,\n setPathValue,\n} from \"./config/form-utils.ts\";\n\nexport type ConfigState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n applySessionKey: string;\n configLoading: boolean;\n configRaw: string;\n configRawOriginal: string;\n configValid: boolean | null;\n configIssues: unknown[];\n configSaving: boolean;\n configApplying: boolean;\n updateRunning: boolean;\n configSnapshot: ConfigSnapshot | null;\n configSchema: unknown;\n configSchemaVersion: string | null;\n configSchemaLoading: boolean;\n configUiHints: ConfigUiHints;\n configForm: Record<string, unknown> | null;\n configFormOriginal: Record<string, unknown> | null;\n configFormDirty: boolean;\n configFormMode: \"form\" | \"raw\";\n configSearchQuery: string;\n configActiveSection: string | null;\n configActiveSubsection: string | null;\n lastError: string | null;\n};\n\nexport async function loadConfig(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.configLoading = true;\n state.lastError = null;\n try {\n const res = await state.client.request<ConfigSnapshot>(\"config.get\", {});\n applyConfigSnapshot(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configLoading = false;\n }\n}\n\nexport async function loadConfigSchema(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.configSchemaLoading) {\n return;\n }\n state.configSchemaLoading = true;\n try {\n const res = await state.client.request<ConfigSchemaResponse>(\"config.schema\", {});\n applyConfigSchema(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configSchemaLoading = false;\n }\n}\n\nexport function applyConfigSchema(state: ConfigState, res: ConfigSchemaResponse) {\n state.configSchema = res.schema ?? null;\n state.configUiHints = res.uiHints ?? {};\n state.configSchemaVersion = res.version ?? null;\n}\n\nexport function applyConfigSnapshot(state: ConfigState, snapshot: ConfigSnapshot) {\n state.configSnapshot = snapshot;\n const rawFromSnapshot =\n typeof snapshot.raw === \"string\"\n ? snapshot.raw\n : snapshot.config && typeof snapshot.config === \"object\"\n ? serializeConfigForm(snapshot.config)\n : state.configRaw;\n if (!state.configFormDirty || state.configFormMode === \"raw\") {\n state.configRaw = rawFromSnapshot;\n } else if (state.configForm) {\n state.configRaw = serializeConfigForm(state.configForm);\n } else {\n state.configRaw = rawFromSnapshot;\n }\n state.configValid = typeof snapshot.valid === \"boolean\" ? snapshot.valid : null;\n state.configIssues = Array.isArray(snapshot.issues) ? snapshot.issues : [];\n\n if (!state.configFormDirty) {\n state.configForm = cloneConfigObject(snapshot.config ?? {});\n state.configFormOriginal = cloneConfigObject(snapshot.config ?? {});\n state.configRawOriginal = rawFromSnapshot;\n }\n}\n\nfunction asJsonSchema(value: unknown): JsonSchema | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n return value as JsonSchema;\n}\n\n/**\n * Serialize the form state for submission to `config.set` / `config.apply`.\n *\n * HTML `<input>` elements produce string `.value` properties, so numeric and\n * boolean config fields can leak into `configForm` as strings. We coerce\n * them back to their schema-defined types before JSON serialization so the\n * gateway's Zod validation always sees correctly typed values.\n */\nfunction serializeFormForSubmit(state: ConfigState): string {\n if (state.configFormMode !== \"form\" || !state.configForm) {\n return state.configRaw;\n }\n const schema = asJsonSchema(state.configSchema);\n const form = schema\n ? (coerceFormValues(state.configForm, schema) as Record<string, unknown>)\n : state.configForm;\n return serializeConfigForm(form);\n}\n\n// Local mirror of src/config/removed-keys.ts — cannot import core (includes.ts → node:fs).\nconst INCLUDE_KEY = \"$include\";\n\nfunction resolveRemovedTopLevelKeys(snapshot: { parsed?: unknown }, next: unknown): string[] {\n const parsed = snapshot.parsed;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return [];\n }\n if (!next || typeof next !== \"object\" || Array.isArray(next)) {\n return [];\n }\n const nextKeys = new Set(\n Object.entries(next as Record<string, unknown>)\n .filter(([, value]) => value !== undefined)\n .map(([key]) => key),\n );\n return Object.keys(parsed as Record<string, unknown>).filter(\n (key) => key !== INCLUDE_KEY && !nextKeys.has(key),\n );\n}\n\nfunction resolveSubmitDocument(state: ConfigState, raw: string): unknown {\n if (state.configFormMode === \"form\" && state.configForm) {\n const schema = asJsonSchema(state.configSchema);\n return schema\n ? (coerceFormValues(state.configForm, schema) as Record<string, unknown>)\n : state.configForm;\n }\n // Raw editor is JSON5 (matches gateway parseConfigJson5); strict JSON.parse misses removals.\n try {\n return JSON5.parse(raw);\n } catch {\n return null;\n }\n}\n\nfunction resolveAllowTopLevelKeyRemoval(state: ConfigState, raw: string): string[] {\n const snapshot = state.configSnapshot;\n if (!snapshot) {\n return [];\n }\n const previous =\n snapshot.parsed !== undefined && snapshot.parsed !== null ? snapshot.parsed : snapshot.config;\n return resolveRemovedTopLevelKeys({ parsed: previous }, resolveSubmitDocument(state, raw));\n}\n\ntype RestartConfirmationChallenge = {\n requiresConfirmation?: unknown;\n activeRuns?: unknown;\n};\n\nfunction isRestartConfirmationChallenge(value: unknown): value is RestartConfirmationChallenge {\n return (\n Boolean(value) &&\n typeof value === \"object\" &&\n (value as RestartConfirmationChallenge).requiresConfirmation === true\n );\n}\n\nfunction confirmRestartWithActiveRuns(activeRuns: unknown): boolean {\n const count = typeof activeRuns === \"number\" && Number.isFinite(activeRuns) ? activeRuns : 0;\n const label = count === 1 ? \"1 active run\" : `${count} active runs`;\n return window.confirm(\n `This operation needs a gateway restart, but ${label} will be interrupted. Continue?`,\n );\n}\n\nexport async function saveConfig(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.configSaving = true;\n state.lastError = null;\n try {\n const raw = serializeFormForSubmit(state);\n const baseHash = state.configSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Config hash missing; reload and retry.\";\n return;\n }\n const allowTopLevelKeyRemoval = resolveAllowTopLevelKeyRemoval(state, raw);\n await state.client.request(\"config.set\", {\n raw,\n baseHash,\n ...(allowTopLevelKeyRemoval.length > 0 ? { allowTopLevelKeyRemoval } : {}),\n });\n state.configFormDirty = false;\n await loadConfig(state);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configSaving = false;\n }\n}\n\nexport async function applyConfig(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.configApplying = true;\n state.lastError = null;\n try {\n const raw = serializeFormForSubmit(state);\n const baseHash = state.configSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Config hash missing; reload and retry.\";\n return;\n }\n const allowTopLevelKeyRemoval = resolveAllowTopLevelKeyRemoval(state, raw);\n const request = {\n raw,\n baseHash,\n sessionKey: state.applySessionKey,\n ...(allowTopLevelKeyRemoval.length > 0 ? { allowTopLevelKeyRemoval } : {}),\n };\n const result = await state.client.request(\"config.apply\", request);\n if (isRestartConfirmationChallenge(result)) {\n if (!confirmRestartWithActiveRuns(result.activeRuns)) {\n return;\n }\n await state.client.request(\"config.apply\", { ...request, confirmed: \"drain\" });\n }\n state.configFormDirty = false;\n await loadConfig(state);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configApplying = false;\n }\n}\n\nexport async function runUpdate(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.updateRunning = true;\n state.lastError = null;\n try {\n const request = {\n sessionKey: state.applySessionKey,\n };\n const result = await state.client.request(\"update.run\", request);\n if (isRestartConfirmationChallenge(result)) {\n if (!confirmRestartWithActiveRuns(result.activeRuns)) {\n return;\n }\n await state.client.request(\"update.run\", { ...request, confirmed: \"drain\" });\n }\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.updateRunning = false;\n }\n}\n\nexport function updateConfigFormValue(\n state: ConfigState,\n path: Array<string | number>,\n value: unknown,\n) {\n const base = cloneConfigObject(state.configForm ?? state.configSnapshot?.config ?? {});\n setPathValue(base, path, value);\n state.configForm = base;\n state.configFormDirty = true;\n if (state.configFormMode === \"form\") {\n state.configRaw = serializeConfigForm(base);\n }\n}\n\nexport function removeConfigFormValue(state: ConfigState, path: Array<string | number>) {\n const base = cloneConfigObject(state.configForm ?? state.configSnapshot?.config ?? {});\n removePathValue(base, path);\n state.configForm = base;\n state.configFormDirty = true;\n if (state.configFormMode === \"form\") {\n state.configRaw = serializeConfigForm(base);\n }\n}\n","import type { OpenClawApp } from \"./app.ts\";\nimport {\n loadChannels,\n logoutWhatsApp,\n startWhatsAppLogin,\n waitWhatsAppLogin,\n} from \"./controllers/channels.ts\";\nimport { loadConfig, saveConfig } from \"./controllers/config.ts\";\nimport type { NostrProfile } from \"./types.ts\";\nimport { createNostrProfileFormState } from \"./views/channels.nostr-profile-form.ts\";\n\nexport async function handleWhatsAppStart(host: OpenClawApp, force: boolean) {\n await startWhatsAppLogin(host, force);\n await loadChannels(host, true);\n}\n\nexport async function handleWhatsAppWait(host: OpenClawApp) {\n await waitWhatsAppLogin(host);\n await loadChannels(host, true);\n}\n\nexport async function handleWhatsAppLogout(host: OpenClawApp) {\n await logoutWhatsApp(host);\n await loadChannels(host, true);\n}\n\nexport async function handleChannelConfigSave(host: OpenClawApp) {\n await saveConfig(host);\n await loadConfig(host);\n await loadChannels(host, true);\n}\n\nexport async function handleChannelConfigReload(host: OpenClawApp) {\n await loadConfig(host);\n await loadChannels(host, true);\n}\n\nfunction parseValidationErrors(details: unknown): Record<string, string> {\n if (!Array.isArray(details)) {\n return {};\n }\n const errors: Record<string, string> = {};\n for (const entry of details) {\n if (typeof entry !== \"string\") {\n continue;\n }\n const [rawField, ...rest] = entry.split(\":\");\n if (!rawField || rest.length === 0) {\n continue;\n }\n const field = rawField.trim();\n const message = rest.join(\":\").trim();\n if (field && message) {\n errors[field] = message;\n }\n }\n return errors;\n}\n\nfunction resolveNostrAccountId(host: OpenClawApp): string {\n const accounts = host.channelsSnapshot?.channelAccounts?.nostr ?? [];\n return accounts[0]?.accountId ?? host.nostrProfileAccountId ?? \"default\";\n}\n\nfunction buildNostrProfileUrl(accountId: string, suffix = \"\"): string {\n return `/api/channels/nostr/${encodeURIComponent(accountId)}/profile${suffix}`;\n}\n\nfunction resolveGatewayHttpAuthHeader(host: OpenClawApp): string | null {\n const deviceToken = host.hello?.auth?.deviceToken?.trim();\n if (deviceToken) {\n return `Bearer ${deviceToken}`;\n }\n const token = host.settings.token.trim();\n if (token) {\n return `Bearer ${token}`;\n }\n const password = host.password.trim();\n if (password) {\n return `Bearer ${password}`;\n }\n return null;\n}\n\nfunction buildGatewayHttpHeaders(host: OpenClawApp): Record<string, string> {\n const authorization = resolveGatewayHttpAuthHeader(host);\n return authorization ? { Authorization: authorization } : {};\n}\n\nexport function handleNostrProfileEdit(\n host: OpenClawApp,\n accountId: string,\n profile: NostrProfile | null,\n) {\n host.nostrProfileAccountId = accountId;\n host.nostrProfileFormState = createNostrProfileFormState(profile ?? undefined);\n}\n\nexport function handleNostrProfileCancel(host: OpenClawApp) {\n host.nostrProfileFormState = null;\n host.nostrProfileAccountId = null;\n}\n\nexport function handleNostrProfileFieldChange(\n host: OpenClawApp,\n field: keyof NostrProfile,\n value: string,\n) {\n const state = host.nostrProfileFormState;\n if (!state) {\n return;\n }\n host.nostrProfileFormState = {\n ...state,\n values: {\n ...state.values,\n [field]: value,\n },\n fieldErrors: {\n ...state.fieldErrors,\n [field]: \"\",\n },\n };\n}\n\nexport function handleNostrProfileToggleAdvanced(host: OpenClawApp) {\n const state = host.nostrProfileFormState;\n if (!state) {\n return;\n }\n host.nostrProfileFormState = {\n ...state,\n showAdvanced: !state.showAdvanced,\n };\n}\n\nexport async function handleNostrProfileSave(host: OpenClawApp) {\n const state = host.nostrProfileFormState;\n if (!state || state.saving) {\n return;\n }\n const accountId = resolveNostrAccountId(host);\n\n host.nostrProfileFormState = {\n ...state,\n saving: true,\n error: null,\n success: null,\n fieldErrors: {},\n };\n\n try {\n const response = await fetch(buildNostrProfileUrl(accountId), {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...buildGatewayHttpHeaders(host),\n },\n body: JSON.stringify(state.values),\n });\n const data = (await response.json().catch(() => null)) as {\n ok?: boolean;\n error?: string;\n details?: unknown;\n persisted?: boolean;\n } | null;\n\n if (!response.ok || data?.ok === false || !data) {\n const errorMessage = data?.error ?? `Profile update failed (${response.status})`;\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: errorMessage,\n success: null,\n fieldErrors: parseValidationErrors(data?.details),\n };\n return;\n }\n\n if (!data.persisted) {\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: \"Profile publish failed on all relays.\",\n success: null,\n };\n return;\n }\n\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: null,\n success: \"Profile published to relays.\",\n fieldErrors: {},\n original: { ...state.values },\n };\n await loadChannels(host, true);\n } catch (err) {\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: `Profile update failed: ${String(err)}`,\n success: null,\n };\n }\n}\n\nexport async function handleNostrProfileImport(host: OpenClawApp) {\n const state = host.nostrProfileFormState;\n if (!state || state.importing) {\n return;\n }\n const accountId = resolveNostrAccountId(host);\n\n host.nostrProfileFormState = {\n ...state,\n importing: true,\n error: null,\n success: null,\n };\n\n try {\n const response = await fetch(buildNostrProfileUrl(accountId, \"/import\"), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...buildGatewayHttpHeaders(host),\n },\n body: JSON.stringify({ autoMerge: true }),\n });\n const data = (await response.json().catch(() => null)) as {\n ok?: boolean;\n error?: string;\n imported?: NostrProfile;\n merged?: NostrProfile;\n saved?: boolean;\n } | null;\n\n if (!response.ok || data?.ok === false || !data) {\n const errorMessage = data?.error ?? `Profile import failed (${response.status})`;\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n error: errorMessage,\n success: null,\n };\n return;\n }\n\n const merged = data.merged ?? data.imported ?? null;\n const nextValues = merged ? { ...state.values, ...merged } : state.values;\n const showAdvanced = Boolean(\n nextValues.banner || nextValues.website || nextValues.nip05 || nextValues.lud16,\n );\n\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n values: nextValues,\n error: null,\n success: data.saved\n ? \"Profile imported from relays. Review and publish.\"\n : \"Profile imported. Review and publish.\",\n showAdvanced,\n };\n\n if (data.saved) {\n await loadChannels(host, true);\n }\n } catch (err) {\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n error: `Profile import failed: ${String(err)}`,\n success: null,\n };\n }\n}\n","export type ParsedAgentSessionKey = {\n agentId: string;\n rest: string;\n};\n\nexport type SessionKeyChatType = \"direct\" | \"group\" | \"channel\" | \"unknown\";\n\n/**\n * Parse agent-scoped session keys in a canonical, case-insensitive way.\n * Returned values are normalized to lowercase for stable comparisons/routing.\n */\nexport function parseAgentSessionKey(\n sessionKey: string | undefined | null,\n): ParsedAgentSessionKey | null {\n const raw = (sessionKey ?? \"\").trim().toLowerCase();\n if (!raw) {\n return null;\n }\n const parts = raw.split(\":\").filter(Boolean);\n if (parts.length < 3) {\n return null;\n }\n if (parts[0] !== \"agent\") {\n return null;\n }\n const agentId = parts[1]?.trim();\n const rest = parts.slice(2).join(\":\");\n if (!agentId || !rest) {\n return null;\n }\n return { agentId, rest };\n}\n\n/**\n * Best-effort chat-type extraction from session keys across canonical and legacy formats.\n */\nexport function deriveSessionChatType(sessionKey: string | undefined | null): SessionKeyChatType {\n const raw = (sessionKey ?? \"\").trim().toLowerCase();\n if (!raw) {\n return \"unknown\";\n }\n const scoped = parseAgentSessionKey(raw)?.rest ?? raw;\n const tokens = new Set(scoped.split(\":\").filter(Boolean));\n if (tokens.has(\"group\")) {\n return \"group\";\n }\n if (tokens.has(\"channel\")) {\n return \"channel\";\n }\n if (tokens.has(\"direct\") || tokens.has(\"dm\")) {\n return \"direct\";\n }\n // Legacy Discord keys can be shaped like:\n // discord:<accountId>:guild-<guildId>:channel-<channelId>\n if (/^discord:(?:[^:]+:)?guild-[^:]+:channel-[^:]+$/.test(scoped)) {\n return \"channel\";\n }\n return \"unknown\";\n}\n\nexport function isCronRunSessionKey(sessionKey: string | undefined | null): boolean {\n const parsed = parseAgentSessionKey(sessionKey);\n if (!parsed) {\n return false;\n }\n return /^cron:[^:]+:run:[^:]+$/.test(parsed.rest);\n}\n\nexport function isCronSessionKey(sessionKey: string | undefined | null): boolean {\n const parsed = parseAgentSessionKey(sessionKey);\n if (!parsed) {\n return false;\n }\n return parsed.rest.toLowerCase().startsWith(\"cron:\");\n}\n\n/** Cron provenance of a stored session key: legacy bare `cron:<job>` or `agent:<id>:cron:<job>`. */\nexport function isCronTriggerSessionKey(sessionKey: string | undefined | null): boolean {\n return (sessionKey ?? \"\").startsWith(\"cron:\") || isCronSessionKey(sessionKey);\n}\n\nexport function isSubagentSessionKey(sessionKey: string | undefined | null): boolean {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) {\n return false;\n }\n if (raw.toLowerCase().startsWith(\"subagent:\")) {\n return true;\n }\n const parsed = parseAgentSessionKey(raw);\n return Boolean((parsed?.rest ?? \"\").toLowerCase().startsWith(\"subagent:\"));\n}\n\nexport function getSubagentDepth(sessionKey: string | undefined | null): number {\n const raw = (sessionKey ?? \"\").trim().toLowerCase();\n if (!raw) {\n return 0;\n }\n return raw.split(\":subagent:\").length - 1;\n}\n\nexport function isAcpSessionKey(sessionKey: string | undefined | null): boolean {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) {\n return false;\n }\n const normalized = raw.toLowerCase();\n if (normalized.startsWith(\"acp:\")) {\n return true;\n }\n const parsed = parseAgentSessionKey(raw);\n return Boolean((parsed?.rest ?? \"\").toLowerCase().startsWith(\"acp:\"));\n}\n\n/**\n * Control-plane segments appended to an existing session key. heartbeat-runner, background-run and\n * the gateway heartbeat probe append HEARTBEAT/BACKGROUND as the final segment; wake-gate appends\n * WAKE_GATE plus a nonce. The legacy actor backfill (ctx-identity-backfill) treats a key as\n * actorless only in those positions: HEARTBEAT/BACKGROUND last, WAKE_GATE second-to-last.\n */\nexport const HEARTBEAT_SESSION_KEY_SEGMENT = \"heartbeat\";\nexport const BACKGROUND_SESSION_KEY_SEGMENT = \"background\";\nexport const WAKE_GATE_SESSION_KEY_SEGMENT = \"wake-gate\";\n\nconst THREAD_SESSION_MARKERS = [\":thread:\", \":topic:\"];\n\nexport function resolveThreadParentSessionKey(\n sessionKey: string | undefined | null,\n): string | null {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) {\n return null;\n }\n const normalized = raw.toLowerCase();\n let idx = -1;\n for (const marker of THREAD_SESSION_MARKERS) {\n const candidate = normalized.lastIndexOf(marker);\n if (candidate > idx) {\n idx = candidate;\n }\n }\n if (idx <= 0) {\n return null;\n }\n const parent = raw.slice(0, idx).trim();\n return parent ? parent : null;\n}\n","/** Distance (px) from the bottom within which we consider the user \"near bottom\". */\nconst NEAR_BOTTOM_THRESHOLD = 450;\n\ntype ScrollHost = {\n updateComplete: Promise<unknown>;\n querySelector: (selectors: string) => Element | null;\n style: CSSStyleDeclaration;\n chatScrollFrame: number | null;\n chatScrollTimeout: number | null;\n chatHasAutoScrolled: boolean;\n chatUserNearBottom: boolean;\n chatNewMessagesBelow: boolean;\n logsScrollFrame: number | null;\n logsAtBottom: boolean;\n topbarObserver: ResizeObserver | null;\n};\n\nexport function scheduleChatScroll(host: ScrollHost, force = false, smooth = false) {\n if (host.chatScrollFrame) {\n cancelAnimationFrame(host.chatScrollFrame);\n }\n if (host.chatScrollTimeout != null) {\n clearTimeout(host.chatScrollTimeout);\n host.chatScrollTimeout = null;\n }\n const pickScrollTarget = () => {\n const container = host.querySelector(\".chat-thread\") as HTMLElement | null;\n if (container) {\n const overflowY = getComputedStyle(container).overflowY;\n const canScroll =\n overflowY === \"auto\" ||\n overflowY === \"scroll\" ||\n container.scrollHeight - container.clientHeight > 1;\n if (canScroll) {\n return container;\n }\n }\n return (document.scrollingElement ?? document.documentElement) as HTMLElement | null;\n };\n // Wait for Lit render to complete, then scroll\n void host.updateComplete.then(() => {\n host.chatScrollFrame = requestAnimationFrame(() => {\n host.chatScrollFrame = null;\n const target = pickScrollTarget();\n if (!target) {\n return;\n }\n const distanceFromBottom = target.scrollHeight - target.scrollTop - target.clientHeight;\n\n // force=true only overrides when we haven't auto-scrolled yet (initial load).\n // After initial load, respect the user's scroll position.\n const effectiveForce = force && !host.chatHasAutoScrolled;\n const shouldStick =\n effectiveForce || host.chatUserNearBottom || distanceFromBottom < NEAR_BOTTOM_THRESHOLD;\n\n if (!shouldStick) {\n // User is scrolled up — flag that new content arrived below.\n host.chatNewMessagesBelow = true;\n return;\n }\n if (effectiveForce) {\n host.chatHasAutoScrolled = true;\n }\n const smoothEnabled =\n smooth &&\n (typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\" ||\n !window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches);\n const scrollTop = target.scrollHeight;\n if (typeof target.scrollTo === \"function\") {\n target.scrollTo({ top: scrollTop, behavior: smoothEnabled ? \"smooth\" : \"auto\" });\n } else {\n target.scrollTop = scrollTop;\n }\n host.chatUserNearBottom = true;\n host.chatNewMessagesBelow = false;\n const retryDelay = effectiveForce ? 150 : 120;\n host.chatScrollTimeout = window.setTimeout(() => {\n host.chatScrollTimeout = null;\n const latest = pickScrollTarget();\n if (!latest) {\n return;\n }\n const latestDistanceFromBottom =\n latest.scrollHeight - latest.scrollTop - latest.clientHeight;\n const shouldStickRetry =\n effectiveForce ||\n host.chatUserNearBottom ||\n latestDistanceFromBottom < NEAR_BOTTOM_THRESHOLD;\n if (!shouldStickRetry) {\n return;\n }\n latest.scrollTop = latest.scrollHeight;\n host.chatUserNearBottom = true;\n }, retryDelay);\n });\n });\n}\n\nexport function scheduleLogsScroll(host: ScrollHost, force = false) {\n if (host.logsScrollFrame) {\n cancelAnimationFrame(host.logsScrollFrame);\n }\n void host.updateComplete.then(() => {\n host.logsScrollFrame = requestAnimationFrame(() => {\n host.logsScrollFrame = null;\n const container = host.querySelector(\".log-stream\") as HTMLElement | null;\n if (!container) {\n return;\n }\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n const shouldStick = force || distanceFromBottom < 80;\n if (!shouldStick) {\n return;\n }\n container.scrollTop = container.scrollHeight;\n });\n });\n}\n\nexport function handleChatScroll(host: ScrollHost, event: Event) {\n const container = event.currentTarget as HTMLElement | null;\n if (!container) {\n return;\n }\n const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;\n host.chatUserNearBottom = distanceFromBottom < NEAR_BOTTOM_THRESHOLD;\n // Clear the \"new messages below\" indicator when user scrolls back to bottom.\n if (host.chatUserNearBottom) {\n host.chatNewMessagesBelow = false;\n }\n}\n\nexport function handleLogsScroll(host: ScrollHost, event: Event) {\n const container = event.currentTarget as HTMLElement | null;\n if (!container) {\n return;\n }\n const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;\n host.logsAtBottom = distanceFromBottom < 80;\n}\n\nexport function resetChatScroll(host: ScrollHost) {\n host.chatHasAutoScrolled = false;\n host.chatUserNearBottom = true;\n host.chatNewMessagesBelow = false;\n}\n\nexport function exportLogs(lines: string[], label: string) {\n if (lines.length === 0) {\n return;\n }\n const blob = new Blob([`${lines.join(\"\\n\")}\\n`], { type: \"text/plain\" });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n const stamp = new Date().toISOString().slice(0, 19).replace(/[:T]/g, \"-\");\n anchor.href = url;\n anchor.download = `openclaw-logs-${label}-${stamp}.log`;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\nexport function observeTopbar(host: ScrollHost) {\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n const topbar = host.querySelector(\".topbar\");\n if (!topbar) {\n return;\n }\n const update = () => {\n const { height } = topbar.getBoundingClientRect();\n host.style.setProperty(\"--topbar-height\", `${height}px`);\n };\n update();\n host.topbarObserver = new ResizeObserver(() => update());\n host.topbarObserver.observe(topbar);\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { HealthSnapshot, StatusSummary } from \"../types.ts\";\n\nexport type DebugState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n debugLoading: boolean;\n debugStatus: StatusSummary | null;\n debugHealth: HealthSnapshot | null;\n debugModels: unknown[];\n debugHeartbeat: unknown;\n debugCallMethod: string;\n debugCallParams: string;\n debugCallResult: string | null;\n debugCallError: string | null;\n};\n\nexport async function loadDebug(state: DebugState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.debugLoading) {\n return;\n }\n state.debugLoading = true;\n try {\n const [status, health, models, heartbeat] = await Promise.all([\n state.client.request(\"status\", {}),\n state.client.request(\"health\", {}),\n state.client.request(\"models.list\", {}),\n state.client.request(\"last-heartbeat\", {}),\n ]);\n state.debugStatus = status as StatusSummary;\n state.debugHealth = health as HealthSnapshot;\n const modelPayload = models as { models?: unknown[] } | undefined;\n state.debugModels = Array.isArray(modelPayload?.models) ? modelPayload?.models : [];\n state.debugHeartbeat = heartbeat;\n } catch (err) {\n state.debugCallError = String(err);\n } finally {\n state.debugLoading = false;\n }\n}\n\nexport async function callDebugMethod(state: DebugState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.debugCallError = null;\n state.debugCallResult = null;\n try {\n const params = state.debugCallParams.trim()\n ? (JSON.parse(state.debugCallParams) as unknown)\n : {};\n const res = await state.client.request(state.debugCallMethod.trim(), params);\n state.debugCallResult = JSON.stringify(res, null, 2);\n } catch (err) {\n state.debugCallError = String(err);\n }\n}\n","import { normalizeDeviceMetadataForAuth } from \"./device-metadata-normalization.js\";\nexport { normalizeDeviceMetadataForAuth };\n\nexport type DeviceAuthPayloadParams = {\n deviceId: string;\n clientId: string;\n clientMode: string;\n role: string;\n scopes: string[];\n signedAtMs: number;\n token?: string | null;\n nonce: string;\n};\n\nexport type DeviceAuthPayloadV3Params = DeviceAuthPayloadParams & {\n platform?: string | null;\n deviceFamily?: string | null;\n};\n\nexport function buildDeviceAuthPayload(params: DeviceAuthPayloadParams): string {\n const scopes = params.scopes.join(\",\");\n const token = params.token ?? \"\";\n return [\n \"v2\",\n params.deviceId,\n params.clientId,\n params.clientMode,\n params.role,\n scopes,\n String(params.signedAtMs),\n token,\n params.nonce,\n ].join(\"|\");\n}\n\nexport function buildDeviceAuthPayloadV3(params: DeviceAuthPayloadV3Params): string {\n const scopes = params.scopes.join(\",\");\n const token = params.token ?? \"\";\n const platform = normalizeDeviceMetadataForAuth(params.platform);\n const deviceFamily = normalizeDeviceMetadataForAuth(params.deviceFamily);\n return [\n \"v3\",\n params.deviceId,\n params.clientId,\n params.clientMode,\n params.role,\n scopes,\n String(params.signedAtMs),\n token,\n params.nonce,\n platform,\n deviceFamily,\n ].join(\"|\");\n}\n","export const GATEWAY_CLIENT_IDS = {\n WEBCHAT_UI: \"webchat-ui\",\n CONTROL_UI: \"openclaw-control-ui\",\n WEBCHAT: \"webchat\",\n CLI: \"cli\",\n GATEWAY_CLIENT: \"gateway-client\",\n MACOS_APP: \"openclaw-macos\",\n IOS_APP: \"openclaw-ios\",\n ANDROID_APP: \"openclaw-android\",\n NODE_HOST: \"node-host\",\n EVEN_G2_NODE: \"openclaw-even-g2-node\",\n WEDNESDAYAI_GLASS_NODE: \"wednesdayai-glass-node\",\n MENTRA_NODE: \"openclaw-mentra-node\",\n USER_CLIENT: \"openclaw-user-client\",\n TEST: \"test\",\n FINGERPRINT: \"fingerprint\",\n PROBE: \"openclaw-probe\",\n} as const;\n\nexport type GatewayClientId = (typeof GATEWAY_CLIENT_IDS)[keyof typeof GATEWAY_CLIENT_IDS];\n\n// Back-compat naming (internal): these values are IDs, not display names.\nexport const GATEWAY_CLIENT_NAMES = GATEWAY_CLIENT_IDS;\nexport type GatewayClientName = GatewayClientId;\n\nexport const GATEWAY_CLIENT_MODES = {\n WEBCHAT: \"webchat\",\n CLI: \"cli\",\n UI: \"ui\",\n BACKEND: \"backend\",\n NODE: \"node\",\n PROBE: \"probe\",\n TEST: \"test\",\n} as const;\n\nexport type GatewayClientMode = (typeof GATEWAY_CLIENT_MODES)[keyof typeof GATEWAY_CLIENT_MODES];\n\nexport type GatewayClientInfo = {\n id: GatewayClientId;\n displayName?: string;\n version: string;\n platform: string;\n deviceFamily?: string;\n modelIdentifier?: string;\n mode: GatewayClientMode;\n instanceId?: string;\n};\n\nexport const GATEWAY_CLIENT_CAPS = {\n TOOL_EVENTS: \"tool-events\",\n UI_SURFACES: \"ui-surfaces\",\n} as const;\n\nexport type GatewayClientCap = (typeof GATEWAY_CLIENT_CAPS)[keyof typeof GATEWAY_CLIENT_CAPS];\n\nconst GATEWAY_CLIENT_ID_SET = new Set<GatewayClientId>(Object.values(GATEWAY_CLIENT_IDS));\nconst GATEWAY_CLIENT_MODE_SET = new Set<GatewayClientMode>(Object.values(GATEWAY_CLIENT_MODES));\n\nexport function normalizeGatewayClientId(raw?: string | null): GatewayClientId | undefined {\n const normalized = raw?.trim().toLowerCase();\n if (!normalized) {\n return undefined;\n }\n return GATEWAY_CLIENT_ID_SET.has(normalized as GatewayClientId)\n ? (normalized as GatewayClientId)\n : undefined;\n}\n\nexport function normalizeGatewayClientName(raw?: string | null): GatewayClientName | undefined {\n return normalizeGatewayClientId(raw);\n}\n\nexport function normalizeGatewayClientMode(raw?: string | null): GatewayClientMode | undefined {\n const normalized = raw?.trim().toLowerCase();\n if (!normalized) {\n return undefined;\n }\n return GATEWAY_CLIENT_MODE_SET.has(normalized as GatewayClientMode)\n ? (normalized as GatewayClientMode)\n : undefined;\n}\n\nexport function hasGatewayClientCap(\n caps: string[] | null | undefined,\n cap: GatewayClientCap,\n): boolean {\n if (!Array.isArray(caps)) {\n return false;\n }\n return caps.includes(cap);\n}\n","export type DeviceAuthEntry = {\n token: string;\n role: string;\n scopes: string[];\n updatedAtMs: number;\n};\n\nexport type DeviceAuthStore = {\n version: 1;\n deviceId: string;\n tokens: Record<string, DeviceAuthEntry>;\n};\n\nexport function normalizeDeviceAuthRole(role: string): string {\n return role.trim();\n}\n\nexport function normalizeDeviceAuthScopes(scopes: string[] | undefined): string[] {\n if (!Array.isArray(scopes)) {\n return [];\n }\n const out = new Set<string>();\n for (const scope of scopes) {\n const trimmed = scope.trim();\n if (trimmed) {\n out.add(trimmed);\n }\n }\n return [...out].toSorted();\n}\n","import {\n type DeviceAuthEntry,\n type DeviceAuthStore,\n normalizeDeviceAuthRole,\n normalizeDeviceAuthScopes,\n} from \"./device-auth.js\";\nexport type { DeviceAuthEntry, DeviceAuthStore } from \"./device-auth.js\";\n\nexport type DeviceAuthStoreAdapter = {\n readStore: () => DeviceAuthStore | null;\n writeStore: (store: DeviceAuthStore) => void;\n};\n\nexport function loadDeviceAuthTokenFromStore(params: {\n adapter: DeviceAuthStoreAdapter;\n deviceId: string;\n role: string;\n}): DeviceAuthEntry | null {\n const store = params.adapter.readStore();\n if (!store || store.deviceId !== params.deviceId) {\n return null;\n }\n const role = normalizeDeviceAuthRole(params.role);\n const entry = store.tokens[role];\n if (!entry || typeof entry.token !== \"string\") {\n return null;\n }\n return entry;\n}\n\nexport function storeDeviceAuthTokenInStore(params: {\n adapter: DeviceAuthStoreAdapter;\n deviceId: string;\n role: string;\n token: string;\n scopes?: string[];\n}): DeviceAuthEntry {\n const role = normalizeDeviceAuthRole(params.role);\n const existing = params.adapter.readStore();\n const next: DeviceAuthStore = {\n version: 1,\n deviceId: params.deviceId,\n tokens:\n existing && existing.deviceId === params.deviceId && existing.tokens\n ? { ...existing.tokens }\n : {},\n };\n const entry: DeviceAuthEntry = {\n token: params.token,\n role,\n scopes: normalizeDeviceAuthScopes(params.scopes),\n updatedAtMs: Date.now(),\n };\n next.tokens[role] = entry;\n params.adapter.writeStore(next);\n return entry;\n}\n\nexport function clearDeviceAuthTokenFromStore(params: {\n adapter: DeviceAuthStoreAdapter;\n deviceId: string;\n role: string;\n}): void {\n const store = params.adapter.readStore();\n if (!store || store.deviceId !== params.deviceId) {\n return;\n }\n const role = normalizeDeviceAuthRole(params.role);\n if (!store.tokens[role]) {\n return;\n }\n const next: DeviceAuthStore = {\n version: 1,\n deviceId: store.deviceId,\n tokens: { ...store.tokens },\n };\n delete next.tokens[role];\n params.adapter.writeStore(next);\n}\n","import {\n clearDeviceAuthTokenFromStore,\n type DeviceAuthEntry,\n loadDeviceAuthTokenFromStore,\n storeDeviceAuthTokenInStore,\n} from \"../../../src/shared/device-auth-store.js\";\nimport type { DeviceAuthStore } from \"../../../src/shared/device-auth.js\";\n\nconst STORAGE_KEY = \"openclaw.device.auth.v1\";\n\nfunction readStore(): DeviceAuthStore | null {\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) {\n return null;\n }\n const parsed = JSON.parse(raw) as DeviceAuthStore;\n if (!parsed || parsed.version !== 1) {\n return null;\n }\n if (!parsed.deviceId || typeof parsed.deviceId !== \"string\") {\n return null;\n }\n if (!parsed.tokens || typeof parsed.tokens !== \"object\") {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction writeStore(store: DeviceAuthStore) {\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(store));\n } catch {\n // best-effort\n }\n}\n\nexport function loadDeviceAuthToken(params: {\n deviceId: string;\n role: string;\n}): DeviceAuthEntry | null {\n return loadDeviceAuthTokenFromStore({\n adapter: { readStore, writeStore },\n deviceId: params.deviceId,\n role: params.role,\n });\n}\n\nexport function storeDeviceAuthToken(params: {\n deviceId: string;\n role: string;\n token: string;\n scopes?: string[];\n}): DeviceAuthEntry {\n return storeDeviceAuthTokenInStore({\n adapter: { readStore, writeStore },\n deviceId: params.deviceId,\n role: params.role,\n token: params.token,\n scopes: params.scopes,\n });\n}\n\nexport function clearDeviceAuthToken(params: { deviceId: string; role: string }) {\n clearDeviceAuthTokenFromStore({\n adapter: { readStore, writeStore },\n deviceId: params.deviceId,\n role: params.role,\n });\n}\n","/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */\n/**\n * 5KB JS implementation of ed25519 EdDSA signatures.\n * Targets RFC8032, FIPS 186-5, and ZIP215 behavior.\n * @module\n * @example\n * ```js\nimport * as ed from '@noble/ed25519';\n(async () => {\n const secretKey = ed.utils.randomSecretKey();\n const message = Uint8Array.from([0xab, 0xbc, 0xcd, 0xde]);\n const pubKey = await ed.getPublicKeyAsync(secretKey); // Sync methods are also present\n const signature = await ed.signAsync(message, secretKey);\n const isValid = await ed.verifyAsync(signature, message, pubKey);\n})();\n```\n */\n/**\n * Curve params. edwards25519 uses the RFC equation `-x² + y² = 1 + dx²y²`.\n * The stored `a` literal below is `p - 1`, i.e. the field-element encoding of RFC `a = -1`.\n * * P = `2n**255n - 19n` // field over which calculations are done\n * * N = `2n**252n + 27742317777372353535851937790883648493n` // prime-order subgroup order\n * * h = 8 // cofactor\n * * a = `Fp.create(BigInt(-1))` // equation param, stored here as `p - 1`\n * * d = -121665/121666 a.k.a. `Fp.neg(121665 * Fp.inv(121666))` // equation param\n * * Gx, Gy are coordinates of Generator / base point\n *\n * Mirror noble-curves: Point.CURVE() exposes shared params, but callers must not be able to mutate\n * that shared view and desynchronize it from the arithmetic constants captured below.\n */\nconst ed25519_CURVE = Object.freeze({\n p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,\n n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,\n h: 8n,\n a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,\n d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,\n Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,\n Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n,\n});\nconst { p: P, n: N, Gx, Gy, a: _a, d: _d, h } = ed25519_CURVE;\nconst L = 32; // shared 32-byte encoded width for Ed25519 points, scalars, signatures, and keys\n// Helpers and Precomputes sections are reused between libraries\n// ## Helpers\n// ----------\n// @ts-ignore\nconst captureTrace = (...args) => {\n if ('captureStackTrace' in Error && typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(...args);\n }\n};\nconst err = (message = '') => {\n const e = new Error(message);\n captureTrace(e, err);\n throw e;\n};\nconst isBig = (n) => typeof n === 'bigint'; // is big integer\nconst isStr = (s) => typeof s === 'string'; // is string\n// Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases. The\n// fallback still requires a real ArrayBuffer view so plain JSON-deserialized `{ constructor: ... }`\n// spoofing is rejected, and `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\nconst isBytes = (a) => a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1);\n/**\n * Asserts something is Bytes, optionally enforces exact length,\n * and returns the same reference.\n */\nconst abytes = (value, length, title = '') => {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const msg = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n throw bytes ? new RangeError(msg) : new TypeError(msg);\n }\n return value;\n};\n/** create Uint8Array */\nconst u8n = (len) => new Uint8Array(len);\n// Clone helper used before in-place byte edits such as sign-bit clearing or endian reversal.\nconst u8fr = (buf) => Uint8Array.from(buf);\n// Left-pad hex to a caller-chosen width. Width enforcement/truncation policy stays with callers.\nconst padh = (n, pad) => n.toString(16).padStart(pad, '0');\n// Lowercase hex serializer.\nconst bytesToHex = (b) => Array.from(abytes(b))\n .map((e) => padh(e, 2))\n .join('');\nconst C = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 }; // ASCII characters\nconst _ch = (ch) => {\n if (ch >= C._0 && ch <= C._9)\n return ch - C._0; // '2' => 50-48\n if (ch >= C.A && ch <= C.F)\n return ch - (C.A - 10); // 'B' => 66-(65-10)\n if (ch >= C.a && ch <= C.f)\n return ch - (C.a - 10); // 'b' => 98-(97-10)\n return;\n};\n// Accepts both uppercase and lowercase hex; all parse failures intentionally collapse to `hex invalid`.\nconst hexToBytes = (hex) => {\n const e = 'hex invalid';\n if (!isStr(hex))\n return err(e);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2)\n return err(e);\n const array = u8n(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n // treat each char as ASCII\n const n1 = _ch(hex.charCodeAt(hi)); // parse first char, multiply it by 16\n const n2 = _ch(hex.charCodeAt(hi + 1)); // parse second char\n if (n1 === undefined || n2 === undefined)\n return err(e);\n array[ai] = n1 * 16 + n2; // example: 'A9' => 10*16 + 9\n }\n return array;\n};\nconst cr = () => globalThis?.crypto; // Optional WebCrypto lookup; sync code still handles absence.\n// Async-path capability helper for WebCrypto-backed APIs.\nconst subtle = () => cr()?.subtle ?? err('crypto.subtle must be defined, consider polyfill');\n// prettier-ignore\nconst concatBytes = (...arrs) => {\n // Argument order is transcript-significant for hash/signature callers, and input validation here\n // intentionally reuses `abytes(...)` without making defensive copies of the source chunks.\n let len = 0;\n for (const a of arrs)\n len += abytes(a).length;\n const r = u8n(len); // create u8a of summed length\n let pad = 0; // walk through each array,\n arrs.forEach(a => { r.set(a, pad); pad += a.length; }); // ensure they have proper type\n return r;\n};\n/** WebCrypto OS-level CSPRNG (random number generator). Absence still fails later via `cr()`. */\nconst randomBytes = (len = L) => {\n const c = cr();\n return c.getRandomValues(u8n(len));\n};\nconst big = BigInt;\n/** Inclusive-lower, exclusive-upper bigint range assertion. */\nconst assertRange = (n, min, max, msg = 'bad number: out of range') => {\n if (!isBig(n))\n throw new TypeError(msg);\n if (min <= n && n < max)\n return n;\n throw new RangeError(msg);\n};\n/** Canonical modular reduction into `[0, b)`. */\nconst M = (a, b = P) => {\n const r = a % b;\n return r >= 0n ? r : b + r;\n};\n// Low-255-bit mask used by the `2^255 - 19` fast reduction in `modP(...)`.\nconst P_MASK = (1n << 255n) - 1n;\n// Fast reduction for the special prime `2^255 - 19`. This path assumes nonnegative inputs; the\n// generic fallback would simply be `M(num, P)`.\nconst modP = (num) => {\n // return M(num, P);\n if (num < 0n)\n err('negative coordinate');\n let r = (num >> 255n) * 19n + (num & P_MASK);\n r = (r >> 255n) * 19n + (r & P_MASK);\n return r % P;\n};\n// Reduce modulo the subgroup order stored in implementation constant `N` (RFC 8032's `L`).\nconst modN = (a) => M(a, N);\n/** Modular inversion using Euclidean GCD (non-CT) instead of the RFC's `x^(p-2)` formulation.\n * This still sits on secret-dependent paths like point normalization during keygen/signing. */\n// prettier-ignore\nconst invert = (num, md) => {\n if (num === 0n || md <= 0n)\n err('no inverse n=' + num + ' mod=' + md);\n let a = M(num, md), b = md, x = 0n, y = 1n, u = 1n, v = 0n;\n while (a !== 0n) {\n const q = b / a, r = b % a;\n const m = x - u * q, n = y - v * q;\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n return b === 1n ? M(x, md) : err('no inverse'); // b is gcd at this point\n};\n// Dynamic lookup keeps sync/async hash providers configurable at runtime. Both exported slots are\n// caller-owned and may be unset; wrapper helpers use this lookup first and then enforce the digest\n// contract instead of trusting provider output.\nconst callHash = (name) => {\n // @ts-ignore\n const fn = hashes[name];\n if (typeof fn !== 'function')\n err('hashes.' + name + ' not set');\n return fn;\n};\n// Both provider slots are configurable API surface and may return arbitrary values, so callers must\n// enforce the promised 64-byte SHA-512 digest contract here instead of trusting provider output.\nconst checkDigest = (value) => abytes(value, 64, 'digest');\n/**\n * SHA-512 helper used by the synchronous API.\n * @param msg - Message bytes to hash.\n * @returns 64-byte SHA-512 digest.\n * @example\n * Hash message bytes after wiring the synchronous SHA-512 implementation.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const digest = ed.hash(new Uint8Array([1, 2, 3]));\n * ```\n */\n// Public helper validates the message boundary explicitly; the configured provider is still looked\n// up dynamically and its output is checked with `checkDigest(...)`.\nconst hash = (msg) => checkDigest(callHash('sha512')(abytes(msg, undefined, 'message')));\n// Runtime class guard: this is `instanceof Point`, so cross-realm / duplicate-bundle Point objects\n// are rejected even if they are structurally identical.\nconst apoint = (p) => (p instanceof Point ? p : err('Point expected'));\n// ## End of Helpers\n// -----------------\n// Exclusive upper bound `2^256` used by 32-byte decode/serialization range checks.\nconst B256 = 2n ** 256n;\n/**\n * Point in XYZT extended coordinates.\n * @param X - X coordinate.\n * @param Y - Y coordinate.\n * @param Z - Projective Z coordinate.\n * @param T - Cached cross-product term.\n * @example\n * Do point arithmetic with the built-in base point and encode the result as hex.\n *\n * ```ts\n * const hex = Point.BASE.double().toHex();\n * ```\n */\nclass Point {\n static BASE;\n static ZERO;\n X;\n Y;\n Z;\n T;\n // Constructor only bounds-checks and freezes XYZT coordinates; it does not prove the point is\n // on-curve or that T matches X*Y/Z.\n constructor(X, Y, Z, T) {\n const max = B256;\n this.X = assertRange(X, 0n, max);\n this.Y = assertRange(Y, 0n, max);\n this.Z = assertRange(Z, 1n, max);\n this.T = assertRange(T, 0n, max);\n Object.freeze(this);\n }\n static CURVE() {\n return ed25519_CURVE;\n }\n static fromAffine(p) {\n return new Point(p.x, p.y, 1n, modP(p.x * p.y));\n }\n /** RFC8032 5.1.3: Bytes to Point. */\n static fromBytes(hex, zip215 = false) {\n const d = _d;\n // Copy array to not mess it up.\n const normed = u8fr(abytes(hex, L));\n // adjust first LE byte = last BE byte\n const lastByte = hex[31];\n normed[31] = lastByte & ~0x80;\n const y = bytesToNumberLE(normed);\n // After clearing the sign bit, parsed `y` is always < 2^255. ZIP-215 still accepts the full\n // post-mask range here, while strict RFC8032 decoding further requires `y < p`.\n const max = zip215 ? B256 : P;\n assertRange(y, 0n, max);\n const y2 = modP(y * y); // y²\n const u = M(y2 - 1n); // u=y²-1\n const v = modP(d * y2 + 1n); // v=dy²+1\n let { isValid, value: x } = uvRatio(u, v); // (uv³)(uv⁷)^(p-5)/8; square root\n if (!isValid)\n err('bad point: y not sqrt'); // not square root: bad point\n const isXOdd = (x & 1n) === 1n; // adjust sign of x coordinate\n const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit\n // ZIP-215-compatible decoding keeps the x=0 / sign-bit=1 encoding accepted; strict RFC 8032\n // rejects it, but the vendored ZIP-215 compliance vectors include this form in A/R bytes.\n if (!zip215 && x === 0n && isLastByteOdd)\n err('bad point: x==0, isLastByteOdd'); // x=0, x_0=1\n if (isLastByteOdd !== isXOdd)\n x = M(-x);\n return new Point(x, y, 1n, modP(x * y)); // Z=1, T=xy\n }\n static fromHex(hex, zip215) {\n return Point.fromBytes(hexToBytes(hex), zip215);\n }\n get x() {\n return this.toAffine().x;\n }\n get y() {\n return this.toAffine().y;\n }\n /** Checks if the point is valid and on-curve. */\n assertValidity() {\n const a = _a;\n const d = _d;\n const p = this;\n // Intentional stricter-than-on-curve policy: reject ZERO by default because many protocols\n // require a non-zero point, and silently accepting identity points is a common caller mistake.\n if (p.is0())\n return err('bad point: ZERO'); // TODO: optimize, with vars below?\n // Equation in affine coordinates: ax² + y² = 1 + dx²y²\n // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²\n const { X, Y, Z, T } = p;\n const X2 = modP(X * X); // X²\n const Y2 = modP(Y * Y); // Y²\n const Z2 = modP(Z * Z); // Z²\n const Z4 = modP(Z2 * Z2); // Z⁴\n const aX2 = modP(X2 * a); // aX²\n const left = modP(Z2 * (aX2 + Y2)); // (aX² + Y²)Z²\n const right = M(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²\n if (left !== right)\n return err('bad point: equation left != right (1)');\n // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T\n const XY = modP(X * Y);\n const ZT = modP(Z * T);\n if (XY !== ZT)\n return err('bad point: equation left != right (2)');\n return this;\n }\n /** Equality check: compare points P&Q. */\n equals(other) {\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const { X: X2, Y: Y2, Z: Z2 } = apoint(other); // checks class equality\n const X1Z2 = modP(X1 * Z2);\n const X2Z1 = modP(X2 * Z1);\n const Y1Z2 = modP(Y1 * Z2);\n const Y2Z1 = modP(Y2 * Z1);\n return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;\n }\n is0() {\n return this.equals(I);\n }\n /** Flip point over y coordinate. */\n negate() {\n return new Point(M(-this.X), this.Y, this.Z, M(-this.T));\n }\n /** Point doubling. Complete formula. Cost: `4M + 4S + 1*a + 6add + 1*2`. */\n double() {\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const a = _a;\n // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd\n const A = modP(X1 * X1);\n const B = modP(Y1 * Y1);\n const C = modP(2n * Z1 * Z1);\n const D = modP(a * A);\n const x1y1 = M(X1 + Y1);\n const E = M(modP(x1y1 * x1y1) - A - B);\n const G = M(D + B);\n const F = M(G - C);\n const H = M(D - B);\n const X3 = modP(E * F);\n const Y3 = modP(G * H);\n const T3 = modP(E * H);\n const Z3 = modP(F * G);\n return new Point(X3, Y3, Z3, T3);\n }\n /** Point addition. Complete formula. Cost: `8M + 1*k + 8add + 1*2`. */\n add(other) {\n const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;\n const { X: X2, Y: Y2, Z: Z2, T: T2 } = apoint(other); // doesn't check if other on-curve\n const a = _a;\n const d = _d;\n // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3\n const A = modP(X1 * X2);\n const B = modP(Y1 * Y2);\n const C = modP(modP(T1 * d) * T2);\n const D = modP(Z1 * Z2);\n const E = M(modP(M(X1 + Y1) * M(X2 + Y2)) - A - B);\n const F = M(D - C);\n const G = M(D + C);\n const H = M(B - modP(a * A));\n const X3 = modP(E * F);\n const Y3 = modP(G * H);\n const T3 = modP(E * H);\n const Z3 = modP(F * G);\n return new Point(X3, Y3, Z3, T3);\n }\n subtract(other) {\n return this.add(apoint(other).negate());\n }\n /**\n * Point-by-scalar multiplication. Safe mode requires `1 <= n < CURVE.n`.\n * Unsafe mode additionally permits `n = 0` and returns the identity point for that case.\n * Uses {@link wNAF} for base point.\n * Uses fake point to mitigate side-channel leakage.\n * @param n - scalar by which point is multiplied\n * @param safe - safe mode guards against timing attacks; unsafe mode is faster\n */\n multiply(n, safe = true) {\n // Mirror noble-curves: unsafe mode still validates scalar range first, but intentionally keeps\n // `n = 0` as the one extra accepted case used by verification-style callers.\n if (!safe && n === 0n)\n return I;\n assertRange(n, 1n, N);\n if (!safe && this.is0())\n return I;\n if (n === 1n)\n return this;\n if (this.equals(G))\n return wNAF(n).p;\n // init result point & fake point\n let p = I;\n let f = G;\n for (let d = this; n > 0n; d = d.double(), n >>= 1n) {\n // if bit is present, add to point\n // if not present, add to fake, for timing safety\n if (n & 1n)\n p = p.add(d);\n else if (safe)\n f = f.add(d);\n }\n return p;\n }\n multiplyUnsafe(scalar) {\n return this.multiply(scalar, false);\n }\n /** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */\n toAffine() {\n const { X, Y, Z } = this;\n // Fast-path only for the identity point; all other inputs still go through inversion.\n if (this.equals(I))\n return { x: 0n, y: 1n };\n const iz = invert(Z, P);\n // (Z * Z^-1) must be 1, otherwise bad math\n if (modP(Z * iz) !== 1n)\n err('invalid inverse');\n // x = X*Z^-1; y = Y*Z^-1\n const x = modP(X * iz);\n const y = modP(Y * iz);\n return { x, y };\n }\n toBytes() {\n const { x, y } = this.toAffine();\n const b = numTo32bLE(y);\n // store sign in first LE byte\n b[31] |= x & 1n ? 0x80 : 0;\n return b;\n }\n toHex() {\n return bytesToHex(this.toBytes());\n }\n clearCofactor() {\n return this.multiply(big(h), false);\n }\n isSmallOrder() {\n return this.clearCofactor().is0();\n }\n isTorsionFree() {\n // Multiply by big number N. We can't `mul(N)` because of checks. Instead, we `mul(N/2)*2+1`\n let p = this.multiply(N / 2n, false).double();\n if (N % 2n)\n p = p.add(this);\n return p.is0();\n }\n}\n/** Generator / base point */\nconst G = new Point(Gx, Gy, 1n, M(Gx * Gy));\n/** Identity / zero point */\nconst I = new Point(0n, 1n, 1n, 0n);\n// Static aliases\nPoint.BASE = G;\nPoint.ZERO = I;\nconst numTo32bLE = (num) => hexToBytes(padh(assertRange(num, 0n, B256), 64)).reverse();\n// Caller-enforced width: some sites require 32-byte RFC encodings, while others intentionally feed\n// wider SHA-512 output chunks through the same little-endian parser.\nconst bytesToNumberLE = (b) => big('0x' + bytesToHex(u8fr(abytes(b)).reverse()));\nconst pow2 = (x, power) => {\n // pow2(x, 4) == x^(2^4)\n // Negative `power` values are not rejected here and currently leave `x` unchanged.\n let r = x;\n while (power-- > 0n) {\n r = modP(r * r);\n }\n return r;\n};\n// prettier-ignore\nconst pow_2_252_3 = (x) => {\n const x2 = modP(x * x); // x^2, bits 1\n const b2 = modP(x2 * x); // x^3, bits 11\n const b4 = modP(pow2(b2, 2n) * b2); // x^(2^4-1), bits 1111\n const b5 = modP(pow2(b4, 1n) * x); // x^(2^5-1), bits 11111\n const b10 = modP(pow2(b5, 5n) * b5); // x^(2^10-1)\n const b20 = modP(pow2(b10, 10n) * b10); // x^(2^20-1)\n const b40 = modP(pow2(b20, 20n) * b20); // x^(2^40-1)\n const b80 = modP(pow2(b40, 40n) * b40); // x^(2^80-1)\n const b160 = modP(pow2(b80, 80n) * b80); // x^(2^160-1)\n const b240 = modP(pow2(b160, 80n) * b80); // x^(2^240-1)\n const b250 = modP(pow2(b240, 10n) * b10); // x^(2^250-1)\n const pow_p_5_8 = modP(pow2(b250, 2n) * x); // x^((p-5)/8), used by RFC8032 point decode\n return { pow_p_5_8, b2 };\n};\nconst RM1 = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n; // 2^((p-1)/4) = sqrt(-1)\n// RFC8032 §5.1.3 square-root helper for point decompression. `value` is only meaningful when\n// `isValid` is true; callers are also expected to pass canonical field elements with non-zero `v`.\n// prettier-ignore\nconst uvRatio = (u, v) => {\n const v3 = modP(v * modP(v * v)); // v³\n const v7 = modP(modP(v3 * v3) * v); // v⁷\n const pow = pow_2_252_3(modP(u * v7)).pow_p_5_8; // (uv⁷)^(p-5)/8\n let x = modP(u * modP(v3 * pow)); // (uv³)(uv⁷)^(p-5)/8\n const vx2 = modP(v * modP(x * x)); // vx²\n const root1 = x; // First root candidate\n const root2 = modP(x * RM1); // Second root candidate; RM1 is √-1\n const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root\n const useRoot2 = vx2 === M(-u); // If vx² = -u, set x <-- x * 2^((p-1)/4)\n const noRoot = vx2 === M(-u * RM1); // There is no valid root, vx² = -u√-1\n if (useRoot1)\n x = root1;\n if (useRoot2 || noRoot)\n x = root2; // We return root2 anyway, for const-time\n if ((M(x) & 1n) === 1n)\n x = M(-x); // edIsNegative\n return { isValid: useRoot1 || useRoot2, value: x };\n};\n// Implementation `N` is the subgroup order; `L` is only the shared 32-byte encoded width constant.\n// Reduce any little-endian byte string modulo the subgroup order; the `hash` name reflects the\n// common caller shape, not an input restriction.\nconst modL_LE = (hash) => modN(bytesToNumberLE(hash)); // modulo L; but little-endian\n// Both sync and async SHA-512 slots are exported/configurable; use `callHash(...)` for both so\n// missing async overrides fail explicitly, then validate the returned digest type/length.\nconst sha512a = (...m) => Promise.resolve(callHash('sha512Async')(concatBytes(...m))).then(checkDigest);\nconst sha512s = (...m) => checkDigest(callHash('sha512')(concatBytes(...m)));\n// RFC8032 5.1.5. Split the 64-byte hashed seed into the clamped scalar half and nonce prefix.\nconst hash2extK = (hashed) => {\n // slice creates a copy, unlike subarray\n const copy = u8fr(hashed);\n const head = copy.slice(0, 32);\n head[0] &= 248; // Clamp bits: 0b1111_1000\n head[31] &= 127; // 0b0111_1111\n head[31] |= 64; // 0b0100_0000\n const prefix = copy.slice(32, 64); // secret key \"prefix\"\n // RFC words this as `[s]B`; reducing the clamped little-endian scalar modulo `N` is equivalent\n // for base-point multiplication because `G` already has subgroup order `N`.\n const scalar = modL_LE(head);\n const point = G.multiply(scalar); // public key point\n const pointBytes = point.toBytes(); // point serialized to Uint8Array\n return { head, prefix, scalar, point, pointBytes };\n};\n// RFC8032 5.1.5; getPublicKey async, sync. Hash priv key and extract point.\nconst getExtendedPublicKeyAsync = (secretKey) => sha512a(abytes(secretKey, L)).then(hash2extK);\nconst getExtendedPublicKey = (secretKey) => hash2extK(sha512s(abytes(secretKey, L)));\n/**\n * Creates a 32-byte Ed25519 public key from the RFC 8032 32-byte secret-key seed. Async.\n * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.\n * @returns 32-byte public key.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Derive the public key bytes for a newly generated signer secret.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const secretKey = ed.utils.randomSecretKey();\n * const publicKey = await ed.getPublicKeyAsync(secretKey);\n * ```\n */\nconst getPublicKeyAsync = (secretKey) => getExtendedPublicKeyAsync(secretKey).then((p) => p.pointBytes);\n/**\n * Creates a 32-byte Ed25519 public key from the RFC 8032 32-byte secret-key seed.\n * To use, set `hashes.sha512` first.\n * @param priv - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.\n * @returns 32-byte public key.\n * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Derive the public key entirely through the synchronous API.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const secretKey = ed.utils.randomSecretKey();\n * const publicKey = ed.getPublicKey(secretKey);\n * ```\n */\nconst getPublicKey = (priv) => getExtendedPublicKey(priv).pointBytes;\nconst hashFinishA = (res) => sha512a(res.hashable).then(res.finish);\nconst hashFinishS = (res) => res.finish(sha512s(res.hashable));\n// Code, shared between sync & async sign\nconst _sign = (e, rBytes, msg) => {\n const { pointBytes: P, scalar: s } = e;\n const r = modL_LE(rBytes); // r was created outside, reduce it modulo L\n // RFC 8032 5.1.6 allows r mod L = 0, and SUPERCOP ref10 accepts the resulting identity-point\n // signature.\n // We intentionally keep the safe multiply() rejection here so a miswired all-zero SHA-512 provider\n // fails loudly instead of silently producing a degenerate signature.\n const R = G.multiply(r).toBytes(); // R = [r]B\n const hashable = concatBytes(R, P, msg); // dom2(F, C) || R || A || PH(M)\n const finish = (hashed) => {\n // k = SHA512(dom2(F, C) || R || A || PH(M))\n const S = modN(r + modL_LE(hashed) * s); // S = (r + k * s) mod L; 0 <= s < l\n return abytes(concatBytes(R, numTo32bLE(S)), 64); // 64-byte sig: 32-byte encoded R point || 32-byte LE(S)\n };\n return { hashable, finish };\n};\n/**\n * Signs message using secret key. Async.\n * Follows RFC8032 5.1.6.\n * @param message - Message bytes to sign.\n * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.\n * @returns 64-byte Ed25519 signature.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Sign an arbitrary message with a fresh Ed25519 secret key.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const secretKey = ed.utils.randomSecretKey();\n * const message = new Uint8Array([1, 2, 3]);\n * const signature = await ed.signAsync(message, secretKey);\n * ```\n */\nconst signAsync = async (message, secretKey) => {\n const m = abytes(message);\n const e = await getExtendedPublicKeyAsync(secretKey);\n const rBytes = await sha512a(e.prefix, m); // r = SHA512(dom2(F, C) || prefix || PH(M))\n return hashFinishA(_sign(e, rBytes, m)); // gen R, k, S, then 64-byte signature\n};\n/**\n * Signs message using secret key. To use, set `hashes.sha512` first.\n * Follows RFC8032 5.1.6.\n * @param message - Message bytes to sign.\n * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.\n * @returns 64-byte Ed25519 signature.\n * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Use the sync API when you've wired a SHA-512 implementation yourself.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const secretKey = ed.utils.randomSecretKey();\n * const signature = ed.sign(new Uint8Array([1, 2, 3]), secretKey);\n * ```\n */\nconst sign = (message, secretKey) => {\n const m = abytes(message);\n const e = getExtendedPublicKey(secretKey);\n const rBytes = sha512s(e.prefix, m); // r = SHA512(dom2(F, C) || prefix || PH(M))\n return hashFinishS(_sign(e, rBytes, m)); // gen R, k, S, then 64-byte signature\n};\n// Exported defaults favor ZIP-215 interoperability semantics; callers must opt into the stricter\n// branch with `{ zip215: false }`.\nconst defaultVerifyOpts = { zip215: true };\nconst _verify = (sig, msg, publicKey, options = defaultVerifyOpts) => {\n sig = abytes(sig, 64); // Signature hex str/Bytes, must be 64 bytes\n msg = abytes(msg); // Message hex str/Bytes\n publicKey = abytes(publicKey, L);\n // zip215=false keeps the library's stricter branch, which still canonicalizes `R` / `A` before\n // hashing and rejects small-order public keys earlier than pure RFC8032 text would require.\n // Preserve the exported ZIP-215 default for `{}` / `{ zip215: undefined }`, not just omitted opts.\n const { zip215 = true } = options;\n const r = sig.subarray(0, L);\n const s = bytesToNumberLE(sig.subarray(L, L * 2)); // Decode second half as an integer S;\n let A, R, SB;\n let hashable = Uint8Array.of();\n let finished = false;\n try {\n // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.\n // zip215=true: 0 <= y < MASK (2^256 for ed25519)\n // zip215=false: 0 <= y < P (2^255-19 for ed25519)\n A = Point.fromBytes(publicKey, zip215);\n R = Point.fromBytes(r, zip215);\n SB = G.multiply(s, false); // 0 <= s < l is done inside\n // ZIP-215 accepts noncanonical / unreduced point encodings, so the challenge hash must use the\n // exact signature/public-key bytes rather than canonicalized re-encodings of the decoded points.\n hashable = concatBytes(r, publicKey, msg); // dom2(F, C) || R || A || PH(M)\n finished = true;\n }\n catch (error) { }\n const finish = (hashed) => {\n if (!finished)\n return false;\n // Policy: strict mode intentionally rejects all small-order public keys, even though the raw RFC\n // equation text is looser here. This matches libsodium and avoids weak / ambiguous verification\n // outcomes where unusual low-order public keys can make distinct key/signature combinations verify.\n if (!zip215 && A.isSmallOrder())\n return false;\n // k = SHA512(dom2(F, C) || R || A || PH(M))\n const k = modL_LE(hashed);\n const RkA = R.add(A.multiply(k, false));\n // Extended group equation\n // [8][S]B = [8]R + [8][k]A'\n return RkA.subtract(SB).clearCofactor().is0();\n };\n return { hashable, finish };\n};\n/**\n * Verifies a signature on message and public key. Async.\n * The implementation is based on RFC8032 5.1.7, but default opts use ZIP-215 semantics; pass\n * `{ zip215: false }` for the library's stricter branch.\n * @param signature - 64-byte signature.\n * @param message - Signed message bytes.\n * @param publicKey - 32-byte public key.\n * @param opts - Verification options. Defaults to ZIP-215 semantics. See {@link EdDSAVerifyOpts}.\n * @returns `true` when the signature is valid.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Verify the signature against the same message and derived public key.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const secretKey = ed.utils.randomSecretKey();\n * const message = new Uint8Array([1, 2, 3]);\n * const publicKey = await ed.getPublicKeyAsync(secretKey);\n * const signature = await ed.signAsync(message, secretKey);\n * const isValid = await ed.verifyAsync(signature, message, publicKey);\n * ```\n */\nconst verifyAsync = async (signature, message, publicKey, opts = defaultVerifyOpts) => hashFinishA(_verify(signature, message, publicKey, opts));\n/**\n * Verifies a signature on message and public key using the synchronous hash path.\n * The implementation is based on RFC8032 5.1.7, but default opts use ZIP-215 semantics; pass\n * `{ zip215: false }` for the library's stricter branch.\n * @param signature - 64-byte signature.\n * @param message - Signed message bytes.\n * @param publicKey - 32-byte public key.\n * @param opts - Verification options. Defaults to ZIP-215 semantics. See {@link EdDSAVerifyOpts}.\n * @returns `true` when the signature is valid.\n * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Verify a signature entirely through the synchronous API.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const secretKey = ed.utils.randomSecretKey();\n * const message = new Uint8Array([1, 2, 3]);\n * const publicKey = ed.getPublicKey(secretKey);\n * const signature = ed.sign(message, secretKey);\n * const isValid = ed.verify(signature, message, publicKey);\n * ```\n */\nconst verify = (signature, message, publicKey, opts = defaultVerifyOpts) => hashFinishS(_verify(signature, message, publicKey, opts));\n/**\n * Math, hex, byte helpers. Not in `utils` because utils share API with noble-curves.\n * Exposes the same low-level field-default `mod` reducer and non-CT `invert` helper used\n * internally.\n * @example\n * Convert bytes to a hex string with the low-level helper namespace.\n *\n * ```ts\n * const hex = etc.bytesToHex(new Uint8Array([1, 2, 3]));\n * ```\n */\nconst etc = /* @__PURE__ */ Object.freeze({\n bytesToHex,\n hexToBytes,\n concatBytes,\n mod: M,\n invert: invert,\n randomBytes,\n});\n/**\n * Hash implementations used by the synchronous API plus the default async WebCrypto provider.\n * Both slots are configurable API surface; wrapper helpers revalidate that providers still return\n * 64-byte SHA-512 digests.\n * @example\n * Provide a SHA-512 implementation before calling synchronous helpers.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const { publicKey } = ed.keygen();\n * ```\n */\nconst hashes = {\n sha512Async: async (message) => {\n const s = subtle();\n const m = concatBytes(message);\n return u8n(await s.digest('SHA-512', m.buffer));\n },\n sha512: undefined,\n};\n// Returns the final 32-byte Ed25519 secret-key seed verbatim, generating fresh random bytes only\n// when omitted.\nconst randomSecretKey = (seed) => {\n seed = seed === undefined ? randomBytes(L) : seed;\n return abytes(seed, L);\n};\n/**\n * Generates a secret/public keypair.\n * @param seed - Optional 32-byte Ed25519 secret-key seed, returned verbatim as `secretKey`.\n * @returns Keypair with `secretKey` and `publicKey`.\n * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Generate a new keypair through the synchronous API after wiring SHA-512.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const { secretKey, publicKey } = ed.keygen();\n * ```\n */\nconst keygen = (seed) => {\n const secretKey = randomSecretKey(seed);\n const publicKey = getPublicKey(secretKey);\n return { secretKey, publicKey };\n};\n/**\n * Generates a secret/public keypair asynchronously.\n * @param seed - Optional 32-byte Ed25519 secret-key seed, returned verbatim as `secretKey`.\n * @returns Keypair with `secretKey` and `publicKey`.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Generate a new keypair through the asynchronous WebCrypto-backed path.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const { secretKey, publicKey } = await ed.keygenAsync();\n * ```\n */\nconst keygenAsync = async (seed) => {\n const secretKey = randomSecretKey(seed);\n const publicKey = await getPublicKeyAsync(secretKey);\n return { secretKey, publicKey };\n};\n/**\n * Ed25519-specific key utilities.\n * `utils.getExtendedPublicKey*` expose secret-derived internals (`head`, `prefix`, `scalar`, and\n * point objects), not just public-key bytes.\n * @example\n * Generate a new Ed25519 secret key and derive the matching public key.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const secretKey = ed.utils.randomSecretKey();\n * const publicKey = await ed.getPublicKeyAsync(secretKey);\n * ```\n */\nconst utils = /* @__PURE__ */ Object.freeze({\n getExtendedPublicKeyAsync: getExtendedPublicKeyAsync,\n getExtendedPublicKey: getExtendedPublicKey,\n randomSecretKey: randomSecretKey,\n});\n// ## Precomputes\n// --------------\nconst W = 8; // W is window size\nconst scalarBits = 256;\nconst pwindows = Math.ceil(scalarBits / W) + 1; // 33 for W=8, NOT 32 - see wNAF loop\nconst pwindowSize = 2 ** (W - 1); // 128 for W=8\n// Layout is grouped by window: each block stores the positive multiples `1*base .. 128*base` for\n// that window, and the extra `+1` window in `pwindows` absorbs carries from signed-digit recoding.\nconst precompute = () => {\n const points = [];\n let p = G;\n let b = p;\n for (let w = 0; w < pwindows; w++) {\n b = p;\n points.push(b);\n for (let i = 1; i < pwindowSize; i++) {\n b = b.add(p);\n points.push(b);\n } // i=1, bc we skip 0\n p = b.double();\n }\n return points;\n};\nlet Gpows = undefined; // shared process-wide cache of base-point precomputes\n// Branch-based negate helper used for JS/JIT mitigation symmetry, not a strict constant-time claim.\nconst ctneg = (cnd, p) => {\n const n = p.negate();\n return cnd ? n : p;\n};\n/**\n * Precomputes give 12x faster getPublicKey(), 10x sign(), 2x verify() by\n * caching multiples of G (base point). Cache is stored in 32MB of RAM.\n * Any time `G.multiply` is done, precomputes are used.\n * Not used for getSharedSecret, which instead multiplies random pubkey `P.multiply`.\n *\n * w-ary non-adjacent form (wNAF) precomputation method is 10% slower than windowed method,\n * but takes 2x less RAM. RAM reduction is possible by utilizing `.subtract`.\n * Returns the real accumulator `p` plus a fake accumulator `f`; callers only care about `p`, while\n * `f` exists to keep similar work in zero-digit branches as a JS/JIT side-channel mitigation.\n *\n * !! Precomputes can be disabled by commenting-out call of the wNAF() inside Point#multiply().\n */\nconst wNAF = (n) => {\n const comp = Gpows || (Gpows = precompute());\n let p = I;\n let f = G; // f must be G, or could become I in the end\n const pow_2_w = 2 ** W; // 256 for W=8\n const maxNum = pow_2_w; // 256 for W=8\n const mask = big(pow_2_w - 1); // 255 for W=8 == mask 0b11111111\n const shiftBy = big(W); // 8 for W=8\n for (let w = 0; w < pwindows; w++) {\n let wbits = Number(n & mask); // extract W bits.\n n >>= shiftBy; // shift number by W bits.\n // We use negative indexes to reduce size of precomputed table by 2x.\n // Instead of needing precomputes 0..256, we only calculate them for 0..128.\n // If an index > 128 is found, we do (256-index) - where 256 is next window.\n // Naive: index +127 => 127, +224 => 224\n // Optimized: index +127 => 127, +224 => 256-32\n if (wbits > pwindowSize) {\n wbits -= maxNum;\n n += 1n;\n }\n const off = w * pwindowSize;\n const offF = off; // offsets, evaluate both\n const offP = off + Math.abs(wbits) - 1;\n const isEven = w % 2 !== 0; // conditions, evaluate both\n const isNeg = wbits < 0;\n if (wbits === 0) {\n // off == I: can't add it. Adding random offF instead.\n f = f.add(ctneg(isEven, comp[offF])); // bits are 0: add garbage to fake point\n }\n else {\n p = p.add(ctneg(isNeg, comp[offP])); // bits are 1: add to result point\n }\n }\n if (n !== 0n)\n err('invalid wnaf');\n return { p, f }; // callers only need `p`; `f` is kept for zero-digit mitigation symmetry\n};\n// !! Remove the export to easily use in REPL / browser console\nexport { etc, getPublicKey, getPublicKeyAsync, hash, hashes, keygen, keygenAsync, Point, sign, signAsync, utils, verify, verifyAsync };\n","import { getPublicKeyAsync, signAsync, utils } from \"@noble/ed25519\";\n\ntype StoredIdentity = {\n version: 1;\n deviceId: string;\n publicKey: string;\n privateKey: string;\n createdAtMs: number;\n};\n\nexport type DeviceIdentity = {\n deviceId: string;\n publicKey: string;\n privateKey: string;\n};\n\nconst STORAGE_KEY = \"openclaw-device-identity-v1\";\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/g, \"\");\n}\n\nfunction base64UrlDecode(input: string): Uint8Array {\n const normalized = input.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n const padded = normalized + \"=\".repeat((4 - (normalized.length % 4)) % 4);\n const binary = atob(padded);\n const out = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) {\n out[i] = binary.charCodeAt(i);\n }\n return out;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nasync function fingerprintPublicKey(publicKey: Uint8Array): Promise<string> {\n const hash = await crypto.subtle.digest(\"SHA-256\", publicKey.slice().buffer);\n return bytesToHex(new Uint8Array(hash));\n}\n\nasync function generateIdentity(): Promise<DeviceIdentity> {\n const privateKey = utils.randomSecretKey();\n const publicKey = await getPublicKeyAsync(privateKey);\n const deviceId = await fingerprintPublicKey(publicKey);\n return {\n deviceId,\n publicKey: base64UrlEncode(publicKey),\n privateKey: base64UrlEncode(privateKey),\n };\n}\n\nexport async function loadOrCreateDeviceIdentity(): Promise<DeviceIdentity> {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as StoredIdentity;\n if (\n parsed?.version === 1 &&\n typeof parsed.deviceId === \"string\" &&\n typeof parsed.publicKey === \"string\" &&\n typeof parsed.privateKey === \"string\"\n ) {\n const derivedId = await fingerprintPublicKey(base64UrlDecode(parsed.publicKey));\n if (derivedId !== parsed.deviceId) {\n const updated: StoredIdentity = {\n ...parsed,\n deviceId: derivedId,\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));\n return {\n deviceId: derivedId,\n publicKey: parsed.publicKey,\n privateKey: parsed.privateKey,\n };\n }\n return {\n deviceId: parsed.deviceId,\n publicKey: parsed.publicKey,\n privateKey: parsed.privateKey,\n };\n }\n }\n } catch {\n // fall through to regenerate\n }\n\n const identity = await generateIdentity();\n const stored: StoredIdentity = {\n version: 1,\n deviceId: identity.deviceId,\n publicKey: identity.publicKey,\n privateKey: identity.privateKey,\n createdAtMs: Date.now(),\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(stored));\n return identity;\n}\n\nexport async function signDevicePayload(privateKeyBase64Url: string, payload: string) {\n const key = base64UrlDecode(privateKeyBase64Url);\n const data = new TextEncoder().encode(payload);\n const sig = await signAsync(data, key);\n return base64UrlEncode(sig);\n}\n","export type CryptoLike = {\n randomUUID?: (() => string) | undefined;\n getRandomValues?: (<T extends Exclude<BufferSource, ArrayBuffer>>(array: T) => T) | undefined;\n};\n\nlet warnedWeakCrypto = false;\n\nfunction uuidFromBytes(bytes: Uint8Array): string {\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 1\n\n let hex = \"\";\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i].toString(16).padStart(2, \"0\");\n }\n\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(\n 16,\n 20,\n )}-${hex.slice(20)}`;\n}\n\nfunction weakRandomBytes(): Uint8Array {\n const bytes = new Uint8Array(16);\n const now = Date.now();\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n bytes[0] ^= now & 0xff;\n bytes[1] ^= (now >>> 8) & 0xff;\n bytes[2] ^= (now >>> 16) & 0xff;\n bytes[3] ^= (now >>> 24) & 0xff;\n return bytes;\n}\n\nfunction warnWeakCryptoOnce() {\n if (warnedWeakCrypto) {\n return;\n }\n warnedWeakCrypto = true;\n console.warn(\"[uuid] crypto API missing; falling back to weak randomness\");\n}\n\nexport function generateUUID(cryptoLike: CryptoLike | null = globalThis.crypto): string {\n if (cryptoLike && typeof cryptoLike.randomUUID === \"function\") {\n return cryptoLike.randomUUID();\n }\n\n if (cryptoLike && typeof cryptoLike.getRandomValues === \"function\") {\n const bytes = new Uint8Array(16);\n cryptoLike.getRandomValues(bytes);\n return uuidFromBytes(bytes);\n }\n\n warnWeakCryptoOnce();\n return uuidFromBytes(weakRandomBytes());\n}\n","import { buildDeviceAuthPayload } from \"../../../src/gateway/device-auth.js\";\nimport {\n GATEWAY_CLIENT_MODES,\n GATEWAY_CLIENT_NAMES,\n type GatewayClientMode,\n type GatewayClientName,\n} from \"../../../src/gateway/protocol/client-info.js\";\nimport { readConnectErrorDetailCode } from \"../../../src/gateway/protocol/connect-error-details.js\";\nimport { clearDeviceAuthToken, loadDeviceAuthToken, storeDeviceAuthToken } from \"./device-auth.ts\";\nimport { loadOrCreateDeviceIdentity, signDevicePayload } from \"./device-identity.ts\";\nimport { generateUUID } from \"./uuid.ts\";\n\nexport type GatewayEventFrame = {\n type: \"event\";\n event: string;\n payload?: unknown;\n seq?: number;\n stateVersion?: { presence: number; health: number };\n};\n\nexport type GatewayResponseFrame = {\n type: \"res\";\n id: string;\n ok: boolean;\n payload?: unknown;\n error?: { code: string; message: string; details?: unknown };\n};\n\nexport type GatewayErrorInfo = {\n code: string;\n message: string;\n details?: unknown;\n};\n\nexport class GatewayRequestError extends Error {\n readonly gatewayCode: string;\n readonly details?: unknown;\n\n constructor(error: GatewayErrorInfo) {\n super(error.message);\n this.name = \"GatewayRequestError\";\n this.gatewayCode = error.code;\n this.details = error.details;\n }\n}\n\nexport function resolveGatewayErrorDetailCode(\n error: { details?: unknown } | null | undefined,\n): string | null {\n return readConnectErrorDetailCode(error?.details);\n}\n\nexport type GatewayHelloOk = {\n type: \"hello-ok\";\n protocol: number;\n server?: {\n version?: string;\n connId?: string;\n };\n features?: { methods?: string[]; events?: string[] };\n snapshot?: unknown;\n auth?: {\n deviceToken?: string;\n role?: string;\n scopes?: string[];\n issuedAtMs?: number;\n };\n policy?: { tickIntervalMs?: number };\n};\n\ntype Pending = {\n resolve: (value: unknown) => void;\n reject: (err: unknown) => void;\n};\n\nexport type GatewayBrowserClientOptions = {\n url: string;\n token?: string;\n password?: string;\n clientName?: GatewayClientName;\n clientVersion?: string;\n platform?: string;\n mode?: GatewayClientMode;\n instanceId?: string;\n onHello?: (hello: GatewayHelloOk) => void;\n onEvent?: (evt: GatewayEventFrame) => void;\n onClose?: (info: { code: number; reason: string; error?: GatewayErrorInfo }) => void;\n onGap?: (info: { expected: number; received: number }) => void;\n};\n\n// 4008 = application-defined code (browser rejects 1008 \"Policy Violation\")\nconst CONNECT_FAILED_CLOSE_CODE = 4008;\n\nexport class GatewayBrowserClient {\n private ws: WebSocket | null = null;\n private pending = new Map<string, Pending>();\n private closed = false;\n private lastSeq: number | null = null;\n private connectNonce: string | null = null;\n private connectSent = false;\n private connectTimer: number | null = null;\n private backoffMs = 800;\n private pendingConnectError: GatewayErrorInfo | undefined;\n\n constructor(private opts: GatewayBrowserClientOptions) {}\n\n start() {\n this.closed = false;\n this.connect();\n }\n\n stop() {\n this.closed = true;\n this.ws?.close();\n this.ws = null;\n this.pendingConnectError = undefined;\n this.flushPending(new Error(\"gateway client stopped\"));\n }\n\n get connected() {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n private connect() {\n if (this.closed) {\n return;\n }\n this.ws = new WebSocket(this.opts.url);\n this.ws.addEventListener(\"open\", () => this.queueConnect());\n this.ws.addEventListener(\"message\", (ev) => this.handleMessage(String(ev.data ?? \"\")));\n this.ws.addEventListener(\"close\", (ev) => {\n const reason = String(ev.reason ?? \"\");\n const connectError = this.pendingConnectError;\n this.pendingConnectError = undefined;\n this.ws = null;\n this.flushPending(new Error(`gateway closed (${ev.code}): ${reason}`));\n this.opts.onClose?.({ code: ev.code, reason, error: connectError });\n this.scheduleReconnect();\n });\n this.ws.addEventListener(\"error\", () => {\n // ignored; close handler will fire\n });\n }\n\n private scheduleReconnect() {\n if (this.closed) {\n return;\n }\n const delay = this.backoffMs;\n this.backoffMs = Math.min(this.backoffMs * 1.7, 15_000);\n window.setTimeout(() => this.connect(), delay);\n }\n\n private flushPending(err: Error) {\n for (const [, p] of this.pending) {\n p.reject(err);\n }\n this.pending.clear();\n }\n\n private async sendConnect() {\n if (this.connectSent) {\n return;\n }\n this.connectSent = true;\n if (this.connectTimer !== null) {\n window.clearTimeout(this.connectTimer);\n this.connectTimer = null;\n }\n\n // crypto.subtle is only available in secure contexts (HTTPS, localhost).\n // Over plain HTTP, we skip device identity and fall back to token-only auth.\n // Gateways may reject this unless gateway.controlUi.allowInsecureAuth is enabled.\n const isSecureContext = typeof crypto !== \"undefined\" && !!crypto.subtle;\n\n const scopes = [\"operator.admin\", \"operator.approvals\", \"operator.pairing\"];\n const role = \"operator\";\n let deviceIdentity: Awaited<ReturnType<typeof loadOrCreateDeviceIdentity>> | null = null;\n let canFallbackToShared = false;\n let authToken = this.opts.token;\n\n if (isSecureContext) {\n deviceIdentity = await loadOrCreateDeviceIdentity();\n const storedToken = loadDeviceAuthToken({\n deviceId: deviceIdentity.deviceId,\n role,\n })?.token;\n authToken = storedToken ?? this.opts.token;\n canFallbackToShared = Boolean(storedToken && this.opts.token);\n }\n const auth =\n authToken || this.opts.password\n ? {\n token: authToken,\n password: this.opts.password,\n }\n : undefined;\n\n let device:\n | {\n id: string;\n publicKey: string;\n signature: string;\n signedAt: number;\n nonce: string;\n }\n | undefined;\n\n if (isSecureContext && deviceIdentity) {\n const signedAtMs = Date.now();\n const nonce = this.connectNonce ?? \"\";\n const payload = buildDeviceAuthPayload({\n deviceId: deviceIdentity.deviceId,\n clientId: this.opts.clientName ?? GATEWAY_CLIENT_NAMES.CONTROL_UI,\n clientMode: this.opts.mode ?? GATEWAY_CLIENT_MODES.WEBCHAT,\n role,\n scopes,\n signedAtMs,\n token: authToken ?? null,\n nonce,\n });\n const signature = await signDevicePayload(deviceIdentity.privateKey, payload);\n device = {\n id: deviceIdentity.deviceId,\n publicKey: deviceIdentity.publicKey,\n signature,\n signedAt: signedAtMs,\n nonce,\n };\n }\n const params = {\n minProtocol: 3,\n maxProtocol: 3,\n client: {\n id: this.opts.clientName ?? GATEWAY_CLIENT_NAMES.CONTROL_UI,\n version: this.opts.clientVersion ?? \"dev\",\n platform: this.opts.platform ?? navigator.platform ?? \"web\",\n mode: this.opts.mode ?? GATEWAY_CLIENT_MODES.WEBCHAT,\n instanceId: this.opts.instanceId,\n },\n role,\n scopes,\n device,\n caps: [],\n auth,\n userAgent: navigator.userAgent,\n locale: navigator.language,\n };\n\n void this.request<GatewayHelloOk>(\"connect\", params)\n .then((hello) => {\n if (hello?.auth?.deviceToken && deviceIdentity) {\n storeDeviceAuthToken({\n deviceId: deviceIdentity.deviceId,\n role: hello.auth.role ?? role,\n token: hello.auth.deviceToken,\n scopes: hello.auth.scopes ?? [],\n });\n }\n this.backoffMs = 800;\n this.opts.onHello?.(hello);\n })\n .catch((err: unknown) => {\n if (err instanceof GatewayRequestError) {\n this.pendingConnectError = {\n code: err.gatewayCode,\n message: err.message,\n details: err.details,\n };\n } else {\n this.pendingConnectError = undefined;\n }\n if (canFallbackToShared && deviceIdentity) {\n clearDeviceAuthToken({ deviceId: deviceIdentity.deviceId, role });\n }\n this.ws?.close(CONNECT_FAILED_CLOSE_CODE, \"connect failed\");\n });\n }\n\n private handleMessage(raw: string) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return;\n }\n\n const frame = parsed as { type?: unknown };\n if (frame.type === \"event\") {\n const evt = parsed as GatewayEventFrame;\n if (evt.event === \"connect.challenge\") {\n const payload = evt.payload as { nonce?: unknown } | undefined;\n const nonce = payload && typeof payload.nonce === \"string\" ? payload.nonce : null;\n if (nonce) {\n this.connectNonce = nonce;\n void this.sendConnect();\n }\n return;\n }\n const seq = typeof evt.seq === \"number\" ? evt.seq : null;\n if (seq !== null) {\n if (this.lastSeq !== null && seq > this.lastSeq + 1) {\n this.opts.onGap?.({ expected: this.lastSeq + 1, received: seq });\n }\n this.lastSeq = seq;\n }\n try {\n this.opts.onEvent?.(evt);\n } catch (err) {\n console.error(\"[gateway] event handler error:\", err);\n }\n return;\n }\n\n if (frame.type === \"res\") {\n const res = parsed as GatewayResponseFrame;\n const pending = this.pending.get(res.id);\n if (!pending) {\n return;\n }\n this.pending.delete(res.id);\n if (res.ok) {\n pending.resolve(res.payload);\n } else {\n pending.reject(\n new GatewayRequestError({\n code: res.error?.code ?? \"UNAVAILABLE\",\n message: res.error?.message ?? \"request failed\",\n details: res.error?.details,\n }),\n );\n }\n return;\n }\n }\n\n request<T = unknown>(method: string, params?: unknown): Promise<T> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error(\"gateway not connected\"));\n }\n const id = generateUUID();\n const frame = { type: \"req\", id, method, params };\n const p = new Promise<T>((resolve, reject) => {\n this.pending.set(id, { resolve: (v) => resolve(v as T), reject });\n });\n this.ws.send(JSON.stringify(frame));\n return p;\n }\n\n private queueConnect() {\n this.connectNonce = null;\n this.connectSent = false;\n if (this.connectTimer !== null) {\n window.clearTimeout(this.connectTimer);\n }\n this.connectTimer = window.setTimeout(() => {\n void this.sendConnect();\n }, 750);\n }\n}\n","import type { TaskRunRecord } from \"../../../../src/config/sessions/task-run-types.js\";\nimport type {\n ProjectedMetricsEvent,\n ProjectedOutcomeEvent,\n ProjectedPhaseEvent,\n ProjectedRunEvent,\n RunEventsTruncationReason,\n TasksRunEventsResult,\n} from \"../../../../src/gateway/server-methods/tasks-run-events.js\";\nimport { GatewayRequestError, type GatewayBrowserClient, type GatewayHelloOk } from \"../gateway.ts\";\n\nexport type {\n ProjectedMetricsEvent,\n ProjectedOutcomeEvent,\n ProjectedPhaseEvent,\n ProjectedRunEvent,\n};\nexport type DreamsTaskRun = TaskRunRecord;\n\n// Every panel reports one of these: \"disabled\" = the method is absent from\n// hello.features.methods (plugin not loaded); \"degraded\" = the method exists but failed\n// (UNAVAILABLE or any other error); \"ok\" includes a successful empty answer.\nexport type PanelStatus = \"idle\" | \"loading\" | \"ok\" | \"disabled\" | \"degraded\";\n\nexport type PanelError = { code: string | null; message: string };\n\nexport type DreamsBudgetWindow = {\n available: boolean;\n error?: string;\n scopeKind: string;\n windowHours: number | null;\n cap: number | null;\n ceilingCap: number | null;\n windowStartTs: string | null;\n windowUsageUnits: number;\n totalDenied: number;\n resetCount: number;\n lastResetTs: string | null;\n};\n\nexport type RunEventsTruncation = Record<\n string,\n { reason: RunEventsTruncationReason; dropped: number }\n>;\n\nexport type DreamsRunsPanel = {\n status: PanelStatus;\n error: PanelError | null;\n runsAvailable: boolean;\n runsError: string | null;\n runs: DreamsTaskRun[];\n budgetWindow: DreamsBudgetWindow | null;\n eventsStatus: PanelStatus;\n eventsError: PanelError | null;\n events: Record<string, ProjectedRunEvent[]>;\n truncated: RunEventsTruncation;\n retentionDays: number | null;\n loadedAt: number | null;\n};\n\nexport type DreamStageView = { name: string; order: number; lastCompleted?: number };\nexport type DreamActiveCycle = {\n cycleKey: string;\n currentStage: string;\n pendingPassCount: number;\n failedStages: string[];\n createdAt: number;\n};\nexport type DreamStatusResult = {\n enabled: boolean;\n stages: DreamStageView[];\n questionCount: number;\n questionCountTruncated?: boolean;\n candidateCount: number;\n candidateCountTruncated?: boolean;\n contemplationConfigured?: boolean;\n activeCycles?: DreamActiveCycle[];\n};\nexport type DreamWeight = {\n agentId: string;\n totals: { completed: number; failed: number };\n successRate: number;\n updatedAt: number;\n};\nexport type DreamCandidate = { signature?: string; taskId?: string; firstSeenAt?: string };\n\nexport type DreamStatePanel = {\n status: PanelStatus;\n error: PanelError | null;\n result: DreamStatusResult | null;\n weightsStatus: PanelStatus;\n weightsError: PanelError | null;\n weights: DreamWeight[];\n weightsTruncated: boolean;\n candidatesStatus: PanelStatus;\n candidatesError: PanelError | null;\n candidates: DreamCandidate[];\n candidatesTruncated: boolean;\n};\n\nexport type LearningOverviewCounts = {\n proposals: { pending: number; applied: number; rejected: number; quarantined: number };\n lessons: number;\n scopes: number;\n truncated?: boolean;\n backend?: string;\n};\n\nexport type QualityPoint = { taskRunId: string; taskId: string; at: string; qualityScore: number };\n\nexport type PreemptionShare = {\n preempted: number;\n total: number;\n shutdownExcluded: number;\n};\n\nexport type DistillAuthoring = { taskRunId: string; at: string; authoring: string } | null;\n\nexport type LessonHealthPanel = {\n overviewStatus: PanelStatus;\n overviewError: PanelError | null;\n overview: LearningOverviewCounts | null;\n runsStatus: PanelStatus;\n runsError: PanelError | null;\n quality: QualityPoint[];\n unclassifiedRecovered: number;\n preemption: PreemptionShare;\n distillStatus: PanelStatus;\n distillError: PanelError | null;\n authoring: DistillAuthoring;\n};\n\nexport type DreamsViewState = {\n runs: DreamsRunsPanel;\n dream: DreamStatePanel;\n health: LessonHealthPanel;\n selectedRunId: string | null;\n};\n\nexport function createDefaultDreamsState(): DreamsViewState {\n return {\n runs: {\n status: \"idle\",\n error: null,\n runsAvailable: false,\n runsError: null,\n runs: [],\n budgetWindow: null,\n eventsStatus: \"idle\",\n eventsError: null,\n events: {},\n truncated: {},\n retentionDays: null,\n loadedAt: null,\n },\n dream: {\n status: \"idle\",\n error: null,\n result: null,\n weightsStatus: \"idle\",\n weightsError: null,\n weights: [],\n weightsTruncated: false,\n candidatesStatus: \"idle\",\n candidatesError: null,\n candidates: [],\n candidatesTruncated: false,\n },\n health: {\n overviewStatus: \"idle\",\n overviewError: null,\n overview: null,\n runsStatus: \"idle\",\n runsError: null,\n quality: [],\n unclassifiedRecovered: 0,\n preemption: { preempted: 0, total: 0, shutdownExcluded: 0 },\n distillStatus: \"idle\",\n distillError: null,\n authoring: null,\n },\n selectedRunId: null,\n };\n}\n\nexport type DreamsHost = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n hello: GatewayHelloOk | null;\n tab: string;\n dreams: DreamsViewState;\n dreamsGeneration: number;\n dreamsDirty: boolean;\n dreamsTrailingTimer: number | null;\n dreamsTrailingPending: boolean;\n dreamsBurstStartedAt: number | null;\n dreamsPollInterval: number | null;\n};\n\nexport const DREAMS_RUNS_LIMIT = 50;\nexport const DREAMS_HEALTH_RUNS_LIMIT = 50;\nexport const DREAMS_DISTILL_LIMIT = 20;\nexport const DREAMS_CANDIDATES_LIMIT = 20;\nexport const RUN_EVENTS_CHUNK = 50;\nexport const DREAMS_TRAILING_MS = 1000;\nexport const DREAMS_TRAILING_MAX_WAIT_MS = 5000;\nexport const DREAMS_POLL_MS = 30_000;\n\nconst PRODUCE_TASK = \"learning-core.produce\";\nconst CONSOLIDATION_TASK = \"learning-core.consolidation\";\nconst DISTILL_TASK = \"learning-core.distill\";\n\n// Absent features list (older gateway): capability unknown, so the request is tried and\n// a failure reads as degraded rather than disabled.\nexport function methodAdvertised(hello: GatewayHelloOk | null, method: string): boolean {\n const methods = hello?.features?.methods;\n if (!Array.isArray(methods)) {\n return true;\n }\n return methods.includes(method);\n}\n\nfunction toPanelError(err: unknown): PanelError {\n if (err instanceof GatewayRequestError) {\n return { code: err.gatewayCode, message: err.message };\n }\n return { code: null, message: err instanceof Error ? err.message : String(err) };\n}\n\nfunction patch(host: DreamsHost, next: Partial<DreamsViewState>) {\n host.dreams = { ...host.dreams, ...next };\n}\n\nfunction patchRuns(host: DreamsHost, next: Partial<DreamsRunsPanel>) {\n patch(host, { runs: { ...host.dreams.runs, ...next } });\n}\n\nfunction patchDream(host: DreamsHost, next: Partial<DreamStatePanel>) {\n patch(host, { dream: { ...host.dreams.dream, ...next } });\n}\n\nfunction patchHealth(host: DreamsHost, next: Partial<LessonHealthPanel>) {\n patch(host, { health: { ...host.dreams.health, ...next } });\n}\n\ntype StatusResult = {\n runs?: DreamsTaskRun[];\n runsAvailable?: boolean;\n runsError?: string;\n budgetWindow?: DreamsBudgetWindow;\n};\n\nasync function requestStatus(\n client: GatewayBrowserClient,\n params: Record<string, unknown>,\n): Promise<StatusResult> {\n return client.request<StatusResult>(\"tasks.status\", params);\n}\n\n// Chunked into requests of at most 50 ids; merged in request order so the result is\n// deterministic regardless of which chunk resolves first.\nexport async function loadRunEvents(\n client: GatewayBrowserClient,\n taskRunIds: string[],\n): Promise<{\n events: Record<string, ProjectedRunEvent[]>;\n truncated: RunEventsTruncation;\n retentionDays: number | null;\n}> {\n const unique = [...new Set(taskRunIds)];\n const chunks: string[][] = [];\n for (let i = 0; i < unique.length; i += RUN_EVENTS_CHUNK) {\n chunks.push(unique.slice(i, i + RUN_EVENTS_CHUNK));\n }\n const results = await Promise.all(\n chunks.map((ids) =>\n client.request<TasksRunEventsResult>(\"tasks.runEvents\", { taskRunIds: ids }),\n ),\n );\n const events: Record<string, ProjectedRunEvent[]> = Object.create(null);\n const truncated: RunEventsTruncation = Object.create(null);\n let retentionDays: number | null = null;\n for (const result of results) {\n retentionDays ??= typeof result.retentionDays === \"number\" ? result.retentionDays : null;\n for (const id of Object.keys(result.events ?? {})) {\n events[id] = result.events[id] ?? [];\n }\n for (const id of Object.keys(result.truncated ?? {})) {\n const entry = result.truncated?.[id];\n if (entry) {\n truncated[id] = entry;\n }\n }\n }\n return { events, truncated, retentionDays };\n}\n\nexport function metricsEvent(\n events: ProjectedRunEvent[] | undefined,\n): ProjectedMetricsEvent | null {\n let found: ProjectedMetricsEvent | null = null;\n for (const event of events ?? []) {\n if (event.kind === \"metrics\") {\n found = event;\n }\n }\n return found;\n}\n\nexport function phaseEvents(events: ProjectedRunEvent[] | undefined): ProjectedPhaseEvent[] {\n return (events ?? [])\n .filter((event): event is ProjectedPhaseEvent => event.kind === \"phase\")\n .toSorted((a, b) => a.offsetMs - b.offsetMs || a.ordinal - b.ordinal);\n}\n\nexport function outcomeEvents(events: ProjectedRunEvent[] | undefined): ProjectedOutcomeEvent[] {\n return (events ?? []).filter((event): event is ProjectedOutcomeEvent => event.kind === \"outcome\");\n}\n\nexport function runTime(run: DreamsTaskRun): string {\n return run.startedAt ?? run.completedAt ?? run.updatedAt;\n}\n\nconst TERMINALISH = new Set([\n \"completed\",\n \"failed\",\n \"dlq\",\n \"preempted\",\n \"preempted_ceiling\",\n \"rolled_back\",\n \"cancelled\",\n]);\n\nexport type MeasurementLabel =\n | \"complete\"\n | \"unavailable\"\n | \"missing\"\n | \"truncated\"\n | \"pruned\"\n | \"denied\"\n | \"in_progress\"\n | \"not_loaded\";\n\n// Classifies what the drawer can honestly say about a run's measurement. A crash-finalized\n// attempt (reclaim, `recovered`) or a timeout-unsettled handler never shows zeros. `isTruncated`\n// is whether the server's bounded response dropped rows for this run (per-run/overall/byte\n// limit): a dropped metrics row must not be reported as \"missing\" — that implies it was never\n// recorded at all, which the caller cannot know once rows were truncated away.\nexport function measurementLabel(\n run: DreamsTaskRun,\n events: ProjectedRunEvent[] | undefined,\n retentionDays: number | null,\n nowMs: number = Date.now(),\n isTruncated = false,\n): MeasurementLabel {\n if (events === undefined) {\n return \"not_loaded\";\n }\n const metrics = metricsEvent(events);\n if (metrics) {\n return metrics.measurementState === \"unavailable\" ? \"unavailable\" : \"complete\";\n }\n if (events.length === 0 && retentionDays !== null) {\n const at = Date.parse(run.completedAt ?? run.updatedAt);\n if (Number.isFinite(at) && nowMs - at > retentionDays * 86_400_000) {\n return \"pruned\";\n }\n }\n if (outcomeEvents(events).some((event) => event.denial)) {\n return \"denied\";\n }\n if (!TERMINALISH.has(run.status) && run.status !== \"deferred\") {\n return \"in_progress\";\n }\n return isTruncated ? \"truncated\" : \"missing\";\n}\n\nexport function isDryRun(run: DreamsTaskRun, events: ProjectedRunEvent[] | undefined): boolean {\n return run.mode === \"dry_run\" || metricsEvent(events)?.mode === \"dry_run\";\n}\n\nfunction isPruned(\n run: DreamsTaskRun,\n events: ProjectedRunEvent[] | undefined,\n retentionDays: number | null,\n): boolean {\n return measurementLabel(run, events, retentionDays) === \"pruned\";\n}\n\nfunction preemptionReason(events: ProjectedRunEvent[] | undefined): string | null {\n let reason: string | null = null;\n for (const event of outcomeEvents(events)) {\n if (event.preemption?.reason) {\n reason = event.preemption.reason;\n }\n }\n return reason;\n}\n\nexport type ConsolidationRunView = {\n run: DreamsTaskRun;\n events: ProjectedRunEvent[] | undefined;\n};\n\n// Merges the two bounded tasks.status reads by run time and keeps only consolidation runs:\n// every standalone consolidation run, and produce runs whose metrics name consolidation as\n// the producer. Dry-runs are excluded; produce runs with no metrics row (crash-recovered)\n// cannot be classified and are counted separately.\nexport function classifyConsolidationRuns(\n produce: DreamsTaskRun[],\n consolidation: DreamsTaskRun[],\n events: Record<string, ProjectedRunEvent[]>,\n): { runs: ConsolidationRunView[]; unclassifiedRecovered: number } {\n const merged = [...produce, ...consolidation].toSorted((a, b) =>\n runTime(b).localeCompare(runTime(a)),\n );\n const runs: ConsolidationRunView[] = [];\n let unclassifiedRecovered = 0;\n for (const run of merged) {\n const runEvents = events[run.taskRunId];\n if (isDryRun(run, runEvents)) {\n continue;\n }\n if (run.taskId === CONSOLIDATION_TASK) {\n runs.push({ run, events: runEvents });\n continue;\n }\n const metrics = metricsEvent(runEvents);\n if (!metrics) {\n if (TERMINALISH.has(run.status)) {\n unclassifiedRecovered += 1;\n }\n continue;\n }\n if (metrics.items?.producer === \"consolidation\") {\n runs.push({ run, events: runEvents });\n }\n }\n return { runs, unclassifiedRecovered };\n}\n\nexport function qualityTrend(runs: ConsolidationRunView[]): QualityPoint[] {\n const points: QualityPoint[] = [];\n for (const { run, events } of runs) {\n const score = metricsEvent(events)?.qualityScore;\n if (typeof score === \"number\" && Number.isFinite(score)) {\n points.push({\n taskRunId: run.taskRunId,\n taskId: run.taskId,\n at: runTime(run),\n qualityScore: score,\n });\n }\n }\n return points.toSorted((a, b) => a.at.localeCompare(b.at));\n}\n\n// Preempted by lease, reclaim, or with no recorded reason, plus preempted_ceiling, over the\n// consolidation runs in view. A cooperative shutdown preemption is not counted as preempted.\nexport function preemptionShare(runs: ConsolidationRunView[]): PreemptionShare {\n let preempted = 0;\n let shutdownExcluded = 0;\n for (const { run, events } of runs) {\n if (run.status === \"preempted_ceiling\") {\n preempted += 1;\n continue;\n }\n if (run.status !== \"preempted\") {\n continue;\n }\n const reason = preemptionReason(events);\n if (reason === \"shutdown\") {\n shutdownExcluded += 1;\n continue;\n }\n preempted += 1;\n }\n return { preempted, total: runs.length, shutdownExcluded };\n}\n\n// The newest normal-mode distill run whose metrics carry `authoring`; newer dry-runs,\n// budget-deferred runs, and runs whose rows were pruned never mask it.\nexport function latestDistillAuthoring(\n runs: DreamsTaskRun[],\n events: Record<string, ProjectedRunEvent[]>,\n retentionDays: number | null,\n): DistillAuthoring {\n const sorted = runs.toSorted((a, b) => runTime(b).localeCompare(runTime(a)));\n for (const run of sorted) {\n const runEvents = events[run.taskRunId];\n if (isDryRun(run, runEvents) || run.status === \"deferred\") {\n continue;\n }\n if (isPruned(run, runEvents, retentionDays)) {\n continue;\n }\n if (outcomeEvents(runEvents).some((event) => event.denial)) {\n continue;\n }\n const authoring = metricsEvent(runEvents)?.authoring;\n if (authoring) {\n return { taskRunId: run.taskRunId, at: runTime(run), authoring };\n }\n }\n return null;\n}\n\nfunction isCurrent(host: DreamsHost, generation: number): boolean {\n return host.dreamsGeneration === generation && host.connected;\n}\n\nasync function loadRunsPanel(host: DreamsHost, generation: number) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, \"tasks.status\")) {\n patchRuns(host, { status: \"disabled\", error: null, runs: [], budgetWindow: null });\n return;\n }\n patchRuns(host, { status: host.dreams.runs.status === \"ok\" ? \"ok\" : \"loading\" });\n let status: StatusResult;\n try {\n status = await requestStatus(client, { limit: DREAMS_RUNS_LIMIT });\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchRuns(host, { status: \"degraded\", error: toPanelError(err) });\n }\n return;\n }\n if (!isCurrent(host, generation)) {\n return;\n }\n const runs = Array.isArray(status.runs) ? status.runs : [];\n // Runs and their events land in one patch, so a row never renders against another\n // refresh's events.\n const base: Partial<DreamsRunsPanel> = {\n status: \"ok\",\n error: null,\n runsAvailable: status.runsAvailable === true,\n runsError: status.runsError ?? null,\n runs,\n budgetWindow: status.budgetWindow ?? null,\n loadedAt: Date.now(),\n };\n if (!methodAdvertised(host.hello, \"tasks.runEvents\")) {\n patchRuns(host, {\n ...base,\n eventsStatus: \"disabled\",\n events: {},\n truncated: {},\n eventsError: null,\n });\n return;\n }\n if (runs.length === 0) {\n patchRuns(host, { ...base, eventsStatus: \"ok\", events: {}, truncated: {}, eventsError: null });\n return;\n }\n try {\n const { events, truncated, retentionDays } = await loadRunEvents(\n client,\n runs.map((run) => run.taskRunId),\n );\n if (isCurrent(host, generation)) {\n patchRuns(host, {\n ...base,\n eventsStatus: \"ok\",\n eventsError: null,\n events,\n truncated,\n retentionDays,\n });\n }\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchRuns(host, {\n ...base,\n eventsStatus: \"degraded\",\n eventsError: toPanelError(err),\n events: {},\n truncated: {},\n });\n }\n }\n}\n\nasync function loadDreamPart<T>(\n host: DreamsHost,\n generation: number,\n method: string,\n params: Record<string, unknown>,\n apply: (result: T) => void,\n fail: (status: PanelStatus, error: PanelError | null) => void,\n) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, method)) {\n fail(\"disabled\", null);\n return;\n }\n try {\n const result = await client.request<T>(method, params);\n if (isCurrent(host, generation)) {\n apply(result);\n }\n } catch (err) {\n if (isCurrent(host, generation)) {\n fail(\"degraded\", toPanelError(err));\n }\n }\n}\n\nasync function loadDreamState(host: DreamsHost, generation: number) {\n if (host.dreams.dream.status === \"idle\") {\n patchDream(host, { status: \"loading\" });\n }\n await Promise.all([\n loadDreamPart<DreamStatusResult>(\n host,\n generation,\n \"dream.status\",\n {},\n (result) => patchDream(host, { status: \"ok\", error: null, result }),\n (status, error) => patchDream(host, { status, error, result: null }),\n ),\n loadDreamPart<{ weights?: DreamWeight[]; truncated?: boolean }>(\n host,\n generation,\n \"dream.weights\",\n {},\n (result) =>\n patchDream(host, {\n weightsStatus: \"ok\",\n weightsError: null,\n weights: Array.isArray(result.weights) ? result.weights : [],\n weightsTruncated: result.truncated === true,\n }),\n (status, error) =>\n patchDream(host, { weightsStatus: status, weightsError: error, weights: [] }),\n ),\n loadDreamPart<{ candidates?: DreamCandidate[]; truncated?: boolean }>(\n host,\n generation,\n \"dream.candidates\",\n { limit: DREAMS_CANDIDATES_LIMIT },\n (result) =>\n patchDream(host, {\n candidatesStatus: \"ok\",\n candidatesError: null,\n candidates: Array.isArray(result.candidates) ? result.candidates : [],\n candidatesTruncated: result.truncated === true,\n }),\n (status, error) =>\n patchDream(host, { candidatesStatus: status, candidatesError: error, candidates: [] }),\n ),\n ]);\n}\n\nasync function loadConsolidationHealth(host: DreamsHost, generation: number) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, \"tasks.status\")) {\n patchHealth(host, { runsStatus: \"disabled\", runsError: null, quality: [] });\n return;\n }\n try {\n const [produce, consolidation] = await Promise.all([\n requestStatus(client, { taskId: PRODUCE_TASK, limit: DREAMS_HEALTH_RUNS_LIMIT }),\n requestStatus(client, { taskId: CONSOLIDATION_TASK, limit: DREAMS_HEALTH_RUNS_LIMIT }),\n ]);\n if (produce.runsAvailable === false || consolidation.runsAvailable === false) {\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n runsStatus: \"degraded\",\n runsError: {\n code: null,\n message: produce.runsError ?? consolidation.runsError ?? \"runs store unavailable\",\n },\n });\n }\n return;\n }\n const produceRuns = produce.runs ?? [];\n const consolidationRuns = consolidation.runs ?? [];\n const ids = [...produceRuns, ...consolidationRuns].map((run) => run.taskRunId);\n if (ids.length > 0 && !methodAdvertised(host.hello, \"tasks.runEvents\")) {\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n runsStatus: \"degraded\",\n runsError: { code: null, message: \"tasks.runEvents not available\" },\n });\n }\n return;\n }\n const { events } =\n ids.length > 0\n ? await loadRunEvents(client, ids)\n : { events: {} as Record<string, ProjectedRunEvent[]> };\n if (!isCurrent(host, generation)) {\n return;\n }\n const classified = classifyConsolidationRuns(produceRuns, consolidationRuns, events);\n patchHealth(host, {\n runsStatus: \"ok\",\n runsError: null,\n quality: qualityTrend(classified.runs),\n unclassifiedRecovered: classified.unclassifiedRecovered,\n preemption: preemptionShare(classified.runs),\n });\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchHealth(host, { runsStatus: \"degraded\", runsError: toPanelError(err) });\n }\n }\n}\n\nasync function loadDistillAuthoring(host: DreamsHost, generation: number) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, \"tasks.status\")) {\n patchHealth(host, { distillStatus: \"disabled\", distillError: null, authoring: null });\n return;\n }\n try {\n const status = await requestStatus(client, {\n taskId: DISTILL_TASK,\n status: \"completed\",\n limit: DREAMS_DISTILL_LIMIT,\n });\n if (status.runsAvailable === false) {\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n distillStatus: \"degraded\",\n distillError: { code: null, message: status.runsError ?? \"runs store unavailable\" },\n });\n }\n return;\n }\n const runs = status.runs ?? [];\n if (runs.length > 0 && !methodAdvertised(host.hello, \"tasks.runEvents\")) {\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n distillStatus: \"degraded\",\n distillError: { code: null, message: \"tasks.runEvents not available\" },\n });\n }\n return;\n }\n const { events, retentionDays } =\n runs.length > 0\n ? await loadRunEvents(\n client,\n runs.map((run) => run.taskRunId),\n )\n : { events: {} as Record<string, ProjectedRunEvent[]>, retentionDays: null };\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n distillStatus: \"ok\",\n distillError: null,\n authoring: latestDistillAuthoring(runs, events, retentionDays),\n });\n }\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchHealth(host, { distillStatus: \"degraded\", distillError: toPanelError(err) });\n }\n }\n}\n\nasync function loadLearningOverviewCounts(host: DreamsHost, generation: number) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, \"learning.overview\")) {\n patchHealth(host, { overviewStatus: \"disabled\", overviewError: null, overview: null });\n return;\n }\n try {\n const overview = await client.request<LearningOverviewCounts>(\"learning.overview\", {});\n if (isCurrent(host, generation)) {\n patchHealth(host, { overviewStatus: \"ok\", overviewError: null, overview });\n }\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchHealth(host, { overviewStatus: \"degraded\", overviewError: toPanelError(err) });\n }\n }\n}\n\n// One full-state refresh. Each panel loads independently, so an unavailable optional plugin\n// never blanks the page; a newer refresh bumps the generation and older responses are dropped.\nexport async function loadDreams(host: DreamsHost): Promise<void> {\n if (!host.client || !host.connected) {\n return;\n }\n host.dreamsDirty = false;\n host.dreamsGeneration += 1;\n const generation = host.dreamsGeneration;\n await Promise.all([\n loadRunsPanel(host, generation),\n loadDreamState(host, generation),\n loadLearningOverviewCounts(host, generation),\n loadConsolidationHealth(host, generation),\n loadDistillAuthoring(host, generation),\n ]);\n}\n\nfunction dreamsVisible(host: DreamsHost): boolean {\n if (host.tab !== \"dreams\") {\n return false;\n }\n return typeof document === \"undefined\" || document.visibilityState !== \"hidden\";\n}\n\nfunction clearTrailing(host: DreamsHost) {\n if (host.dreamsTrailingTimer != null) {\n clearTimeout(host.dreamsTrailingTimer);\n }\n host.dreamsTrailingTimer = null;\n host.dreamsTrailingPending = false;\n host.dreamsBurstStartedAt = null;\n}\n\n// `dreams.update` is a payload-free hint. While the Dreams tab is not visible it only marks\n// the view dirty (zero RPCs). Visible: the first hint of a burst refreshes at once; later\n// hints arm one trailing re-fetch 1 s after the last hint, bounded by a max wait.\nexport function handleDreamsUpdate(host: DreamsHost, nowMs: number = Date.now()) {\n if (!dreamsVisible(host) || !host.connected) {\n host.dreamsDirty = true;\n return;\n }\n if (host.dreamsTrailingTimer == null) {\n host.dreamsBurstStartedAt = nowMs;\n host.dreamsTrailingPending = false;\n void loadDreams(host);\n } else {\n host.dreamsTrailingPending = true;\n clearTimeout(host.dreamsTrailingTimer);\n }\n const burstAge = nowMs - (host.dreamsBurstStartedAt ?? nowMs);\n const delay = Math.max(0, Math.min(DREAMS_TRAILING_MS, DREAMS_TRAILING_MAX_WAIT_MS - burstAge));\n host.dreamsTrailingTimer = window.setTimeout(() => {\n const pending = host.dreamsTrailingPending;\n clearTrailing(host);\n if (!pending) {\n return;\n }\n if (dreamsVisible(host) && host.connected) {\n void loadDreams(host);\n } else {\n host.dreamsDirty = true;\n }\n }, delay);\n}\n\nexport function startDreamsPolling(host: DreamsHost) {\n if (host.dreamsPollInterval != null) {\n return;\n }\n host.dreamsPollInterval = window.setInterval(() => {\n if (!dreamsVisible(host) || !host.connected) {\n return;\n }\n void loadDreams(host);\n }, DREAMS_POLL_MS);\n}\n\nexport function stopDreamsPolling(host: DreamsHost) {\n if (host.dreamsPollInterval != null) {\n clearInterval(host.dreamsPollInterval);\n }\n host.dreamsPollInterval = null;\n clearTrailing(host);\n // In-flight responses from before the stop belong to a dead connection.\n host.dreamsGeneration += 1;\n}\n\n// A browser tab coming back into view catches up once if hints arrived while it was hidden.\nexport function handleDreamsVisibilityChange(host: DreamsHost) {\n if (host.dreamsDirty && dreamsVisible(host) && host.connected) {\n void loadDreams(host);\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { LogEntry, LogLevel } from \"../types.ts\";\n\nexport type LogsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n logsLoading: boolean;\n logsError: string | null;\n logsCursor: number | null;\n logsFile: string | null;\n logsEntries: LogEntry[];\n logsTruncated: boolean;\n logsLastFetchAt: number | null;\n logsLimit: number;\n logsMaxBytes: number;\n};\n\nconst LOG_BUFFER_LIMIT = 2000;\nconst LEVELS = new Set<LogLevel>([\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"]);\n\nfunction parseMaybeJsonString(value: unknown) {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n if (!trimmed.startsWith(\"{\") || !trimmed.endsWith(\"}\")) {\n return null;\n }\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!parsed || typeof parsed !== \"object\") {\n return null;\n }\n return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction normalizeLevel(value: unknown): LogLevel | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const lowered = value.toLowerCase() as LogLevel;\n return LEVELS.has(lowered) ? lowered : null;\n}\n\nexport function parseLogLine(line: string): LogEntry {\n if (!line.trim()) {\n return { raw: line, message: line };\n }\n try {\n const obj = JSON.parse(line) as Record<string, unknown>;\n const meta =\n obj && typeof obj._meta === \"object\" && obj._meta !== null\n ? (obj._meta as Record<string, unknown>)\n : null;\n const time =\n typeof obj.time === \"string\" ? obj.time : typeof meta?.date === \"string\" ? meta?.date : null;\n const level = normalizeLevel(meta?.logLevelName ?? meta?.level);\n\n const contextCandidate =\n typeof obj[\"0\"] === \"string\" ? obj[\"0\"] : typeof meta?.name === \"string\" ? meta?.name : null;\n const contextObj = parseMaybeJsonString(contextCandidate);\n let subsystem: string | null = null;\n if (contextObj) {\n if (typeof contextObj.subsystem === \"string\") {\n subsystem = contextObj.subsystem;\n } else if (typeof contextObj.module === \"string\") {\n subsystem = contextObj.module;\n }\n }\n if (!subsystem && contextCandidate && contextCandidate.length < 120) {\n subsystem = contextCandidate;\n }\n\n let message: string | null = null;\n if (typeof obj[\"1\"] === \"string\") {\n message = obj[\"1\"];\n } else if (!contextObj && typeof obj[\"0\"] === \"string\") {\n message = obj[\"0\"];\n } else if (typeof obj.message === \"string\") {\n message = obj.message;\n }\n\n return {\n raw: line,\n time,\n level,\n subsystem,\n message: message ?? line,\n meta: meta ?? undefined,\n };\n } catch {\n return { raw: line, message: line };\n }\n}\n\nexport async function loadLogs(state: LogsState, opts?: { reset?: boolean; quiet?: boolean }) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.logsLoading && !opts?.quiet) {\n return;\n }\n if (!opts?.quiet) {\n state.logsLoading = true;\n }\n state.logsError = null;\n try {\n const res = await state.client.request(\"logs.tail\", {\n cursor: opts?.reset ? undefined : (state.logsCursor ?? undefined),\n limit: state.logsLimit,\n maxBytes: state.logsMaxBytes,\n });\n const payload = res as {\n file?: string;\n cursor?: number;\n size?: number;\n lines?: unknown;\n truncated?: boolean;\n reset?: boolean;\n };\n const lines = Array.isArray(payload.lines)\n ? payload.lines.filter((line) => typeof line === \"string\")\n : [];\n const entries = lines.map(parseLogLine);\n const shouldReset = Boolean(opts?.reset || payload.reset || state.logsCursor == null);\n state.logsEntries = shouldReset\n ? entries\n : [...state.logsEntries, ...entries].slice(-LOG_BUFFER_LIMIT);\n if (typeof payload.cursor === \"number\") {\n state.logsCursor = payload.cursor;\n }\n if (typeof payload.file === \"string\") {\n state.logsFile = payload.file;\n }\n state.logsTruncated = Boolean(payload.truncated);\n state.logsLastFetchAt = Date.now();\n } catch (err) {\n state.logsError = String(err);\n } finally {\n if (!opts?.quiet) {\n state.logsLoading = false;\n }\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\n\nexport type NodesState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n nodesLoading: boolean;\n nodes: Array<Record<string, unknown>>;\n lastError: string | null;\n};\n\nexport async function loadNodes(state: NodesState, opts?: { quiet?: boolean }) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.nodesLoading) {\n return;\n }\n state.nodesLoading = true;\n if (!opts?.quiet) {\n state.lastError = null;\n }\n try {\n const res = await state.client.request<{ nodes?: Record<string, unknown> }>(\"node.list\", {});\n state.nodes = Array.isArray(res.nodes) ? res.nodes : [];\n } catch (err) {\n if (!opts?.quiet) {\n state.lastError = String(err);\n }\n } finally {\n state.nodesLoading = false;\n }\n}\n","import { toNumber } from \"../format.ts\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type {\n DurableSessionRunListResult,\n DurableSessionRunRecord,\n SessionRunsResult,\n SessionsListResult,\n SessionsThresholdsResult,\n} from \"../types.ts\";\n\nexport type SessionsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionsLoading: boolean;\n sessionsResult: SessionsListResult | null;\n sessionsError: string | null;\n sessionsFilterActive: string;\n sessionsFilterLimit: string;\n sessionsIncludeGlobal: boolean;\n sessionsIncludeUnknown: boolean;\n sessionRunsResult: SessionRunsResult | null;\n sessionRunsError: string | null;\n sessionRunsFetchedAt: number;\n sessionRunsLoading: boolean;\n recentlyCompletedRuns: { key: string; completedAt: number }[];\n sessionRunsPrevKeys: Set<string>;\n sessionsThresholdsResult: SessionsThresholdsResult | null;\n sessionsThresholdsError: string | null;\n sessionsThresholdsLoading: boolean;\n sessionRunsInterruptingKeys: Set<string>;\n recoverableRuns: DurableSessionRunRecord[];\n recoveryError: string | null;\n decidingRunIds: Set<string>;\n recoverableRunsLoading: boolean;\n};\n\nexport async function loadSessions(\n state: SessionsState,\n overrides?: {\n activeMinutes?: number;\n limit?: number;\n includeGlobal?: boolean;\n includeUnknown?: boolean;\n },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.sessionsLoading) {\n return;\n }\n state.sessionsLoading = true;\n state.sessionsError = null;\n try {\n const includeGlobal = overrides?.includeGlobal ?? state.sessionsIncludeGlobal;\n const includeUnknown = overrides?.includeUnknown ?? state.sessionsIncludeUnknown;\n const activeMinutes = overrides?.activeMinutes ?? toNumber(state.sessionsFilterActive, 0);\n const limit = overrides?.limit ?? toNumber(state.sessionsFilterLimit, 0);\n const params: Record<string, unknown> = {\n includeGlobal,\n includeUnknown,\n };\n if (activeMinutes > 0) {\n params.activeMinutes = activeMinutes;\n }\n if (limit > 0) {\n params.limit = limit;\n }\n const res = await state.client.request<SessionsListResult | undefined>(\"sessions.list\", params);\n if (res) {\n state.sessionsResult = res;\n }\n } catch (err) {\n state.sessionsError = String(err);\n } finally {\n state.sessionsLoading = false;\n }\n}\n\nexport async function loadSessionRuns(state: SessionsState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.sessionRunsLoading) {\n return;\n }\n state.sessionRunsLoading = true;\n // Capture pre-await snapshots so a push event that fires during the network round-trip\n // does not corrupt the ring-buffer diff or clobber fresher push-delivered state.\n const prevKeys = state.sessionRunsPrevKeys;\n const prevFetchedAt = state.sessionRunsFetchedAt;\n try {\n const res = await state.client.request<SessionRunsResult | undefined>(\"sessions.runs\", {});\n state.sessionRunsError = null;\n if (res) {\n const now = Date.now();\n state.recentlyCompletedRuns = updateRecentlyCompletedRuns(\n prevKeys,\n res.runs,\n state.recentlyCompletedRuns,\n now,\n );\n // A push that fired during the poll already delivered fresher data; don't overwrite it.\n if (state.sessionRunsFetchedAt <= prevFetchedAt) {\n state.sessionRunsFetchedAt = now;\n state.sessionRunsPrevKeys = new Set(res.runs.map((r) => r.key));\n state.sessionRunsResult = res;\n }\n }\n } catch (err) {\n state.sessionRunsError = String(err);\n // Do NOT advance sessionRunsFetchedAt on error — the age formula relies on the\n // last-successful-fetch timestamp to continue growing correctly during outages.\n } finally {\n state.sessionRunsLoading = false;\n }\n}\n\nexport async function loadSessionThresholds(state: SessionsState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.sessionsThresholdsLoading) {\n return;\n }\n state.sessionsThresholdsLoading = true;\n try {\n const res = await state.client.request<SessionsThresholdsResult | undefined>(\n \"sessions.thresholds\",\n {},\n );\n state.sessionsThresholdsError = null;\n if (res) {\n state.sessionsThresholdsResult = res;\n }\n } catch (err) {\n state.sessionsThresholdsError = String(err);\n } finally {\n state.sessionsThresholdsLoading = false;\n }\n}\n\nexport async function interruptSession(state: SessionsState, key: string): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n state.sessionRunsInterruptingKeys = new Set([...state.sessionRunsInterruptingKeys, key]);\n try {\n const res = await state.client.request<{ ok: boolean; key?: string } | undefined>(\n \"sessions.interrupt\",\n { key },\n );\n if (res && !res.ok) {\n state.sessionRunsError = `Interrupt not applied: session run not found (${key})`;\n }\n } catch (err) {\n state.sessionRunsError = String(err);\n } finally {\n const next = new Set(state.sessionRunsInterruptingKeys);\n next.delete(key);\n state.sessionRunsInterruptingKeys = next;\n }\n}\n\nexport async function listRecoverableRuns(\n state: SessionsState,\n): Promise<DurableSessionRunListResult> {\n if (!state.client || !state.connected) {\n return { runs: [] };\n }\n const res = await state.client.request<DurableSessionRunListResult | undefined>(\n \"sessions.runs.list\",\n { statuses: [\"needs_recovery_decision\"] },\n );\n return res ?? { runs: [] };\n}\n\nexport async function loadRecoverableRuns(state: SessionsState): Promise<void> {\n if (!state.client || !state.connected || state.recoverableRunsLoading) {\n return;\n }\n state.recoverableRunsLoading = true;\n state.recoveryError = null;\n try {\n const result = await listRecoverableRuns(state);\n state.recoverableRuns = result.runs;\n } catch (err) {\n state.recoveryError = String(err);\n } finally {\n state.recoverableRunsLoading = false;\n }\n}\n\nexport async function continueRun(\n state: SessionsState,\n sessionRunId: string,\n decisionVersion: number,\n): Promise<{ ok: boolean; conflict: boolean }> {\n if (!state.client || !state.connected) {\n return { ok: false, conflict: false };\n }\n const res = await state.client.request<{ ok: boolean; conflict: boolean } | undefined>(\n \"sessions.runs.continue\",\n { sessionRunId, expectedDecisionVersion: decisionVersion },\n );\n return res ?? { ok: false, conflict: false };\n}\n\nexport async function cancelRun(\n state: SessionsState,\n sessionRunId: string,\n decisionVersion: number,\n): Promise<{ ok: boolean; conflict: boolean }> {\n if (!state.client || !state.connected) {\n return { ok: false, conflict: false };\n }\n const res = await state.client.request<{ ok: boolean; conflict: boolean } | undefined>(\n \"sessions.runs.cancel\",\n { sessionRunId, expectedDecisionVersion: decisionVersion },\n );\n return res ?? { ok: false, conflict: false };\n}\n\nexport async function patchSession(\n state: SessionsState,\n key: string,\n patch: {\n label?: string | null;\n thinkingLevel?: string | null;\n verboseLevel?: string | null;\n reasoningLevel?: string | null;\n },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n const params: Record<string, unknown> = { key };\n if (\"label\" in patch) {\n params.label = patch.label;\n }\n if (\"thinkingLevel\" in patch) {\n params.thinkingLevel = patch.thinkingLevel;\n }\n if (\"verboseLevel\" in patch) {\n params.verboseLevel = patch.verboseLevel;\n }\n if (\"reasoningLevel\" in patch) {\n params.reasoningLevel = patch.reasoningLevel;\n }\n try {\n await state.client.request(\"sessions.patch\", params);\n await loadSessions(state);\n } catch (err) {\n state.sessionsError = String(err);\n }\n}\n\nexport async function deleteSession(state: SessionsState, key: string): Promise<boolean> {\n if (!state.client || !state.connected) {\n return false;\n }\n if (state.sessionsLoading) {\n return false;\n }\n const confirmed = window.confirm(\n `Delete session \"${key}\"?\\n\\nDeletes the session entry and archives its transcript.`,\n );\n if (!confirmed) {\n return false;\n }\n state.sessionsLoading = true;\n state.sessionsError = null;\n try {\n await state.client.request(\"sessions.delete\", { key, deleteTranscript: true });\n return true;\n } catch (err) {\n state.sessionsError = String(err);\n return false;\n } finally {\n state.sessionsLoading = false;\n }\n}\n\nexport async function deleteSessionAndRefresh(state: SessionsState, key: string): Promise<boolean> {\n const deleted = await deleteSession(state, key);\n if (!deleted) {\n return false;\n }\n await loadSessions(state);\n return true;\n}\n\nconst RECENT_RUNS_MAX = 10;\nconst RECENT_RUNS_TTL_MS = 5 * 60_000;\n\nexport function updateRecentlyCompletedRuns(\n prevKeys: Set<string>,\n newRuns: { key: string }[],\n existing: { key: string; completedAt: number }[],\n now: number,\n): { key: string; completedAt: number }[] {\n const newKeySet = new Set(newRuns.map((r) => r.key));\n const existingKeys = new Set(existing.map((r) => r.key));\n const fresh: { key: string; completedAt: number }[] = [];\n for (const key of prevKeys) {\n if (!newKeySet.has(key) && !existingKeys.has(key)) {\n fresh.push({ key, completedAt: now });\n }\n }\n return [...fresh, ...existing]\n .filter((r) => now - r.completedAt < RECENT_RUNS_TTL_MS)\n .toSorted((a, b) => b.completedAt - a.completedAt)\n .slice(0, RECENT_RUNS_MAX);\n}\n","import type { OpenClawApp } from \"./app.ts\";\nimport { loadDebug } from \"./controllers/debug.ts\";\nimport {\n startDreamsPolling as startDreamsPollingInternal,\n stopDreamsPolling as stopDreamsPollingInternal,\n type DreamsHost,\n} from \"./controllers/dreams.ts\";\nimport { loadLogs } from \"./controllers/logs.ts\";\nimport { loadNodes } from \"./controllers/nodes.ts\";\nimport {\n loadRecoverableRuns,\n loadSessionRuns,\n loadSessionThresholds,\n} from \"./controllers/sessions.ts\";\n\ntype PollingHost = {\n nodesPollInterval: number | null;\n logsPollInterval: number | null;\n debugPollInterval: number | null;\n sessionRunsPollInterval: number | null;\n sessionRunsTickInterval: number | null;\n tab: string;\n};\n\nexport function startNodesPolling(host: PollingHost) {\n if (host.nodesPollInterval != null) {\n return;\n }\n host.nodesPollInterval = window.setInterval(\n () => void loadNodes(host as unknown as OpenClawApp, { quiet: true }),\n 5000,\n );\n}\n\nexport function stopNodesPolling(host: PollingHost) {\n if (host.nodesPollInterval == null) {\n return;\n }\n clearInterval(host.nodesPollInterval);\n host.nodesPollInterval = null;\n}\n\nexport function startLogsPolling(host: PollingHost) {\n if (host.logsPollInterval != null) {\n return;\n }\n host.logsPollInterval = window.setInterval(() => {\n if (host.tab !== \"logs\") {\n return;\n }\n void loadLogs(host as unknown as OpenClawApp, { quiet: true });\n }, 2000);\n}\n\nexport function stopLogsPolling(host: PollingHost) {\n if (host.logsPollInterval == null) {\n return;\n }\n clearInterval(host.logsPollInterval);\n host.logsPollInterval = null;\n}\n\nexport function startDebugPolling(host: PollingHost) {\n if (host.debugPollInterval != null) {\n return;\n }\n host.debugPollInterval = window.setInterval(() => {\n if (host.tab !== \"debug\") {\n return;\n }\n void loadDebug(host as unknown as OpenClawApp);\n }, 3000);\n}\n\nexport function stopDebugPolling(host: PollingHost) {\n if (host.debugPollInterval == null) {\n return;\n }\n clearInterval(host.debugPollInterval);\n host.debugPollInterval = null;\n}\n\nexport function startSessionRunsPolling(host: PollingHost) {\n if (host.sessionRunsPollInterval != null) {\n return;\n }\n host.sessionRunsPollInterval = window.setInterval(() => {\n if (host.tab !== \"sessions\") {\n return;\n }\n void loadSessionRuns(host as unknown as Parameters<typeof loadSessionRuns>[0]);\n void loadSessionThresholds(host as unknown as Parameters<typeof loadSessionThresholds>[0]);\n void loadRecoverableRuns(host as unknown as Parameters<typeof loadRecoverableRuns>[0]);\n }, 30_000);\n}\n\nexport function stopSessionRunsPolling(host: PollingHost) {\n if (host.sessionRunsPollInterval == null) {\n return;\n }\n clearInterval(host.sessionRunsPollInterval);\n host.sessionRunsPollInterval = null;\n}\n\n// Visible-tab fallback for a dropped `dreams.update` hint: 30 s, and only while the Dreams tab\n// is the active console tab in a visible browser tab.\nexport function startDreamsPolling(host: PollingHost) {\n startDreamsPollingInternal(host as unknown as DreamsHost);\n}\n\nexport function stopDreamsPolling(host: PollingHost) {\n stopDreamsPollingInternal(host as unknown as DreamsHost);\n}\n\nfunction prefersReducedMotion(): boolean {\n return window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n}\n\nexport function startSessionRunsTick(host: PollingHost) {\n if (host.sessionRunsTickInterval != null || prefersReducedMotion()) {\n return;\n }\n host.sessionRunsTickInterval = window.setInterval(() => {\n if (host.tab !== \"sessions\") {\n return;\n }\n const runs = (host as unknown as { sessionRunsResult?: { runs?: unknown[] } }).sessionRunsResult\n ?.runs;\n if (!runs || runs.length === 0) {\n return;\n }\n (host as unknown as { requestUpdate: () => void }).requestUpdate();\n }, 1000);\n}\n\nexport function stopSessionRunsTick(host: PollingHost) {\n if (host.sessionRunsTickInterval == null) {\n return;\n }\n clearInterval(host.sessionRunsTickInterval);\n host.sessionRunsTickInterval = null;\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { AgentIdentityResult } from \"../types.ts\";\n\nexport type AgentIdentityState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentIdentityLoading: boolean;\n agentIdentityError: string | null;\n agentIdentityById: Record<string, AgentIdentityResult>;\n};\n\nexport async function loadAgentIdentity(state: AgentIdentityState, agentId: string) {\n if (!state.client || !state.connected || state.agentIdentityLoading) {\n return;\n }\n if (state.agentIdentityById[agentId]) {\n return;\n }\n state.agentIdentityLoading = true;\n state.agentIdentityError = null;\n try {\n const res = await state.client.request<AgentIdentityResult | null>(\"agent.identity.get\", {\n agentId,\n });\n if (res) {\n state.agentIdentityById = { ...state.agentIdentityById, [agentId]: res };\n }\n } catch (err) {\n state.agentIdentityError = String(err);\n } finally {\n state.agentIdentityLoading = false;\n }\n}\n\nexport async function loadAgentIdentities(state: AgentIdentityState, agentIds: string[]) {\n if (!state.client || !state.connected || state.agentIdentityLoading) {\n return;\n }\n const missing = agentIds.filter((id) => !state.agentIdentityById[id]);\n if (missing.length === 0) {\n return;\n }\n state.agentIdentityLoading = true;\n state.agentIdentityError = null;\n try {\n for (const agentId of missing) {\n const res = await state.client.request<AgentIdentityResult | null>(\"agent.identity.get\", {\n agentId,\n });\n if (res) {\n state.agentIdentityById = { ...state.agentIdentityById, [agentId]: res };\n }\n }\n } catch (err) {\n state.agentIdentityError = String(err);\n } finally {\n state.agentIdentityLoading = false;\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { SkillStatusReport } from \"../types.ts\";\n\nexport type AgentSkillsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentSkillsLoading: boolean;\n agentSkillsError: string | null;\n agentSkillsReport: SkillStatusReport | null;\n agentSkillsAgentId: string | null;\n};\n\nexport async function loadAgentSkills(state: AgentSkillsState, agentId: string) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.agentSkillsLoading) {\n return;\n }\n state.agentSkillsLoading = true;\n state.agentSkillsError = null;\n try {\n const res = await state.client.request(\"skills.status\", { agentId });\n if (res) {\n state.agentSkillsReport = res as SkillStatusReport;\n state.agentSkillsAgentId = agentId;\n }\n } catch (err) {\n state.agentSkillsError = String(err);\n } finally {\n state.agentSkillsLoading = false;\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { AgentsListResult, ToolsCatalogResult } from \"../types.ts\";\n\nexport type AgentsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentsLoading: boolean;\n agentsError: string | null;\n agentsList: AgentsListResult | null;\n agentsSelectedId: string | null;\n toolsCatalogLoading: boolean;\n toolsCatalogError: string | null;\n toolsCatalogResult: ToolsCatalogResult | null;\n};\n\nexport async function loadAgents(state: AgentsState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.agentsLoading) {\n return;\n }\n state.agentsLoading = true;\n state.agentsError = null;\n try {\n const res = await state.client.request<AgentsListResult>(\"agents.list\", {});\n if (res) {\n state.agentsList = res;\n const selected = state.agentsSelectedId;\n const known = res.agents.some((entry) => entry.id === selected);\n if (!selected || !known) {\n state.agentsSelectedId = res.defaultId ?? res.agents[0]?.id ?? null;\n }\n }\n } catch (err) {\n state.agentsError = String(err);\n } finally {\n state.agentsLoading = false;\n }\n}\n\nexport async function loadToolsCatalog(state: AgentsState, agentId?: string | null) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.toolsCatalogLoading) {\n return;\n }\n state.toolsCatalogLoading = true;\n state.toolsCatalogError = null;\n try {\n const res = await state.client.request<ToolsCatalogResult>(\"tools.catalog\", {\n agentId: agentId ?? state.agentsSelectedId ?? undefined,\n includePlugins: true,\n });\n if (res) {\n state.toolsCatalogResult = res;\n }\n } catch (err) {\n state.toolsCatalogError = String(err);\n } finally {\n state.toolsCatalogLoading = false;\n }\n}\n\nexport async function nudgeAgent(state: AgentsState, agentId: string, text: string) {\n if (!state.client || !state.connected) {\n return;\n }\n const trimmed = text.trim();\n if (!trimmed) {\n return;\n }\n try {\n await state.client.request(\"agent.nudge\", { agentId, text: trimmed });\n } catch (err) {\n state.agentsError = String(err);\n }\n}\n","import { clearDeviceAuthToken, storeDeviceAuthToken } from \"../device-auth.ts\";\nimport { loadOrCreateDeviceIdentity } from \"../device-identity.ts\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\n\nexport type DeviceTokenSummary = {\n role: string;\n scopes?: string[];\n createdAtMs?: number;\n rotatedAtMs?: number;\n revokedAtMs?: number;\n lastUsedAtMs?: number;\n};\n\nexport type PendingDevice = {\n requestId: string;\n deviceId: string;\n displayName?: string;\n role?: string;\n remoteIp?: string;\n isRepair?: boolean;\n ts?: number;\n};\n\nexport type PairedDevice = {\n deviceId: string;\n displayName?: string;\n roles?: string[];\n scopes?: string[];\n remoteIp?: string;\n tokens?: DeviceTokenSummary[];\n createdAtMs?: number;\n approvedAtMs?: number;\n};\n\nexport type DevicePairingList = {\n pending: PendingDevice[];\n paired: PairedDevice[];\n};\n\nexport type DevicesState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n devicesLoading: boolean;\n devicesError: string | null;\n devicesList: DevicePairingList | null;\n};\n\nexport async function loadDevices(state: DevicesState, opts?: { quiet?: boolean }) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.devicesLoading) {\n return;\n }\n state.devicesLoading = true;\n if (!opts?.quiet) {\n state.devicesError = null;\n }\n try {\n const res = await state.client.request<{\n pending?: Array<PendingDevice>;\n paired?: Array<PendingDevice>;\n }>(\"device.pair.list\", {});\n state.devicesList = {\n pending: Array.isArray(res?.pending) ? res.pending : [],\n paired: Array.isArray(res?.paired) ? res.paired : [],\n };\n } catch (err) {\n if (!opts?.quiet) {\n state.devicesError = String(err);\n }\n } finally {\n state.devicesLoading = false;\n }\n}\n\nexport async function approveDevicePairing(state: DevicesState, requestId: string) {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n await state.client.request(\"device.pair.approve\", { requestId });\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function rejectDevicePairing(state: DevicesState, requestId: string) {\n if (!state.client || !state.connected) {\n return;\n }\n const confirmed = window.confirm(\"Reject this device pairing request?\");\n if (!confirmed) {\n return;\n }\n try {\n await state.client.request(\"device.pair.reject\", { requestId });\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function rotateDeviceToken(\n state: DevicesState,\n params: { deviceId: string; role: string; scopes?: string[] },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<{\n token: string;\n role?: string;\n deviceId?: string;\n scopes?: Array<string>;\n }>(\"device.token.rotate\", params);\n if (res?.token) {\n const identity = await loadOrCreateDeviceIdentity();\n const role = res.role ?? params.role;\n if (res.deviceId === identity.deviceId || params.deviceId === identity.deviceId) {\n storeDeviceAuthToken({\n deviceId: identity.deviceId,\n role,\n token: res.token,\n scopes: res.scopes ?? params.scopes ?? [],\n });\n }\n window.prompt(\"New device token (copy and store securely):\", res.token);\n }\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function revokeDeviceToken(\n state: DevicesState,\n params: { deviceId: string; role: string },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n const confirmed = window.confirm(`Revoke token for ${params.deviceId} (${params.role})?`);\n if (!confirmed) {\n return;\n }\n try {\n await state.client.request(\"device.token.revoke\", params);\n const identity = await loadOrCreateDeviceIdentity();\n if (params.deviceId === identity.deviceId) {\n clearDeviceAuthToken({ deviceId: identity.deviceId, role: params.role });\n }\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport { cloneConfigObject, removePathValue, setPathValue } from \"./config/form-utils.ts\";\n\nexport type ExecApprovalsDefaults = {\n security?: string;\n ask?: string;\n askFallback?: string;\n autoAllowSkills?: boolean;\n};\n\nexport type ExecApprovalsAllowlistEntry = {\n id?: string;\n pattern: string;\n lastUsedAt?: number;\n lastUsedCommand?: string;\n lastResolvedPath?: string;\n};\n\nexport type ExecApprovalsAgent = ExecApprovalsDefaults & {\n allowlist?: ExecApprovalsAllowlistEntry[];\n};\n\nexport type ExecApprovalsFile = {\n version?: number;\n socket?: { path?: string };\n defaults?: ExecApprovalsDefaults;\n agents?: Record<string, ExecApprovalsAgent>;\n};\n\nexport type ExecApprovalsSnapshot = {\n path: string;\n exists: boolean;\n hash: string;\n file: ExecApprovalsFile;\n};\n\nexport type ExecApprovalsTarget = { kind: \"gateway\" } | { kind: \"node\"; nodeId: string };\n\nexport type ExecApprovalsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n execApprovalsLoading: boolean;\n execApprovalsSaving: boolean;\n execApprovalsDirty: boolean;\n execApprovalsSnapshot: ExecApprovalsSnapshot | null;\n execApprovalsForm: ExecApprovalsFile | null;\n execApprovalsSelectedAgent: string | null;\n lastError: string | null;\n};\n\nfunction resolveExecApprovalsRpc(target?: ExecApprovalsTarget | null): {\n method: string;\n params: Record<string, unknown>;\n} | null {\n if (!target || target.kind === \"gateway\") {\n return { method: \"exec.approvals.get\", params: {} };\n }\n const nodeId = target.nodeId.trim();\n if (!nodeId) {\n return null;\n }\n return { method: \"exec.approvals.node.get\", params: { nodeId } };\n}\n\nfunction resolveExecApprovalsSaveRpc(\n target: ExecApprovalsTarget | null | undefined,\n params: { file: ExecApprovalsFile; baseHash: string },\n): { method: string; params: Record<string, unknown> } | null {\n if (!target || target.kind === \"gateway\") {\n return { method: \"exec.approvals.set\", params };\n }\n const nodeId = target.nodeId.trim();\n if (!nodeId) {\n return null;\n }\n return { method: \"exec.approvals.node.set\", params: { ...params, nodeId } };\n}\n\nexport async function loadExecApprovals(\n state: ExecApprovalsState,\n target?: ExecApprovalsTarget | null,\n) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.execApprovalsLoading) {\n return;\n }\n state.execApprovalsLoading = true;\n state.lastError = null;\n try {\n const rpc = resolveExecApprovalsRpc(target);\n if (!rpc) {\n state.lastError = \"Select a node before loading exec approvals.\";\n return;\n }\n const res = await state.client.request<ExecApprovalsSnapshot>(rpc.method, rpc.params);\n applyExecApprovalsSnapshot(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.execApprovalsLoading = false;\n }\n}\n\nexport function applyExecApprovalsSnapshot(\n state: ExecApprovalsState,\n snapshot: ExecApprovalsSnapshot,\n) {\n state.execApprovalsSnapshot = snapshot;\n if (!state.execApprovalsDirty) {\n state.execApprovalsForm = cloneConfigObject(snapshot.file ?? {});\n }\n}\n\nexport async function saveExecApprovals(\n state: ExecApprovalsState,\n target?: ExecApprovalsTarget | null,\n) {\n if (!state.client || !state.connected) {\n return;\n }\n state.execApprovalsSaving = true;\n state.lastError = null;\n try {\n const baseHash = state.execApprovalsSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Exec approvals hash missing; reload and retry.\";\n return;\n }\n const file = state.execApprovalsForm ?? state.execApprovalsSnapshot?.file ?? {};\n const rpc = resolveExecApprovalsSaveRpc(target, { file, baseHash });\n if (!rpc) {\n state.lastError = \"Select a node before saving exec approvals.\";\n return;\n }\n await state.client.request(rpc.method, rpc.params);\n state.execApprovalsDirty = false;\n await loadExecApprovals(state, target);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.execApprovalsSaving = false;\n }\n}\n\nexport function updateExecApprovalsFormValue(\n state: ExecApprovalsState,\n path: Array<string | number>,\n value: unknown,\n) {\n const base = cloneConfigObject(\n state.execApprovalsForm ?? state.execApprovalsSnapshot?.file ?? {},\n );\n setPathValue(base, path, value);\n state.execApprovalsForm = base;\n state.execApprovalsDirty = true;\n}\n\nexport function removeExecApprovalsFormValue(\n state: ExecApprovalsState,\n path: Array<string | number>,\n) {\n const base = cloneConfigObject(\n state.execApprovalsForm ?? state.execApprovalsSnapshot?.file ?? {},\n );\n removePathValue(base, path);\n state.execApprovalsForm = base;\n state.execApprovalsDirty = true;\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { PresenceEntry } from \"../types.ts\";\n\nexport type PresenceState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n presenceLoading: boolean;\n presenceEntries: PresenceEntry[];\n presenceError: string | null;\n presenceStatus: string | null;\n};\n\nexport async function loadPresence(state: PresenceState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.presenceLoading) {\n return;\n }\n state.presenceLoading = true;\n state.presenceError = null;\n state.presenceStatus = null;\n try {\n const res = await state.client.request(\"system-presence\", {});\n if (Array.isArray(res)) {\n state.presenceEntries = res;\n state.presenceStatus = res.length === 0 ? \"No instances yet.\" : null;\n } else {\n state.presenceEntries = [];\n state.presenceStatus = \"No presence payload.\";\n }\n } catch (err) {\n state.presenceError = String(err);\n } finally {\n state.presenceLoading = false;\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { SkillStatusReport } from \"../types.ts\";\n\nexport type SkillsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n skillsLoading: boolean;\n skillsReport: SkillStatusReport | null;\n skillsError: string | null;\n skillsBusyKey: string | null;\n skillEdits: Record<string, string>;\n skillMessages: SkillMessageMap;\n};\n\nexport type SkillMessage = {\n kind: \"success\" | \"error\";\n message: string;\n};\n\nexport type SkillMessageMap = Record<string, SkillMessage>;\n\ntype LoadSkillsOptions = {\n clearMessages?: boolean;\n};\n\nfunction setSkillMessage(state: SkillsState, key: string, message?: SkillMessage) {\n if (!key.trim()) {\n return;\n }\n const next = { ...state.skillMessages };\n if (message) {\n next[key] = message;\n } else {\n delete next[key];\n }\n state.skillMessages = next;\n}\n\nfunction getErrorMessage(err: unknown) {\n if (err instanceof Error) {\n return err.message;\n }\n return String(err);\n}\n\nexport async function loadSkills(state: SkillsState, options?: LoadSkillsOptions) {\n if (options?.clearMessages && Object.keys(state.skillMessages).length > 0) {\n state.skillMessages = {};\n }\n if (!state.client || !state.connected) {\n return;\n }\n if (state.skillsLoading) {\n return;\n }\n state.skillsLoading = true;\n state.skillsError = null;\n try {\n const res = await state.client.request<SkillStatusReport | undefined>(\"skills.status\", {});\n if (res) {\n state.skillsReport = res;\n }\n } catch (err) {\n state.skillsError = getErrorMessage(err);\n } finally {\n state.skillsLoading = false;\n }\n}\n\nexport function updateSkillEdit(state: SkillsState, skillKey: string, value: string) {\n state.skillEdits = { ...state.skillEdits, [skillKey]: value };\n}\n\nexport async function updateSkillEnabled(state: SkillsState, skillKey: string, enabled: boolean) {\n if (!state.client || !state.connected) {\n return;\n }\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n await state.client.request(\"skills.update\", { skillKey, enabled });\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: enabled ? \"Skill enabled\" : \"Skill disabled\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n\nexport async function saveSkillApiKey(state: SkillsState, skillKey: string) {\n if (!state.client || !state.connected) {\n return;\n }\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n const apiKey = state.skillEdits[skillKey] ?? \"\";\n await state.client.request(\"skills.update\", { skillKey, apiKey });\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: \"API key saved\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n\nexport async function installSkill(\n state: SkillsState,\n skillKey: string,\n name: string,\n installId: string,\n) {\n if (!state.client || !state.connected) {\n return;\n }\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n const result = await state.client.request<{ message?: string }>(\"skills.install\", {\n name,\n installId,\n timeoutMs: 120000,\n });\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: result?.message ?? \"Installed\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n","const KEY = \"openclaw.control.settings.v1\";\n\nimport { isSupportedLocale } from \"../i18n/index.ts\";\nimport { inferBasePathFromPathname, normalizeBasePath } from \"./navigation.ts\";\nimport type { ThemeMode } from \"./theme.ts\";\n\nexport type UiSettings = {\n gatewayUrl: string;\n token: string;\n sessionKey: string;\n lastActiveSessionKey: string;\n theme: ThemeMode;\n chatFocusMode: boolean;\n chatShowThinking: boolean;\n splitRatio: number; // Sidebar split ratio (0.4 to 0.7, default 0.6)\n navCollapsed: boolean; // Collapsible sidebar state\n navGroupsCollapsed: Record<string, boolean>; // Which nav groups are collapsed\n locale?: string;\n};\n\nexport function loadSettings(): UiSettings {\n const defaultUrl = (() => {\n const proto = location.protocol === \"https:\" ? \"wss\" : \"ws\";\n const configured =\n typeof window !== \"undefined\" &&\n typeof window.__OPENCLAW_CONTROL_UI_BASE_PATH__ === \"string\" &&\n window.__OPENCLAW_CONTROL_UI_BASE_PATH__.trim();\n const basePath = configured\n ? normalizeBasePath(configured)\n : inferBasePathFromPathname(location.pathname);\n return `${proto}://${location.host}${basePath}`;\n })();\n\n const defaults: UiSettings = {\n gatewayUrl: defaultUrl,\n token: \"\",\n sessionKey: \"main\",\n lastActiveSessionKey: \"main\",\n theme: \"system\",\n chatFocusMode: false,\n chatShowThinking: true,\n splitRatio: 0.6,\n navCollapsed: false,\n navGroupsCollapsed: {},\n };\n\n try {\n const raw = localStorage.getItem(KEY);\n if (!raw) {\n return defaults;\n }\n const parsed = JSON.parse(raw) as Partial<UiSettings>;\n return {\n gatewayUrl:\n typeof parsed.gatewayUrl === \"string\" && parsed.gatewayUrl.trim()\n ? parsed.gatewayUrl.trim()\n : defaults.gatewayUrl,\n token: typeof parsed.token === \"string\" ? parsed.token : defaults.token,\n sessionKey:\n typeof parsed.sessionKey === \"string\" && parsed.sessionKey.trim()\n ? parsed.sessionKey.trim()\n : defaults.sessionKey,\n lastActiveSessionKey:\n typeof parsed.lastActiveSessionKey === \"string\" && parsed.lastActiveSessionKey.trim()\n ? parsed.lastActiveSessionKey.trim()\n : (typeof parsed.sessionKey === \"string\" && parsed.sessionKey.trim()) ||\n defaults.lastActiveSessionKey,\n theme:\n parsed.theme === \"light\" || parsed.theme === \"dark\" || parsed.theme === \"system\"\n ? parsed.theme\n : defaults.theme,\n chatFocusMode:\n typeof parsed.chatFocusMode === \"boolean\" ? parsed.chatFocusMode : defaults.chatFocusMode,\n chatShowThinking:\n typeof parsed.chatShowThinking === \"boolean\"\n ? parsed.chatShowThinking\n : defaults.chatShowThinking,\n splitRatio:\n typeof parsed.splitRatio === \"number\" &&\n parsed.splitRatio >= 0.4 &&\n parsed.splitRatio <= 0.7\n ? parsed.splitRatio\n : defaults.splitRatio,\n navCollapsed:\n typeof parsed.navCollapsed === \"boolean\" ? parsed.navCollapsed : defaults.navCollapsed,\n navGroupsCollapsed:\n typeof parsed.navGroupsCollapsed === \"object\" && parsed.navGroupsCollapsed !== null\n ? parsed.navGroupsCollapsed\n : defaults.navGroupsCollapsed,\n locale: isSupportedLocale(parsed.locale) ? parsed.locale : undefined,\n };\n } catch {\n return defaults;\n }\n}\n\nexport function saveSettings(next: UiSettings) {\n localStorage.setItem(KEY, JSON.stringify(next));\n}\n","import type { ThemeMode } from \"./theme.ts\";\n\nexport type ThemeTransitionContext = {\n element?: HTMLElement | null;\n pointerClientX?: number;\n pointerClientY?: number;\n};\n\nexport type ThemeTransitionOptions = {\n nextTheme: ThemeMode;\n applyTheme: () => void;\n context?: ThemeTransitionContext;\n currentTheme?: ThemeMode | null;\n};\n\ntype DocumentWithViewTransition = Document & {\n startViewTransition?: (callback: () => void) => { finished: Promise<void> };\n};\n\nconst clamp01 = (value: number) => {\n if (Number.isNaN(value)) {\n return 0.5;\n }\n if (value <= 0) {\n return 0;\n }\n if (value >= 1) {\n return 1;\n }\n return value;\n};\n\nconst hasReducedMotionPreference = () => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n};\n\nconst cleanupThemeTransition = (root: HTMLElement) => {\n root.classList.remove(\"theme-transition\");\n root.style.removeProperty(\"--theme-switch-x\");\n root.style.removeProperty(\"--theme-switch-y\");\n};\n\nexport const startThemeTransition = ({\n nextTheme,\n applyTheme,\n context,\n currentTheme,\n}: ThemeTransitionOptions) => {\n if (currentTheme === nextTheme) {\n return;\n }\n\n const documentReference = globalThis.document ?? null;\n if (!documentReference) {\n applyTheme();\n return;\n }\n\n const root = documentReference.documentElement;\n const document_ = documentReference as DocumentWithViewTransition;\n const prefersReducedMotion = hasReducedMotionPreference();\n\n const canUseViewTransition = Boolean(document_.startViewTransition) && !prefersReducedMotion;\n\n if (canUseViewTransition) {\n let xPercent = 0.5;\n let yPercent = 0.5;\n\n if (\n context?.pointerClientX !== undefined &&\n context?.pointerClientY !== undefined &&\n typeof window !== \"undefined\"\n ) {\n xPercent = clamp01(context.pointerClientX / window.innerWidth);\n yPercent = clamp01(context.pointerClientY / window.innerHeight);\n } else if (context?.element) {\n const rect = context.element.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0 && typeof window !== \"undefined\") {\n xPercent = clamp01((rect.left + rect.width / 2) / window.innerWidth);\n yPercent = clamp01((rect.top + rect.height / 2) / window.innerHeight);\n }\n }\n\n root.style.setProperty(\"--theme-switch-x\", `${xPercent * 100}%`);\n root.style.setProperty(\"--theme-switch-y\", `${yPercent * 100}%`);\n root.classList.add(\"theme-transition\");\n\n try {\n const transition = document_.startViewTransition?.(() => {\n applyTheme();\n });\n if (transition?.finished) {\n void transition.finished.finally(() => cleanupThemeTransition(root));\n } else {\n cleanupThemeTransition(root);\n }\n } catch {\n cleanupThemeTransition(root);\n applyTheme();\n }\n return;\n }\n\n applyTheme();\n cleanupThemeTransition(root);\n};\n","export type ThemeMode = \"system\" | \"light\" | \"dark\";\nexport type ResolvedTheme = \"light\" | \"dark\";\n\nexport function getSystemTheme(): ResolvedTheme {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return \"dark\";\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n}\n\nexport function resolveTheme(mode: ThemeMode): ResolvedTheme {\n if (mode === \"system\") {\n return getSystemTheme();\n }\n return mode;\n}\n","import { refreshChat } from \"./app-chat.ts\";\nimport {\n startLogsPolling,\n stopLogsPolling,\n startDebugPolling,\n stopDebugPolling,\n} from \"./app-polling.ts\";\nimport { scheduleChatScroll, scheduleLogsScroll } from \"./app-scroll.ts\";\nimport type { OpenClawApp } from \"./app.ts\";\nimport { loadAgentIdentities, loadAgentIdentity } from \"./controllers/agent-identity.ts\";\nimport { loadAgentSkills } from \"./controllers/agent-skills.ts\";\nimport { loadAgents, loadToolsCatalog } from \"./controllers/agents.ts\";\nimport { loadChannels } from \"./controllers/channels.ts\";\nimport { loadConfig, loadConfigSchema } from \"./controllers/config.ts\";\nimport {\n loadCronJobs,\n loadCronModelSuggestions,\n loadCronRuns,\n loadCronStatus,\n} from \"./controllers/cron.ts\";\nimport { loadDebug } from \"./controllers/debug.ts\";\nimport { loadDevices } from \"./controllers/devices.ts\";\nimport { loadDreams, type DreamsHost } from \"./controllers/dreams.ts\";\nimport { loadExecApprovals } from \"./controllers/exec-approvals.ts\";\nimport { loadLogs } from \"./controllers/logs.ts\";\nimport { loadNodes } from \"./controllers/nodes.ts\";\nimport { loadPresence } from \"./controllers/presence.ts\";\nimport { loadSessionRuns, loadSessionThresholds, loadSessions } from \"./controllers/sessions.ts\";\nimport { loadSkills } from \"./controllers/skills.ts\";\nimport type { TalkController } from \"./controllers/talk.ts\";\nimport {\n inferBasePathFromPathname,\n normalizeBasePath,\n normalizePath,\n pathForTab,\n tabFromPath,\n type Tab,\n} from \"./navigation.ts\";\nimport { saveSettings, type UiSettings } from \"./storage.ts\";\nimport { startThemeTransition, type ThemeTransitionContext } from \"./theme-transition.ts\";\nimport { resolveTheme, type ResolvedTheme, type ThemeMode } from \"./theme.ts\";\nimport type { AgentsListResult } from \"./types.ts\";\n\ntype SettingsHost = {\n settings: UiSettings;\n password?: string;\n theme: ThemeMode;\n themeResolved: ResolvedTheme;\n applySessionKey: string;\n sessionKey: string;\n tab: Tab;\n connected: boolean;\n chatHasAutoScrolled: boolean;\n logsAtBottom: boolean;\n eventLog: unknown[];\n eventLogBuffer: unknown[];\n basePath: string;\n agentsList?: AgentsListResult | null;\n agentsSelectedId?: string | null;\n agentsPanel?: \"overview\" | \"files\" | \"tools\" | \"skills\" | \"channels\" | \"cron\";\n themeMedia: MediaQueryList | null;\n themeMediaHandler: ((event: MediaQueryListEvent) => void) | null;\n pendingGatewayUrl?: string | null;\n talkController: Pick<TalkController, \"stop\">;\n};\n\nexport function applySettings(host: SettingsHost, next: UiSettings) {\n const normalized = {\n ...next,\n lastActiveSessionKey: next.lastActiveSessionKey?.trim() || next.sessionKey.trim() || \"main\",\n };\n host.settings = normalized;\n saveSettings(normalized);\n if (next.theme !== host.theme) {\n host.theme = next.theme;\n applyResolvedTheme(host, resolveTheme(next.theme));\n }\n host.applySessionKey = host.settings.lastActiveSessionKey;\n}\n\nexport function setLastActiveSessionKey(host: SettingsHost, next: string) {\n const trimmed = next.trim();\n if (!trimmed) {\n return;\n }\n if (host.settings.lastActiveSessionKey === trimmed) {\n return;\n }\n applySettings(host, { ...host.settings, lastActiveSessionKey: trimmed });\n}\n\nexport function applySettingsFromUrl(host: SettingsHost) {\n if (!window.location.search && !window.location.hash) {\n return;\n }\n const url = new URL(window.location.href);\n const params = new URLSearchParams(url.search);\n const hashParams = new URLSearchParams(url.hash.startsWith(\"#\") ? url.hash.slice(1) : url.hash);\n\n const tokenRaw = params.get(\"token\") ?? hashParams.get(\"token\");\n const passwordRaw = params.get(\"password\") ?? hashParams.get(\"password\");\n const sessionRaw = params.get(\"session\") ?? hashParams.get(\"session\");\n const gatewayUrlRaw = params.get(\"gatewayUrl\") ?? hashParams.get(\"gatewayUrl\");\n let shouldCleanUrl = false;\n\n if (tokenRaw != null) {\n const token = tokenRaw.trim();\n if (token && token !== host.settings.token) {\n applySettings(host, { ...host.settings, token });\n }\n params.delete(\"token\");\n hashParams.delete(\"token\");\n shouldCleanUrl = true;\n }\n\n if (passwordRaw != null) {\n // Never hydrate password from URL params; strip only.\n params.delete(\"password\");\n hashParams.delete(\"password\");\n shouldCleanUrl = true;\n }\n\n if (sessionRaw != null) {\n const session = sessionRaw.trim();\n if (session) {\n host.sessionKey = session;\n applySettings(host, {\n ...host.settings,\n sessionKey: session,\n lastActiveSessionKey: session,\n });\n }\n }\n\n if (gatewayUrlRaw != null) {\n const gatewayUrl = gatewayUrlRaw.trim();\n if (gatewayUrl && gatewayUrl !== host.settings.gatewayUrl) {\n host.pendingGatewayUrl = gatewayUrl;\n }\n params.delete(\"gatewayUrl\");\n hashParams.delete(\"gatewayUrl\");\n shouldCleanUrl = true;\n }\n\n if (!shouldCleanUrl) {\n return;\n }\n url.search = params.toString();\n const nextHash = hashParams.toString();\n url.hash = nextHash ? `#${nextHash}` : \"\";\n window.history.replaceState({}, \"\", url.toString());\n}\n\nexport function setTab(host: SettingsHost, next: Tab) {\n applyTabSelection(host, next, { refreshPolicy: \"always\", syncUrl: true });\n}\n\nexport function setTheme(host: SettingsHost, next: ThemeMode, context?: ThemeTransitionContext) {\n const applyTheme = () => {\n host.theme = next;\n applySettings(host, { ...host.settings, theme: next });\n applyResolvedTheme(host, resolveTheme(next));\n };\n startThemeTransition({\n nextTheme: next,\n applyTheme,\n context,\n currentTheme: host.theme,\n });\n}\n\nexport async function refreshActiveTab(host: SettingsHost) {\n if (host.tab === \"overview\") {\n await loadOverview(host);\n }\n if (host.tab === \"channels\") {\n await loadChannelsTab(host);\n }\n if (host.tab === \"instances\") {\n await loadPresence(host as unknown as OpenClawApp);\n }\n if (host.tab === \"sessions\") {\n await loadSessions(host as unknown as OpenClawApp);\n void loadSessionRuns(host as unknown as OpenClawApp);\n void loadSessionThresholds(host as unknown as OpenClawApp);\n }\n if (host.tab === \"cron\") {\n await loadCron(host);\n }\n if (host.tab === \"learning\") {\n await (host as unknown as OpenClawApp).loadLearning();\n }\n if (host.tab === \"dreams\") {\n await loadDreams(host as unknown as DreamsHost);\n }\n if (host.tab === \"skills\") {\n await loadSkills(host as unknown as OpenClawApp);\n }\n if (host.tab === \"agents\") {\n await loadAgents(host as unknown as OpenClawApp);\n await loadToolsCatalog(host as unknown as OpenClawApp);\n await loadConfig(host as unknown as OpenClawApp);\n const agentIds = host.agentsList?.agents?.map((entry) => entry.id) ?? [];\n if (agentIds.length > 0) {\n void loadAgentIdentities(host as unknown as OpenClawApp, agentIds);\n }\n const agentId =\n host.agentsSelectedId ?? host.agentsList?.defaultId ?? host.agentsList?.agents?.[0]?.id;\n if (agentId) {\n void loadAgentIdentity(host as unknown as OpenClawApp, agentId);\n if (host.agentsPanel === \"skills\") {\n void loadAgentSkills(host as unknown as OpenClawApp, agentId);\n }\n if (host.agentsPanel === \"channels\") {\n void loadChannels(host as unknown as OpenClawApp, false);\n }\n if (host.agentsPanel === \"cron\") {\n void loadCron(host);\n }\n }\n }\n if (host.tab === \"nodes\") {\n await loadNodes(host as unknown as OpenClawApp);\n await loadDevices(host as unknown as OpenClawApp);\n await loadConfig(host as unknown as OpenClawApp);\n await loadExecApprovals(host as unknown as OpenClawApp);\n }\n if (host.tab === \"chat\") {\n await refreshChat(host as unknown as Parameters<typeof refreshChat>[0]);\n scheduleChatScroll(\n host as unknown as Parameters<typeof scheduleChatScroll>[0],\n !host.chatHasAutoScrolled,\n );\n }\n if (host.tab === \"config\") {\n await loadConfigSchema(host as unknown as OpenClawApp);\n await loadConfig(host as unknown as OpenClawApp);\n }\n if (host.tab === \"debug\") {\n await loadDebug(host as unknown as OpenClawApp);\n host.eventLog = host.eventLogBuffer;\n }\n if (host.tab === \"logs\") {\n host.logsAtBottom = true;\n await loadLogs(host as unknown as OpenClawApp, { reset: true });\n scheduleLogsScroll(host as unknown as Parameters<typeof scheduleLogsScroll>[0], true);\n }\n}\n\nexport function inferBasePath() {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n const configured = window.__OPENCLAW_CONTROL_UI_BASE_PATH__;\n if (typeof configured === \"string\" && configured.trim()) {\n return normalizeBasePath(configured);\n }\n return inferBasePathFromPathname(window.location.pathname);\n}\n\nexport function syncThemeWithSettings(host: SettingsHost) {\n host.theme = host.settings.theme ?? \"system\";\n applyResolvedTheme(host, resolveTheme(host.theme));\n}\n\nexport function applyResolvedTheme(host: SettingsHost, resolved: ResolvedTheme) {\n host.themeResolved = resolved;\n if (typeof document === \"undefined\") {\n return;\n }\n const root = document.documentElement;\n root.dataset.theme = resolved;\n root.style.colorScheme = resolved;\n}\n\nexport function attachThemeListener(host: SettingsHost) {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return;\n }\n host.themeMedia = window.matchMedia(\"(prefers-color-scheme: dark)\");\n host.themeMediaHandler = (event) => {\n if (host.theme !== \"system\") {\n return;\n }\n applyResolvedTheme(host, event.matches ? \"dark\" : \"light\");\n };\n if (typeof host.themeMedia.addEventListener === \"function\") {\n host.themeMedia.addEventListener(\"change\", host.themeMediaHandler);\n return;\n }\n const legacy = host.themeMedia as MediaQueryList & {\n addListener: (cb: (event: MediaQueryListEvent) => void) => void;\n };\n legacy.addListener(host.themeMediaHandler);\n}\n\nexport function detachThemeListener(host: SettingsHost) {\n if (!host.themeMedia || !host.themeMediaHandler) {\n return;\n }\n if (typeof host.themeMedia.removeEventListener === \"function\") {\n host.themeMedia.removeEventListener(\"change\", host.themeMediaHandler);\n return;\n }\n const legacy = host.themeMedia as MediaQueryList & {\n removeListener: (cb: (event: MediaQueryListEvent) => void) => void;\n };\n legacy.removeListener(host.themeMediaHandler);\n host.themeMedia = null;\n host.themeMediaHandler = null;\n}\n\nexport function syncTabWithLocation(host: SettingsHost, replace: boolean) {\n if (typeof window === \"undefined\") {\n return;\n }\n const resolved = tabFromPath(window.location.pathname, host.basePath) ?? \"overview\";\n setTabFromRoute(host, resolved);\n syncUrlWithTab(host, resolved, replace);\n}\n\nexport function onPopState(host: SettingsHost) {\n if (typeof window === \"undefined\") {\n return;\n }\n const resolved = tabFromPath(window.location.pathname, host.basePath);\n if (!resolved) {\n return;\n }\n\n const url = new URL(window.location.href);\n const session = url.searchParams.get(\"session\")?.trim();\n if (session) {\n host.sessionKey = session;\n applySettings(host, {\n ...host.settings,\n sessionKey: session,\n lastActiveSessionKey: session,\n });\n }\n\n setTabFromRoute(host, resolved);\n}\n\nexport function setTabFromRoute(host: SettingsHost, next: Tab) {\n applyTabSelection(host, next, { refreshPolicy: \"connected\" });\n}\n\nfunction applyTabSelection(\n host: SettingsHost,\n next: Tab,\n options: { refreshPolicy: \"always\" | \"connected\"; syncUrl?: boolean },\n) {\n if (host.tab === \"talk\" && next !== \"talk\") {\n try {\n host.talkController.stop().catch(() => undefined);\n } catch {\n // A misbehaving stop() may throw synchronously instead of rejecting;\n // the tab switch and reconciliation below must still run.\n }\n }\n if (host.tab !== next) {\n host.tab = next;\n }\n if (next === \"chat\") {\n host.chatHasAutoScrolled = false;\n }\n if (next === \"logs\") {\n startLogsPolling(host as unknown as Parameters<typeof startLogsPolling>[0]);\n } else {\n stopLogsPolling(host as unknown as Parameters<typeof stopLogsPolling>[0]);\n }\n if (next === \"debug\") {\n startDebugPolling(host as unknown as Parameters<typeof startDebugPolling>[0]);\n } else {\n stopDebugPolling(host as unknown as Parameters<typeof stopDebugPolling>[0]);\n }\n\n if (options.refreshPolicy === \"always\" || host.connected) {\n void refreshActiveTab(host);\n }\n\n if (options.syncUrl) {\n syncUrlWithTab(host, next, false);\n }\n}\n\nexport function syncUrlWithTab(host: SettingsHost, tab: Tab, replace: boolean) {\n if (typeof window === \"undefined\") {\n return;\n }\n const targetPath = normalizePath(pathForTab(tab, host.basePath));\n const currentPath = normalizePath(window.location.pathname);\n const baseRootPath = normalizeBasePath(host.basePath) || \"/\";\n const preserveOverviewRoot = tab === \"overview\" && currentPath === normalizePath(baseRootPath);\n const url = new URL(window.location.href);\n\n if (tab === \"chat\" && host.sessionKey) {\n url.searchParams.set(\"session\", host.sessionKey);\n } else {\n url.searchParams.delete(\"session\");\n }\n\n if (!preserveOverviewRoot && currentPath !== targetPath) {\n url.pathname = targetPath;\n }\n\n if (replace) {\n window.history.replaceState({}, \"\", url.toString());\n } else {\n window.history.pushState({}, \"\", url.toString());\n }\n}\n\nexport function syncUrlWithSessionKey(host: SettingsHost, sessionKey: string, replace: boolean) {\n if (typeof window === \"undefined\") {\n return;\n }\n const url = new URL(window.location.href);\n url.searchParams.set(\"session\", sessionKey);\n if (replace) {\n window.history.replaceState({}, \"\", url.toString());\n } else {\n window.history.pushState({}, \"\", url.toString());\n }\n}\n\nexport async function loadOverview(host: SettingsHost) {\n await Promise.all([\n loadChannels(host as unknown as OpenClawApp, false),\n loadPresence(host as unknown as OpenClawApp),\n loadSessions(host as unknown as OpenClawApp),\n loadCronStatus(host as unknown as OpenClawApp),\n loadDebug(host as unknown as OpenClawApp),\n ]);\n}\n\nexport async function loadChannelsTab(host: SettingsHost) {\n await Promise.all([\n loadChannels(host as unknown as OpenClawApp, true),\n loadConfigSchema(host as unknown as OpenClawApp),\n loadConfig(host as unknown as OpenClawApp),\n ]);\n}\n\nexport async function loadCron(host: SettingsHost) {\n const cronHost = host as unknown as OpenClawApp;\n await Promise.all([\n loadChannels(host as unknown as OpenClawApp, false),\n loadCronStatus(cronHost),\n loadCronJobs(cronHost),\n loadCronModelSuggestions(cronHost),\n ]);\n if (cronHost.cronRunsScope === \"all\") {\n await loadCronRuns(cronHost, null);\n return;\n }\n if (cronHost.cronRunsJobId) {\n await loadCronRuns(cronHost, cronHost.cronRunsJobId);\n }\n}\n","import { truncateText } from \"./format.ts\";\n\nconst TOOL_STREAM_LIMIT = 50;\nconst TOOL_STREAM_THROTTLE_MS = 80;\nconst TOOL_OUTPUT_CHAR_LIMIT = 120_000;\n\nexport type AgentEventPayload = {\n runId: string;\n seq: number;\n stream: string;\n ts: number;\n sessionKey?: string;\n data: Record<string, unknown>;\n};\n\nexport type ToolStreamEntry = {\n toolCallId: string;\n runId: string;\n sessionKey?: string;\n name: string;\n args?: unknown;\n output?: string;\n startedAt: number;\n updatedAt: number;\n message: Record<string, unknown>;\n};\n\ntype ToolStreamHost = {\n sessionKey: string;\n chatRunId: string | null;\n toolStreamById: Map<string, ToolStreamEntry>;\n toolStreamOrder: string[];\n chatToolMessages: Record<string, unknown>[];\n toolStreamSyncTimer: number | null;\n};\n\nfunction toTrimmedString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n}\n\nfunction resolveModelLabel(provider: unknown, model: unknown): string | null {\n const modelValue = toTrimmedString(model);\n if (!modelValue) {\n return null;\n }\n const providerValue = toTrimmedString(provider);\n if (providerValue) {\n const prefix = `${providerValue}/`;\n if (modelValue.toLowerCase().startsWith(prefix.toLowerCase())) {\n const trimmedModel = modelValue.slice(prefix.length).trim();\n if (trimmedModel) {\n return `${providerValue}/${trimmedModel}`;\n }\n }\n return `${providerValue}/${modelValue}`;\n }\n const slashIndex = modelValue.indexOf(\"/\");\n if (slashIndex > 0) {\n const p = modelValue.slice(0, slashIndex).trim();\n const m = modelValue.slice(slashIndex + 1).trim();\n if (p && m) {\n return `${p}/${m}`;\n }\n }\n return modelValue;\n}\n\ntype FallbackAttempt = {\n provider: string;\n model: string;\n reason: string;\n};\n\nfunction parseFallbackAttemptSummaries(value: unknown): string[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((entry) => toTrimmedString(entry))\n .filter((entry): entry is string => Boolean(entry));\n}\n\nfunction parseFallbackAttempts(value: unknown): FallbackAttempt[] {\n if (!Array.isArray(value)) {\n return [];\n }\n const out: FallbackAttempt[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\") {\n continue;\n }\n const item = entry as Record<string, unknown>;\n const provider = toTrimmedString(item.provider);\n const model = toTrimmedString(item.model);\n if (!provider || !model) {\n continue;\n }\n const reason =\n toTrimmedString(item.reason)?.replace(/_/g, \" \") ??\n toTrimmedString(item.code) ??\n (typeof item.status === \"number\" ? `HTTP ${item.status}` : null) ??\n toTrimmedString(item.error) ??\n \"error\";\n out.push({ provider, model, reason });\n }\n return out;\n}\n\nfunction extractToolOutputText(value: unknown): string | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.text === \"string\") {\n return record.text;\n }\n const content = record.content;\n if (!Array.isArray(content)) {\n return null;\n }\n const parts = content\n .map((item) => {\n if (!item || typeof item !== \"object\") {\n return null;\n }\n const entry = item as Record<string, unknown>;\n if (entry.type === \"text\" && typeof entry.text === \"string\") {\n return entry.text;\n }\n return null;\n })\n .filter((part): part is string => Boolean(part));\n if (parts.length === 0) {\n return null;\n }\n return parts.join(\"\\n\");\n}\n\nfunction formatToolOutput(value: unknown): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n const contentText = extractToolOutputText(value);\n let text: string;\n if (typeof value === \"string\") {\n text = value;\n } else if (contentText) {\n text = contentText;\n } else {\n try {\n text = JSON.stringify(value, null, 2);\n } catch {\n // oxlint-disable typescript/no-base-to-string\n text = String(value);\n }\n }\n const truncated = truncateText(text, TOOL_OUTPUT_CHAR_LIMIT);\n if (!truncated.truncated) {\n return truncated.text;\n }\n return `${truncated.text}\\n\\n… truncated (${truncated.total} chars, showing first ${truncated.text.length}).`;\n}\n\nfunction buildToolStreamMessage(entry: ToolStreamEntry): Record<string, unknown> {\n const content: Array<Record<string, unknown>> = [];\n content.push({\n type: \"toolcall\",\n name: entry.name,\n arguments: entry.args ?? {},\n });\n if (entry.output) {\n content.push({\n type: \"toolresult\",\n name: entry.name,\n text: entry.output,\n });\n }\n return {\n role: \"assistant\",\n toolCallId: entry.toolCallId,\n runId: entry.runId,\n content,\n timestamp: entry.startedAt,\n };\n}\n\nfunction trimToolStream(host: ToolStreamHost) {\n if (host.toolStreamOrder.length <= TOOL_STREAM_LIMIT) {\n return;\n }\n const overflow = host.toolStreamOrder.length - TOOL_STREAM_LIMIT;\n const removed = host.toolStreamOrder.splice(0, overflow);\n for (const id of removed) {\n host.toolStreamById.delete(id);\n }\n}\n\nfunction syncToolStreamMessages(host: ToolStreamHost) {\n host.chatToolMessages = host.toolStreamOrder\n .map((id) => host.toolStreamById.get(id)?.message)\n .filter((msg): msg is Record<string, unknown> => Boolean(msg));\n}\n\nexport function flushToolStreamSync(host: ToolStreamHost) {\n if (host.toolStreamSyncTimer != null) {\n clearTimeout(host.toolStreamSyncTimer);\n host.toolStreamSyncTimer = null;\n }\n syncToolStreamMessages(host);\n}\n\nexport function scheduleToolStreamSync(host: ToolStreamHost, force = false) {\n if (force) {\n flushToolStreamSync(host);\n return;\n }\n if (host.toolStreamSyncTimer != null) {\n return;\n }\n host.toolStreamSyncTimer = window.setTimeout(\n () => flushToolStreamSync(host),\n TOOL_STREAM_THROTTLE_MS,\n );\n}\n\nexport function resetToolStream(host: ToolStreamHost) {\n host.toolStreamById.clear();\n host.toolStreamOrder = [];\n host.chatToolMessages = [];\n flushToolStreamSync(host);\n}\n\nexport type CompactionStatus = {\n active: boolean;\n startedAt: number | null;\n completedAt: number | null;\n /** The compaction ended without a successful result (failed or canceled). */\n failed: boolean;\n};\n\nexport type FallbackStatus = {\n phase?: \"active\" | \"cleared\";\n selected: string;\n active: string;\n previous?: string;\n reason?: string;\n attempts: string[];\n occurredAt: number;\n};\n\ntype CompactionHost = ToolStreamHost & {\n compactionStatus?: CompactionStatus | null;\n compactionClearTimer?: number | null;\n fallbackStatus?: FallbackStatus | null;\n fallbackClearTimer?: number | null;\n};\n\nconst COMPACTION_TOAST_DURATION_MS = 5000;\nconst FALLBACK_TOAST_DURATION_MS = 8000;\n\nexport function handleCompactionEvent(host: CompactionHost, payload: AgentEventPayload) {\n const data = payload.data ?? {};\n const phase = typeof data.phase === \"string\" ? data.phase : \"\";\n\n // Clear any existing timer\n if (host.compactionClearTimer != null) {\n window.clearTimeout(host.compactionClearTimer);\n host.compactionClearTimer = null;\n }\n\n if (phase === \"start\") {\n host.compactionStatus = {\n active: true,\n startedAt: Date.now(),\n completedAt: null,\n failed: false,\n };\n } else if (phase === \"end\") {\n // A failed/canceled compaction shares the \"end\" phase; only the completed\n // flag distinguishes it, so the indicator must not claim success.\n const failed = data.completed === false;\n host.compactionStatus = {\n active: false,\n startedAt: host.compactionStatus?.startedAt ?? null,\n completedAt: Date.now(),\n failed,\n };\n // Auto-clear the toast after duration\n host.compactionClearTimer = window.setTimeout(() => {\n host.compactionStatus = null;\n host.compactionClearTimer = null;\n }, COMPACTION_TOAST_DURATION_MS);\n }\n}\n\nfunction resolveAcceptedSession(\n host: ToolStreamHost,\n payload: AgentEventPayload,\n options?: {\n allowSessionScopedWhenIdle?: boolean;\n },\n): { accepted: boolean; sessionKey?: string } {\n const sessionKey = typeof payload.sessionKey === \"string\" ? payload.sessionKey : undefined;\n if (sessionKey && sessionKey !== host.sessionKey) {\n return { accepted: false };\n }\n if (!host.chatRunId && options?.allowSessionScopedWhenIdle && sessionKey) {\n return { accepted: true, sessionKey };\n }\n // Fallback: only accept session-less events for the active run.\n if (!sessionKey && host.chatRunId && payload.runId !== host.chatRunId) {\n return { accepted: false };\n }\n if (host.chatRunId && payload.runId !== host.chatRunId) {\n return { accepted: false };\n }\n if (!host.chatRunId) {\n return { accepted: false };\n }\n return { accepted: true, sessionKey };\n}\n\nfunction handleLifecycleFallbackEvent(host: CompactionHost, payload: AgentEventPayload) {\n const data = payload.data ?? {};\n const phase = payload.stream === \"fallback\" ? \"fallback\" : toTrimmedString(data.phase);\n if (payload.stream === \"lifecycle\" && phase !== \"fallback\" && phase !== \"fallback_cleared\") {\n return;\n }\n\n const accepted = resolveAcceptedSession(host, payload, { allowSessionScopedWhenIdle: true });\n if (!accepted.accepted) {\n return;\n }\n\n const selected =\n resolveModelLabel(data.selectedProvider, data.selectedModel) ??\n resolveModelLabel(data.fromProvider, data.fromModel);\n const active =\n resolveModelLabel(data.activeProvider, data.activeModel) ??\n resolveModelLabel(data.toProvider, data.toModel);\n const previous =\n resolveModelLabel(data.previousActiveProvider, data.previousActiveModel) ??\n toTrimmedString(data.previousActiveModel);\n if (!selected || !active) {\n return;\n }\n if (phase === \"fallback\" && selected === active) {\n return;\n }\n\n const reason = toTrimmedString(data.reasonSummary) ?? toTrimmedString(data.reason);\n const attempts = (() => {\n const summaries = parseFallbackAttemptSummaries(data.attemptSummaries);\n if (summaries.length > 0) {\n return summaries;\n }\n return parseFallbackAttempts(data.attempts).map((attempt) => {\n const modelRef = resolveModelLabel(attempt.provider, attempt.model);\n return `${modelRef ?? `${attempt.provider}/${attempt.model}`}: ${attempt.reason}`;\n });\n })();\n\n if (host.fallbackClearTimer != null) {\n window.clearTimeout(host.fallbackClearTimer);\n host.fallbackClearTimer = null;\n }\n host.fallbackStatus = {\n phase: phase === \"fallback_cleared\" ? \"cleared\" : \"active\",\n selected,\n active: phase === \"fallback_cleared\" ? selected : active,\n previous:\n phase === \"fallback_cleared\"\n ? (previous ?? (active !== selected ? active : undefined))\n : undefined,\n reason: reason ?? undefined,\n attempts,\n occurredAt: Date.now(),\n };\n host.fallbackClearTimer = window.setTimeout(() => {\n host.fallbackStatus = null;\n host.fallbackClearTimer = null;\n }, FALLBACK_TOAST_DURATION_MS);\n}\n\nexport function handleAgentEvent(host: ToolStreamHost, payload?: AgentEventPayload) {\n if (!payload) {\n return;\n }\n\n // Handle compaction events\n if (payload.stream === \"compaction\") {\n handleCompactionEvent(host as CompactionHost, payload);\n return;\n }\n\n if (payload.stream === \"lifecycle\" || payload.stream === \"fallback\") {\n handleLifecycleFallbackEvent(host as CompactionHost, payload);\n return;\n }\n\n if (payload.stream !== \"tool\") {\n return;\n }\n const accepted = resolveAcceptedSession(host, payload);\n if (!accepted.accepted) {\n return;\n }\n const sessionKey = accepted.sessionKey;\n\n const data = payload.data ?? {};\n const toolCallId = typeof data.toolCallId === \"string\" ? data.toolCallId : \"\";\n if (!toolCallId) {\n return;\n }\n const name = typeof data.name === \"string\" ? data.name : \"tool\";\n const phase = typeof data.phase === \"string\" ? data.phase : \"\";\n const args = phase === \"start\" ? data.args : undefined;\n const output =\n phase === \"update\"\n ? formatToolOutput(data.partialResult)\n : phase === \"result\"\n ? formatToolOutput(data.result)\n : undefined;\n\n const now = Date.now();\n let entry = host.toolStreamById.get(toolCallId);\n if (!entry) {\n entry = {\n toolCallId,\n runId: payload.runId,\n sessionKey,\n name,\n args,\n output: output || undefined,\n startedAt: typeof payload.ts === \"number\" ? payload.ts : now,\n updatedAt: now,\n message: {},\n };\n host.toolStreamById.set(toolCallId, entry);\n host.toolStreamOrder.push(toolCallId);\n } else {\n entry.name = name;\n if (args !== undefined) {\n entry.args = args;\n }\n if (output !== undefined) {\n entry.output = output || undefined;\n }\n entry.updatedAt = now;\n }\n\n entry.message = buildToolStreamMessage(entry);\n trimToolStream(host);\n scheduleToolStreamSync(host, phase === \"result\");\n}\n","import { extractText } from \"../chat/message-extract.ts\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { ChatAttachment } from \"../ui-types.ts\";\nimport { generateUUID } from \"../uuid.ts\";\n\nconst SILENT_REPLY_PATTERN = /^\\s*NO_REPLY\\s*$/;\n\nfunction isSilentReplyStream(text: string): boolean {\n return SILENT_REPLY_PATTERN.test(text);\n}\n/** Client-side defense-in-depth: detect assistant messages whose text is purely NO_REPLY. */\nfunction isAssistantSilentReply(message: unknown): boolean {\n if (!message || typeof message !== \"object\") {\n return false;\n }\n const entry = message as Record<string, unknown>;\n const role = typeof entry.role === \"string\" ? entry.role.toLowerCase() : \"\";\n if (role !== \"assistant\") {\n return false;\n }\n // entry.text takes precedence — matches gateway extractAssistantTextForSilentCheck\n if (typeof entry.text === \"string\") {\n return isSilentReplyStream(entry.text);\n }\n const text = extractText(message);\n return typeof text === \"string\" && isSilentReplyStream(text);\n}\n\nexport type ChatState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionKey: string;\n chatLoading: boolean;\n chatMessages: unknown[];\n chatThinkingLevel: string | null;\n chatSending: boolean;\n chatMessage: string;\n chatAttachments: ChatAttachment[];\n chatRunId: string | null;\n chatStream: string | null;\n chatStreamStartedAt: number | null;\n lastError: string | null;\n};\n\nexport type ChatEventPayload = {\n runId: string;\n sessionKey: string;\n state: \"delta\" | \"final\" | \"aborted\" | \"error\";\n message?: unknown;\n errorMessage?: string;\n};\n\nexport async function loadChatHistory(state: ChatState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.chatLoading = true;\n state.lastError = null;\n try {\n const res = await state.client.request<{ messages?: Array<unknown>; thinkingLevel?: string }>(\n \"chat.history\",\n {\n sessionKey: state.sessionKey,\n limit: 200,\n },\n );\n const messages = Array.isArray(res.messages) ? res.messages : [];\n state.chatMessages = messages.filter((message) => !isAssistantSilentReply(message));\n state.chatThinkingLevel = res.thinkingLevel ?? null;\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.chatLoading = false;\n }\n}\n\nfunction dataUrlToBase64(dataUrl: string): { content: string; mimeType: string } | null {\n const match = /^data:([^;]+);base64,(.+)$/.exec(dataUrl);\n if (!match) {\n return null;\n }\n return { mimeType: match[1], content: match[2] };\n}\n\ntype AssistantMessageNormalizationOptions = {\n roleRequirement: \"required\" | \"optional\";\n roleCaseSensitive?: boolean;\n requireContentArray?: boolean;\n allowTextField?: boolean;\n};\n\nfunction normalizeAssistantMessage(\n message: unknown,\n options: AssistantMessageNormalizationOptions,\n): Record<string, unknown> | null {\n if (!message || typeof message !== \"object\") {\n return null;\n }\n const candidate = message as Record<string, unknown>;\n const roleValue = candidate.role;\n if (typeof roleValue === \"string\") {\n const role = options.roleCaseSensitive ? roleValue : roleValue.toLowerCase();\n if (role !== \"assistant\") {\n return null;\n }\n } else if (options.roleRequirement === \"required\") {\n return null;\n }\n\n if (options.requireContentArray) {\n return Array.isArray(candidate.content) ? candidate : null;\n }\n if (!(\"content\" in candidate) && !(options.allowTextField && \"text\" in candidate)) {\n return null;\n }\n return candidate;\n}\n\nfunction normalizeAbortedAssistantMessage(message: unknown): Record<string, unknown> | null {\n return normalizeAssistantMessage(message, {\n roleRequirement: \"required\",\n roleCaseSensitive: true,\n requireContentArray: true,\n });\n}\n\nfunction normalizeFinalAssistantMessage(message: unknown): Record<string, unknown> | null {\n return normalizeAssistantMessage(message, {\n roleRequirement: \"optional\",\n allowTextField: true,\n });\n}\n\nexport async function sendChatMessage(\n state: ChatState,\n message: string,\n attachments?: ChatAttachment[],\n): Promise<string | null> {\n if (!state.client || !state.connected) {\n return null;\n }\n const msg = message.trim();\n const hasAttachments = attachments && attachments.length > 0;\n if (!msg && !hasAttachments) {\n return null;\n }\n\n const now = Date.now();\n\n // Build user message content blocks\n const contentBlocks: Array<{ type: string; text?: string; source?: unknown }> = [];\n if (msg) {\n contentBlocks.push({ type: \"text\", text: msg });\n }\n // Add image previews to the message for display\n if (hasAttachments) {\n for (const att of attachments) {\n contentBlocks.push({\n type: \"image\",\n source: { type: \"base64\", media_type: att.mimeType, data: att.dataUrl },\n });\n }\n }\n\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"user\",\n content: contentBlocks,\n timestamp: now,\n },\n ];\n\n state.chatSending = true;\n state.lastError = null;\n const runId = generateUUID();\n state.chatRunId = runId;\n state.chatStream = \"\";\n state.chatStreamStartedAt = now;\n\n // Convert attachments to API format\n const apiAttachments = hasAttachments\n ? attachments\n .map((att) => {\n const parsed = dataUrlToBase64(att.dataUrl);\n if (!parsed) {\n return null;\n }\n return {\n type: \"image\",\n mimeType: parsed.mimeType,\n content: parsed.content,\n };\n })\n .filter((a): a is NonNullable<typeof a> => a !== null)\n : undefined;\n\n try {\n await state.client.request(\"chat.send\", {\n sessionKey: state.sessionKey,\n message: msg,\n deliver: false,\n idempotencyKey: runId,\n attachments: apiAttachments,\n });\n return runId;\n } catch (err) {\n const error = String(err);\n state.chatRunId = null;\n state.chatStream = null;\n state.chatStreamStartedAt = null;\n state.lastError = error;\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"assistant\",\n content: [{ type: \"text\", text: \"Error: \" + error }],\n timestamp: Date.now(),\n },\n ];\n return null;\n } finally {\n state.chatSending = false;\n }\n}\n\nexport async function abortChatRun(state: ChatState): Promise<boolean> {\n if (!state.client || !state.connected) {\n return false;\n }\n const runId = state.chatRunId;\n try {\n await state.client.request(\n \"chat.abort\",\n runId ? { sessionKey: state.sessionKey, runId } : { sessionKey: state.sessionKey },\n );\n return true;\n } catch (err) {\n state.lastError = String(err);\n return false;\n }\n}\n\nexport function handleChatEvent(state: ChatState, payload?: ChatEventPayload) {\n if (!payload) {\n return null;\n }\n if (payload.sessionKey !== state.sessionKey) {\n return null;\n }\n\n // Final from another run (e.g. sub-agent announce): refresh history to show new message.\n // See https://github.com/openclaw/openclaw/issues/1909\n if (payload.runId && state.chatRunId && payload.runId !== state.chatRunId) {\n if (payload.state === \"final\") {\n const finalMessage = normalizeFinalAssistantMessage(payload.message);\n if (finalMessage && !isAssistantSilentReply(finalMessage)) {\n state.chatMessages = [...state.chatMessages, finalMessage];\n return null;\n }\n return \"final\";\n }\n return null;\n }\n\n if (payload.state === \"delta\") {\n const next = extractText(payload.message);\n if (typeof next === \"string\" && !isSilentReplyStream(next)) {\n const current = state.chatStream ?? \"\";\n if (!current || next.length >= current.length) {\n state.chatStream = next;\n }\n }\n } else if (payload.state === \"final\") {\n const finalMessage = normalizeFinalAssistantMessage(payload.message);\n if (finalMessage && !isAssistantSilentReply(finalMessage)) {\n state.chatMessages = [...state.chatMessages, finalMessage];\n } else if (state.chatStream?.trim() && !isSilentReplyStream(state.chatStream)) {\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"assistant\",\n content: [{ type: \"text\", text: state.chatStream }],\n timestamp: Date.now(),\n },\n ];\n }\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n } else if (payload.state === \"aborted\") {\n const normalizedMessage = normalizeAbortedAssistantMessage(payload.message);\n if (normalizedMessage && !isAssistantSilentReply(normalizedMessage)) {\n state.chatMessages = [...state.chatMessages, normalizedMessage];\n } else {\n const streamedText = state.chatStream ?? \"\";\n if (streamedText.trim() && !isSilentReplyStream(streamedText)) {\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"assistant\",\n content: [{ type: \"text\", text: streamedText }],\n timestamp: Date.now(),\n },\n ];\n }\n }\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n } else if (payload.state === \"error\") {\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n state.lastError = payload.errorMessage ?? \"chat error\";\n }\n return payload.state;\n}\n","import { parseAgentSessionKey } from \"../../../src/sessions/session-key-utils.js\";\nimport { scheduleChatScroll } from \"./app-scroll.ts\";\nimport { setLastActiveSessionKey } from \"./app-settings.ts\";\nimport { resetToolStream } from \"./app-tool-stream.ts\";\nimport type { OpenClawApp } from \"./app.ts\";\nimport { abortChatRun, loadChatHistory, sendChatMessage } from \"./controllers/chat.ts\";\nimport { loadSessions } from \"./controllers/sessions.ts\";\nimport type { GatewayHelloOk } from \"./gateway.ts\";\nimport { normalizeBasePath } from \"./navigation.ts\";\nimport type { ChatAttachment, ChatQueueItem } from \"./ui-types.ts\";\nimport { generateUUID } from \"./uuid.ts\";\n\nexport type ChatHost = {\n connected: boolean;\n chatMessage: string;\n chatAttachments: ChatAttachment[];\n chatQueue: ChatQueueItem[];\n chatRunId: string | null;\n chatSending: boolean;\n sessionKey: string;\n basePath: string;\n hello: GatewayHelloOk | null;\n chatAvatarUrl: string | null;\n refreshSessionsAfterChat: Set<string>;\n};\n\nexport const CHAT_SESSIONS_ACTIVE_MINUTES = 120;\n\nexport function isChatBusy(host: ChatHost) {\n return host.chatSending || Boolean(host.chatRunId);\n}\n\nexport function isChatStopCommand(text: string) {\n const trimmed = text.trim();\n if (!trimmed) {\n return false;\n }\n const normalized = trimmed.toLowerCase();\n if (normalized === \"/stop\") {\n return true;\n }\n return (\n normalized === \"stop\" ||\n normalized === \"esc\" ||\n normalized === \"abort\" ||\n normalized === \"wait\" ||\n normalized === \"exit\"\n );\n}\n\nfunction isChatResetCommand(text: string) {\n const trimmed = text.trim();\n if (!trimmed) {\n return false;\n }\n const normalized = trimmed.toLowerCase();\n if (normalized === \"/new\" || normalized === \"/reset\") {\n return true;\n }\n return normalized.startsWith(\"/new \") || normalized.startsWith(\"/reset \");\n}\n\nexport async function handleAbortChat(host: ChatHost) {\n if (!host.connected) {\n return;\n }\n host.chatMessage = \"\";\n await abortChatRun(host as unknown as OpenClawApp);\n}\n\nfunction enqueueChatMessage(\n host: ChatHost,\n text: string,\n attachments?: ChatAttachment[],\n refreshSessions?: boolean,\n) {\n const trimmed = text.trim();\n const hasAttachments = Boolean(attachments && attachments.length > 0);\n if (!trimmed && !hasAttachments) {\n return;\n }\n host.chatQueue = [\n ...host.chatQueue,\n {\n id: generateUUID(),\n text: trimmed,\n createdAt: Date.now(),\n attachments: hasAttachments ? attachments?.map((att) => ({ ...att })) : undefined,\n refreshSessions,\n },\n ];\n}\n\nasync function sendChatMessageNow(\n host: ChatHost,\n message: string,\n opts?: {\n previousDraft?: string;\n restoreDraft?: boolean;\n attachments?: ChatAttachment[];\n previousAttachments?: ChatAttachment[];\n restoreAttachments?: boolean;\n refreshSessions?: boolean;\n },\n) {\n resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);\n const runId = await sendChatMessage(host as unknown as OpenClawApp, message, opts?.attachments);\n const ok = Boolean(runId);\n if (!ok && opts?.previousDraft != null) {\n host.chatMessage = opts.previousDraft;\n }\n if (!ok && opts?.previousAttachments) {\n host.chatAttachments = opts.previousAttachments;\n }\n if (ok) {\n setLastActiveSessionKey(\n host as unknown as Parameters<typeof setLastActiveSessionKey>[0],\n host.sessionKey,\n );\n }\n if (ok && opts?.restoreDraft && opts.previousDraft?.trim()) {\n host.chatMessage = opts.previousDraft;\n }\n if (ok && opts?.restoreAttachments && opts.previousAttachments?.length) {\n host.chatAttachments = opts.previousAttachments;\n }\n scheduleChatScroll(host as unknown as Parameters<typeof scheduleChatScroll>[0]);\n if (ok && !host.chatRunId) {\n void flushChatQueue(host);\n }\n if (ok && opts?.refreshSessions && runId) {\n host.refreshSessionsAfterChat.add(runId);\n }\n return ok;\n}\n\nasync function flushChatQueue(host: ChatHost) {\n if (!host.connected || isChatBusy(host)) {\n return;\n }\n const [next, ...rest] = host.chatQueue;\n if (!next) {\n return;\n }\n host.chatQueue = rest;\n const ok = await sendChatMessageNow(host, next.text, {\n attachments: next.attachments,\n refreshSessions: next.refreshSessions,\n });\n if (!ok) {\n host.chatQueue = [next, ...host.chatQueue];\n }\n}\n\nexport function removeQueuedMessage(host: ChatHost, id: string) {\n host.chatQueue = host.chatQueue.filter((item) => item.id !== id);\n}\n\nexport async function handleSendChat(\n host: ChatHost,\n messageOverride?: string,\n opts?: { restoreDraft?: boolean },\n) {\n if (!host.connected) {\n return;\n }\n const previousDraft = host.chatMessage;\n const message = (messageOverride ?? host.chatMessage).trim();\n const attachments = host.chatAttachments ?? [];\n const attachmentsToSend = messageOverride == null ? attachments : [];\n const hasAttachments = attachmentsToSend.length > 0;\n\n // Allow sending with just attachments (no message text required)\n if (!message && !hasAttachments) {\n return;\n }\n\n if (isChatStopCommand(message)) {\n await handleAbortChat(host);\n return;\n }\n\n const refreshSessions = isChatResetCommand(message);\n if (messageOverride == null) {\n host.chatMessage = \"\";\n // Clear attachments when sending\n host.chatAttachments = [];\n }\n\n if (isChatBusy(host)) {\n enqueueChatMessage(host, message, attachmentsToSend, refreshSessions);\n return;\n }\n\n await sendChatMessageNow(host, message, {\n previousDraft: messageOverride == null ? previousDraft : undefined,\n restoreDraft: Boolean(messageOverride && opts?.restoreDraft),\n attachments: hasAttachments ? attachmentsToSend : undefined,\n previousAttachments: messageOverride == null ? attachments : undefined,\n restoreAttachments: Boolean(messageOverride && opts?.restoreDraft),\n refreshSessions,\n });\n}\n\nexport async function refreshChat(host: ChatHost, opts?: { scheduleScroll?: boolean }) {\n await Promise.all([\n loadChatHistory(host as unknown as OpenClawApp),\n loadSessions(host as unknown as OpenClawApp, {\n activeMinutes: CHAT_SESSIONS_ACTIVE_MINUTES,\n }),\n refreshChatAvatar(host),\n ]);\n if (opts?.scheduleScroll !== false) {\n scheduleChatScroll(host as unknown as Parameters<typeof scheduleChatScroll>[0]);\n }\n}\n\nexport const flushChatQueueForEvent = flushChatQueue;\n\ntype SessionDefaultsSnapshot = {\n defaultAgentId?: string;\n};\n\nfunction resolveAgentIdForSession(host: ChatHost): string | null {\n const parsed = parseAgentSessionKey(host.sessionKey);\n if (parsed?.agentId) {\n return parsed.agentId;\n }\n const snapshot = host.hello?.snapshot as\n | { sessionDefaults?: SessionDefaultsSnapshot }\n | undefined;\n const fallback = snapshot?.sessionDefaults?.defaultAgentId?.trim();\n return fallback || \"main\";\n}\n\nfunction buildAvatarMetaUrl(basePath: string, agentId: string): string {\n const base = normalizeBasePath(basePath);\n const encoded = encodeURIComponent(agentId);\n return base ? `${base}/avatar/${encoded}?meta=1` : `/avatar/${encoded}?meta=1`;\n}\n\nexport async function refreshChatAvatar(host: ChatHost) {\n if (!host.connected) {\n host.chatAvatarUrl = null;\n return;\n }\n const agentId = resolveAgentIdForSession(host);\n if (!agentId) {\n host.chatAvatarUrl = null;\n return;\n }\n host.chatAvatarUrl = null;\n const url = buildAvatarMetaUrl(host.basePath, agentId);\n try {\n const res = await fetch(url, { method: \"GET\" });\n if (!res.ok) {\n host.chatAvatarUrl = null;\n return;\n }\n const data = (await res.json()) as { avatarUrl?: unknown };\n const avatarUrl = typeof data.avatarUrl === \"string\" ? data.avatarUrl.trim() : \"\";\n host.chatAvatarUrl = avatarUrl || null;\n } catch {\n host.chatAvatarUrl = null;\n }\n}\n","import type { ChatEventPayload } from \"./controllers/chat.ts\";\n\nexport function shouldReloadHistoryForFinalEvent(payload?: ChatEventPayload): boolean {\n if (!payload || payload.state !== \"final\") {\n return false;\n }\n if (!payload.message || typeof payload.message !== \"object\") {\n return true;\n }\n const message = payload.message as Record<string, unknown>;\n const role = typeof message.role === \"string\" ? message.role.toLowerCase() : \"\";\n if (role && role !== \"assistant\") {\n return true;\n }\n return false;\n}\n","/**\n * Closed assistant colour palette (ADR 0084 s6, design D11). Every consumer - config validation\n * (zod), the `agents.list` wire shape (typebox), and `packages/brand-tokens/tokens.css` - is\n * bound to this exact set so contrast can be guaranteed in every theme.\n */\nexport const ASSISTANT_IDENTITY_COLORS = [\n \"indigo\",\n \"violet\",\n \"pink\",\n \"rose\",\n \"amber\",\n \"lime\",\n \"teal\",\n \"sky\",\n] as const;\n\nexport type AssistantIdentityColor = (typeof ASSISTANT_IDENTITY_COLORS)[number];\n\nexport function coerceIdentityValue(\n value: string | undefined,\n maxLength: number,\n): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n if (!trimmed) {\n return undefined;\n }\n if (trimmed.length <= maxLength) {\n return trimmed;\n }\n return trimmed.slice(0, maxLength);\n}\n","import { coerceIdentityValue } from \"../../../src/shared/assistant-identity-values.js\";\n\nconst MAX_ASSISTANT_NAME = 50;\nconst MAX_ASSISTANT_AVATAR = 200;\n\nexport const DEFAULT_ASSISTANT_NAME = \"Assistant\";\nexport const DEFAULT_ASSISTANT_AVATAR = \"A\";\n\nexport type AssistantIdentity = {\n agentId?: string | null;\n name: string;\n avatar: string | null;\n};\n\nexport function normalizeAssistantIdentity(\n input?: Partial<AssistantIdentity> | null,\n): AssistantIdentity {\n const name = coerceIdentityValue(input?.name, MAX_ASSISTANT_NAME) ?? DEFAULT_ASSISTANT_NAME;\n const avatar = coerceIdentityValue(input?.avatar ?? undefined, MAX_ASSISTANT_AVATAR) ?? null;\n const agentId =\n typeof input?.agentId === \"string\" && input.agentId.trim() ? input.agentId.trim() : null;\n return { agentId, name, avatar };\n}\n","import { normalizeAssistantIdentity } from \"../assistant-identity.ts\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\n\nexport type AssistantIdentityState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionKey: string;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n};\n\nexport async function loadAssistantIdentity(\n state: AssistantIdentityState,\n opts?: { sessionKey?: string },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n const sessionKey = opts?.sessionKey?.trim() || state.sessionKey.trim();\n const params = sessionKey ? { sessionKey } : {};\n try {\n const res = await state.client.request(\"agent.identity.get\", params);\n if (!res) {\n return;\n }\n const normalized = normalizeAssistantIdentity(res);\n state.assistantName = normalized.name;\n state.assistantAvatar = normalized.avatar;\n state.assistantAgentId = normalized.agentId ?? null;\n } catch {\n // Ignore errors; keep last known identity.\n }\n}\n","export type ExecApprovalRequestPayload = {\n command: string;\n cwd?: string | null;\n host?: string | null;\n security?: string | null;\n ask?: string | null;\n agentId?: string | null;\n resolvedPath?: string | null;\n sessionKey?: string | null;\n};\n\nexport type ExecApprovalRequest = {\n id: string;\n request: ExecApprovalRequestPayload;\n createdAtMs: number;\n expiresAtMs: number;\n};\n\nexport type ExecApprovalResolved = {\n id: string;\n decision?: string | null;\n resolvedBy?: string | null;\n ts?: number | null;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function parseExecApprovalRequested(payload: unknown): ExecApprovalRequest | null {\n if (!isRecord(payload)) {\n return null;\n }\n const id = typeof payload.id === \"string\" ? payload.id.trim() : \"\";\n const request = payload.request;\n if (!id || !isRecord(request)) {\n return null;\n }\n const command = typeof request.command === \"string\" ? request.command.trim() : \"\";\n if (!command) {\n return null;\n }\n const createdAtMs = typeof payload.createdAtMs === \"number\" ? payload.createdAtMs : 0;\n const expiresAtMs = typeof payload.expiresAtMs === \"number\" ? payload.expiresAtMs : 0;\n if (!createdAtMs || !expiresAtMs) {\n return null;\n }\n return {\n id,\n request: {\n command,\n cwd: typeof request.cwd === \"string\" ? request.cwd : null,\n host: typeof request.host === \"string\" ? request.host : null,\n security: typeof request.security === \"string\" ? request.security : null,\n ask: typeof request.ask === \"string\" ? request.ask : null,\n agentId: typeof request.agentId === \"string\" ? request.agentId : null,\n resolvedPath: typeof request.resolvedPath === \"string\" ? request.resolvedPath : null,\n sessionKey: typeof request.sessionKey === \"string\" ? request.sessionKey : null,\n },\n createdAtMs,\n expiresAtMs,\n };\n}\n\nexport function parseExecApprovalResolved(payload: unknown): ExecApprovalResolved | null {\n if (!isRecord(payload)) {\n return null;\n }\n const id = typeof payload.id === \"string\" ? payload.id.trim() : \"\";\n if (!id) {\n return null;\n }\n return {\n id,\n decision: typeof payload.decision === \"string\" ? payload.decision : null,\n resolvedBy: typeof payload.resolvedBy === \"string\" ? payload.resolvedBy : null,\n ts: typeof payload.ts === \"number\" ? payload.ts : null,\n };\n}\n\nexport function pruneExecApprovalQueue(queue: ExecApprovalRequest[]): ExecApprovalRequest[] {\n const now = Date.now();\n return queue.filter((entry) => entry.expiresAtMs > now);\n}\n\nexport function addExecApproval(\n queue: ExecApprovalRequest[],\n entry: ExecApprovalRequest,\n): ExecApprovalRequest[] {\n const next = pruneExecApprovalQueue(queue).filter((item) => item.id !== entry.id);\n next.push(entry);\n return next;\n}\n\nexport function removeExecApproval(\n queue: ExecApprovalRequest[],\n id: string,\n): ExecApprovalRequest[] {\n return pruneExecApprovalQueue(queue).filter((entry) => entry.id !== id);\n}\n","import {\n GATEWAY_EVENT_UPDATE_AVAILABLE,\n type GatewayUpdateAvailableEventPayload,\n} from \"../../../src/gateway/events.js\";\nimport { CHAT_SESSIONS_ACTIVE_MINUTES, flushChatQueueForEvent } from \"./app-chat.ts\";\nimport type { EventLogEntry } from \"./app-events.ts\";\nimport {\n applySettings,\n loadCron,\n refreshActiveTab,\n setLastActiveSessionKey,\n} from \"./app-settings.ts\";\nimport { handleAgentEvent, resetToolStream, type AgentEventPayload } from \"./app-tool-stream.ts\";\nimport type { OpenClawApp } from \"./app.ts\";\nimport { shouldReloadHistoryForFinalEvent } from \"./chat-event-reload.ts\";\nimport { loadAgents, loadToolsCatalog } from \"./controllers/agents.ts\";\nimport { loadAssistantIdentity } from \"./controllers/assistant-identity.ts\";\nimport { loadChatHistory } from \"./controllers/chat.ts\";\nimport { handleChatEvent, type ChatEventPayload } from \"./controllers/chat.ts\";\nimport { loadDevices } from \"./controllers/devices.ts\";\nimport { handleDreamsUpdate, type DreamsHost } from \"./controllers/dreams.ts\";\nimport type { ExecApprovalRequest } from \"./controllers/exec-approval.ts\";\nimport {\n addExecApproval,\n parseExecApprovalRequested,\n parseExecApprovalResolved,\n removeExecApproval,\n} from \"./controllers/exec-approval.ts\";\nimport { loadNodes } from \"./controllers/nodes.ts\";\nimport {\n loadRecoverableRuns,\n loadSessionRuns,\n loadSessions,\n updateRecentlyCompletedRuns,\n} from \"./controllers/sessions.ts\";\nimport type { TalkController, TalkRealtimeRelayEvent } from \"./controllers/talk.ts\";\nimport {\n resolveGatewayErrorDetailCode,\n type GatewayEventFrame,\n type GatewayHelloOk,\n} from \"./gateway.ts\";\nimport { GatewayBrowserClient } from \"./gateway.ts\";\nimport type { Tab } from \"./navigation.ts\";\nimport type { UiSettings } from \"./storage.ts\";\nimport type { SessionRunsResult } from \"./types.ts\";\nimport type {\n AgentsListResult,\n PresenceEntry,\n HealthSnapshot,\n StatusSummary,\n UpdateAvailable,\n} from \"./types.ts\";\n\ntype GatewayHost = {\n settings: UiSettings;\n password: string;\n clientInstanceId: string;\n client: GatewayBrowserClient | null;\n connected: boolean;\n hello: GatewayHelloOk | null;\n lastError: string | null;\n lastErrorCode: string | null;\n onboarding?: boolean;\n eventLogBuffer: EventLogEntry[];\n eventLog: EventLogEntry[];\n tab: Tab;\n presenceEntries: PresenceEntry[];\n presenceError: string | null;\n presenceStatus: StatusSummary | null;\n agentsLoading: boolean;\n agentsList: AgentsListResult | null;\n agentsError: string | null;\n toolsCatalogLoading: boolean;\n toolsCatalogError: string | null;\n toolsCatalogResult: import(\"./types.ts\").ToolsCatalogResult | null;\n debugHealth: HealthSnapshot | null;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n sessionKey: string;\n chatRunId: string | null;\n refreshSessionsAfterChat: Set<string>;\n execApprovalQueue: ExecApprovalRequest[];\n execApprovalError: string | null;\n updateAvailable: UpdateAvailable | null;\n talkController: TalkController;\n};\n\nexport function createGatewayRequester(host: { client: GatewayBrowserClient | null }) {\n return <T>(method: string, params?: unknown): Promise<T> => {\n const client = host.client;\n if (!client) {\n return Promise.reject(new Error(\"Gateway is not connected\"));\n }\n return client.request<T>(method, params);\n };\n}\n\ntype SessionDefaultsSnapshot = {\n defaultAgentId?: string;\n mainKey?: string;\n mainSessionKey?: string;\n scope?: string;\n};\n\nfunction normalizeSessionKeyForDefaults(\n value: string | undefined,\n defaults: SessionDefaultsSnapshot,\n): string {\n const raw = (value ?? \"\").trim();\n const mainSessionKey = defaults.mainSessionKey?.trim();\n if (!mainSessionKey) {\n return raw;\n }\n if (!raw) {\n return mainSessionKey;\n }\n const mainKey = defaults.mainKey?.trim() || \"main\";\n const defaultAgentId = defaults.defaultAgentId?.trim();\n const isAlias =\n raw === \"main\" ||\n raw === mainKey ||\n (defaultAgentId &&\n (raw === `agent:${defaultAgentId}:main` || raw === `agent:${defaultAgentId}:${mainKey}`));\n return isAlias ? mainSessionKey : raw;\n}\n\nfunction applySessionDefaults(host: GatewayHost, defaults?: SessionDefaultsSnapshot) {\n if (!defaults?.mainSessionKey) {\n return;\n }\n const resolvedSessionKey = normalizeSessionKeyForDefaults(host.sessionKey, defaults);\n const resolvedSettingsSessionKey = normalizeSessionKeyForDefaults(\n host.settings.sessionKey,\n defaults,\n );\n const resolvedLastActiveSessionKey = normalizeSessionKeyForDefaults(\n host.settings.lastActiveSessionKey,\n defaults,\n );\n const nextSessionKey = resolvedSessionKey || resolvedSettingsSessionKey || host.sessionKey;\n const nextSettings = {\n ...host.settings,\n sessionKey: resolvedSettingsSessionKey || nextSessionKey,\n lastActiveSessionKey: resolvedLastActiveSessionKey || nextSessionKey,\n };\n const shouldUpdateSettings =\n nextSettings.sessionKey !== host.settings.sessionKey ||\n nextSettings.lastActiveSessionKey !== host.settings.lastActiveSessionKey;\n if (nextSessionKey !== host.sessionKey) {\n host.sessionKey = nextSessionKey;\n }\n if (shouldUpdateSettings) {\n applySettings(host as unknown as Parameters<typeof applySettings>[0], nextSettings);\n }\n}\n\nexport function connectGateway(host: GatewayHost) {\n host.lastError = null;\n host.lastErrorCode = null;\n host.hello = null;\n host.connected = false;\n host.execApprovalQueue = [];\n host.execApprovalError = null;\n\n const previousClient = host.client;\n const client = new GatewayBrowserClient({\n url: host.settings.gatewayUrl,\n token: host.settings.token.trim() ? host.settings.token : undefined,\n password: host.password.trim() ? host.password : undefined,\n clientName: \"openclaw-control-ui\",\n mode: \"webchat\",\n instanceId: host.clientInstanceId,\n onHello: (hello) => {\n if (host.client !== client) {\n return;\n }\n try {\n const availability = host.talkController.loadAvailability();\n void availability.catch(() => undefined);\n } catch {\n // A synchronous refresh failure must not prevent the connection from becoming ready.\n }\n void host.talkController.reconnectIfIntended().catch(() => undefined);\n host.connected = true;\n host.lastError = null;\n host.lastErrorCode = null;\n host.hello = hello;\n applySnapshot(host, hello);\n // Reset orphaned chat run state from before disconnect.\n // Any in-flight run's final event was lost during the disconnect window.\n host.chatRunId = null;\n (host as unknown as { chatStream: string | null }).chatStream = null;\n (host as unknown as { chatStreamStartedAt: number | null }).chatStreamStartedAt = null;\n resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);\n void loadAssistantIdentity(host as unknown as OpenClawApp);\n void loadAgents(host as unknown as OpenClawApp);\n void loadToolsCatalog(host as unknown as OpenClawApp);\n void loadNodes(host as unknown as OpenClawApp, { quiet: true });\n void loadDevices(host as unknown as OpenClawApp, { quiet: true });\n void loadSessionRuns(host as unknown as OpenClawApp);\n void loadRecoverableRuns(host as unknown as OpenClawApp);\n void refreshActiveTab(host as unknown as Parameters<typeof refreshActiveTab>[0]);\n },\n onClose: ({ code, reason, error }) => {\n if (host.client !== client) {\n return;\n }\n host.talkController.handleGatewayClose();\n host.connected = false;\n // Code 1012 = Service Restart (expected during config saves, don't show as error)\n host.lastErrorCode =\n resolveGatewayErrorDetailCode(error) ??\n (typeof error?.code === \"string\" ? error.code : null);\n if (code !== 1012) {\n if (error?.message) {\n host.lastError = error.message;\n return;\n }\n host.lastError = `disconnected (${code}): ${reason || \"no reason\"}`;\n } else {\n host.lastError = null;\n host.lastErrorCode = null;\n }\n },\n onEvent: (evt) => {\n if (host.client !== client) {\n return;\n }\n handleGatewayEvent(host, evt);\n },\n onGap: ({ expected, received }) => {\n if (host.client !== client) {\n return;\n }\n host.lastError = `event gap detected (expected seq ${expected}, got ${received}); refresh recommended`;\n host.lastErrorCode = null;\n },\n });\n host.client = client;\n previousClient?.stop();\n client.start();\n}\n\nexport function handleGatewayEvent(host: GatewayHost, evt: GatewayEventFrame) {\n try {\n handleGatewayEventUnsafe(host, evt);\n } catch (err) {\n console.error(\"[gateway] handleGatewayEvent error:\", evt.event, err);\n }\n}\n\nfunction handleTerminalChatEvent(\n host: GatewayHost,\n payload: ChatEventPayload | undefined,\n state: ReturnType<typeof handleChatEvent>,\n) {\n if (state !== \"final\" && state !== \"error\" && state !== \"aborted\") {\n return;\n }\n resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);\n void flushChatQueueForEvent(host as unknown as Parameters<typeof flushChatQueueForEvent>[0]);\n const runId = payload?.runId;\n if (!runId || !host.refreshSessionsAfterChat.has(runId)) {\n return;\n }\n host.refreshSessionsAfterChat.delete(runId);\n if (state === \"final\") {\n void loadSessions(host as unknown as OpenClawApp, {\n activeMinutes: CHAT_SESSIONS_ACTIVE_MINUTES,\n });\n }\n}\n\nfunction handleChatGatewayEvent(host: GatewayHost, payload: ChatEventPayload | undefined) {\n if (payload?.sessionKey) {\n setLastActiveSessionKey(\n host as unknown as Parameters<typeof setLastActiveSessionKey>[0],\n payload.sessionKey,\n );\n }\n const state = handleChatEvent(host as unknown as OpenClawApp, payload);\n handleTerminalChatEvent(host, payload, state);\n if (state === \"final\" && shouldReloadHistoryForFinalEvent(payload)) {\n void loadChatHistory(host as unknown as OpenClawApp);\n }\n}\n\nfunction handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {\n const talkRelayType =\n evt.event === \"talk.realtime.relay\" && typeof evt.payload === \"object\" && evt.payload !== null\n ? (evt.payload as { type?: unknown }).type\n : undefined;\n const bufferedPayload =\n evt.event === \"talk.realtime.relay\"\n ? { type: typeof talkRelayType === \"string\" ? talkRelayType : undefined }\n : evt.payload;\n host.eventLogBuffer = [\n { ts: Date.now(), event: evt.event, payload: bufferedPayload },\n ...host.eventLogBuffer,\n ].slice(0, 250);\n if (host.tab === \"debug\") {\n host.eventLog = host.eventLogBuffer;\n }\n\n if (evt.event === \"talk.realtime.relay\") {\n host.talkController.handleRelayEvent(evt.payload as TalkRealtimeRelayEvent);\n return;\n }\n\n if (evt.event === \"agent\") {\n if (host.onboarding) {\n return;\n }\n handleAgentEvent(\n host as unknown as Parameters<typeof handleAgentEvent>[0],\n evt.payload as AgentEventPayload | undefined,\n );\n return;\n }\n\n if (evt.event === \"chat\") {\n handleChatGatewayEvent(host, evt.payload as ChatEventPayload | undefined);\n return;\n }\n\n if (evt.event === \"presence\") {\n const payload = evt.payload as { presence?: PresenceEntry[] } | undefined;\n if (payload?.presence && Array.isArray(payload.presence)) {\n host.presenceEntries = payload.presence;\n host.presenceError = null;\n host.presenceStatus = null;\n }\n return;\n }\n\n if (evt.event === \"cron\" && host.tab === \"cron\") {\n void loadCron(host as unknown as Parameters<typeof loadCron>[0]);\n }\n\n if (evt.event === \"dreams.update\") {\n handleDreamsUpdate(host as unknown as DreamsHost);\n return;\n }\n\n if (evt.event === \"device.pair.requested\" || evt.event === \"device.pair.resolved\") {\n void loadDevices(host as unknown as OpenClawApp, { quiet: true });\n }\n\n if (evt.event === \"exec.approval.requested\") {\n const entry = parseExecApprovalRequested(evt.payload);\n if (entry) {\n host.execApprovalQueue = addExecApproval(host.execApprovalQueue, entry);\n host.execApprovalError = null;\n const delay = Math.max(0, entry.expiresAtMs - Date.now() + 500);\n window.setTimeout(() => {\n host.execApprovalQueue = removeExecApproval(host.execApprovalQueue, entry.id);\n }, delay);\n }\n return;\n }\n\n if (evt.event === \"exec.approval.resolved\") {\n const resolved = parseExecApprovalResolved(evt.payload);\n if (resolved) {\n host.execApprovalQueue = removeExecApproval(host.execApprovalQueue, resolved.id);\n }\n return;\n }\n\n if (evt.event === \"sessions.runsUpdate\") {\n const payload = evt.payload as SessionRunsResult | undefined;\n if (payload) {\n const app = host as unknown as OpenClawApp;\n const nowTs = Date.now();\n app.recentlyCompletedRuns = updateRecentlyCompletedRuns(\n app.sessionRunsPrevKeys,\n payload.runs,\n app.recentlyCompletedRuns,\n nowTs,\n );\n app.sessionRunsPrevKeys = new Set(payload.runs.map((r) => r.key));\n app.sessionRunsResult = payload;\n app.sessionRunsFetchedAt = nowTs;\n app.sessionRunsError = null;\n }\n return;\n }\n\n if (evt.event === GATEWAY_EVENT_UPDATE_AVAILABLE) {\n const payload = evt.payload as GatewayUpdateAvailableEventPayload | undefined;\n host.updateAvailable = payload?.updateAvailable ?? null;\n }\n}\n\nexport function applySnapshot(host: GatewayHost, hello: GatewayHelloOk) {\n const snapshot = hello.snapshot as\n | {\n presence?: PresenceEntry[];\n health?: HealthSnapshot;\n sessionDefaults?: SessionDefaultsSnapshot;\n updateAvailable?: UpdateAvailable;\n }\n | undefined;\n if (snapshot?.presence && Array.isArray(snapshot.presence)) {\n host.presenceEntries = snapshot.presence;\n }\n if (snapshot?.health) {\n host.debugHealth = snapshot.health;\n }\n if (snapshot?.sessionDefaults) {\n applySessionDefaults(host, snapshot.sessionDefaults);\n }\n host.updateAvailable = snapshot?.updateAvailable ?? null;\n}\n","export const CONTROL_UI_BOOTSTRAP_CONFIG_PATH = \"/__openclaw/control-ui-config.json\";\n\nexport type ControlUiBootstrapConfig = {\n basePath: string;\n /**\n * Path of the default (v2) console, with a trailing slash, e.g. \"/\" at the root or\n * \"/v2/control/\". `null` when the v2 console is disabled, so the classic UI can link to it.\n */\n consolePath: string | null;\n assistantName: string;\n assistantAvatar: string;\n assistantAgentId: string;\n};\n","import {\n CONTROL_UI_BOOTSTRAP_CONFIG_PATH,\n type ControlUiBootstrapConfig,\n} from \"../../../../src/gateway/control-ui-contract.js\";\nimport { normalizeAssistantIdentity } from \"../assistant-identity.ts\";\nimport { normalizeBasePath } from \"../navigation.ts\";\n\nexport type ControlUiBootstrapState = {\n basePath: string;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n consolePath: string | null;\n};\n\nexport async function loadControlUiBootstrapConfig(state: ControlUiBootstrapState) {\n if (typeof window === \"undefined\") {\n return;\n }\n if (typeof fetch !== \"function\") {\n return;\n }\n\n const basePath = normalizeBasePath(state.basePath ?? \"\");\n const url = basePath\n ? `${basePath}${CONTROL_UI_BOOTSTRAP_CONFIG_PATH}`\n : CONTROL_UI_BOOTSTRAP_CONFIG_PATH;\n\n try {\n const res = await fetch(url, {\n method: \"GET\",\n headers: { Accept: \"application/json\" },\n credentials: \"same-origin\",\n });\n if (!res.ok) {\n return;\n }\n const parsed = (await res.json()) as ControlUiBootstrapConfig;\n const normalized = normalizeAssistantIdentity({\n agentId: parsed.assistantAgentId ?? null,\n name: parsed.assistantName,\n avatar: parsed.assistantAvatar ?? null,\n });\n state.assistantName = normalized.name;\n state.assistantAvatar = normalized.avatar;\n state.assistantAgentId = normalized.agentId ?? null;\n state.consolePath = typeof parsed.consolePath === \"string\" ? parsed.consolePath : null;\n } catch {\n // Ignore bootstrap failures; UI will update identity after connecting.\n }\n}\n","import { connectGateway } from \"./app-gateway.ts\";\nimport {\n startLogsPolling,\n startNodesPolling,\n stopLogsPolling,\n stopNodesPolling,\n startDebugPolling,\n stopDebugPolling,\n startSessionRunsPolling,\n stopSessionRunsPolling,\n startSessionRunsTick,\n stopSessionRunsTick,\n startDreamsPolling,\n stopDreamsPolling,\n} from \"./app-polling.ts\";\nimport { observeTopbar, scheduleChatScroll, scheduleLogsScroll } from \"./app-scroll.ts\";\nimport {\n applySettingsFromUrl,\n attachThemeListener,\n detachThemeListener,\n inferBasePath,\n syncTabWithLocation,\n syncThemeWithSettings,\n} from \"./app-settings.ts\";\nimport { loadControlUiBootstrapConfig } from \"./controllers/control-ui-bootstrap.ts\";\nimport { handleDreamsVisibilityChange, type DreamsHost } from \"./controllers/dreams.ts\";\nimport type { TalkController } from \"./controllers/talk.ts\";\nimport type { Tab } from \"./navigation.ts\";\n\ntype LifecycleHost = {\n basePath: string;\n client?: { stop: () => void } | null;\n connected?: boolean;\n tab: Tab;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n consolePath: string | null;\n chatHasAutoScrolled: boolean;\n chatManualRefreshInFlight: boolean;\n chatLoading: boolean;\n chatMessages: unknown[];\n chatToolMessages: unknown[];\n chatStream: string;\n logsAutoFollow: boolean;\n logsAtBottom: boolean;\n logsEntries: unknown[];\n popStateHandler: () => void;\n visibilityHandler: () => void;\n topbarObserver: ResizeObserver | null;\n talkController: Pick<TalkController, \"stop\">;\n};\n\nexport function handleConnected(host: LifecycleHost) {\n host.basePath = inferBasePath();\n void loadControlUiBootstrapConfig(host);\n applySettingsFromUrl(host as unknown as Parameters<typeof applySettingsFromUrl>[0]);\n syncTabWithLocation(host as unknown as Parameters<typeof syncTabWithLocation>[0], true);\n syncThemeWithSettings(host as unknown as Parameters<typeof syncThemeWithSettings>[0]);\n attachThemeListener(host as unknown as Parameters<typeof attachThemeListener>[0]);\n window.addEventListener(\"popstate\", host.popStateHandler);\n if (typeof document !== \"undefined\") {\n document.addEventListener(\"visibilitychange\", host.visibilityHandler);\n }\n connectGateway(host as unknown as Parameters<typeof connectGateway>[0]);\n startNodesPolling(host as unknown as Parameters<typeof startNodesPolling>[0]);\n startSessionRunsPolling(host as unknown as Parameters<typeof startSessionRunsPolling>[0]);\n startSessionRunsTick(host as unknown as Parameters<typeof startSessionRunsTick>[0]);\n startDreamsPolling(host as unknown as Parameters<typeof startDreamsPolling>[0]);\n if (host.tab === \"logs\") {\n startLogsPolling(host as unknown as Parameters<typeof startLogsPolling>[0]);\n }\n if (host.tab === \"debug\") {\n startDebugPolling(host as unknown as Parameters<typeof startDebugPolling>[0]);\n }\n}\n\nexport function handleVisibilityChange(host: LifecycleHost) {\n handleDreamsVisibilityChange(host as unknown as DreamsHost);\n}\n\nexport function handleFirstUpdated(host: LifecycleHost) {\n observeTopbar(host as unknown as Parameters<typeof observeTopbar>[0]);\n}\n\nexport function handleDisconnected(host: LifecycleHost) {\n try {\n host.talkController.stop().catch(() => undefined);\n } catch {\n // A misbehaving stop() may throw synchronously instead of rejecting; the\n // rest of teardown must still run.\n }\n window.removeEventListener(\"popstate\", host.popStateHandler);\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", host.visibilityHandler);\n }\n stopNodesPolling(host as unknown as Parameters<typeof stopNodesPolling>[0]);\n stopLogsPolling(host as unknown as Parameters<typeof stopLogsPolling>[0]);\n stopDebugPolling(host as unknown as Parameters<typeof stopDebugPolling>[0]);\n stopSessionRunsPolling(host as unknown as Parameters<typeof stopSessionRunsPolling>[0]);\n stopSessionRunsTick(host as unknown as Parameters<typeof stopSessionRunsTick>[0]);\n stopDreamsPolling(host as unknown as Parameters<typeof stopDreamsPolling>[0]);\n host.client?.stop();\n host.client = null;\n host.connected = false;\n detachThemeListener(host as unknown as Parameters<typeof detachThemeListener>[0]);\n host.topbarObserver?.disconnect();\n host.topbarObserver = null;\n}\n\nexport function handleUpdated(host: LifecycleHost, changed: Map<PropertyKey, unknown>) {\n if (host.tab === \"chat\" && host.chatManualRefreshInFlight) {\n return;\n }\n if (\n host.tab === \"chat\" &&\n (changed.has(\"chatMessages\") ||\n changed.has(\"chatToolMessages\") ||\n changed.has(\"chatStream\") ||\n changed.has(\"chatLoading\") ||\n changed.has(\"tab\"))\n ) {\n const forcedByTab = changed.has(\"tab\");\n const forcedByLoad =\n changed.has(\"chatLoading\") && changed.get(\"chatLoading\") === true && !host.chatLoading;\n scheduleChatScroll(\n host as unknown as Parameters<typeof scheduleChatScroll>[0],\n forcedByTab || forcedByLoad || !host.chatHasAutoScrolled,\n );\n }\n if (\n host.tab === \"logs\" &&\n (changed.has(\"logsEntries\") || changed.has(\"logsAutoFollow\") || changed.has(\"tab\"))\n ) {\n if (host.logsAutoFollow && host.logsAtBottom) {\n scheduleLogsScroll(\n host as unknown as Parameters<typeof scheduleLogsScroll>[0],\n changed.has(\"tab\") || changed.has(\"logsAutoFollow\"),\n );\n }\n }\n}\n","import { html, type TemplateResult } from \"lit\";\n\nexport type LazyViewHost = {\n requestUpdate: () => void;\n};\n\nexport function createLazyView<TModule, TProps>(\n loadModule: () => Promise<TModule>,\n selectRenderer: (module: TModule) => (props: TProps) => TemplateResult,\n loadingLabel: string,\n) {\n let moduleValue: TModule | null = null;\n let loadPromise: Promise<TModule> | null = null;\n let loadError: string | null = null;\n // The chunk load is shared by every host that renders this view, so every host\n // that is currently showing the placeholder has to be re-rendered when it\n // settles. Notifying only the host that happened to start the load leaves any\n // later host stuck on \"Loading ...\" forever, because nothing else asks it to\n // update.\n const pendingHosts = new Set<LazyViewHost>();\n\n const notifyPendingHosts = () => {\n const hosts = [...pendingHosts];\n pendingHosts.clear();\n for (const pending of hosts) {\n pending.requestUpdate();\n }\n };\n\n return {\n render(host: LazyViewHost, props: TProps): TemplateResult {\n if (moduleValue) {\n return selectRenderer(moduleValue)(props);\n }\n if (loadError) {\n return html`<div class=\"callout danger\">${loadError}</div>`;\n }\n pendingHosts.add(host);\n loadPromise ??= loadModule()\n .then((loaded) => {\n moduleValue = loaded;\n notifyPendingHosts();\n return loaded;\n })\n .catch((error: unknown) => {\n loadError = error instanceof Error ? error.message : \"View failed to load\";\n notifyPendingHosts();\n throw error;\n });\n void loadPromise.catch(() => undefined);\n return html`<div class=\"muted\">${loadingLabel}</div>`;\n },\n };\n}\n","import { createLazyView } from \"./lazy-view.ts\";\n\nexport const consoleViews = {\n agents: createLazyView(\n () => import(\"./views/agents.ts\"),\n (module) => module.renderAgents,\n \"Loading agents...\",\n ),\n channels: createLazyView(\n () => import(\"./views/channels.ts\"),\n (module) => module.renderChannels,\n \"Loading channels...\",\n ),\n chat: createLazyView(\n () => import(\"./views/chat.ts\"),\n (module) => module.renderChat,\n \"Loading Chat...\",\n ),\n config: createLazyView(\n () => import(\"./views/config.ts\"),\n (module) => module.renderConfig,\n \"Loading config...\",\n ),\n cron: createLazyView(\n () => import(\"./views/cron.ts\"),\n (module) => module.renderCron,\n \"Loading cron...\",\n ),\n debug: createLazyView(\n () => import(\"./views/debug.ts\"),\n (module) => module.renderDebug,\n \"Loading debug...\",\n ),\n instances: createLazyView(\n () => import(\"./views/instances.ts\"),\n (module) => module.renderInstances,\n \"Loading instances...\",\n ),\n logs: createLazyView(\n () => import(\"./views/logs.ts\"),\n (module) => module.renderLogs,\n \"Loading logs...\",\n ),\n dreams: createLazyView(\n () => import(\"./views/dreams.ts\"),\n (module) => module.renderDreams,\n \"Loading dreams...\",\n ),\n learning: createLazyView(\n () => import(\"./views/learning.ts\"),\n (module) => module.renderLearning,\n \"Loading learning...\",\n ),\n nodes: createLazyView(\n () => import(\"./views/nodes.ts\"),\n (module) => module.renderNodes,\n \"Loading nodes...\",\n ),\n overview: createLazyView(\n () => import(\"./views/overview.ts\"),\n (module) => module.renderOverview,\n \"Loading overview...\",\n ),\n sessions: createLazyView(\n () => import(\"./views/sessions.ts\"),\n (module) => module.renderSessions,\n \"Loading sessions...\",\n ),\n skills: createLazyView(\n () => import(\"./views/skills.ts\"),\n (module) => module.renderSkills,\n \"Loading skills...\",\n ),\n talk: createLazyView(\n () => import(\"./views/talk.ts\"),\n (module) => module.renderTalk,\n \"Loading Talk...\",\n ),\n usage: createLazyView(\n () => import(\"./views/usage.ts\"),\n (module) => module.renderUsage,\n \"Loading usage...\",\n ),\n};\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { SessionsUsageResult, CostUsageSummary, SessionUsageTimeSeries } from \"../types.ts\";\nimport type { SessionLogEntry } from \"../views/usage.ts\";\n\nexport type UsageState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n usageLoading: boolean;\n usageResult: SessionsUsageResult | null;\n usageCostSummary: CostUsageSummary | null;\n usageError: string | null;\n usageStartDate: string;\n usageEndDate: string;\n usageSelectedSessions: string[];\n usageSelectedDays: string[];\n usageTimeSeries: SessionUsageTimeSeries | null;\n usageTimeSeriesLoading: boolean;\n usageTimeSeriesCursorStart: number | null;\n usageTimeSeriesCursorEnd: number | null;\n usageSessionLogs: SessionLogEntry[] | null;\n usageSessionLogsLoading: boolean;\n usageTimeZone: \"local\" | \"utc\";\n settings?: { gatewayUrl?: string };\n};\n\ntype DateInterpretationMode = \"utc\" | \"gateway\" | \"specific\";\n\ntype UsageDateInterpretationParams = {\n mode: DateInterpretationMode;\n utcOffset?: string;\n};\n\nconst LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY = \"openclaw.control.usage.date-params.v1\";\nconst LEGACY_USAGE_DATE_PARAMS_DEFAULT_GATEWAY_KEY = \"__default__\";\nconst LEGACY_USAGE_DATE_PARAMS_MODE_RE = /unexpected property ['\"]mode['\"]/i;\nconst LEGACY_USAGE_DATE_PARAMS_OFFSET_RE = /unexpected property ['\"]utcoffset['\"]/i;\nconst LEGACY_USAGE_DATE_PARAMS_INVALID_RE = /invalid sessions\\.usage params/i;\n\nlet legacyUsageDateParamsCache: Set<string> | null = null;\n\nfunction getLocalStorage(): Storage | null {\n // Support browser runtime and node tests (when localStorage is stubbed globally).\n if (typeof window !== \"undefined\" && window.localStorage) {\n return window.localStorage;\n }\n if (typeof localStorage !== \"undefined\") {\n return localStorage;\n }\n return null;\n}\n\nfunction loadLegacyUsageDateParamsCache(): Set<string> {\n const storage = getLocalStorage();\n if (!storage) {\n return new Set<string>();\n }\n try {\n const raw = storage.getItem(LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY);\n if (!raw) {\n return new Set<string>();\n }\n const parsed = JSON.parse(raw) as { unsupportedGatewayKeys?: unknown } | null;\n if (!parsed || !Array.isArray(parsed.unsupportedGatewayKeys)) {\n return new Set<string>();\n }\n return new Set(\n parsed.unsupportedGatewayKeys\n .filter((entry): entry is string => typeof entry === \"string\")\n .map((entry) => entry.trim())\n .filter(Boolean),\n );\n } catch {\n return new Set<string>();\n }\n}\n\nfunction persistLegacyUsageDateParamsCache(cache: Set<string>) {\n const storage = getLocalStorage();\n if (!storage) {\n return;\n }\n try {\n storage.setItem(\n LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY,\n JSON.stringify({ unsupportedGatewayKeys: Array.from(cache) }),\n );\n } catch {\n // ignore quota/private-mode failures\n }\n}\n\nfunction getLegacyUsageDateParamsCache(): Set<string> {\n if (!legacyUsageDateParamsCache) {\n legacyUsageDateParamsCache = loadLegacyUsageDateParamsCache();\n }\n return legacyUsageDateParamsCache;\n}\n\nfunction normalizeGatewayCompatibilityKey(gatewayUrl?: string): string {\n const trimmed = gatewayUrl?.trim();\n if (!trimmed) {\n return LEGACY_USAGE_DATE_PARAMS_DEFAULT_GATEWAY_KEY;\n }\n try {\n const parsed = new URL(trimmed);\n const pathname = parsed.pathname === \"/\" ? \"\" : parsed.pathname;\n return `${parsed.protocol}//${parsed.host}${pathname}`.toLowerCase();\n } catch {\n return trimmed.toLowerCase();\n }\n}\n\nfunction resolveGatewayCompatibilityKey(state: UsageState): string {\n return normalizeGatewayCompatibilityKey(state.settings?.gatewayUrl);\n}\n\nfunction shouldSendLegacyDateInterpretation(state: UsageState): boolean {\n return !getLegacyUsageDateParamsCache().has(resolveGatewayCompatibilityKey(state));\n}\n\nfunction rememberLegacyDateInterpretation(state: UsageState) {\n const cache = getLegacyUsageDateParamsCache();\n cache.add(resolveGatewayCompatibilityKey(state));\n persistLegacyUsageDateParamsCache(cache);\n}\n\nfunction isLegacyDateInterpretationUnsupportedError(err: unknown): boolean {\n const message = toErrorMessage(err);\n return (\n LEGACY_USAGE_DATE_PARAMS_INVALID_RE.test(message) &&\n (LEGACY_USAGE_DATE_PARAMS_MODE_RE.test(message) ||\n LEGACY_USAGE_DATE_PARAMS_OFFSET_RE.test(message))\n );\n}\n\nconst formatUtcOffset = (timezoneOffsetMinutes: number): string => {\n // `Date#getTimezoneOffset()` is minutes to add to local time to reach UTC.\n // Convert to UTC±H[:MM] where positive means east of UTC.\n const offsetFromUtcMinutes = -timezoneOffsetMinutes;\n const sign = offsetFromUtcMinutes >= 0 ? \"+\" : \"-\";\n const absMinutes = Math.abs(offsetFromUtcMinutes);\n const hours = Math.floor(absMinutes / 60);\n const minutes = absMinutes % 60;\n return minutes === 0\n ? `UTC${sign}${hours}`\n : `UTC${sign}${hours}:${minutes.toString().padStart(2, \"0\")}`;\n};\n\nconst buildDateInterpretationParams = (\n timeZone: \"local\" | \"utc\",\n includeDateInterpretation: boolean,\n): UsageDateInterpretationParams | undefined => {\n if (!includeDateInterpretation) {\n return undefined;\n }\n if (timeZone === \"utc\") {\n return { mode: \"utc\" };\n }\n return {\n mode: \"specific\",\n utcOffset: formatUtcOffset(new Date().getTimezoneOffset()),\n };\n};\n\nfunction toErrorMessage(err: unknown): string {\n if (typeof err === \"string\") {\n return err;\n }\n if (err instanceof Error && typeof err.message === \"string\" && err.message.trim()) {\n return err.message;\n }\n if (err && typeof err === \"object\") {\n try {\n const serialized = JSON.stringify(err);\n if (serialized) {\n return serialized;\n }\n } catch {\n // ignore\n }\n }\n return \"request failed\";\n}\n\nexport async function loadUsage(\n state: UsageState,\n overrides?: {\n startDate?: string;\n endDate?: string;\n },\n) {\n // Capture client for TS18047 work around on it being possibly null\n const client = state.client;\n if (!client || !state.connected) {\n return;\n }\n if (state.usageLoading) {\n return;\n }\n state.usageLoading = true;\n state.usageError = null;\n try {\n const startDate = overrides?.startDate ?? state.usageStartDate;\n const endDate = overrides?.endDate ?? state.usageEndDate;\n const runUsageRequests = async (includeDateInterpretation: boolean) => {\n const dateInterpretation = buildDateInterpretationParams(\n state.usageTimeZone,\n includeDateInterpretation,\n );\n return await Promise.all([\n client.request(\"sessions.usage\", {\n startDate,\n endDate,\n ...dateInterpretation,\n limit: 1000, // Cap at 1000 sessions\n includeContextWeight: true,\n }),\n client.request(\"usage.cost\", {\n startDate,\n endDate,\n ...dateInterpretation,\n }),\n ]);\n };\n\n const applyUsageResults = (sessionsRes: unknown, costRes: unknown) => {\n if (sessionsRes) {\n state.usageResult = sessionsRes as SessionsUsageResult;\n }\n if (costRes) {\n state.usageCostSummary = costRes as CostUsageSummary;\n }\n };\n\n const includeDateInterpretation = shouldSendLegacyDateInterpretation(state);\n try {\n const [sessionsRes, costRes] = await runUsageRequests(includeDateInterpretation);\n applyUsageResults(sessionsRes, costRes);\n } catch (err) {\n if (includeDateInterpretation && isLegacyDateInterpretationUnsupportedError(err)) {\n // Older gateways reject `mode`/`utcOffset` in `sessions.usage`.\n // Remember this per gateway and retry once without those fields.\n rememberLegacyDateInterpretation(state);\n const [sessionsRes, costRes] = await runUsageRequests(false);\n applyUsageResults(sessionsRes, costRes);\n } else {\n throw err;\n }\n }\n } catch (err) {\n state.usageError = toErrorMessage(err);\n } finally {\n state.usageLoading = false;\n }\n}\n\nexport const __test = {\n formatUtcOffset,\n buildDateInterpretationParams,\n toErrorMessage,\n isLegacyDateInterpretationUnsupportedError,\n normalizeGatewayCompatibilityKey,\n shouldSendLegacyDateInterpretation,\n rememberLegacyDateInterpretation,\n resetLegacyUsageDateParamsCache: () => {\n legacyUsageDateParamsCache = null;\n },\n};\n\nexport async function loadSessionTimeSeries(state: UsageState, sessionKey: string) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.usageTimeSeriesLoading) {\n return;\n }\n state.usageTimeSeriesLoading = true;\n state.usageTimeSeries = null;\n try {\n const res = await state.client.request(\"sessions.usage.timeseries\", { key: sessionKey });\n if (res) {\n state.usageTimeSeries = res as SessionUsageTimeSeries;\n }\n } catch {\n // Silently fail - time series is optional\n state.usageTimeSeries = null;\n } finally {\n state.usageTimeSeriesLoading = false;\n }\n}\n\nexport async function loadSessionLogs(state: UsageState, sessionKey: string) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.usageSessionLogsLoading) {\n return;\n }\n state.usageSessionLogsLoading = true;\n state.usageSessionLogs = null;\n try {\n const res = await state.client.request(\"sessions.usage.logs\", {\n key: sessionKey,\n limit: 1000,\n });\n if (res && Array.isArray((res as { logs: SessionLogEntry[] }).logs)) {\n state.usageSessionLogs = (res as { logs: SessionLogEntry[] }).logs;\n }\n } catch {\n // Silently fail - logs are optional\n state.usageSessionLogs = null;\n } finally {\n state.usageSessionLogsLoading = false;\n }\n}\n","import { nothing } from \"lit\";\nimport { consoleViews } from \"./app-view-dispatcher.ts\";\nimport type { AppViewState } from \"./app-view-state.ts\";\nimport type { UsageState } from \"./controllers/usage.ts\";\nimport { loadUsage, loadSessionTimeSeries, loadSessionLogs } from \"./controllers/usage.ts\";\n\n// Module-scope debounce for usage date changes (avoids type-unsafe hacks on state object)\nlet usageDateDebounceTimeout: number | null = null;\nconst debouncedLoadUsage = (state: UsageState) => {\n if (usageDateDebounceTimeout) {\n clearTimeout(usageDateDebounceTimeout);\n }\n usageDateDebounceTimeout = window.setTimeout(() => void loadUsage(state), 400);\n};\n\nexport function renderUsageTab(state: AppViewState) {\n if (state.tab !== \"usage\") {\n return nothing;\n }\n\n return consoleViews.usage.render(state, {\n loading: state.usageLoading,\n error: state.usageError,\n startDate: state.usageStartDate,\n endDate: state.usageEndDate,\n sessions: state.usageResult?.sessions ?? [],\n sessionsLimitReached: (state.usageResult?.sessions?.length ?? 0) >= 1000,\n totals: state.usageResult?.totals ?? null,\n aggregates: state.usageResult?.aggregates ?? null,\n costDaily: state.usageCostSummary?.daily ?? [],\n selectedSessions: state.usageSelectedSessions,\n selectedDays: state.usageSelectedDays,\n selectedHours: state.usageSelectedHours,\n chartMode: state.usageChartMode,\n dailyChartMode: state.usageDailyChartMode,\n timeSeriesMode: state.usageTimeSeriesMode,\n timeSeriesBreakdownMode: state.usageTimeSeriesBreakdownMode,\n timeSeries: state.usageTimeSeries,\n timeSeriesLoading: state.usageTimeSeriesLoading,\n timeSeriesCursorStart: state.usageTimeSeriesCursorStart,\n timeSeriesCursorEnd: state.usageTimeSeriesCursorEnd,\n sessionLogs: state.usageSessionLogs,\n sessionLogsLoading: state.usageSessionLogsLoading,\n sessionLogsExpanded: state.usageSessionLogsExpanded,\n logFilterRoles: state.usageLogFilterRoles,\n logFilterTools: state.usageLogFilterTools,\n logFilterHasTools: state.usageLogFilterHasTools,\n logFilterQuery: state.usageLogFilterQuery,\n query: state.usageQuery,\n queryDraft: state.usageQueryDraft,\n sessionSort: state.usageSessionSort,\n sessionSortDir: state.usageSessionSortDir,\n recentSessions: state.usageRecentSessions,\n sessionsTab: state.usageSessionsTab,\n visibleColumns: state.usageVisibleColumns as import(\"./views/usage.ts\").UsageColumnId[],\n timeZone: state.usageTimeZone,\n contextExpanded: state.usageContextExpanded,\n headerPinned: state.usageHeaderPinned,\n onStartDateChange: (date) => {\n state.usageStartDate = date;\n state.usageSelectedDays = [];\n state.usageSelectedHours = [];\n state.usageSelectedSessions = [];\n debouncedLoadUsage(state);\n },\n onEndDateChange: (date) => {\n state.usageEndDate = date;\n state.usageSelectedDays = [];\n state.usageSelectedHours = [];\n state.usageSelectedSessions = [];\n debouncedLoadUsage(state);\n },\n onRefresh: () => loadUsage(state),\n onTimeZoneChange: (zone) => {\n state.usageTimeZone = zone;\n state.usageSelectedDays = [];\n state.usageSelectedHours = [];\n state.usageSelectedSessions = [];\n void loadUsage(state);\n },\n onToggleContextExpanded: () => {\n state.usageContextExpanded = !state.usageContextExpanded;\n },\n onToggleSessionLogsExpanded: () => {\n state.usageSessionLogsExpanded = !state.usageSessionLogsExpanded;\n },\n onLogFilterRolesChange: (next) => {\n state.usageLogFilterRoles = next;\n },\n onLogFilterToolsChange: (next) => {\n state.usageLogFilterTools = next;\n },\n onLogFilterHasToolsChange: (next) => {\n state.usageLogFilterHasTools = next;\n },\n onLogFilterQueryChange: (next) => {\n state.usageLogFilterQuery = next;\n },\n onLogFilterClear: () => {\n state.usageLogFilterRoles = [];\n state.usageLogFilterTools = [];\n state.usageLogFilterHasTools = false;\n state.usageLogFilterQuery = \"\";\n },\n onToggleHeaderPinned: () => {\n state.usageHeaderPinned = !state.usageHeaderPinned;\n },\n onSelectHour: (hour, shiftKey) => {\n if (shiftKey && state.usageSelectedHours.length > 0) {\n const allHours = Array.from({ length: 24 }, (_, i) => i);\n const lastSelected = state.usageSelectedHours[state.usageSelectedHours.length - 1];\n const lastIdx = allHours.indexOf(lastSelected);\n const thisIdx = allHours.indexOf(hour);\n if (lastIdx !== -1 && thisIdx !== -1) {\n const [start, end] = lastIdx < thisIdx ? [lastIdx, thisIdx] : [thisIdx, lastIdx];\n const range = allHours.slice(start, end + 1);\n state.usageSelectedHours = [...new Set([...state.usageSelectedHours, ...range])];\n }\n } else {\n if (state.usageSelectedHours.includes(hour)) {\n state.usageSelectedHours = state.usageSelectedHours.filter((h) => h !== hour);\n } else {\n state.usageSelectedHours = [...state.usageSelectedHours, hour];\n }\n }\n },\n onQueryDraftChange: (query) => {\n state.usageQueryDraft = query;\n if (state.usageQueryDebounceTimer) {\n window.clearTimeout(state.usageQueryDebounceTimer);\n }\n state.usageQueryDebounceTimer = window.setTimeout(() => {\n state.usageQuery = state.usageQueryDraft;\n state.usageQueryDebounceTimer = null;\n }, 250);\n },\n onApplyQuery: () => {\n if (state.usageQueryDebounceTimer) {\n window.clearTimeout(state.usageQueryDebounceTimer);\n state.usageQueryDebounceTimer = null;\n }\n state.usageQuery = state.usageQueryDraft;\n },\n onClearQuery: () => {\n if (state.usageQueryDebounceTimer) {\n window.clearTimeout(state.usageQueryDebounceTimer);\n state.usageQueryDebounceTimer = null;\n }\n state.usageQueryDraft = \"\";\n state.usageQuery = \"\";\n },\n onSessionSortChange: (sort) => {\n state.usageSessionSort = sort;\n },\n onSessionSortDirChange: (dir) => {\n state.usageSessionSortDir = dir;\n },\n onSessionsTabChange: (tab) => {\n state.usageSessionsTab = tab;\n },\n onToggleColumn: (column) => {\n if (state.usageVisibleColumns.includes(column)) {\n state.usageVisibleColumns = state.usageVisibleColumns.filter((entry) => entry !== column);\n } else {\n state.usageVisibleColumns = [...state.usageVisibleColumns, column];\n }\n },\n onSelectSession: (key, shiftKey) => {\n state.usageTimeSeries = null;\n state.usageSessionLogs = null;\n state.usageRecentSessions = [\n key,\n ...state.usageRecentSessions.filter((entry) => entry !== key),\n ].slice(0, 8);\n\n if (shiftKey && state.usageSelectedSessions.length > 0) {\n // Shift-click: select range from last selected to this session\n // Sort sessions same way as displayed (by tokens or cost descending)\n const isTokenMode = state.usageChartMode === \"tokens\";\n const sortedSessions = [...(state.usageResult?.sessions ?? [])].toSorted((a, b) => {\n const valA = isTokenMode ? (a.usage?.totalTokens ?? 0) : (a.usage?.totalCost ?? 0);\n const valB = isTokenMode ? (b.usage?.totalTokens ?? 0) : (b.usage?.totalCost ?? 0);\n return valB - valA;\n });\n const allKeys = sortedSessions.map((s) => s.key);\n const lastSelected = state.usageSelectedSessions[state.usageSelectedSessions.length - 1];\n const lastIdx = allKeys.indexOf(lastSelected);\n const thisIdx = allKeys.indexOf(key);\n if (lastIdx !== -1 && thisIdx !== -1) {\n const [start, end] = lastIdx < thisIdx ? [lastIdx, thisIdx] : [thisIdx, lastIdx];\n const range = allKeys.slice(start, end + 1);\n const newSelection = [...new Set([...state.usageSelectedSessions, ...range])];\n state.usageSelectedSessions = newSelection;\n }\n } else {\n // Regular click: focus a single session (so details always open).\n // Click the focused session again to clear selection.\n if (state.usageSelectedSessions.length === 1 && state.usageSelectedSessions[0] === key) {\n state.usageSelectedSessions = [];\n } else {\n state.usageSelectedSessions = [key];\n }\n }\n\n // Reset range selection when switching sessions\n state.usageTimeSeriesCursorStart = null;\n state.usageTimeSeriesCursorEnd = null;\n\n // Load timeseries/logs only if exactly one session selected\n if (state.usageSelectedSessions.length === 1) {\n void loadSessionTimeSeries(state, state.usageSelectedSessions[0]);\n void loadSessionLogs(state, state.usageSelectedSessions[0]);\n }\n },\n onSelectDay: (day, shiftKey) => {\n if (shiftKey && state.usageSelectedDays.length > 0) {\n // Shift-click: select range from last selected to this day\n const allDays = (state.usageCostSummary?.daily ?? []).map((d) => d.date);\n const lastSelected = state.usageSelectedDays[state.usageSelectedDays.length - 1];\n const lastIdx = allDays.indexOf(lastSelected);\n const thisIdx = allDays.indexOf(day);\n if (lastIdx !== -1 && thisIdx !== -1) {\n const [start, end] = lastIdx < thisIdx ? [lastIdx, thisIdx] : [thisIdx, lastIdx];\n const range = allDays.slice(start, end + 1);\n // Merge with existing selection\n const newSelection = [...new Set([...state.usageSelectedDays, ...range])];\n state.usageSelectedDays = newSelection;\n }\n } else {\n // Regular click: toggle single day\n if (state.usageSelectedDays.includes(day)) {\n state.usageSelectedDays = state.usageSelectedDays.filter((d) => d !== day);\n } else {\n state.usageSelectedDays = [day];\n }\n }\n },\n onChartModeChange: (mode) => {\n state.usageChartMode = mode;\n },\n onDailyChartModeChange: (mode) => {\n state.usageDailyChartMode = mode;\n },\n onTimeSeriesModeChange: (mode) => {\n state.usageTimeSeriesMode = mode;\n },\n onTimeSeriesBreakdownChange: (mode) => {\n state.usageTimeSeriesBreakdownMode = mode;\n },\n onTimeSeriesCursorRangeChange: (start, end) => {\n state.usageTimeSeriesCursorStart = start;\n state.usageTimeSeriesCursorEnd = end;\n },\n onClearDays: () => {\n state.usageSelectedDays = [];\n },\n onClearHours: () => {\n state.usageSelectedHours = [];\n },\n onClearSessions: () => {\n state.usageSelectedSessions = [];\n state.usageTimeSeries = null;\n state.usageSessionLogs = null;\n },\n onClearFilters: () => {\n state.usageSelectedDays = [];\n state.usageSelectedHours = [];\n state.usageSelectedSessions = [];\n state.usageTimeSeries = null;\n state.usageSessionLogs = null;\n },\n });\n}\n","import { html, nothing } from \"lit\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { t } from \"../i18n/index.ts\";\nimport { refreshChat } from \"./app-chat.ts\";\nimport { syncUrlWithSessionKey } from \"./app-settings.ts\";\nimport type { AppViewState } from \"./app-view-state.ts\";\nimport { OpenClawApp } from \"./app.ts\";\nimport { ChatState, loadChatHistory } from \"./controllers/chat.ts\";\nimport { icons } from \"./icons.ts\";\nimport { iconForTab, pathForTab, titleForTab, type Tab } from \"./navigation.ts\";\nimport type { ThemeTransitionContext } from \"./theme-transition.ts\";\nimport type { ThemeMode } from \"./theme.ts\";\nimport type { SessionsListResult } from \"./types.ts\";\n\ntype SessionDefaultsSnapshot = {\n mainSessionKey?: string;\n mainKey?: string;\n};\n\nfunction resolveSidebarChatSessionKey(state: AppViewState): string {\n const snapshot = state.hello?.snapshot as\n | { sessionDefaults?: SessionDefaultsSnapshot }\n | undefined;\n const mainSessionKey = snapshot?.sessionDefaults?.mainSessionKey?.trim();\n if (mainSessionKey) {\n return mainSessionKey;\n }\n const mainKey = snapshot?.sessionDefaults?.mainKey?.trim();\n if (mainKey) {\n return mainKey;\n }\n return \"main\";\n}\n\nfunction resetChatStateForSessionSwitch(state: AppViewState, sessionKey: string) {\n state.sessionKey = sessionKey;\n state.chatMessage = \"\";\n state.chatStream = null;\n (state as unknown as OpenClawApp).chatStreamStartedAt = null;\n state.chatRunId = null;\n (state as unknown as OpenClawApp).resetToolStream();\n (state as unknown as OpenClawApp).resetChatScroll();\n state.applySettings({\n ...state.settings,\n sessionKey,\n lastActiveSessionKey: sessionKey,\n });\n}\n\nexport function renderTab(state: AppViewState, tab: Tab) {\n const href = pathForTab(tab, state.basePath);\n return html`\n <a\n href=${href}\n class=\"nav-item ${state.tab === tab ? \"active\" : \"\"}\"\n @click=${(event: MouseEvent) => {\n if (\n event.defaultPrevented ||\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n event.preventDefault();\n if (tab === \"chat\") {\n const mainSessionKey = resolveSidebarChatSessionKey(state);\n if (state.sessionKey !== mainSessionKey) {\n resetChatStateForSessionSwitch(state, mainSessionKey);\n void state.loadAssistantIdentity();\n }\n }\n state.setTab(tab);\n }}\n title=${titleForTab(tab)}\n >\n <span class=\"nav-item__icon\" aria-hidden=\"true\">${icons[iconForTab(tab)]}</span>\n <span class=\"nav-item__text\">${titleForTab(tab)}</span>\n ${\n tab === \"learning\" && (state.overview?.proposals?.pending ?? 0) > 0\n ? html`<span class=\"nav-item__badge\">${state.overview?.proposals?.pending}</span>`\n : nothing\n }\n </a>\n `;\n}\n\nfunction renderCronFilterIcon(hiddenCount: number) {\n return html`\n <span style=\"position: relative; display: inline-flex; align-items: center;\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <polyline points=\"12 6 12 12 16 14\"></polyline>\n </svg>\n ${\n hiddenCount > 0\n ? html`<span\n style=\"\n position: absolute;\n top: -5px;\n right: -6px;\n background: var(--accent);\n color: #fff;\n border-radius: 999px;\n font-size: 9px;\n line-height: 1;\n padding: 1px 3px;\n pointer-events: none;\n \"\n >${hiddenCount}</span\n >`\n : \"\"\n }\n </span>\n `;\n}\n\nexport function renderChatControls(state: AppViewState) {\n const mainSessionKey = resolveMainSessionKey(state.hello, state.sessionsResult);\n const hideCron = state.sessionsHideCron ?? true;\n const hiddenCronCount = hideCron\n ? countHiddenCronSessions(state.sessionKey, state.sessionsResult)\n : 0;\n const sessionOptions = resolveSessionOptions(\n state.sessionKey,\n state.sessionsResult,\n mainSessionKey,\n hideCron,\n );\n const disableThinkingToggle = state.onboarding;\n const disableFocusToggle = state.onboarding;\n const showThinking = state.onboarding ? false : state.settings.chatShowThinking;\n const focusActive = state.onboarding ? true : state.settings.chatFocusMode;\n // Refresh icon\n const refreshIcon = html`\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\"></path>\n <path d=\"M21 3v5h-5\"></path>\n </svg>\n `;\n const focusIcon = html`\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M4 7V4h3\"></path>\n <path d=\"M20 7V4h-3\"></path>\n <path d=\"M4 17v3h3\"></path>\n <path d=\"M20 17v3h-3\"></path>\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\n </svg>\n `;\n return html`\n <div class=\"chat-controls\">\n <label class=\"field chat-controls__session\">\n <select\n .value=${state.sessionKey}\n ?disabled=${!state.connected}\n @change=${(e: Event) => {\n const next = (e.target as HTMLSelectElement).value;\n state.sessionKey = next;\n state.chatMessage = \"\";\n state.chatStream = null;\n (state as unknown as OpenClawApp).chatStreamStartedAt = null;\n state.chatRunId = null;\n (state as unknown as OpenClawApp).resetToolStream();\n (state as unknown as OpenClawApp).resetChatScroll();\n state.applySettings({\n ...state.settings,\n sessionKey: next,\n lastActiveSessionKey: next,\n });\n void state.loadAssistantIdentity();\n syncUrlWithSessionKey(\n state as unknown as Parameters<typeof syncUrlWithSessionKey>[0],\n next,\n true,\n );\n void loadChatHistory(state as unknown as ChatState);\n }}\n >\n ${repeat(\n sessionOptions,\n (entry) => entry.key,\n (entry) =>\n html`<option value=${entry.key} title=${entry.key}>\n ${entry.displayName ?? entry.key}\n </option>`,\n )}\n </select>\n </label>\n <button\n class=\"btn btn--sm btn--icon\"\n ?disabled=${state.chatLoading || !state.connected}\n @click=${async () => {\n const app = state as unknown as OpenClawApp;\n app.chatManualRefreshInFlight = true;\n app.chatNewMessagesBelow = false;\n await app.updateComplete;\n app.resetToolStream();\n try {\n await refreshChat(state as unknown as Parameters<typeof refreshChat>[0], {\n scheduleScroll: false,\n });\n app.scrollToBottom({ smooth: true });\n } finally {\n requestAnimationFrame(() => {\n app.chatManualRefreshInFlight = false;\n app.chatNewMessagesBelow = false;\n });\n }\n }}\n title=${t(\"chat.refreshTitle\")}\n >\n ${refreshIcon}\n </button>\n <span class=\"chat-controls__separator\">|</span>\n <button\n class=\"btn btn--sm btn--icon ${showThinking ? \"active\" : \"\"}\"\n ?disabled=${disableThinkingToggle}\n @click=${() => {\n if (disableThinkingToggle) {\n return;\n }\n state.applySettings({\n ...state.settings,\n chatShowThinking: !state.settings.chatShowThinking,\n });\n }}\n aria-pressed=${showThinking}\n title=${disableThinkingToggle ? t(\"chat.onboardingDisabled\") : t(\"chat.thinkingToggle\")}\n >\n ${icons.brain}\n </button>\n <button\n class=\"btn btn--sm btn--icon ${focusActive ? \"active\" : \"\"}\"\n ?disabled=${disableFocusToggle}\n @click=${() => {\n if (disableFocusToggle) {\n return;\n }\n state.applySettings({\n ...state.settings,\n chatFocusMode: !state.settings.chatFocusMode,\n });\n }}\n aria-pressed=${focusActive}\n title=${disableFocusToggle ? t(\"chat.onboardingDisabled\") : t(\"chat.focusToggle\")}\n >\n ${focusIcon}\n </button>\n <button\n class=\"btn btn--sm btn--icon ${hideCron ? \"active\" : \"\"}\"\n @click=${() => {\n state.sessionsHideCron = !hideCron;\n }}\n aria-pressed=${hideCron}\n title=${\n hideCron\n ? hiddenCronCount > 0\n ? t(\"chat.showCronSessionsHidden\", { count: String(hiddenCronCount) })\n : t(\"chat.showCronSessions\")\n : t(\"chat.hideCronSessions\")\n }\n >\n ${renderCronFilterIcon(hiddenCronCount)}\n </button>\n </div>\n `;\n}\n\nfunction resolveMainSessionKey(\n hello: AppViewState[\"hello\"],\n sessions: SessionsListResult | null,\n): string | null {\n const snapshot = hello?.snapshot as { sessionDefaults?: SessionDefaultsSnapshot } | undefined;\n const mainSessionKey = snapshot?.sessionDefaults?.mainSessionKey?.trim();\n if (mainSessionKey) {\n return mainSessionKey;\n }\n const mainKey = snapshot?.sessionDefaults?.mainKey?.trim();\n if (mainKey) {\n return mainKey;\n }\n if (sessions?.sessions?.some((row) => row.key === \"main\")) {\n return \"main\";\n }\n return null;\n}\n\n/* ── Channel display labels ────────────────────────────── */\nconst CHANNEL_LABELS: Record<string, string> = {\n bluebubbles: \"iMessage\",\n telegram: \"Telegram\",\n discord: \"Discord\",\n signal: \"Signal\",\n slack: \"Slack\",\n whatsapp: \"WhatsApp\",\n matrix: \"Matrix\",\n email: \"Email\",\n sms: \"SMS\",\n};\n\nconst KNOWN_CHANNEL_KEYS = Object.keys(CHANNEL_LABELS);\n\n/** Parsed type / context extracted from a session key. */\nexport type SessionKeyInfo = {\n /** Prefix for typed sessions (Subagent:/Cron:). Empty for others. */\n prefix: string;\n /** Human-readable fallback when no label / displayName is available. */\n fallbackName: string;\n};\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/**\n * Parse a session key to extract type information and a human-readable\n * fallback display name. When a gateway row is supplied, its actor-backed\n * `channel`/`kind` take precedence over the key text (whose channel slot is\n * ambiguous — accounts may be named \"direct\"/\"group\"/\"channel\"); the regexes\n * below are the fallback for rows without them. Exported for testing.\n */\nexport function parseSessionKey(\n key: string,\n row?: SessionsListResult[\"sessions\"][number],\n): SessionKeyInfo {\n const normalized = key.toLowerCase();\n\n // ── Main session ─────────────────────────────────\n if (key === \"main\" || key === \"agent:main:main\") {\n return { prefix: \"\", fallbackName: \"Main Session\" };\n }\n\n // ── Subagent ─────────────────────────────────────\n if (key.includes(\":subagent:\")) {\n return { prefix: \"Subagent:\", fallbackName: \"Subagent:\" };\n }\n\n // ── Cron job ─────────────────────────────────────\n if (normalized.startsWith(\"cron:\") || key.includes(\":cron:\")) {\n return { prefix: \"Cron:\", fallbackName: \"Cron Job:\" };\n }\n\n // ── Gateway row channel/kind (actor-backed) ──────\n const rowChannel = row?.channel?.trim();\n const rowKind = row?.kind;\n if (rowChannel && (rowKind === \"direct\" || rowKind === \"group\")) {\n const channelLabel = CHANNEL_LABELS[rowChannel] ?? capitalize(rowChannel);\n if (rowKind === \"group\") {\n return { prefix: \"\", fallbackName: `${channelLabel} Group` };\n }\n const marker = \":direct:\";\n const markerAt = key.lastIndexOf(marker);\n const peerText =\n markerAt >= 0 ? key.slice(markerAt + marker.length) : key.slice(key.lastIndexOf(\":\") + 1);\n return { prefix: \"\", fallbackName: `${channelLabel} · ${peerText}` };\n }\n\n // ── Direct chat (agent:<x>:<channel>:direct:<id>) ──\n const directMatch = key.match(/^agent:[^:]+:([^:]+):direct:(.+)$/);\n if (directMatch) {\n const channel = directMatch[1];\n const identifier = directMatch[2];\n const channelLabel = CHANNEL_LABELS[channel] ?? capitalize(channel);\n return { prefix: \"\", fallbackName: `${channelLabel} · ${identifier}` };\n }\n\n // ── Group chat (agent:<x>:<channel>:group:<id>) ────\n const groupMatch = key.match(/^agent:[^:]+:([^:]+):group:(.+)$/);\n if (groupMatch) {\n const channel = groupMatch[1];\n const channelLabel = CHANNEL_LABELS[channel] ?? capitalize(channel);\n return { prefix: \"\", fallbackName: `${channelLabel} Group` };\n }\n\n // ── Channel-prefixed legacy keys (e.g. \"bluebubbles:g-…\") ──\n for (const ch of KNOWN_CHANNEL_KEYS) {\n if (key === ch || key.startsWith(`${ch}:`)) {\n return { prefix: \"\", fallbackName: `${CHANNEL_LABELS[ch]} Session` };\n }\n }\n\n // ── Unknown — return key as-is ───────────────────\n return { prefix: \"\", fallbackName: key };\n}\n\nexport function resolveSessionDisplayName(\n key: string,\n row?: SessionsListResult[\"sessions\"][number],\n): string {\n const label = row?.label?.trim() || \"\";\n const displayName = row?.displayName?.trim() || \"\";\n const { prefix, fallbackName } = parseSessionKey(key, row);\n\n const applyTypedPrefix = (name: string): string => {\n if (!prefix) {\n return name;\n }\n const prefixPattern = new RegExp(`^${prefix.replace(/[.*+?^${}()|[\\\\]\\\\]/g, \"\\\\$&\")}\\\\s*`, \"i\");\n return prefixPattern.test(name) ? name : `${prefix} ${name}`;\n };\n\n if (label && label !== key) {\n return applyTypedPrefix(label);\n }\n if (displayName && displayName !== key) {\n return applyTypedPrefix(displayName);\n }\n return fallbackName;\n}\n\nexport function isCronSessionKey(key: string): boolean {\n const normalized = key.trim().toLowerCase();\n if (!normalized) {\n return false;\n }\n if (normalized.startsWith(\"cron:\")) {\n return true;\n }\n if (!normalized.startsWith(\"agent:\")) {\n return false;\n }\n const parts = normalized.split(\":\").filter(Boolean);\n if (parts.length < 3) {\n return false;\n }\n const rest = parts.slice(2).join(\":\");\n return rest.startsWith(\"cron:\");\n}\n\nfunction resolveSessionOptions(\n sessionKey: string,\n sessions: SessionsListResult | null,\n mainSessionKey?: string | null,\n hideCron = false,\n) {\n const seen = new Set<string>();\n const options: Array<{ key: string; displayName?: string }> = [];\n\n const resolvedMain = mainSessionKey && sessions?.sessions?.find((s) => s.key === mainSessionKey);\n const resolvedCurrent = sessions?.sessions?.find((s) => s.key === sessionKey);\n\n // Add main session key first\n if (mainSessionKey) {\n seen.add(mainSessionKey);\n options.push({\n key: mainSessionKey,\n displayName: resolveSessionDisplayName(mainSessionKey, resolvedMain || undefined),\n });\n }\n\n // Add current session key next — always include it even if it's a cron session,\n // so the active session is never silently dropped from the select.\n if (!seen.has(sessionKey)) {\n seen.add(sessionKey);\n options.push({\n key: sessionKey,\n displayName: resolveSessionDisplayName(sessionKey, resolvedCurrent),\n });\n }\n\n // Add sessions from the result, optionally filtering out cron sessions.\n if (sessions?.sessions) {\n for (const s of sessions.sessions) {\n if (!seen.has(s.key) && !(hideCron && isCronSessionKey(s.key))) {\n seen.add(s.key);\n options.push({\n key: s.key,\n displayName: resolveSessionDisplayName(s.key, s),\n });\n }\n }\n }\n\n return options;\n}\n\n/** Count sessions with a cron: key that would be hidden when hideCron=true. */\nfunction countHiddenCronSessions(sessionKey: string, sessions: SessionsListResult | null): number {\n if (!sessions?.sessions) {\n return 0;\n }\n // Don't count the currently active session even if it's a cron.\n return sessions.sessions.filter((s) => isCronSessionKey(s.key) && s.key !== sessionKey).length;\n}\n\nconst THEME_ORDER: ThemeMode[] = [\"system\", \"light\", \"dark\"];\n\nexport function renderThemeToggle(state: AppViewState) {\n const index = Math.max(0, THEME_ORDER.indexOf(state.theme));\n const applyTheme = (next: ThemeMode) => (event: MouseEvent) => {\n const element = event.currentTarget as HTMLElement;\n const context: ThemeTransitionContext = { element };\n if (event.clientX || event.clientY) {\n context.pointerClientX = event.clientX;\n context.pointerClientY = event.clientY;\n }\n state.setTheme(next, context);\n };\n\n return html`\n <div class=\"theme-toggle\" style=\"--theme-index: ${index};\">\n <div class=\"theme-toggle__track\" role=\"group\" aria-label=\"Theme\">\n <span class=\"theme-toggle__indicator\"></span>\n <button\n class=\"theme-toggle__button ${state.theme === \"system\" ? \"active\" : \"\"}\"\n @click=${applyTheme(\"system\")}\n aria-pressed=${state.theme === \"system\"}\n aria-label=\"System theme\"\n title=\"System\"\n >\n ${renderMonitorIcon()}\n </button>\n <button\n class=\"theme-toggle__button ${state.theme === \"light\" ? \"active\" : \"\"}\"\n @click=${applyTheme(\"light\")}\n aria-pressed=${state.theme === \"light\"}\n aria-label=\"Light theme\"\n title=\"Light\"\n >\n ${renderSunIcon()}\n </button>\n <button\n class=\"theme-toggle__button ${state.theme === \"dark\" ? \"active\" : \"\"}\"\n @click=${applyTheme(\"dark\")}\n aria-pressed=${state.theme === \"dark\"}\n aria-label=\"Dark theme\"\n title=\"Dark\"\n >\n ${renderMoonIcon()}\n </button>\n </div>\n </div>\n `;\n}\n\nfunction renderSunIcon() {\n return html`\n <svg class=\"theme-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\n <path d=\"M12 2v2\"></path>\n <path d=\"M12 20v2\"></path>\n <path d=\"m4.93 4.93 1.41 1.41\"></path>\n <path d=\"m17.66 17.66 1.41 1.41\"></path>\n <path d=\"M2 12h2\"></path>\n <path d=\"M20 12h2\"></path>\n <path d=\"m6.34 17.66-1.41 1.41\"></path>\n <path d=\"m19.07 4.93-1.41 1.41\"></path>\n </svg>\n `;\n}\n\nfunction renderMoonIcon() {\n return html`\n <svg class=\"theme-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\n ></path>\n </svg>\n `;\n}\n\nfunction renderMonitorIcon() {\n return html`\n <svg class=\"theme-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"3\" rx=\"2\"></rect>\n <line x1=\"8\" x2=\"16\" y1=\"21\" y2=\"21\"></line>\n <line x1=\"12\" x2=\"12\" y1=\"17\" y2=\"21\"></line>\n </svg>\n `;\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type {\n AgentFileEntry,\n AgentsFilesGetResult,\n AgentsFilesListResult,\n AgentsFilesSetResult,\n} from \"../types.ts\";\n\nexport type AgentFilesState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentFilesLoading: boolean;\n agentFilesError: string | null;\n agentFilesList: AgentsFilesListResult | null;\n agentFileContents: Record<string, string>;\n agentFileDrafts: Record<string, string>;\n agentFileActive: string | null;\n agentFileSaving: boolean;\n};\n\nfunction mergeFileEntry(\n list: AgentsFilesListResult | null,\n entry: AgentFileEntry,\n): AgentsFilesListResult | null {\n if (!list) {\n return list;\n }\n const hasEntry = list.files.some((file) => file.name === entry.name);\n const nextFiles = hasEntry\n ? list.files.map((file) => (file.name === entry.name ? entry : file))\n : [...list.files, entry];\n return { ...list, files: nextFiles };\n}\n\nexport async function loadAgentFiles(state: AgentFilesState, agentId: string) {\n if (!state.client || !state.connected || state.agentFilesLoading) {\n return;\n }\n state.agentFilesLoading = true;\n state.agentFilesError = null;\n try {\n const res = await state.client.request<AgentsFilesListResult | null>(\"agents.files.list\", {\n agentId,\n });\n if (res) {\n state.agentFilesList = res;\n if (state.agentFileActive && !res.files.some((file) => file.name === state.agentFileActive)) {\n state.agentFileActive = null;\n }\n }\n } catch (err) {\n state.agentFilesError = String(err);\n } finally {\n state.agentFilesLoading = false;\n }\n}\n\nexport async function loadAgentFileContent(\n state: AgentFilesState,\n agentId: string,\n name: string,\n opts?: { force?: boolean; preserveDraft?: boolean },\n) {\n if (!state.client || !state.connected || state.agentFilesLoading) {\n return;\n }\n if (!opts?.force && Object.hasOwn(state.agentFileContents, name)) {\n return;\n }\n state.agentFilesLoading = true;\n state.agentFilesError = null;\n try {\n const res = await state.client.request<AgentsFilesGetResult | null>(\"agents.files.get\", {\n agentId,\n name,\n });\n if (res?.file) {\n const content = res.file.content ?? \"\";\n const previousBase = state.agentFileContents[name] ?? \"\";\n const currentDraft = state.agentFileDrafts[name];\n const preserveDraft = opts?.preserveDraft ?? true;\n state.agentFilesList = mergeFileEntry(state.agentFilesList, res.file);\n state.agentFileContents = { ...state.agentFileContents, [name]: content };\n if (\n !preserveDraft ||\n !Object.hasOwn(state.agentFileDrafts, name) ||\n currentDraft === previousBase\n ) {\n state.agentFileDrafts = { ...state.agentFileDrafts, [name]: content };\n }\n }\n } catch (err) {\n state.agentFilesError = String(err);\n } finally {\n state.agentFilesLoading = false;\n }\n}\n\nexport async function saveAgentFile(\n state: AgentFilesState,\n agentId: string,\n name: string,\n content: string,\n) {\n if (!state.client || !state.connected || state.agentFileSaving) {\n return;\n }\n state.agentFileSaving = true;\n state.agentFilesError = null;\n try {\n const res = await state.client.request<AgentsFilesSetResult | null>(\"agents.files.set\", {\n agentId,\n name,\n content,\n });\n if (res?.file) {\n state.agentFilesList = mergeFileEntry(state.agentFilesList, res.file);\n state.agentFileContents = { ...state.agentFileContents, [name]: content };\n state.agentFileDrafts = { ...state.agentFileDrafts, [name]: content };\n }\n } catch (err) {\n state.agentFilesError = String(err);\n } finally {\n state.agentFileSaving = false;\n }\n}\n","import { html, nothing } from \"lit\";\nimport type { AppViewState } from \"../app-view-state.ts\";\n\nfunction formatRemaining(ms: number): string {\n const remaining = Math.max(0, ms);\n const totalSeconds = Math.floor(remaining / 1000);\n if (totalSeconds < 60) {\n return `${totalSeconds}s`;\n }\n const minutes = Math.floor(totalSeconds / 60);\n if (minutes < 60) {\n return `${minutes}m`;\n }\n const hours = Math.floor(minutes / 60);\n return `${hours}h`;\n}\n\nfunction renderMetaRow(label: string, value?: string | null) {\n if (!value) {\n return nothing;\n }\n return html`<div class=\"exec-approval-meta-row\"><span>${label}</span><span>${value}</span></div>`;\n}\n\nexport function renderExecApprovalPrompt(state: AppViewState) {\n const active = state.execApprovalQueue[0];\n if (!active) {\n return nothing;\n }\n const request = active.request;\n const remainingMs = active.expiresAtMs - Date.now();\n const remaining = remainingMs > 0 ? `expires in ${formatRemaining(remainingMs)}` : \"expired\";\n const queueCount = state.execApprovalQueue.length;\n return html`\n <div class=\"exec-approval-overlay\" role=\"dialog\" aria-live=\"polite\">\n <div class=\"exec-approval-card\">\n <div class=\"exec-approval-header\">\n <div>\n <div class=\"exec-approval-title\">Exec approval needed</div>\n <div class=\"exec-approval-sub\">${remaining}</div>\n </div>\n ${\n queueCount > 1\n ? html`<div class=\"exec-approval-queue\">${queueCount} pending</div>`\n : nothing\n }\n </div>\n <div class=\"exec-approval-command mono\">${request.command}</div>\n <div class=\"exec-approval-meta\">\n ${renderMetaRow(\"Host\", request.host)}\n ${renderMetaRow(\"Agent\", request.agentId)}\n ${renderMetaRow(\"Session\", request.sessionKey)}\n ${renderMetaRow(\"CWD\", request.cwd)}\n ${renderMetaRow(\"Resolved\", request.resolvedPath)}\n ${renderMetaRow(\"Security\", request.security)}\n ${renderMetaRow(\"Ask\", request.ask)}\n </div>\n ${\n state.execApprovalError\n ? html`<div class=\"exec-approval-error\">${state.execApprovalError}</div>`\n : nothing\n }\n <div class=\"exec-approval-actions\">\n <button\n class=\"btn primary\"\n ?disabled=${state.execApprovalBusy}\n @click=${() => state.handleExecApprovalDecision(\"allow-once\")}\n >\n Allow once\n </button>\n <button\n class=\"btn\"\n ?disabled=${state.execApprovalBusy}\n @click=${() => state.handleExecApprovalDecision(\"allow-always\")}\n >\n Always allow\n </button>\n <button\n class=\"btn danger\"\n ?disabled=${state.execApprovalBusy}\n @click=${() => state.handleExecApprovalDecision(\"deny\")}\n >\n Deny\n </button>\n </div>\n </div>\n </div>\n `;\n}\n","import { html, nothing } from \"lit\";\nimport type { AppViewState } from \"../app-view-state.ts\";\n\nexport function renderGatewayUrlConfirmation(state: AppViewState) {\n const { pendingGatewayUrl } = state;\n if (!pendingGatewayUrl) {\n return nothing;\n }\n\n return html`\n <div class=\"exec-approval-overlay\" role=\"dialog\" aria-modal=\"true\" aria-live=\"polite\">\n <div class=\"exec-approval-card\">\n <div class=\"exec-approval-header\">\n <div>\n <div class=\"exec-approval-title\">Change Gateway URL</div>\n <div class=\"exec-approval-sub\">This will reconnect to a different gateway server</div>\n </div>\n </div>\n <div class=\"exec-approval-command mono\">${pendingGatewayUrl}</div>\n <div class=\"callout danger\" style=\"margin-top: 12px;\">\n Only confirm if you trust this URL. Malicious URLs can compromise your system.\n </div>\n <div class=\"exec-approval-actions\">\n <button\n class=\"btn primary\"\n @click=${() => state.handleGatewayUrlConfirm()}\n >\n Confirm\n </button>\n <button\n class=\"btn\"\n @click=${() => state.handleGatewayUrlCancel()}\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n `;\n}\n","import { html, nothing } from \"lit\";\nimport { DOCS_SITE_URL } from \"../../../src/infra/docs-site.js\";\nimport { parseAgentSessionKey } from \"../../../src/routing/session-key.js\";\nimport { t } from \"../i18n/index.ts\";\nimport { refreshChatAvatar } from \"./app-chat.ts\";\nimport { renderUsageTab } from \"./app-render-usage-tab.ts\";\nimport { renderChatControls, renderTab, renderThemeToggle } from \"./app-render.helpers.ts\";\nimport { consoleViews } from \"./app-view-dispatcher.ts\";\nimport type { AppViewState } from \"./app-view-state.ts\";\nimport { loadAgentFileContent, loadAgentFiles, saveAgentFile } from \"./controllers/agent-files.ts\";\nimport { loadAgentIdentities, loadAgentIdentity } from \"./controllers/agent-identity.ts\";\nimport { loadAgentSkills } from \"./controllers/agent-skills.ts\";\nimport { loadAgents, loadToolsCatalog, nudgeAgent } from \"./controllers/agents.ts\";\nimport { loadChannels } from \"./controllers/channels.ts\";\nimport { loadChatHistory } from \"./controllers/chat.ts\";\nimport {\n applyConfig,\n loadConfig,\n runUpdate,\n saveConfig,\n updateConfigFormValue,\n removeConfigFormValue,\n} from \"./controllers/config.ts\";\nimport {\n loadCronRuns,\n loadMoreCronJobs,\n loadMoreCronRuns,\n reloadCronJobs,\n toggleCronJob,\n runCronJob,\n removeCronJob,\n addCronJob,\n startCronCreate,\n startCronEdit,\n startCronClone,\n cancelCronEdit,\n validateCronForm,\n hasCronFormErrors,\n normalizeCronFormState,\n getVisibleCronJobs,\n updateCronJobsFilter,\n updateCronRunsFilter,\n} from \"./controllers/cron.ts\";\nimport { loadDebug, callDebugMethod } from \"./controllers/debug.ts\";\nimport {\n approveDevicePairing,\n loadDevices,\n rejectDevicePairing,\n revokeDeviceToken,\n rotateDeviceToken,\n} from \"./controllers/devices.ts\";\nimport {\n loadExecApprovals,\n removeExecApprovalsFormValue,\n saveExecApprovals,\n updateExecApprovalsFormValue,\n} from \"./controllers/exec-approvals.ts\";\nimport { loadLogs } from \"./controllers/logs.ts\";\nimport { loadNodes } from \"./controllers/nodes.ts\";\nimport { loadPresence } from \"./controllers/presence.ts\";\nimport {\n cancelRun,\n continueRun,\n deleteSessionAndRefresh,\n interruptSession,\n loadRecoverableRuns,\n loadSessionRuns,\n loadSessionThresholds,\n loadSessions,\n patchSession,\n} from \"./controllers/sessions.ts\";\nimport {\n installSkill,\n loadSkills,\n saveSkillApiKey,\n updateSkillEdit,\n updateSkillEnabled,\n} from \"./controllers/skills.ts\";\nimport { docsHrefForTab } from \"./docs-refs.ts\";\nimport { buildExternalLinkRel, EXTERNAL_LINK_TARGET } from \"./external-link.ts\";\nimport { icons } from \"./icons.ts\";\nimport {\n normalizeBasePath,\n pathForTab,\n TAB_GROUPS,\n subtitleForTab,\n titleForTab,\n} from \"./navigation.ts\";\nimport { resolveConfiguredCronModelSuggestions, sortLocaleStrings } from \"./views/agents-utils.ts\";\nimport { renderExecApprovalPrompt } from \"./views/exec-approval.ts\";\nimport { renderGatewayUrlConfirmation } from \"./views/gateway-url-confirmation.ts\";\n\nconst AVATAR_DATA_RE = /^data:/i;\nconst AVATAR_HTTP_RE = /^https?:\\/\\//i;\nconst CRON_THINKING_SUGGESTIONS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\"];\nconst CRON_TIMEZONE_SUGGESTIONS = [\n \"UTC\",\n \"America/Los_Angeles\",\n \"America/Denver\",\n \"America/Chicago\",\n \"America/New_York\",\n \"Europe/London\",\n \"Europe/Berlin\",\n \"Asia/Tokyo\",\n];\n\nfunction isHttpUrl(value: string): boolean {\n return /^https?:\\/\\//i.test(value.trim());\n}\n\nfunction normalizeSuggestionValue(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction uniquePreserveOrder(values: string[]): string[] {\n const seen = new Set<string>();\n const output: string[] = [];\n for (const value of values) {\n const normalized = value.trim();\n if (!normalized) {\n continue;\n }\n const key = normalized.toLowerCase();\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n output.push(normalized);\n }\n return output;\n}\n\nfunction resolveAssistantAvatarUrl(state: AppViewState): string | undefined {\n const list = state.agentsList?.agents ?? [];\n const parsed = parseAgentSessionKey(state.sessionKey);\n const agentId = parsed?.agentId ?? state.agentsList?.defaultId ?? \"main\";\n const agent = list.find((entry) => entry.id === agentId);\n const identity = agent?.identity;\n const candidate = identity?.avatarUrl ?? identity?.avatar;\n if (!candidate) {\n return undefined;\n }\n if (AVATAR_DATA_RE.test(candidate) || AVATAR_HTTP_RE.test(candidate)) {\n return candidate;\n }\n return identity?.avatarUrl;\n}\n\nfunction isTalkAvailable(state: AppViewState): boolean {\n const availability = state.talkState.availability;\n return (\n state.connected &&\n availability.resolved &&\n !availability.loading &&\n !availability.error &&\n availability.enabled &&\n availability.available\n );\n}\n\nfunction renderTalkAvailabilityGuard(state: AppViewState, message: string) {\n return html`\n <div class=\"callout\" role=\"status\">\n <span>${message}</span>\n ${\n state.talkState.lifecycle === \"idle\"\n ? nothing\n : html`\n <button class=\"btn btn--sm\" type=\"button\" @click=${() => void state.handleTalkStop()}>\n ${t(\"talk.stop\")}\n </button>\n `\n }\n </div>\n `;\n}\n\nexport function renderApp(state: AppViewState) {\n const openClawVersion =\n (typeof state.hello?.server?.version === \"string\" && state.hello.server.version.trim()) ||\n state.updateAvailable?.currentVersion ||\n t(\"common.na\");\n const availableUpdate =\n state.updateAvailable &&\n state.updateAvailable.latestVersion !== state.updateAvailable.currentVersion\n ? state.updateAvailable\n : null;\n const versionStatusClass = availableUpdate ? \"warn\" : \"ok\";\n const presenceCount = state.presenceEntries.length;\n const sessionsCount = state.sessionsResult?.count ?? null;\n const cronNext = state.cronStatus?.nextWakeAtMs ?? null;\n const chatDisabledReason = state.connected ? null : t(\"chat.disconnected\");\n const isChat = state.tab === \"chat\";\n const docsHref = docsHrefForTab(state.tab);\n const chatFocus = isChat && (state.settings.chatFocusMode || state.onboarding);\n const showThinking = state.onboarding ? false : state.settings.chatShowThinking;\n const assistantAvatarUrl = resolveAssistantAvatarUrl(state);\n const chatAvatarUrl = state.chatAvatarUrl ?? assistantAvatarUrl ?? null;\n const talkAvailability = state.talkState.availability;\n const talkAvailable = isTalkAvailable(state);\n const configValue =\n state.configForm ?? (state.configSnapshot?.config as Record<string, unknown> | null);\n const basePath = normalizeBasePath(state.basePath ?? \"\");\n const resolvedAgentId =\n state.agentsSelectedId ??\n state.agentsList?.defaultId ??\n state.agentsList?.agents?.[0]?.id ??\n null;\n const cronAgentSuggestions = sortLocaleStrings(\n new Set(\n [\n ...(state.agentsList?.agents?.map((entry) => entry.id.trim()) ?? []),\n ...state.cronJobs\n .map((job) => (typeof job.agentId === \"string\" ? job.agentId.trim() : \"\"))\n .filter(Boolean),\n ].filter(Boolean),\n ),\n );\n const cronModelSuggestions = sortLocaleStrings(\n new Set(\n [\n ...state.cronModelSuggestions,\n ...resolveConfiguredCronModelSuggestions(configValue),\n ...state.cronJobs\n .map((job) => {\n if (job.payload.kind !== \"agentTurn\" || typeof job.payload.model !== \"string\") {\n return \"\";\n }\n return job.payload.model.trim();\n })\n .filter(Boolean),\n ].filter(Boolean),\n ),\n );\n const visibleCronJobs = getVisibleCronJobs(state);\n const selectedCronJob =\n state.cronRunsJobId == null\n ? null\n : (state.cronJobs.find((job) => job.id === state.cronRunsJobId) ?? null);\n const selectedDeliveryChannel =\n state.cronForm.deliveryChannel && state.cronForm.deliveryChannel.trim()\n ? state.cronForm.deliveryChannel.trim()\n : \"last\";\n const jobToSuggestions = state.cronJobs\n .map((job) => normalizeSuggestionValue(job.delivery?.to))\n .filter(Boolean);\n const accountToSuggestions = (\n selectedDeliveryChannel === \"last\"\n ? Object.values(state.channelsSnapshot?.channelAccounts ?? {}).flat()\n : (state.channelsSnapshot?.channelAccounts?.[selectedDeliveryChannel] ?? [])\n )\n .flatMap((account) => [\n normalizeSuggestionValue(account.accountId),\n normalizeSuggestionValue(account.name),\n ])\n .filter(Boolean);\n const rawDeliveryToSuggestions = uniquePreserveOrder([\n ...jobToSuggestions,\n ...accountToSuggestions,\n ]);\n const accountSuggestions = uniquePreserveOrder(accountToSuggestions);\n const deliveryToSuggestions =\n state.cronForm.deliveryMode === \"webhook\"\n ? rawDeliveryToSuggestions.filter((value) => isHttpUrl(value))\n : rawDeliveryToSuggestions;\n\n return html`\n <div class=\"shell ${isChat ? \"shell--chat\" : \"\"} ${chatFocus ? \"shell--chat-focus\" : \"\"} ${state.settings.navCollapsed ? \"shell--nav-collapsed\" : \"\"} ${state.onboarding ? \"shell--onboarding\" : \"\"}\">\n <header class=\"topbar\">\n <div class=\"topbar-left\">\n <button\n class=\"nav-collapse-toggle\"\n @click=${() =>\n state.applySettings({\n ...state.settings,\n navCollapsed: !state.settings.navCollapsed,\n })}\n title=\"${state.settings.navCollapsed ? t(\"nav.expand\") : t(\"nav.collapse\")}\"\n aria-label=\"${state.settings.navCollapsed ? t(\"nav.expand\") : t(\"nav.collapse\")}\"\n aria-controls=\"primary-nav\"\n aria-expanded=\"${!state.settings.navCollapsed}\"\n >\n <span class=\"nav-collapse-toggle__icon\" aria-hidden=\"true\">${icons.panelLeft}</span>\n </button>\n <div class=\"brand\">\n <div class=\"brand-logo\">\n <img\n src=${basePath ? `${basePath}/brand/wednesdayai-logo-mark.png` : \"/brand/wednesdayai-logo-mark.png\"}\n alt=\"WednesdayAI\"\n />\n </div>\n <div class=\"brand-text\">\n <div class=\"brand-title\">WednesdayAI</div>\n <div class=\"brand-sub\">Operations Console</div>\n </div>\n </div>\n </div>\n <div class=\"topbar-status\">\n <div class=\"pill\">\n <span class=\"statusDot ${versionStatusClass}\"></span>\n <span>${t(\"common.version\")}</span>\n <span class=\"mono\">${openClawVersion}</span>\n </div>\n <div class=\"pill\">\n <span class=\"statusDot ${state.connected ? \"ok\" : \"\"}\"></span>\n <span>${t(\"common.health\")}</span>\n <span class=\"mono\">${state.connected ? t(\"common.ok\") : t(\"common.offline\")}</span>\n </div>\n ${renderThemeToggle(state)}\n </div>\n </header>\n <aside id=\"primary-nav\" class=\"nav ${state.settings.navCollapsed ? \"nav--collapsed\" : \"\"}\">\n ${TAB_GROUPS.map((group) => {\n const tabs = group.tabs.filter((tab) => tab !== \"talk\" || talkAvailable);\n const isGroupCollapsed = state.settings.navGroupsCollapsed[group.label] ?? false;\n const hasActiveTab = tabs.some((tab) => tab === state.tab);\n return html`\n <div class=\"nav-group ${isGroupCollapsed && !hasActiveTab ? \"nav-group--collapsed\" : \"\"}\">\n <button\n class=\"nav-label\"\n @click=${() => {\n const next = { ...state.settings.navGroupsCollapsed };\n next[group.label] = !isGroupCollapsed;\n state.applySettings({\n ...state.settings,\n navGroupsCollapsed: next,\n });\n }}\n aria-expanded=${!isGroupCollapsed}\n >\n <span class=\"nav-label__text\">${t(`nav.${group.label}`)}</span>\n <span class=\"nav-label__chevron\">${isGroupCollapsed ? \"+\" : \"−\"}</span>\n </button>\n <div class=\"nav-group__items\">\n ${tabs.map((tab) => renderTab(state, tab))}\n </div>\n </div>\n `;\n })}\n <div class=\"nav-group nav-group--links\">\n <div class=\"nav-label nav-label--static\">\n <span class=\"nav-label__text\">${t(\"common.resources\")}</span>\n </div>\n <div class=\"nav-group__items\">\n <a\n class=\"nav-item nav-item--external\"\n href=${DOCS_SITE_URL}\n target=${EXTERNAL_LINK_TARGET}\n rel=${buildExternalLinkRel()}\n title=\"${t(\"common.docs\")} (opens in new tab)\"\n >\n <span class=\"nav-item__icon\" aria-hidden=\"true\">${icons.book}</span>\n <span class=\"nav-item__text\">${t(\"common.docs\")}</span>\n </a>\n </div>\n </div>\n </aside>\n <main class=\"content ${isChat ? \"content--chat\" : \"\"}\">\n <div class=\"callout info classic-deprecation\" role=\"status\">\n The classic console is deprecated and will be removed in the next release.\n ${state.consolePath ? html`<a href=${state.consolePath}>Open the new console</a>` : nothing}\n </div>\n ${\n availableUpdate\n ? html`<div class=\"update-banner callout danger\" role=\"alert\">\n <strong>Update available:</strong> v${availableUpdate.latestVersion}\n (running v${availableUpdate.currentVersion}).\n <button\n class=\"btn btn--sm update-banner__btn\"\n ?disabled=${state.updateRunning || !state.connected}\n @click=${() => runUpdate(state)}\n >${state.updateRunning ? \"Updating…\" : \"Update now\"}</button>\n </div>`\n : nothing\n }\n <section class=\"content-header\">\n <div>\n ${state.tab === \"usage\" ? nothing : html`<div class=\"page-title\">${titleForTab(state.tab)}</div>`}\n ${state.tab === \"usage\" ? nothing : html`<div class=\"page-sub\">${subtitleForTab(state.tab)}</div>`}\n </div>\n <div class=\"page-meta\">\n ${state.lastError ? html`<div class=\"pill danger\">${state.lastError}</div>` : nothing}\n <a\n class=\"btn btn--sm\"\n href=${docsHref}\n target=${EXTERNAL_LINK_TARGET}\n rel=${buildExternalLinkRel()}\n title=\"${t(\"common.help\")} (opens in new tab)\"\n >\n ${icons.book}\n <span>${t(\"common.help\")}</span>\n </a>\n ${isChat ? renderChatControls(state) : nothing}\n </div>\n </section>\n\n ${\n state.tab === \"overview\"\n ? consoleViews.overview.render(state, {\n connected: state.connected,\n hello: state.hello,\n settings: state.settings,\n password: state.password,\n lastError: state.lastError,\n lastErrorCode: state.lastErrorCode,\n presenceCount,\n sessionsCount,\n cronEnabled: state.cronStatus?.enabled ?? null,\n cronNext,\n lastChannelsRefresh: state.channelsLastSuccess,\n onSettingsChange: (next) => state.applySettings(next),\n onPasswordChange: (next) => (state.password = next),\n onSessionKeyChange: (next) => {\n state.sessionKey = next;\n state.chatMessage = \"\";\n state.resetToolStream();\n state.applySettings({\n ...state.settings,\n sessionKey: next,\n lastActiveSessionKey: next,\n });\n void state.loadAssistantIdentity();\n },\n onConnect: () => state.connect(),\n onRefresh: () => state.loadOverview(),\n })\n : nothing\n }\n\n ${\n state.tab === \"channels\"\n ? consoleViews.channels.render(state, {\n connected: state.connected,\n loading: state.channelsLoading,\n snapshot: state.channelsSnapshot,\n lastError: state.channelsError,\n lastSuccessAt: state.channelsLastSuccess,\n whatsappMessage: state.whatsappLoginMessage,\n whatsappQrDataUrl: state.whatsappLoginQrDataUrl,\n whatsappConnected: state.whatsappLoginConnected,\n whatsappBusy: state.whatsappBusy,\n configSchema: state.configSchema,\n configSchemaLoading: state.configSchemaLoading,\n configForm: state.configForm,\n configUiHints: state.configUiHints,\n configSaving: state.configSaving,\n configFormDirty: state.configFormDirty,\n nostrProfileFormState: state.nostrProfileFormState,\n nostrProfileAccountId: state.nostrProfileAccountId,\n activeRuns: state.sessionRunsResult?.runs ?? [],\n onRefresh: (probe) => loadChannels(state, probe),\n onWhatsAppStart: (force) => state.handleWhatsAppStart(force),\n onWhatsAppWait: () => state.handleWhatsAppWait(),\n onWhatsAppLogout: () => state.handleWhatsAppLogout(),\n onConfigPatch: (path, value) => updateConfigFormValue(state, path, value),\n onConfigSave: () => state.handleChannelConfigSave(),\n onConfigReload: () => state.handleChannelConfigReload(),\n onNostrProfileEdit: (accountId, profile) =>\n state.handleNostrProfileEdit(accountId, profile),\n onNostrProfileCancel: () => state.handleNostrProfileCancel(),\n onNostrProfileFieldChange: (field, value) =>\n state.handleNostrProfileFieldChange(field, value),\n onNostrProfileSave: () => state.handleNostrProfileSave(),\n onNostrProfileImport: () => state.handleNostrProfileImport(),\n onNostrProfileToggleAdvanced: () => state.handleNostrProfileToggleAdvanced(),\n })\n : nothing\n }\n\n ${\n state.tab === \"instances\"\n ? consoleViews.instances.render(state, {\n loading: state.presenceLoading,\n entries: state.presenceEntries,\n lastError: state.presenceError,\n statusMessage: state.presenceStatus,\n onRefresh: () => loadPresence(state),\n })\n : nothing\n }\n\n ${\n state.tab === \"sessions\"\n ? consoleViews.sessions.render(state, {\n loading: state.sessionsLoading,\n result: state.sessionsResult,\n error: state.sessionsError,\n activeMinutes: state.sessionsFilterActive,\n limit: state.sessionsFilterLimit,\n includeGlobal: state.sessionsIncludeGlobal,\n includeUnknown: state.sessionsIncludeUnknown,\n basePath: state.basePath,\n runs: state.sessionRunsResult?.runs ?? [],\n runsCapturedAt: state.sessionRunsResult?.capturedAt ?? 0,\n runsFetchedAt: state.sessionRunsFetchedAt,\n runsStuckThresholdMs: state.sessionRunsResult?.stuckThresholdMs ?? 0,\n perAgentThresholdMs: state.sessionsThresholdsResult?.byAgentId ?? {},\n runsError: state.sessionRunsError,\n runsThresholdsError: state.sessionsThresholdsError,\n recentlyCompletedRuns: state.recentlyCompletedRuns,\n onFiltersChange: (next) => {\n state.sessionsFilterActive = next.activeMinutes;\n state.sessionsFilterLimit = next.limit;\n state.sessionsIncludeGlobal = next.includeGlobal;\n state.sessionsIncludeUnknown = next.includeUnknown;\n },\n onRefresh: () => {\n void loadSessions(state);\n void loadSessionRuns(state);\n void loadSessionThresholds(state);\n void loadRecoverableRuns(state);\n },\n onPatch: (key, patch) => patchSession(state, key, patch),\n onDelete: (key) => deleteSessionAndRefresh(state, key),\n onInterrupt: (key) => void interruptSession(state, key),\n interruptingKeys: state.sessionRunsInterruptingKeys,\n recoverableRuns: state.recoverableRuns,\n recoveryError: state.recoveryError,\n decidingRunIds: state.decidingRunIds,\n onContinue: (sessionRunId, decisionVersion) => {\n if (state.decidingRunIds.has(sessionRunId)) {\n return;\n }\n state.decidingRunIds = new Set([...state.decidingRunIds, sessionRunId]);\n void continueRun(state, sessionRunId, decisionVersion)\n .then((res) => {\n if (res.conflict || !res.ok) {\n void loadRecoverableRuns(state);\n } else {\n state.recoverableRuns = state.recoverableRuns.filter(\n (r) => r.sessionRunId !== sessionRunId,\n );\n }\n })\n .catch(() => {\n void loadRecoverableRuns(state);\n })\n .finally(() => {\n state.decidingRunIds = new Set(\n [...state.decidingRunIds].filter((id) => id !== sessionRunId),\n );\n });\n },\n onCancel: (sessionRunId, decisionVersion) => {\n if (state.decidingRunIds.has(sessionRunId)) {\n return;\n }\n state.decidingRunIds = new Set([...state.decidingRunIds, sessionRunId]);\n void cancelRun(state, sessionRunId, decisionVersion)\n .then((res) => {\n if (res.conflict || !res.ok) {\n void loadRecoverableRuns(state);\n } else {\n state.recoverableRuns = state.recoverableRuns.filter(\n (r) => r.sessionRunId !== sessionRunId,\n );\n }\n })\n .catch(() => {\n void loadRecoverableRuns(state);\n })\n .finally(() => {\n state.decidingRunIds = new Set(\n [...state.decidingRunIds].filter((id) => id !== sessionRunId),\n );\n });\n },\n })\n : nothing\n }\n\n ${renderUsageTab(state)}\n\n ${\n state.tab === \"cron\"\n ? consoleViews.cron.render(state, {\n basePath: state.basePath,\n loading: state.cronLoading,\n jobsLoadingMore: state.cronJobsLoadingMore,\n status: state.cronStatus,\n jobs: visibleCronJobs,\n selectedJob: selectedCronJob,\n jobsTotal: state.cronJobsTotal,\n jobsHasMore: state.cronJobsHasMore,\n jobsQuery: state.cronJobsQuery,\n jobsEnabledFilter: state.cronJobsEnabledFilter,\n jobsScheduleKindFilter: state.cronJobsScheduleKindFilter,\n jobsLastStatusFilter: state.cronJobsLastStatusFilter,\n jobsSortBy: state.cronJobsSortBy,\n jobsSortDir: state.cronJobsSortDir,\n error: state.cronError,\n busy: state.cronBusy,\n lastRunSessionKey: state.cronLastRunSessionKey,\n lastRunJobId: state.cronLastRunJobId,\n runningJobId: state.cronRunningJobId,\n form: state.cronForm,\n fieldErrors: state.cronFieldErrors,\n canSubmit: !hasCronFormErrors(state.cronFieldErrors),\n editingJobId: state.cronEditingJobId,\n creatingJob: state.cronCreatingJob,\n channels: state.channelsSnapshot?.channelMeta?.length\n ? state.channelsSnapshot.channelMeta.map((entry) => entry.id)\n : (state.channelsSnapshot?.channelOrder ?? []),\n channelLabels: state.channelsSnapshot?.channelLabels ?? {},\n channelMeta: state.channelsSnapshot?.channelMeta ?? [],\n runsJobId: state.cronRunsJobId,\n runs: state.cronRuns,\n runsTotal: state.cronRunsTotal,\n runsHasMore: state.cronRunsHasMore,\n runsLoadingMore: state.cronRunsLoadingMore,\n runsScope: state.cronRunsScope,\n runsStatuses: state.cronRunsStatuses,\n runsDeliveryStatuses: state.cronRunsDeliveryStatuses,\n runsStatusFilter: state.cronRunsStatusFilter,\n runsQuery: state.cronRunsQuery,\n runsSortDir: state.cronRunsSortDir,\n agentSuggestions: cronAgentSuggestions,\n modelSuggestions: cronModelSuggestions,\n thinkingSuggestions: CRON_THINKING_SUGGESTIONS,\n timezoneSuggestions: CRON_TIMEZONE_SUGGESTIONS,\n deliveryToSuggestions,\n accountSuggestions,\n onFormChange: (patch) => {\n state.cronForm = normalizeCronFormState({ ...state.cronForm, ...patch });\n state.cronFieldErrors = validateCronForm(state.cronForm, {\n defaultAgentId: state.agentsList?.defaultId,\n });\n },\n onRefresh: () => state.loadCron(),\n onAdd: () => addCronJob(state),\n onCreate: () => startCronCreate(state),\n onEdit: (job) => startCronEdit(state, job),\n onClone: (job) => startCronClone(state, job),\n onCancelEdit: () => cancelCronEdit(state),\n onToggle: (job, enabled) => toggleCronJob(state, job, enabled),\n onRun: (job, mode) => runCronJob(state, job, mode ?? \"force\"),\n onRemove: (job) => removeCronJob(state, job),\n onLoadRuns: async (jobId) => {\n updateCronRunsFilter(state, { cronRunsScope: \"job\" });\n await loadCronRuns(state, jobId);\n },\n onLoadMoreJobs: () => loadMoreCronJobs(state),\n onJobsFiltersChange: async (patch) => {\n updateCronJobsFilter(state, patch);\n const shouldReload =\n typeof patch.cronJobsQuery === \"string\" ||\n Boolean(patch.cronJobsEnabledFilter) ||\n Boolean(patch.cronJobsSortBy) ||\n Boolean(patch.cronJobsSortDir);\n if (shouldReload) {\n await reloadCronJobs(state);\n }\n },\n onJobsFiltersReset: async () => {\n updateCronJobsFilter(state, {\n cronJobsQuery: \"\",\n cronJobsEnabledFilter: \"all\",\n cronJobsScheduleKindFilter: \"all\",\n cronJobsLastStatusFilter: \"all\",\n cronJobsSortBy: \"nextRunAtMs\",\n cronJobsSortDir: \"asc\",\n });\n await reloadCronJobs(state);\n },\n onLoadMoreRuns: () => loadMoreCronRuns(state),\n onRunsFiltersChange: async (patch) => {\n updateCronRunsFilter(state, patch);\n if (state.cronRunsScope === \"all\") {\n await loadCronRuns(state, null);\n return;\n }\n await loadCronRuns(state, state.cronRunsJobId);\n },\n })\n : nothing\n }\n\n ${\n state.tab === \"learning\"\n ? consoleViews.learning.render(state, {\n subView: state.learningSubView,\n loading: state.learningLoading,\n error: state.learningError,\n busy: state.learningBusy,\n overview: state.overview,\n proposals: state.proposals,\n lessons: state.lessons,\n selectedProposal: state.selectedProposal,\n pendingApplyId: state.learningPendingApplyId,\n onSelectSubView: (v) => {\n state.learningSubView = v;\n },\n onOpenProposal: (id) => void state.openLearningProposal(id),\n onDecide: (id, action) => void state.decideLearningProposal(id, action),\n onRequestApply: (id) => {\n state.learningPendingApplyId = id;\n },\n onConfirmApply: (id) => {\n state.learningPendingApplyId = null;\n void state.decideLearningProposal(id, \"apply\");\n },\n onCancelApply: () => {\n state.learningPendingApplyId = null;\n },\n onOpenLesson: () => {},\n })\n : nothing\n }\n\n ${\n state.tab === \"dreams\"\n ? consoleViews.dreams.render(state, {\n state: state.dreams,\n nowMs: Date.now(),\n learningHref: pathForTab(\"learning\", state.basePath),\n onSelectRun: (taskRunId) => state.selectDreamsRun(taskRunId),\n onRefresh: () => void state.loadDreams(),\n onOpenLearning: () => state.setTab(\"learning\"),\n })\n : nothing\n }\n\n ${\n state.tab === \"agents\"\n ? consoleViews.agents.render(state, {\n loading: state.agentsLoading,\n error: state.agentsError,\n agentsList: state.agentsList,\n selectedAgentId: resolvedAgentId,\n activePanel: state.agentsPanel,\n configForm: configValue,\n configLoading: state.configLoading,\n configSaving: state.configSaving,\n configDirty: state.configFormDirty,\n channelsLoading: state.channelsLoading,\n channelsError: state.channelsError,\n channelsSnapshot: state.channelsSnapshot,\n channelsLastSuccess: state.channelsLastSuccess,\n cronLoading: state.cronLoading,\n cronStatus: state.cronStatus,\n cronJobs: state.cronJobs,\n cronError: state.cronError,\n agentFilesLoading: state.agentFilesLoading,\n agentFilesError: state.agentFilesError,\n agentFilesList: state.agentFilesList,\n agentFileActive: state.agentFileActive,\n agentFileContents: state.agentFileContents,\n agentFileDrafts: state.agentFileDrafts,\n agentFileSaving: state.agentFileSaving,\n agentIdentityLoading: state.agentIdentityLoading,\n agentIdentityError: state.agentIdentityError,\n agentIdentityById: state.agentIdentityById,\n agentSkillsLoading: state.agentSkillsLoading,\n agentSkillsReport: state.agentSkillsReport,\n agentSkillsError: state.agentSkillsError,\n agentSkillsAgentId: state.agentSkillsAgentId,\n toolsCatalogLoading: state.toolsCatalogLoading,\n toolsCatalogError: state.toolsCatalogError,\n toolsCatalogResult: state.toolsCatalogResult,\n skillsFilter: state.skillsFilter,\n onRefresh: async () => {\n await loadAgents(state);\n const nextSelected =\n state.agentsSelectedId ??\n state.agentsList?.defaultId ??\n state.agentsList?.agents?.[0]?.id ??\n null;\n await loadToolsCatalog(state, nextSelected);\n const agentIds = state.agentsList?.agents?.map((entry) => entry.id) ?? [];\n if (agentIds.length > 0) {\n void loadAgentIdentities(state, agentIds);\n }\n },\n onSelectAgent: (agentId) => {\n if (state.agentsSelectedId === agentId) {\n return;\n }\n state.agentsSelectedId = agentId;\n state.agentFilesList = null;\n state.agentFilesError = null;\n state.agentFilesLoading = false;\n state.agentFileActive = null;\n state.agentFileContents = {};\n state.agentFileDrafts = {};\n state.agentSkillsReport = null;\n state.agentSkillsError = null;\n state.agentSkillsAgentId = null;\n void loadAgentIdentity(state, agentId);\n if (state.agentsPanel === \"tools\") {\n void loadToolsCatalog(state, agentId);\n }\n if (state.agentsPanel === \"files\") {\n void loadAgentFiles(state, agentId);\n }\n if (state.agentsPanel === \"skills\") {\n void loadAgentSkills(state, agentId);\n }\n },\n onNudgeAgent: (agentId: string) => {\n void nudgeAgent(state, agentId, \"Check in\");\n },\n onSelectPanel: (panel) => {\n state.agentsPanel = panel;\n if (panel === \"files\" && resolvedAgentId) {\n if (state.agentFilesList?.agentId !== resolvedAgentId) {\n state.agentFilesList = null;\n state.agentFilesError = null;\n state.agentFileActive = null;\n state.agentFileContents = {};\n state.agentFileDrafts = {};\n void loadAgentFiles(state, resolvedAgentId);\n }\n }\n if (panel === \"tools\") {\n void loadToolsCatalog(state, resolvedAgentId);\n }\n if (panel === \"skills\") {\n if (resolvedAgentId) {\n void loadAgentSkills(state, resolvedAgentId);\n }\n }\n if (panel === \"channels\") {\n void loadChannels(state, false);\n }\n if (panel === \"cron\") {\n void state.loadCron();\n }\n },\n onLoadFiles: (agentId) => loadAgentFiles(state, agentId),\n onSelectFile: (name) => {\n state.agentFileActive = name;\n if (!resolvedAgentId) {\n return;\n }\n void loadAgentFileContent(state, resolvedAgentId, name);\n },\n onFileDraftChange: (name, content) => {\n state.agentFileDrafts = { ...state.agentFileDrafts, [name]: content };\n },\n onFileReset: (name) => {\n const base = state.agentFileContents[name] ?? \"\";\n state.agentFileDrafts = { ...state.agentFileDrafts, [name]: base };\n },\n onFileSave: (name) => {\n if (!resolvedAgentId) {\n return;\n }\n const content =\n state.agentFileDrafts[name] ?? state.agentFileContents[name] ?? \"\";\n void saveAgentFile(state, resolvedAgentId, name, content);\n },\n onToolsProfileChange: (agentId, profile, clearAllow) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"tools\"];\n if (profile) {\n updateConfigFormValue(state, [...basePath, \"profile\"], profile);\n } else {\n removeConfigFormValue(state, [...basePath, \"profile\"]);\n }\n if (clearAllow) {\n removeConfigFormValue(state, [...basePath, \"allow\"]);\n }\n },\n onToolsExecPresetChange: (agentId, preset) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"tools\"];\n if (preset) {\n updateConfigFormValue(state, [...basePath, \"exec\", \"preset\"], preset);\n } else {\n removeConfigFormValue(state, [...basePath, \"exec\", \"preset\"]);\n }\n },\n onToolsOverridesChange: (agentId, alsoAllow, deny) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"tools\"];\n if (alsoAllow.length > 0) {\n updateConfigFormValue(state, [...basePath, \"alsoAllow\"], alsoAllow);\n } else {\n removeConfigFormValue(state, [...basePath, \"alsoAllow\"]);\n }\n if (deny.length > 0) {\n updateConfigFormValue(state, [...basePath, \"deny\"], deny);\n } else {\n removeConfigFormValue(state, [...basePath, \"deny\"]);\n }\n },\n onConfigReload: () => loadConfig(state),\n onConfigSave: async () => {\n await saveConfig(state);\n if (state.agentsPanel === \"tools\" && resolvedAgentId) {\n void loadToolsCatalog(state, resolvedAgentId);\n }\n },\n onChannelsRefresh: () => loadChannels(state, false),\n onCronRefresh: () => state.loadCron(),\n onSkillsFilterChange: (next) => (state.skillsFilter = next),\n onSkillsRefresh: () => {\n if (resolvedAgentId) {\n void loadAgentSkills(state, resolvedAgentId);\n }\n },\n onAgentSkillToggle: (agentId, skillName, enabled) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const entry = list[index] as { skills?: unknown };\n const normalizedSkill = skillName.trim();\n if (!normalizedSkill) {\n return;\n }\n const allSkills =\n state.agentSkillsReport?.skills?.map((skill) => skill.name).filter(Boolean) ??\n [];\n const existing = Array.isArray(entry.skills)\n ? entry.skills.map((name) => String(name).trim()).filter(Boolean)\n : undefined;\n const base = existing ?? allSkills;\n const next = new Set(base);\n if (enabled) {\n next.add(normalizedSkill);\n } else {\n next.delete(normalizedSkill);\n }\n updateConfigFormValue(state, [\"agents\", \"list\", index, \"skills\"], [...next]);\n },\n onAgentSkillsClear: (agentId) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n removeConfigFormValue(state, [\"agents\", \"list\", index, \"skills\"]);\n },\n onAgentSkillsDisableAll: (agentId) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n updateConfigFormValue(state, [\"agents\", \"list\", index, \"skills\"], []);\n },\n onModelChange: (agentId, modelId) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"model\"];\n if (!modelId) {\n removeConfigFormValue(state, basePath);\n return;\n }\n const entry = list[index] as { model?: unknown };\n const existing = entry?.model;\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\n const fallbacks = (existing as { fallbacks?: unknown }).fallbacks;\n const next = {\n primary: modelId,\n ...(Array.isArray(fallbacks) ? { fallbacks } : {}),\n };\n updateConfigFormValue(state, basePath, next);\n } else {\n updateConfigFormValue(state, basePath, modelId);\n }\n },\n onModelFallbacksChange: (agentId, fallbacks) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"model\"];\n const entry = list[index] as { model?: unknown };\n const normalized = fallbacks.map((name) => name.trim()).filter(Boolean);\n const existing = entry.model;\n const resolvePrimary = () => {\n if (typeof existing === \"string\") {\n return existing.trim() || null;\n }\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\n const primary = (existing as { primary?: unknown }).primary;\n if (typeof primary === \"string\") {\n const trimmed = primary.trim();\n return trimmed || null;\n }\n }\n return null;\n };\n const primary = resolvePrimary();\n if (normalized.length === 0) {\n if (primary) {\n updateConfigFormValue(state, basePath, primary);\n } else {\n removeConfigFormValue(state, basePath);\n }\n return;\n }\n const next = primary\n ? { primary, fallbacks: normalized }\n : { fallbacks: normalized };\n updateConfigFormValue(state, basePath, next);\n },\n })\n : nothing\n }\n\n ${\n state.tab === \"skills\"\n ? consoleViews.skills.render(state, {\n loading: state.skillsLoading,\n report: state.skillsReport,\n error: state.skillsError,\n filter: state.skillsFilter,\n edits: state.skillEdits,\n messages: state.skillMessages,\n busyKey: state.skillsBusyKey,\n onFilterChange: (next) => (state.skillsFilter = next),\n onRefresh: () => loadSkills(state, { clearMessages: true }),\n onToggle: (key, enabled) => updateSkillEnabled(state, key, enabled),\n onEdit: (key, value) => updateSkillEdit(state, key, value),\n onSaveKey: (key) => saveSkillApiKey(state, key),\n onInstall: (skillKey, name, installId) =>\n installSkill(state, skillKey, name, installId),\n })\n : nothing\n }\n\n ${\n state.tab === \"nodes\"\n ? consoleViews.nodes.render(state, {\n loading: state.nodesLoading,\n nodes: state.nodes,\n devicesLoading: state.devicesLoading,\n devicesError: state.devicesError,\n devicesList: state.devicesList,\n configForm:\n state.configForm ??\n (state.configSnapshot?.config as Record<string, unknown> | null),\n configLoading: state.configLoading,\n configSaving: state.configSaving,\n configDirty: state.configFormDirty,\n configFormMode: state.configFormMode,\n execApprovalsLoading: state.execApprovalsLoading,\n execApprovalsSaving: state.execApprovalsSaving,\n execApprovalsDirty: state.execApprovalsDirty,\n execApprovalsSnapshot: state.execApprovalsSnapshot,\n execApprovalsForm: state.execApprovalsForm,\n execApprovalsSelectedAgent: state.execApprovalsSelectedAgent,\n execApprovalsTarget: state.execApprovalsTarget,\n execApprovalsTargetNodeId: state.execApprovalsTargetNodeId,\n onRefresh: () => loadNodes(state),\n onDevicesRefresh: () => loadDevices(state),\n onDeviceApprove: (requestId) => approveDevicePairing(state, requestId),\n onDeviceReject: (requestId) => rejectDevicePairing(state, requestId),\n onDeviceRotate: (deviceId, role, scopes) =>\n rotateDeviceToken(state, { deviceId, role, scopes }),\n onDeviceRevoke: (deviceId, role) => revokeDeviceToken(state, { deviceId, role }),\n onLoadConfig: () => loadConfig(state),\n onLoadExecApprovals: () => {\n const target =\n state.execApprovalsTarget === \"node\" && state.execApprovalsTargetNodeId\n ? { kind: \"node\" as const, nodeId: state.execApprovalsTargetNodeId }\n : { kind: \"gateway\" as const };\n return loadExecApprovals(state, target);\n },\n onBindDefault: (nodeId) => {\n if (nodeId) {\n updateConfigFormValue(state, [\"tools\", \"exec\", \"node\"], nodeId);\n } else {\n removeConfigFormValue(state, [\"tools\", \"exec\", \"node\"]);\n }\n },\n onBindAgent: (agentIndex, nodeId) => {\n const basePath = [\"agents\", \"list\", agentIndex, \"tools\", \"exec\", \"node\"];\n if (nodeId) {\n updateConfigFormValue(state, basePath, nodeId);\n } else {\n removeConfigFormValue(state, basePath);\n }\n },\n onSaveBindings: () => saveConfig(state),\n onExecApprovalsTargetChange: (kind, nodeId) => {\n state.execApprovalsTarget = kind;\n state.execApprovalsTargetNodeId = nodeId;\n state.execApprovalsSnapshot = null;\n state.execApprovalsForm = null;\n state.execApprovalsDirty = false;\n state.execApprovalsSelectedAgent = null;\n },\n onExecApprovalsSelectAgent: (agentId) => {\n state.execApprovalsSelectedAgent = agentId;\n },\n onExecApprovalsPatch: (path, value) =>\n updateExecApprovalsFormValue(state, path, value),\n onExecApprovalsRemove: (path) => removeExecApprovalsFormValue(state, path),\n onSaveExecApprovals: () => {\n const target =\n state.execApprovalsTarget === \"node\" && state.execApprovalsTargetNodeId\n ? { kind: \"node\" as const, nodeId: state.execApprovalsTargetNodeId }\n : { kind: \"gateway\" as const };\n return saveExecApprovals(state, target);\n },\n })\n : nothing\n }\n\n ${\n state.onboarding && isChat\n ? html`\n <div class=\"brand-hero\">\n <img\n src=${basePath ? `${basePath}/brand/wednesdayai-logo-bricks.png` : \"/brand/wednesdayai-logo-bricks.png\"}\n alt=\"\"\n class=\"brand-hero__img\"\n />\n </div>\n `\n : nothing\n }\n\n ${\n state.tab === \"chat\"\n ? consoleViews.chat.render(state, {\n sessionKey: state.sessionKey,\n onSessionKeyChange: (next) => {\n state.sessionKey = next;\n state.chatMessage = \"\";\n state.chatAttachments = [];\n state.chatStream = null;\n state.chatStreamStartedAt = null;\n state.chatRunId = null;\n state.chatQueue = [];\n state.resetToolStream();\n state.resetChatScroll();\n state.applySettings({\n ...state.settings,\n sessionKey: next,\n lastActiveSessionKey: next,\n });\n void state.loadAssistantIdentity();\n void loadChatHistory(state);\n void refreshChatAvatar(state);\n },\n thinkingLevel: state.chatThinkingLevel,\n showThinking,\n loading: state.chatLoading,\n sending: state.chatSending,\n compactionStatus: state.compactionStatus,\n fallbackStatus: state.fallbackStatus,\n assistantAvatarUrl: chatAvatarUrl,\n messages: state.chatMessages,\n toolMessages: state.chatToolMessages,\n stream: state.chatStream,\n streamStartedAt: state.chatStreamStartedAt,\n draft: state.chatMessage,\n queue: state.chatQueue,\n connected: state.connected,\n canSend: state.connected,\n disabledReason: chatDisabledReason,\n error: state.lastError,\n sessions: state.sessionsResult,\n focusMode: chatFocus,\n onRefresh: () => {\n state.resetToolStream();\n return Promise.all([loadChatHistory(state), refreshChatAvatar(state)]);\n },\n onToggleFocusMode: () => {\n if (state.onboarding) {\n return;\n }\n state.applySettings({\n ...state.settings,\n chatFocusMode: !state.settings.chatFocusMode,\n });\n },\n onChatScroll: (event) => state.handleChatScroll(event),\n onDraftChange: (next) => (state.chatMessage = next),\n attachments: state.chatAttachments,\n onAttachmentsChange: (next) => (state.chatAttachments = next),\n onSend: () => state.handleSendChat(),\n canAbort: Boolean(state.chatRunId),\n onAbort: () => void state.handleAbortChat(),\n onQueueRemove: (id) => state.removeQueuedMessage(id),\n onNewSession: () => state.handleSendChat(\"/new\", { restoreDraft: true }),\n showNewMessages: state.chatNewMessagesBelow && !state.chatManualRefreshInFlight,\n onScrollToBottom: () => state.scrollToBottom(),\n // Sidebar props for tool output viewing\n sidebarOpen: state.sidebarOpen,\n sidebarContent: state.sidebarContent,\n sidebarError: state.sidebarError,\n splitRatio: state.splitRatio,\n onOpenSidebar: (content: string) => state.handleOpenSidebar(content),\n onCloseSidebar: () => state.handleCloseSidebar(),\n onSplitRatioChange: (ratio: number) => state.handleSplitRatioChange(ratio),\n assistantName: state.assistantName,\n assistantAvatar: state.assistantAvatar,\n })\n : nothing\n }\n\n ${\n state.tab === \"talk\"\n ? !state.connected\n ? renderTalkAvailabilityGuard(state, t(\"talk.reconnecting\"))\n : !talkAvailability.resolved || talkAvailability.loading\n ? renderTalkAvailabilityGuard(state, t(\"talk.loading\"))\n : talkAvailable\n ? consoleViews.talk.render(state, {\n ...state.talkState,\n unavailable: null,\n onStart: () => void state.handleTalkStart(),\n onStop: () => void state.handleTalkStop(),\n onRetry: () => void state.handleTalkRetry(),\n })\n : renderTalkAvailabilityGuard(state, t(\"talk.unavailable\"))\n : nothing\n }\n\n ${\n state.tab === \"config\"\n ? consoleViews.config.render(state, {\n raw: state.configRaw,\n originalRaw: state.configRawOriginal,\n valid: state.configValid,\n issues: state.configIssues,\n loading: state.configLoading,\n saving: state.configSaving,\n applying: state.configApplying,\n updating: state.updateRunning,\n connected: state.connected,\n schema: state.configSchema,\n schemaLoading: state.configSchemaLoading,\n uiHints: state.configUiHints,\n formMode: state.configFormMode,\n formValue: state.configForm,\n originalValue: state.configFormOriginal,\n searchQuery: state.configSearchQuery,\n activeSection: state.configActiveSection,\n activeSubsection: state.configActiveSubsection,\n onRawChange: (next) => {\n state.configRaw = next;\n },\n onFormModeChange: (mode) => (state.configFormMode = mode),\n onFormPatch: (path, value) => updateConfigFormValue(state, path, value),\n onSearchChange: (query) => (state.configSearchQuery = query),\n onSectionChange: (section) => {\n state.configActiveSection = section;\n state.configActiveSubsection = null;\n },\n onSubsectionChange: (section) => (state.configActiveSubsection = section),\n onReload: () => loadConfig(state),\n onSave: () => saveConfig(state),\n onApply: () => applyConfig(state),\n onUpdate: () => runUpdate(state),\n })\n : nothing\n }\n\n ${\n state.tab === \"debug\"\n ? consoleViews.debug.render(state, {\n loading: state.debugLoading,\n status: state.debugStatus,\n health: state.debugHealth,\n models: state.debugModels,\n heartbeat: state.debugHeartbeat,\n eventLog: state.eventLog,\n callMethod: state.debugCallMethod,\n callParams: state.debugCallParams,\n callResult: state.debugCallResult,\n callError: state.debugCallError,\n onCallMethodChange: (next) => (state.debugCallMethod = next),\n onCallParamsChange: (next) => (state.debugCallParams = next),\n onRefresh: () => loadDebug(state),\n onCall: () => callDebugMethod(state),\n })\n : nothing\n }\n\n ${\n state.tab === \"logs\"\n ? consoleViews.logs.render(state, {\n loading: state.logsLoading,\n error: state.logsError,\n file: state.logsFile,\n entries: state.logsEntries,\n filterText: state.logsFilterText,\n levelFilters: state.logsLevelFilters,\n autoFollow: state.logsAutoFollow,\n truncated: state.logsTruncated,\n onFilterTextChange: (next) => (state.logsFilterText = next),\n onLevelToggle: (level, enabled) => {\n state.logsLevelFilters = { ...state.logsLevelFilters, [level]: enabled };\n },\n onToggleAutoFollow: (next) => (state.logsAutoFollow = next),\n onRefresh: () => loadLogs(state, { reset: true }),\n onExport: (lines, label) => state.exportLogs(lines, label),\n onScroll: (event) => state.handleLogsScroll(event),\n })\n : nothing\n }\n </main>\n ${renderExecApprovalPrompt(state)}\n ${renderGatewayUrlConfirmation(state)}\n </div>\n `;\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\n\nexport type ScopeLabel = {\n workspaceId?: string;\n agentId?: string;\n workspaceLabel: string;\n agentLabel: string;\n};\n\nexport type LearningProposalRow = {\n id: string;\n title: string;\n status: \"pending\" | \"applied\" | \"rejected\" | \"quarantined\";\n scopeLabel?: ScopeLabel;\n findingCount?: number;\n};\n\nexport type LearningLessonRow = {\n id: string;\n kind: \"correction\" | \"preference\" | \"procedure\" | \"failure\";\n text: string;\n confidence?: number;\n occurrences?: number;\n distinctSessions?: number;\n scopeLabel?: ScopeLabel;\n recordKind?: \"lesson\" | \"skill\";\n durability?: \"durable\" | \"decaying\" | \"ephemeral\";\n validFrom?: string;\n invalidAt?: string;\n supersedesId?: string;\n sessionId?: string;\n};\n\nexport type LearningOverview = {\n proposals: { pending: number; applied: number; rejected: number; quarantined: number };\n lessons: number;\n scopes: number;\n backend?: \"sqlite\" | \"postgres\";\n capability?: \"full\";\n};\n\nexport type LearningProposalDetail = {\n id: string;\n body: string;\n scannerFindings: unknown[];\n sourceLessonIds: string[];\n history: unknown[];\n scopeLabel?: ScopeLabel;\n};\n\nexport type LearningDecisionAction = \"apply\" | \"reject\" | \"quarantine\";\n\nexport type LearningState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n learningLoading: boolean;\n learningError: string | null;\n overview: LearningOverview | null;\n proposals: LearningProposalRow[];\n lessons: LearningLessonRow[];\n selectedProposal: LearningProposalDetail | null;\n learningBusy: boolean;\n searchGeneration: number;\n};\n\nexport function createDefaultLearningState(): LearningState {\n return {\n client: null,\n connected: false,\n learningLoading: false,\n learningError: null,\n overview: null,\n proposals: [],\n lessons: [],\n selectedProposal: null,\n learningBusy: false,\n searchGeneration: 0,\n };\n}\n\nexport async function loadLearningOverview(state: LearningState): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<LearningOverview>(\"learning.overview\", {});\n state.overview = res;\n } catch (err) {\n state.learningError = String(err);\n }\n}\n\nexport async function loadProposals(state: LearningState): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<{ proposals: LearningProposalRow[] }>(\n \"learning.listProposals\",\n {},\n );\n state.proposals = res.proposals ?? [];\n } catch (err) {\n state.learningError = String(err);\n }\n}\n\nexport async function loadLessons(state: LearningState): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<{ lessons: LearningLessonRow[] }>(\n \"learning.listLessons\",\n {},\n );\n state.lessons = res.lessons ?? [];\n } catch (err) {\n state.learningError = String(err);\n }\n}\n\nexport async function inspectProposal(state: LearningState, proposalId: string): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<LearningProposalDetail>(\"learning.inspectProposal\", {\n proposalId,\n });\n state.selectedProposal = res;\n } catch (err) {\n state.learningError = String(err);\n }\n}\n\nexport async function decideProposal(\n state: LearningState,\n proposalId: string,\n action: LearningDecisionAction,\n): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.learningBusy) {\n return;\n }\n state.learningBusy = true;\n try {\n await state.client.request(\"learning.decideProposal\", { proposalId, action });\n await loadProposals(state);\n await loadLearningOverview(state);\n } catch (err) {\n state.learningError = String(err);\n } finally {\n state.learningBusy = false;\n }\n}\n\nexport async function searchLessons(state: LearningState, query: string): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n const trimmed = query.trim();\n const token = state.searchGeneration + 1;\n state.searchGeneration = token;\n if (!trimmed) {\n await loadLessons(state);\n return;\n }\n try {\n const res = await state.client.request<{\n hits: Array<{ lesson: LearningLessonRow; score: number; sessionId?: string }>;\n }>(\"learning.searchLessons\", { query: trimmed, k: 20 });\n if (state.searchGeneration !== token) {\n return;\n }\n state.lessons = (res.hits ?? []).map((hit) => ({\n ...hit.lesson,\n sessionId: hit.sessionId ?? hit.lesson.sessionId,\n }));\n } catch (err) {\n if (state.searchGeneration !== token) {\n return;\n }\n state.learningError = String(err);\n }\n}\n\nexport async function decideProposals(\n state: LearningState,\n ids: string[],\n action: LearningDecisionAction,\n): Promise<void> {\n if (!state.client || !state.connected || ids.length === 0) {\n return;\n }\n if (state.learningBusy) {\n return;\n }\n state.learningBusy = true;\n try {\n await state.client.request(\"learning.decideProposals\", { ids, action });\n await loadProposals(state);\n await loadLearningOverview(state);\n } catch (err) {\n state.learningError = String(err);\n } finally {\n state.learningBusy = false;\n }\n}\n","import type {\n TalkLifecycle,\n TalkRealtimeRelayEvent,\n TalkRealtimeTranscriptStatus,\n TalkSessionClient,\n TalkSessionClientState,\n} from \"talk-client\";\n\nexport type TalkTranscriptEntry = {\n id: string;\n relaySessionId: string;\n role: \"user\" | \"assistant\";\n text: string;\n final: boolean;\n itemId?: string;\n responseId?: string;\n contentIndex?: number;\n itemOrder?: number;\n status?: TalkRealtimeTranscriptStatus;\n startedAtMs: number;\n completedAtMs?: number;\n};\n\nexport type TalkAvailabilityState = {\n resolved: boolean;\n loading: boolean;\n enabled: boolean;\n available: boolean;\n configuredProviderIds: string[];\n error: string | null;\n};\n\nexport type TalkState = {\n lifecycle: TalkLifecycle;\n relaySessionId: string | null;\n provider: string | null;\n transcript: TalkTranscriptEntry[];\n error: string | null;\n recording: boolean;\n playing: boolean;\n droppedAudioFrames: number;\n availability: TalkAvailabilityState;\n};\n\nexport const DEFAULT_TALK_STATE: TalkState = {\n lifecycle: \"idle\",\n relaySessionId: null,\n provider: null,\n transcript: [],\n error: null,\n recording: false,\n playing: false,\n droppedAudioFrames: 0,\n availability: {\n resolved: false,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: null,\n },\n};\n\nexport function createDefaultTalkState(): TalkState {\n return {\n ...DEFAULT_TALK_STATE,\n transcript: DEFAULT_TALK_STATE.transcript.map((entry) => ({ ...entry })),\n availability: {\n ...DEFAULT_TALK_STATE.availability,\n configuredProviderIds: [...DEFAULT_TALK_STATE.availability.configuredProviderIds],\n },\n };\n}\n\nexport type TalkController = {\n start(): Promise<void>;\n stop(): Promise<void>;\n retry(): Promise<void>;\n reconnectIfIntended(): Promise<void>;\n handleRelayEvent(event: TalkRealtimeRelayEvent): void;\n handleSessionEvent(event: TalkRealtimeRelayEvent): void;\n handleSessionState(state: TalkSessionClientState): void;\n handleGatewayClose(): void;\n loadAvailability(): Promise<void>;\n};\n\nexport type TalkControllerOptions = {\n sessionClient: TalkSessionClient;\n onState: (state: TalkState) => void;\n now?: () => number;\n request?: <T>(method: string, params?: unknown) => Promise<T>;\n};\n\nfunction normalizeError(error: unknown, fallback: string): string {\n if (error instanceof Error && error.message.trim()) {\n return error.message.trim();\n }\n if (typeof error === \"string\" && error.trim()) {\n return error.trim();\n }\n return fallback;\n}\n\ntype TalkCommand = {\n generation: number;\n promise: Promise<void>;\n resolve: () => void;\n reject: (error: unknown) => void;\n gatewayCloseError?: string | null;\n};\n\nfunction createTalkCommand(generation: number): TalkCommand {\n let resolve!: () => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<void>((promiseResolve, promiseReject) => {\n resolve = () => promiseResolve();\n reject = promiseReject;\n });\n return { generation, promise, resolve, reject };\n}\n\nexport function createTalkController(options: TalkControllerOptions): TalkController {\n const now = options.now ?? Date.now;\n const MAX_EPOCH_MS = 8.64e15;\n const validEpochMs = (value: unknown): value is number =>\n Number.isInteger(value) && (value as number) >= 0 && (value as number) <= MAX_EPOCH_MS;\n const readNow = (): number => {\n const value = now();\n if (!validEpochMs(value)) {\n throw new Error(\"Talk clock returned an invalid epoch millisecond value\");\n }\n return value;\n };\n let state: TalkState = createDefaultTalkState();\n let commandGeneration = 0;\n let availabilityGeneration = 0;\n let transcriptSequence = 0;\n let relaySessionSequence = 0;\n const relaySessionOrders = new Map<string, number>();\n let startCommand: TalkCommand | null = null;\n let stopCommand: TalkCommand | null = null;\n let startBarrier: Promise<void> | null = null;\n let intendedActive = false;\n let intentGeneration = 0;\n let reconnectInFlight: Promise<void> | null = null;\n let reconnectIntentGeneration: number | null = null;\n let pendingInterruptState: TalkSessionClientState | null = null;\n let activePartialTranscriptIds: Record<TalkTranscriptEntry[\"role\"], string | null> = {\n user: null,\n assistant: null,\n };\n let preReducedCloseRelaySessionId: string | null = null;\n let delegatedRelayEvent: TalkRealtimeRelayEvent | null = null;\n let delegatedRelayGeneration: number | null = null;\n\n function publish(patch: Partial<TalkState>) {\n state = { ...state, ...patch };\n options.onState(state);\n }\n\n function publishAvailability(availability: TalkAvailabilityState) {\n publish({\n availability: {\n ...availability,\n configuredProviderIds: [...availability.configuredProviderIds],\n },\n });\n }\n\n function loadAvailability(): Promise<void> {\n const generation = ++availabilityGeneration;\n publishAvailability({\n resolved: false,\n loading: true,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: null,\n });\n\n const request = options.request;\n if (!request) {\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: \"Talk availability requester is unavailable\",\n });\n return Promise.resolve();\n }\n\n let responsePromise: Promise<unknown>;\n try {\n responsePromise = request<unknown>(\"talk.realtime.status\", {});\n } catch (error) {\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: normalizeError(error, \"Talk availability request failed\").slice(0, 200),\n });\n return Promise.resolve();\n }\n\n return responsePromise\n .then((result) => {\n if (!isTalkAvailabilityResponse(result)) {\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: \"Malformed Talk availability response\",\n });\n return;\n }\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: result.enabled,\n available: result.available,\n configuredProviderIds: result.configuredProviderIds,\n error: null,\n });\n })\n .catch((error: unknown) => {\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: normalizeError(error, \"Talk availability request failed\").slice(0, 200),\n });\n });\n }\n\n function publishAvailabilityIfCurrent(\n generation: number,\n availability: TalkAvailabilityState,\n ): void {\n if (availabilityGeneration === generation) {\n publishAvailability(availability);\n }\n }\n\n function isTalkAvailabilityResponse(value: unknown): value is {\n enabled: boolean;\n available: boolean;\n configuredProviderIds: string[];\n } {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const response = value as Record<string, unknown>;\n const configuredProviderIds = response.configuredProviderIds;\n return (\n typeof response.enabled === \"boolean\" &&\n typeof response.available === \"boolean\" &&\n Array.isArray(configuredProviderIds) &&\n configuredProviderIds.every((providerId) => typeof providerId === \"string\") &&\n !(response.available && (!response.enabled || configuredProviderIds.length === 0))\n );\n }\n\n function resetActivePartialTranscripts() {\n activePartialTranscriptIds = { user: null, assistant: null };\n }\n\n function resetToIdle(error: string | null = state.error) {\n pendingInterruptState = null;\n resetActivePartialTranscripts();\n publish({\n lifecycle: \"idle\",\n relaySessionId: null,\n provider: null,\n error,\n recording: false,\n playing: false,\n });\n }\n\n function retainStartBarrier(promise: Promise<void>) {\n const barrier = promise.catch(() => undefined);\n startBarrier = barrier;\n void barrier.then(() => {\n if (startBarrier === barrier) {\n startBarrier = null;\n }\n });\n }\n\n function disassociateStartCommand() {\n if (startCommand) {\n retainStartBarrier(startCommand.promise);\n }\n startCommand = null;\n }\n\n function beginStart(generation: number, waitFor?: Promise<void>): Promise<void> {\n resetActivePartialTranscripts();\n const command = createTalkCommand(generation);\n startCommand = command;\n void command.promise.then(\n () => {\n if (startCommand === command) {\n startCommand = null;\n }\n },\n () => {\n if (startCommand === command) {\n startCommand = null;\n }\n },\n );\n publish({ lifecycle: \"starting\", error: null, recording: false, playing: false });\n if (commandGeneration !== command.generation || startCommand !== command) {\n command.resolve();\n return command.promise;\n }\n const run = (async () => {\n if (waitFor) {\n await waitFor;\n if (commandGeneration !== command.generation || startCommand !== command) {\n return;\n }\n }\n try {\n await options.sessionClient.start();\n } catch (error) {\n if (commandGeneration === command.generation && startCommand === command) {\n resetToIdle(normalizeError(error, \"Unable to start Talk\"));\n }\n return;\n }\n if (commandGeneration !== command.generation || startCommand !== command) {\n return;\n }\n })();\n void run.then(command.resolve, command.reject);\n return command.promise;\n }\n\n function start(): Promise<void> {\n intendedActive = true;\n intentGeneration += 1;\n if (startCommand) {\n return startCommand.promise;\n }\n if (!stopCommand && (state.lifecycle === \"active\" || state.lifecycle === \"interrupting\")) {\n return Promise.resolve();\n }\n const generation = ++commandGeneration;\n // A reconnect still in flight after the intent bump above is dead; the new\n // start must chain after it settles or handleSessionState would swallow\n // its client echoes for as long as the stale reconnect is in flight.\n const staleReconnect =\n reconnectInFlight !== null && reconnectIntentGeneration !== intentGeneration\n ? reconnectInFlight\n : null;\n const barriers = [stopCommand?.promise, startBarrier, staleReconnect].filter(\n (barrier): barrier is Promise<void> => barrier !== undefined && barrier !== null,\n );\n const waitFor =\n barriers.length === 0\n ? undefined\n : barriers.length === 1\n ? barriers[0]\n : Promise.all(barriers).then(() => undefined);\n return beginStart(generation, waitFor);\n }\n\n function associateStopCommand(command: TalkCommand) {\n stopCommand = command;\n void command.promise.then(\n () => {\n if (stopCommand === command) {\n stopCommand = null;\n }\n },\n () => {\n if (stopCommand === command) {\n stopCommand = null;\n }\n },\n );\n }\n\n function runStopCommand(command: TalkCommand) {\n const run = (async () => {\n let stopError: string | null = null;\n try {\n await options.sessionClient.stop();\n } catch (error) {\n stopError = normalizeError(error, \"Unable to stop Talk\");\n }\n if (commandGeneration === command.generation && stopCommand === command) {\n resetToIdle(stopError ?? command.gatewayCloseError ?? null);\n }\n })();\n void run.then(command.resolve, command.reject);\n }\n\n function beginStop(generation: number): Promise<void> {\n const command = createTalkCommand(generation);\n associateStopCommand(command);\n publish({\n lifecycle: \"stopping\",\n relaySessionId: null,\n provider: null,\n recording: false,\n playing: false,\n });\n runStopCommand(command);\n return command.promise;\n }\n\n function stop(): Promise<void> {\n const wasIntendedActive = intendedActive;\n intendedActive = false;\n intentGeneration += 1;\n const generation = ++commandGeneration;\n resetActivePartialTranscripts();\n disassociateStartCommand();\n if (stopCommand) {\n stopCommand.generation = generation;\n delete stopCommand.gatewayCloseError;\n return stopCommand.promise;\n }\n // A stop while idle is silent once nothing is left to tear down: either no\n // start intent was ever recorded, or a gateway close already ran its\n // teardown, kept the intent, and settled. While a reconnect or a pending\n // start barrier is in flight the full stop cycle still runs so the client\n // attempt is cancelled and observers see the stopping transition.\n if (!wasIntendedActive && state.lifecycle === \"idle\") {\n return Promise.resolve();\n }\n if (\n wasIntendedActive &&\n state.lifecycle === \"idle\" &&\n startBarrier === null &&\n reconnectInFlight === null\n ) {\n return Promise.resolve();\n }\n return beginStop(generation);\n }\n\n function reconnectIfIntended(): Promise<void> {\n if (!intendedActive) {\n return Promise.resolve();\n }\n if (reconnectInFlight) {\n return reconnectInFlight;\n }\n const capturedIntentGeneration = intentGeneration;\n const pending = (async () => {\n try {\n await options.sessionClient.start();\n if (intentGeneration === capturedIntentGeneration) {\n publish({ error: null });\n }\n } catch (error) {\n if (intentGeneration === capturedIntentGeneration) {\n resetToIdle(normalizeError(error, \"Unable to start Talk\"));\n }\n }\n })();\n reconnectInFlight = pending;\n reconnectIntentGeneration = capturedIntentGeneration;\n void pending.finally(() => {\n if (reconnectInFlight === pending) {\n reconnectInFlight = null;\n reconnectIntentGeneration = null;\n }\n });\n return pending;\n }\n\n function ensureRelaySessionOrder(relaySessionId: string): number {\n const existing = relaySessionOrders.get(relaySessionId);\n if (existing !== undefined) {\n return existing;\n }\n relaySessionSequence += 1;\n relaySessionOrders.set(relaySessionId, relaySessionSequence);\n return relaySessionSequence;\n }\n\n function hasTranscriptIdentity(\n event: Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }>,\n ): event is Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }> & {\n itemId: string;\n contentIndex: number;\n itemOrder?: number;\n } {\n return (\n typeof event.itemId === \"string\" &&\n event.itemId.length > 0 &&\n Number.isInteger(event.contentIndex) &&\n (event.contentIndex ?? -1) >= 0\n );\n }\n\n function hasValidTranscriptItemOrder(value: number | undefined): value is number {\n return value !== undefined && Number.isInteger(value) && value >= 0;\n }\n\n type TranscriptEvent = Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }>;\n type TranscriptTiming = { startedAtMs: number; completedAtMs?: number };\n\n function terminalState(event: TranscriptEvent): \"open\" | \"terminal\" | \"contradictory\" {\n if ((event.status === \"pending\" || event.status === \"streaming\") && event.final) {\n return \"contradictory\";\n }\n if (event.status === \"final\" || event.status === \"failed\") {\n return \"terminal\";\n }\n return event.status === undefined && event.final ? \"terminal\" : \"open\";\n }\n\n function resolveTranscriptTiming(\n event: TranscriptEvent,\n existing?: TalkTranscriptEntry,\n ): TranscriptTiming {\n const terminal = terminalState(event) === \"terminal\";\n const needsStart = existing === undefined && !validEpochMs(event.startedAtMs);\n const needsCompletion =\n terminal && existing?.completedAtMs === undefined && !validEpochMs(event.completedAtMs);\n const observedAt = needsStart || needsCompletion ? readNow() : undefined;\n const startedAtMs =\n existing?.startedAtMs ?? (validEpochMs(event.startedAtMs) ? event.startedAtMs : observedAt!);\n const completedAtMs =\n existing?.completedAtMs ??\n (terminal\n ? validEpochMs(event.completedAtMs)\n ? event.completedAtMs\n : observedAt!\n : undefined);\n return {\n startedAtMs,\n ...(completedAtMs !== undefined ? { completedAtMs } : {}),\n };\n }\n\n function orderTranscript(entries: TalkTranscriptEntry[]): TalkTranscriptEntry[] {\n const groups = new Map<string, TalkTranscriptEntry[]>();\n for (const entry of entries) {\n const group = groups.get(entry.relaySessionId) ?? [];\n group.push(entry);\n groups.set(entry.relaySessionId, group);\n }\n // Array.from already produced a fresh array, so it is sorted in place.\n const orderedGroups = Array.from(groups.entries());\n orderedGroups.sort(\n ([leftSessionId], [rightSessionId]) =>\n ensureRelaySessionOrder(leftSessionId) - ensureRelaySessionOrder(rightSessionId),\n );\n return orderedGroups.flatMap(([, group]) => {\n const identifiedIndexes: number[] = [];\n const identifiedEntries: TalkTranscriptEntry[] = [];\n group.forEach((entry, index) => {\n if (entry.itemOrder !== undefined) {\n identifiedIndexes.push(index);\n identifiedEntries.push(entry);\n }\n });\n identifiedEntries.sort((left, right) => left.itemOrder! - right.itemOrder!);\n const ordered = [...group];\n identifiedIndexes.forEach((index, identifiedIndex) => {\n ordered[index] = identifiedEntries[identifiedIndex];\n });\n return ordered;\n });\n }\n\n function upsertIdentifiedTranscript(\n event: Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }> & {\n itemId: string;\n contentIndex: number;\n itemOrder?: number;\n },\n ): void {\n ensureRelaySessionOrder(event.relaySessionId);\n const id = JSON.stringify([event.relaySessionId, event.itemId, event.contentIndex]);\n const existingIndex = state.transcript.findIndex((entry) => entry.id === id);\n const existing = existingIndex >= 0 ? state.transcript[existingIndex] : undefined;\n if (\n existing &&\n (existing.final || existing.status === \"final\" || existing.status === \"failed\")\n ) {\n return;\n }\n if (existing && event.status === \"pending\") {\n return;\n }\n const replaceText = terminalState(event) === \"terminal\";\n const timing = resolveTranscriptTiming(event, existing);\n // An invalid item order keeps identified handling but is ignored (treated\n // as absent); a valid order survives updates that omit it.\n const itemOrder = hasValidTranscriptItemOrder(event.itemOrder) ? event.itemOrder : undefined;\n const entry: TalkTranscriptEntry = {\n id,\n relaySessionId: event.relaySessionId,\n role: event.role,\n text: existing && !replaceText ? `${existing.text}${event.text}` : event.text,\n final: event.final,\n itemId: event.itemId,\n ...(event.responseId !== undefined || existing?.responseId !== undefined\n ? { responseId: event.responseId ?? existing?.responseId }\n : {}),\n contentIndex: event.contentIndex,\n ...(itemOrder !== undefined || existing?.itemOrder !== undefined\n ? { itemOrder: itemOrder ?? existing?.itemOrder }\n : {}),\n ...(event.status !== undefined ? { status: event.status } : {}),\n ...timing,\n };\n const transcript = [...state.transcript];\n if (existingIndex >= 0) {\n transcript[existingIndex] = entry;\n } else {\n transcript.push(entry);\n }\n publish({ transcript: orderTranscript(transcript) });\n }\n\n function appendTranscript(event: Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }>) {\n const eventState = terminalState(event);\n if (eventState === \"contradictory\") {\n return;\n }\n if (hasTranscriptIdentity(event)) {\n upsertIdentifiedTranscript(event);\n return;\n }\n ensureRelaySessionOrder(event.relaySessionId);\n const activePartialTranscriptId = activePartialTranscriptIds[event.role];\n const activeIndex = activePartialTranscriptId\n ? state.transcript.findIndex((entry) => entry.id === activePartialTranscriptId)\n : -1;\n const active = activeIndex >= 0 ? state.transcript[activeIndex] : undefined;\n const activeIsOpen =\n active !== undefined &&\n active.role === event.role &&\n !active.final &&\n active.status !== \"final\" &&\n active.status !== \"failed\";\n if (activeIsOpen) {\n const timing = resolveTranscriptTiming(event, active);\n const transcript = [...state.transcript];\n transcript[activeIndex] = {\n id: active.id,\n relaySessionId: active.relaySessionId,\n role: active.role,\n text: eventState === \"terminal\" ? event.text : `${active.text}${event.text}`,\n final: event.final,\n ...(event.status !== undefined ? { status: event.status } : {}),\n ...timing,\n };\n if (eventState === \"terminal\") {\n activePartialTranscriptIds[event.role] = null;\n }\n publish({\n transcript,\n });\n return;\n }\n transcriptSequence += 1;\n const id = `transcript-${transcriptSequence}`;\n const timing = resolveTranscriptTiming(event);\n activePartialTranscriptIds[event.role] = eventState === \"terminal\" ? null : id;\n publish({\n transcript: [\n ...state.transcript,\n {\n id,\n relaySessionId: event.relaySessionId,\n role: event.role,\n text: event.text,\n final: event.final,\n ...(event.status !== undefined ? { status: event.status } : {}),\n ...timing,\n },\n ],\n });\n }\n\n function handleSessionEvent(event: TalkRealtimeRelayEvent) {\n const invalidatedDelegatedEvent =\n delegatedRelayEvent === event &&\n delegatedRelayGeneration !== null &&\n delegatedRelayGeneration !== commandGeneration;\n const acceptedPreReducedClose =\n event.type === \"close\" && preReducedCloseRelaySessionId === event.relaySessionId;\n if (invalidatedDelegatedEvent && !acceptedPreReducedClose) {\n return;\n }\n switch (event.type) {\n case \"audio\":\n publish({\n lifecycle: state.lifecycle === \"interrupting\" ? \"active\" : state.lifecycle,\n playing: true,\n });\n break;\n case \"clear\": {\n const pendingRecording = pendingInterruptState?.recording;\n const captureStarting = state.lifecycle === \"starting\";\n pendingInterruptState = null;\n publish({\n lifecycle: captureStarting\n ? \"starting\"\n : event.reason === \"barge-in\"\n ? \"interrupting\"\n : state.lifecycle === \"idle\" || state.lifecycle === \"stopping\"\n ? state.lifecycle\n : \"active\",\n recording:\n !captureStarting &&\n (pendingRecording ?? (state.lifecycle !== \"idle\" && state.lifecycle !== \"stopping\")),\n playing: false,\n });\n break;\n }\n case \"vadBargeIn\": {\n const captureStarting = state.lifecycle === \"starting\";\n publish({\n lifecycle: captureStarting\n ? \"starting\"\n : state.lifecycle === \"idle\" || state.lifecycle === \"stopping\"\n ? state.lifecycle\n : \"interrupting\",\n recording:\n !captureStarting &&\n (pendingInterruptState?.recording ??\n (state.lifecycle !== \"idle\" && state.lifecycle !== \"stopping\")),\n playing: false,\n });\n break;\n }\n case \"ready\":\n if (state.lifecycle === \"interrupting\") {\n publish({ lifecycle: \"active\" });\n }\n break;\n case \"transcript\":\n appendTranscript(event);\n if (event.role === \"assistant\" && state.lifecycle === \"interrupting\") {\n publish({ lifecycle: \"active\" });\n }\n break;\n case \"error\":\n publish({ error: normalizeError(event.message, \"Talk provider error\") });\n break;\n case \"close\":\n if (preReducedCloseRelaySessionId === event.relaySessionId) {\n preReducedCloseRelaySessionId = null;\n break;\n }\n commandGeneration += 1;\n preReducedCloseRelaySessionId = null;\n disassociateStartCommand();\n resetToIdle();\n break;\n default:\n break;\n }\n }\n\n options.onState(state);\n\n return {\n start,\n stop,\n reconnectIfIntended,\n async retry() {\n intendedActive = true;\n intentGeneration += 1;\n const generation = ++commandGeneration;\n resetActivePartialTranscripts();\n disassociateStartCommand();\n // Same barrier as start(): a reconnect in flight is dead after the intent\n // bump, and the retried start must chain after it settles.\n const staleReconnect =\n reconnectInFlight !== null && reconnectIntentGeneration !== intentGeneration\n ? reconnectInFlight\n : null;\n const stopped = stopCommand?.promise ?? beginStop(generation);\n await stopped;\n if (commandGeneration !== generation) {\n return;\n }\n const started = beginStart(generation, staleReconnect ?? undefined);\n await started;\n if (commandGeneration !== generation) {\n return;\n }\n },\n handleRelayEvent(event) {\n const previousEvent = delegatedRelayEvent;\n const previousGeneration = delegatedRelayGeneration;\n delegatedRelayEvent = event;\n delegatedRelayGeneration = commandGeneration;\n try {\n options.sessionClient.handleRelayEvent(event);\n } finally {\n delegatedRelayEvent = previousEvent;\n delegatedRelayGeneration = previousGeneration;\n }\n },\n handleSessionEvent,\n handleSessionState(sessionState) {\n // A reconnect whose intent generation was superseded (user stop or a new\n // user start) is dead; its client echoes must never install session\n // state. New user starts chain after the dead reconnect settles, so\n // their states arrive only after this ignore window closes.\n if (reconnectIntentGeneration !== null && reconnectIntentGeneration !== intentGeneration) {\n return;\n }\n const supersededStopIdle =\n sessionState.lifecycle === \"idle\" &&\n state.lifecycle === \"starting\" &&\n startCommand?.generation === commandGeneration &&\n stopCommand !== null &&\n stopCommand.generation < commandGeneration;\n if (supersededStopIdle) {\n return;\n }\n const delegatedClose =\n delegatedRelayEvent?.type === \"close\" ? delegatedRelayEvent : undefined;\n const closeInducedIdle =\n sessionState.lifecycle === \"idle\" &&\n sessionState.relaySessionId === null &&\n (delegatedClose !== undefined ||\n (state.relaySessionId !== null &&\n (state.lifecycle === \"active\" || state.lifecycle === \"interrupting\")));\n if (closeInducedIdle) {\n commandGeneration += 1;\n preReducedCloseRelaySessionId = delegatedClose?.relaySessionId ?? state.relaySessionId;\n disassociateStartCommand();\n resetActivePartialTranscripts();\n }\n if (sessionState.lifecycle === \"interrupting\") {\n pendingInterruptState = sessionState;\n publish({\n relaySessionId: sessionState.relaySessionId,\n provider: sessionState.provider,\n recording: state.lifecycle === \"starting\" ? false : sessionState.recording,\n playing: sessionState.playing,\n droppedAudioFrames: sessionState.droppedAudioFrames,\n });\n return;\n }\n pendingInterruptState = null;\n publish({\n lifecycle: sessionState.lifecycle,\n relaySessionId: sessionState.relaySessionId,\n provider: sessionState.provider,\n recording: sessionState.recording,\n playing: sessionState.playing,\n droppedAudioFrames: sessionState.droppedAudioFrames,\n });\n },\n handleGatewayClose() {\n const generation = ++commandGeneration;\n resetActivePartialTranscripts();\n preReducedCloseRelaySessionId = null;\n disassociateStartCommand();\n let teardown = stopCommand;\n const createdTeardown = !teardown;\n if (teardown) {\n teardown.generation = generation;\n } else {\n teardown = createTalkCommand(generation);\n associateStopCommand(teardown);\n }\n if (createdTeardown || Object.hasOwn(teardown, \"gatewayCloseError\")) {\n teardown.gatewayCloseError = state.error;\n }\n options.sessionClient.handleGatewayClose();\n if (commandGeneration === generation && stopCommand === teardown) {\n resetToIdle();\n }\n if (createdTeardown) {\n runStopCommand(teardown);\n }\n },\n loadAvailability,\n };\n}\n\nexport type { TalkLifecycle, TalkRealtimeRelayEvent };\n","import { LitElement } from \"lit\";\nimport { customElement, state } from \"lit/decorators.js\";\nimport {\n createTalkAudioCapture,\n createTalkAudioPlayback,\n createTalkSessionClient,\n type TalkSessionClient,\n} from \"talk-client\";\nimport { i18n, I18nController, isSupportedLocale } from \"../i18n/index.ts\";\nimport {\n handleChannelConfigReload as handleChannelConfigReloadInternal,\n handleChannelConfigSave as handleChannelConfigSaveInternal,\n handleNostrProfileCancel as handleNostrProfileCancelInternal,\n handleNostrProfileEdit as handleNostrProfileEditInternal,\n handleNostrProfileFieldChange as handleNostrProfileFieldChangeInternal,\n handleNostrProfileImport as handleNostrProfileImportInternal,\n handleNostrProfileSave as handleNostrProfileSaveInternal,\n handleNostrProfileToggleAdvanced as handleNostrProfileToggleAdvancedInternal,\n handleWhatsAppLogout as handleWhatsAppLogoutInternal,\n handleWhatsAppStart as handleWhatsAppStartInternal,\n handleWhatsAppWait as handleWhatsAppWaitInternal,\n} from \"./app-channels.ts\";\nimport {\n handleAbortChat as handleAbortChatInternal,\n handleSendChat as handleSendChatInternal,\n removeQueuedMessage as removeQueuedMessageInternal,\n} from \"./app-chat.ts\";\nimport { DEFAULT_CRON_FORM, DEFAULT_LOG_LEVEL_FILTERS } from \"./app-defaults.ts\";\nimport type { EventLogEntry } from \"./app-events.ts\";\nimport { connectGateway as connectGatewayInternal, createGatewayRequester } from \"./app-gateway.ts\";\nimport {\n handleConnected,\n handleDisconnected,\n handleFirstUpdated,\n handleUpdated,\n handleVisibilityChange as handleVisibilityChangeInternal,\n} from \"./app-lifecycle.ts\";\nimport { renderApp } from \"./app-render.ts\";\nimport {\n exportLogs as exportLogsInternal,\n handleChatScroll as handleChatScrollInternal,\n handleLogsScroll as handleLogsScrollInternal,\n resetChatScroll as resetChatScrollInternal,\n scheduleChatScroll as scheduleChatScrollInternal,\n} from \"./app-scroll.ts\";\nimport {\n applySettings as applySettingsInternal,\n loadCron as loadCronInternal,\n loadOverview as loadOverviewInternal,\n setTab as setTabInternal,\n setTheme as setThemeInternal,\n onPopState as onPopStateInternal,\n} from \"./app-settings.ts\";\nimport {\n resetToolStream as resetToolStreamInternal,\n type ToolStreamEntry,\n type CompactionStatus,\n type FallbackStatus,\n} from \"./app-tool-stream.ts\";\nimport type { AppViewState } from \"./app-view-state.ts\";\nimport { normalizeAssistantIdentity } from \"./assistant-identity.ts\";\nimport { loadAssistantIdentity as loadAssistantIdentityInternal } from \"./controllers/assistant-identity.ts\";\nimport type { CronFieldErrors } from \"./controllers/cron.ts\";\nimport type { DevicePairingList } from \"./controllers/devices.ts\";\nimport {\n createDefaultDreamsState,\n loadDreams as loadDreamsInternal,\n type DreamsViewState,\n} from \"./controllers/dreams.ts\";\nimport type { ExecApprovalRequest } from \"./controllers/exec-approval.ts\";\nimport type { ExecApprovalsFile, ExecApprovalsSnapshot } from \"./controllers/exec-approvals.ts\";\nimport {\n loadLearningOverview,\n loadProposals,\n loadLessons,\n inspectProposal,\n decideProposal,\n} from \"./controllers/learning.ts\";\nimport type { SkillMessage } from \"./controllers/skills.ts\";\nimport {\n createDefaultTalkState,\n createTalkController,\n type TalkController,\n type TalkState,\n} from \"./controllers/talk.ts\";\nimport type { GatewayBrowserClient, GatewayHelloOk } from \"./gateway.ts\";\nimport type { Tab } from \"./navigation.ts\";\nimport { loadSettings, type UiSettings } from \"./storage.ts\";\nimport type { ResolvedTheme, ThemeMode } from \"./theme.ts\";\nimport type {\n AgentsListResult,\n AgentsFilesListResult,\n AgentIdentityResult,\n ConfigSnapshot,\n ConfigUiHints,\n CronJob,\n CronRunLogEntry,\n CronStatus,\n HealthSnapshot,\n LogEntry,\n LogLevel,\n PresenceEntry,\n ChannelsStatusSnapshot,\n SessionRunsResult,\n SessionsThresholdsResult,\n SessionsListResult,\n SkillStatusReport,\n ToolsCatalogResult,\n StatusSummary,\n NostrProfile,\n} from \"./types.ts\";\nimport { type ChatAttachment, type ChatQueueItem, type CronFormState } from \"./ui-types.ts\";\nimport { generateUUID } from \"./uuid.ts\";\nimport type { NostrProfileFormState } from \"./views/channels.nostr-profile-form.ts\";\n\ndeclare global {\n interface Window {\n __OPENCLAW_CONTROL_UI_BASE_PATH__?: string;\n }\n}\n\nconst bootAssistantIdentity = normalizeAssistantIdentity({});\n\nfunction resolveOnboardingMode(): boolean {\n if (!window.location.search) {\n return false;\n }\n const params = new URLSearchParams(window.location.search);\n const raw = params.get(\"onboarding\");\n if (!raw) {\n return false;\n }\n const normalized = raw.trim().toLowerCase();\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\" || normalized === \"on\";\n}\n\n@customElement(\"openclaw-app\")\nexport class OpenClawApp extends LitElement {\n private i18nController = new I18nController(this);\n clientInstanceId = generateUUID();\n @state() settings: UiSettings = loadSettings();\n constructor() {\n super();\n if (isSupportedLocale(this.settings.locale)) {\n void i18n.setLocale(this.settings.locale);\n }\n const request = createGatewayRequester(this);\n this.talkSessionClient = createTalkSessionClient({\n request,\n capture: createTalkAudioCapture,\n playback: createTalkAudioPlayback,\n onState: (next) => this.talkController.handleSessionState(next),\n onEvent: (event) => this.talkController.handleSessionEvent(event),\n });\n this.talkController = createTalkController({\n sessionClient: this.talkSessionClient,\n request,\n onState: (next) => {\n this.talkState = next;\n },\n });\n }\n @state() password = \"\";\n @state() tab: Tab = \"overview\";\n @state() onboarding = resolveOnboardingMode();\n @state() connected = false;\n @state() theme: ThemeMode = this.settings.theme ?? \"system\";\n @state() themeResolved: ResolvedTheme = \"dark\";\n @state() hello: GatewayHelloOk | null = null;\n @state() lastError: string | null = null;\n @state() lastErrorCode: string | null = null;\n @state() eventLog: EventLogEntry[] = [];\n private eventLogBuffer: EventLogEntry[] = [];\n private toolStreamSyncTimer: number | null = null;\n private sidebarCloseTimer: number | null = null;\n\n @state() assistantName = bootAssistantIdentity.name;\n @state() assistantAvatar = bootAssistantIdentity.avatar;\n @state() assistantAgentId = bootAssistantIdentity.agentId ?? null;\n @state() consolePath: string | null = null;\n\n @state() sessionKey = this.settings.sessionKey;\n @state() chatLoading = false;\n @state() chatSending = false;\n @state() chatMessage = \"\";\n @state() chatMessages: unknown[] = [];\n @state() chatToolMessages: unknown[] = [];\n @state() chatStream: string | null = null;\n @state() chatStreamStartedAt: number | null = null;\n @state() chatRunId: string | null = null;\n @state() compactionStatus: CompactionStatus | null = null;\n @state() fallbackStatus: FallbackStatus | null = null;\n @state() chatAvatarUrl: string | null = null;\n @state() chatThinkingLevel: string | null = null;\n @state() chatQueue: ChatQueueItem[] = [];\n @state() chatAttachments: ChatAttachment[] = [];\n @state() chatManualRefreshInFlight = false;\n // Sidebar state for tool output viewing\n @state() sidebarOpen = false;\n @state() sidebarContent: string | null = null;\n @state() sidebarError: string | null = null;\n @state() splitRatio = this.settings.splitRatio;\n\n @state() nodesLoading = false;\n @state() nodes: Array<Record<string, unknown>> = [];\n @state() devicesLoading = false;\n @state() devicesError: string | null = null;\n @state() devicesList: DevicePairingList | null = null;\n @state() execApprovalsLoading = false;\n @state() execApprovalsSaving = false;\n @state() execApprovalsDirty = false;\n @state() execApprovalsSnapshot: ExecApprovalsSnapshot | null = null;\n @state() execApprovalsForm: ExecApprovalsFile | null = null;\n @state() execApprovalsSelectedAgent: string | null = null;\n @state() execApprovalsTarget: \"gateway\" | \"node\" = \"gateway\";\n @state() execApprovalsTargetNodeId: string | null = null;\n @state() execApprovalQueue: ExecApprovalRequest[] = [];\n @state() execApprovalBusy = false;\n @state() execApprovalError: string | null = null;\n @state() pendingGatewayUrl: string | null = null;\n\n @state() configLoading = false;\n @state() configRaw = \"{\\n}\\n\";\n @state() configRawOriginal = \"\";\n @state() configValid: boolean | null = null;\n @state() configIssues: unknown[] = [];\n @state() configSaving = false;\n @state() configApplying = false;\n @state() updateRunning = false;\n @state() applySessionKey = this.settings.lastActiveSessionKey;\n @state() configSnapshot: ConfigSnapshot | null = null;\n @state() configSchema: unknown = null;\n @state() configSchemaVersion: string | null = null;\n @state() configSchemaLoading = false;\n @state() configUiHints: ConfigUiHints = {};\n @state() configForm: Record<string, unknown> | null = null;\n @state() configFormOriginal: Record<string, unknown> | null = null;\n @state() configFormDirty = false;\n @state() configFormMode: \"form\" | \"raw\" = \"form\";\n @state() configSearchQuery = \"\";\n @state() configActiveSection: string | null = null;\n @state() configActiveSubsection: string | null = null;\n\n @state() channelsLoading = false;\n @state() channelsSnapshot: ChannelsStatusSnapshot | null = null;\n @state() channelsError: string | null = null;\n @state() channelsLastSuccess: number | null = null;\n @state() whatsappLoginMessage: string | null = null;\n @state() whatsappLoginQrDataUrl: string | null = null;\n @state() whatsappLoginConnected: boolean | null = null;\n @state() whatsappBusy = false;\n @state() nostrProfileFormState: NostrProfileFormState | null = null;\n @state() nostrProfileAccountId: string | null = null;\n\n @state() presenceLoading = false;\n @state() presenceEntries: PresenceEntry[] = [];\n @state() presenceError: string | null = null;\n @state() presenceStatus: string | null = null;\n\n @state() agentsLoading = false;\n @state() agentsList: AgentsListResult | null = null;\n @state() agentsError: string | null = null;\n @state() agentsSelectedId: string | null = null;\n @state() toolsCatalogLoading = false;\n @state() toolsCatalogError: string | null = null;\n @state() toolsCatalogResult: ToolsCatalogResult | null = null;\n @state() agentsPanel: \"overview\" | \"files\" | \"tools\" | \"skills\" | \"channels\" | \"cron\" =\n \"overview\";\n @state() agentFilesLoading = false;\n @state() agentFilesError: string | null = null;\n @state() agentFilesList: AgentsFilesListResult | null = null;\n @state() agentFileContents: Record<string, string> = {};\n @state() agentFileDrafts: Record<string, string> = {};\n @state() agentFileActive: string | null = null;\n @state() agentFileSaving = false;\n @state() agentIdentityLoading = false;\n @state() agentIdentityError: string | null = null;\n @state() agentIdentityById: Record<string, AgentIdentityResult> = {};\n @state() agentSkillsLoading = false;\n @state() agentSkillsError: string | null = null;\n @state() agentSkillsReport: SkillStatusReport | null = null;\n @state() agentSkillsAgentId: string | null = null;\n\n @state() sessionsLoading = false;\n @state() sessionsResult: SessionsListResult | null = null;\n @state() sessionsError: string | null = null;\n @state() sessionsFilterActive = \"\";\n @state() sessionsFilterLimit = \"120\";\n @state() sessionsIncludeGlobal = true;\n @state() sessionsIncludeUnknown = false;\n @state() sessionRunsResult: SessionRunsResult | null = null;\n @state() sessionRunsError: string | null = null;\n sessionRunsFetchedAt = 0;\n sessionRunsLoading = false;\n @state() sessionsThresholdsResult: SessionsThresholdsResult | null = null;\n @state() sessionsThresholdsError: string | null = null;\n sessionsThresholdsLoading = false;\n @state() sessionRunsInterruptingKeys = new Set<string>();\n @state() recentlyCompletedRuns: { key: string; completedAt: number }[] = [];\n sessionRunsPrevKeys = new Set<string>();\n @state() recoverableRuns: import(\"./types.js\").DurableSessionRunRecord[] = [];\n @state() recoveryError: string | null = null;\n @state() decidingRunIds = new Set<string>();\n recoverableRunsLoading = false;\n @state() sessionsHideCron = true;\n\n @state() usageLoading = false;\n @state() usageResult: import(\"./types.js\").SessionsUsageResult | null = null;\n @state() usageCostSummary: import(\"./types.js\").CostUsageSummary | null = null;\n @state() usageError: string | null = null;\n @state() usageStartDate = (() => {\n const d = new Date();\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(d.getDate()).padStart(2, \"0\")}`;\n })();\n @state() usageEndDate = (() => {\n const d = new Date();\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(d.getDate()).padStart(2, \"0\")}`;\n })();\n @state() usageSelectedSessions: string[] = [];\n @state() usageSelectedDays: string[] = [];\n @state() usageSelectedHours: number[] = [];\n @state() usageChartMode: \"tokens\" | \"cost\" = \"tokens\";\n @state() usageDailyChartMode: \"total\" | \"by-type\" = \"by-type\";\n @state() usageTimeSeriesMode: \"cumulative\" | \"per-turn\" = \"per-turn\";\n @state() usageTimeSeriesBreakdownMode: \"total\" | \"by-type\" = \"by-type\";\n @state() usageTimeSeries: import(\"./types.js\").SessionUsageTimeSeries | null = null;\n @state() usageTimeSeriesLoading = false;\n @state() usageTimeSeriesCursorStart: number | null = null;\n @state() usageTimeSeriesCursorEnd: number | null = null;\n @state() usageSessionLogs: import(\"./views/usage.js\").SessionLogEntry[] | null = null;\n @state() usageSessionLogsLoading = false;\n @state() usageSessionLogsExpanded = false;\n // Applied query (used to filter the already-loaded sessions list client-side).\n @state() usageQuery = \"\";\n // Draft query text (updates immediately as the user types; applied via debounce or \"Search\").\n @state() usageQueryDraft = \"\";\n @state() usageSessionSort: \"tokens\" | \"cost\" | \"recent\" | \"messages\" | \"errors\" = \"recent\";\n @state() usageSessionSortDir: \"desc\" | \"asc\" = \"desc\";\n @state() usageRecentSessions: string[] = [];\n @state() usageTimeZone: \"local\" | \"utc\" = \"local\";\n @state() usageContextExpanded = false;\n @state() usageHeaderPinned = false;\n @state() usageSessionsTab: \"all\" | \"recent\" = \"all\";\n @state() usageVisibleColumns: string[] = [\n \"channel\",\n \"agent\",\n \"provider\",\n \"model\",\n \"messages\",\n \"tools\",\n \"errors\",\n \"duration\",\n ];\n @state() usageLogFilterRoles: import(\"./views/usage.js\").SessionLogRole[] = [];\n @state() usageLogFilterTools: string[] = [];\n @state() usageLogFilterHasTools = false;\n @state() usageLogFilterQuery = \"\";\n\n // Non-reactive (don’t trigger renders just for timer bookkeeping).\n usageQueryDebounceTimer: number | null = null;\n\n @state() cronLoading = false;\n @state() cronJobsLoadingMore = false;\n @state() cronJobs: CronJob[] = [];\n @state() cronJobsTotal = 0;\n @state() cronJobsHasMore = false;\n @state() cronJobsNextOffset: number | null = null;\n @state() cronJobsLimit = 50;\n @state() cronJobsQuery = \"\";\n @state() cronJobsEnabledFilter: import(\"./types.js\").CronJobsEnabledFilter = \"all\";\n @state() cronJobsScheduleKindFilter: import(\"./controllers/cron.js\").CronJobsScheduleKindFilter =\n \"all\";\n @state() cronJobsLastStatusFilter: import(\"./controllers/cron.js\").CronJobsLastStatusFilter =\n \"all\";\n @state() cronJobsSortBy: import(\"./types.js\").CronJobsSortBy = \"nextRunAtMs\";\n @state() cronJobsSortDir: import(\"./types.js\").CronSortDir = \"asc\";\n @state() cronStatus: CronStatus | null = null;\n @state() cronError: string | null = null;\n @state() cronForm: CronFormState = { ...DEFAULT_CRON_FORM };\n @state() cronFieldErrors: CronFieldErrors = {};\n @state() cronEditingJobId: string | null = null;\n @state() cronCreatingJob = false;\n @state() cronRunsJobId: string | null = null;\n @state() cronRunsLoadingMore = false;\n @state() cronRuns: CronRunLogEntry[] = [];\n @state() cronRunsTotal = 0;\n @state() cronRunsHasMore = false;\n @state() cronRunsNextOffset: number | null = null;\n @state() cronRunsLimit = 50;\n @state() cronRunsScope: import(\"./types.js\").CronRunScope = \"all\";\n @state() cronRunsStatuses: import(\"./types.js\").CronRunsStatusValue[] = [];\n @state() cronRunsDeliveryStatuses: import(\"./types.js\").CronDeliveryStatus[] = [];\n @state() cronRunsStatusFilter: import(\"./types.js\").CronRunsStatusFilter = \"all\";\n @state() cronRunsQuery = \"\";\n @state() cronRunsSortDir: import(\"./types.js\").CronSortDir = \"desc\";\n @state() cronModelSuggestions: string[] = [];\n @state() cronBusy = false;\n @state() cronLastRunSessionKey: string | null = null;\n @state() cronLastRunJobId: string | null = null;\n @state() cronRunningJobId: string | null = null;\n\n // Learning inbox state\n @state() learningLoading = false;\n @state() learningError: string | null = null;\n @state() overview: import(\"./controllers/learning.ts\").LearningOverview | null = null;\n @state() proposals: import(\"./controllers/learning.ts\").LearningProposalRow[] = [];\n @state() lessons: import(\"./controllers/learning.ts\").LearningLessonRow[] = [];\n @state() selectedProposal: import(\"./controllers/learning.ts\").LearningProposalDetail | null =\n null;\n @state() learningBusy = false;\n @state() learningSubView: \"proposals\" | \"lessons\" = \"proposals\";\n @state() learningPendingApplyId: string | null = null;\n\n // Dreams view state: every value is replaced from a durable read, never set optimistically.\n @state() dreams: DreamsViewState = createDefaultDreamsState();\n dreamsGeneration = 0;\n dreamsDirty = false;\n dreamsTrailingTimer: number | null = null;\n dreamsTrailingPending = false;\n dreamsBurstStartedAt: number | null = null;\n dreamsPollInterval: number | null = null;\n\n @state() updateAvailable: import(\"./types.js\").UpdateAvailable | null = null;\n\n @state() skillsLoading = false;\n @state() skillsReport: SkillStatusReport | null = null;\n @state() skillsError: string | null = null;\n @state() skillsFilter = \"\";\n @state() skillEdits: Record<string, string> = {};\n @state() skillsBusyKey: string | null = null;\n @state() skillMessages: Record<string, SkillMessage> = {};\n\n @state() debugLoading = false;\n @state() debugStatus: StatusSummary | null = null;\n @state() debugHealth: HealthSnapshot | null = null;\n @state() debugModels: unknown[] = [];\n @state() debugHeartbeat: unknown = null;\n @state() debugCallMethod = \"\";\n @state() debugCallParams = \"{}\";\n @state() debugCallResult: string | null = null;\n @state() debugCallError: string | null = null;\n\n @state() logsLoading = false;\n @state() logsError: string | null = null;\n @state() logsFile: string | null = null;\n @state() logsEntries: LogEntry[] = [];\n @state() logsFilterText = \"\";\n @state() logsLevelFilters: Record<LogLevel, boolean> = {\n ...DEFAULT_LOG_LEVEL_FILTERS,\n };\n @state() logsAutoFollow = true;\n @state() logsTruncated = false;\n @state() logsCursor: number | null = null;\n @state() logsLastFetchAt: number | null = null;\n @state() logsLimit = 500;\n @state() logsMaxBytes = 250_000;\n @state() logsAtBottom = true;\n @state() talkState: TalkState = createDefaultTalkState();\n\n client: GatewayBrowserClient | null = null;\n private readonly talkSessionClient: TalkSessionClient;\n private readonly talkController: TalkController;\n private chatScrollFrame: number | null = null;\n private chatScrollTimeout: number | null = null;\n private chatHasAutoScrolled = false;\n private chatUserNearBottom = true;\n @state() chatNewMessagesBelow = false;\n private nodesPollInterval: number | null = null;\n private logsPollInterval: number | null = null;\n private debugPollInterval: number | null = null;\n private sessionRunsPollInterval: number | null = null;\n private sessionRunsTickInterval: number | null = null;\n private logsScrollFrame: number | null = null;\n private toolStreamById = new Map<string, ToolStreamEntry>();\n private toolStreamOrder: string[] = [];\n refreshSessionsAfterChat = new Set<string>();\n basePath = \"\";\n private visibilityHandler = () =>\n handleVisibilityChangeInternal(\n this as unknown as Parameters<typeof handleVisibilityChangeInternal>[0],\n );\n private popStateHandler = () =>\n onPopStateInternal(this as unknown as Parameters<typeof onPopStateInternal>[0]);\n private themeMedia: MediaQueryList | null = null;\n private themeMediaHandler: ((event: MediaQueryListEvent) => void) | null = null;\n private topbarObserver: ResizeObserver | null = null;\n\n createRenderRoot() {\n return this;\n }\n\n connectedCallback() {\n super.connectedCallback();\n handleConnected(this as unknown as Parameters<typeof handleConnected>[0]);\n }\n\n protected firstUpdated() {\n handleFirstUpdated(this as unknown as Parameters<typeof handleFirstUpdated>[0]);\n }\n\n disconnectedCallback() {\n handleDisconnected(this as unknown as Parameters<typeof handleDisconnected>[0]);\n super.disconnectedCallback();\n }\n\n protected updated(changed: Map<PropertyKey, unknown>) {\n handleUpdated(this as unknown as Parameters<typeof handleUpdated>[0], changed);\n }\n\n connect() {\n connectGatewayInternal(this as unknown as Parameters<typeof connectGatewayInternal>[0]);\n }\n\n handleChatScroll(event: Event) {\n handleChatScrollInternal(\n this as unknown as Parameters<typeof handleChatScrollInternal>[0],\n event,\n );\n }\n\n handleLogsScroll(event: Event) {\n handleLogsScrollInternal(\n this as unknown as Parameters<typeof handleLogsScrollInternal>[0],\n event,\n );\n }\n\n exportLogs(lines: string[], label: string) {\n exportLogsInternal(lines, label);\n }\n\n resetToolStream() {\n resetToolStreamInternal(this as unknown as Parameters<typeof resetToolStreamInternal>[0]);\n }\n\n resetChatScroll() {\n resetChatScrollInternal(this as unknown as Parameters<typeof resetChatScrollInternal>[0]);\n }\n\n scrollToBottom(opts?: { smooth?: boolean }) {\n resetChatScrollInternal(this as unknown as Parameters<typeof resetChatScrollInternal>[0]);\n scheduleChatScrollInternal(\n this as unknown as Parameters<typeof scheduleChatScrollInternal>[0],\n true,\n Boolean(opts?.smooth),\n );\n }\n\n async loadAssistantIdentity() {\n await loadAssistantIdentityInternal(this);\n }\n\n applySettings(next: UiSettings) {\n applySettingsInternal(this as unknown as Parameters<typeof applySettingsInternal>[0], next);\n }\n\n setTab(next: Tab) {\n setTabInternal(this as unknown as Parameters<typeof setTabInternal>[0], next);\n }\n\n setTheme(next: ThemeMode, context?: Parameters<typeof setThemeInternal>[2]) {\n setThemeInternal(this as unknown as Parameters<typeof setThemeInternal>[0], next, context);\n }\n\n async loadOverview() {\n await loadOverviewInternal(this as unknown as Parameters<typeof loadOverviewInternal>[0]);\n }\n\n async loadCron() {\n await loadCronInternal(this as unknown as Parameters<typeof loadCronInternal>[0]);\n }\n\n async loadLearning(): Promise<void> {\n await Promise.all([\n loadLearningOverview(this as unknown as Parameters<typeof loadLearningOverview>[0]),\n loadProposals(this as unknown as Parameters<typeof loadProposals>[0]),\n loadLessons(this as unknown as Parameters<typeof loadLessons>[0]),\n ]);\n }\n\n async loadDreams(): Promise<void> {\n await loadDreamsInternal(this as unknown as Parameters<typeof loadDreamsInternal>[0]);\n }\n\n selectDreamsRun(taskRunId: string | null) {\n this.dreams = { ...this.dreams, selectedRunId: taskRunId };\n }\n\n async openLearningProposal(id: string): Promise<void> {\n await inspectProposal(this as unknown as Parameters<typeof inspectProposal>[0], id);\n }\n\n async decideLearningProposal(\n id: string,\n action: \"apply\" | \"reject\" | \"quarantine\",\n ): Promise<void> {\n await decideProposal(this as unknown as Parameters<typeof decideProposal>[0], id, action);\n }\n\n async handleTalkStart() {\n await this.talkController.start();\n }\n\n async handleTalkStop() {\n await this.talkController.stop();\n }\n\n async handleTalkRetry() {\n await this.talkController.retry();\n }\n\n async handleAbortChat() {\n await handleAbortChatInternal(this as unknown as Parameters<typeof handleAbortChatInternal>[0]);\n }\n\n removeQueuedMessage(id: string) {\n removeQueuedMessageInternal(\n this as unknown as Parameters<typeof removeQueuedMessageInternal>[0],\n id,\n );\n }\n\n async handleSendChat(\n messageOverride?: string,\n opts?: Parameters<typeof handleSendChatInternal>[2],\n ) {\n await handleSendChatInternal(\n this as unknown as Parameters<typeof handleSendChatInternal>[0],\n messageOverride,\n opts,\n );\n }\n\n async handleWhatsAppStart(force: boolean) {\n await handleWhatsAppStartInternal(this, force);\n }\n\n async handleWhatsAppWait() {\n await handleWhatsAppWaitInternal(this);\n }\n\n async handleWhatsAppLogout() {\n await handleWhatsAppLogoutInternal(this);\n }\n\n async handleChannelConfigSave() {\n await handleChannelConfigSaveInternal(this);\n }\n\n async handleChannelConfigReload() {\n await handleChannelConfigReloadInternal(this);\n }\n\n handleNostrProfileEdit(accountId: string, profile: NostrProfile | null) {\n handleNostrProfileEditInternal(this, accountId, profile);\n }\n\n handleNostrProfileCancel() {\n handleNostrProfileCancelInternal(this);\n }\n\n handleNostrProfileFieldChange(field: keyof NostrProfile, value: string) {\n handleNostrProfileFieldChangeInternal(this, field, value);\n }\n\n async handleNostrProfileSave() {\n await handleNostrProfileSaveInternal(this);\n }\n\n async handleNostrProfileImport() {\n await handleNostrProfileImportInternal(this);\n }\n\n handleNostrProfileToggleAdvanced() {\n handleNostrProfileToggleAdvancedInternal(this);\n }\n\n async handleExecApprovalDecision(decision: \"allow-once\" | \"allow-always\" | \"deny\") {\n const active = this.execApprovalQueue[0];\n if (!active || !this.client || this.execApprovalBusy) {\n return;\n }\n this.execApprovalBusy = true;\n this.execApprovalError = null;\n try {\n await this.client.request(\"exec.approval.resolve\", {\n id: active.id,\n decision,\n });\n this.execApprovalQueue = this.execApprovalQueue.filter((entry) => entry.id !== active.id);\n } catch (err) {\n this.execApprovalError = `Exec approval failed: ${String(err)}`;\n } finally {\n this.execApprovalBusy = false;\n }\n }\n\n handleGatewayUrlConfirm() {\n const nextGatewayUrl = this.pendingGatewayUrl;\n if (!nextGatewayUrl) {\n return;\n }\n this.pendingGatewayUrl = null;\n applySettingsInternal(this as unknown as Parameters<typeof applySettingsInternal>[0], {\n ...this.settings,\n gatewayUrl: nextGatewayUrl,\n });\n this.connect();\n }\n\n handleGatewayUrlCancel() {\n this.pendingGatewayUrl = null;\n }\n\n // Sidebar handlers for tool output viewing\n handleOpenSidebar(content: string) {\n if (this.sidebarCloseTimer != null) {\n window.clearTimeout(this.sidebarCloseTimer);\n this.sidebarCloseTimer = null;\n }\n this.sidebarContent = content;\n this.sidebarError = null;\n this.sidebarOpen = true;\n }\n\n handleCloseSidebar() {\n this.sidebarOpen = false;\n // Clear content after transition\n if (this.sidebarCloseTimer != null) {\n window.clearTimeout(this.sidebarCloseTimer);\n }\n this.sidebarCloseTimer = window.setTimeout(() => {\n if (this.sidebarOpen) {\n return;\n }\n this.sidebarContent = null;\n this.sidebarError = null;\n this.sidebarCloseTimer = null;\n }, 200);\n }\n\n handleSplitRatioChange(ratio: number) {\n const newRatio = Math.max(0.4, Math.min(0.7, ratio));\n this.splitRatio = newRatio;\n this.applySettings({ ...this.settings, splitRatio: newRatio });\n }\n\n render() {\n return renderApp(this as unknown as AppViewState);\n }\n}\n"],"file":"index-D6XwnS7I.js"}
|
|
1
|
+
{"version":3,"mappings":"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C7B,GAAa,gBACA,GAAa,gBAsBzB,YACA,2BACE,GAAsB,iBACvB,cACO,KAAK,SAAS,OAAS,4BACX,kBACA,oBACJ,wBACI,mBACH,CAAC,sBACI,CAAC,2BACE,4BACF,wBAElB,GAAsB,0BACpB,GAAsB,6BACrB,GAAsB,SAAW,sBACvB,qBAEhB,KAAK,SAAS,4BACb,oBACA,oBACA,qBACY,CAAC,wBACG,CAAC,kBACH,8BACS,oBACV,2BACiB,yBACJ,wBACT,4BACI,oBACN,CAAC,uBACM,CAAC,iCACT,oBAEd,uBACkB,uBACF,qBACjB,KAAK,SAAS,6BAEZ,cACyB,CAAC,sBACxB,qBACa,sBACU,+BACjB,4BACD,2BACD,8BACiC,4BACR,qCACF,8BACF,yCACC,4BACA,CAAC,wBACzB,0BACgB,4BACA,wBAEnB,kBACJ;;yBACQ,oBACU,uBACJ,CAAC,oBACZ,uBACE,sBACD,wBACE,KAAK,SAAS,yCACQ,uBAChB,8BACa,8BACf,sBACS,CAAC,kBACa,6BACQ,0BACnC,uBACe,8BACb,4BACiB,iCACG,0BAEtB,yBACgC,wBACnB,8BACM,+BACC,iCACE,iCACC,uBAC1B,8BACuC,gCACf,0BAErB,wBACiB,CAAC,qBACL,yBACC,wBAEhB,mBACsB,sBACT,2BACK,8BACZ,0BACa,6BACa,sBAEvD,kCAC2B,wBACa,yBACc,4BACH,CAAC,uBACH,CAAC,uBACV,0BACf,6BACK,2BACa,4BACqB,CAAC,0BACrC,yBACa,4BACY,6BACV,0BAElB,uBAC0B,wBACb,+BACR,4BACD,iCACE,+BACC,0BACqB,2BACZ,+BACpB,0BACF,iCACgD,kCACnB,oCACtB,oCACW,IAAI,+BAC8B,CAAC,2BACpD,IAAI,yBACiD,CAAC,qBACpC,yBACd,IAAI,gCACL,yBACG,qBAEJ,oBACgD,2BACE,qBACrC,8BACJ,CAC/B,IAAM,EAAI,IAAI,KACd,MAAO,GAAG,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,SAAS,EAAI,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,GAC/G,GAAG,yBAC4B,CAC7B,IAAM,EAAI,IAAI,KACd,MAAO,GAAG,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,SAAS,EAAI,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,GAC/G,GAAG,6BACwC,CAAC,yBACL,CAAC,0BACA,CAAC,sBACI,kCACO,mCACM,6CACG,+BACkB,iCAC7C,mCACmB,mCACF,2BAC8B,kCAC9C,iCACC,mBAEd,wBAEK,yBACuD,kCACnC,gCACN,CAAC,qBACA,kCACV,0BACH,yBACiB,+BACL,CACvC,UACA,QACA,WACA,QACA,WACA,QACA,SACA,UACF,2BAC4E,CAAC,2BACpC,CAAC,8BACR,4BACH,gCAGU,sBAElB,4BACQ,iBACA,CAAC,qBACP,uBACE,2BACkB,wBACpB,sBACA,8BACoD,sCAE3E,oCAEA,0BAC6D,mCACF,sBACpB,oBACL,mBACD,CAAE,GAAG,CAAkB,uBACd,CAAC,wBACF,0BAChB,sBACa,8BACT,iBACQ,CAAC,qBACf,uBACE,2BACkB,wBACpB,sBACmC,4BACY,CAAC,gCACM,CAAC,4BACL,yBAClD,wBACoC,iCACnB,CAAC,gBACvB,8BAC4B,2BACL,2BACA,0BAGhB,sBACa,mBACyC,oBACD,CAAC,eACL,CAAC,wBAE3E,uBACsB,wBAC4B,wCACH,iBAGd,GAAyB,wBACzC,mBACL,4BACuB,gCACb,6BACc,6BACF,0BAEoC,wBAE/C,qBACyB,sBACZ,uBACd,mBACsB,CAAC,qBACP,wBACe,CAAC,oBAEhC,oBACqB,sBACC,sBACZ,CAAC,sBACA,0BACR,wBACA,0BACe,yBACD,sBAElB,kBACa,mBACD,sBACA,CAAC,sBACV,yBAC6B,CACrD,GAAG,CACL,sBAC0B,sBACD,mBACY,0BACK,oBACrB,sBACG,uBACA,kBACQ,GAAuB,cAEjB,0BAGG,4BACE,8BACb,2BACD,6BACG,0BACW,2BACD,4BACC,kCACM,kCACA,0BACR,yBAChB,IAAI,yB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","names":["module","exports","bytesToHex"],"ignoreList":[4,17],"sources":["../../../packages/talk-client/src/audio-capture.ts","../../../packages/talk-client/src/audio-playback.ts","../../../packages/talk-client/src/talk-session-client.ts","../../../ui/src/ui/controllers/channels.ts","../../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/dist/index.js","../../../ui/src/ui/controllers/config/form-coerce.ts","../../../ui/src/ui/controllers/config/form-utils.ts","../../../ui/src/ui/controllers/config.ts","../../../ui/src/ui/app-channels.ts","../../../src/sessions/session-key-utils.ts","../../../ui/src/ui/app-scroll.ts","../../../ui/src/ui/controllers/debug.ts","../../../src/gateway/device-auth.ts","../../../src/gateway/protocol/client-info.ts","../../../src/shared/device-auth.ts","../../../src/shared/device-auth-store.ts","../../../ui/src/ui/device-auth.ts","../../../node_modules/.pnpm/@noble+ed25519@3.1.0/node_modules/@noble/ed25519/index.js","../../../ui/src/ui/device-identity.ts","../../../ui/src/ui/uuid.ts","../../../ui/src/ui/gateway.ts","../../../ui/src/ui/controllers/dreams.ts","../../../ui/src/ui/controllers/logs.ts","../../../ui/src/ui/controllers/nodes.ts","../../../ui/src/ui/controllers/sessions.ts","../../../ui/src/ui/app-polling.ts","../../../ui/src/ui/controllers/agent-identity.ts","../../../ui/src/ui/controllers/agent-skills.ts","../../../ui/src/ui/controllers/agents.ts","../../../ui/src/ui/controllers/devices.ts","../../../ui/src/ui/controllers/exec-approvals.ts","../../../ui/src/ui/controllers/presence.ts","../../../ui/src/ui/controllers/skills.ts","../../../ui/src/ui/storage.ts","../../../ui/src/ui/theme-transition.ts","../../../ui/src/ui/theme.ts","../../../ui/src/ui/app-settings.ts","../../../ui/src/ui/app-tool-stream.ts","../../../ui/src/ui/controllers/chat.ts","../../../ui/src/ui/app-chat.ts","../../../ui/src/ui/chat-event-reload.ts","../../../src/shared/assistant-identity-values.ts","../../../ui/src/ui/assistant-identity.ts","../../../ui/src/ui/controllers/assistant-identity.ts","../../../ui/src/ui/controllers/exec-approval.ts","../../../ui/src/ui/app-gateway.ts","../../../src/gateway/control-ui-contract.ts","../../../ui/src/ui/controllers/control-ui-bootstrap.ts","../../../ui/src/ui/app-lifecycle.ts","../../../ui/src/ui/lazy-view.ts","../../../ui/src/ui/app-view-dispatcher.ts","../../../ui/src/ui/controllers/usage.ts","../../../ui/src/ui/app-render-usage-tab.ts","../../../ui/src/ui/app-render.helpers.ts","../../../ui/src/ui/controllers/agent-files.ts","../../../ui/src/ui/views/exec-approval.ts","../../../ui/src/ui/views/gateway-url-confirmation.ts","../../../ui/src/ui/app-render.ts","../../../ui/src/ui/controllers/learning.ts","../../../ui/src/ui/controllers/talk.ts","../../../ui/src/ui/app.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport audioCaptureWorkletUrl from \"./audio-capture-worklet.ts?worker&url\";\n\nconst mediaConstraints: MediaStreamConstraints = {\n audio: {\n // The capture worklet downmixes to mono, so mono is a preference rather\n // than a hard constraint that could fail device selection outright.\n channelCount: { ideal: 1 },\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n};\n\nconst DEFAULT_TARGET_SAMPLE_RATE_HZ = 24_000;\n\n// How long stop() waits for the worklet's final flushed batch to arrive after\n// posting \"stop\" before removing the message listener and tearing down.\nconst STOP_FLUSH_DRAIN_MS = 50;\n\nexport function createTalkAudioCapture(options: {\n onPcm16: (frame: Uint8Array) => void;\n /** Resample target for the worklet's output; the OpenAI realtime console uses 24 kHz, the\n * ADR 0087 streaming STT seam uses 16 kHz. Defaults to 24 kHz (console behaviour unchanged). */\n targetSampleRateHz?: number;\n}) {\n const targetSampleRateHz = options.targetSampleRateHz ?? DEFAULT_TARGET_SAMPLE_RATE_HZ;\n let stream: MediaStream | null = null;\n let context: AudioContext | null = null;\n let source: MediaStreamAudioSourceNode | null = null;\n let worklet: AudioWorkletNode | null = null;\n let gain: GainNode | null = null;\n let messageListener: ((event: MessageEvent<unknown>) => void) | null = null;\n let lifecycle = 0;\n let startPromise: Promise<void> | null = null;\n\n async function stop(): Promise<void> {\n lifecycle += 1;\n startPromise = null;\n const ownedStream = stream;\n const ownedContext = context;\n const ownedSource = source;\n const ownedWorklet = worklet;\n const ownedGain = gain;\n const ownedMessageListener = messageListener;\n\n stream = null;\n context = null;\n source = null;\n worklet = null;\n gain = null;\n messageListener = null;\n\n if (ownedWorklet && ownedMessageListener) {\n // Post the stop flush while a message listener is still attached so the\n // worklet's final batch is delivered, then give it a bounded moment to\n // arrive before removing the listeners and tearing the graph down.\n let settleFlush!: () => void;\n const flushed = new Promise<void>((resolveFlush) => {\n settleFlush = resolveFlush;\n });\n const flushAck = (event: MessageEvent<unknown>) => {\n // Only the worklet's explicit flush acknowledgement settles the drain;\n // a PCM batch queued ahead of the \"stop\" message must not.\n if (event.data === \"flushed\") {\n settleFlush();\n }\n };\n ownedWorklet.port.addEventListener(\"message\", flushAck);\n try {\n ownedWorklet.port.postMessage?.(\"stop\");\n } catch {\n // Flushing is best effort; teardown continues on a broken port.\n }\n await Promise.race([\n flushed,\n new Promise<void>((resolveTimeout) => {\n setTimeout(resolveTimeout, STOP_FLUSH_DRAIN_MS);\n }),\n ]);\n ownedWorklet.port.removeEventListener(\"message\", ownedMessageListener);\n ownedWorklet.port.removeEventListener(\"message\", flushAck);\n }\n ownedSource?.disconnect();\n ownedWorklet?.disconnect();\n ownedGain?.disconnect();\n for (const track of ownedStream?.getTracks() ?? []) {\n track.stop();\n }\n await ownedContext?.close();\n }\n\n async function startCapture(startup: number): Promise<void> {\n try {\n const acquiredStream = await navigator.mediaDevices.getUserMedia(mediaConstraints);\n if (startup !== lifecycle) {\n for (const track of acquiredStream.getTracks()) {\n track.stop();\n }\n return;\n }\n stream = acquiredStream;\n const acquiredContext = new AudioContext();\n context = acquiredContext;\n await acquiredContext.audioWorklet.addModule(audioCaptureWorkletUrl);\n if (startup !== lifecycle) {\n return;\n }\n source = acquiredContext.createMediaStreamSource(acquiredStream);\n worklet = new AudioWorkletNode(acquiredContext, \"wednesdayai-audio-capture\", {\n processorOptions: { targetSampleRateHz },\n });\n messageListener = (event: MessageEvent<unknown>) => {\n const buffer = event.data;\n if (buffer instanceof ArrayBuffer && buffer.byteLength % 2 === 0) {\n options.onPcm16(new Uint8Array(buffer));\n }\n };\n worklet.port.addEventListener(\"message\", messageListener);\n worklet.port.start();\n gain = acquiredContext.createGain();\n gain.gain.value = 0;\n source.connect(worklet);\n worklet.connect(gain);\n gain.connect(acquiredContext.destination);\n } catch (error) {\n if (startup !== lifecycle) {\n return;\n }\n await stop();\n throw error;\n }\n }\n\n return {\n start(): Promise<void> {\n if (startPromise) {\n return startPromise;\n }\n const pending = startCapture(++lifecycle);\n startPromise = pending;\n void pending.catch(() => {\n if (startPromise === pending) {\n startPromise = null;\n }\n });\n return pending;\n },\n async suspend(): Promise<void> {\n await context?.suspend();\n },\n async resume(): Promise<void> {\n await context?.resume();\n },\n stop,\n };\n}\n","type PlaybackSource = {\n node: AudioBufferSourceNode;\n generation: number;\n sequence: number;\n};\n\ntype PlaybackMark = {\n name: string;\n generation: number;\n barrier: number;\n};\n\nexport function createTalkAudioPlayback(options: {\n sampleRateHz: number;\n onMarkPlayed: (name: string, monotonicMs: number) => void;\n now: () => number;\n onOverflow?: () => void;\n /** Lookahead applied only when starting fresh (no audio currently scheduled), so the very first\n * chunk of an utterance has a buffer against a late-arriving next chunk. 0 (the default) keeps\n * the operator console's existing back-to-back scheduling unchanged. */\n preRollMs?: number;\n /** Route output through a `MediaStreamAudioDestinationNode` into an `<audio>` element instead of\n * `context.destination` directly, so the stream has a real media element for the browser's echo\n * cancellation to reference. Defaults to false (console's existing direct-destination sink). */\n echoSafeSink?: boolean;\n}) {\n const context = new AudioContext();\n const preRollSec = (options.preRollMs ?? 0) / 1000;\n const sinkNode: AudioNode = options.echoSafeSink\n ? context.createMediaStreamDestination()\n : context.destination;\n let audioElement: HTMLAudioElement | null = null;\n if (options.echoSafeSink) {\n const mediaStreamDestination = sinkNode as MediaStreamAudioDestinationNode;\n audioElement = document.createElement(\"audio\");\n audioElement.srcObject = mediaStreamDestination.stream;\n audioElement.autoplay = true;\n audioElement.muted = false;\n document.body.appendChild(audioElement);\n }\n const sources = new Set<PlaybackSource>();\n let marks: PlaybackMark[] = [];\n let generation = 0;\n let sourceSequence = 0;\n let nextPlayAt = 0;\n let closePromise: Promise<void> | null = null;\n let lastPlaybackEndedAt: number | null = null;\n\n function acknowledgeReadyMarks(endedGeneration: number, endedAt?: number) {\n const ready: PlaybackMark[] = [];\n const waiting: PlaybackMark[] = [];\n\n for (const mark of marks) {\n let blocked = false;\n for (const source of sources) {\n if (source.generation === mark.generation && source.sequence <= mark.barrier) {\n blocked = true;\n break;\n }\n }\n if (mark.generation === endedGeneration && !blocked) {\n ready.push(mark);\n } else {\n waiting.push(mark);\n }\n }\n marks = waiting;\n\n for (const mark of ready) {\n if (mark.generation !== generation) {\n break;\n }\n options.onMarkPlayed(mark.name, endedAt ?? options.now());\n }\n }\n\n function clear() {\n generation += 1;\n const scheduled = [...sources];\n sources.clear();\n marks = [];\n sourceSequence = 0;\n nextPlayAt = 0;\n\n for (const source of scheduled) {\n source.node.stop();\n }\n }\n\n return {\n enqueuePcm16(pcm16: Uint8Array) {\n const frameCount = Math.floor(pcm16.byteLength / 2);\n const buffer = context.createBuffer(1, frameCount, options.sampleRateHz);\n const samples = buffer.getChannelData(0);\n const view = new DataView(pcm16.buffer, pcm16.byteOffset, pcm16.byteLength);\n for (let index = 0; index < frameCount; index += 1) {\n samples[index] = view.getInt16(index * 2, true) / 32_768;\n }\n\n const node = context.createBufferSource();\n node.buffer = buffer;\n node.connect(sinkNode);\n // A pre-roll lookahead applies only when nothing is currently scheduled (fresh start or an\n // underrun) — once a run of chunks is already ahead of currentTime, back-to-back scheduling\n // continues from nextPlayAt exactly as before.\n const floor =\n nextPlayAt <= context.currentTime ? context.currentTime + preRollSec : nextPlayAt;\n const startAt = Math.max(context.currentTime, floor);\n nextPlayAt = startAt + frameCount / options.sampleRateHz;\n const source: PlaybackSource = {\n node,\n generation,\n sequence: ++sourceSequence,\n };\n sources.add(source);\n node.addEventListener(\"ended\", () => {\n if (source.generation !== generation) {\n return;\n }\n sources.delete(source);\n if (sources.size === 0) {\n const endedAt = options.now();\n lastPlaybackEndedAt = endedAt;\n acknowledgeReadyMarks(source.generation, endedAt);\n return;\n }\n acknowledgeReadyMarks(source.generation);\n });\n node.start(startAt);\n },\n attachMark(name: string) {\n if (marks.length >= 256) {\n clear();\n options.onOverflow?.();\n return;\n }\n marks.push({ name, generation, barrier: sourceSequence });\n acknowledgeReadyMarks(generation);\n },\n clear,\n stop(): Promise<void> {\n if (!closePromise) {\n clear();\n audioElement?.remove();\n closePromise = context.close();\n }\n return closePromise;\n },\n isPlaying() {\n return sources.size > 0;\n },\n suspend(): Promise<void> | undefined {\n if (closePromise) {\n return undefined;\n }\n return context.suspend();\n },\n resume(): Promise<void> | undefined {\n if (closePromise) {\n return undefined;\n }\n return context.resume();\n },\n get lastPlaybackEndedAt() {\n return lastPlaybackEndedAt;\n },\n };\n}\n","import type { TalkRealtimeRelayEvent, TalkRealtimeRelaySessionResult } from \"./types.ts\";\n\nexport type TalkLifecycle = \"idle\" | \"starting\" | \"active\" | \"interrupting\" | \"stopping\";\n\nexport type TalkRequest = <T>(method: string, params?: unknown) => Promise<T>;\n\nexport type TalkAudioCapture = {\n start(): Promise<void>;\n suspend(): Promise<void>;\n resume(): Promise<void>;\n stop(): Promise<void>;\n};\n\nexport type TalkAudioPlayback = {\n enqueuePcm16(frame: Uint8Array): void;\n attachMark(name: string): void;\n clear(): void;\n stop(): Promise<void>;\n isPlaying(): boolean;\n suspend?(): Promise<void> | undefined;\n resume?(): Promise<void> | undefined;\n readonly lastPlaybackEndedAt?: number | null;\n};\n\nexport type TalkSessionClientState = {\n lifecycle: TalkLifecycle;\n relaySessionId: string | null;\n provider: string | null;\n recording: boolean;\n playing: boolean;\n droppedAudioFrames: number;\n};\n\nexport type TalkSessionClientOptions = {\n request: TalkRequest;\n capture: (options: { onPcm16: (frame: Uint8Array) => void }) => TalkAudioCapture;\n playback: (options: {\n sampleRateHz: number;\n onMarkPlayed: (name: string, monotonicMs: number) => void;\n now: () => number;\n onOverflow?: () => void;\n }) => TalkAudioPlayback;\n onState: (state: TalkSessionClientState) => void;\n onEvent: (event: TalkRealtimeRelayEvent) => void;\n now?: () => number;\n};\n\nexport type TalkSessionClient = {\n start(): Promise<void>;\n handleRelayEvent(event: TalkRealtimeRelayEvent): void;\n handleGatewayClose(): void;\n stop(): Promise<void>;\n};\n\nconst MAX_IN_FLIGHT_AUDIO_REQUESTS = 4;\nconst ECHO_TAIL_SUPPRESS_MS = 500;\nconst RELAY_READY_TIMEOUT_MS = 10_000;\n\nfunction encodeBase64(bytes: Uint8Array): string {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n return btoa(binary);\n}\n\nfunction decodeBase64(value: string): Uint8Array {\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nexport function createTalkSessionClient(options: TalkSessionClientOptions): TalkSessionClient {\n const now = options.now ?? (() => performance.now());\n const inFlightAudioRequests = new Set<Promise<unknown>>();\n const remoteStopRequests = new Map<string, Promise<void>>();\n let lifecycle: TalkLifecycle = \"idle\";\n let relaySessionId: string | null = null;\n let provider: string | null = null;\n let capture: TalkAudioCapture | null = null;\n let playback: TalkAudioPlayback | null = null;\n let droppedAudioFrames = 0;\n let generation = 0;\n let startPromise: Promise<void> | null = null;\n let stopPromise: Promise<void> | null = null;\n let visibilityHandler: (() => void) | null = null;\n let visibilityHandlerGeneration: number | null = null;\n let readyWaiter: {\n relaySessionId: string;\n generation: number;\n resolve: () => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n } | null = null;\n let readySeen: { relaySessionId: string; generation: number } | null = null;\n\n function emitState() {\n options.onState({\n lifecycle,\n relaySessionId,\n provider,\n recording: capture !== null && (lifecycle === \"active\" || lifecycle === \"interrupting\"),\n playing: playback?.isPlaying() ?? false,\n droppedAudioFrames,\n });\n }\n\n function setLifecycle(next: TalkLifecycle) {\n lifecycle = next;\n emitState();\n }\n\n function stopRemoteOnce(id: string): Promise<void> {\n const existing = remoteStopRequests.get(id);\n if (existing) {\n return existing;\n }\n let pending: Promise<void>;\n try {\n pending = options\n .request<void>(\"talk.realtime.stop\", { relaySessionId: id })\n .catch(() => undefined);\n } catch {\n pending = Promise.resolve();\n }\n remoteStopRequests.set(id, pending);\n // Only the entry this call installed may be dropped; a later stop for the\n // same relay id owns the map from the moment it replaces this one.\n void pending\n .finally(() => {\n if (remoteStopRequests.get(id) === pending) {\n remoteStopRequests.delete(id);\n }\n })\n .catch(() => undefined);\n return pending;\n }\n\n function quietResource(promise: Promise<void> | undefined) {\n if (promise) {\n void promise.catch(() => undefined);\n }\n }\n\n function removeVisibilityHandler() {\n const handler = visibilityHandler;\n visibilityHandler = null;\n visibilityHandlerGeneration = null;\n if (!handler || typeof document === \"undefined\") {\n return;\n }\n document.removeEventListener(\"visibilitychange\", handler);\n }\n\n function clearReadyWaiter() {\n const waiter = readyWaiter;\n if (!waiter) {\n return;\n }\n readyWaiter = null;\n clearTimeout(waiter.timer);\n // Settle the abandoned waiter so the start continuation awaiting relay\n // readiness unblocks and its cleanup path (or stop()) can complete.\n waiter.reject(new Error(\"Relay readiness aborted\"));\n }\n\n function waitForRelayReady(ownerGeneration: number, ownerRelaySessionId: string): Promise<void> {\n if (\n readySeen?.relaySessionId === ownerRelaySessionId &&\n readySeen.generation === ownerGeneration\n ) {\n return Promise.resolve();\n }\n clearReadyWaiter();\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n if (readyWaiter?.generation === ownerGeneration) {\n readyWaiter = null;\n }\n resolve();\n }, RELAY_READY_TIMEOUT_MS);\n readyWaiter = {\n relaySessionId: ownerRelaySessionId,\n generation: ownerGeneration,\n resolve: () => {\n clearTimeout(timer);\n readyWaiter = null;\n resolve();\n },\n reject: (error: Error) => {\n clearTimeout(timer);\n readyWaiter = null;\n reject(error);\n },\n timer,\n };\n });\n }\n\n function installVisibilityHandler(ownerGeneration: number) {\n if (typeof document === \"undefined\") {\n return;\n }\n if (visibilityHandler !== null && visibilityHandlerGeneration === ownerGeneration) {\n return;\n }\n removeVisibilityHandler();\n // The handler is owned by the generation that installed it; a stale\n // handler from a torn-down session must never touch live resources.\n // relaySessionId is written exactly once per generation (at resource\n // install), so the generation fence also pins the relay identity.\n const handler = () => {\n if (generation !== ownerGeneration) {\n return;\n }\n const ownedCapture = capture;\n const ownedPlayback = playback;\n const ownedRelaySessionId = relaySessionId;\n if (!ownedCapture && !ownedPlayback) {\n return;\n }\n if (document.hidden) {\n try {\n quietResource(ownedCapture?.suspend());\n } catch {\n // Visibility suspension is best effort.\n }\n quietResource(ownedPlayback?.suspend?.());\n return;\n }\n if (ownedRelaySessionId === null) {\n return;\n }\n try {\n quietResource(ownedCapture?.resume());\n } catch {\n // See suspend above.\n }\n quietResource(ownedPlayback?.resume?.());\n };\n visibilityHandler = handler;\n visibilityHandlerGeneration = ownerGeneration;\n document.addEventListener(\"visibilitychange\", handler);\n }\n\n function failClosedOnPlaybackOverflow(ownerGeneration: number, ownerRelaySessionId: string) {\n if (generation !== ownerGeneration || relaySessionId !== ownerRelaySessionId) {\n return;\n }\n generation += 1;\n // Unblock a startOwned still waiting for relay readiness; its stale fence\n // then routes the continuation into cleanup instead of the 10s fallback.\n clearReadyWaiter();\n readySeen = null;\n inFlightAudioRequests.clear();\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n const localRelease = releaseLocal();\n setLifecycle(\"idle\");\n void (async () => {\n await localRelease;\n await stopRemoteOnce(ownerRelaySessionId);\n })();\n }\n\n function releaseLocal(): Promise<void> {\n const ownedCapture = capture;\n const ownedPlayback = playback;\n capture = null;\n playback = null;\n const releases: Promise<unknown>[] = [];\n\n if (ownedCapture) {\n try {\n releases.push(ownedCapture.stop());\n } catch {\n // Local release is best effort, but every owned resource still gets its stop call.\n }\n }\n if (ownedPlayback) {\n try {\n releases.push(ownedPlayback.stop());\n } catch {\n // See capture teardown above.\n }\n }\n return Promise.allSettled(releases).then(() => undefined);\n }\n\n function sendAudio(frame: Uint8Array, ownerGeneration: number, ownerRelaySessionId: string) {\n if (\n generation !== ownerGeneration ||\n relaySessionId !== ownerRelaySessionId ||\n (lifecycle !== \"active\" && lifecycle !== \"interrupting\")\n ) {\n return;\n }\n // Echo tail: the microphone can still carry assistant audio shortly after playback ends.\n // The generation/relay fence above guarantees any observable playback end belongs to the\n // current session, so a recent end suppresses the frame silently while playback is idle.\n if (playback !== null && !playback.isPlaying()) {\n const playbackEndedAt = playback.lastPlaybackEndedAt;\n if (\n playbackEndedAt !== null &&\n playbackEndedAt !== undefined &&\n now() - playbackEndedAt < ECHO_TAIL_SUPPRESS_MS\n ) {\n return;\n }\n }\n if (inFlightAudioRequests.size >= MAX_IN_FLIGHT_AUDIO_REQUESTS) {\n droppedAudioFrames += 1;\n emitState();\n return;\n }\n\n let pending: Promise<unknown>;\n try {\n pending = options.request<void>(\"talk.realtime.audio\", {\n relaySessionId: ownerRelaySessionId,\n audioBase64: encodeBase64(frame),\n timestamp: now(),\n });\n } catch {\n return;\n }\n inFlightAudioRequests.add(pending);\n const releaseIfCurrent = () => {\n if (generation === ownerGeneration && relaySessionId === ownerRelaySessionId) {\n inFlightAudioRequests.delete(pending);\n }\n };\n void pending.then(releaseIfCurrent, releaseIfCurrent);\n }\n\n function acknowledgeMark(\n name: string,\n monotonicMs: number,\n ownerGeneration: number,\n ownerRelaySessionId: string,\n ) {\n if (generation !== ownerGeneration || relaySessionId !== ownerRelaySessionId) {\n return;\n }\n try {\n void options\n .request<void>(\"talk.realtime.mark\", {\n relaySessionId: ownerRelaySessionId,\n markName: name,\n timestamp: monotonicMs,\n })\n .catch(() => undefined);\n } catch {\n // Playback acknowledgement is best effort after local playback has completed.\n }\n emitState();\n }\n\n async function startOwned(ownerGeneration: number): Promise<void> {\n let session: TalkRealtimeRelaySessionResult;\n try {\n session = await options.request<TalkRealtimeRelaySessionResult>(\"talk.realtime.session\", {\n transport: \"gateway-relay\",\n });\n } catch (error) {\n if (generation !== ownerGeneration) {\n return;\n }\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n setLifecycle(\"idle\");\n throw error;\n }\n\n if (generation !== ownerGeneration) {\n await stopRemoteOnce(session.relaySessionId);\n return;\n }\n\n relaySessionId = session.relaySessionId;\n provider = session.provider;\n try {\n const playbackOptions: {\n sampleRateHz: number;\n onMarkPlayed: (name: string, monotonicMs: number) => void;\n now: () => number;\n onOverflow?: () => void;\n } = {\n sampleRateHz: session.audio.outputSampleRateHz,\n onMarkPlayed: (name, monotonicMs) =>\n acknowledgeMark(name, monotonicMs, ownerGeneration, session.relaySessionId),\n now,\n onOverflow: () => failClosedOnPlaybackOverflow(ownerGeneration, session.relaySessionId),\n };\n playback = options.playback(playbackOptions);\n try {\n await playback.resume?.();\n } catch {\n // Autoplay resume is best effort; capture startup must still proceed.\n }\n if (generation !== ownerGeneration) {\n throw new Error(\"Talk start aborted: session superseded during playback resume\");\n }\n capture = options.capture({\n onPcm16: (frame) => sendAudio(frame, ownerGeneration, session.relaySessionId),\n });\n await waitForRelayReady(ownerGeneration, session.relaySessionId);\n if (generation !== ownerGeneration) {\n throw new Error(\"Talk start aborted: session superseded before capture start\");\n }\n await capture.start();\n } catch (error) {\n const isCurrent = generation === ownerGeneration;\n if (isCurrent) {\n generation += 1;\n clearReadyWaiter();\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n }\n await releaseLocal();\n await stopRemoteOnce(session.relaySessionId);\n if (isCurrent) {\n setLifecycle(\"idle\");\n throw error;\n }\n return;\n }\n\n if (generation !== ownerGeneration || relaySessionId !== session.relaySessionId) {\n await releaseLocal();\n await stopRemoteOnce(session.relaySessionId);\n return;\n }\n if (typeof document !== \"undefined\" && document.hidden) {\n // A session that becomes active while hidden starts suspended; the fence\n // above guarantees these resources still belong to the current generation.\n try {\n quietResource(capture?.suspend());\n } catch {\n // Visibility suspension is best effort.\n }\n quietResource(playback?.suspend?.());\n }\n setLifecycle(\"active\");\n }\n\n function start(): Promise<void> {\n if (stopPromise) {\n return stopPromise.then(() => start());\n }\n if (startPromise) {\n return startPromise;\n }\n if (relaySessionId) {\n return Promise.resolve();\n }\n\n const ownerGeneration = ++generation;\n droppedAudioFrames = 0;\n // Armed at claim time so a hide during the pending session request is not\n // lost; resources installing later suspend themselves while hidden.\n installVisibilityHandler(ownerGeneration);\n setLifecycle(\"starting\");\n const pending = startOwned(ownerGeneration);\n startPromise = pending;\n void pending.then(\n () => {\n if (startPromise === pending) {\n startPromise = null;\n }\n },\n () => {\n if (startPromise === pending) {\n startPromise = null;\n }\n },\n );\n return pending;\n }\n\n function stop(): Promise<void> {\n if (stopPromise) {\n return stopPromise;\n }\n\n const stopGeneration = ++generation;\n clearReadyWaiter();\n readySeen = null;\n const ownedRelaySessionId = relaySessionId;\n const ownedStart = startPromise;\n inFlightAudioRequests.clear();\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n const localRelease = releaseLocal();\n setLifecycle(\"stopping\");\n\n const pending = (async () => {\n await localRelease;\n if (ownedRelaySessionId) {\n await stopRemoteOnce(ownedRelaySessionId);\n }\n if (ownedStart) {\n await ownedStart.catch(() => undefined);\n }\n if (generation === stopGeneration) {\n setLifecycle(\"idle\");\n }\n })();\n stopPromise = pending;\n void pending.then(\n () => {\n if (stopPromise === pending) {\n stopPromise = null;\n }\n },\n () => {\n if (stopPromise === pending) {\n stopPromise = null;\n }\n },\n );\n return pending;\n }\n\n function handleRelayEvent(event: TalkRealtimeRelayEvent) {\n if (event.relaySessionId !== relaySessionId) {\n return;\n }\n\n switch (event.type) {\n case \"audio\":\n playback?.enqueuePcm16(decodeBase64(event.audioBase64));\n if (lifecycle === \"interrupting\") {\n setLifecycle(\"active\");\n } else {\n emitState();\n }\n break;\n case \"mark\":\n playback?.attachMark(event.markName);\n emitState();\n break;\n case \"clear\":\n case \"vadBargeIn\": {\n if (lifecycle === \"interrupting\") {\n break;\n }\n playback?.clear();\n setLifecycle(\"interrupting\");\n break;\n }\n case \"ready\":\n // Latch readiness for this generation so a ready event that arrives\n // while the start continuation is still awaiting playback resume is\n // not dropped in front of the waiter installation.\n readySeen = { relaySessionId: event.relaySessionId, generation };\n if (\n readyWaiter?.relaySessionId === event.relaySessionId &&\n readyWaiter.generation === generation\n ) {\n readyWaiter.resolve();\n }\n if (lifecycle === \"interrupting\") {\n setLifecycle(\"active\");\n }\n break;\n case \"transcript\":\n if (event.role === \"assistant\" && lifecycle === \"interrupting\") {\n setLifecycle(\"active\");\n }\n break;\n case \"close\": {\n generation += 1;\n clearReadyWaiter();\n readySeen = null;\n inFlightAudioRequests.clear();\n relaySessionId = null;\n provider = null;\n removeVisibilityHandler();\n const localRelease = releaseLocal();\n setLifecycle(\"idle\");\n void localRelease;\n break;\n }\n default:\n break;\n }\n options.onEvent(event);\n }\n\n return {\n start,\n handleRelayEvent,\n handleGatewayClose() {\n void stop();\n },\n stop,\n };\n}\n\nexport type { TalkRealtimeRelayEvent, TalkRealtimeRelaySessionResult };\n","import { ChannelsStatusSnapshot } from \"../types.ts\";\nimport type { ChannelsState } from \"./channels.types.ts\";\n\nexport type { ChannelsState };\n\nexport async function loadChannels(state: ChannelsState, probe: boolean) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.channelsLoading) {\n return;\n }\n state.channelsLoading = true;\n state.channelsError = null;\n try {\n const res = await state.client.request<ChannelsStatusSnapshot | null>(\"channels.status\", {\n probe,\n timeoutMs: 8000,\n });\n state.channelsSnapshot = res;\n state.channelsLastSuccess = Date.now();\n } catch (err) {\n state.channelsError = String(err);\n } finally {\n state.channelsLoading = false;\n }\n}\n\nexport async function startWhatsAppLogin(state: ChannelsState, force: boolean) {\n if (!state.client || !state.connected || state.whatsappBusy) {\n return;\n }\n state.whatsappBusy = true;\n try {\n const res = await state.client.request<{ message?: string; qrDataUrl?: string }>(\n \"web.login.start\",\n {\n force,\n timeoutMs: 30000,\n },\n );\n state.whatsappLoginMessage = res.message ?? null;\n state.whatsappLoginQrDataUrl = res.qrDataUrl ?? null;\n state.whatsappLoginConnected = null;\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n state.whatsappLoginQrDataUrl = null;\n state.whatsappLoginConnected = null;\n } finally {\n state.whatsappBusy = false;\n }\n}\n\nexport async function waitWhatsAppLogin(state: ChannelsState) {\n if (!state.client || !state.connected || state.whatsappBusy) {\n return;\n }\n state.whatsappBusy = true;\n try {\n const res = await state.client.request<{ message?: string; connected?: boolean }>(\n \"web.login.wait\",\n {\n timeoutMs: 120000,\n },\n );\n state.whatsappLoginMessage = res.message ?? null;\n state.whatsappLoginConnected = res.connected ?? null;\n if (res.connected) {\n state.whatsappLoginQrDataUrl = null;\n }\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n state.whatsappLoginConnected = null;\n } finally {\n state.whatsappBusy = false;\n }\n}\n\nexport async function logoutWhatsApp(state: ChannelsState) {\n if (!state.client || !state.connected || state.whatsappBusy) {\n return;\n }\n state.whatsappBusy = true;\n try {\n await state.client.request(\"channels.logout\", { channel: \"whatsapp\" });\n state.whatsappLoginMessage = \"Logged out.\";\n state.whatsappLoginQrDataUrl = null;\n state.whatsappLoginConnected = null;\n } catch (err) {\n state.whatsappLoginMessage = String(err);\n } finally {\n state.whatsappBusy = false;\n }\n}\n","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(global.JSON5 = factory());\n}(this, (function () { 'use strict';\n\n\tfunction createCommonjsModule(fn, module) {\n\t\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n\t}\n\n\tvar _global = createCommonjsModule(function (module) {\n\t// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\n\tvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n\t ? window : typeof self != 'undefined' && self.Math == Math ? self\n\t // eslint-disable-next-line no-new-func\n\t : Function('return this')();\n\tif (typeof __g == 'number') { __g = global; } // eslint-disable-line no-undef\n\t});\n\n\tvar _core = createCommonjsModule(function (module) {\n\tvar core = module.exports = { version: '2.6.5' };\n\tif (typeof __e == 'number') { __e = core; } // eslint-disable-line no-undef\n\t});\n\tvar _core_1 = _core.version;\n\n\tvar _isObject = function (it) {\n\t return typeof it === 'object' ? it !== null : typeof it === 'function';\n\t};\n\n\tvar _anObject = function (it) {\n\t if (!_isObject(it)) { throw TypeError(it + ' is not an object!'); }\n\t return it;\n\t};\n\n\tvar _fails = function (exec) {\n\t try {\n\t return !!exec();\n\t } catch (e) {\n\t return true;\n\t }\n\t};\n\n\t// Thank's IE8 for his funny defineProperty\n\tvar _descriptors = !_fails(function () {\n\t return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n\t});\n\n\tvar document = _global.document;\n\t// typeof document.createElement is 'object' in old IE\n\tvar is = _isObject(document) && _isObject(document.createElement);\n\tvar _domCreate = function (it) {\n\t return is ? document.createElement(it) : {};\n\t};\n\n\tvar _ie8DomDefine = !_descriptors && !_fails(function () {\n\t return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7;\n\t});\n\n\t// 7.1.1 ToPrimitive(input [, PreferredType])\n\n\t// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n\t// and the second argument - flag - preferred type is a string\n\tvar _toPrimitive = function (it, S) {\n\t if (!_isObject(it)) { return it; }\n\t var fn, val;\n\t if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; }\n\t if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) { return val; }\n\t if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; }\n\t throw TypeError(\"Can't convert object to primitive value\");\n\t};\n\n\tvar dP = Object.defineProperty;\n\n\tvar f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n\t _anObject(O);\n\t P = _toPrimitive(P, true);\n\t _anObject(Attributes);\n\t if (_ie8DomDefine) { try {\n\t return dP(O, P, Attributes);\n\t } catch (e) { /* empty */ } }\n\t if ('get' in Attributes || 'set' in Attributes) { throw TypeError('Accessors not supported!'); }\n\t if ('value' in Attributes) { O[P] = Attributes.value; }\n\t return O;\n\t};\n\n\tvar _objectDp = {\n\t\tf: f\n\t};\n\n\tvar _propertyDesc = function (bitmap, value) {\n\t return {\n\t enumerable: !(bitmap & 1),\n\t configurable: !(bitmap & 2),\n\t writable: !(bitmap & 4),\n\t value: value\n\t };\n\t};\n\n\tvar _hide = _descriptors ? function (object, key, value) {\n\t return _objectDp.f(object, key, _propertyDesc(1, value));\n\t} : function (object, key, value) {\n\t object[key] = value;\n\t return object;\n\t};\n\n\tvar hasOwnProperty = {}.hasOwnProperty;\n\tvar _has = function (it, key) {\n\t return hasOwnProperty.call(it, key);\n\t};\n\n\tvar id = 0;\n\tvar px = Math.random();\n\tvar _uid = function (key) {\n\t return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n\t};\n\n\tvar _library = false;\n\n\tvar _shared = createCommonjsModule(function (module) {\n\tvar SHARED = '__core-js_shared__';\n\tvar store = _global[SHARED] || (_global[SHARED] = {});\n\n\t(module.exports = function (key, value) {\n\t return store[key] || (store[key] = value !== undefined ? value : {});\n\t})('versions', []).push({\n\t version: _core.version,\n\t mode: _library ? 'pure' : 'global',\n\t copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n\t});\n\t});\n\n\tvar _functionToString = _shared('native-function-to-string', Function.toString);\n\n\tvar _redefine = createCommonjsModule(function (module) {\n\tvar SRC = _uid('src');\n\n\tvar TO_STRING = 'toString';\n\tvar TPL = ('' + _functionToString).split(TO_STRING);\n\n\t_core.inspectSource = function (it) {\n\t return _functionToString.call(it);\n\t};\n\n\t(module.exports = function (O, key, val, safe) {\n\t var isFunction = typeof val == 'function';\n\t if (isFunction) { _has(val, 'name') || _hide(val, 'name', key); }\n\t if (O[key] === val) { return; }\n\t if (isFunction) { _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); }\n\t if (O === _global) {\n\t O[key] = val;\n\t } else if (!safe) {\n\t delete O[key];\n\t _hide(O, key, val);\n\t } else if (O[key]) {\n\t O[key] = val;\n\t } else {\n\t _hide(O, key, val);\n\t }\n\t// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n\t})(Function.prototype, TO_STRING, function toString() {\n\t return typeof this == 'function' && this[SRC] || _functionToString.call(this);\n\t});\n\t});\n\n\tvar _aFunction = function (it) {\n\t if (typeof it != 'function') { throw TypeError(it + ' is not a function!'); }\n\t return it;\n\t};\n\n\t// optional / simple context binding\n\n\tvar _ctx = function (fn, that, length) {\n\t _aFunction(fn);\n\t if (that === undefined) { return fn; }\n\t switch (length) {\n\t case 1: return function (a) {\n\t return fn.call(that, a);\n\t };\n\t case 2: return function (a, b) {\n\t return fn.call(that, a, b);\n\t };\n\t case 3: return function (a, b, c) {\n\t return fn.call(that, a, b, c);\n\t };\n\t }\n\t return function (/* ...args */) {\n\t return fn.apply(that, arguments);\n\t };\n\t};\n\n\tvar PROTOTYPE = 'prototype';\n\n\tvar $export = function (type, name, source) {\n\t var IS_FORCED = type & $export.F;\n\t var IS_GLOBAL = type & $export.G;\n\t var IS_STATIC = type & $export.S;\n\t var IS_PROTO = type & $export.P;\n\t var IS_BIND = type & $export.B;\n\t var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];\n\t var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});\n\t var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n\t var key, own, out, exp;\n\t if (IS_GLOBAL) { source = name; }\n\t for (key in source) {\n\t // contains in native\n\t own = !IS_FORCED && target && target[key] !== undefined;\n\t // export native or passed\n\t out = (own ? target : source)[key];\n\t // bind timers to global for call from export context\n\t exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;\n\t // extend global\n\t if (target) { _redefine(target, key, out, type & $export.U); }\n\t // export\n\t if (exports[key] != out) { _hide(exports, key, exp); }\n\t if (IS_PROTO && expProto[key] != out) { expProto[key] = out; }\n\t }\n\t};\n\t_global.core = _core;\n\t// type bitmap\n\t$export.F = 1; // forced\n\t$export.G = 2; // global\n\t$export.S = 4; // static\n\t$export.P = 8; // proto\n\t$export.B = 16; // bind\n\t$export.W = 32; // wrap\n\t$export.U = 64; // safe\n\t$export.R = 128; // real proto method for `library`\n\tvar _export = $export;\n\n\t// 7.1.4 ToInteger\n\tvar ceil = Math.ceil;\n\tvar floor = Math.floor;\n\tvar _toInteger = function (it) {\n\t return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n\t};\n\n\t// 7.2.1 RequireObjectCoercible(argument)\n\tvar _defined = function (it) {\n\t if (it == undefined) { throw TypeError(\"Can't call method on \" + it); }\n\t return it;\n\t};\n\n\t// true -> String#at\n\t// false -> String#codePointAt\n\tvar _stringAt = function (TO_STRING) {\n\t return function (that, pos) {\n\t var s = String(_defined(that));\n\t var i = _toInteger(pos);\n\t var l = s.length;\n\t var a, b;\n\t if (i < 0 || i >= l) { return TO_STRING ? '' : undefined; }\n\t a = s.charCodeAt(i);\n\t return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n\t ? TO_STRING ? s.charAt(i) : a\n\t : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n\t };\n\t};\n\n\tvar $at = _stringAt(false);\n\t_export(_export.P, 'String', {\n\t // 21.1.3.3 String.prototype.codePointAt(pos)\n\t codePointAt: function codePointAt(pos) {\n\t return $at(this, pos);\n\t }\n\t});\n\n\tvar codePointAt = _core.String.codePointAt;\n\n\tvar max = Math.max;\n\tvar min = Math.min;\n\tvar _toAbsoluteIndex = function (index, length) {\n\t index = _toInteger(index);\n\t return index < 0 ? max(index + length, 0) : min(index, length);\n\t};\n\n\tvar fromCharCode = String.fromCharCode;\n\tvar $fromCodePoint = String.fromCodePoint;\n\n\t// length should be 1, old FF problem\n\t_export(_export.S + _export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {\n\t // 21.1.2.2 String.fromCodePoint(...codePoints)\n\t fromCodePoint: function fromCodePoint(x) {\n\t var arguments$1 = arguments;\n\t // eslint-disable-line no-unused-vars\n\t var res = [];\n\t var aLen = arguments.length;\n\t var i = 0;\n\t var code;\n\t while (aLen > i) {\n\t code = +arguments$1[i++];\n\t if (_toAbsoluteIndex(code, 0x10ffff) !== code) { throw RangeError(code + ' is not a valid code point'); }\n\t res.push(code < 0x10000\n\t ? fromCharCode(code)\n\t : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)\n\t );\n\t } return res.join('');\n\t }\n\t});\n\n\tvar fromCodePoint = _core.String.fromCodePoint;\n\n\t// This is a generated file. Do not edit.\n\tvar Space_Separator = /[\\u1680\\u2000-\\u200A\\u202F\\u205F\\u3000]/;\n\tvar ID_Start = /[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u08A0-\\u08B4\\u08B6-\\u08BD\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312E\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FEA\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7AE\\uA7B0-\\uA7B7\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB65\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDD40-\\uDD74\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF4A\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF\\uDFD1-\\uDFD5]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE33\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2]|\\uD804[\\uDC03-\\uDC37\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDF00-\\uDF19]|\\uD806[\\uDCA0-\\uDCDF\\uDCFF\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE83\\uDE86-\\uDE89\\uDEC0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC00-\\uDC6E\\uDC80-\\uDD43]|[\\uD80C\\uD81C-\\uD820\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDF00-\\uDF44\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1]|\\uD821[\\uDC00-\\uDFEC]|\\uD822[\\uDC00-\\uDEF2]|\\uD82C[\\uDC00-\\uDD1E\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDED6\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF34\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]/;\n\tvar ID_Continue = /[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u0860-\\u086A\\u08A0-\\u08B4\\u08B6-\\u08BD\\u08D4-\\u08E1\\u08E3-\\u0963\\u0966-\\u096F\\u0971-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u09FC\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0AF9-\\u0AFF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C00-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58-\\u0C5A\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C80-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D00-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D54-\\u0D57\\u0D5F-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DE6-\\u0DEF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19D9\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1AB0-\\u1ABD\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1C80-\\u1C88\\u1CD0-\\u1CD2\\u1CD4-\\u1CF9\\u1D00-\\u1DF9\\u1DFB-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u2E2F\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099\\u309A\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312E\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FEA\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7AE\\uA7B0-\\uA7B7\\uA7F7-\\uA827\\uA840-\\uA873\\uA880-\\uA8C5\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA8FD\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uA9E0-\\uA9FE\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB65\\uAB70-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE2F\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDD40-\\uDD74\\uDDFD\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDEE0\\uDF00-\\uDF1F\\uDF2D-\\uDF4A\\uDF50-\\uDF7A\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF\\uDFD1-\\uDFD5]|\\uD801[\\uDC00-\\uDC9D\\uDCA0-\\uDCA9\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00-\\uDE03\\uDE05\\uDE06\\uDE0C-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE33\\uDE38-\\uDE3A\\uDE3F\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE6\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2]|\\uD804[\\uDC00-\\uDC46\\uDC66-\\uDC6F\\uDC7F-\\uDCBA\\uDCD0-\\uDCE8\\uDCF0-\\uDCF9\\uDD00-\\uDD34\\uDD36-\\uDD3F\\uDD50-\\uDD73\\uDD76\\uDD80-\\uDDC4\\uDDCA-\\uDDCC\\uDDD0-\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE37\\uDE3E\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEEA\\uDEF0-\\uDEF9\\uDF00-\\uDF03\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3C-\\uDF44\\uDF47\\uDF48\\uDF4B-\\uDF4D\\uDF50\\uDF57\\uDF5D-\\uDF63\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDC00-\\uDC4A\\uDC50-\\uDC59\\uDC80-\\uDCC5\\uDCC7\\uDCD0-\\uDCD9\\uDD80-\\uDDB5\\uDDB8-\\uDDC0\\uDDD8-\\uDDDD\\uDE00-\\uDE40\\uDE44\\uDE50-\\uDE59\\uDE80-\\uDEB7\\uDEC0-\\uDEC9\\uDF00-\\uDF19\\uDF1D-\\uDF2B\\uDF30-\\uDF39]|\\uD806[\\uDCA0-\\uDCE9\\uDCFF\\uDE00-\\uDE3E\\uDE47\\uDE50-\\uDE83\\uDE86-\\uDE99\\uDEC0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC36\\uDC38-\\uDC40\\uDC50-\\uDC59\\uDC72-\\uDC8F\\uDC92-\\uDCA7\\uDCA9-\\uDCB6\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD36\\uDD3A\\uDD3C\\uDD3D\\uDD3F-\\uDD47\\uDD50-\\uDD59]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC00-\\uDC6E\\uDC80-\\uDD43]|[\\uD80C\\uD81C-\\uD820\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE60-\\uDE69\\uDED0-\\uDEED\\uDEF0-\\uDEF4\\uDF00-\\uDF36\\uDF40-\\uDF43\\uDF50-\\uDF59\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDF00-\\uDF44\\uDF50-\\uDF7E\\uDF8F-\\uDF9F\\uDFE0\\uDFE1]|\\uD821[\\uDC00-\\uDFEC]|\\uD822[\\uDC00-\\uDEF2]|\\uD82C[\\uDC00-\\uDD1E\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99\\uDC9D\\uDC9E]|\\uD834[\\uDD65-\\uDD69\\uDD6D-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB\\uDFCE-\\uDFFF]|\\uD836[\\uDE00-\\uDE36\\uDE3B-\\uDE6C\\uDE75\\uDE84\\uDE9B-\\uDE9F\\uDEA1-\\uDEAF]|\\uD838[\\uDC00-\\uDC06\\uDC08-\\uDC18\\uDC1B-\\uDC21\\uDC23\\uDC24\\uDC26-\\uDC2A]|\\uD83A[\\uDC00-\\uDCC4\\uDCD0-\\uDCD6\\uDD00-\\uDD4A\\uDD50-\\uDD59]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDED6\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF34\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]|\\uDB40[\\uDD00-\\uDDEF]/;\n\n\tvar unicode = {\n\t\tSpace_Separator: Space_Separator,\n\t\tID_Start: ID_Start,\n\t\tID_Continue: ID_Continue\n\t};\n\n\tvar util = {\n\t isSpaceSeparator: function isSpaceSeparator (c) {\n\t return typeof c === 'string' && unicode.Space_Separator.test(c)\n\t },\n\n\t isIdStartChar: function isIdStartChar (c) {\n\t return typeof c === 'string' && (\n\t (c >= 'a' && c <= 'z') ||\n\t (c >= 'A' && c <= 'Z') ||\n\t (c === '$') || (c === '_') ||\n\t unicode.ID_Start.test(c)\n\t )\n\t },\n\n\t isIdContinueChar: function isIdContinueChar (c) {\n\t return typeof c === 'string' && (\n\t (c >= 'a' && c <= 'z') ||\n\t (c >= 'A' && c <= 'Z') ||\n\t (c >= '0' && c <= '9') ||\n\t (c === '$') || (c === '_') ||\n\t (c === '\\u200C') || (c === '\\u200D') ||\n\t unicode.ID_Continue.test(c)\n\t )\n\t },\n\n\t isDigit: function isDigit (c) {\n\t return typeof c === 'string' && /[0-9]/.test(c)\n\t },\n\n\t isHexDigit: function isHexDigit (c) {\n\t return typeof c === 'string' && /[0-9A-Fa-f]/.test(c)\n\t },\n\t};\n\n\tvar source;\n\tvar parseState;\n\tvar stack;\n\tvar pos;\n\tvar line;\n\tvar column;\n\tvar token;\n\tvar key;\n\tvar root;\n\n\tvar parse = function parse (text, reviver) {\n\t source = String(text);\n\t parseState = 'start';\n\t stack = [];\n\t pos = 0;\n\t line = 1;\n\t column = 0;\n\t token = undefined;\n\t key = undefined;\n\t root = undefined;\n\n\t do {\n\t token = lex();\n\n\t // This code is unreachable.\n\t // if (!parseStates[parseState]) {\n\t // throw invalidParseState()\n\t // }\n\n\t parseStates[parseState]();\n\t } while (token.type !== 'eof')\n\n\t if (typeof reviver === 'function') {\n\t return internalize({'': root}, '', reviver)\n\t }\n\n\t return root\n\t};\n\n\tfunction internalize (holder, name, reviver) {\n\t var value = holder[name];\n\t if (value != null && typeof value === 'object') {\n\t if (Array.isArray(value)) {\n\t for (var i = 0; i < value.length; i++) {\n\t var key = String(i);\n\t var replacement = internalize(value, key, reviver);\n\t if (replacement === undefined) {\n\t delete value[key];\n\t } else {\n\t Object.defineProperty(value, key, {\n\t value: replacement,\n\t writable: true,\n\t enumerable: true,\n\t configurable: true,\n\t });\n\t }\n\t }\n\t } else {\n\t for (var key$1 in value) {\n\t var replacement$1 = internalize(value, key$1, reviver);\n\t if (replacement$1 === undefined) {\n\t delete value[key$1];\n\t } else {\n\t Object.defineProperty(value, key$1, {\n\t value: replacement$1,\n\t writable: true,\n\t enumerable: true,\n\t configurable: true,\n\t });\n\t }\n\t }\n\t }\n\t }\n\n\t return reviver.call(holder, name, value)\n\t}\n\n\tvar lexState;\n\tvar buffer;\n\tvar doubleQuote;\n\tvar sign;\n\tvar c;\n\n\tfunction lex () {\n\t lexState = 'default';\n\t buffer = '';\n\t doubleQuote = false;\n\t sign = 1;\n\n\t for (;;) {\n\t c = peek();\n\n\t // This code is unreachable.\n\t // if (!lexStates[lexState]) {\n\t // throw invalidLexState(lexState)\n\t // }\n\n\t var token = lexStates[lexState]();\n\t if (token) {\n\t return token\n\t }\n\t }\n\t}\n\n\tfunction peek () {\n\t if (source[pos]) {\n\t return String.fromCodePoint(source.codePointAt(pos))\n\t }\n\t}\n\n\tfunction read () {\n\t var c = peek();\n\n\t if (c === '\\n') {\n\t line++;\n\t column = 0;\n\t } else if (c) {\n\t column += c.length;\n\t } else {\n\t column++;\n\t }\n\n\t if (c) {\n\t pos += c.length;\n\t }\n\n\t return c\n\t}\n\n\tvar lexStates = {\n\t default: function default$1 () {\n\t switch (c) {\n\t case '\\t':\n\t case '\\v':\n\t case '\\f':\n\t case ' ':\n\t case '\\u00A0':\n\t case '\\uFEFF':\n\t case '\\n':\n\t case '\\r':\n\t case '\\u2028':\n\t case '\\u2029':\n\t read();\n\t return\n\n\t case '/':\n\t read();\n\t lexState = 'comment';\n\t return\n\n\t case undefined:\n\t read();\n\t return newToken('eof')\n\t }\n\n\t if (util.isSpaceSeparator(c)) {\n\t read();\n\t return\n\t }\n\n\t // This code is unreachable.\n\t // if (!lexStates[parseState]) {\n\t // throw invalidLexState(parseState)\n\t // }\n\n\t return lexStates[parseState]()\n\t },\n\n\t comment: function comment () {\n\t switch (c) {\n\t case '*':\n\t read();\n\t lexState = 'multiLineComment';\n\t return\n\n\t case '/':\n\t read();\n\t lexState = 'singleLineComment';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t multiLineComment: function multiLineComment () {\n\t switch (c) {\n\t case '*':\n\t read();\n\t lexState = 'multiLineCommentAsterisk';\n\t return\n\n\t case undefined:\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t },\n\n\t multiLineCommentAsterisk: function multiLineCommentAsterisk () {\n\t switch (c) {\n\t case '*':\n\t read();\n\t return\n\n\t case '/':\n\t read();\n\t lexState = 'default';\n\t return\n\n\t case undefined:\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t lexState = 'multiLineComment';\n\t },\n\n\t singleLineComment: function singleLineComment () {\n\t switch (c) {\n\t case '\\n':\n\t case '\\r':\n\t case '\\u2028':\n\t case '\\u2029':\n\t read();\n\t lexState = 'default';\n\t return\n\n\t case undefined:\n\t read();\n\t return newToken('eof')\n\t }\n\n\t read();\n\t },\n\n\t value: function value () {\n\t switch (c) {\n\t case '{':\n\t case '[':\n\t return newToken('punctuator', read())\n\n\t case 'n':\n\t read();\n\t literal('ull');\n\t return newToken('null', null)\n\n\t case 't':\n\t read();\n\t literal('rue');\n\t return newToken('boolean', true)\n\n\t case 'f':\n\t read();\n\t literal('alse');\n\t return newToken('boolean', false)\n\n\t case '-':\n\t case '+':\n\t if (read() === '-') {\n\t sign = -1;\n\t }\n\n\t lexState = 'sign';\n\t return\n\n\t case '.':\n\t buffer = read();\n\t lexState = 'decimalPointLeading';\n\t return\n\n\t case '0':\n\t buffer = read();\n\t lexState = 'zero';\n\t return\n\n\t case '1':\n\t case '2':\n\t case '3':\n\t case '4':\n\t case '5':\n\t case '6':\n\t case '7':\n\t case '8':\n\t case '9':\n\t buffer = read();\n\t lexState = 'decimalInteger';\n\t return\n\n\t case 'I':\n\t read();\n\t literal('nfinity');\n\t return newToken('numeric', Infinity)\n\n\t case 'N':\n\t read();\n\t literal('aN');\n\t return newToken('numeric', NaN)\n\n\t case '\"':\n\t case \"'\":\n\t doubleQuote = (read() === '\"');\n\t buffer = '';\n\t lexState = 'string';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t identifierNameStartEscape: function identifierNameStartEscape () {\n\t if (c !== 'u') {\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t var u = unicodeEscape();\n\t switch (u) {\n\t case '$':\n\t case '_':\n\t break\n\n\t default:\n\t if (!util.isIdStartChar(u)) {\n\t throw invalidIdentifier()\n\t }\n\n\t break\n\t }\n\n\t buffer += u;\n\t lexState = 'identifierName';\n\t },\n\n\t identifierName: function identifierName () {\n\t switch (c) {\n\t case '$':\n\t case '_':\n\t case '\\u200C':\n\t case '\\u200D':\n\t buffer += read();\n\t return\n\n\t case '\\\\':\n\t read();\n\t lexState = 'identifierNameEscape';\n\t return\n\t }\n\n\t if (util.isIdContinueChar(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('identifier', buffer)\n\t },\n\n\t identifierNameEscape: function identifierNameEscape () {\n\t if (c !== 'u') {\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t var u = unicodeEscape();\n\t switch (u) {\n\t case '$':\n\t case '_':\n\t case '\\u200C':\n\t case '\\u200D':\n\t break\n\n\t default:\n\t if (!util.isIdContinueChar(u)) {\n\t throw invalidIdentifier()\n\t }\n\n\t break\n\t }\n\n\t buffer += u;\n\t lexState = 'identifierName';\n\t },\n\n\t sign: function sign$1 () {\n\t switch (c) {\n\t case '.':\n\t buffer = read();\n\t lexState = 'decimalPointLeading';\n\t return\n\n\t case '0':\n\t buffer = read();\n\t lexState = 'zero';\n\t return\n\n\t case '1':\n\t case '2':\n\t case '3':\n\t case '4':\n\t case '5':\n\t case '6':\n\t case '7':\n\t case '8':\n\t case '9':\n\t buffer = read();\n\t lexState = 'decimalInteger';\n\t return\n\n\t case 'I':\n\t read();\n\t literal('nfinity');\n\t return newToken('numeric', sign * Infinity)\n\n\t case 'N':\n\t read();\n\t literal('aN');\n\t return newToken('numeric', NaN)\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t zero: function zero () {\n\t switch (c) {\n\t case '.':\n\t buffer += read();\n\t lexState = 'decimalPoint';\n\t return\n\n\t case 'e':\n\t case 'E':\n\t buffer += read();\n\t lexState = 'decimalExponent';\n\t return\n\n\t case 'x':\n\t case 'X':\n\t buffer += read();\n\t lexState = 'hexadecimal';\n\t return\n\t }\n\n\t return newToken('numeric', sign * 0)\n\t },\n\n\t decimalInteger: function decimalInteger () {\n\t switch (c) {\n\t case '.':\n\t buffer += read();\n\t lexState = 'decimalPoint';\n\t return\n\n\t case 'e':\n\t case 'E':\n\t buffer += read();\n\t lexState = 'decimalExponent';\n\t return\n\t }\n\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t decimalPointLeading: function decimalPointLeading () {\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t lexState = 'decimalFraction';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t decimalPoint: function decimalPoint () {\n\t switch (c) {\n\t case 'e':\n\t case 'E':\n\t buffer += read();\n\t lexState = 'decimalExponent';\n\t return\n\t }\n\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t lexState = 'decimalFraction';\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t decimalFraction: function decimalFraction () {\n\t switch (c) {\n\t case 'e':\n\t case 'E':\n\t buffer += read();\n\t lexState = 'decimalExponent';\n\t return\n\t }\n\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t decimalExponent: function decimalExponent () {\n\t switch (c) {\n\t case '+':\n\t case '-':\n\t buffer += read();\n\t lexState = 'decimalExponentSign';\n\t return\n\t }\n\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t lexState = 'decimalExponentInteger';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t decimalExponentSign: function decimalExponentSign () {\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t lexState = 'decimalExponentInteger';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t decimalExponentInteger: function decimalExponentInteger () {\n\t if (util.isDigit(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t hexadecimal: function hexadecimal () {\n\t if (util.isHexDigit(c)) {\n\t buffer += read();\n\t lexState = 'hexadecimalInteger';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t hexadecimalInteger: function hexadecimalInteger () {\n\t if (util.isHexDigit(c)) {\n\t buffer += read();\n\t return\n\t }\n\n\t return newToken('numeric', sign * Number(buffer))\n\t },\n\n\t string: function string () {\n\t switch (c) {\n\t case '\\\\':\n\t read();\n\t buffer += escape();\n\t return\n\n\t case '\"':\n\t if (doubleQuote) {\n\t read();\n\t return newToken('string', buffer)\n\t }\n\n\t buffer += read();\n\t return\n\n\t case \"'\":\n\t if (!doubleQuote) {\n\t read();\n\t return newToken('string', buffer)\n\t }\n\n\t buffer += read();\n\t return\n\n\t case '\\n':\n\t case '\\r':\n\t throw invalidChar(read())\n\n\t case '\\u2028':\n\t case '\\u2029':\n\t separatorChar(c);\n\t break\n\n\t case undefined:\n\t throw invalidChar(read())\n\t }\n\n\t buffer += read();\n\t },\n\n\t start: function start () {\n\t switch (c) {\n\t case '{':\n\t case '[':\n\t return newToken('punctuator', read())\n\n\t // This code is unreachable since the default lexState handles eof.\n\t // case undefined:\n\t // return newToken('eof')\n\t }\n\n\t lexState = 'value';\n\t },\n\n\t beforePropertyName: function beforePropertyName () {\n\t switch (c) {\n\t case '$':\n\t case '_':\n\t buffer = read();\n\t lexState = 'identifierName';\n\t return\n\n\t case '\\\\':\n\t read();\n\t lexState = 'identifierNameStartEscape';\n\t return\n\n\t case '}':\n\t return newToken('punctuator', read())\n\n\t case '\"':\n\t case \"'\":\n\t doubleQuote = (read() === '\"');\n\t lexState = 'string';\n\t return\n\t }\n\n\t if (util.isIdStartChar(c)) {\n\t buffer += read();\n\t lexState = 'identifierName';\n\t return\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t afterPropertyName: function afterPropertyName () {\n\t if (c === ':') {\n\t return newToken('punctuator', read())\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t beforePropertyValue: function beforePropertyValue () {\n\t lexState = 'value';\n\t },\n\n\t afterPropertyValue: function afterPropertyValue () {\n\t switch (c) {\n\t case ',':\n\t case '}':\n\t return newToken('punctuator', read())\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t beforeArrayValue: function beforeArrayValue () {\n\t if (c === ']') {\n\t return newToken('punctuator', read())\n\t }\n\n\t lexState = 'value';\n\t },\n\n\t afterArrayValue: function afterArrayValue () {\n\t switch (c) {\n\t case ',':\n\t case ']':\n\t return newToken('punctuator', read())\n\t }\n\n\t throw invalidChar(read())\n\t },\n\n\t end: function end () {\n\t // This code is unreachable since it's handled by the default lexState.\n\t // if (c === undefined) {\n\t // read()\n\t // return newToken('eof')\n\t // }\n\n\t throw invalidChar(read())\n\t },\n\t};\n\n\tfunction newToken (type, value) {\n\t return {\n\t type: type,\n\t value: value,\n\t line: line,\n\t column: column,\n\t }\n\t}\n\n\tfunction literal (s) {\n\t for (var i = 0, list = s; i < list.length; i += 1) {\n\t var c = list[i];\n\n\t var p = peek();\n\n\t if (p !== c) {\n\t throw invalidChar(read())\n\t }\n\n\t read();\n\t }\n\t}\n\n\tfunction escape () {\n\t var c = peek();\n\t switch (c) {\n\t case 'b':\n\t read();\n\t return '\\b'\n\n\t case 'f':\n\t read();\n\t return '\\f'\n\n\t case 'n':\n\t read();\n\t return '\\n'\n\n\t case 'r':\n\t read();\n\t return '\\r'\n\n\t case 't':\n\t read();\n\t return '\\t'\n\n\t case 'v':\n\t read();\n\t return '\\v'\n\n\t case '0':\n\t read();\n\t if (util.isDigit(peek())) {\n\t throw invalidChar(read())\n\t }\n\n\t return '\\0'\n\n\t case 'x':\n\t read();\n\t return hexEscape()\n\n\t case 'u':\n\t read();\n\t return unicodeEscape()\n\n\t case '\\n':\n\t case '\\u2028':\n\t case '\\u2029':\n\t read();\n\t return ''\n\n\t case '\\r':\n\t read();\n\t if (peek() === '\\n') {\n\t read();\n\t }\n\n\t return ''\n\n\t case '1':\n\t case '2':\n\t case '3':\n\t case '4':\n\t case '5':\n\t case '6':\n\t case '7':\n\t case '8':\n\t case '9':\n\t throw invalidChar(read())\n\n\t case undefined:\n\t throw invalidChar(read())\n\t }\n\n\t return read()\n\t}\n\n\tfunction hexEscape () {\n\t var buffer = '';\n\t var c = peek();\n\n\t if (!util.isHexDigit(c)) {\n\t throw invalidChar(read())\n\t }\n\n\t buffer += read();\n\n\t c = peek();\n\t if (!util.isHexDigit(c)) {\n\t throw invalidChar(read())\n\t }\n\n\t buffer += read();\n\n\t return String.fromCodePoint(parseInt(buffer, 16))\n\t}\n\n\tfunction unicodeEscape () {\n\t var buffer = '';\n\t var count = 4;\n\n\t while (count-- > 0) {\n\t var c = peek();\n\t if (!util.isHexDigit(c)) {\n\t throw invalidChar(read())\n\t }\n\n\t buffer += read();\n\t }\n\n\t return String.fromCodePoint(parseInt(buffer, 16))\n\t}\n\n\tvar parseStates = {\n\t start: function start () {\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t push();\n\t },\n\n\t beforePropertyName: function beforePropertyName () {\n\t switch (token.type) {\n\t case 'identifier':\n\t case 'string':\n\t key = token.value;\n\t parseState = 'afterPropertyName';\n\t return\n\n\t case 'punctuator':\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.value !== '}') {\n\t // throw invalidToken()\n\t // }\n\n\t pop();\n\t return\n\n\t case 'eof':\n\t throw invalidEOF()\n\t }\n\n\t // This code is unreachable since it's handled by the lexState.\n\t // throw invalidToken()\n\t },\n\n\t afterPropertyName: function afterPropertyName () {\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.type !== 'punctuator' || token.value !== ':') {\n\t // throw invalidToken()\n\t // }\n\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t parseState = 'beforePropertyValue';\n\t },\n\n\t beforePropertyValue: function beforePropertyValue () {\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t push();\n\t },\n\n\t beforeArrayValue: function beforeArrayValue () {\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t if (token.type === 'punctuator' && token.value === ']') {\n\t pop();\n\t return\n\t }\n\n\t push();\n\t },\n\n\t afterPropertyValue: function afterPropertyValue () {\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.type !== 'punctuator') {\n\t // throw invalidToken()\n\t // }\n\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t switch (token.value) {\n\t case ',':\n\t parseState = 'beforePropertyName';\n\t return\n\n\t case '}':\n\t pop();\n\t }\n\n\t // This code is unreachable since it's handled by the lexState.\n\t // throw invalidToken()\n\t },\n\n\t afterArrayValue: function afterArrayValue () {\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.type !== 'punctuator') {\n\t // throw invalidToken()\n\t // }\n\n\t if (token.type === 'eof') {\n\t throw invalidEOF()\n\t }\n\n\t switch (token.value) {\n\t case ',':\n\t parseState = 'beforeArrayValue';\n\t return\n\n\t case ']':\n\t pop();\n\t }\n\n\t // This code is unreachable since it's handled by the lexState.\n\t // throw invalidToken()\n\t },\n\n\t end: function end () {\n\t // This code is unreachable since it's handled by the lexState.\n\t // if (token.type !== 'eof') {\n\t // throw invalidToken()\n\t // }\n\t },\n\t};\n\n\tfunction push () {\n\t var value;\n\n\t switch (token.type) {\n\t case 'punctuator':\n\t switch (token.value) {\n\t case '{':\n\t value = {};\n\t break\n\n\t case '[':\n\t value = [];\n\t break\n\t }\n\n\t break\n\n\t case 'null':\n\t case 'boolean':\n\t case 'numeric':\n\t case 'string':\n\t value = token.value;\n\t break\n\n\t // This code is unreachable.\n\t // default:\n\t // throw invalidToken()\n\t }\n\n\t if (root === undefined) {\n\t root = value;\n\t } else {\n\t var parent = stack[stack.length - 1];\n\t if (Array.isArray(parent)) {\n\t parent.push(value);\n\t } else {\n\t Object.defineProperty(parent, key, {\n\t value: value,\n\t writable: true,\n\t enumerable: true,\n\t configurable: true,\n\t });\n\t }\n\t }\n\n\t if (value !== null && typeof value === 'object') {\n\t stack.push(value);\n\n\t if (Array.isArray(value)) {\n\t parseState = 'beforeArrayValue';\n\t } else {\n\t parseState = 'beforePropertyName';\n\t }\n\t } else {\n\t var current = stack[stack.length - 1];\n\t if (current == null) {\n\t parseState = 'end';\n\t } else if (Array.isArray(current)) {\n\t parseState = 'afterArrayValue';\n\t } else {\n\t parseState = 'afterPropertyValue';\n\t }\n\t }\n\t}\n\n\tfunction pop () {\n\t stack.pop();\n\n\t var current = stack[stack.length - 1];\n\t if (current == null) {\n\t parseState = 'end';\n\t } else if (Array.isArray(current)) {\n\t parseState = 'afterArrayValue';\n\t } else {\n\t parseState = 'afterPropertyValue';\n\t }\n\t}\n\n\t// This code is unreachable.\n\t// function invalidParseState () {\n\t// return new Error(`JSON5: invalid parse state '${parseState}'`)\n\t// }\n\n\t// This code is unreachable.\n\t// function invalidLexState (state) {\n\t// return new Error(`JSON5: invalid lex state '${state}'`)\n\t// }\n\n\tfunction invalidChar (c) {\n\t if (c === undefined) {\n\t return syntaxError((\"JSON5: invalid end of input at \" + line + \":\" + column))\n\t }\n\n\t return syntaxError((\"JSON5: invalid character '\" + (formatChar(c)) + \"' at \" + line + \":\" + column))\n\t}\n\n\tfunction invalidEOF () {\n\t return syntaxError((\"JSON5: invalid end of input at \" + line + \":\" + column))\n\t}\n\n\t// This code is unreachable.\n\t// function invalidToken () {\n\t// if (token.type === 'eof') {\n\t// return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)\n\t// }\n\n\t// const c = String.fromCodePoint(token.value.codePointAt(0))\n\t// return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`)\n\t// }\n\n\tfunction invalidIdentifier () {\n\t column -= 5;\n\t return syntaxError((\"JSON5: invalid identifier character at \" + line + \":\" + column))\n\t}\n\n\tfunction separatorChar (c) {\n\t console.warn((\"JSON5: '\" + (formatChar(c)) + \"' in strings is not valid ECMAScript; consider escaping\"));\n\t}\n\n\tfunction formatChar (c) {\n\t var replacements = {\n\t \"'\": \"\\\\'\",\n\t '\"': '\\\\\"',\n\t '\\\\': '\\\\\\\\',\n\t '\\b': '\\\\b',\n\t '\\f': '\\\\f',\n\t '\\n': '\\\\n',\n\t '\\r': '\\\\r',\n\t '\\t': '\\\\t',\n\t '\\v': '\\\\v',\n\t '\\0': '\\\\0',\n\t '\\u2028': '\\\\u2028',\n\t '\\u2029': '\\\\u2029',\n\t };\n\n\t if (replacements[c]) {\n\t return replacements[c]\n\t }\n\n\t if (c < ' ') {\n\t var hexString = c.charCodeAt(0).toString(16);\n\t return '\\\\x' + ('00' + hexString).substring(hexString.length)\n\t }\n\n\t return c\n\t}\n\n\tfunction syntaxError (message) {\n\t var err = new SyntaxError(message);\n\t err.lineNumber = line;\n\t err.columnNumber = column;\n\t return err\n\t}\n\n\tvar stringify = function stringify (value, replacer, space) {\n\t var stack = [];\n\t var indent = '';\n\t var propertyList;\n\t var replacerFunc;\n\t var gap = '';\n\t var quote;\n\n\t if (\n\t replacer != null &&\n\t typeof replacer === 'object' &&\n\t !Array.isArray(replacer)\n\t ) {\n\t space = replacer.space;\n\t quote = replacer.quote;\n\t replacer = replacer.replacer;\n\t }\n\n\t if (typeof replacer === 'function') {\n\t replacerFunc = replacer;\n\t } else if (Array.isArray(replacer)) {\n\t propertyList = [];\n\t for (var i = 0, list = replacer; i < list.length; i += 1) {\n\t var v = list[i];\n\n\t var item = (void 0);\n\n\t if (typeof v === 'string') {\n\t item = v;\n\t } else if (\n\t typeof v === 'number' ||\n\t v instanceof String ||\n\t v instanceof Number\n\t ) {\n\t item = String(v);\n\t }\n\n\t if (item !== undefined && propertyList.indexOf(item) < 0) {\n\t propertyList.push(item);\n\t }\n\t }\n\t }\n\n\t if (space instanceof Number) {\n\t space = Number(space);\n\t } else if (space instanceof String) {\n\t space = String(space);\n\t }\n\n\t if (typeof space === 'number') {\n\t if (space > 0) {\n\t space = Math.min(10, Math.floor(space));\n\t gap = ' '.substr(0, space);\n\t }\n\t } else if (typeof space === 'string') {\n\t gap = space.substr(0, 10);\n\t }\n\n\t return serializeProperty('', {'': value})\n\n\t function serializeProperty (key, holder) {\n\t var value = holder[key];\n\t if (value != null) {\n\t if (typeof value.toJSON5 === 'function') {\n\t value = value.toJSON5(key);\n\t } else if (typeof value.toJSON === 'function') {\n\t value = value.toJSON(key);\n\t }\n\t }\n\n\t if (replacerFunc) {\n\t value = replacerFunc.call(holder, key, value);\n\t }\n\n\t if (value instanceof Number) {\n\t value = Number(value);\n\t } else if (value instanceof String) {\n\t value = String(value);\n\t } else if (value instanceof Boolean) {\n\t value = value.valueOf();\n\t }\n\n\t switch (value) {\n\t case null: return 'null'\n\t case true: return 'true'\n\t case false: return 'false'\n\t }\n\n\t if (typeof value === 'string') {\n\t return quoteString(value, false)\n\t }\n\n\t if (typeof value === 'number') {\n\t return String(value)\n\t }\n\n\t if (typeof value === 'object') {\n\t return Array.isArray(value) ? serializeArray(value) : serializeObject(value)\n\t }\n\n\t return undefined\n\t }\n\n\t function quoteString (value) {\n\t var quotes = {\n\t \"'\": 0.1,\n\t '\"': 0.2,\n\t };\n\n\t var replacements = {\n\t \"'\": \"\\\\'\",\n\t '\"': '\\\\\"',\n\t '\\\\': '\\\\\\\\',\n\t '\\b': '\\\\b',\n\t '\\f': '\\\\f',\n\t '\\n': '\\\\n',\n\t '\\r': '\\\\r',\n\t '\\t': '\\\\t',\n\t '\\v': '\\\\v',\n\t '\\0': '\\\\0',\n\t '\\u2028': '\\\\u2028',\n\t '\\u2029': '\\\\u2029',\n\t };\n\n\t var product = '';\n\n\t for (var i = 0; i < value.length; i++) {\n\t var c = value[i];\n\t switch (c) {\n\t case \"'\":\n\t case '\"':\n\t quotes[c]++;\n\t product += c;\n\t continue\n\n\t case '\\0':\n\t if (util.isDigit(value[i + 1])) {\n\t product += '\\\\x00';\n\t continue\n\t }\n\t }\n\n\t if (replacements[c]) {\n\t product += replacements[c];\n\t continue\n\t }\n\n\t if (c < ' ') {\n\t var hexString = c.charCodeAt(0).toString(16);\n\t product += '\\\\x' + ('00' + hexString).substring(hexString.length);\n\t continue\n\t }\n\n\t product += c;\n\t }\n\n\t var quoteChar = quote || Object.keys(quotes).reduce(function (a, b) { return (quotes[a] < quotes[b]) ? a : b; });\n\n\t product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]);\n\n\t return quoteChar + product + quoteChar\n\t }\n\n\t function serializeObject (value) {\n\t if (stack.indexOf(value) >= 0) {\n\t throw TypeError('Converting circular structure to JSON5')\n\t }\n\n\t stack.push(value);\n\n\t var stepback = indent;\n\t indent = indent + gap;\n\n\t var keys = propertyList || Object.keys(value);\n\t var partial = [];\n\t for (var i = 0, list = keys; i < list.length; i += 1) {\n\t var key = list[i];\n\n\t var propertyString = serializeProperty(key, value);\n\t if (propertyString !== undefined) {\n\t var member = serializeKey(key) + ':';\n\t if (gap !== '') {\n\t member += ' ';\n\t }\n\t member += propertyString;\n\t partial.push(member);\n\t }\n\t }\n\n\t var final;\n\t if (partial.length === 0) {\n\t final = '{}';\n\t } else {\n\t var properties;\n\t if (gap === '') {\n\t properties = partial.join(',');\n\t final = '{' + properties + '}';\n\t } else {\n\t var separator = ',\\n' + indent;\n\t properties = partial.join(separator);\n\t final = '{\\n' + indent + properties + ',\\n' + stepback + '}';\n\t }\n\t }\n\n\t stack.pop();\n\t indent = stepback;\n\t return final\n\t }\n\n\t function serializeKey (key) {\n\t if (key.length === 0) {\n\t return quoteString(key, true)\n\t }\n\n\t var firstChar = String.fromCodePoint(key.codePointAt(0));\n\t if (!util.isIdStartChar(firstChar)) {\n\t return quoteString(key, true)\n\t }\n\n\t for (var i = firstChar.length; i < key.length; i++) {\n\t if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) {\n\t return quoteString(key, true)\n\t }\n\t }\n\n\t return key\n\t }\n\n\t function serializeArray (value) {\n\t if (stack.indexOf(value) >= 0) {\n\t throw TypeError('Converting circular structure to JSON5')\n\t }\n\n\t stack.push(value);\n\n\t var stepback = indent;\n\t indent = indent + gap;\n\n\t var partial = [];\n\t for (var i = 0; i < value.length; i++) {\n\t var propertyString = serializeProperty(String(i), value);\n\t partial.push((propertyString !== undefined) ? propertyString : 'null');\n\t }\n\n\t var final;\n\t if (partial.length === 0) {\n\t final = '[]';\n\t } else {\n\t if (gap === '') {\n\t var properties = partial.join(',');\n\t final = '[' + properties + ']';\n\t } else {\n\t var separator = ',\\n' + indent;\n\t var properties$1 = partial.join(separator);\n\t final = '[\\n' + indent + properties$1 + ',\\n' + stepback + ']';\n\t }\n\t }\n\n\t stack.pop();\n\t indent = stepback;\n\t return final\n\t }\n\t};\n\n\tvar JSON5 = {\n\t parse: parse,\n\t stringify: stringify,\n\t};\n\n\tvar lib = JSON5;\n\n\tvar es5 = lib;\n\n\treturn es5;\n\n})));\n","import { schemaType, type JsonSchema } from \"../../views/config-form.shared.ts\";\n\nfunction coerceNumberString(value: string, integer: boolean): number | undefined | string {\n const trimmed = value.trim();\n if (trimmed === \"\") {\n return undefined;\n }\n const parsed = Number(trimmed);\n if (!Number.isFinite(parsed)) {\n return value;\n }\n if (integer && !Number.isInteger(parsed)) {\n return value;\n }\n return parsed;\n}\n\nfunction coerceBooleanString(value: string): boolean | string {\n const trimmed = value.trim();\n if (trimmed === \"true\") {\n return true;\n }\n if (trimmed === \"false\") {\n return false;\n }\n return value;\n}\n\n/**\n * Walk a form value tree alongside its JSON Schema and coerce string values\n * to their schema-defined types (number, boolean).\n *\n * HTML `<input>` elements always produce string `.value` properties. Even\n * though the form rendering code converts values correctly for most paths,\n * some interactions (map-field repopulation, re-renders, paste, etc.) can\n * leak raw strings into the config form state. This utility acts as a\n * safety net before serialization so that `config.set` always receives\n * correctly typed JSON.\n */\nexport function coerceFormValues(value: unknown, schema: JsonSchema): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (schema.allOf && schema.allOf.length > 0) {\n let next: unknown = value;\n for (const segment of schema.allOf) {\n next = coerceFormValues(next, segment);\n }\n return next;\n }\n\n const type = schemaType(schema);\n\n // Handle anyOf/oneOf — try to match the value against a variant\n if (schema.anyOf || schema.oneOf) {\n const variants = (schema.anyOf ?? schema.oneOf ?? []).filter(\n (v) => !(v.type === \"null\" || (Array.isArray(v.type) && v.type.includes(\"null\"))),\n );\n\n if (variants.length === 1) {\n return coerceFormValues(value, variants[0]);\n }\n\n // Try number/boolean coercion for string values\n if (typeof value === \"string\") {\n for (const variant of variants) {\n const variantType = schemaType(variant);\n if (variantType === \"number\" || variantType === \"integer\") {\n const coerced = coerceNumberString(value, variantType === \"integer\");\n if (coerced === undefined || typeof coerced === \"number\") {\n return coerced;\n }\n }\n if (variantType === \"boolean\") {\n const coerced = coerceBooleanString(value);\n if (typeof coerced === \"boolean\") {\n return coerced;\n }\n }\n }\n }\n\n // For non-string values (objects, arrays), try to recurse into matching variant\n for (const variant of variants) {\n const variantType = schemaType(variant);\n if (variantType === \"object\" && typeof value === \"object\" && !Array.isArray(value)) {\n return coerceFormValues(value, variant);\n }\n if (variantType === \"array\" && Array.isArray(value)) {\n return coerceFormValues(value, variant);\n }\n }\n\n return value;\n }\n\n if (type === \"number\" || type === \"integer\") {\n if (typeof value === \"string\") {\n const coerced = coerceNumberString(value, type === \"integer\");\n if (coerced === undefined || typeof coerced === \"number\") {\n return coerced;\n }\n }\n return value;\n }\n\n if (type === \"boolean\") {\n if (typeof value === \"string\") {\n const coerced = coerceBooleanString(value);\n if (typeof coerced === \"boolean\") {\n return coerced;\n }\n }\n return value;\n }\n\n if (type === \"object\") {\n if (typeof value !== \"object\" || Array.isArray(value)) {\n return value;\n }\n const obj = value as Record<string, unknown>;\n const props = schema.properties ?? {};\n const additional =\n schema.additionalProperties && typeof schema.additionalProperties === \"object\"\n ? schema.additionalProperties\n : null;\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(obj)) {\n const propSchema = props[key] ?? additional;\n const coerced = propSchema ? coerceFormValues(val, propSchema) : val;\n // Omit undefined — \"clear field = unset\" for optional properties\n if (coerced !== undefined) {\n result[key] = coerced;\n }\n }\n return result;\n }\n\n if (type === \"array\") {\n if (!Array.isArray(value)) {\n return value;\n }\n if (Array.isArray(schema.items)) {\n // Tuple form: each index has its own schema\n const tuple = schema.items;\n return value.map((item, i) => {\n const s = i < tuple.length ? tuple[i] : undefined;\n return s ? coerceFormValues(item, s) : item;\n });\n }\n const itemsSchema = schema.items;\n if (!itemsSchema) {\n return value;\n }\n return value.map((item) => coerceFormValues(item, itemsSchema)).filter((v) => v !== undefined);\n }\n\n return value;\n}\n","export function cloneConfigObject<T>(value: T): T {\n if (typeof structuredClone === \"function\") {\n return structuredClone(value);\n }\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function serializeConfigForm(form: Record<string, unknown>): string {\n return `${JSON.stringify(form, null, 2).trimEnd()}\\n`;\n}\n\nexport function setPathValue(\n obj: Record<string, unknown> | unknown[],\n path: Array<string | number>,\n value: unknown,\n) {\n if (path.length === 0) {\n return;\n }\n let current: Record<string, unknown> | unknown[] = obj;\n for (let i = 0; i < path.length - 1; i += 1) {\n const key = path[i];\n const nextKey = path[i + 1];\n if (typeof key === \"number\") {\n if (!Array.isArray(current)) {\n return;\n }\n if (current[key] == null) {\n current[key] = typeof nextKey === \"number\" ? [] : ({} as Record<string, unknown>);\n }\n current = current[key] as Record<string, unknown> | unknown[];\n } else {\n if (typeof current !== \"object\" || current == null) {\n return;\n }\n const record = current as Record<string, unknown>;\n if (record[key] == null) {\n record[key] = typeof nextKey === \"number\" ? [] : ({} as Record<string, unknown>);\n }\n current = record[key] as Record<string, unknown> | unknown[];\n }\n }\n const lastKey = path[path.length - 1];\n if (typeof lastKey === \"number\") {\n if (Array.isArray(current)) {\n current[lastKey] = value;\n }\n return;\n }\n if (typeof current === \"object\" && current != null) {\n (current as Record<string, unknown>)[lastKey] = value;\n }\n}\n\nexport function removePathValue(\n obj: Record<string, unknown> | unknown[],\n path: Array<string | number>,\n) {\n if (path.length === 0) {\n return;\n }\n let current: Record<string, unknown> | unknown[] = obj;\n for (let i = 0; i < path.length - 1; i += 1) {\n const key = path[i];\n if (typeof key === \"number\") {\n if (!Array.isArray(current)) {\n return;\n }\n current = current[key] as Record<string, unknown> | unknown[];\n } else {\n if (typeof current !== \"object\" || current == null) {\n return;\n }\n current = (current as Record<string, unknown>)[key] as Record<string, unknown> | unknown[];\n }\n if (current == null) {\n return;\n }\n }\n const lastKey = path[path.length - 1];\n if (typeof lastKey === \"number\") {\n if (Array.isArray(current)) {\n current.splice(lastKey, 1);\n }\n return;\n }\n if (typeof current === \"object\" && current != null) {\n delete (current as Record<string, unknown>)[lastKey];\n }\n}\n","import JSON5 from \"json5\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { ConfigSchemaResponse, ConfigSnapshot, ConfigUiHints } from \"../types.ts\";\nimport type { JsonSchema } from \"../views/config-form.shared.ts\";\nimport { coerceFormValues } from \"./config/form-coerce.ts\";\nimport {\n cloneConfigObject,\n removePathValue,\n serializeConfigForm,\n setPathValue,\n} from \"./config/form-utils.ts\";\n\nexport type ConfigState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n applySessionKey: string;\n configLoading: boolean;\n configRaw: string;\n configRawOriginal: string;\n configValid: boolean | null;\n configIssues: unknown[];\n configSaving: boolean;\n configApplying: boolean;\n updateRunning: boolean;\n configSnapshot: ConfigSnapshot | null;\n configSchema: unknown;\n configSchemaVersion: string | null;\n configSchemaLoading: boolean;\n configUiHints: ConfigUiHints;\n configForm: Record<string, unknown> | null;\n configFormOriginal: Record<string, unknown> | null;\n configFormDirty: boolean;\n configFormMode: \"form\" | \"raw\";\n configSearchQuery: string;\n configActiveSection: string | null;\n configActiveSubsection: string | null;\n lastError: string | null;\n};\n\nexport async function loadConfig(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.configLoading = true;\n state.lastError = null;\n try {\n const res = await state.client.request<ConfigSnapshot>(\"config.get\", {});\n applyConfigSnapshot(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configLoading = false;\n }\n}\n\nexport async function loadConfigSchema(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.configSchemaLoading) {\n return;\n }\n state.configSchemaLoading = true;\n try {\n const res = await state.client.request<ConfigSchemaResponse>(\"config.schema\", {});\n applyConfigSchema(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configSchemaLoading = false;\n }\n}\n\nexport function applyConfigSchema(state: ConfigState, res: ConfigSchemaResponse) {\n state.configSchema = res.schema ?? null;\n state.configUiHints = res.uiHints ?? {};\n state.configSchemaVersion = res.version ?? null;\n}\n\nexport function applyConfigSnapshot(state: ConfigState, snapshot: ConfigSnapshot) {\n state.configSnapshot = snapshot;\n const rawFromSnapshot =\n typeof snapshot.raw === \"string\"\n ? snapshot.raw\n : snapshot.config && typeof snapshot.config === \"object\"\n ? serializeConfigForm(snapshot.config)\n : state.configRaw;\n if (!state.configFormDirty || state.configFormMode === \"raw\") {\n state.configRaw = rawFromSnapshot;\n } else if (state.configForm) {\n state.configRaw = serializeConfigForm(state.configForm);\n } else {\n state.configRaw = rawFromSnapshot;\n }\n state.configValid = typeof snapshot.valid === \"boolean\" ? snapshot.valid : null;\n state.configIssues = Array.isArray(snapshot.issues) ? snapshot.issues : [];\n\n if (!state.configFormDirty) {\n state.configForm = cloneConfigObject(snapshot.config ?? {});\n state.configFormOriginal = cloneConfigObject(snapshot.config ?? {});\n state.configRawOriginal = rawFromSnapshot;\n }\n}\n\nfunction asJsonSchema(value: unknown): JsonSchema | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n return value as JsonSchema;\n}\n\n/**\n * Serialize the form state for submission to `config.set` / `config.apply`.\n *\n * HTML `<input>` elements produce string `.value` properties, so numeric and\n * boolean config fields can leak into `configForm` as strings. We coerce\n * them back to their schema-defined types before JSON serialization so the\n * gateway's Zod validation always sees correctly typed values.\n */\nfunction serializeFormForSubmit(state: ConfigState): string {\n if (state.configFormMode !== \"form\" || !state.configForm) {\n return state.configRaw;\n }\n const schema = asJsonSchema(state.configSchema);\n const form = schema\n ? (coerceFormValues(state.configForm, schema) as Record<string, unknown>)\n : state.configForm;\n return serializeConfigForm(form);\n}\n\n// Local mirror of src/config/removed-keys.ts — cannot import core (includes.ts → node:fs).\nconst INCLUDE_KEY = \"$include\";\n\nfunction resolveRemovedTopLevelKeys(snapshot: { parsed?: unknown }, next: unknown): string[] {\n const parsed = snapshot.parsed;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return [];\n }\n if (!next || typeof next !== \"object\" || Array.isArray(next)) {\n return [];\n }\n const nextKeys = new Set(\n Object.entries(next as Record<string, unknown>)\n .filter(([, value]) => value !== undefined)\n .map(([key]) => key),\n );\n return Object.keys(parsed as Record<string, unknown>).filter(\n (key) => key !== INCLUDE_KEY && !nextKeys.has(key),\n );\n}\n\nfunction resolveSubmitDocument(state: ConfigState, raw: string): unknown {\n if (state.configFormMode === \"form\" && state.configForm) {\n const schema = asJsonSchema(state.configSchema);\n return schema\n ? (coerceFormValues(state.configForm, schema) as Record<string, unknown>)\n : state.configForm;\n }\n // Raw editor is JSON5 (matches gateway parseConfigJson5); strict JSON.parse misses removals.\n try {\n return JSON5.parse(raw);\n } catch {\n return null;\n }\n}\n\nfunction resolveAllowTopLevelKeyRemoval(state: ConfigState, raw: string): string[] {\n const snapshot = state.configSnapshot;\n if (!snapshot) {\n return [];\n }\n const previous =\n snapshot.parsed !== undefined && snapshot.parsed !== null ? snapshot.parsed : snapshot.config;\n return resolveRemovedTopLevelKeys({ parsed: previous }, resolveSubmitDocument(state, raw));\n}\n\ntype RestartConfirmationChallenge = {\n requiresConfirmation?: unknown;\n activeRuns?: unknown;\n};\n\nfunction isRestartConfirmationChallenge(value: unknown): value is RestartConfirmationChallenge {\n return (\n Boolean(value) &&\n typeof value === \"object\" &&\n (value as RestartConfirmationChallenge).requiresConfirmation === true\n );\n}\n\nfunction confirmRestartWithActiveRuns(activeRuns: unknown): boolean {\n const count = typeof activeRuns === \"number\" && Number.isFinite(activeRuns) ? activeRuns : 0;\n const label = count === 1 ? \"1 active run\" : `${count} active runs`;\n return window.confirm(\n `This operation needs a gateway restart, but ${label} will be interrupted. Continue?`,\n );\n}\n\nexport async function saveConfig(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.configSaving = true;\n state.lastError = null;\n try {\n const raw = serializeFormForSubmit(state);\n const baseHash = state.configSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Config hash missing; reload and retry.\";\n return;\n }\n const allowTopLevelKeyRemoval = resolveAllowTopLevelKeyRemoval(state, raw);\n await state.client.request(\"config.set\", {\n raw,\n baseHash,\n ...(allowTopLevelKeyRemoval.length > 0 ? { allowTopLevelKeyRemoval } : {}),\n });\n state.configFormDirty = false;\n await loadConfig(state);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configSaving = false;\n }\n}\n\nexport async function applyConfig(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.configApplying = true;\n state.lastError = null;\n try {\n const raw = serializeFormForSubmit(state);\n const baseHash = state.configSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Config hash missing; reload and retry.\";\n return;\n }\n const allowTopLevelKeyRemoval = resolveAllowTopLevelKeyRemoval(state, raw);\n const request = {\n raw,\n baseHash,\n sessionKey: state.applySessionKey,\n ...(allowTopLevelKeyRemoval.length > 0 ? { allowTopLevelKeyRemoval } : {}),\n };\n const result = await state.client.request(\"config.apply\", request);\n if (isRestartConfirmationChallenge(result)) {\n if (!confirmRestartWithActiveRuns(result.activeRuns)) {\n return;\n }\n await state.client.request(\"config.apply\", { ...request, confirmed: \"drain\" });\n }\n state.configFormDirty = false;\n await loadConfig(state);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.configApplying = false;\n }\n}\n\nexport async function runUpdate(state: ConfigState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.updateRunning = true;\n state.lastError = null;\n try {\n const request = {\n sessionKey: state.applySessionKey,\n };\n const result = await state.client.request(\"update.run\", request);\n if (isRestartConfirmationChallenge(result)) {\n if (!confirmRestartWithActiveRuns(result.activeRuns)) {\n return;\n }\n await state.client.request(\"update.run\", { ...request, confirmed: \"drain\" });\n }\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.updateRunning = false;\n }\n}\n\nexport function updateConfigFormValue(\n state: ConfigState,\n path: Array<string | number>,\n value: unknown,\n) {\n const base = cloneConfigObject(state.configForm ?? state.configSnapshot?.config ?? {});\n setPathValue(base, path, value);\n state.configForm = base;\n state.configFormDirty = true;\n if (state.configFormMode === \"form\") {\n state.configRaw = serializeConfigForm(base);\n }\n}\n\nexport function removeConfigFormValue(state: ConfigState, path: Array<string | number>) {\n const base = cloneConfigObject(state.configForm ?? state.configSnapshot?.config ?? {});\n removePathValue(base, path);\n state.configForm = base;\n state.configFormDirty = true;\n if (state.configFormMode === \"form\") {\n state.configRaw = serializeConfigForm(base);\n }\n}\n","import type { OpenClawApp } from \"./app.ts\";\nimport {\n loadChannels,\n logoutWhatsApp,\n startWhatsAppLogin,\n waitWhatsAppLogin,\n} from \"./controllers/channels.ts\";\nimport { loadConfig, saveConfig } from \"./controllers/config.ts\";\nimport type { NostrProfile } from \"./types.ts\";\nimport { createNostrProfileFormState } from \"./views/channels.nostr-profile-form.ts\";\n\nexport async function handleWhatsAppStart(host: OpenClawApp, force: boolean) {\n await startWhatsAppLogin(host, force);\n await loadChannels(host, true);\n}\n\nexport async function handleWhatsAppWait(host: OpenClawApp) {\n await waitWhatsAppLogin(host);\n await loadChannels(host, true);\n}\n\nexport async function handleWhatsAppLogout(host: OpenClawApp) {\n await logoutWhatsApp(host);\n await loadChannels(host, true);\n}\n\nexport async function handleChannelConfigSave(host: OpenClawApp) {\n await saveConfig(host);\n await loadConfig(host);\n await loadChannels(host, true);\n}\n\nexport async function handleChannelConfigReload(host: OpenClawApp) {\n await loadConfig(host);\n await loadChannels(host, true);\n}\n\nfunction parseValidationErrors(details: unknown): Record<string, string> {\n if (!Array.isArray(details)) {\n return {};\n }\n const errors: Record<string, string> = {};\n for (const entry of details) {\n if (typeof entry !== \"string\") {\n continue;\n }\n const [rawField, ...rest] = entry.split(\":\");\n if (!rawField || rest.length === 0) {\n continue;\n }\n const field = rawField.trim();\n const message = rest.join(\":\").trim();\n if (field && message) {\n errors[field] = message;\n }\n }\n return errors;\n}\n\nfunction resolveNostrAccountId(host: OpenClawApp): string {\n const accounts = host.channelsSnapshot?.channelAccounts?.nostr ?? [];\n return accounts[0]?.accountId ?? host.nostrProfileAccountId ?? \"default\";\n}\n\nfunction buildNostrProfileUrl(accountId: string, suffix = \"\"): string {\n return `/api/channels/nostr/${encodeURIComponent(accountId)}/profile${suffix}`;\n}\n\nfunction resolveGatewayHttpAuthHeader(host: OpenClawApp): string | null {\n const deviceToken = host.hello?.auth?.deviceToken?.trim();\n if (deviceToken) {\n return `Bearer ${deviceToken}`;\n }\n const token = host.settings.token.trim();\n if (token) {\n return `Bearer ${token}`;\n }\n const password = host.password.trim();\n if (password) {\n return `Bearer ${password}`;\n }\n return null;\n}\n\nfunction buildGatewayHttpHeaders(host: OpenClawApp): Record<string, string> {\n const authorization = resolveGatewayHttpAuthHeader(host);\n return authorization ? { Authorization: authorization } : {};\n}\n\nexport function handleNostrProfileEdit(\n host: OpenClawApp,\n accountId: string,\n profile: NostrProfile | null,\n) {\n host.nostrProfileAccountId = accountId;\n host.nostrProfileFormState = createNostrProfileFormState(profile ?? undefined);\n}\n\nexport function handleNostrProfileCancel(host: OpenClawApp) {\n host.nostrProfileFormState = null;\n host.nostrProfileAccountId = null;\n}\n\nexport function handleNostrProfileFieldChange(\n host: OpenClawApp,\n field: keyof NostrProfile,\n value: string,\n) {\n const state = host.nostrProfileFormState;\n if (!state) {\n return;\n }\n host.nostrProfileFormState = {\n ...state,\n values: {\n ...state.values,\n [field]: value,\n },\n fieldErrors: {\n ...state.fieldErrors,\n [field]: \"\",\n },\n };\n}\n\nexport function handleNostrProfileToggleAdvanced(host: OpenClawApp) {\n const state = host.nostrProfileFormState;\n if (!state) {\n return;\n }\n host.nostrProfileFormState = {\n ...state,\n showAdvanced: !state.showAdvanced,\n };\n}\n\nexport async function handleNostrProfileSave(host: OpenClawApp) {\n const state = host.nostrProfileFormState;\n if (!state || state.saving) {\n return;\n }\n const accountId = resolveNostrAccountId(host);\n\n host.nostrProfileFormState = {\n ...state,\n saving: true,\n error: null,\n success: null,\n fieldErrors: {},\n };\n\n try {\n const response = await fetch(buildNostrProfileUrl(accountId), {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...buildGatewayHttpHeaders(host),\n },\n body: JSON.stringify(state.values),\n });\n const data = (await response.json().catch(() => null)) as {\n ok?: boolean;\n error?: string;\n details?: unknown;\n persisted?: boolean;\n } | null;\n\n if (!response.ok || data?.ok === false || !data) {\n const errorMessage = data?.error ?? `Profile update failed (${response.status})`;\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: errorMessage,\n success: null,\n fieldErrors: parseValidationErrors(data?.details),\n };\n return;\n }\n\n if (!data.persisted) {\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: \"Profile publish failed on all relays.\",\n success: null,\n };\n return;\n }\n\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: null,\n success: \"Profile published to relays.\",\n fieldErrors: {},\n original: { ...state.values },\n };\n await loadChannels(host, true);\n } catch (err) {\n host.nostrProfileFormState = {\n ...state,\n saving: false,\n error: `Profile update failed: ${String(err)}`,\n success: null,\n };\n }\n}\n\nexport async function handleNostrProfileImport(host: OpenClawApp) {\n const state = host.nostrProfileFormState;\n if (!state || state.importing) {\n return;\n }\n const accountId = resolveNostrAccountId(host);\n\n host.nostrProfileFormState = {\n ...state,\n importing: true,\n error: null,\n success: null,\n };\n\n try {\n const response = await fetch(buildNostrProfileUrl(accountId, \"/import\"), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...buildGatewayHttpHeaders(host),\n },\n body: JSON.stringify({ autoMerge: true }),\n });\n const data = (await response.json().catch(() => null)) as {\n ok?: boolean;\n error?: string;\n imported?: NostrProfile;\n merged?: NostrProfile;\n saved?: boolean;\n } | null;\n\n if (!response.ok || data?.ok === false || !data) {\n const errorMessage = data?.error ?? `Profile import failed (${response.status})`;\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n error: errorMessage,\n success: null,\n };\n return;\n }\n\n const merged = data.merged ?? data.imported ?? null;\n const nextValues = merged ? { ...state.values, ...merged } : state.values;\n const showAdvanced = Boolean(\n nextValues.banner || nextValues.website || nextValues.nip05 || nextValues.lud16,\n );\n\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n values: nextValues,\n error: null,\n success: data.saved\n ? \"Profile imported from relays. Review and publish.\"\n : \"Profile imported. Review and publish.\",\n showAdvanced,\n };\n\n if (data.saved) {\n await loadChannels(host, true);\n }\n } catch (err) {\n host.nostrProfileFormState = {\n ...state,\n importing: false,\n error: `Profile import failed: ${String(err)}`,\n success: null,\n };\n }\n}\n","export type ParsedAgentSessionKey = {\n agentId: string;\n rest: string;\n};\n\nexport type SessionKeyChatType = \"direct\" | \"group\" | \"channel\" | \"unknown\";\n\n/**\n * Parse agent-scoped session keys in a canonical, case-insensitive way.\n * Returned values are normalized to lowercase for stable comparisons/routing.\n */\nexport function parseAgentSessionKey(\n sessionKey: string | undefined | null,\n): ParsedAgentSessionKey | null {\n const raw = (sessionKey ?? \"\").trim().toLowerCase();\n if (!raw) {\n return null;\n }\n const parts = raw.split(\":\").filter(Boolean);\n if (parts.length < 3) {\n return null;\n }\n if (parts[0] !== \"agent\") {\n return null;\n }\n const agentId = parts[1]?.trim();\n const rest = parts.slice(2).join(\":\");\n if (!agentId || !rest) {\n return null;\n }\n return { agentId, rest };\n}\n\n/**\n * Best-effort chat-type extraction from session keys across canonical and legacy formats.\n */\nexport function deriveSessionChatType(sessionKey: string | undefined | null): SessionKeyChatType {\n const raw = (sessionKey ?? \"\").trim().toLowerCase();\n if (!raw) {\n return \"unknown\";\n }\n const scoped = parseAgentSessionKey(raw)?.rest ?? raw;\n const tokens = new Set(scoped.split(\":\").filter(Boolean));\n if (tokens.has(\"group\")) {\n return \"group\";\n }\n if (tokens.has(\"channel\")) {\n return \"channel\";\n }\n if (tokens.has(\"direct\") || tokens.has(\"dm\")) {\n return \"direct\";\n }\n // Legacy Discord keys can be shaped like:\n // discord:<accountId>:guild-<guildId>:channel-<channelId>\n if (/^discord:(?:[^:]+:)?guild-[^:]+:channel-[^:]+$/.test(scoped)) {\n return \"channel\";\n }\n return \"unknown\";\n}\n\nexport function isCronRunSessionKey(sessionKey: string | undefined | null): boolean {\n const parsed = parseAgentSessionKey(sessionKey);\n if (!parsed) {\n return false;\n }\n return /^cron:[^:]+:run:[^:]+$/.test(parsed.rest);\n}\n\nexport function isCronSessionKey(sessionKey: string | undefined | null): boolean {\n const parsed = parseAgentSessionKey(sessionKey);\n if (!parsed) {\n return false;\n }\n return parsed.rest.toLowerCase().startsWith(\"cron:\");\n}\n\n/** Cron provenance of a stored session key: legacy bare `cron:<job>` or `agent:<id>:cron:<job>`. */\nexport function isCronTriggerSessionKey(sessionKey: string | undefined | null): boolean {\n return (sessionKey ?? \"\").startsWith(\"cron:\") || isCronSessionKey(sessionKey);\n}\n\nexport function isSubagentSessionKey(sessionKey: string | undefined | null): boolean {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) {\n return false;\n }\n if (raw.toLowerCase().startsWith(\"subagent:\")) {\n return true;\n }\n const parsed = parseAgentSessionKey(raw);\n return Boolean((parsed?.rest ?? \"\").toLowerCase().startsWith(\"subagent:\"));\n}\n\nexport function getSubagentDepth(sessionKey: string | undefined | null): number {\n const raw = (sessionKey ?? \"\").trim().toLowerCase();\n if (!raw) {\n return 0;\n }\n return raw.split(\":subagent:\").length - 1;\n}\n\nexport function isAcpSessionKey(sessionKey: string | undefined | null): boolean {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) {\n return false;\n }\n const normalized = raw.toLowerCase();\n if (normalized.startsWith(\"acp:\")) {\n return true;\n }\n const parsed = parseAgentSessionKey(raw);\n return Boolean((parsed?.rest ?? \"\").toLowerCase().startsWith(\"acp:\"));\n}\n\n/**\n * Control-plane segments appended to an existing session key. heartbeat-runner, background-run and\n * the gateway heartbeat probe append HEARTBEAT/BACKGROUND as the final segment; wake-gate appends\n * WAKE_GATE plus a nonce. The legacy actor backfill (ctx-identity-backfill) treats a key as\n * actorless only in those positions: HEARTBEAT/BACKGROUND last, WAKE_GATE second-to-last.\n */\nexport const HEARTBEAT_SESSION_KEY_SEGMENT = \"heartbeat\";\nexport const BACKGROUND_SESSION_KEY_SEGMENT = \"background\";\nexport const WAKE_GATE_SESSION_KEY_SEGMENT = \"wake-gate\";\n\nconst THREAD_SESSION_MARKERS = [\":thread:\", \":topic:\"];\n\nexport function resolveThreadParentSessionKey(\n sessionKey: string | undefined | null,\n): string | null {\n const raw = (sessionKey ?? \"\").trim();\n if (!raw) {\n return null;\n }\n const normalized = raw.toLowerCase();\n let idx = -1;\n for (const marker of THREAD_SESSION_MARKERS) {\n const candidate = normalized.lastIndexOf(marker);\n if (candidate > idx) {\n idx = candidate;\n }\n }\n if (idx <= 0) {\n return null;\n }\n const parent = raw.slice(0, idx).trim();\n return parent ? parent : null;\n}\n","/** Distance (px) from the bottom within which we consider the user \"near bottom\". */\nconst NEAR_BOTTOM_THRESHOLD = 450;\n\ntype ScrollHost = {\n updateComplete: Promise<unknown>;\n querySelector: (selectors: string) => Element | null;\n style: CSSStyleDeclaration;\n chatScrollFrame: number | null;\n chatScrollTimeout: number | null;\n chatHasAutoScrolled: boolean;\n chatUserNearBottom: boolean;\n chatNewMessagesBelow: boolean;\n logsScrollFrame: number | null;\n logsAtBottom: boolean;\n topbarObserver: ResizeObserver | null;\n};\n\nexport function scheduleChatScroll(host: ScrollHost, force = false, smooth = false) {\n if (host.chatScrollFrame) {\n cancelAnimationFrame(host.chatScrollFrame);\n }\n if (host.chatScrollTimeout != null) {\n clearTimeout(host.chatScrollTimeout);\n host.chatScrollTimeout = null;\n }\n const pickScrollTarget = () => {\n const container = host.querySelector(\".chat-thread\") as HTMLElement | null;\n if (container) {\n const overflowY = getComputedStyle(container).overflowY;\n const canScroll =\n overflowY === \"auto\" ||\n overflowY === \"scroll\" ||\n container.scrollHeight - container.clientHeight > 1;\n if (canScroll) {\n return container;\n }\n }\n return (document.scrollingElement ?? document.documentElement) as HTMLElement | null;\n };\n // Wait for Lit render to complete, then scroll\n void host.updateComplete.then(() => {\n host.chatScrollFrame = requestAnimationFrame(() => {\n host.chatScrollFrame = null;\n const target = pickScrollTarget();\n if (!target) {\n return;\n }\n const distanceFromBottom = target.scrollHeight - target.scrollTop - target.clientHeight;\n\n // force=true only overrides when we haven't auto-scrolled yet (initial load).\n // After initial load, respect the user's scroll position.\n const effectiveForce = force && !host.chatHasAutoScrolled;\n const shouldStick =\n effectiveForce || host.chatUserNearBottom || distanceFromBottom < NEAR_BOTTOM_THRESHOLD;\n\n if (!shouldStick) {\n // User is scrolled up — flag that new content arrived below.\n host.chatNewMessagesBelow = true;\n return;\n }\n if (effectiveForce) {\n host.chatHasAutoScrolled = true;\n }\n const smoothEnabled =\n smooth &&\n (typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\" ||\n !window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches);\n const scrollTop = target.scrollHeight;\n if (typeof target.scrollTo === \"function\") {\n target.scrollTo({ top: scrollTop, behavior: smoothEnabled ? \"smooth\" : \"auto\" });\n } else {\n target.scrollTop = scrollTop;\n }\n host.chatUserNearBottom = true;\n host.chatNewMessagesBelow = false;\n const retryDelay = effectiveForce ? 150 : 120;\n host.chatScrollTimeout = window.setTimeout(() => {\n host.chatScrollTimeout = null;\n const latest = pickScrollTarget();\n if (!latest) {\n return;\n }\n const latestDistanceFromBottom =\n latest.scrollHeight - latest.scrollTop - latest.clientHeight;\n const shouldStickRetry =\n effectiveForce ||\n host.chatUserNearBottom ||\n latestDistanceFromBottom < NEAR_BOTTOM_THRESHOLD;\n if (!shouldStickRetry) {\n return;\n }\n latest.scrollTop = latest.scrollHeight;\n host.chatUserNearBottom = true;\n }, retryDelay);\n });\n });\n}\n\nexport function scheduleLogsScroll(host: ScrollHost, force = false) {\n if (host.logsScrollFrame) {\n cancelAnimationFrame(host.logsScrollFrame);\n }\n void host.updateComplete.then(() => {\n host.logsScrollFrame = requestAnimationFrame(() => {\n host.logsScrollFrame = null;\n const container = host.querySelector(\".log-stream\") as HTMLElement | null;\n if (!container) {\n return;\n }\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n const shouldStick = force || distanceFromBottom < 80;\n if (!shouldStick) {\n return;\n }\n container.scrollTop = container.scrollHeight;\n });\n });\n}\n\nexport function handleChatScroll(host: ScrollHost, event: Event) {\n const container = event.currentTarget as HTMLElement | null;\n if (!container) {\n return;\n }\n const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;\n host.chatUserNearBottom = distanceFromBottom < NEAR_BOTTOM_THRESHOLD;\n // Clear the \"new messages below\" indicator when user scrolls back to bottom.\n if (host.chatUserNearBottom) {\n host.chatNewMessagesBelow = false;\n }\n}\n\nexport function handleLogsScroll(host: ScrollHost, event: Event) {\n const container = event.currentTarget as HTMLElement | null;\n if (!container) {\n return;\n }\n const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;\n host.logsAtBottom = distanceFromBottom < 80;\n}\n\nexport function resetChatScroll(host: ScrollHost) {\n host.chatHasAutoScrolled = false;\n host.chatUserNearBottom = true;\n host.chatNewMessagesBelow = false;\n}\n\nexport function exportLogs(lines: string[], label: string) {\n if (lines.length === 0) {\n return;\n }\n const blob = new Blob([`${lines.join(\"\\n\")}\\n`], { type: \"text/plain\" });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n const stamp = new Date().toISOString().slice(0, 19).replace(/[:T]/g, \"-\");\n anchor.href = url;\n anchor.download = `openclaw-logs-${label}-${stamp}.log`;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\nexport function observeTopbar(host: ScrollHost) {\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n const topbar = host.querySelector(\".topbar\");\n if (!topbar) {\n return;\n }\n const update = () => {\n const { height } = topbar.getBoundingClientRect();\n host.style.setProperty(\"--topbar-height\", `${height}px`);\n };\n update();\n host.topbarObserver = new ResizeObserver(() => update());\n host.topbarObserver.observe(topbar);\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { HealthSnapshot, StatusSummary } from \"../types.ts\";\n\nexport type DebugState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n debugLoading: boolean;\n debugStatus: StatusSummary | null;\n debugHealth: HealthSnapshot | null;\n debugModels: unknown[];\n debugHeartbeat: unknown;\n debugCallMethod: string;\n debugCallParams: string;\n debugCallResult: string | null;\n debugCallError: string | null;\n};\n\nexport async function loadDebug(state: DebugState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.debugLoading) {\n return;\n }\n state.debugLoading = true;\n try {\n const [status, health, models, heartbeat] = await Promise.all([\n state.client.request(\"status\", {}),\n state.client.request(\"health\", {}),\n state.client.request(\"models.list\", {}),\n state.client.request(\"last-heartbeat\", {}),\n ]);\n state.debugStatus = status as StatusSummary;\n state.debugHealth = health as HealthSnapshot;\n const modelPayload = models as { models?: unknown[] } | undefined;\n state.debugModels = Array.isArray(modelPayload?.models) ? modelPayload?.models : [];\n state.debugHeartbeat = heartbeat;\n } catch (err) {\n state.debugCallError = String(err);\n } finally {\n state.debugLoading = false;\n }\n}\n\nexport async function callDebugMethod(state: DebugState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.debugCallError = null;\n state.debugCallResult = null;\n try {\n const params = state.debugCallParams.trim()\n ? (JSON.parse(state.debugCallParams) as unknown)\n : {};\n const res = await state.client.request(state.debugCallMethod.trim(), params);\n state.debugCallResult = JSON.stringify(res, null, 2);\n } catch (err) {\n state.debugCallError = String(err);\n }\n}\n","import { normalizeDeviceMetadataForAuth } from \"./device-metadata-normalization.js\";\nexport { normalizeDeviceMetadataForAuth };\n\nexport type DeviceAuthPayloadParams = {\n deviceId: string;\n clientId: string;\n clientMode: string;\n role: string;\n scopes: string[];\n signedAtMs: number;\n token?: string | null;\n nonce: string;\n};\n\nexport type DeviceAuthPayloadV3Params = DeviceAuthPayloadParams & {\n platform?: string | null;\n deviceFamily?: string | null;\n};\n\nexport function buildDeviceAuthPayload(params: DeviceAuthPayloadParams): string {\n const scopes = params.scopes.join(\",\");\n const token = params.token ?? \"\";\n return [\n \"v2\",\n params.deviceId,\n params.clientId,\n params.clientMode,\n params.role,\n scopes,\n String(params.signedAtMs),\n token,\n params.nonce,\n ].join(\"|\");\n}\n\nexport function buildDeviceAuthPayloadV3(params: DeviceAuthPayloadV3Params): string {\n const scopes = params.scopes.join(\",\");\n const token = params.token ?? \"\";\n const platform = normalizeDeviceMetadataForAuth(params.platform);\n const deviceFamily = normalizeDeviceMetadataForAuth(params.deviceFamily);\n return [\n \"v3\",\n params.deviceId,\n params.clientId,\n params.clientMode,\n params.role,\n scopes,\n String(params.signedAtMs),\n token,\n params.nonce,\n platform,\n deviceFamily,\n ].join(\"|\");\n}\n","export const GATEWAY_CLIENT_IDS = {\n WEBCHAT_UI: \"webchat-ui\",\n CONTROL_UI: \"openclaw-control-ui\",\n WEBCHAT: \"webchat\",\n CLI: \"cli\",\n GATEWAY_CLIENT: \"gateway-client\",\n MACOS_APP: \"openclaw-macos\",\n IOS_APP: \"openclaw-ios\",\n ANDROID_APP: \"openclaw-android\",\n NODE_HOST: \"node-host\",\n EVEN_G2_NODE: \"openclaw-even-g2-node\",\n WEDNESDAYAI_GLASS_NODE: \"wednesdayai-glass-node\",\n MENTRA_NODE: \"openclaw-mentra-node\",\n USER_CLIENT: \"openclaw-user-client\",\n TEST: \"test\",\n FINGERPRINT: \"fingerprint\",\n PROBE: \"openclaw-probe\",\n} as const;\n\nexport type GatewayClientId = (typeof GATEWAY_CLIENT_IDS)[keyof typeof GATEWAY_CLIENT_IDS];\n\n// Back-compat naming (internal): these values are IDs, not display names.\nexport const GATEWAY_CLIENT_NAMES = GATEWAY_CLIENT_IDS;\nexport type GatewayClientName = GatewayClientId;\n\nexport const GATEWAY_CLIENT_MODES = {\n WEBCHAT: \"webchat\",\n CLI: \"cli\",\n UI: \"ui\",\n BACKEND: \"backend\",\n NODE: \"node\",\n PROBE: \"probe\",\n TEST: \"test\",\n} as const;\n\nexport type GatewayClientMode = (typeof GATEWAY_CLIENT_MODES)[keyof typeof GATEWAY_CLIENT_MODES];\n\nexport type GatewayClientInfo = {\n id: GatewayClientId;\n displayName?: string;\n version: string;\n platform: string;\n deviceFamily?: string;\n modelIdentifier?: string;\n mode: GatewayClientMode;\n instanceId?: string;\n};\n\nexport const GATEWAY_CLIENT_CAPS = {\n TOOL_EVENTS: \"tool-events\",\n UI_SURFACES: \"ui-surfaces\",\n} as const;\n\nexport type GatewayClientCap = (typeof GATEWAY_CLIENT_CAPS)[keyof typeof GATEWAY_CLIENT_CAPS];\n\nconst GATEWAY_CLIENT_ID_SET = new Set<GatewayClientId>(Object.values(GATEWAY_CLIENT_IDS));\nconst GATEWAY_CLIENT_MODE_SET = new Set<GatewayClientMode>(Object.values(GATEWAY_CLIENT_MODES));\n\nexport function normalizeGatewayClientId(raw?: string | null): GatewayClientId | undefined {\n const normalized = raw?.trim().toLowerCase();\n if (!normalized) {\n return undefined;\n }\n return GATEWAY_CLIENT_ID_SET.has(normalized as GatewayClientId)\n ? (normalized as GatewayClientId)\n : undefined;\n}\n\nexport function normalizeGatewayClientName(raw?: string | null): GatewayClientName | undefined {\n return normalizeGatewayClientId(raw);\n}\n\nexport function normalizeGatewayClientMode(raw?: string | null): GatewayClientMode | undefined {\n const normalized = raw?.trim().toLowerCase();\n if (!normalized) {\n return undefined;\n }\n return GATEWAY_CLIENT_MODE_SET.has(normalized as GatewayClientMode)\n ? (normalized as GatewayClientMode)\n : undefined;\n}\n\nexport function hasGatewayClientCap(\n caps: string[] | null | undefined,\n cap: GatewayClientCap,\n): boolean {\n if (!Array.isArray(caps)) {\n return false;\n }\n return caps.includes(cap);\n}\n","export type DeviceAuthEntry = {\n token: string;\n role: string;\n scopes: string[];\n updatedAtMs: number;\n};\n\nexport type DeviceAuthStore = {\n version: 1;\n deviceId: string;\n tokens: Record<string, DeviceAuthEntry>;\n};\n\nexport function normalizeDeviceAuthRole(role: string): string {\n return role.trim();\n}\n\nexport function normalizeDeviceAuthScopes(scopes: string[] | undefined): string[] {\n if (!Array.isArray(scopes)) {\n return [];\n }\n const out = new Set<string>();\n for (const scope of scopes) {\n const trimmed = scope.trim();\n if (trimmed) {\n out.add(trimmed);\n }\n }\n return [...out].toSorted();\n}\n","import {\n type DeviceAuthEntry,\n type DeviceAuthStore,\n normalizeDeviceAuthRole,\n normalizeDeviceAuthScopes,\n} from \"./device-auth.js\";\nexport type { DeviceAuthEntry, DeviceAuthStore } from \"./device-auth.js\";\n\nexport type DeviceAuthStoreAdapter = {\n readStore: () => DeviceAuthStore | null;\n writeStore: (store: DeviceAuthStore) => void;\n};\n\nexport function loadDeviceAuthTokenFromStore(params: {\n adapter: DeviceAuthStoreAdapter;\n deviceId: string;\n role: string;\n}): DeviceAuthEntry | null {\n const store = params.adapter.readStore();\n if (!store || store.deviceId !== params.deviceId) {\n return null;\n }\n const role = normalizeDeviceAuthRole(params.role);\n const entry = store.tokens[role];\n if (!entry || typeof entry.token !== \"string\") {\n return null;\n }\n return entry;\n}\n\nexport function storeDeviceAuthTokenInStore(params: {\n adapter: DeviceAuthStoreAdapter;\n deviceId: string;\n role: string;\n token: string;\n scopes?: string[];\n}): DeviceAuthEntry {\n const role = normalizeDeviceAuthRole(params.role);\n const existing = params.adapter.readStore();\n const next: DeviceAuthStore = {\n version: 1,\n deviceId: params.deviceId,\n tokens:\n existing && existing.deviceId === params.deviceId && existing.tokens\n ? { ...existing.tokens }\n : {},\n };\n const entry: DeviceAuthEntry = {\n token: params.token,\n role,\n scopes: normalizeDeviceAuthScopes(params.scopes),\n updatedAtMs: Date.now(),\n };\n next.tokens[role] = entry;\n params.adapter.writeStore(next);\n return entry;\n}\n\nexport function clearDeviceAuthTokenFromStore(params: {\n adapter: DeviceAuthStoreAdapter;\n deviceId: string;\n role: string;\n}): void {\n const store = params.adapter.readStore();\n if (!store || store.deviceId !== params.deviceId) {\n return;\n }\n const role = normalizeDeviceAuthRole(params.role);\n if (!store.tokens[role]) {\n return;\n }\n const next: DeviceAuthStore = {\n version: 1,\n deviceId: store.deviceId,\n tokens: { ...store.tokens },\n };\n delete next.tokens[role];\n params.adapter.writeStore(next);\n}\n","import {\n clearDeviceAuthTokenFromStore,\n type DeviceAuthEntry,\n loadDeviceAuthTokenFromStore,\n storeDeviceAuthTokenInStore,\n} from \"../../../src/shared/device-auth-store.js\";\nimport type { DeviceAuthStore } from \"../../../src/shared/device-auth.js\";\n\nconst STORAGE_KEY = \"openclaw.device.auth.v1\";\n\nfunction readStore(): DeviceAuthStore | null {\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) {\n return null;\n }\n const parsed = JSON.parse(raw) as DeviceAuthStore;\n if (!parsed || parsed.version !== 1) {\n return null;\n }\n if (!parsed.deviceId || typeof parsed.deviceId !== \"string\") {\n return null;\n }\n if (!parsed.tokens || typeof parsed.tokens !== \"object\") {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction writeStore(store: DeviceAuthStore) {\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(store));\n } catch {\n // best-effort\n }\n}\n\nexport function loadDeviceAuthToken(params: {\n deviceId: string;\n role: string;\n}): DeviceAuthEntry | null {\n return loadDeviceAuthTokenFromStore({\n adapter: { readStore, writeStore },\n deviceId: params.deviceId,\n role: params.role,\n });\n}\n\nexport function storeDeviceAuthToken(params: {\n deviceId: string;\n role: string;\n token: string;\n scopes?: string[];\n}): DeviceAuthEntry {\n return storeDeviceAuthTokenInStore({\n adapter: { readStore, writeStore },\n deviceId: params.deviceId,\n role: params.role,\n token: params.token,\n scopes: params.scopes,\n });\n}\n\nexport function clearDeviceAuthToken(params: { deviceId: string; role: string }) {\n clearDeviceAuthTokenFromStore({\n adapter: { readStore, writeStore },\n deviceId: params.deviceId,\n role: params.role,\n });\n}\n","/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */\n/**\n * 5KB JS implementation of ed25519 EdDSA signatures.\n * Targets RFC8032, FIPS 186-5, and ZIP215 behavior.\n * @module\n * @example\n * ```js\nimport * as ed from '@noble/ed25519';\n(async () => {\n const secretKey = ed.utils.randomSecretKey();\n const message = Uint8Array.from([0xab, 0xbc, 0xcd, 0xde]);\n const pubKey = await ed.getPublicKeyAsync(secretKey); // Sync methods are also present\n const signature = await ed.signAsync(message, secretKey);\n const isValid = await ed.verifyAsync(signature, message, pubKey);\n})();\n```\n */\n/**\n * Curve params. edwards25519 uses the RFC equation `-x² + y² = 1 + dx²y²`.\n * The stored `a` literal below is `p - 1`, i.e. the field-element encoding of RFC `a = -1`.\n * * P = `2n**255n - 19n` // field over which calculations are done\n * * N = `2n**252n + 27742317777372353535851937790883648493n` // prime-order subgroup order\n * * h = 8 // cofactor\n * * a = `Fp.create(BigInt(-1))` // equation param, stored here as `p - 1`\n * * d = -121665/121666 a.k.a. `Fp.neg(121665 * Fp.inv(121666))` // equation param\n * * Gx, Gy are coordinates of Generator / base point\n *\n * Mirror noble-curves: Point.CURVE() exposes shared params, but callers must not be able to mutate\n * that shared view and desynchronize it from the arithmetic constants captured below.\n */\nconst ed25519_CURVE = Object.freeze({\n p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,\n n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,\n h: 8n,\n a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,\n d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,\n Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,\n Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n,\n});\nconst { p: P, n: N, Gx, Gy, a: _a, d: _d, h } = ed25519_CURVE;\nconst L = 32; // shared 32-byte encoded width for Ed25519 points, scalars, signatures, and keys\n// Helpers and Precomputes sections are reused between libraries\n// ## Helpers\n// ----------\n// @ts-ignore\nconst captureTrace = (...args) => {\n if ('captureStackTrace' in Error && typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(...args);\n }\n};\nconst err = (message = '') => {\n const e = new Error(message);\n captureTrace(e, err);\n throw e;\n};\nconst isBig = (n) => typeof n === 'bigint'; // is big integer\nconst isStr = (s) => typeof s === 'string'; // is string\n// Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases. The\n// fallback still requires a real ArrayBuffer view so plain JSON-deserialized `{ constructor: ... }`\n// spoofing is rejected, and `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\nconst isBytes = (a) => a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1);\n/**\n * Asserts something is Bytes, optionally enforces exact length,\n * and returns the same reference.\n */\nconst abytes = (value, length, title = '') => {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const msg = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n throw bytes ? new RangeError(msg) : new TypeError(msg);\n }\n return value;\n};\n/** create Uint8Array */\nconst u8n = (len) => new Uint8Array(len);\n// Clone helper used before in-place byte edits such as sign-bit clearing or endian reversal.\nconst u8fr = (buf) => Uint8Array.from(buf);\n// Left-pad hex to a caller-chosen width. Width enforcement/truncation policy stays with callers.\nconst padh = (n, pad) => n.toString(16).padStart(pad, '0');\n// Lowercase hex serializer.\nconst bytesToHex = (b) => Array.from(abytes(b))\n .map((e) => padh(e, 2))\n .join('');\nconst C = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 }; // ASCII characters\nconst _ch = (ch) => {\n if (ch >= C._0 && ch <= C._9)\n return ch - C._0; // '2' => 50-48\n if (ch >= C.A && ch <= C.F)\n return ch - (C.A - 10); // 'B' => 66-(65-10)\n if (ch >= C.a && ch <= C.f)\n return ch - (C.a - 10); // 'b' => 98-(97-10)\n return;\n};\n// Accepts both uppercase and lowercase hex; all parse failures intentionally collapse to `hex invalid`.\nconst hexToBytes = (hex) => {\n const e = 'hex invalid';\n if (!isStr(hex))\n return err(e);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2)\n return err(e);\n const array = u8n(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n // treat each char as ASCII\n const n1 = _ch(hex.charCodeAt(hi)); // parse first char, multiply it by 16\n const n2 = _ch(hex.charCodeAt(hi + 1)); // parse second char\n if (n1 === undefined || n2 === undefined)\n return err(e);\n array[ai] = n1 * 16 + n2; // example: 'A9' => 10*16 + 9\n }\n return array;\n};\nconst cr = () => globalThis?.crypto; // Optional WebCrypto lookup; sync code still handles absence.\n// Async-path capability helper for WebCrypto-backed APIs.\nconst subtle = () => cr()?.subtle ?? err('crypto.subtle must be defined, consider polyfill');\n// prettier-ignore\nconst concatBytes = (...arrs) => {\n // Argument order is transcript-significant for hash/signature callers, and input validation here\n // intentionally reuses `abytes(...)` without making defensive copies of the source chunks.\n let len = 0;\n for (const a of arrs)\n len += abytes(a).length;\n const r = u8n(len); // create u8a of summed length\n let pad = 0; // walk through each array,\n arrs.forEach(a => { r.set(a, pad); pad += a.length; }); // ensure they have proper type\n return r;\n};\n/** WebCrypto OS-level CSPRNG (random number generator). Absence still fails later via `cr()`. */\nconst randomBytes = (len = L) => {\n const c = cr();\n return c.getRandomValues(u8n(len));\n};\nconst big = BigInt;\n/** Inclusive-lower, exclusive-upper bigint range assertion. */\nconst assertRange = (n, min, max, msg = 'bad number: out of range') => {\n if (!isBig(n))\n throw new TypeError(msg);\n if (min <= n && n < max)\n return n;\n throw new RangeError(msg);\n};\n/** Canonical modular reduction into `[0, b)`. */\nconst M = (a, b = P) => {\n const r = a % b;\n return r >= 0n ? r : b + r;\n};\n// Low-255-bit mask used by the `2^255 - 19` fast reduction in `modP(...)`.\nconst P_MASK = (1n << 255n) - 1n;\n// Fast reduction for the special prime `2^255 - 19`. This path assumes nonnegative inputs; the\n// generic fallback would simply be `M(num, P)`.\nconst modP = (num) => {\n // return M(num, P);\n if (num < 0n)\n err('negative coordinate');\n let r = (num >> 255n) * 19n + (num & P_MASK);\n r = (r >> 255n) * 19n + (r & P_MASK);\n return r % P;\n};\n// Reduce modulo the subgroup order stored in implementation constant `N` (RFC 8032's `L`).\nconst modN = (a) => M(a, N);\n/** Modular inversion using Euclidean GCD (non-CT) instead of the RFC's `x^(p-2)` formulation.\n * This still sits on secret-dependent paths like point normalization during keygen/signing. */\n// prettier-ignore\nconst invert = (num, md) => {\n if (num === 0n || md <= 0n)\n err('no inverse n=' + num + ' mod=' + md);\n let a = M(num, md), b = md, x = 0n, y = 1n, u = 1n, v = 0n;\n while (a !== 0n) {\n const q = b / a, r = b % a;\n const m = x - u * q, n = y - v * q;\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n return b === 1n ? M(x, md) : err('no inverse'); // b is gcd at this point\n};\n// Dynamic lookup keeps sync/async hash providers configurable at runtime. Both exported slots are\n// caller-owned and may be unset; wrapper helpers use this lookup first and then enforce the digest\n// contract instead of trusting provider output.\nconst callHash = (name) => {\n // @ts-ignore\n const fn = hashes[name];\n if (typeof fn !== 'function')\n err('hashes.' + name + ' not set');\n return fn;\n};\n// Both provider slots are configurable API surface and may return arbitrary values, so callers must\n// enforce the promised 64-byte SHA-512 digest contract here instead of trusting provider output.\nconst checkDigest = (value) => abytes(value, 64, 'digest');\n/**\n * SHA-512 helper used by the synchronous API.\n * @param msg - Message bytes to hash.\n * @returns 64-byte SHA-512 digest.\n * @example\n * Hash message bytes after wiring the synchronous SHA-512 implementation.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const digest = ed.hash(new Uint8Array([1, 2, 3]));\n * ```\n */\n// Public helper validates the message boundary explicitly; the configured provider is still looked\n// up dynamically and its output is checked with `checkDigest(...)`.\nconst hash = (msg) => checkDigest(callHash('sha512')(abytes(msg, undefined, 'message')));\n// Runtime class guard: this is `instanceof Point`, so cross-realm / duplicate-bundle Point objects\n// are rejected even if they are structurally identical.\nconst apoint = (p) => (p instanceof Point ? p : err('Point expected'));\n// ## End of Helpers\n// -----------------\n// Exclusive upper bound `2^256` used by 32-byte decode/serialization range checks.\nconst B256 = 2n ** 256n;\n/**\n * Point in XYZT extended coordinates.\n * @param X - X coordinate.\n * @param Y - Y coordinate.\n * @param Z - Projective Z coordinate.\n * @param T - Cached cross-product term.\n * @example\n * Do point arithmetic with the built-in base point and encode the result as hex.\n *\n * ```ts\n * const hex = Point.BASE.double().toHex();\n * ```\n */\nclass Point {\n static BASE;\n static ZERO;\n X;\n Y;\n Z;\n T;\n // Constructor only bounds-checks and freezes XYZT coordinates; it does not prove the point is\n // on-curve or that T matches X*Y/Z.\n constructor(X, Y, Z, T) {\n const max = B256;\n this.X = assertRange(X, 0n, max);\n this.Y = assertRange(Y, 0n, max);\n this.Z = assertRange(Z, 1n, max);\n this.T = assertRange(T, 0n, max);\n Object.freeze(this);\n }\n static CURVE() {\n return ed25519_CURVE;\n }\n static fromAffine(p) {\n return new Point(p.x, p.y, 1n, modP(p.x * p.y));\n }\n /** RFC8032 5.1.3: Bytes to Point. */\n static fromBytes(hex, zip215 = false) {\n const d = _d;\n // Copy array to not mess it up.\n const normed = u8fr(abytes(hex, L));\n // adjust first LE byte = last BE byte\n const lastByte = hex[31];\n normed[31] = lastByte & ~0x80;\n const y = bytesToNumberLE(normed);\n // After clearing the sign bit, parsed `y` is always < 2^255. ZIP-215 still accepts the full\n // post-mask range here, while strict RFC8032 decoding further requires `y < p`.\n const max = zip215 ? B256 : P;\n assertRange(y, 0n, max);\n const y2 = modP(y * y); // y²\n const u = M(y2 - 1n); // u=y²-1\n const v = modP(d * y2 + 1n); // v=dy²+1\n let { isValid, value: x } = uvRatio(u, v); // (uv³)(uv⁷)^(p-5)/8; square root\n if (!isValid)\n err('bad point: y not sqrt'); // not square root: bad point\n const isXOdd = (x & 1n) === 1n; // adjust sign of x coordinate\n const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit\n // ZIP-215-compatible decoding keeps the x=0 / sign-bit=1 encoding accepted; strict RFC 8032\n // rejects it, but the vendored ZIP-215 compliance vectors include this form in A/R bytes.\n if (!zip215 && x === 0n && isLastByteOdd)\n err('bad point: x==0, isLastByteOdd'); // x=0, x_0=1\n if (isLastByteOdd !== isXOdd)\n x = M(-x);\n return new Point(x, y, 1n, modP(x * y)); // Z=1, T=xy\n }\n static fromHex(hex, zip215) {\n return Point.fromBytes(hexToBytes(hex), zip215);\n }\n get x() {\n return this.toAffine().x;\n }\n get y() {\n return this.toAffine().y;\n }\n /** Checks if the point is valid and on-curve. */\n assertValidity() {\n const a = _a;\n const d = _d;\n const p = this;\n // Intentional stricter-than-on-curve policy: reject ZERO by default because many protocols\n // require a non-zero point, and silently accepting identity points is a common caller mistake.\n if (p.is0())\n return err('bad point: ZERO'); // TODO: optimize, with vars below?\n // Equation in affine coordinates: ax² + y² = 1 + dx²y²\n // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²\n const { X, Y, Z, T } = p;\n const X2 = modP(X * X); // X²\n const Y2 = modP(Y * Y); // Y²\n const Z2 = modP(Z * Z); // Z²\n const Z4 = modP(Z2 * Z2); // Z⁴\n const aX2 = modP(X2 * a); // aX²\n const left = modP(Z2 * (aX2 + Y2)); // (aX² + Y²)Z²\n const right = M(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²\n if (left !== right)\n return err('bad point: equation left != right (1)');\n // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T\n const XY = modP(X * Y);\n const ZT = modP(Z * T);\n if (XY !== ZT)\n return err('bad point: equation left != right (2)');\n return this;\n }\n /** Equality check: compare points P&Q. */\n equals(other) {\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const { X: X2, Y: Y2, Z: Z2 } = apoint(other); // checks class equality\n const X1Z2 = modP(X1 * Z2);\n const X2Z1 = modP(X2 * Z1);\n const Y1Z2 = modP(Y1 * Z2);\n const Y2Z1 = modP(Y2 * Z1);\n return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;\n }\n is0() {\n return this.equals(I);\n }\n /** Flip point over y coordinate. */\n negate() {\n return new Point(M(-this.X), this.Y, this.Z, M(-this.T));\n }\n /** Point doubling. Complete formula. Cost: `4M + 4S + 1*a + 6add + 1*2`. */\n double() {\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const a = _a;\n // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd\n const A = modP(X1 * X1);\n const B = modP(Y1 * Y1);\n const C = modP(2n * Z1 * Z1);\n const D = modP(a * A);\n const x1y1 = M(X1 + Y1);\n const E = M(modP(x1y1 * x1y1) - A - B);\n const G = M(D + B);\n const F = M(G - C);\n const H = M(D - B);\n const X3 = modP(E * F);\n const Y3 = modP(G * H);\n const T3 = modP(E * H);\n const Z3 = modP(F * G);\n return new Point(X3, Y3, Z3, T3);\n }\n /** Point addition. Complete formula. Cost: `8M + 1*k + 8add + 1*2`. */\n add(other) {\n const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;\n const { X: X2, Y: Y2, Z: Z2, T: T2 } = apoint(other); // doesn't check if other on-curve\n const a = _a;\n const d = _d;\n // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3\n const A = modP(X1 * X2);\n const B = modP(Y1 * Y2);\n const C = modP(modP(T1 * d) * T2);\n const D = modP(Z1 * Z2);\n const E = M(modP(M(X1 + Y1) * M(X2 + Y2)) - A - B);\n const F = M(D - C);\n const G = M(D + C);\n const H = M(B - modP(a * A));\n const X3 = modP(E * F);\n const Y3 = modP(G * H);\n const T3 = modP(E * H);\n const Z3 = modP(F * G);\n return new Point(X3, Y3, Z3, T3);\n }\n subtract(other) {\n return this.add(apoint(other).negate());\n }\n /**\n * Point-by-scalar multiplication. Safe mode requires `1 <= n < CURVE.n`.\n * Unsafe mode additionally permits `n = 0` and returns the identity point for that case.\n * Uses {@link wNAF} for base point.\n * Uses fake point to mitigate side-channel leakage.\n * @param n - scalar by which point is multiplied\n * @param safe - safe mode guards against timing attacks; unsafe mode is faster\n */\n multiply(n, safe = true) {\n // Mirror noble-curves: unsafe mode still validates scalar range first, but intentionally keeps\n // `n = 0` as the one extra accepted case used by verification-style callers.\n if (!safe && n === 0n)\n return I;\n assertRange(n, 1n, N);\n if (!safe && this.is0())\n return I;\n if (n === 1n)\n return this;\n if (this.equals(G))\n return wNAF(n).p;\n // init result point & fake point\n let p = I;\n let f = G;\n for (let d = this; n > 0n; d = d.double(), n >>= 1n) {\n // if bit is present, add to point\n // if not present, add to fake, for timing safety\n if (n & 1n)\n p = p.add(d);\n else if (safe)\n f = f.add(d);\n }\n return p;\n }\n multiplyUnsafe(scalar) {\n return this.multiply(scalar, false);\n }\n /** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */\n toAffine() {\n const { X, Y, Z } = this;\n // Fast-path only for the identity point; all other inputs still go through inversion.\n if (this.equals(I))\n return { x: 0n, y: 1n };\n const iz = invert(Z, P);\n // (Z * Z^-1) must be 1, otherwise bad math\n if (modP(Z * iz) !== 1n)\n err('invalid inverse');\n // x = X*Z^-1; y = Y*Z^-1\n const x = modP(X * iz);\n const y = modP(Y * iz);\n return { x, y };\n }\n toBytes() {\n const { x, y } = this.toAffine();\n const b = numTo32bLE(y);\n // store sign in first LE byte\n b[31] |= x & 1n ? 0x80 : 0;\n return b;\n }\n toHex() {\n return bytesToHex(this.toBytes());\n }\n clearCofactor() {\n return this.multiply(big(h), false);\n }\n isSmallOrder() {\n return this.clearCofactor().is0();\n }\n isTorsionFree() {\n // Multiply by big number N. We can't `mul(N)` because of checks. Instead, we `mul(N/2)*2+1`\n let p = this.multiply(N / 2n, false).double();\n if (N % 2n)\n p = p.add(this);\n return p.is0();\n }\n}\n/** Generator / base point */\nconst G = new Point(Gx, Gy, 1n, M(Gx * Gy));\n/** Identity / zero point */\nconst I = new Point(0n, 1n, 1n, 0n);\n// Static aliases\nPoint.BASE = G;\nPoint.ZERO = I;\nconst numTo32bLE = (num) => hexToBytes(padh(assertRange(num, 0n, B256), 64)).reverse();\n// Caller-enforced width: some sites require 32-byte RFC encodings, while others intentionally feed\n// wider SHA-512 output chunks through the same little-endian parser.\nconst bytesToNumberLE = (b) => big('0x' + bytesToHex(u8fr(abytes(b)).reverse()));\nconst pow2 = (x, power) => {\n // pow2(x, 4) == x^(2^4)\n // Negative `power` values are not rejected here and currently leave `x` unchanged.\n let r = x;\n while (power-- > 0n) {\n r = modP(r * r);\n }\n return r;\n};\n// prettier-ignore\nconst pow_2_252_3 = (x) => {\n const x2 = modP(x * x); // x^2, bits 1\n const b2 = modP(x2 * x); // x^3, bits 11\n const b4 = modP(pow2(b2, 2n) * b2); // x^(2^4-1), bits 1111\n const b5 = modP(pow2(b4, 1n) * x); // x^(2^5-1), bits 11111\n const b10 = modP(pow2(b5, 5n) * b5); // x^(2^10-1)\n const b20 = modP(pow2(b10, 10n) * b10); // x^(2^20-1)\n const b40 = modP(pow2(b20, 20n) * b20); // x^(2^40-1)\n const b80 = modP(pow2(b40, 40n) * b40); // x^(2^80-1)\n const b160 = modP(pow2(b80, 80n) * b80); // x^(2^160-1)\n const b240 = modP(pow2(b160, 80n) * b80); // x^(2^240-1)\n const b250 = modP(pow2(b240, 10n) * b10); // x^(2^250-1)\n const pow_p_5_8 = modP(pow2(b250, 2n) * x); // x^((p-5)/8), used by RFC8032 point decode\n return { pow_p_5_8, b2 };\n};\nconst RM1 = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n; // 2^((p-1)/4) = sqrt(-1)\n// RFC8032 §5.1.3 square-root helper for point decompression. `value` is only meaningful when\n// `isValid` is true; callers are also expected to pass canonical field elements with non-zero `v`.\n// prettier-ignore\nconst uvRatio = (u, v) => {\n const v3 = modP(v * modP(v * v)); // v³\n const v7 = modP(modP(v3 * v3) * v); // v⁷\n const pow = pow_2_252_3(modP(u * v7)).pow_p_5_8; // (uv⁷)^(p-5)/8\n let x = modP(u * modP(v3 * pow)); // (uv³)(uv⁷)^(p-5)/8\n const vx2 = modP(v * modP(x * x)); // vx²\n const root1 = x; // First root candidate\n const root2 = modP(x * RM1); // Second root candidate; RM1 is √-1\n const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root\n const useRoot2 = vx2 === M(-u); // If vx² = -u, set x <-- x * 2^((p-1)/4)\n const noRoot = vx2 === M(-u * RM1); // There is no valid root, vx² = -u√-1\n if (useRoot1)\n x = root1;\n if (useRoot2 || noRoot)\n x = root2; // We return root2 anyway, for const-time\n if ((M(x) & 1n) === 1n)\n x = M(-x); // edIsNegative\n return { isValid: useRoot1 || useRoot2, value: x };\n};\n// Implementation `N` is the subgroup order; `L` is only the shared 32-byte encoded width constant.\n// Reduce any little-endian byte string modulo the subgroup order; the `hash` name reflects the\n// common caller shape, not an input restriction.\nconst modL_LE = (hash) => modN(bytesToNumberLE(hash)); // modulo L; but little-endian\n// Both sync and async SHA-512 slots are exported/configurable; use `callHash(...)` for both so\n// missing async overrides fail explicitly, then validate the returned digest type/length.\nconst sha512a = (...m) => Promise.resolve(callHash('sha512Async')(concatBytes(...m))).then(checkDigest);\nconst sha512s = (...m) => checkDigest(callHash('sha512')(concatBytes(...m)));\n// RFC8032 5.1.5. Split the 64-byte hashed seed into the clamped scalar half and nonce prefix.\nconst hash2extK = (hashed) => {\n // slice creates a copy, unlike subarray\n const copy = u8fr(hashed);\n const head = copy.slice(0, 32);\n head[0] &= 248; // Clamp bits: 0b1111_1000\n head[31] &= 127; // 0b0111_1111\n head[31] |= 64; // 0b0100_0000\n const prefix = copy.slice(32, 64); // secret key \"prefix\"\n // RFC words this as `[s]B`; reducing the clamped little-endian scalar modulo `N` is equivalent\n // for base-point multiplication because `G` already has subgroup order `N`.\n const scalar = modL_LE(head);\n const point = G.multiply(scalar); // public key point\n const pointBytes = point.toBytes(); // point serialized to Uint8Array\n return { head, prefix, scalar, point, pointBytes };\n};\n// RFC8032 5.1.5; getPublicKey async, sync. Hash priv key and extract point.\nconst getExtendedPublicKeyAsync = (secretKey) => sha512a(abytes(secretKey, L)).then(hash2extK);\nconst getExtendedPublicKey = (secretKey) => hash2extK(sha512s(abytes(secretKey, L)));\n/**\n * Creates a 32-byte Ed25519 public key from the RFC 8032 32-byte secret-key seed. Async.\n * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.\n * @returns 32-byte public key.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Derive the public key bytes for a newly generated signer secret.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const secretKey = ed.utils.randomSecretKey();\n * const publicKey = await ed.getPublicKeyAsync(secretKey);\n * ```\n */\nconst getPublicKeyAsync = (secretKey) => getExtendedPublicKeyAsync(secretKey).then((p) => p.pointBytes);\n/**\n * Creates a 32-byte Ed25519 public key from the RFC 8032 32-byte secret-key seed.\n * To use, set `hashes.sha512` first.\n * @param priv - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.\n * @returns 32-byte public key.\n * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Derive the public key entirely through the synchronous API.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const secretKey = ed.utils.randomSecretKey();\n * const publicKey = ed.getPublicKey(secretKey);\n * ```\n */\nconst getPublicKey = (priv) => getExtendedPublicKey(priv).pointBytes;\nconst hashFinishA = (res) => sha512a(res.hashable).then(res.finish);\nconst hashFinishS = (res) => res.finish(sha512s(res.hashable));\n// Code, shared between sync & async sign\nconst _sign = (e, rBytes, msg) => {\n const { pointBytes: P, scalar: s } = e;\n const r = modL_LE(rBytes); // r was created outside, reduce it modulo L\n // RFC 8032 5.1.6 allows r mod L = 0, and SUPERCOP ref10 accepts the resulting identity-point\n // signature.\n // We intentionally keep the safe multiply() rejection here so a miswired all-zero SHA-512 provider\n // fails loudly instead of silently producing a degenerate signature.\n const R = G.multiply(r).toBytes(); // R = [r]B\n const hashable = concatBytes(R, P, msg); // dom2(F, C) || R || A || PH(M)\n const finish = (hashed) => {\n // k = SHA512(dom2(F, C) || R || A || PH(M))\n const S = modN(r + modL_LE(hashed) * s); // S = (r + k * s) mod L; 0 <= s < l\n return abytes(concatBytes(R, numTo32bLE(S)), 64); // 64-byte sig: 32-byte encoded R point || 32-byte LE(S)\n };\n return { hashable, finish };\n};\n/**\n * Signs message using secret key. Async.\n * Follows RFC8032 5.1.6.\n * @param message - Message bytes to sign.\n * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.\n * @returns 64-byte Ed25519 signature.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Sign an arbitrary message with a fresh Ed25519 secret key.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const secretKey = ed.utils.randomSecretKey();\n * const message = new Uint8Array([1, 2, 3]);\n * const signature = await ed.signAsync(message, secretKey);\n * ```\n */\nconst signAsync = async (message, secretKey) => {\n const m = abytes(message);\n const e = await getExtendedPublicKeyAsync(secretKey);\n const rBytes = await sha512a(e.prefix, m); // r = SHA512(dom2(F, C) || prefix || PH(M))\n return hashFinishA(_sign(e, rBytes, m)); // gen R, k, S, then 64-byte signature\n};\n/**\n * Signs message using secret key. To use, set `hashes.sha512` first.\n * Follows RFC8032 5.1.6.\n * @param message - Message bytes to sign.\n * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.\n * @returns 64-byte Ed25519 signature.\n * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Use the sync API when you've wired a SHA-512 implementation yourself.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const secretKey = ed.utils.randomSecretKey();\n * const signature = ed.sign(new Uint8Array([1, 2, 3]), secretKey);\n * ```\n */\nconst sign = (message, secretKey) => {\n const m = abytes(message);\n const e = getExtendedPublicKey(secretKey);\n const rBytes = sha512s(e.prefix, m); // r = SHA512(dom2(F, C) || prefix || PH(M))\n return hashFinishS(_sign(e, rBytes, m)); // gen R, k, S, then 64-byte signature\n};\n// Exported defaults favor ZIP-215 interoperability semantics; callers must opt into the stricter\n// branch with `{ zip215: false }`.\nconst defaultVerifyOpts = { zip215: true };\nconst _verify = (sig, msg, publicKey, options = defaultVerifyOpts) => {\n sig = abytes(sig, 64); // Signature hex str/Bytes, must be 64 bytes\n msg = abytes(msg); // Message hex str/Bytes\n publicKey = abytes(publicKey, L);\n // zip215=false keeps the library's stricter branch, which still canonicalizes `R` / `A` before\n // hashing and rejects small-order public keys earlier than pure RFC8032 text would require.\n // Preserve the exported ZIP-215 default for `{}` / `{ zip215: undefined }`, not just omitted opts.\n const { zip215 = true } = options;\n const r = sig.subarray(0, L);\n const s = bytesToNumberLE(sig.subarray(L, L * 2)); // Decode second half as an integer S;\n let A, R, SB;\n let hashable = Uint8Array.of();\n let finished = false;\n try {\n // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.\n // zip215=true: 0 <= y < MASK (2^256 for ed25519)\n // zip215=false: 0 <= y < P (2^255-19 for ed25519)\n A = Point.fromBytes(publicKey, zip215);\n R = Point.fromBytes(r, zip215);\n SB = G.multiply(s, false); // 0 <= s < l is done inside\n // ZIP-215 accepts noncanonical / unreduced point encodings, so the challenge hash must use the\n // exact signature/public-key bytes rather than canonicalized re-encodings of the decoded points.\n hashable = concatBytes(r, publicKey, msg); // dom2(F, C) || R || A || PH(M)\n finished = true;\n }\n catch (error) { }\n const finish = (hashed) => {\n if (!finished)\n return false;\n // Policy: strict mode intentionally rejects all small-order public keys, even though the raw RFC\n // equation text is looser here. This matches libsodium and avoids weak / ambiguous verification\n // outcomes where unusual low-order public keys can make distinct key/signature combinations verify.\n if (!zip215 && A.isSmallOrder())\n return false;\n // k = SHA512(dom2(F, C) || R || A || PH(M))\n const k = modL_LE(hashed);\n const RkA = R.add(A.multiply(k, false));\n // Extended group equation\n // [8][S]B = [8]R + [8][k]A'\n return RkA.subtract(SB).clearCofactor().is0();\n };\n return { hashable, finish };\n};\n/**\n * Verifies a signature on message and public key. Async.\n * The implementation is based on RFC8032 5.1.7, but default opts use ZIP-215 semantics; pass\n * `{ zip215: false }` for the library's stricter branch.\n * @param signature - 64-byte signature.\n * @param message - Signed message bytes.\n * @param publicKey - 32-byte public key.\n * @param opts - Verification options. Defaults to ZIP-215 semantics. See {@link EdDSAVerifyOpts}.\n * @returns `true` when the signature is valid.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Verify the signature against the same message and derived public key.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const secretKey = ed.utils.randomSecretKey();\n * const message = new Uint8Array([1, 2, 3]);\n * const publicKey = await ed.getPublicKeyAsync(secretKey);\n * const signature = await ed.signAsync(message, secretKey);\n * const isValid = await ed.verifyAsync(signature, message, publicKey);\n * ```\n */\nconst verifyAsync = async (signature, message, publicKey, opts = defaultVerifyOpts) => hashFinishA(_verify(signature, message, publicKey, opts));\n/**\n * Verifies a signature on message and public key using the synchronous hash path.\n * The implementation is based on RFC8032 5.1.7, but default opts use ZIP-215 semantics; pass\n * `{ zip215: false }` for the library's stricter branch.\n * @param signature - 64-byte signature.\n * @param message - Signed message bytes.\n * @param publicKey - 32-byte public key.\n * @param opts - Verification options. Defaults to ZIP-215 semantics. See {@link EdDSAVerifyOpts}.\n * @returns `true` when the signature is valid.\n * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Verify a signature entirely through the synchronous API.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const secretKey = ed.utils.randomSecretKey();\n * const message = new Uint8Array([1, 2, 3]);\n * const publicKey = ed.getPublicKey(secretKey);\n * const signature = ed.sign(message, secretKey);\n * const isValid = ed.verify(signature, message, publicKey);\n * ```\n */\nconst verify = (signature, message, publicKey, opts = defaultVerifyOpts) => hashFinishS(_verify(signature, message, publicKey, opts));\n/**\n * Math, hex, byte helpers. Not in `utils` because utils share API with noble-curves.\n * Exposes the same low-level field-default `mod` reducer and non-CT `invert` helper used\n * internally.\n * @example\n * Convert bytes to a hex string with the low-level helper namespace.\n *\n * ```ts\n * const hex = etc.bytesToHex(new Uint8Array([1, 2, 3]));\n * ```\n */\nconst etc = /* @__PURE__ */ Object.freeze({\n bytesToHex,\n hexToBytes,\n concatBytes,\n mod: M,\n invert: invert,\n randomBytes,\n});\n/**\n * Hash implementations used by the synchronous API plus the default async WebCrypto provider.\n * Both slots are configurable API surface; wrapper helpers revalidate that providers still return\n * 64-byte SHA-512 digests.\n * @example\n * Provide a SHA-512 implementation before calling synchronous helpers.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const { publicKey } = ed.keygen();\n * ```\n */\nconst hashes = {\n sha512Async: async (message) => {\n const s = subtle();\n const m = concatBytes(message);\n return u8n(await s.digest('SHA-512', m.buffer));\n },\n sha512: undefined,\n};\n// Returns the final 32-byte Ed25519 secret-key seed verbatim, generating fresh random bytes only\n// when omitted.\nconst randomSecretKey = (seed) => {\n seed = seed === undefined ? randomBytes(L) : seed;\n return abytes(seed, L);\n};\n/**\n * Generates a secret/public keypair.\n * @param seed - Optional 32-byte Ed25519 secret-key seed, returned verbatim as `secretKey`.\n * @returns Keypair with `secretKey` and `publicKey`.\n * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Generate a new keypair through the synchronous API after wiring SHA-512.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n * import { sha512 } from '@noble/hashes/sha2.js';\n *\n * ed.hashes.sha512 = sha512;\n * const { secretKey, publicKey } = ed.keygen();\n * ```\n */\nconst keygen = (seed) => {\n const secretKey = randomSecretKey(seed);\n const publicKey = getPublicKey(secretKey);\n return { secretKey, publicKey };\n};\n/**\n * Generates a secret/public keypair asynchronously.\n * @param seed - Optional 32-byte Ed25519 secret-key seed, returned verbatim as `secretKey`.\n * @returns Keypair with `secretKey` and `publicKey`.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Generate a new keypair through the asynchronous WebCrypto-backed path.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const { secretKey, publicKey } = await ed.keygenAsync();\n * ```\n */\nconst keygenAsync = async (seed) => {\n const secretKey = randomSecretKey(seed);\n const publicKey = await getPublicKeyAsync(secretKey);\n return { secretKey, publicKey };\n};\n/**\n * Ed25519-specific key utilities.\n * `utils.getExtendedPublicKey*` expose secret-derived internals (`head`, `prefix`, `scalar`, and\n * point objects), not just public-key bytes.\n * @example\n * Generate a new Ed25519 secret key and derive the matching public key.\n *\n * ```ts\n * import * as ed from '@noble/ed25519';\n *\n * const secretKey = ed.utils.randomSecretKey();\n * const publicKey = await ed.getPublicKeyAsync(secretKey);\n * ```\n */\nconst utils = /* @__PURE__ */ Object.freeze({\n getExtendedPublicKeyAsync: getExtendedPublicKeyAsync,\n getExtendedPublicKey: getExtendedPublicKey,\n randomSecretKey: randomSecretKey,\n});\n// ## Precomputes\n// --------------\nconst W = 8; // W is window size\nconst scalarBits = 256;\nconst pwindows = Math.ceil(scalarBits / W) + 1; // 33 for W=8, NOT 32 - see wNAF loop\nconst pwindowSize = 2 ** (W - 1); // 128 for W=8\n// Layout is grouped by window: each block stores the positive multiples `1*base .. 128*base` for\n// that window, and the extra `+1` window in `pwindows` absorbs carries from signed-digit recoding.\nconst precompute = () => {\n const points = [];\n let p = G;\n let b = p;\n for (let w = 0; w < pwindows; w++) {\n b = p;\n points.push(b);\n for (let i = 1; i < pwindowSize; i++) {\n b = b.add(p);\n points.push(b);\n } // i=1, bc we skip 0\n p = b.double();\n }\n return points;\n};\nlet Gpows = undefined; // shared process-wide cache of base-point precomputes\n// Branch-based negate helper used for JS/JIT mitigation symmetry, not a strict constant-time claim.\nconst ctneg = (cnd, p) => {\n const n = p.negate();\n return cnd ? n : p;\n};\n/**\n * Precomputes give 12x faster getPublicKey(), 10x sign(), 2x verify() by\n * caching multiples of G (base point). Cache is stored in 32MB of RAM.\n * Any time `G.multiply` is done, precomputes are used.\n * Not used for getSharedSecret, which instead multiplies random pubkey `P.multiply`.\n *\n * w-ary non-adjacent form (wNAF) precomputation method is 10% slower than windowed method,\n * but takes 2x less RAM. RAM reduction is possible by utilizing `.subtract`.\n * Returns the real accumulator `p` plus a fake accumulator `f`; callers only care about `p`, while\n * `f` exists to keep similar work in zero-digit branches as a JS/JIT side-channel mitigation.\n *\n * !! Precomputes can be disabled by commenting-out call of the wNAF() inside Point#multiply().\n */\nconst wNAF = (n) => {\n const comp = Gpows || (Gpows = precompute());\n let p = I;\n let f = G; // f must be G, or could become I in the end\n const pow_2_w = 2 ** W; // 256 for W=8\n const maxNum = pow_2_w; // 256 for W=8\n const mask = big(pow_2_w - 1); // 255 for W=8 == mask 0b11111111\n const shiftBy = big(W); // 8 for W=8\n for (let w = 0; w < pwindows; w++) {\n let wbits = Number(n & mask); // extract W bits.\n n >>= shiftBy; // shift number by W bits.\n // We use negative indexes to reduce size of precomputed table by 2x.\n // Instead of needing precomputes 0..256, we only calculate them for 0..128.\n // If an index > 128 is found, we do (256-index) - where 256 is next window.\n // Naive: index +127 => 127, +224 => 224\n // Optimized: index +127 => 127, +224 => 256-32\n if (wbits > pwindowSize) {\n wbits -= maxNum;\n n += 1n;\n }\n const off = w * pwindowSize;\n const offF = off; // offsets, evaluate both\n const offP = off + Math.abs(wbits) - 1;\n const isEven = w % 2 !== 0; // conditions, evaluate both\n const isNeg = wbits < 0;\n if (wbits === 0) {\n // off == I: can't add it. Adding random offF instead.\n f = f.add(ctneg(isEven, comp[offF])); // bits are 0: add garbage to fake point\n }\n else {\n p = p.add(ctneg(isNeg, comp[offP])); // bits are 1: add to result point\n }\n }\n if (n !== 0n)\n err('invalid wnaf');\n return { p, f }; // callers only need `p`; `f` is kept for zero-digit mitigation symmetry\n};\n// !! Remove the export to easily use in REPL / browser console\nexport { etc, getPublicKey, getPublicKeyAsync, hash, hashes, keygen, keygenAsync, Point, sign, signAsync, utils, verify, verifyAsync };\n","import { getPublicKeyAsync, signAsync, utils } from \"@noble/ed25519\";\n\ntype StoredIdentity = {\n version: 1;\n deviceId: string;\n publicKey: string;\n privateKey: string;\n createdAtMs: number;\n};\n\nexport type DeviceIdentity = {\n deviceId: string;\n publicKey: string;\n privateKey: string;\n};\n\nconst STORAGE_KEY = \"openclaw-device-identity-v1\";\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/g, \"\");\n}\n\nfunction base64UrlDecode(input: string): Uint8Array {\n const normalized = input.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n const padded = normalized + \"=\".repeat((4 - (normalized.length % 4)) % 4);\n const binary = atob(padded);\n const out = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) {\n out[i] = binary.charCodeAt(i);\n }\n return out;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nasync function fingerprintPublicKey(publicKey: Uint8Array): Promise<string> {\n const hash = await crypto.subtle.digest(\"SHA-256\", publicKey.slice().buffer);\n return bytesToHex(new Uint8Array(hash));\n}\n\nasync function generateIdentity(): Promise<DeviceIdentity> {\n const privateKey = utils.randomSecretKey();\n const publicKey = await getPublicKeyAsync(privateKey);\n const deviceId = await fingerprintPublicKey(publicKey);\n return {\n deviceId,\n publicKey: base64UrlEncode(publicKey),\n privateKey: base64UrlEncode(privateKey),\n };\n}\n\nexport async function loadOrCreateDeviceIdentity(): Promise<DeviceIdentity> {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as StoredIdentity;\n if (\n parsed?.version === 1 &&\n typeof parsed.deviceId === \"string\" &&\n typeof parsed.publicKey === \"string\" &&\n typeof parsed.privateKey === \"string\"\n ) {\n const derivedId = await fingerprintPublicKey(base64UrlDecode(parsed.publicKey));\n if (derivedId !== parsed.deviceId) {\n const updated: StoredIdentity = {\n ...parsed,\n deviceId: derivedId,\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));\n return {\n deviceId: derivedId,\n publicKey: parsed.publicKey,\n privateKey: parsed.privateKey,\n };\n }\n return {\n deviceId: parsed.deviceId,\n publicKey: parsed.publicKey,\n privateKey: parsed.privateKey,\n };\n }\n }\n } catch {\n // fall through to regenerate\n }\n\n const identity = await generateIdentity();\n const stored: StoredIdentity = {\n version: 1,\n deviceId: identity.deviceId,\n publicKey: identity.publicKey,\n privateKey: identity.privateKey,\n createdAtMs: Date.now(),\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(stored));\n return identity;\n}\n\nexport async function signDevicePayload(privateKeyBase64Url: string, payload: string) {\n const key = base64UrlDecode(privateKeyBase64Url);\n const data = new TextEncoder().encode(payload);\n const sig = await signAsync(data, key);\n return base64UrlEncode(sig);\n}\n","export type CryptoLike = {\n randomUUID?: (() => string) | undefined;\n getRandomValues?: (<T extends Exclude<BufferSource, ArrayBuffer>>(array: T) => T) | undefined;\n};\n\nlet warnedWeakCrypto = false;\n\nfunction uuidFromBytes(bytes: Uint8Array): string {\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 1\n\n let hex = \"\";\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i].toString(16).padStart(2, \"0\");\n }\n\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(\n 16,\n 20,\n )}-${hex.slice(20)}`;\n}\n\nfunction weakRandomBytes(): Uint8Array {\n const bytes = new Uint8Array(16);\n const now = Date.now();\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n bytes[0] ^= now & 0xff;\n bytes[1] ^= (now >>> 8) & 0xff;\n bytes[2] ^= (now >>> 16) & 0xff;\n bytes[3] ^= (now >>> 24) & 0xff;\n return bytes;\n}\n\nfunction warnWeakCryptoOnce() {\n if (warnedWeakCrypto) {\n return;\n }\n warnedWeakCrypto = true;\n console.warn(\"[uuid] crypto API missing; falling back to weak randomness\");\n}\n\nexport function generateUUID(cryptoLike: CryptoLike | null = globalThis.crypto): string {\n if (cryptoLike && typeof cryptoLike.randomUUID === \"function\") {\n return cryptoLike.randomUUID();\n }\n\n if (cryptoLike && typeof cryptoLike.getRandomValues === \"function\") {\n const bytes = new Uint8Array(16);\n cryptoLike.getRandomValues(bytes);\n return uuidFromBytes(bytes);\n }\n\n warnWeakCryptoOnce();\n return uuidFromBytes(weakRandomBytes());\n}\n","import { buildDeviceAuthPayload } from \"../../../src/gateway/device-auth.js\";\nimport {\n GATEWAY_CLIENT_MODES,\n GATEWAY_CLIENT_NAMES,\n type GatewayClientMode,\n type GatewayClientName,\n} from \"../../../src/gateway/protocol/client-info.js\";\nimport { readConnectErrorDetailCode } from \"../../../src/gateway/protocol/connect-error-details.js\";\nimport { clearDeviceAuthToken, loadDeviceAuthToken, storeDeviceAuthToken } from \"./device-auth.ts\";\nimport { loadOrCreateDeviceIdentity, signDevicePayload } from \"./device-identity.ts\";\nimport { generateUUID } from \"./uuid.ts\";\n\nexport type GatewayEventFrame = {\n type: \"event\";\n event: string;\n payload?: unknown;\n seq?: number;\n stateVersion?: { presence: number; health: number };\n};\n\nexport type GatewayResponseFrame = {\n type: \"res\";\n id: string;\n ok: boolean;\n payload?: unknown;\n error?: { code: string; message: string; details?: unknown };\n};\n\nexport type GatewayErrorInfo = {\n code: string;\n message: string;\n details?: unknown;\n};\n\nexport class GatewayRequestError extends Error {\n readonly gatewayCode: string;\n readonly details?: unknown;\n\n constructor(error: GatewayErrorInfo) {\n super(error.message);\n this.name = \"GatewayRequestError\";\n this.gatewayCode = error.code;\n this.details = error.details;\n }\n}\n\nexport function resolveGatewayErrorDetailCode(\n error: { details?: unknown } | null | undefined,\n): string | null {\n return readConnectErrorDetailCode(error?.details);\n}\n\nexport type GatewayHelloOk = {\n type: \"hello-ok\";\n protocol: number;\n server?: {\n version?: string;\n connId?: string;\n };\n features?: { methods?: string[]; events?: string[] };\n snapshot?: unknown;\n auth?: {\n deviceToken?: string;\n role?: string;\n scopes?: string[];\n issuedAtMs?: number;\n };\n policy?: { tickIntervalMs?: number };\n};\n\ntype Pending = {\n resolve: (value: unknown) => void;\n reject: (err: unknown) => void;\n};\n\nexport type GatewayBrowserClientOptions = {\n url: string;\n token?: string;\n password?: string;\n clientName?: GatewayClientName;\n clientVersion?: string;\n platform?: string;\n mode?: GatewayClientMode;\n instanceId?: string;\n onHello?: (hello: GatewayHelloOk) => void;\n onEvent?: (evt: GatewayEventFrame) => void;\n onClose?: (info: { code: number; reason: string; error?: GatewayErrorInfo }) => void;\n onGap?: (info: { expected: number; received: number }) => void;\n};\n\n// 4008 = application-defined code (browser rejects 1008 \"Policy Violation\")\nconst CONNECT_FAILED_CLOSE_CODE = 4008;\n\nexport class GatewayBrowserClient {\n private ws: WebSocket | null = null;\n private pending = new Map<string, Pending>();\n private closed = false;\n private lastSeq: number | null = null;\n private connectNonce: string | null = null;\n private connectSent = false;\n private connectTimer: number | null = null;\n private backoffMs = 800;\n private pendingConnectError: GatewayErrorInfo | undefined;\n\n constructor(private opts: GatewayBrowserClientOptions) {}\n\n start() {\n this.closed = false;\n this.connect();\n }\n\n stop() {\n this.closed = true;\n this.ws?.close();\n this.ws = null;\n this.pendingConnectError = undefined;\n this.flushPending(new Error(\"gateway client stopped\"));\n }\n\n get connected() {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n private connect() {\n if (this.closed) {\n return;\n }\n this.ws = new WebSocket(this.opts.url);\n this.ws.addEventListener(\"open\", () => this.queueConnect());\n this.ws.addEventListener(\"message\", (ev) => this.handleMessage(String(ev.data ?? \"\")));\n this.ws.addEventListener(\"close\", (ev) => {\n const reason = String(ev.reason ?? \"\");\n const connectError = this.pendingConnectError;\n this.pendingConnectError = undefined;\n this.ws = null;\n this.flushPending(new Error(`gateway closed (${ev.code}): ${reason}`));\n this.opts.onClose?.({ code: ev.code, reason, error: connectError });\n this.scheduleReconnect();\n });\n this.ws.addEventListener(\"error\", () => {\n // ignored; close handler will fire\n });\n }\n\n private scheduleReconnect() {\n if (this.closed) {\n return;\n }\n const delay = this.backoffMs;\n this.backoffMs = Math.min(this.backoffMs * 1.7, 15_000);\n window.setTimeout(() => this.connect(), delay);\n }\n\n private flushPending(err: Error) {\n for (const [, p] of this.pending) {\n p.reject(err);\n }\n this.pending.clear();\n }\n\n private async sendConnect() {\n if (this.connectSent) {\n return;\n }\n this.connectSent = true;\n if (this.connectTimer !== null) {\n window.clearTimeout(this.connectTimer);\n this.connectTimer = null;\n }\n\n // crypto.subtle is only available in secure contexts (HTTPS, localhost).\n // Over plain HTTP, we skip device identity and fall back to token-only auth.\n // Gateways may reject this unless gateway.controlUi.allowInsecureAuth is enabled.\n const isSecureContext = typeof crypto !== \"undefined\" && !!crypto.subtle;\n\n const scopes = [\"operator.admin\", \"operator.approvals\", \"operator.pairing\"];\n const role = \"operator\";\n let deviceIdentity: Awaited<ReturnType<typeof loadOrCreateDeviceIdentity>> | null = null;\n let canFallbackToShared = false;\n let authToken = this.opts.token;\n\n if (isSecureContext) {\n deviceIdentity = await loadOrCreateDeviceIdentity();\n const storedToken = loadDeviceAuthToken({\n deviceId: deviceIdentity.deviceId,\n role,\n })?.token;\n authToken = storedToken ?? this.opts.token;\n canFallbackToShared = Boolean(storedToken && this.opts.token);\n }\n const auth =\n authToken || this.opts.password\n ? {\n token: authToken,\n password: this.opts.password,\n }\n : undefined;\n\n let device:\n | {\n id: string;\n publicKey: string;\n signature: string;\n signedAt: number;\n nonce: string;\n }\n | undefined;\n\n if (isSecureContext && deviceIdentity) {\n const signedAtMs = Date.now();\n const nonce = this.connectNonce ?? \"\";\n const payload = buildDeviceAuthPayload({\n deviceId: deviceIdentity.deviceId,\n clientId: this.opts.clientName ?? GATEWAY_CLIENT_NAMES.CONTROL_UI,\n clientMode: this.opts.mode ?? GATEWAY_CLIENT_MODES.WEBCHAT,\n role,\n scopes,\n signedAtMs,\n token: authToken ?? null,\n nonce,\n });\n const signature = await signDevicePayload(deviceIdentity.privateKey, payload);\n device = {\n id: deviceIdentity.deviceId,\n publicKey: deviceIdentity.publicKey,\n signature,\n signedAt: signedAtMs,\n nonce,\n };\n }\n const params = {\n minProtocol: 3,\n maxProtocol: 3,\n client: {\n id: this.opts.clientName ?? GATEWAY_CLIENT_NAMES.CONTROL_UI,\n version: this.opts.clientVersion ?? \"dev\",\n platform: this.opts.platform ?? navigator.platform ?? \"web\",\n mode: this.opts.mode ?? GATEWAY_CLIENT_MODES.WEBCHAT,\n instanceId: this.opts.instanceId,\n },\n role,\n scopes,\n device,\n caps: [],\n auth,\n userAgent: navigator.userAgent,\n locale: navigator.language,\n };\n\n void this.request<GatewayHelloOk>(\"connect\", params)\n .then((hello) => {\n if (hello?.auth?.deviceToken && deviceIdentity) {\n storeDeviceAuthToken({\n deviceId: deviceIdentity.deviceId,\n role: hello.auth.role ?? role,\n token: hello.auth.deviceToken,\n scopes: hello.auth.scopes ?? [],\n });\n }\n this.backoffMs = 800;\n this.opts.onHello?.(hello);\n })\n .catch((err: unknown) => {\n if (err instanceof GatewayRequestError) {\n this.pendingConnectError = {\n code: err.gatewayCode,\n message: err.message,\n details: err.details,\n };\n } else {\n this.pendingConnectError = undefined;\n }\n if (canFallbackToShared && deviceIdentity) {\n clearDeviceAuthToken({ deviceId: deviceIdentity.deviceId, role });\n }\n this.ws?.close(CONNECT_FAILED_CLOSE_CODE, \"connect failed\");\n });\n }\n\n private handleMessage(raw: string) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return;\n }\n\n const frame = parsed as { type?: unknown };\n if (frame.type === \"event\") {\n const evt = parsed as GatewayEventFrame;\n if (evt.event === \"connect.challenge\") {\n const payload = evt.payload as { nonce?: unknown } | undefined;\n const nonce = payload && typeof payload.nonce === \"string\" ? payload.nonce : null;\n if (nonce) {\n this.connectNonce = nonce;\n void this.sendConnect();\n }\n return;\n }\n const seq = typeof evt.seq === \"number\" ? evt.seq : null;\n if (seq !== null) {\n if (this.lastSeq !== null && seq > this.lastSeq + 1) {\n this.opts.onGap?.({ expected: this.lastSeq + 1, received: seq });\n }\n this.lastSeq = seq;\n }\n try {\n this.opts.onEvent?.(evt);\n } catch (err) {\n console.error(\"[gateway] event handler error:\", err);\n }\n return;\n }\n\n if (frame.type === \"res\") {\n const res = parsed as GatewayResponseFrame;\n const pending = this.pending.get(res.id);\n if (!pending) {\n return;\n }\n this.pending.delete(res.id);\n if (res.ok) {\n pending.resolve(res.payload);\n } else {\n pending.reject(\n new GatewayRequestError({\n code: res.error?.code ?? \"UNAVAILABLE\",\n message: res.error?.message ?? \"request failed\",\n details: res.error?.details,\n }),\n );\n }\n return;\n }\n }\n\n request<T = unknown>(method: string, params?: unknown): Promise<T> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error(\"gateway not connected\"));\n }\n const id = generateUUID();\n const frame = { type: \"req\", id, method, params };\n const p = new Promise<T>((resolve, reject) => {\n this.pending.set(id, { resolve: (v) => resolve(v as T), reject });\n });\n this.ws.send(JSON.stringify(frame));\n return p;\n }\n\n private queueConnect() {\n this.connectNonce = null;\n this.connectSent = false;\n if (this.connectTimer !== null) {\n window.clearTimeout(this.connectTimer);\n }\n this.connectTimer = window.setTimeout(() => {\n void this.sendConnect();\n }, 750);\n }\n}\n","import type { TaskRunRecord } from \"../../../../src/config/sessions/task-run-types.js\";\nimport type {\n ProjectedMetricsEvent,\n ProjectedOutcomeEvent,\n ProjectedPhaseEvent,\n ProjectedRunEvent,\n RunEventsTruncationReason,\n TasksRunEventsResult,\n} from \"../../../../src/gateway/server-methods/tasks-run-events.js\";\nimport { GatewayRequestError, type GatewayBrowserClient, type GatewayHelloOk } from \"../gateway.ts\";\n\nexport type {\n ProjectedMetricsEvent,\n ProjectedOutcomeEvent,\n ProjectedPhaseEvent,\n ProjectedRunEvent,\n};\nexport type DreamsTaskRun = TaskRunRecord;\n\n// Every panel reports one of these: \"disabled\" = the method is absent from\n// hello.features.methods (plugin not loaded); \"degraded\" = the method exists but failed\n// (UNAVAILABLE or any other error); \"ok\" includes a successful empty answer.\nexport type PanelStatus = \"idle\" | \"loading\" | \"ok\" | \"disabled\" | \"degraded\";\n\nexport type PanelError = { code: string | null; message: string };\n\nexport type DreamsBudgetWindow = {\n available: boolean;\n error?: string;\n scopeKind: string;\n windowHours: number | null;\n cap: number | null;\n ceilingCap: number | null;\n windowStartTs: string | null;\n windowUsageUnits: number;\n totalDenied: number;\n resetCount: number;\n lastResetTs: string | null;\n};\n\nexport type RunEventsTruncation = Record<\n string,\n { reason: RunEventsTruncationReason; dropped: number }\n>;\n\nexport type DreamsRunsPanel = {\n status: PanelStatus;\n error: PanelError | null;\n runsAvailable: boolean;\n runsError: string | null;\n runs: DreamsTaskRun[];\n budgetWindow: DreamsBudgetWindow | null;\n eventsStatus: PanelStatus;\n eventsError: PanelError | null;\n events: Record<string, ProjectedRunEvent[]>;\n truncated: RunEventsTruncation;\n retentionDays: number | null;\n loadedAt: number | null;\n};\n\nexport type DreamStageView = { name: string; order: number; lastCompleted?: number };\nexport type DreamActiveCycle = {\n cycleKey: string;\n currentStage: string;\n pendingPassCount: number;\n failedStages: string[];\n createdAt: number;\n};\nexport type DreamStatusResult = {\n enabled: boolean;\n stages: DreamStageView[];\n questionCount: number;\n questionCountTruncated?: boolean;\n candidateCount: number;\n candidateCountTruncated?: boolean;\n contemplationConfigured?: boolean;\n activeCycles?: DreamActiveCycle[];\n};\nexport type DreamWeight = {\n agentId: string;\n totals: { completed: number; failed: number };\n successRate: number;\n updatedAt: number;\n};\nexport type DreamCandidate = { signature?: string; taskId?: string; firstSeenAt?: string };\n\nexport type DreamStatePanel = {\n status: PanelStatus;\n error: PanelError | null;\n result: DreamStatusResult | null;\n weightsStatus: PanelStatus;\n weightsError: PanelError | null;\n weights: DreamWeight[];\n weightsTruncated: boolean;\n candidatesStatus: PanelStatus;\n candidatesError: PanelError | null;\n candidates: DreamCandidate[];\n candidatesTruncated: boolean;\n};\n\nexport type LearningOverviewCounts = {\n proposals: { pending: number; applied: number; rejected: number; quarantined: number };\n lessons: number;\n scopes: number;\n truncated?: boolean;\n backend?: string;\n};\n\nexport type QualityPoint = { taskRunId: string; taskId: string; at: string; qualityScore: number };\n\nexport type PreemptionShare = {\n preempted: number;\n total: number;\n shutdownExcluded: number;\n};\n\nexport type DistillAuthoring = { taskRunId: string; at: string; authoring: string } | null;\n\nexport type LessonHealthPanel = {\n overviewStatus: PanelStatus;\n overviewError: PanelError | null;\n overview: LearningOverviewCounts | null;\n runsStatus: PanelStatus;\n runsError: PanelError | null;\n quality: QualityPoint[];\n unclassifiedRecovered: number;\n preemption: PreemptionShare;\n distillStatus: PanelStatus;\n distillError: PanelError | null;\n authoring: DistillAuthoring;\n};\n\nexport type DreamsViewState = {\n runs: DreamsRunsPanel;\n dream: DreamStatePanel;\n health: LessonHealthPanel;\n selectedRunId: string | null;\n};\n\nexport function createDefaultDreamsState(): DreamsViewState {\n return {\n runs: {\n status: \"idle\",\n error: null,\n runsAvailable: false,\n runsError: null,\n runs: [],\n budgetWindow: null,\n eventsStatus: \"idle\",\n eventsError: null,\n events: {},\n truncated: {},\n retentionDays: null,\n loadedAt: null,\n },\n dream: {\n status: \"idle\",\n error: null,\n result: null,\n weightsStatus: \"idle\",\n weightsError: null,\n weights: [],\n weightsTruncated: false,\n candidatesStatus: \"idle\",\n candidatesError: null,\n candidates: [],\n candidatesTruncated: false,\n },\n health: {\n overviewStatus: \"idle\",\n overviewError: null,\n overview: null,\n runsStatus: \"idle\",\n runsError: null,\n quality: [],\n unclassifiedRecovered: 0,\n preemption: { preempted: 0, total: 0, shutdownExcluded: 0 },\n distillStatus: \"idle\",\n distillError: null,\n authoring: null,\n },\n selectedRunId: null,\n };\n}\n\nexport type DreamsHost = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n hello: GatewayHelloOk | null;\n tab: string;\n dreams: DreamsViewState;\n dreamsGeneration: number;\n dreamsDirty: boolean;\n dreamsTrailingTimer: number | null;\n dreamsTrailingPending: boolean;\n dreamsBurstStartedAt: number | null;\n dreamsPollInterval: number | null;\n};\n\nexport const DREAMS_RUNS_LIMIT = 50;\nexport const DREAMS_HEALTH_RUNS_LIMIT = 50;\nexport const DREAMS_DISTILL_LIMIT = 20;\nexport const DREAMS_CANDIDATES_LIMIT = 20;\nexport const RUN_EVENTS_CHUNK = 50;\nexport const DREAMS_TRAILING_MS = 1000;\nexport const DREAMS_TRAILING_MAX_WAIT_MS = 5000;\nexport const DREAMS_POLL_MS = 30_000;\n\nconst PRODUCE_TASK = \"learning-core.produce\";\nconst CONSOLIDATION_TASK = \"learning-core.consolidation\";\nconst DISTILL_TASK = \"learning-core.distill\";\n\n// Absent features list (older gateway): capability unknown, so the request is tried and\n// a failure reads as degraded rather than disabled.\nexport function methodAdvertised(hello: GatewayHelloOk | null, method: string): boolean {\n const methods = hello?.features?.methods;\n if (!Array.isArray(methods)) {\n return true;\n }\n return methods.includes(method);\n}\n\nfunction toPanelError(err: unknown): PanelError {\n if (err instanceof GatewayRequestError) {\n return { code: err.gatewayCode, message: err.message };\n }\n return { code: null, message: err instanceof Error ? err.message : String(err) };\n}\n\nfunction patch(host: DreamsHost, next: Partial<DreamsViewState>) {\n host.dreams = { ...host.dreams, ...next };\n}\n\nfunction patchRuns(host: DreamsHost, next: Partial<DreamsRunsPanel>) {\n patch(host, { runs: { ...host.dreams.runs, ...next } });\n}\n\nfunction patchDream(host: DreamsHost, next: Partial<DreamStatePanel>) {\n patch(host, { dream: { ...host.dreams.dream, ...next } });\n}\n\nfunction patchHealth(host: DreamsHost, next: Partial<LessonHealthPanel>) {\n patch(host, { health: { ...host.dreams.health, ...next } });\n}\n\ntype StatusResult = {\n runs?: DreamsTaskRun[];\n runsAvailable?: boolean;\n runsError?: string;\n budgetWindow?: DreamsBudgetWindow;\n};\n\nasync function requestStatus(\n client: GatewayBrowserClient,\n params: Record<string, unknown>,\n): Promise<StatusResult> {\n return client.request<StatusResult>(\"tasks.status\", params);\n}\n\n// Chunked into requests of at most 50 ids; merged in request order so the result is\n// deterministic regardless of which chunk resolves first.\nexport async function loadRunEvents(\n client: GatewayBrowserClient,\n taskRunIds: string[],\n): Promise<{\n events: Record<string, ProjectedRunEvent[]>;\n truncated: RunEventsTruncation;\n retentionDays: number | null;\n}> {\n const unique = [...new Set(taskRunIds)];\n const chunks: string[][] = [];\n for (let i = 0; i < unique.length; i += RUN_EVENTS_CHUNK) {\n chunks.push(unique.slice(i, i + RUN_EVENTS_CHUNK));\n }\n const results = await Promise.all(\n chunks.map((ids) =>\n client.request<TasksRunEventsResult>(\"tasks.runEvents\", { taskRunIds: ids }),\n ),\n );\n const events: Record<string, ProjectedRunEvent[]> = Object.create(null);\n const truncated: RunEventsTruncation = Object.create(null);\n let retentionDays: number | null = null;\n for (const result of results) {\n retentionDays ??= typeof result.retentionDays === \"number\" ? result.retentionDays : null;\n for (const id of Object.keys(result.events ?? {})) {\n events[id] = result.events[id] ?? [];\n }\n for (const id of Object.keys(result.truncated ?? {})) {\n const entry = result.truncated?.[id];\n if (entry) {\n truncated[id] = entry;\n }\n }\n }\n return { events, truncated, retentionDays };\n}\n\nexport function metricsEvent(\n events: ProjectedRunEvent[] | undefined,\n): ProjectedMetricsEvent | null {\n let found: ProjectedMetricsEvent | null = null;\n for (const event of events ?? []) {\n if (event.kind === \"metrics\") {\n found = event;\n }\n }\n return found;\n}\n\nexport function phaseEvents(events: ProjectedRunEvent[] | undefined): ProjectedPhaseEvent[] {\n return (events ?? [])\n .filter((event): event is ProjectedPhaseEvent => event.kind === \"phase\")\n .toSorted((a, b) => a.offsetMs - b.offsetMs || a.ordinal - b.ordinal);\n}\n\nexport function outcomeEvents(events: ProjectedRunEvent[] | undefined): ProjectedOutcomeEvent[] {\n return (events ?? []).filter((event): event is ProjectedOutcomeEvent => event.kind === \"outcome\");\n}\n\nexport function runTime(run: DreamsTaskRun): string {\n return run.startedAt ?? run.completedAt ?? run.updatedAt;\n}\n\nconst TERMINALISH = new Set([\n \"completed\",\n \"failed\",\n \"dlq\",\n \"preempted\",\n \"preempted_ceiling\",\n \"rolled_back\",\n \"cancelled\",\n]);\n\nexport type MeasurementLabel =\n | \"complete\"\n | \"unavailable\"\n | \"missing\"\n | \"truncated\"\n | \"pruned\"\n | \"denied\"\n | \"in_progress\"\n | \"not_loaded\";\n\n// Classifies what the drawer can honestly say about a run's measurement. A crash-finalized\n// attempt (reclaim, `recovered`) or a timeout-unsettled handler never shows zeros. `isTruncated`\n// is whether the server's bounded response dropped rows for this run (per-run/overall/byte\n// limit): a dropped metrics row must not be reported as \"missing\" — that implies it was never\n// recorded at all, which the caller cannot know once rows were truncated away.\nexport function measurementLabel(\n run: DreamsTaskRun,\n events: ProjectedRunEvent[] | undefined,\n retentionDays: number | null,\n nowMs: number = Date.now(),\n isTruncated = false,\n): MeasurementLabel {\n if (events === undefined) {\n return \"not_loaded\";\n }\n const metrics = metricsEvent(events);\n if (metrics) {\n return metrics.measurementState === \"unavailable\" ? \"unavailable\" : \"complete\";\n }\n if (events.length === 0 && retentionDays !== null) {\n const at = Date.parse(run.completedAt ?? run.updatedAt);\n if (Number.isFinite(at) && nowMs - at > retentionDays * 86_400_000) {\n return \"pruned\";\n }\n }\n if (outcomeEvents(events).some((event) => event.denial)) {\n return \"denied\";\n }\n if (!TERMINALISH.has(run.status) && run.status !== \"deferred\") {\n return \"in_progress\";\n }\n return isTruncated ? \"truncated\" : \"missing\";\n}\n\nexport function isDryRun(run: DreamsTaskRun, events: ProjectedRunEvent[] | undefined): boolean {\n return run.mode === \"dry_run\" || metricsEvent(events)?.mode === \"dry_run\";\n}\n\nfunction isPruned(\n run: DreamsTaskRun,\n events: ProjectedRunEvent[] | undefined,\n retentionDays: number | null,\n): boolean {\n return measurementLabel(run, events, retentionDays) === \"pruned\";\n}\n\nfunction preemptionReason(events: ProjectedRunEvent[] | undefined): string | null {\n let reason: string | null = null;\n for (const event of outcomeEvents(events)) {\n if (event.preemption?.reason) {\n reason = event.preemption.reason;\n }\n }\n return reason;\n}\n\nexport type ConsolidationRunView = {\n run: DreamsTaskRun;\n events: ProjectedRunEvent[] | undefined;\n};\n\n// Merges the two bounded tasks.status reads by run time and keeps only consolidation runs:\n// every standalone consolidation run, and produce runs whose metrics name consolidation as\n// the producer. Dry-runs are excluded; produce runs with no metrics row (crash-recovered)\n// cannot be classified and are counted separately.\nexport function classifyConsolidationRuns(\n produce: DreamsTaskRun[],\n consolidation: DreamsTaskRun[],\n events: Record<string, ProjectedRunEvent[]>,\n): { runs: ConsolidationRunView[]; unclassifiedRecovered: number } {\n const merged = [...produce, ...consolidation].toSorted((a, b) =>\n runTime(b).localeCompare(runTime(a)),\n );\n const runs: ConsolidationRunView[] = [];\n let unclassifiedRecovered = 0;\n for (const run of merged) {\n const runEvents = events[run.taskRunId];\n if (isDryRun(run, runEvents)) {\n continue;\n }\n if (run.taskId === CONSOLIDATION_TASK) {\n runs.push({ run, events: runEvents });\n continue;\n }\n const metrics = metricsEvent(runEvents);\n if (!metrics) {\n if (TERMINALISH.has(run.status)) {\n unclassifiedRecovered += 1;\n }\n continue;\n }\n if (metrics.items?.producer === \"consolidation\") {\n runs.push({ run, events: runEvents });\n }\n }\n return { runs, unclassifiedRecovered };\n}\n\nexport function qualityTrend(runs: ConsolidationRunView[]): QualityPoint[] {\n const points: QualityPoint[] = [];\n for (const { run, events } of runs) {\n const score = metricsEvent(events)?.qualityScore;\n if (typeof score === \"number\" && Number.isFinite(score)) {\n points.push({\n taskRunId: run.taskRunId,\n taskId: run.taskId,\n at: runTime(run),\n qualityScore: score,\n });\n }\n }\n return points.toSorted((a, b) => a.at.localeCompare(b.at));\n}\n\n// Preempted by lease, reclaim, or with no recorded reason, plus preempted_ceiling, over the\n// consolidation runs in view. A cooperative shutdown preemption is not counted as preempted.\nexport function preemptionShare(runs: ConsolidationRunView[]): PreemptionShare {\n let preempted = 0;\n let shutdownExcluded = 0;\n for (const { run, events } of runs) {\n if (run.status === \"preempted_ceiling\") {\n preempted += 1;\n continue;\n }\n if (run.status !== \"preempted\") {\n continue;\n }\n const reason = preemptionReason(events);\n if (reason === \"shutdown\") {\n shutdownExcluded += 1;\n continue;\n }\n preempted += 1;\n }\n return { preempted, total: runs.length, shutdownExcluded };\n}\n\n// The newest normal-mode distill run whose metrics carry `authoring`; newer dry-runs,\n// budget-deferred runs, and runs whose rows were pruned never mask it.\nexport function latestDistillAuthoring(\n runs: DreamsTaskRun[],\n events: Record<string, ProjectedRunEvent[]>,\n retentionDays: number | null,\n): DistillAuthoring {\n const sorted = runs.toSorted((a, b) => runTime(b).localeCompare(runTime(a)));\n for (const run of sorted) {\n const runEvents = events[run.taskRunId];\n if (isDryRun(run, runEvents) || run.status === \"deferred\") {\n continue;\n }\n if (isPruned(run, runEvents, retentionDays)) {\n continue;\n }\n if (outcomeEvents(runEvents).some((event) => event.denial)) {\n continue;\n }\n const authoring = metricsEvent(runEvents)?.authoring;\n if (authoring) {\n return { taskRunId: run.taskRunId, at: runTime(run), authoring };\n }\n }\n return null;\n}\n\nfunction isCurrent(host: DreamsHost, generation: number): boolean {\n return host.dreamsGeneration === generation && host.connected;\n}\n\nasync function loadRunsPanel(host: DreamsHost, generation: number) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, \"tasks.status\")) {\n patchRuns(host, { status: \"disabled\", error: null, runs: [], budgetWindow: null });\n return;\n }\n patchRuns(host, { status: host.dreams.runs.status === \"ok\" ? \"ok\" : \"loading\" });\n let status: StatusResult;\n try {\n status = await requestStatus(client, { limit: DREAMS_RUNS_LIMIT });\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchRuns(host, { status: \"degraded\", error: toPanelError(err) });\n }\n return;\n }\n if (!isCurrent(host, generation)) {\n return;\n }\n const runs = Array.isArray(status.runs) ? status.runs : [];\n // Runs and their events land in one patch, so a row never renders against another\n // refresh's events.\n const base: Partial<DreamsRunsPanel> = {\n status: \"ok\",\n error: null,\n runsAvailable: status.runsAvailable === true,\n runsError: status.runsError ?? null,\n runs,\n budgetWindow: status.budgetWindow ?? null,\n loadedAt: Date.now(),\n };\n if (!methodAdvertised(host.hello, \"tasks.runEvents\")) {\n patchRuns(host, {\n ...base,\n eventsStatus: \"disabled\",\n events: {},\n truncated: {},\n eventsError: null,\n });\n return;\n }\n if (runs.length === 0) {\n patchRuns(host, { ...base, eventsStatus: \"ok\", events: {}, truncated: {}, eventsError: null });\n return;\n }\n try {\n const { events, truncated, retentionDays } = await loadRunEvents(\n client,\n runs.map((run) => run.taskRunId),\n );\n if (isCurrent(host, generation)) {\n patchRuns(host, {\n ...base,\n eventsStatus: \"ok\",\n eventsError: null,\n events,\n truncated,\n retentionDays,\n });\n }\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchRuns(host, {\n ...base,\n eventsStatus: \"degraded\",\n eventsError: toPanelError(err),\n events: {},\n truncated: {},\n });\n }\n }\n}\n\nasync function loadDreamPart<T>(\n host: DreamsHost,\n generation: number,\n method: string,\n params: Record<string, unknown>,\n apply: (result: T) => void,\n fail: (status: PanelStatus, error: PanelError | null) => void,\n) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, method)) {\n fail(\"disabled\", null);\n return;\n }\n try {\n const result = await client.request<T>(method, params);\n if (isCurrent(host, generation)) {\n apply(result);\n }\n } catch (err) {\n if (isCurrent(host, generation)) {\n fail(\"degraded\", toPanelError(err));\n }\n }\n}\n\nasync function loadDreamState(host: DreamsHost, generation: number) {\n if (host.dreams.dream.status === \"idle\") {\n patchDream(host, { status: \"loading\" });\n }\n await Promise.all([\n loadDreamPart<DreamStatusResult>(\n host,\n generation,\n \"dream.status\",\n {},\n (result) => patchDream(host, { status: \"ok\", error: null, result }),\n (status, error) => patchDream(host, { status, error, result: null }),\n ),\n loadDreamPart<{ weights?: DreamWeight[]; truncated?: boolean }>(\n host,\n generation,\n \"dream.weights\",\n {},\n (result) =>\n patchDream(host, {\n weightsStatus: \"ok\",\n weightsError: null,\n weights: Array.isArray(result.weights) ? result.weights : [],\n weightsTruncated: result.truncated === true,\n }),\n (status, error) =>\n patchDream(host, { weightsStatus: status, weightsError: error, weights: [] }),\n ),\n loadDreamPart<{ candidates?: DreamCandidate[]; truncated?: boolean }>(\n host,\n generation,\n \"dream.candidates\",\n { limit: DREAMS_CANDIDATES_LIMIT },\n (result) =>\n patchDream(host, {\n candidatesStatus: \"ok\",\n candidatesError: null,\n candidates: Array.isArray(result.candidates) ? result.candidates : [],\n candidatesTruncated: result.truncated === true,\n }),\n (status, error) =>\n patchDream(host, { candidatesStatus: status, candidatesError: error, candidates: [] }),\n ),\n ]);\n}\n\nasync function loadConsolidationHealth(host: DreamsHost, generation: number) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, \"tasks.status\")) {\n patchHealth(host, { runsStatus: \"disabled\", runsError: null, quality: [] });\n return;\n }\n try {\n const [produce, consolidation] = await Promise.all([\n requestStatus(client, { taskId: PRODUCE_TASK, limit: DREAMS_HEALTH_RUNS_LIMIT }),\n requestStatus(client, { taskId: CONSOLIDATION_TASK, limit: DREAMS_HEALTH_RUNS_LIMIT }),\n ]);\n if (produce.runsAvailable === false || consolidation.runsAvailable === false) {\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n runsStatus: \"degraded\",\n runsError: {\n code: null,\n message: produce.runsError ?? consolidation.runsError ?? \"runs store unavailable\",\n },\n });\n }\n return;\n }\n const produceRuns = produce.runs ?? [];\n const consolidationRuns = consolidation.runs ?? [];\n const ids = [...produceRuns, ...consolidationRuns].map((run) => run.taskRunId);\n if (ids.length > 0 && !methodAdvertised(host.hello, \"tasks.runEvents\")) {\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n runsStatus: \"degraded\",\n runsError: { code: null, message: \"tasks.runEvents not available\" },\n });\n }\n return;\n }\n const { events } =\n ids.length > 0\n ? await loadRunEvents(client, ids)\n : { events: {} as Record<string, ProjectedRunEvent[]> };\n if (!isCurrent(host, generation)) {\n return;\n }\n const classified = classifyConsolidationRuns(produceRuns, consolidationRuns, events);\n patchHealth(host, {\n runsStatus: \"ok\",\n runsError: null,\n quality: qualityTrend(classified.runs),\n unclassifiedRecovered: classified.unclassifiedRecovered,\n preemption: preemptionShare(classified.runs),\n });\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchHealth(host, { runsStatus: \"degraded\", runsError: toPanelError(err) });\n }\n }\n}\n\nasync function loadDistillAuthoring(host: DreamsHost, generation: number) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, \"tasks.status\")) {\n patchHealth(host, { distillStatus: \"disabled\", distillError: null, authoring: null });\n return;\n }\n try {\n const status = await requestStatus(client, {\n taskId: DISTILL_TASK,\n status: \"completed\",\n limit: DREAMS_DISTILL_LIMIT,\n });\n if (status.runsAvailable === false) {\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n distillStatus: \"degraded\",\n distillError: { code: null, message: status.runsError ?? \"runs store unavailable\" },\n });\n }\n return;\n }\n const runs = status.runs ?? [];\n if (runs.length > 0 && !methodAdvertised(host.hello, \"tasks.runEvents\")) {\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n distillStatus: \"degraded\",\n distillError: { code: null, message: \"tasks.runEvents not available\" },\n });\n }\n return;\n }\n const { events, retentionDays } =\n runs.length > 0\n ? await loadRunEvents(\n client,\n runs.map((run) => run.taskRunId),\n )\n : { events: {} as Record<string, ProjectedRunEvent[]>, retentionDays: null };\n if (isCurrent(host, generation)) {\n patchHealth(host, {\n distillStatus: \"ok\",\n distillError: null,\n authoring: latestDistillAuthoring(runs, events, retentionDays),\n });\n }\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchHealth(host, { distillStatus: \"degraded\", distillError: toPanelError(err) });\n }\n }\n}\n\nasync function loadLearningOverviewCounts(host: DreamsHost, generation: number) {\n const client = host.client;\n if (!client) {\n return;\n }\n if (!methodAdvertised(host.hello, \"learning.overview\")) {\n patchHealth(host, { overviewStatus: \"disabled\", overviewError: null, overview: null });\n return;\n }\n try {\n const overview = await client.request<LearningOverviewCounts>(\"learning.overview\", {});\n if (isCurrent(host, generation)) {\n patchHealth(host, { overviewStatus: \"ok\", overviewError: null, overview });\n }\n } catch (err) {\n if (isCurrent(host, generation)) {\n patchHealth(host, { overviewStatus: \"degraded\", overviewError: toPanelError(err) });\n }\n }\n}\n\n// One full-state refresh. Each panel loads independently, so an unavailable optional plugin\n// never blanks the page; a newer refresh bumps the generation and older responses are dropped.\nexport async function loadDreams(host: DreamsHost): Promise<void> {\n if (!host.client || !host.connected) {\n return;\n }\n host.dreamsDirty = false;\n host.dreamsGeneration += 1;\n const generation = host.dreamsGeneration;\n await Promise.all([\n loadRunsPanel(host, generation),\n loadDreamState(host, generation),\n loadLearningOverviewCounts(host, generation),\n loadConsolidationHealth(host, generation),\n loadDistillAuthoring(host, generation),\n ]);\n}\n\nfunction dreamsVisible(host: DreamsHost): boolean {\n if (host.tab !== \"dreams\") {\n return false;\n }\n return typeof document === \"undefined\" || document.visibilityState !== \"hidden\";\n}\n\nfunction clearTrailing(host: DreamsHost) {\n if (host.dreamsTrailingTimer != null) {\n clearTimeout(host.dreamsTrailingTimer);\n }\n host.dreamsTrailingTimer = null;\n host.dreamsTrailingPending = false;\n host.dreamsBurstStartedAt = null;\n}\n\n// `dreams.update` is a payload-free hint. While the Dreams tab is not visible it only marks\n// the view dirty (zero RPCs). Visible: the first hint of a burst refreshes at once; later\n// hints arm one trailing re-fetch 1 s after the last hint, bounded by a max wait.\nexport function handleDreamsUpdate(host: DreamsHost, nowMs: number = Date.now()) {\n if (!dreamsVisible(host) || !host.connected) {\n host.dreamsDirty = true;\n return;\n }\n if (host.dreamsTrailingTimer == null) {\n host.dreamsBurstStartedAt = nowMs;\n host.dreamsTrailingPending = false;\n void loadDreams(host);\n } else {\n host.dreamsTrailingPending = true;\n clearTimeout(host.dreamsTrailingTimer);\n }\n const burstAge = nowMs - (host.dreamsBurstStartedAt ?? nowMs);\n const delay = Math.max(0, Math.min(DREAMS_TRAILING_MS, DREAMS_TRAILING_MAX_WAIT_MS - burstAge));\n host.dreamsTrailingTimer = window.setTimeout(() => {\n const pending = host.dreamsTrailingPending;\n clearTrailing(host);\n if (!pending) {\n return;\n }\n if (dreamsVisible(host) && host.connected) {\n void loadDreams(host);\n } else {\n host.dreamsDirty = true;\n }\n }, delay);\n}\n\nexport function startDreamsPolling(host: DreamsHost) {\n if (host.dreamsPollInterval != null) {\n return;\n }\n host.dreamsPollInterval = window.setInterval(() => {\n if (!dreamsVisible(host) || !host.connected) {\n return;\n }\n void loadDreams(host);\n }, DREAMS_POLL_MS);\n}\n\nexport function stopDreamsPolling(host: DreamsHost) {\n if (host.dreamsPollInterval != null) {\n clearInterval(host.dreamsPollInterval);\n }\n host.dreamsPollInterval = null;\n clearTrailing(host);\n // In-flight responses from before the stop belong to a dead connection.\n host.dreamsGeneration += 1;\n}\n\n// A browser tab coming back into view catches up once if hints arrived while it was hidden.\nexport function handleDreamsVisibilityChange(host: DreamsHost) {\n if (host.dreamsDirty && dreamsVisible(host) && host.connected) {\n void loadDreams(host);\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { LogEntry, LogLevel } from \"../types.ts\";\n\nexport type LogsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n logsLoading: boolean;\n logsError: string | null;\n logsCursor: number | null;\n logsFile: string | null;\n logsEntries: LogEntry[];\n logsTruncated: boolean;\n logsLastFetchAt: number | null;\n logsLimit: number;\n logsMaxBytes: number;\n};\n\nconst LOG_BUFFER_LIMIT = 2000;\nconst LEVELS = new Set<LogLevel>([\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"]);\n\nfunction parseMaybeJsonString(value: unknown) {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n if (!trimmed.startsWith(\"{\") || !trimmed.endsWith(\"}\")) {\n return null;\n }\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!parsed || typeof parsed !== \"object\") {\n return null;\n }\n return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction normalizeLevel(value: unknown): LogLevel | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const lowered = value.toLowerCase() as LogLevel;\n return LEVELS.has(lowered) ? lowered : null;\n}\n\nexport function parseLogLine(line: string): LogEntry {\n if (!line.trim()) {\n return { raw: line, message: line };\n }\n try {\n const obj = JSON.parse(line) as Record<string, unknown>;\n const meta =\n obj && typeof obj._meta === \"object\" && obj._meta !== null\n ? (obj._meta as Record<string, unknown>)\n : null;\n const time =\n typeof obj.time === \"string\" ? obj.time : typeof meta?.date === \"string\" ? meta?.date : null;\n const level = normalizeLevel(meta?.logLevelName ?? meta?.level);\n\n const contextCandidate =\n typeof obj[\"0\"] === \"string\" ? obj[\"0\"] : typeof meta?.name === \"string\" ? meta?.name : null;\n const contextObj = parseMaybeJsonString(contextCandidate);\n let subsystem: string | null = null;\n if (contextObj) {\n if (typeof contextObj.subsystem === \"string\") {\n subsystem = contextObj.subsystem;\n } else if (typeof contextObj.module === \"string\") {\n subsystem = contextObj.module;\n }\n }\n if (!subsystem && contextCandidate && contextCandidate.length < 120) {\n subsystem = contextCandidate;\n }\n\n let message: string | null = null;\n if (typeof obj[\"1\"] === \"string\") {\n message = obj[\"1\"];\n } else if (!contextObj && typeof obj[\"0\"] === \"string\") {\n message = obj[\"0\"];\n } else if (typeof obj.message === \"string\") {\n message = obj.message;\n }\n\n return {\n raw: line,\n time,\n level,\n subsystem,\n message: message ?? line,\n meta: meta ?? undefined,\n };\n } catch {\n return { raw: line, message: line };\n }\n}\n\nexport async function loadLogs(state: LogsState, opts?: { reset?: boolean; quiet?: boolean }) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.logsLoading && !opts?.quiet) {\n return;\n }\n if (!opts?.quiet) {\n state.logsLoading = true;\n }\n state.logsError = null;\n try {\n const res = await state.client.request(\"logs.tail\", {\n cursor: opts?.reset ? undefined : (state.logsCursor ?? undefined),\n limit: state.logsLimit,\n maxBytes: state.logsMaxBytes,\n });\n const payload = res as {\n file?: string;\n cursor?: number;\n size?: number;\n lines?: unknown;\n truncated?: boolean;\n reset?: boolean;\n };\n const lines = Array.isArray(payload.lines)\n ? payload.lines.filter((line) => typeof line === \"string\")\n : [];\n const entries = lines.map(parseLogLine);\n const shouldReset = Boolean(opts?.reset || payload.reset || state.logsCursor == null);\n state.logsEntries = shouldReset\n ? entries\n : [...state.logsEntries, ...entries].slice(-LOG_BUFFER_LIMIT);\n if (typeof payload.cursor === \"number\") {\n state.logsCursor = payload.cursor;\n }\n if (typeof payload.file === \"string\") {\n state.logsFile = payload.file;\n }\n state.logsTruncated = Boolean(payload.truncated);\n state.logsLastFetchAt = Date.now();\n } catch (err) {\n state.logsError = String(err);\n } finally {\n if (!opts?.quiet) {\n state.logsLoading = false;\n }\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\n\nexport type NodesState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n nodesLoading: boolean;\n nodes: Array<Record<string, unknown>>;\n lastError: string | null;\n};\n\nexport async function loadNodes(state: NodesState, opts?: { quiet?: boolean }) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.nodesLoading) {\n return;\n }\n state.nodesLoading = true;\n if (!opts?.quiet) {\n state.lastError = null;\n }\n try {\n const res = await state.client.request<{ nodes?: Record<string, unknown> }>(\"node.list\", {});\n state.nodes = Array.isArray(res.nodes) ? res.nodes : [];\n } catch (err) {\n if (!opts?.quiet) {\n state.lastError = String(err);\n }\n } finally {\n state.nodesLoading = false;\n }\n}\n","import { toNumber } from \"../format.ts\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type {\n DurableSessionRunListResult,\n DurableSessionRunRecord,\n SessionRunsResult,\n SessionsListResult,\n SessionsThresholdsResult,\n} from \"../types.ts\";\n\nexport type SessionsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionsLoading: boolean;\n sessionsResult: SessionsListResult | null;\n sessionsError: string | null;\n sessionsFilterActive: string;\n sessionsFilterLimit: string;\n sessionsIncludeGlobal: boolean;\n sessionsIncludeUnknown: boolean;\n sessionRunsResult: SessionRunsResult | null;\n sessionRunsError: string | null;\n sessionRunsFetchedAt: number;\n sessionRunsLoading: boolean;\n recentlyCompletedRuns: { key: string; completedAt: number }[];\n sessionRunsPrevKeys: Set<string>;\n sessionsThresholdsResult: SessionsThresholdsResult | null;\n sessionsThresholdsError: string | null;\n sessionsThresholdsLoading: boolean;\n sessionRunsInterruptingKeys: Set<string>;\n recoverableRuns: DurableSessionRunRecord[];\n recoveryError: string | null;\n decidingRunIds: Set<string>;\n recoverableRunsLoading: boolean;\n};\n\nexport async function loadSessions(\n state: SessionsState,\n overrides?: {\n activeMinutes?: number;\n limit?: number;\n includeGlobal?: boolean;\n includeUnknown?: boolean;\n },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.sessionsLoading) {\n return;\n }\n state.sessionsLoading = true;\n state.sessionsError = null;\n try {\n const includeGlobal = overrides?.includeGlobal ?? state.sessionsIncludeGlobal;\n const includeUnknown = overrides?.includeUnknown ?? state.sessionsIncludeUnknown;\n const activeMinutes = overrides?.activeMinutes ?? toNumber(state.sessionsFilterActive, 0);\n const limit = overrides?.limit ?? toNumber(state.sessionsFilterLimit, 0);\n const params: Record<string, unknown> = {\n includeGlobal,\n includeUnknown,\n };\n if (activeMinutes > 0) {\n params.activeMinutes = activeMinutes;\n }\n if (limit > 0) {\n params.limit = limit;\n }\n const res = await state.client.request<SessionsListResult | undefined>(\"sessions.list\", params);\n if (res) {\n state.sessionsResult = res;\n }\n } catch (err) {\n state.sessionsError = String(err);\n } finally {\n state.sessionsLoading = false;\n }\n}\n\nexport async function loadSessionRuns(state: SessionsState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.sessionRunsLoading) {\n return;\n }\n state.sessionRunsLoading = true;\n // Capture pre-await snapshots so a push event that fires during the network round-trip\n // does not corrupt the ring-buffer diff or clobber fresher push-delivered state.\n const prevKeys = state.sessionRunsPrevKeys;\n const prevFetchedAt = state.sessionRunsFetchedAt;\n try {\n const res = await state.client.request<SessionRunsResult | undefined>(\"sessions.runs\", {});\n state.sessionRunsError = null;\n if (res) {\n const now = Date.now();\n state.recentlyCompletedRuns = updateRecentlyCompletedRuns(\n prevKeys,\n res.runs,\n state.recentlyCompletedRuns,\n now,\n );\n // A push that fired during the poll already delivered fresher data; don't overwrite it.\n if (state.sessionRunsFetchedAt <= prevFetchedAt) {\n state.sessionRunsFetchedAt = now;\n state.sessionRunsPrevKeys = new Set(res.runs.map((r) => r.key));\n state.sessionRunsResult = res;\n }\n }\n } catch (err) {\n state.sessionRunsError = String(err);\n // Do NOT advance sessionRunsFetchedAt on error — the age formula relies on the\n // last-successful-fetch timestamp to continue growing correctly during outages.\n } finally {\n state.sessionRunsLoading = false;\n }\n}\n\nexport async function loadSessionThresholds(state: SessionsState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.sessionsThresholdsLoading) {\n return;\n }\n state.sessionsThresholdsLoading = true;\n try {\n const res = await state.client.request<SessionsThresholdsResult | undefined>(\n \"sessions.thresholds\",\n {},\n );\n state.sessionsThresholdsError = null;\n if (res) {\n state.sessionsThresholdsResult = res;\n }\n } catch (err) {\n state.sessionsThresholdsError = String(err);\n } finally {\n state.sessionsThresholdsLoading = false;\n }\n}\n\nexport async function interruptSession(state: SessionsState, key: string): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n state.sessionRunsInterruptingKeys = new Set([...state.sessionRunsInterruptingKeys, key]);\n try {\n const res = await state.client.request<{ ok: boolean; key?: string } | undefined>(\n \"sessions.interrupt\",\n { key },\n );\n if (res && !res.ok) {\n state.sessionRunsError = `Interrupt not applied: session run not found (${key})`;\n }\n } catch (err) {\n state.sessionRunsError = String(err);\n } finally {\n const next = new Set(state.sessionRunsInterruptingKeys);\n next.delete(key);\n state.sessionRunsInterruptingKeys = next;\n }\n}\n\nexport async function listRecoverableRuns(\n state: SessionsState,\n): Promise<DurableSessionRunListResult> {\n if (!state.client || !state.connected) {\n return { runs: [] };\n }\n const res = await state.client.request<DurableSessionRunListResult | undefined>(\n \"sessions.runs.list\",\n { statuses: [\"needs_recovery_decision\"] },\n );\n return res ?? { runs: [] };\n}\n\nexport async function loadRecoverableRuns(state: SessionsState): Promise<void> {\n if (!state.client || !state.connected || state.recoverableRunsLoading) {\n return;\n }\n state.recoverableRunsLoading = true;\n state.recoveryError = null;\n try {\n const result = await listRecoverableRuns(state);\n state.recoverableRuns = result.runs;\n } catch (err) {\n state.recoveryError = String(err);\n } finally {\n state.recoverableRunsLoading = false;\n }\n}\n\nexport async function continueRun(\n state: SessionsState,\n sessionRunId: string,\n decisionVersion: number,\n): Promise<{ ok: boolean; conflict: boolean }> {\n if (!state.client || !state.connected) {\n return { ok: false, conflict: false };\n }\n const res = await state.client.request<{ ok: boolean; conflict: boolean } | undefined>(\n \"sessions.runs.continue\",\n { sessionRunId, expectedDecisionVersion: decisionVersion },\n );\n return res ?? { ok: false, conflict: false };\n}\n\nexport async function cancelRun(\n state: SessionsState,\n sessionRunId: string,\n decisionVersion: number,\n): Promise<{ ok: boolean; conflict: boolean }> {\n if (!state.client || !state.connected) {\n return { ok: false, conflict: false };\n }\n const res = await state.client.request<{ ok: boolean; conflict: boolean } | undefined>(\n \"sessions.runs.cancel\",\n { sessionRunId, expectedDecisionVersion: decisionVersion },\n );\n return res ?? { ok: false, conflict: false };\n}\n\nexport async function patchSession(\n state: SessionsState,\n key: string,\n patch: {\n label?: string | null;\n thinkingLevel?: string | null;\n verboseLevel?: string | null;\n reasoningLevel?: string | null;\n },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n const params: Record<string, unknown> = { key };\n if (\"label\" in patch) {\n params.label = patch.label;\n }\n if (\"thinkingLevel\" in patch) {\n params.thinkingLevel = patch.thinkingLevel;\n }\n if (\"verboseLevel\" in patch) {\n params.verboseLevel = patch.verboseLevel;\n }\n if (\"reasoningLevel\" in patch) {\n params.reasoningLevel = patch.reasoningLevel;\n }\n try {\n await state.client.request(\"sessions.patch\", params);\n await loadSessions(state);\n } catch (err) {\n state.sessionsError = String(err);\n }\n}\n\nexport async function deleteSession(state: SessionsState, key: string): Promise<boolean> {\n if (!state.client || !state.connected) {\n return false;\n }\n if (state.sessionsLoading) {\n return false;\n }\n const confirmed = window.confirm(\n `Delete session \"${key}\"?\\n\\nDeletes the session entry and archives its transcript.`,\n );\n if (!confirmed) {\n return false;\n }\n state.sessionsLoading = true;\n state.sessionsError = null;\n try {\n await state.client.request(\"sessions.delete\", { key, deleteTranscript: true });\n return true;\n } catch (err) {\n state.sessionsError = String(err);\n return false;\n } finally {\n state.sessionsLoading = false;\n }\n}\n\nexport async function deleteSessionAndRefresh(state: SessionsState, key: string): Promise<boolean> {\n const deleted = await deleteSession(state, key);\n if (!deleted) {\n return false;\n }\n await loadSessions(state);\n return true;\n}\n\nconst RECENT_RUNS_MAX = 10;\nconst RECENT_RUNS_TTL_MS = 5 * 60_000;\n\nexport function updateRecentlyCompletedRuns(\n prevKeys: Set<string>,\n newRuns: { key: string }[],\n existing: { key: string; completedAt: number }[],\n now: number,\n): { key: string; completedAt: number }[] {\n const newKeySet = new Set(newRuns.map((r) => r.key));\n const existingKeys = new Set(existing.map((r) => r.key));\n const fresh: { key: string; completedAt: number }[] = [];\n for (const key of prevKeys) {\n if (!newKeySet.has(key) && !existingKeys.has(key)) {\n fresh.push({ key, completedAt: now });\n }\n }\n return [...fresh, ...existing]\n .filter((r) => now - r.completedAt < RECENT_RUNS_TTL_MS)\n .toSorted((a, b) => b.completedAt - a.completedAt)\n .slice(0, RECENT_RUNS_MAX);\n}\n","import type { OpenClawApp } from \"./app.ts\";\nimport { loadDebug } from \"./controllers/debug.ts\";\nimport {\n startDreamsPolling as startDreamsPollingInternal,\n stopDreamsPolling as stopDreamsPollingInternal,\n type DreamsHost,\n} from \"./controllers/dreams.ts\";\nimport { loadLogs } from \"./controllers/logs.ts\";\nimport { loadNodes } from \"./controllers/nodes.ts\";\nimport {\n loadRecoverableRuns,\n loadSessionRuns,\n loadSessionThresholds,\n} from \"./controllers/sessions.ts\";\n\ntype PollingHost = {\n nodesPollInterval: number | null;\n logsPollInterval: number | null;\n debugPollInterval: number | null;\n sessionRunsPollInterval: number | null;\n sessionRunsTickInterval: number | null;\n tab: string;\n};\n\nexport function startNodesPolling(host: PollingHost) {\n if (host.nodesPollInterval != null) {\n return;\n }\n host.nodesPollInterval = window.setInterval(\n () => void loadNodes(host as unknown as OpenClawApp, { quiet: true }),\n 5000,\n );\n}\n\nexport function stopNodesPolling(host: PollingHost) {\n if (host.nodesPollInterval == null) {\n return;\n }\n clearInterval(host.nodesPollInterval);\n host.nodesPollInterval = null;\n}\n\nexport function startLogsPolling(host: PollingHost) {\n if (host.logsPollInterval != null) {\n return;\n }\n host.logsPollInterval = window.setInterval(() => {\n if (host.tab !== \"logs\") {\n return;\n }\n void loadLogs(host as unknown as OpenClawApp, { quiet: true });\n }, 2000);\n}\n\nexport function stopLogsPolling(host: PollingHost) {\n if (host.logsPollInterval == null) {\n return;\n }\n clearInterval(host.logsPollInterval);\n host.logsPollInterval = null;\n}\n\nexport function startDebugPolling(host: PollingHost) {\n if (host.debugPollInterval != null) {\n return;\n }\n host.debugPollInterval = window.setInterval(() => {\n if (host.tab !== \"debug\") {\n return;\n }\n void loadDebug(host as unknown as OpenClawApp);\n }, 3000);\n}\n\nexport function stopDebugPolling(host: PollingHost) {\n if (host.debugPollInterval == null) {\n return;\n }\n clearInterval(host.debugPollInterval);\n host.debugPollInterval = null;\n}\n\nexport function startSessionRunsPolling(host: PollingHost) {\n if (host.sessionRunsPollInterval != null) {\n return;\n }\n host.sessionRunsPollInterval = window.setInterval(() => {\n if (host.tab !== \"sessions\") {\n return;\n }\n void loadSessionRuns(host as unknown as Parameters<typeof loadSessionRuns>[0]);\n void loadSessionThresholds(host as unknown as Parameters<typeof loadSessionThresholds>[0]);\n void loadRecoverableRuns(host as unknown as Parameters<typeof loadRecoverableRuns>[0]);\n }, 30_000);\n}\n\nexport function stopSessionRunsPolling(host: PollingHost) {\n if (host.sessionRunsPollInterval == null) {\n return;\n }\n clearInterval(host.sessionRunsPollInterval);\n host.sessionRunsPollInterval = null;\n}\n\n// Visible-tab fallback for a dropped `dreams.update` hint: 30 s, and only while the Dreams tab\n// is the active console tab in a visible browser tab.\nexport function startDreamsPolling(host: PollingHost) {\n startDreamsPollingInternal(host as unknown as DreamsHost);\n}\n\nexport function stopDreamsPolling(host: PollingHost) {\n stopDreamsPollingInternal(host as unknown as DreamsHost);\n}\n\nfunction prefersReducedMotion(): boolean {\n return window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n}\n\nexport function startSessionRunsTick(host: PollingHost) {\n if (host.sessionRunsTickInterval != null || prefersReducedMotion()) {\n return;\n }\n host.sessionRunsTickInterval = window.setInterval(() => {\n if (host.tab !== \"sessions\") {\n return;\n }\n const runs = (host as unknown as { sessionRunsResult?: { runs?: unknown[] } }).sessionRunsResult\n ?.runs;\n if (!runs || runs.length === 0) {\n return;\n }\n (host as unknown as { requestUpdate: () => void }).requestUpdate();\n }, 1000);\n}\n\nexport function stopSessionRunsTick(host: PollingHost) {\n if (host.sessionRunsTickInterval == null) {\n return;\n }\n clearInterval(host.sessionRunsTickInterval);\n host.sessionRunsTickInterval = null;\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { AgentIdentityResult } from \"../types.ts\";\n\nexport type AgentIdentityState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentIdentityLoading: boolean;\n agentIdentityError: string | null;\n agentIdentityById: Record<string, AgentIdentityResult>;\n};\n\nexport async function loadAgentIdentity(state: AgentIdentityState, agentId: string) {\n if (!state.client || !state.connected || state.agentIdentityLoading) {\n return;\n }\n if (state.agentIdentityById[agentId]) {\n return;\n }\n state.agentIdentityLoading = true;\n state.agentIdentityError = null;\n try {\n const res = await state.client.request<AgentIdentityResult | null>(\"agent.identity.get\", {\n agentId,\n });\n if (res) {\n state.agentIdentityById = { ...state.agentIdentityById, [agentId]: res };\n }\n } catch (err) {\n state.agentIdentityError = String(err);\n } finally {\n state.agentIdentityLoading = false;\n }\n}\n\nexport async function loadAgentIdentities(state: AgentIdentityState, agentIds: string[]) {\n if (!state.client || !state.connected || state.agentIdentityLoading) {\n return;\n }\n const missing = agentIds.filter((id) => !state.agentIdentityById[id]);\n if (missing.length === 0) {\n return;\n }\n state.agentIdentityLoading = true;\n state.agentIdentityError = null;\n try {\n for (const agentId of missing) {\n const res = await state.client.request<AgentIdentityResult | null>(\"agent.identity.get\", {\n agentId,\n });\n if (res) {\n state.agentIdentityById = { ...state.agentIdentityById, [agentId]: res };\n }\n }\n } catch (err) {\n state.agentIdentityError = String(err);\n } finally {\n state.agentIdentityLoading = false;\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { SkillStatusReport } from \"../types.ts\";\n\nexport type AgentSkillsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentSkillsLoading: boolean;\n agentSkillsError: string | null;\n agentSkillsReport: SkillStatusReport | null;\n agentSkillsAgentId: string | null;\n};\n\nexport async function loadAgentSkills(state: AgentSkillsState, agentId: string) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.agentSkillsLoading) {\n return;\n }\n state.agentSkillsLoading = true;\n state.agentSkillsError = null;\n try {\n const res = await state.client.request(\"skills.status\", { agentId });\n if (res) {\n state.agentSkillsReport = res as SkillStatusReport;\n state.agentSkillsAgentId = agentId;\n }\n } catch (err) {\n state.agentSkillsError = String(err);\n } finally {\n state.agentSkillsLoading = false;\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { AgentsListResult, ToolsCatalogResult } from \"../types.ts\";\n\nexport type AgentsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentsLoading: boolean;\n agentsError: string | null;\n agentsList: AgentsListResult | null;\n agentsSelectedId: string | null;\n toolsCatalogLoading: boolean;\n toolsCatalogError: string | null;\n toolsCatalogResult: ToolsCatalogResult | null;\n};\n\nexport async function loadAgents(state: AgentsState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.agentsLoading) {\n return;\n }\n state.agentsLoading = true;\n state.agentsError = null;\n try {\n const res = await state.client.request<AgentsListResult>(\"agents.list\", {});\n if (res) {\n state.agentsList = res;\n const selected = state.agentsSelectedId;\n const known = res.agents.some((entry) => entry.id === selected);\n if (!selected || !known) {\n state.agentsSelectedId = res.defaultId ?? res.agents[0]?.id ?? null;\n }\n }\n } catch (err) {\n state.agentsError = String(err);\n } finally {\n state.agentsLoading = false;\n }\n}\n\nexport async function loadToolsCatalog(state: AgentsState, agentId?: string | null) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.toolsCatalogLoading) {\n return;\n }\n state.toolsCatalogLoading = true;\n state.toolsCatalogError = null;\n try {\n const res = await state.client.request<ToolsCatalogResult>(\"tools.catalog\", {\n agentId: agentId ?? state.agentsSelectedId ?? undefined,\n includePlugins: true,\n });\n if (res) {\n state.toolsCatalogResult = res;\n }\n } catch (err) {\n state.toolsCatalogError = String(err);\n } finally {\n state.toolsCatalogLoading = false;\n }\n}\n\nexport async function nudgeAgent(state: AgentsState, agentId: string, text: string) {\n if (!state.client || !state.connected) {\n return;\n }\n const trimmed = text.trim();\n if (!trimmed) {\n return;\n }\n try {\n await state.client.request(\"agent.nudge\", { agentId, text: trimmed });\n } catch (err) {\n state.agentsError = String(err);\n }\n}\n","import { clearDeviceAuthToken, storeDeviceAuthToken } from \"../device-auth.ts\";\nimport { loadOrCreateDeviceIdentity } from \"../device-identity.ts\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\n\nexport type DeviceTokenSummary = {\n role: string;\n scopes?: string[];\n createdAtMs?: number;\n rotatedAtMs?: number;\n revokedAtMs?: number;\n lastUsedAtMs?: number;\n};\n\nexport type PendingDevice = {\n requestId: string;\n deviceId: string;\n displayName?: string;\n role?: string;\n remoteIp?: string;\n isRepair?: boolean;\n ts?: number;\n};\n\nexport type PairedDevice = {\n deviceId: string;\n displayName?: string;\n roles?: string[];\n scopes?: string[];\n remoteIp?: string;\n tokens?: DeviceTokenSummary[];\n createdAtMs?: number;\n approvedAtMs?: number;\n};\n\nexport type DevicePairingList = {\n pending: PendingDevice[];\n paired: PairedDevice[];\n};\n\nexport type DevicesState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n devicesLoading: boolean;\n devicesError: string | null;\n devicesList: DevicePairingList | null;\n};\n\nexport async function loadDevices(state: DevicesState, opts?: { quiet?: boolean }) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.devicesLoading) {\n return;\n }\n state.devicesLoading = true;\n if (!opts?.quiet) {\n state.devicesError = null;\n }\n try {\n const res = await state.client.request<{\n pending?: Array<PendingDevice>;\n paired?: Array<PendingDevice>;\n }>(\"device.pair.list\", {});\n state.devicesList = {\n pending: Array.isArray(res?.pending) ? res.pending : [],\n paired: Array.isArray(res?.paired) ? res.paired : [],\n };\n } catch (err) {\n if (!opts?.quiet) {\n state.devicesError = String(err);\n }\n } finally {\n state.devicesLoading = false;\n }\n}\n\nexport async function approveDevicePairing(state: DevicesState, requestId: string) {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n await state.client.request(\"device.pair.approve\", { requestId });\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function rejectDevicePairing(state: DevicesState, requestId: string) {\n if (!state.client || !state.connected) {\n return;\n }\n const confirmed = window.confirm(\"Reject this device pairing request?\");\n if (!confirmed) {\n return;\n }\n try {\n await state.client.request(\"device.pair.reject\", { requestId });\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function rotateDeviceToken(\n state: DevicesState,\n params: { deviceId: string; role: string; scopes?: string[] },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<{\n token: string;\n role?: string;\n deviceId?: string;\n scopes?: Array<string>;\n }>(\"device.token.rotate\", params);\n if (res?.token) {\n const identity = await loadOrCreateDeviceIdentity();\n const role = res.role ?? params.role;\n if (res.deviceId === identity.deviceId || params.deviceId === identity.deviceId) {\n storeDeviceAuthToken({\n deviceId: identity.deviceId,\n role,\n token: res.token,\n scopes: res.scopes ?? params.scopes ?? [],\n });\n }\n window.prompt(\"New device token (copy and store securely):\", res.token);\n }\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n\nexport async function revokeDeviceToken(\n state: DevicesState,\n params: { deviceId: string; role: string },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n const confirmed = window.confirm(`Revoke token for ${params.deviceId} (${params.role})?`);\n if (!confirmed) {\n return;\n }\n try {\n await state.client.request(\"device.token.revoke\", params);\n const identity = await loadOrCreateDeviceIdentity();\n if (params.deviceId === identity.deviceId) {\n clearDeviceAuthToken({ deviceId: identity.deviceId, role: params.role });\n }\n await loadDevices(state);\n } catch (err) {\n state.devicesError = String(err);\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport { cloneConfigObject, removePathValue, setPathValue } from \"./config/form-utils.ts\";\n\nexport type ExecApprovalsDefaults = {\n security?: string;\n ask?: string;\n askFallback?: string;\n autoAllowSkills?: boolean;\n};\n\nexport type ExecApprovalsAllowlistEntry = {\n id?: string;\n pattern: string;\n lastUsedAt?: number;\n lastUsedCommand?: string;\n lastResolvedPath?: string;\n};\n\nexport type ExecApprovalsAgent = ExecApprovalsDefaults & {\n allowlist?: ExecApprovalsAllowlistEntry[];\n};\n\nexport type ExecApprovalsFile = {\n version?: number;\n socket?: { path?: string };\n defaults?: ExecApprovalsDefaults;\n agents?: Record<string, ExecApprovalsAgent>;\n};\n\nexport type ExecApprovalsSnapshot = {\n path: string;\n exists: boolean;\n hash: string;\n file: ExecApprovalsFile;\n};\n\nexport type ExecApprovalsTarget = { kind: \"gateway\" } | { kind: \"node\"; nodeId: string };\n\nexport type ExecApprovalsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n execApprovalsLoading: boolean;\n execApprovalsSaving: boolean;\n execApprovalsDirty: boolean;\n execApprovalsSnapshot: ExecApprovalsSnapshot | null;\n execApprovalsForm: ExecApprovalsFile | null;\n execApprovalsSelectedAgent: string | null;\n lastError: string | null;\n};\n\nfunction resolveExecApprovalsRpc(target?: ExecApprovalsTarget | null): {\n method: string;\n params: Record<string, unknown>;\n} | null {\n if (!target || target.kind === \"gateway\") {\n return { method: \"exec.approvals.get\", params: {} };\n }\n const nodeId = target.nodeId.trim();\n if (!nodeId) {\n return null;\n }\n return { method: \"exec.approvals.node.get\", params: { nodeId } };\n}\n\nfunction resolveExecApprovalsSaveRpc(\n target: ExecApprovalsTarget | null | undefined,\n params: { file: ExecApprovalsFile; baseHash: string },\n): { method: string; params: Record<string, unknown> } | null {\n if (!target || target.kind === \"gateway\") {\n return { method: \"exec.approvals.set\", params };\n }\n const nodeId = target.nodeId.trim();\n if (!nodeId) {\n return null;\n }\n return { method: \"exec.approvals.node.set\", params: { ...params, nodeId } };\n}\n\nexport async function loadExecApprovals(\n state: ExecApprovalsState,\n target?: ExecApprovalsTarget | null,\n) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.execApprovalsLoading) {\n return;\n }\n state.execApprovalsLoading = true;\n state.lastError = null;\n try {\n const rpc = resolveExecApprovalsRpc(target);\n if (!rpc) {\n state.lastError = \"Select a node before loading exec approvals.\";\n return;\n }\n const res = await state.client.request<ExecApprovalsSnapshot>(rpc.method, rpc.params);\n applyExecApprovalsSnapshot(state, res);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.execApprovalsLoading = false;\n }\n}\n\nexport function applyExecApprovalsSnapshot(\n state: ExecApprovalsState,\n snapshot: ExecApprovalsSnapshot,\n) {\n state.execApprovalsSnapshot = snapshot;\n if (!state.execApprovalsDirty) {\n state.execApprovalsForm = cloneConfigObject(snapshot.file ?? {});\n }\n}\n\nexport async function saveExecApprovals(\n state: ExecApprovalsState,\n target?: ExecApprovalsTarget | null,\n) {\n if (!state.client || !state.connected) {\n return;\n }\n state.execApprovalsSaving = true;\n state.lastError = null;\n try {\n const baseHash = state.execApprovalsSnapshot?.hash;\n if (!baseHash) {\n state.lastError = \"Exec approvals hash missing; reload and retry.\";\n return;\n }\n const file = state.execApprovalsForm ?? state.execApprovalsSnapshot?.file ?? {};\n const rpc = resolveExecApprovalsSaveRpc(target, { file, baseHash });\n if (!rpc) {\n state.lastError = \"Select a node before saving exec approvals.\";\n return;\n }\n await state.client.request(rpc.method, rpc.params);\n state.execApprovalsDirty = false;\n await loadExecApprovals(state, target);\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.execApprovalsSaving = false;\n }\n}\n\nexport function updateExecApprovalsFormValue(\n state: ExecApprovalsState,\n path: Array<string | number>,\n value: unknown,\n) {\n const base = cloneConfigObject(\n state.execApprovalsForm ?? state.execApprovalsSnapshot?.file ?? {},\n );\n setPathValue(base, path, value);\n state.execApprovalsForm = base;\n state.execApprovalsDirty = true;\n}\n\nexport function removeExecApprovalsFormValue(\n state: ExecApprovalsState,\n path: Array<string | number>,\n) {\n const base = cloneConfigObject(\n state.execApprovalsForm ?? state.execApprovalsSnapshot?.file ?? {},\n );\n removePathValue(base, path);\n state.execApprovalsForm = base;\n state.execApprovalsDirty = true;\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { PresenceEntry } from \"../types.ts\";\n\nexport type PresenceState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n presenceLoading: boolean;\n presenceEntries: PresenceEntry[];\n presenceError: string | null;\n presenceStatus: string | null;\n};\n\nexport async function loadPresence(state: PresenceState) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.presenceLoading) {\n return;\n }\n state.presenceLoading = true;\n state.presenceError = null;\n state.presenceStatus = null;\n try {\n const res = await state.client.request(\"system-presence\", {});\n if (Array.isArray(res)) {\n state.presenceEntries = res;\n state.presenceStatus = res.length === 0 ? \"No instances yet.\" : null;\n } else {\n state.presenceEntries = [];\n state.presenceStatus = \"No presence payload.\";\n }\n } catch (err) {\n state.presenceError = String(err);\n } finally {\n state.presenceLoading = false;\n }\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { SkillStatusReport } from \"../types.ts\";\n\nexport type SkillsState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n skillsLoading: boolean;\n skillsReport: SkillStatusReport | null;\n skillsError: string | null;\n skillsBusyKey: string | null;\n skillEdits: Record<string, string>;\n skillMessages: SkillMessageMap;\n};\n\nexport type SkillMessage = {\n kind: \"success\" | \"error\";\n message: string;\n};\n\nexport type SkillMessageMap = Record<string, SkillMessage>;\n\ntype LoadSkillsOptions = {\n clearMessages?: boolean;\n};\n\nfunction setSkillMessage(state: SkillsState, key: string, message?: SkillMessage) {\n if (!key.trim()) {\n return;\n }\n const next = { ...state.skillMessages };\n if (message) {\n next[key] = message;\n } else {\n delete next[key];\n }\n state.skillMessages = next;\n}\n\nfunction getErrorMessage(err: unknown) {\n if (err instanceof Error) {\n return err.message;\n }\n return String(err);\n}\n\nexport async function loadSkills(state: SkillsState, options?: LoadSkillsOptions) {\n if (options?.clearMessages && Object.keys(state.skillMessages).length > 0) {\n state.skillMessages = {};\n }\n if (!state.client || !state.connected) {\n return;\n }\n if (state.skillsLoading) {\n return;\n }\n state.skillsLoading = true;\n state.skillsError = null;\n try {\n const res = await state.client.request<SkillStatusReport | undefined>(\"skills.status\", {});\n if (res) {\n state.skillsReport = res;\n }\n } catch (err) {\n state.skillsError = getErrorMessage(err);\n } finally {\n state.skillsLoading = false;\n }\n}\n\nexport function updateSkillEdit(state: SkillsState, skillKey: string, value: string) {\n state.skillEdits = { ...state.skillEdits, [skillKey]: value };\n}\n\nexport async function updateSkillEnabled(state: SkillsState, skillKey: string, enabled: boolean) {\n if (!state.client || !state.connected) {\n return;\n }\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n await state.client.request(\"skills.update\", { skillKey, enabled });\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: enabled ? \"Skill enabled\" : \"Skill disabled\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n\nexport async function saveSkillApiKey(state: SkillsState, skillKey: string) {\n if (!state.client || !state.connected) {\n return;\n }\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n const apiKey = state.skillEdits[skillKey] ?? \"\";\n await state.client.request(\"skills.update\", { skillKey, apiKey });\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: \"API key saved\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n\nexport async function installSkill(\n state: SkillsState,\n skillKey: string,\n name: string,\n installId: string,\n) {\n if (!state.client || !state.connected) {\n return;\n }\n state.skillsBusyKey = skillKey;\n state.skillsError = null;\n try {\n const result = await state.client.request<{ message?: string }>(\"skills.install\", {\n name,\n installId,\n timeoutMs: 120000,\n });\n await loadSkills(state);\n setSkillMessage(state, skillKey, {\n kind: \"success\",\n message: result?.message ?? \"Installed\",\n });\n } catch (err) {\n const message = getErrorMessage(err);\n state.skillsError = message;\n setSkillMessage(state, skillKey, {\n kind: \"error\",\n message,\n });\n } finally {\n state.skillsBusyKey = null;\n }\n}\n","const KEY = \"openclaw.control.settings.v1\";\n\nimport { isSupportedLocale } from \"../i18n/index.ts\";\nimport { inferBasePathFromPathname, normalizeBasePath } from \"./navigation.ts\";\nimport type { ThemeMode } from \"./theme.ts\";\n\nexport type UiSettings = {\n gatewayUrl: string;\n token: string;\n sessionKey: string;\n lastActiveSessionKey: string;\n theme: ThemeMode;\n chatFocusMode: boolean;\n chatShowThinking: boolean;\n splitRatio: number; // Sidebar split ratio (0.4 to 0.7, default 0.6)\n navCollapsed: boolean; // Collapsible sidebar state\n navGroupsCollapsed: Record<string, boolean>; // Which nav groups are collapsed\n locale?: string;\n};\n\nexport function loadSettings(): UiSettings {\n const defaultUrl = (() => {\n const proto = location.protocol === \"https:\" ? \"wss\" : \"ws\";\n const configured =\n typeof window !== \"undefined\" &&\n typeof window.__OPENCLAW_CONTROL_UI_BASE_PATH__ === \"string\" &&\n window.__OPENCLAW_CONTROL_UI_BASE_PATH__.trim();\n const basePath = configured\n ? normalizeBasePath(configured)\n : inferBasePathFromPathname(location.pathname);\n return `${proto}://${location.host}${basePath}`;\n })();\n\n const defaults: UiSettings = {\n gatewayUrl: defaultUrl,\n token: \"\",\n sessionKey: \"main\",\n lastActiveSessionKey: \"main\",\n theme: \"system\",\n chatFocusMode: false,\n chatShowThinking: true,\n splitRatio: 0.6,\n navCollapsed: false,\n navGroupsCollapsed: {},\n };\n\n try {\n const raw = localStorage.getItem(KEY);\n if (!raw) {\n return defaults;\n }\n const parsed = JSON.parse(raw) as Partial<UiSettings>;\n return {\n gatewayUrl:\n typeof parsed.gatewayUrl === \"string\" && parsed.gatewayUrl.trim()\n ? parsed.gatewayUrl.trim()\n : defaults.gatewayUrl,\n token: typeof parsed.token === \"string\" ? parsed.token : defaults.token,\n sessionKey:\n typeof parsed.sessionKey === \"string\" && parsed.sessionKey.trim()\n ? parsed.sessionKey.trim()\n : defaults.sessionKey,\n lastActiveSessionKey:\n typeof parsed.lastActiveSessionKey === \"string\" && parsed.lastActiveSessionKey.trim()\n ? parsed.lastActiveSessionKey.trim()\n : (typeof parsed.sessionKey === \"string\" && parsed.sessionKey.trim()) ||\n defaults.lastActiveSessionKey,\n theme:\n parsed.theme === \"light\" || parsed.theme === \"dark\" || parsed.theme === \"system\"\n ? parsed.theme\n : defaults.theme,\n chatFocusMode:\n typeof parsed.chatFocusMode === \"boolean\" ? parsed.chatFocusMode : defaults.chatFocusMode,\n chatShowThinking:\n typeof parsed.chatShowThinking === \"boolean\"\n ? parsed.chatShowThinking\n : defaults.chatShowThinking,\n splitRatio:\n typeof parsed.splitRatio === \"number\" &&\n parsed.splitRatio >= 0.4 &&\n parsed.splitRatio <= 0.7\n ? parsed.splitRatio\n : defaults.splitRatio,\n navCollapsed:\n typeof parsed.navCollapsed === \"boolean\" ? parsed.navCollapsed : defaults.navCollapsed,\n navGroupsCollapsed:\n typeof parsed.navGroupsCollapsed === \"object\" && parsed.navGroupsCollapsed !== null\n ? parsed.navGroupsCollapsed\n : defaults.navGroupsCollapsed,\n locale: isSupportedLocale(parsed.locale) ? parsed.locale : undefined,\n };\n } catch {\n return defaults;\n }\n}\n\nexport function saveSettings(next: UiSettings) {\n localStorage.setItem(KEY, JSON.stringify(next));\n}\n","import type { ThemeMode } from \"./theme.ts\";\n\nexport type ThemeTransitionContext = {\n element?: HTMLElement | null;\n pointerClientX?: number;\n pointerClientY?: number;\n};\n\nexport type ThemeTransitionOptions = {\n nextTheme: ThemeMode;\n applyTheme: () => void;\n context?: ThemeTransitionContext;\n currentTheme?: ThemeMode | null;\n};\n\ntype DocumentWithViewTransition = Document & {\n startViewTransition?: (callback: () => void) => { finished: Promise<void> };\n};\n\nconst clamp01 = (value: number) => {\n if (Number.isNaN(value)) {\n return 0.5;\n }\n if (value <= 0) {\n return 0;\n }\n if (value >= 1) {\n return 1;\n }\n return value;\n};\n\nconst hasReducedMotionPreference = () => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n};\n\nconst cleanupThemeTransition = (root: HTMLElement) => {\n root.classList.remove(\"theme-transition\");\n root.style.removeProperty(\"--theme-switch-x\");\n root.style.removeProperty(\"--theme-switch-y\");\n};\n\nexport const startThemeTransition = ({\n nextTheme,\n applyTheme,\n context,\n currentTheme,\n}: ThemeTransitionOptions) => {\n if (currentTheme === nextTheme) {\n return;\n }\n\n const documentReference = globalThis.document ?? null;\n if (!documentReference) {\n applyTheme();\n return;\n }\n\n const root = documentReference.documentElement;\n const document_ = documentReference as DocumentWithViewTransition;\n const prefersReducedMotion = hasReducedMotionPreference();\n\n const canUseViewTransition = Boolean(document_.startViewTransition) && !prefersReducedMotion;\n\n if (canUseViewTransition) {\n let xPercent = 0.5;\n let yPercent = 0.5;\n\n if (\n context?.pointerClientX !== undefined &&\n context?.pointerClientY !== undefined &&\n typeof window !== \"undefined\"\n ) {\n xPercent = clamp01(context.pointerClientX / window.innerWidth);\n yPercent = clamp01(context.pointerClientY / window.innerHeight);\n } else if (context?.element) {\n const rect = context.element.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0 && typeof window !== \"undefined\") {\n xPercent = clamp01((rect.left + rect.width / 2) / window.innerWidth);\n yPercent = clamp01((rect.top + rect.height / 2) / window.innerHeight);\n }\n }\n\n root.style.setProperty(\"--theme-switch-x\", `${xPercent * 100}%`);\n root.style.setProperty(\"--theme-switch-y\", `${yPercent * 100}%`);\n root.classList.add(\"theme-transition\");\n\n try {\n const transition = document_.startViewTransition?.(() => {\n applyTheme();\n });\n if (transition?.finished) {\n void transition.finished.finally(() => cleanupThemeTransition(root));\n } else {\n cleanupThemeTransition(root);\n }\n } catch {\n cleanupThemeTransition(root);\n applyTheme();\n }\n return;\n }\n\n applyTheme();\n cleanupThemeTransition(root);\n};\n","export type ThemeMode = \"system\" | \"light\" | \"dark\";\nexport type ResolvedTheme = \"light\" | \"dark\";\n\nexport function getSystemTheme(): ResolvedTheme {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return \"dark\";\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n}\n\nexport function resolveTheme(mode: ThemeMode): ResolvedTheme {\n if (mode === \"system\") {\n return getSystemTheme();\n }\n return mode;\n}\n","import { refreshChat } from \"./app-chat.ts\";\nimport {\n startLogsPolling,\n stopLogsPolling,\n startDebugPolling,\n stopDebugPolling,\n} from \"./app-polling.ts\";\nimport { scheduleChatScroll, scheduleLogsScroll } from \"./app-scroll.ts\";\nimport type { OpenClawApp } from \"./app.ts\";\nimport { loadAgentIdentities, loadAgentIdentity } from \"./controllers/agent-identity.ts\";\nimport { loadAgentSkills } from \"./controllers/agent-skills.ts\";\nimport { loadAgents, loadToolsCatalog } from \"./controllers/agents.ts\";\nimport { loadChannels } from \"./controllers/channels.ts\";\nimport { loadConfig, loadConfigSchema } from \"./controllers/config.ts\";\nimport {\n loadCronJobs,\n loadCronModelSuggestions,\n loadCronRuns,\n loadCronStatus,\n} from \"./controllers/cron.ts\";\nimport { loadDebug } from \"./controllers/debug.ts\";\nimport { loadDevices } from \"./controllers/devices.ts\";\nimport { loadDreams, type DreamsHost } from \"./controllers/dreams.ts\";\nimport { loadExecApprovals } from \"./controllers/exec-approvals.ts\";\nimport { loadLogs } from \"./controllers/logs.ts\";\nimport { loadNodes } from \"./controllers/nodes.ts\";\nimport { loadPresence } from \"./controllers/presence.ts\";\nimport { loadSessionRuns, loadSessionThresholds, loadSessions } from \"./controllers/sessions.ts\";\nimport { loadSkills } from \"./controllers/skills.ts\";\nimport type { TalkController } from \"./controllers/talk.ts\";\nimport {\n inferBasePathFromPathname,\n normalizeBasePath,\n normalizePath,\n pathForTab,\n tabFromPath,\n type Tab,\n} from \"./navigation.ts\";\nimport { saveSettings, type UiSettings } from \"./storage.ts\";\nimport { startThemeTransition, type ThemeTransitionContext } from \"./theme-transition.ts\";\nimport { resolveTheme, type ResolvedTheme, type ThemeMode } from \"./theme.ts\";\nimport type { AgentsListResult } from \"./types.ts\";\n\ntype SettingsHost = {\n settings: UiSettings;\n password?: string;\n theme: ThemeMode;\n themeResolved: ResolvedTheme;\n applySessionKey: string;\n sessionKey: string;\n tab: Tab;\n connected: boolean;\n chatHasAutoScrolled: boolean;\n logsAtBottom: boolean;\n eventLog: unknown[];\n eventLogBuffer: unknown[];\n basePath: string;\n agentsList?: AgentsListResult | null;\n agentsSelectedId?: string | null;\n agentsPanel?: \"overview\" | \"files\" | \"tools\" | \"skills\" | \"channels\" | \"cron\";\n themeMedia: MediaQueryList | null;\n themeMediaHandler: ((event: MediaQueryListEvent) => void) | null;\n pendingGatewayUrl?: string | null;\n talkController: Pick<TalkController, \"stop\">;\n};\n\nexport function applySettings(host: SettingsHost, next: UiSettings) {\n const normalized = {\n ...next,\n lastActiveSessionKey: next.lastActiveSessionKey?.trim() || next.sessionKey.trim() || \"main\",\n };\n host.settings = normalized;\n saveSettings(normalized);\n if (next.theme !== host.theme) {\n host.theme = next.theme;\n applyResolvedTheme(host, resolveTheme(next.theme));\n }\n host.applySessionKey = host.settings.lastActiveSessionKey;\n}\n\nexport function setLastActiveSessionKey(host: SettingsHost, next: string) {\n const trimmed = next.trim();\n if (!trimmed) {\n return;\n }\n if (host.settings.lastActiveSessionKey === trimmed) {\n return;\n }\n applySettings(host, { ...host.settings, lastActiveSessionKey: trimmed });\n}\n\nexport function applySettingsFromUrl(host: SettingsHost) {\n if (!window.location.search && !window.location.hash) {\n return;\n }\n const url = new URL(window.location.href);\n const params = new URLSearchParams(url.search);\n const hashParams = new URLSearchParams(url.hash.startsWith(\"#\") ? url.hash.slice(1) : url.hash);\n\n const tokenRaw = params.get(\"token\") ?? hashParams.get(\"token\");\n const passwordRaw = params.get(\"password\") ?? hashParams.get(\"password\");\n const sessionRaw = params.get(\"session\") ?? hashParams.get(\"session\");\n const gatewayUrlRaw = params.get(\"gatewayUrl\") ?? hashParams.get(\"gatewayUrl\");\n let shouldCleanUrl = false;\n\n if (tokenRaw != null) {\n const token = tokenRaw.trim();\n if (token && token !== host.settings.token) {\n applySettings(host, { ...host.settings, token });\n }\n params.delete(\"token\");\n hashParams.delete(\"token\");\n shouldCleanUrl = true;\n }\n\n if (passwordRaw != null) {\n // Never hydrate password from URL params; strip only.\n params.delete(\"password\");\n hashParams.delete(\"password\");\n shouldCleanUrl = true;\n }\n\n if (sessionRaw != null) {\n const session = sessionRaw.trim();\n if (session) {\n host.sessionKey = session;\n applySettings(host, {\n ...host.settings,\n sessionKey: session,\n lastActiveSessionKey: session,\n });\n }\n }\n\n if (gatewayUrlRaw != null) {\n const gatewayUrl = gatewayUrlRaw.trim();\n if (gatewayUrl && gatewayUrl !== host.settings.gatewayUrl) {\n host.pendingGatewayUrl = gatewayUrl;\n }\n params.delete(\"gatewayUrl\");\n hashParams.delete(\"gatewayUrl\");\n shouldCleanUrl = true;\n }\n\n if (!shouldCleanUrl) {\n return;\n }\n url.search = params.toString();\n const nextHash = hashParams.toString();\n url.hash = nextHash ? `#${nextHash}` : \"\";\n window.history.replaceState({}, \"\", url.toString());\n}\n\nexport function setTab(host: SettingsHost, next: Tab) {\n applyTabSelection(host, next, { refreshPolicy: \"always\", syncUrl: true });\n}\n\nexport function setTheme(host: SettingsHost, next: ThemeMode, context?: ThemeTransitionContext) {\n const applyTheme = () => {\n host.theme = next;\n applySettings(host, { ...host.settings, theme: next });\n applyResolvedTheme(host, resolveTheme(next));\n };\n startThemeTransition({\n nextTheme: next,\n applyTheme,\n context,\n currentTheme: host.theme,\n });\n}\n\nexport async function refreshActiveTab(host: SettingsHost) {\n if (host.tab === \"overview\") {\n await loadOverview(host);\n }\n if (host.tab === \"channels\") {\n await loadChannelsTab(host);\n }\n if (host.tab === \"instances\") {\n await loadPresence(host as unknown as OpenClawApp);\n }\n if (host.tab === \"sessions\") {\n await loadSessions(host as unknown as OpenClawApp);\n void loadSessionRuns(host as unknown as OpenClawApp);\n void loadSessionThresholds(host as unknown as OpenClawApp);\n }\n if (host.tab === \"cron\") {\n await loadCron(host);\n }\n if (host.tab === \"learning\") {\n await (host as unknown as OpenClawApp).loadLearning();\n }\n if (host.tab === \"dreams\") {\n await loadDreams(host as unknown as DreamsHost);\n }\n if (host.tab === \"skills\") {\n await loadSkills(host as unknown as OpenClawApp);\n }\n if (host.tab === \"agents\") {\n await loadAgents(host as unknown as OpenClawApp);\n await loadToolsCatalog(host as unknown as OpenClawApp);\n await loadConfig(host as unknown as OpenClawApp);\n const agentIds = host.agentsList?.agents?.map((entry) => entry.id) ?? [];\n if (agentIds.length > 0) {\n void loadAgentIdentities(host as unknown as OpenClawApp, agentIds);\n }\n const agentId =\n host.agentsSelectedId ?? host.agentsList?.defaultId ?? host.agentsList?.agents?.[0]?.id;\n if (agentId) {\n void loadAgentIdentity(host as unknown as OpenClawApp, agentId);\n if (host.agentsPanel === \"skills\") {\n void loadAgentSkills(host as unknown as OpenClawApp, agentId);\n }\n if (host.agentsPanel === \"channels\") {\n void loadChannels(host as unknown as OpenClawApp, false);\n }\n if (host.agentsPanel === \"cron\") {\n void loadCron(host);\n }\n }\n }\n if (host.tab === \"nodes\") {\n await loadNodes(host as unknown as OpenClawApp);\n await loadDevices(host as unknown as OpenClawApp);\n await loadConfig(host as unknown as OpenClawApp);\n await loadExecApprovals(host as unknown as OpenClawApp);\n }\n if (host.tab === \"chat\") {\n await refreshChat(host as unknown as Parameters<typeof refreshChat>[0]);\n scheduleChatScroll(\n host as unknown as Parameters<typeof scheduleChatScroll>[0],\n !host.chatHasAutoScrolled,\n );\n }\n if (host.tab === \"config\") {\n await loadConfigSchema(host as unknown as OpenClawApp);\n await loadConfig(host as unknown as OpenClawApp);\n }\n if (host.tab === \"debug\") {\n await loadDebug(host as unknown as OpenClawApp);\n host.eventLog = host.eventLogBuffer;\n }\n if (host.tab === \"logs\") {\n host.logsAtBottom = true;\n await loadLogs(host as unknown as OpenClawApp, { reset: true });\n scheduleLogsScroll(host as unknown as Parameters<typeof scheduleLogsScroll>[0], true);\n }\n}\n\nexport function inferBasePath() {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n const configured = window.__OPENCLAW_CONTROL_UI_BASE_PATH__;\n if (typeof configured === \"string\" && configured.trim()) {\n return normalizeBasePath(configured);\n }\n return inferBasePathFromPathname(window.location.pathname);\n}\n\nexport function syncThemeWithSettings(host: SettingsHost) {\n host.theme = host.settings.theme ?? \"system\";\n applyResolvedTheme(host, resolveTheme(host.theme));\n}\n\nexport function applyResolvedTheme(host: SettingsHost, resolved: ResolvedTheme) {\n host.themeResolved = resolved;\n if (typeof document === \"undefined\") {\n return;\n }\n const root = document.documentElement;\n root.dataset.theme = resolved;\n root.style.colorScheme = resolved;\n}\n\nexport function attachThemeListener(host: SettingsHost) {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return;\n }\n host.themeMedia = window.matchMedia(\"(prefers-color-scheme: dark)\");\n host.themeMediaHandler = (event) => {\n if (host.theme !== \"system\") {\n return;\n }\n applyResolvedTheme(host, event.matches ? \"dark\" : \"light\");\n };\n if (typeof host.themeMedia.addEventListener === \"function\") {\n host.themeMedia.addEventListener(\"change\", host.themeMediaHandler);\n return;\n }\n const legacy = host.themeMedia as MediaQueryList & {\n addListener: (cb: (event: MediaQueryListEvent) => void) => void;\n };\n legacy.addListener(host.themeMediaHandler);\n}\n\nexport function detachThemeListener(host: SettingsHost) {\n if (!host.themeMedia || !host.themeMediaHandler) {\n return;\n }\n if (typeof host.themeMedia.removeEventListener === \"function\") {\n host.themeMedia.removeEventListener(\"change\", host.themeMediaHandler);\n return;\n }\n const legacy = host.themeMedia as MediaQueryList & {\n removeListener: (cb: (event: MediaQueryListEvent) => void) => void;\n };\n legacy.removeListener(host.themeMediaHandler);\n host.themeMedia = null;\n host.themeMediaHandler = null;\n}\n\nexport function syncTabWithLocation(host: SettingsHost, replace: boolean) {\n if (typeof window === \"undefined\") {\n return;\n }\n const resolved = tabFromPath(window.location.pathname, host.basePath) ?? \"overview\";\n setTabFromRoute(host, resolved);\n syncUrlWithTab(host, resolved, replace);\n}\n\nexport function onPopState(host: SettingsHost) {\n if (typeof window === \"undefined\") {\n return;\n }\n const resolved = tabFromPath(window.location.pathname, host.basePath);\n if (!resolved) {\n return;\n }\n\n const url = new URL(window.location.href);\n const session = url.searchParams.get(\"session\")?.trim();\n if (session) {\n host.sessionKey = session;\n applySettings(host, {\n ...host.settings,\n sessionKey: session,\n lastActiveSessionKey: session,\n });\n }\n\n setTabFromRoute(host, resolved);\n}\n\nexport function setTabFromRoute(host: SettingsHost, next: Tab) {\n applyTabSelection(host, next, { refreshPolicy: \"connected\" });\n}\n\nfunction applyTabSelection(\n host: SettingsHost,\n next: Tab,\n options: { refreshPolicy: \"always\" | \"connected\"; syncUrl?: boolean },\n) {\n if (host.tab === \"talk\" && next !== \"talk\") {\n try {\n host.talkController.stop().catch(() => undefined);\n } catch {\n // A misbehaving stop() may throw synchronously instead of rejecting;\n // the tab switch and reconciliation below must still run.\n }\n }\n if (host.tab !== next) {\n host.tab = next;\n }\n if (next === \"chat\") {\n host.chatHasAutoScrolled = false;\n }\n if (next === \"logs\") {\n startLogsPolling(host as unknown as Parameters<typeof startLogsPolling>[0]);\n } else {\n stopLogsPolling(host as unknown as Parameters<typeof stopLogsPolling>[0]);\n }\n if (next === \"debug\") {\n startDebugPolling(host as unknown as Parameters<typeof startDebugPolling>[0]);\n } else {\n stopDebugPolling(host as unknown as Parameters<typeof stopDebugPolling>[0]);\n }\n\n if (options.refreshPolicy === \"always\" || host.connected) {\n void refreshActiveTab(host);\n }\n\n if (options.syncUrl) {\n syncUrlWithTab(host, next, false);\n }\n}\n\nexport function syncUrlWithTab(host: SettingsHost, tab: Tab, replace: boolean) {\n if (typeof window === \"undefined\") {\n return;\n }\n const targetPath = normalizePath(pathForTab(tab, host.basePath));\n const currentPath = normalizePath(window.location.pathname);\n const baseRootPath = normalizeBasePath(host.basePath) || \"/\";\n const preserveOverviewRoot = tab === \"overview\" && currentPath === normalizePath(baseRootPath);\n const url = new URL(window.location.href);\n\n if (tab === \"chat\" && host.sessionKey) {\n url.searchParams.set(\"session\", host.sessionKey);\n } else {\n url.searchParams.delete(\"session\");\n }\n\n if (!preserveOverviewRoot && currentPath !== targetPath) {\n url.pathname = targetPath;\n }\n\n if (replace) {\n window.history.replaceState({}, \"\", url.toString());\n } else {\n window.history.pushState({}, \"\", url.toString());\n }\n}\n\nexport function syncUrlWithSessionKey(host: SettingsHost, sessionKey: string, replace: boolean) {\n if (typeof window === \"undefined\") {\n return;\n }\n const url = new URL(window.location.href);\n url.searchParams.set(\"session\", sessionKey);\n if (replace) {\n window.history.replaceState({}, \"\", url.toString());\n } else {\n window.history.pushState({}, \"\", url.toString());\n }\n}\n\nexport async function loadOverview(host: SettingsHost) {\n await Promise.all([\n loadChannels(host as unknown as OpenClawApp, false),\n loadPresence(host as unknown as OpenClawApp),\n loadSessions(host as unknown as OpenClawApp),\n loadCronStatus(host as unknown as OpenClawApp),\n loadDebug(host as unknown as OpenClawApp),\n ]);\n}\n\nexport async function loadChannelsTab(host: SettingsHost) {\n await Promise.all([\n loadChannels(host as unknown as OpenClawApp, true),\n loadConfigSchema(host as unknown as OpenClawApp),\n loadConfig(host as unknown as OpenClawApp),\n ]);\n}\n\nexport async function loadCron(host: SettingsHost) {\n const cronHost = host as unknown as OpenClawApp;\n await Promise.all([\n loadChannels(host as unknown as OpenClawApp, false),\n loadCronStatus(cronHost),\n loadCronJobs(cronHost),\n loadCronModelSuggestions(cronHost),\n ]);\n if (cronHost.cronRunsScope === \"all\") {\n await loadCronRuns(cronHost, null);\n return;\n }\n if (cronHost.cronRunsJobId) {\n await loadCronRuns(cronHost, cronHost.cronRunsJobId);\n }\n}\n","import { truncateText } from \"./format.ts\";\n\nconst TOOL_STREAM_LIMIT = 50;\nconst TOOL_STREAM_THROTTLE_MS = 80;\nconst TOOL_OUTPUT_CHAR_LIMIT = 120_000;\n\nexport type AgentEventPayload = {\n runId: string;\n seq: number;\n stream: string;\n ts: number;\n sessionKey?: string;\n data: Record<string, unknown>;\n};\n\nexport type ToolStreamEntry = {\n toolCallId: string;\n runId: string;\n sessionKey?: string;\n name: string;\n args?: unknown;\n output?: string;\n startedAt: number;\n updatedAt: number;\n message: Record<string, unknown>;\n};\n\ntype ToolStreamHost = {\n sessionKey: string;\n chatRunId: string | null;\n toolStreamById: Map<string, ToolStreamEntry>;\n toolStreamOrder: string[];\n chatToolMessages: Record<string, unknown>[];\n toolStreamSyncTimer: number | null;\n};\n\nfunction toTrimmedString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n}\n\nfunction resolveModelLabel(provider: unknown, model: unknown): string | null {\n const modelValue = toTrimmedString(model);\n if (!modelValue) {\n return null;\n }\n const providerValue = toTrimmedString(provider);\n if (providerValue) {\n const prefix = `${providerValue}/`;\n if (modelValue.toLowerCase().startsWith(prefix.toLowerCase())) {\n const trimmedModel = modelValue.slice(prefix.length).trim();\n if (trimmedModel) {\n return `${providerValue}/${trimmedModel}`;\n }\n }\n return `${providerValue}/${modelValue}`;\n }\n const slashIndex = modelValue.indexOf(\"/\");\n if (slashIndex > 0) {\n const p = modelValue.slice(0, slashIndex).trim();\n const m = modelValue.slice(slashIndex + 1).trim();\n if (p && m) {\n return `${p}/${m}`;\n }\n }\n return modelValue;\n}\n\ntype FallbackAttempt = {\n provider: string;\n model: string;\n reason: string;\n};\n\nfunction parseFallbackAttemptSummaries(value: unknown): string[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((entry) => toTrimmedString(entry))\n .filter((entry): entry is string => Boolean(entry));\n}\n\nfunction parseFallbackAttempts(value: unknown): FallbackAttempt[] {\n if (!Array.isArray(value)) {\n return [];\n }\n const out: FallbackAttempt[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\") {\n continue;\n }\n const item = entry as Record<string, unknown>;\n const provider = toTrimmedString(item.provider);\n const model = toTrimmedString(item.model);\n if (!provider || !model) {\n continue;\n }\n const reason =\n toTrimmedString(item.reason)?.replace(/_/g, \" \") ??\n toTrimmedString(item.code) ??\n (typeof item.status === \"number\" ? `HTTP ${item.status}` : null) ??\n toTrimmedString(item.error) ??\n \"error\";\n out.push({ provider, model, reason });\n }\n return out;\n}\n\nfunction extractToolOutputText(value: unknown): string | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.text === \"string\") {\n return record.text;\n }\n const content = record.content;\n if (!Array.isArray(content)) {\n return null;\n }\n const parts = content\n .map((item) => {\n if (!item || typeof item !== \"object\") {\n return null;\n }\n const entry = item as Record<string, unknown>;\n if (entry.type === \"text\" && typeof entry.text === \"string\") {\n return entry.text;\n }\n return null;\n })\n .filter((part): part is string => Boolean(part));\n if (parts.length === 0) {\n return null;\n }\n return parts.join(\"\\n\");\n}\n\nfunction formatToolOutput(value: unknown): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n const contentText = extractToolOutputText(value);\n let text: string;\n if (typeof value === \"string\") {\n text = value;\n } else if (contentText) {\n text = contentText;\n } else {\n try {\n text = JSON.stringify(value, null, 2);\n } catch {\n // oxlint-disable typescript/no-base-to-string\n text = String(value);\n }\n }\n const truncated = truncateText(text, TOOL_OUTPUT_CHAR_LIMIT);\n if (!truncated.truncated) {\n return truncated.text;\n }\n return `${truncated.text}\\n\\n… truncated (${truncated.total} chars, showing first ${truncated.text.length}).`;\n}\n\nfunction buildToolStreamMessage(entry: ToolStreamEntry): Record<string, unknown> {\n const content: Array<Record<string, unknown>> = [];\n content.push({\n type: \"toolcall\",\n name: entry.name,\n arguments: entry.args ?? {},\n });\n if (entry.output) {\n content.push({\n type: \"toolresult\",\n name: entry.name,\n text: entry.output,\n });\n }\n return {\n role: \"assistant\",\n toolCallId: entry.toolCallId,\n runId: entry.runId,\n content,\n timestamp: entry.startedAt,\n };\n}\n\nfunction trimToolStream(host: ToolStreamHost) {\n if (host.toolStreamOrder.length <= TOOL_STREAM_LIMIT) {\n return;\n }\n const overflow = host.toolStreamOrder.length - TOOL_STREAM_LIMIT;\n const removed = host.toolStreamOrder.splice(0, overflow);\n for (const id of removed) {\n host.toolStreamById.delete(id);\n }\n}\n\nfunction syncToolStreamMessages(host: ToolStreamHost) {\n host.chatToolMessages = host.toolStreamOrder\n .map((id) => host.toolStreamById.get(id)?.message)\n .filter((msg): msg is Record<string, unknown> => Boolean(msg));\n}\n\nexport function flushToolStreamSync(host: ToolStreamHost) {\n if (host.toolStreamSyncTimer != null) {\n clearTimeout(host.toolStreamSyncTimer);\n host.toolStreamSyncTimer = null;\n }\n syncToolStreamMessages(host);\n}\n\nexport function scheduleToolStreamSync(host: ToolStreamHost, force = false) {\n if (force) {\n flushToolStreamSync(host);\n return;\n }\n if (host.toolStreamSyncTimer != null) {\n return;\n }\n host.toolStreamSyncTimer = window.setTimeout(\n () => flushToolStreamSync(host),\n TOOL_STREAM_THROTTLE_MS,\n );\n}\n\nexport function resetToolStream(host: ToolStreamHost) {\n host.toolStreamById.clear();\n host.toolStreamOrder = [];\n host.chatToolMessages = [];\n flushToolStreamSync(host);\n}\n\nexport type CompactionStatus = {\n active: boolean;\n startedAt: number | null;\n completedAt: number | null;\n /** The compaction ended without a successful result (failed or canceled). */\n failed: boolean;\n};\n\nexport type FallbackStatus = {\n phase?: \"active\" | \"cleared\";\n selected: string;\n active: string;\n previous?: string;\n reason?: string;\n attempts: string[];\n occurredAt: number;\n};\n\ntype CompactionHost = ToolStreamHost & {\n compactionStatus?: CompactionStatus | null;\n compactionClearTimer?: number | null;\n fallbackStatus?: FallbackStatus | null;\n fallbackClearTimer?: number | null;\n};\n\nconst COMPACTION_TOAST_DURATION_MS = 5000;\nconst FALLBACK_TOAST_DURATION_MS = 8000;\n\nexport function handleCompactionEvent(host: CompactionHost, payload: AgentEventPayload) {\n const data = payload.data ?? {};\n const phase = typeof data.phase === \"string\" ? data.phase : \"\";\n\n // Clear any existing timer\n if (host.compactionClearTimer != null) {\n window.clearTimeout(host.compactionClearTimer);\n host.compactionClearTimer = null;\n }\n\n if (phase === \"start\") {\n host.compactionStatus = {\n active: true,\n startedAt: Date.now(),\n completedAt: null,\n failed: false,\n };\n } else if (phase === \"end\") {\n // A failed/canceled compaction shares the \"end\" phase; only the completed\n // flag distinguishes it, so the indicator must not claim success.\n const failed = data.completed === false;\n host.compactionStatus = {\n active: false,\n startedAt: host.compactionStatus?.startedAt ?? null,\n completedAt: Date.now(),\n failed,\n };\n // Auto-clear the toast after duration\n host.compactionClearTimer = window.setTimeout(() => {\n host.compactionStatus = null;\n host.compactionClearTimer = null;\n }, COMPACTION_TOAST_DURATION_MS);\n }\n}\n\nfunction resolveAcceptedSession(\n host: ToolStreamHost,\n payload: AgentEventPayload,\n options?: {\n allowSessionScopedWhenIdle?: boolean;\n },\n): { accepted: boolean; sessionKey?: string } {\n const sessionKey = typeof payload.sessionKey === \"string\" ? payload.sessionKey : undefined;\n if (sessionKey && sessionKey !== host.sessionKey) {\n return { accepted: false };\n }\n if (!host.chatRunId && options?.allowSessionScopedWhenIdle && sessionKey) {\n return { accepted: true, sessionKey };\n }\n // Fallback: only accept session-less events for the active run.\n if (!sessionKey && host.chatRunId && payload.runId !== host.chatRunId) {\n return { accepted: false };\n }\n if (host.chatRunId && payload.runId !== host.chatRunId) {\n return { accepted: false };\n }\n if (!host.chatRunId) {\n return { accepted: false };\n }\n return { accepted: true, sessionKey };\n}\n\nfunction handleLifecycleFallbackEvent(host: CompactionHost, payload: AgentEventPayload) {\n const data = payload.data ?? {};\n const phase = payload.stream === \"fallback\" ? \"fallback\" : toTrimmedString(data.phase);\n if (payload.stream === \"lifecycle\" && phase !== \"fallback\" && phase !== \"fallback_cleared\") {\n return;\n }\n\n const accepted = resolveAcceptedSession(host, payload, { allowSessionScopedWhenIdle: true });\n if (!accepted.accepted) {\n return;\n }\n\n const selected =\n resolveModelLabel(data.selectedProvider, data.selectedModel) ??\n resolveModelLabel(data.fromProvider, data.fromModel);\n const active =\n resolveModelLabel(data.activeProvider, data.activeModel) ??\n resolveModelLabel(data.toProvider, data.toModel);\n const previous =\n resolveModelLabel(data.previousActiveProvider, data.previousActiveModel) ??\n toTrimmedString(data.previousActiveModel);\n if (!selected || !active) {\n return;\n }\n if (phase === \"fallback\" && selected === active) {\n return;\n }\n\n const reason = toTrimmedString(data.reasonSummary) ?? toTrimmedString(data.reason);\n const attempts = (() => {\n const summaries = parseFallbackAttemptSummaries(data.attemptSummaries);\n if (summaries.length > 0) {\n return summaries;\n }\n return parseFallbackAttempts(data.attempts).map((attempt) => {\n const modelRef = resolveModelLabel(attempt.provider, attempt.model);\n return `${modelRef ?? `${attempt.provider}/${attempt.model}`}: ${attempt.reason}`;\n });\n })();\n\n if (host.fallbackClearTimer != null) {\n window.clearTimeout(host.fallbackClearTimer);\n host.fallbackClearTimer = null;\n }\n host.fallbackStatus = {\n phase: phase === \"fallback_cleared\" ? \"cleared\" : \"active\",\n selected,\n active: phase === \"fallback_cleared\" ? selected : active,\n previous:\n phase === \"fallback_cleared\"\n ? (previous ?? (active !== selected ? active : undefined))\n : undefined,\n reason: reason ?? undefined,\n attempts,\n occurredAt: Date.now(),\n };\n host.fallbackClearTimer = window.setTimeout(() => {\n host.fallbackStatus = null;\n host.fallbackClearTimer = null;\n }, FALLBACK_TOAST_DURATION_MS);\n}\n\nexport function handleAgentEvent(host: ToolStreamHost, payload?: AgentEventPayload) {\n if (!payload) {\n return;\n }\n\n // Handle compaction events\n if (payload.stream === \"compaction\") {\n handleCompactionEvent(host as CompactionHost, payload);\n return;\n }\n\n if (payload.stream === \"lifecycle\" || payload.stream === \"fallback\") {\n handleLifecycleFallbackEvent(host as CompactionHost, payload);\n return;\n }\n\n if (payload.stream !== \"tool\") {\n return;\n }\n const accepted = resolveAcceptedSession(host, payload);\n if (!accepted.accepted) {\n return;\n }\n const sessionKey = accepted.sessionKey;\n\n const data = payload.data ?? {};\n const toolCallId = typeof data.toolCallId === \"string\" ? data.toolCallId : \"\";\n if (!toolCallId) {\n return;\n }\n const name = typeof data.name === \"string\" ? data.name : \"tool\";\n const phase = typeof data.phase === \"string\" ? data.phase : \"\";\n const args = phase === \"start\" ? data.args : undefined;\n const output =\n phase === \"update\"\n ? formatToolOutput(data.partialResult)\n : phase === \"result\"\n ? formatToolOutput(data.result)\n : undefined;\n\n const now = Date.now();\n let entry = host.toolStreamById.get(toolCallId);\n if (!entry) {\n entry = {\n toolCallId,\n runId: payload.runId,\n sessionKey,\n name,\n args,\n output: output || undefined,\n startedAt: typeof payload.ts === \"number\" ? payload.ts : now,\n updatedAt: now,\n message: {},\n };\n host.toolStreamById.set(toolCallId, entry);\n host.toolStreamOrder.push(toolCallId);\n } else {\n entry.name = name;\n if (args !== undefined) {\n entry.args = args;\n }\n if (output !== undefined) {\n entry.output = output || undefined;\n }\n entry.updatedAt = now;\n }\n\n entry.message = buildToolStreamMessage(entry);\n trimToolStream(host);\n scheduleToolStreamSync(host, phase === \"result\");\n}\n","import { extractText } from \"../chat/message-extract.ts\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { ChatAttachment } from \"../ui-types.ts\";\nimport { generateUUID } from \"../uuid.ts\";\n\nconst SILENT_REPLY_PATTERN = /^\\s*NO_REPLY\\s*$/;\n\nfunction isSilentReplyStream(text: string): boolean {\n return SILENT_REPLY_PATTERN.test(text);\n}\n/** Client-side defense-in-depth: detect assistant messages whose text is purely NO_REPLY. */\nfunction isAssistantSilentReply(message: unknown): boolean {\n if (!message || typeof message !== \"object\") {\n return false;\n }\n const entry = message as Record<string, unknown>;\n const role = typeof entry.role === \"string\" ? entry.role.toLowerCase() : \"\";\n if (role !== \"assistant\") {\n return false;\n }\n // entry.text takes precedence — matches gateway extractAssistantTextForSilentCheck\n if (typeof entry.text === \"string\") {\n return isSilentReplyStream(entry.text);\n }\n const text = extractText(message);\n return typeof text === \"string\" && isSilentReplyStream(text);\n}\n\nexport type ChatState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionKey: string;\n chatLoading: boolean;\n chatMessages: unknown[];\n chatThinkingLevel: string | null;\n chatSending: boolean;\n chatMessage: string;\n chatAttachments: ChatAttachment[];\n chatRunId: string | null;\n chatStream: string | null;\n chatStreamStartedAt: number | null;\n lastError: string | null;\n};\n\nexport type ChatEventPayload = {\n runId: string;\n sessionKey: string;\n state: \"delta\" | \"final\" | \"aborted\" | \"error\";\n message?: unknown;\n errorMessage?: string;\n};\n\nexport async function loadChatHistory(state: ChatState) {\n if (!state.client || !state.connected) {\n return;\n }\n state.chatLoading = true;\n state.lastError = null;\n try {\n const res = await state.client.request<{ messages?: Array<unknown>; thinkingLevel?: string }>(\n \"chat.history\",\n {\n sessionKey: state.sessionKey,\n limit: 200,\n },\n );\n const messages = Array.isArray(res.messages) ? res.messages : [];\n state.chatMessages = messages.filter((message) => !isAssistantSilentReply(message));\n state.chatThinkingLevel = res.thinkingLevel ?? null;\n } catch (err) {\n state.lastError = String(err);\n } finally {\n state.chatLoading = false;\n }\n}\n\nfunction dataUrlToBase64(dataUrl: string): { content: string; mimeType: string } | null {\n const match = /^data:([^;]+);base64,(.+)$/.exec(dataUrl);\n if (!match) {\n return null;\n }\n return { mimeType: match[1], content: match[2] };\n}\n\ntype AssistantMessageNormalizationOptions = {\n roleRequirement: \"required\" | \"optional\";\n roleCaseSensitive?: boolean;\n requireContentArray?: boolean;\n allowTextField?: boolean;\n};\n\nfunction normalizeAssistantMessage(\n message: unknown,\n options: AssistantMessageNormalizationOptions,\n): Record<string, unknown> | null {\n if (!message || typeof message !== \"object\") {\n return null;\n }\n const candidate = message as Record<string, unknown>;\n const roleValue = candidate.role;\n if (typeof roleValue === \"string\") {\n const role = options.roleCaseSensitive ? roleValue : roleValue.toLowerCase();\n if (role !== \"assistant\") {\n return null;\n }\n } else if (options.roleRequirement === \"required\") {\n return null;\n }\n\n if (options.requireContentArray) {\n return Array.isArray(candidate.content) ? candidate : null;\n }\n if (!(\"content\" in candidate) && !(options.allowTextField && \"text\" in candidate)) {\n return null;\n }\n return candidate;\n}\n\nfunction normalizeAbortedAssistantMessage(message: unknown): Record<string, unknown> | null {\n return normalizeAssistantMessage(message, {\n roleRequirement: \"required\",\n roleCaseSensitive: true,\n requireContentArray: true,\n });\n}\n\nfunction normalizeFinalAssistantMessage(message: unknown): Record<string, unknown> | null {\n return normalizeAssistantMessage(message, {\n roleRequirement: \"optional\",\n allowTextField: true,\n });\n}\n\nexport async function sendChatMessage(\n state: ChatState,\n message: string,\n attachments?: ChatAttachment[],\n): Promise<string | null> {\n if (!state.client || !state.connected) {\n return null;\n }\n const msg = message.trim();\n const hasAttachments = attachments && attachments.length > 0;\n if (!msg && !hasAttachments) {\n return null;\n }\n\n const now = Date.now();\n\n // Build user message content blocks\n const contentBlocks: Array<{ type: string; text?: string; source?: unknown }> = [];\n if (msg) {\n contentBlocks.push({ type: \"text\", text: msg });\n }\n // Add image previews to the message for display\n if (hasAttachments) {\n for (const att of attachments) {\n contentBlocks.push({\n type: \"image\",\n source: { type: \"base64\", media_type: att.mimeType, data: att.dataUrl },\n });\n }\n }\n\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"user\",\n content: contentBlocks,\n timestamp: now,\n },\n ];\n\n state.chatSending = true;\n state.lastError = null;\n const runId = generateUUID();\n state.chatRunId = runId;\n state.chatStream = \"\";\n state.chatStreamStartedAt = now;\n\n // Convert attachments to API format\n const apiAttachments = hasAttachments\n ? attachments\n .map((att) => {\n const parsed = dataUrlToBase64(att.dataUrl);\n if (!parsed) {\n return null;\n }\n return {\n type: \"image\",\n mimeType: parsed.mimeType,\n content: parsed.content,\n };\n })\n .filter((a): a is NonNullable<typeof a> => a !== null)\n : undefined;\n\n try {\n await state.client.request(\"chat.send\", {\n sessionKey: state.sessionKey,\n message: msg,\n deliver: false,\n idempotencyKey: runId,\n attachments: apiAttachments,\n });\n return runId;\n } catch (err) {\n const error = String(err);\n state.chatRunId = null;\n state.chatStream = null;\n state.chatStreamStartedAt = null;\n state.lastError = error;\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"assistant\",\n content: [{ type: \"text\", text: \"Error: \" + error }],\n timestamp: Date.now(),\n },\n ];\n return null;\n } finally {\n state.chatSending = false;\n }\n}\n\nexport async function abortChatRun(state: ChatState): Promise<boolean> {\n if (!state.client || !state.connected) {\n return false;\n }\n const runId = state.chatRunId;\n try {\n await state.client.request(\n \"chat.abort\",\n runId ? { sessionKey: state.sessionKey, runId } : { sessionKey: state.sessionKey },\n );\n return true;\n } catch (err) {\n state.lastError = String(err);\n return false;\n }\n}\n\nexport function handleChatEvent(state: ChatState, payload?: ChatEventPayload) {\n if (!payload) {\n return null;\n }\n if (payload.sessionKey !== state.sessionKey) {\n return null;\n }\n\n // Final from another run (e.g. sub-agent announce): refresh history to show new message.\n // See https://github.com/openclaw/openclaw/issues/1909\n if (payload.runId && state.chatRunId && payload.runId !== state.chatRunId) {\n if (payload.state === \"final\") {\n const finalMessage = normalizeFinalAssistantMessage(payload.message);\n if (finalMessage && !isAssistantSilentReply(finalMessage)) {\n state.chatMessages = [...state.chatMessages, finalMessage];\n return null;\n }\n return \"final\";\n }\n return null;\n }\n\n if (payload.state === \"delta\") {\n const next = extractText(payload.message);\n if (typeof next === \"string\" && !isSilentReplyStream(next)) {\n const current = state.chatStream ?? \"\";\n if (!current || next.length >= current.length) {\n state.chatStream = next;\n }\n }\n } else if (payload.state === \"final\") {\n const finalMessage = normalizeFinalAssistantMessage(payload.message);\n if (finalMessage && !isAssistantSilentReply(finalMessage)) {\n state.chatMessages = [...state.chatMessages, finalMessage];\n } else if (state.chatStream?.trim() && !isSilentReplyStream(state.chatStream)) {\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"assistant\",\n content: [{ type: \"text\", text: state.chatStream }],\n timestamp: Date.now(),\n },\n ];\n }\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n } else if (payload.state === \"aborted\") {\n const normalizedMessage = normalizeAbortedAssistantMessage(payload.message);\n if (normalizedMessage && !isAssistantSilentReply(normalizedMessage)) {\n state.chatMessages = [...state.chatMessages, normalizedMessage];\n } else {\n const streamedText = state.chatStream ?? \"\";\n if (streamedText.trim() && !isSilentReplyStream(streamedText)) {\n state.chatMessages = [\n ...state.chatMessages,\n {\n role: \"assistant\",\n content: [{ type: \"text\", text: streamedText }],\n timestamp: Date.now(),\n },\n ];\n }\n }\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n } else if (payload.state === \"error\") {\n state.chatStream = null;\n state.chatRunId = null;\n state.chatStreamStartedAt = null;\n state.lastError = payload.errorMessage ?? \"chat error\";\n }\n return payload.state;\n}\n","import { parseAgentSessionKey } from \"../../../src/sessions/session-key-utils.js\";\nimport { scheduleChatScroll } from \"./app-scroll.ts\";\nimport { setLastActiveSessionKey } from \"./app-settings.ts\";\nimport { resetToolStream } from \"./app-tool-stream.ts\";\nimport type { OpenClawApp } from \"./app.ts\";\nimport { abortChatRun, loadChatHistory, sendChatMessage } from \"./controllers/chat.ts\";\nimport { loadSessions } from \"./controllers/sessions.ts\";\nimport type { GatewayHelloOk } from \"./gateway.ts\";\nimport { normalizeBasePath } from \"./navigation.ts\";\nimport type { ChatAttachment, ChatQueueItem } from \"./ui-types.ts\";\nimport { generateUUID } from \"./uuid.ts\";\n\nexport type ChatHost = {\n connected: boolean;\n chatMessage: string;\n chatAttachments: ChatAttachment[];\n chatQueue: ChatQueueItem[];\n chatRunId: string | null;\n chatSending: boolean;\n sessionKey: string;\n basePath: string;\n hello: GatewayHelloOk | null;\n chatAvatarUrl: string | null;\n refreshSessionsAfterChat: Set<string>;\n};\n\nexport const CHAT_SESSIONS_ACTIVE_MINUTES = 120;\n\nexport function isChatBusy(host: ChatHost) {\n return host.chatSending || Boolean(host.chatRunId);\n}\n\nexport function isChatStopCommand(text: string) {\n const trimmed = text.trim();\n if (!trimmed) {\n return false;\n }\n const normalized = trimmed.toLowerCase();\n if (normalized === \"/stop\") {\n return true;\n }\n return (\n normalized === \"stop\" ||\n normalized === \"esc\" ||\n normalized === \"abort\" ||\n normalized === \"wait\" ||\n normalized === \"exit\"\n );\n}\n\nfunction isChatResetCommand(text: string) {\n const trimmed = text.trim();\n if (!trimmed) {\n return false;\n }\n const normalized = trimmed.toLowerCase();\n if (normalized === \"/new\" || normalized === \"/reset\") {\n return true;\n }\n return normalized.startsWith(\"/new \") || normalized.startsWith(\"/reset \");\n}\n\nexport async function handleAbortChat(host: ChatHost) {\n if (!host.connected) {\n return;\n }\n host.chatMessage = \"\";\n await abortChatRun(host as unknown as OpenClawApp);\n}\n\nfunction enqueueChatMessage(\n host: ChatHost,\n text: string,\n attachments?: ChatAttachment[],\n refreshSessions?: boolean,\n) {\n const trimmed = text.trim();\n const hasAttachments = Boolean(attachments && attachments.length > 0);\n if (!trimmed && !hasAttachments) {\n return;\n }\n host.chatQueue = [\n ...host.chatQueue,\n {\n id: generateUUID(),\n text: trimmed,\n createdAt: Date.now(),\n attachments: hasAttachments ? attachments?.map((att) => ({ ...att })) : undefined,\n refreshSessions,\n },\n ];\n}\n\nasync function sendChatMessageNow(\n host: ChatHost,\n message: string,\n opts?: {\n previousDraft?: string;\n restoreDraft?: boolean;\n attachments?: ChatAttachment[];\n previousAttachments?: ChatAttachment[];\n restoreAttachments?: boolean;\n refreshSessions?: boolean;\n },\n) {\n resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);\n const runId = await sendChatMessage(host as unknown as OpenClawApp, message, opts?.attachments);\n const ok = Boolean(runId);\n if (!ok && opts?.previousDraft != null) {\n host.chatMessage = opts.previousDraft;\n }\n if (!ok && opts?.previousAttachments) {\n host.chatAttachments = opts.previousAttachments;\n }\n if (ok) {\n setLastActiveSessionKey(\n host as unknown as Parameters<typeof setLastActiveSessionKey>[0],\n host.sessionKey,\n );\n }\n if (ok && opts?.restoreDraft && opts.previousDraft?.trim()) {\n host.chatMessage = opts.previousDraft;\n }\n if (ok && opts?.restoreAttachments && opts.previousAttachments?.length) {\n host.chatAttachments = opts.previousAttachments;\n }\n scheduleChatScroll(host as unknown as Parameters<typeof scheduleChatScroll>[0]);\n if (ok && !host.chatRunId) {\n void flushChatQueue(host);\n }\n if (ok && opts?.refreshSessions && runId) {\n host.refreshSessionsAfterChat.add(runId);\n }\n return ok;\n}\n\nasync function flushChatQueue(host: ChatHost) {\n if (!host.connected || isChatBusy(host)) {\n return;\n }\n const [next, ...rest] = host.chatQueue;\n if (!next) {\n return;\n }\n host.chatQueue = rest;\n const ok = await sendChatMessageNow(host, next.text, {\n attachments: next.attachments,\n refreshSessions: next.refreshSessions,\n });\n if (!ok) {\n host.chatQueue = [next, ...host.chatQueue];\n }\n}\n\nexport function removeQueuedMessage(host: ChatHost, id: string) {\n host.chatQueue = host.chatQueue.filter((item) => item.id !== id);\n}\n\nexport async function handleSendChat(\n host: ChatHost,\n messageOverride?: string,\n opts?: { restoreDraft?: boolean },\n) {\n if (!host.connected) {\n return;\n }\n const previousDraft = host.chatMessage;\n const message = (messageOverride ?? host.chatMessage).trim();\n const attachments = host.chatAttachments ?? [];\n const attachmentsToSend = messageOverride == null ? attachments : [];\n const hasAttachments = attachmentsToSend.length > 0;\n\n // Allow sending with just attachments (no message text required)\n if (!message && !hasAttachments) {\n return;\n }\n\n if (isChatStopCommand(message)) {\n await handleAbortChat(host);\n return;\n }\n\n const refreshSessions = isChatResetCommand(message);\n if (messageOverride == null) {\n host.chatMessage = \"\";\n // Clear attachments when sending\n host.chatAttachments = [];\n }\n\n if (isChatBusy(host)) {\n enqueueChatMessage(host, message, attachmentsToSend, refreshSessions);\n return;\n }\n\n await sendChatMessageNow(host, message, {\n previousDraft: messageOverride == null ? previousDraft : undefined,\n restoreDraft: Boolean(messageOverride && opts?.restoreDraft),\n attachments: hasAttachments ? attachmentsToSend : undefined,\n previousAttachments: messageOverride == null ? attachments : undefined,\n restoreAttachments: Boolean(messageOverride && opts?.restoreDraft),\n refreshSessions,\n });\n}\n\nexport async function refreshChat(host: ChatHost, opts?: { scheduleScroll?: boolean }) {\n await Promise.all([\n loadChatHistory(host as unknown as OpenClawApp),\n loadSessions(host as unknown as OpenClawApp, {\n activeMinutes: CHAT_SESSIONS_ACTIVE_MINUTES,\n }),\n refreshChatAvatar(host),\n ]);\n if (opts?.scheduleScroll !== false) {\n scheduleChatScroll(host as unknown as Parameters<typeof scheduleChatScroll>[0]);\n }\n}\n\nexport const flushChatQueueForEvent = flushChatQueue;\n\ntype SessionDefaultsSnapshot = {\n defaultAgentId?: string;\n};\n\nfunction resolveAgentIdForSession(host: ChatHost): string | null {\n const parsed = parseAgentSessionKey(host.sessionKey);\n if (parsed?.agentId) {\n return parsed.agentId;\n }\n const snapshot = host.hello?.snapshot as\n | { sessionDefaults?: SessionDefaultsSnapshot }\n | undefined;\n const fallback = snapshot?.sessionDefaults?.defaultAgentId?.trim();\n return fallback || \"main\";\n}\n\nfunction buildAvatarMetaUrl(basePath: string, agentId: string): string {\n const base = normalizeBasePath(basePath);\n const encoded = encodeURIComponent(agentId);\n return base ? `${base}/avatar/${encoded}?meta=1` : `/avatar/${encoded}?meta=1`;\n}\n\nexport async function refreshChatAvatar(host: ChatHost) {\n if (!host.connected) {\n host.chatAvatarUrl = null;\n return;\n }\n const agentId = resolveAgentIdForSession(host);\n if (!agentId) {\n host.chatAvatarUrl = null;\n return;\n }\n host.chatAvatarUrl = null;\n const url = buildAvatarMetaUrl(host.basePath, agentId);\n try {\n const res = await fetch(url, { method: \"GET\" });\n if (!res.ok) {\n host.chatAvatarUrl = null;\n return;\n }\n const data = (await res.json()) as { avatarUrl?: unknown };\n const avatarUrl = typeof data.avatarUrl === \"string\" ? data.avatarUrl.trim() : \"\";\n host.chatAvatarUrl = avatarUrl || null;\n } catch {\n host.chatAvatarUrl = null;\n }\n}\n","import type { ChatEventPayload } from \"./controllers/chat.ts\";\n\nexport function shouldReloadHistoryForFinalEvent(payload?: ChatEventPayload): boolean {\n if (!payload || payload.state !== \"final\") {\n return false;\n }\n if (!payload.message || typeof payload.message !== \"object\") {\n return true;\n }\n const message = payload.message as Record<string, unknown>;\n const role = typeof message.role === \"string\" ? message.role.toLowerCase() : \"\";\n if (role && role !== \"assistant\") {\n return true;\n }\n return false;\n}\n","/**\n * Closed assistant colour palette (ADR 0084 s6, design D11). Every consumer - config validation\n * (zod), the `agents.list` wire shape (typebox), and `packages/brand-tokens/tokens.css` - is\n * bound to this exact set so contrast can be guaranteed in every theme.\n */\nexport const ASSISTANT_IDENTITY_COLORS = [\n \"indigo\",\n \"violet\",\n \"pink\",\n \"rose\",\n \"amber\",\n \"lime\",\n \"teal\",\n \"sky\",\n] as const;\n\nexport type AssistantIdentityColor = (typeof ASSISTANT_IDENTITY_COLORS)[number];\n\nexport function coerceIdentityValue(\n value: string | undefined,\n maxLength: number,\n): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n if (!trimmed) {\n return undefined;\n }\n if (trimmed.length <= maxLength) {\n return trimmed;\n }\n return trimmed.slice(0, maxLength);\n}\n","import { coerceIdentityValue } from \"../../../src/shared/assistant-identity-values.js\";\n\nconst MAX_ASSISTANT_NAME = 50;\nconst MAX_ASSISTANT_AVATAR = 200;\n\nexport const DEFAULT_ASSISTANT_NAME = \"Assistant\";\nexport const DEFAULT_ASSISTANT_AVATAR = \"A\";\n\nexport type AssistantIdentity = {\n agentId?: string | null;\n name: string;\n avatar: string | null;\n};\n\nexport function normalizeAssistantIdentity(\n input?: Partial<AssistantIdentity> | null,\n): AssistantIdentity {\n const name = coerceIdentityValue(input?.name, MAX_ASSISTANT_NAME) ?? DEFAULT_ASSISTANT_NAME;\n const avatar = coerceIdentityValue(input?.avatar ?? undefined, MAX_ASSISTANT_AVATAR) ?? null;\n const agentId =\n typeof input?.agentId === \"string\" && input.agentId.trim() ? input.agentId.trim() : null;\n return { agentId, name, avatar };\n}\n","import { normalizeAssistantIdentity } from \"../assistant-identity.ts\";\nimport type { GatewayBrowserClient } from \"../gateway.ts\";\n\nexport type AssistantIdentityState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n sessionKey: string;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n};\n\nexport async function loadAssistantIdentity(\n state: AssistantIdentityState,\n opts?: { sessionKey?: string },\n) {\n if (!state.client || !state.connected) {\n return;\n }\n const sessionKey = opts?.sessionKey?.trim() || state.sessionKey.trim();\n const params = sessionKey ? { sessionKey } : {};\n try {\n const res = await state.client.request(\"agent.identity.get\", params);\n if (!res) {\n return;\n }\n const normalized = normalizeAssistantIdentity(res);\n state.assistantName = normalized.name;\n state.assistantAvatar = normalized.avatar;\n state.assistantAgentId = normalized.agentId ?? null;\n } catch {\n // Ignore errors; keep last known identity.\n }\n}\n","export type ExecApprovalRequestPayload = {\n command: string;\n cwd?: string | null;\n host?: string | null;\n security?: string | null;\n ask?: string | null;\n agentId?: string | null;\n resolvedPath?: string | null;\n sessionKey?: string | null;\n};\n\nexport type ExecApprovalRequest = {\n id: string;\n request: ExecApprovalRequestPayload;\n createdAtMs: number;\n expiresAtMs: number;\n};\n\nexport type ExecApprovalResolved = {\n id: string;\n decision?: string | null;\n resolvedBy?: string | null;\n ts?: number | null;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function parseExecApprovalRequested(payload: unknown): ExecApprovalRequest | null {\n if (!isRecord(payload)) {\n return null;\n }\n const id = typeof payload.id === \"string\" ? payload.id.trim() : \"\";\n const request = payload.request;\n if (!id || !isRecord(request)) {\n return null;\n }\n const command = typeof request.command === \"string\" ? request.command.trim() : \"\";\n if (!command) {\n return null;\n }\n const createdAtMs = typeof payload.createdAtMs === \"number\" ? payload.createdAtMs : 0;\n const expiresAtMs = typeof payload.expiresAtMs === \"number\" ? payload.expiresAtMs : 0;\n if (!createdAtMs || !expiresAtMs) {\n return null;\n }\n return {\n id,\n request: {\n command,\n cwd: typeof request.cwd === \"string\" ? request.cwd : null,\n host: typeof request.host === \"string\" ? request.host : null,\n security: typeof request.security === \"string\" ? request.security : null,\n ask: typeof request.ask === \"string\" ? request.ask : null,\n agentId: typeof request.agentId === \"string\" ? request.agentId : null,\n resolvedPath: typeof request.resolvedPath === \"string\" ? request.resolvedPath : null,\n sessionKey: typeof request.sessionKey === \"string\" ? request.sessionKey : null,\n },\n createdAtMs,\n expiresAtMs,\n };\n}\n\nexport function parseExecApprovalResolved(payload: unknown): ExecApprovalResolved | null {\n if (!isRecord(payload)) {\n return null;\n }\n const id = typeof payload.id === \"string\" ? payload.id.trim() : \"\";\n if (!id) {\n return null;\n }\n return {\n id,\n decision: typeof payload.decision === \"string\" ? payload.decision : null,\n resolvedBy: typeof payload.resolvedBy === \"string\" ? payload.resolvedBy : null,\n ts: typeof payload.ts === \"number\" ? payload.ts : null,\n };\n}\n\nexport function pruneExecApprovalQueue(queue: ExecApprovalRequest[]): ExecApprovalRequest[] {\n const now = Date.now();\n return queue.filter((entry) => entry.expiresAtMs > now);\n}\n\nexport function addExecApproval(\n queue: ExecApprovalRequest[],\n entry: ExecApprovalRequest,\n): ExecApprovalRequest[] {\n const next = pruneExecApprovalQueue(queue).filter((item) => item.id !== entry.id);\n next.push(entry);\n return next;\n}\n\nexport function removeExecApproval(\n queue: ExecApprovalRequest[],\n id: string,\n): ExecApprovalRequest[] {\n return pruneExecApprovalQueue(queue).filter((entry) => entry.id !== id);\n}\n","import {\n GATEWAY_EVENT_UPDATE_AVAILABLE,\n type GatewayUpdateAvailableEventPayload,\n} from \"../../../src/gateway/events.js\";\nimport { CHAT_SESSIONS_ACTIVE_MINUTES, flushChatQueueForEvent } from \"./app-chat.ts\";\nimport type { EventLogEntry } from \"./app-events.ts\";\nimport {\n applySettings,\n loadCron,\n refreshActiveTab,\n setLastActiveSessionKey,\n} from \"./app-settings.ts\";\nimport { handleAgentEvent, resetToolStream, type AgentEventPayload } from \"./app-tool-stream.ts\";\nimport type { OpenClawApp } from \"./app.ts\";\nimport { shouldReloadHistoryForFinalEvent } from \"./chat-event-reload.ts\";\nimport { loadAgents, loadToolsCatalog } from \"./controllers/agents.ts\";\nimport { loadAssistantIdentity } from \"./controllers/assistant-identity.ts\";\nimport { loadChatHistory } from \"./controllers/chat.ts\";\nimport { handleChatEvent, type ChatEventPayload } from \"./controllers/chat.ts\";\nimport { loadDevices } from \"./controllers/devices.ts\";\nimport { handleDreamsUpdate, type DreamsHost } from \"./controllers/dreams.ts\";\nimport type { ExecApprovalRequest } from \"./controllers/exec-approval.ts\";\nimport {\n addExecApproval,\n parseExecApprovalRequested,\n parseExecApprovalResolved,\n removeExecApproval,\n} from \"./controllers/exec-approval.ts\";\nimport { loadNodes } from \"./controllers/nodes.ts\";\nimport {\n loadRecoverableRuns,\n loadSessionRuns,\n loadSessions,\n updateRecentlyCompletedRuns,\n} from \"./controllers/sessions.ts\";\nimport type { TalkController, TalkRealtimeRelayEvent } from \"./controllers/talk.ts\";\nimport {\n resolveGatewayErrorDetailCode,\n type GatewayEventFrame,\n type GatewayHelloOk,\n} from \"./gateway.ts\";\nimport { GatewayBrowserClient } from \"./gateway.ts\";\nimport type { Tab } from \"./navigation.ts\";\nimport type { UiSettings } from \"./storage.ts\";\nimport type { SessionRunsResult } from \"./types.ts\";\nimport type {\n AgentsListResult,\n PresenceEntry,\n HealthSnapshot,\n StatusSummary,\n UpdateAvailable,\n} from \"./types.ts\";\n\ntype GatewayHost = {\n settings: UiSettings;\n password: string;\n clientInstanceId: string;\n client: GatewayBrowserClient | null;\n connected: boolean;\n hello: GatewayHelloOk | null;\n lastError: string | null;\n lastErrorCode: string | null;\n onboarding?: boolean;\n eventLogBuffer: EventLogEntry[];\n eventLog: EventLogEntry[];\n tab: Tab;\n presenceEntries: PresenceEntry[];\n presenceError: string | null;\n presenceStatus: StatusSummary | null;\n agentsLoading: boolean;\n agentsList: AgentsListResult | null;\n agentsError: string | null;\n toolsCatalogLoading: boolean;\n toolsCatalogError: string | null;\n toolsCatalogResult: import(\"./types.ts\").ToolsCatalogResult | null;\n debugHealth: HealthSnapshot | null;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n sessionKey: string;\n chatRunId: string | null;\n refreshSessionsAfterChat: Set<string>;\n execApprovalQueue: ExecApprovalRequest[];\n execApprovalError: string | null;\n updateAvailable: UpdateAvailable | null;\n talkController: TalkController;\n};\n\nexport function createGatewayRequester(host: { client: GatewayBrowserClient | null }) {\n return <T>(method: string, params?: unknown): Promise<T> => {\n const client = host.client;\n if (!client) {\n return Promise.reject(new Error(\"Gateway is not connected\"));\n }\n return client.request<T>(method, params);\n };\n}\n\ntype SessionDefaultsSnapshot = {\n defaultAgentId?: string;\n mainKey?: string;\n mainSessionKey?: string;\n scope?: string;\n};\n\nfunction normalizeSessionKeyForDefaults(\n value: string | undefined,\n defaults: SessionDefaultsSnapshot,\n): string {\n const raw = (value ?? \"\").trim();\n const mainSessionKey = defaults.mainSessionKey?.trim();\n if (!mainSessionKey) {\n return raw;\n }\n if (!raw) {\n return mainSessionKey;\n }\n const mainKey = defaults.mainKey?.trim() || \"main\";\n const defaultAgentId = defaults.defaultAgentId?.trim();\n const isAlias =\n raw === \"main\" ||\n raw === mainKey ||\n (defaultAgentId &&\n (raw === `agent:${defaultAgentId}:main` || raw === `agent:${defaultAgentId}:${mainKey}`));\n return isAlias ? mainSessionKey : raw;\n}\n\nfunction applySessionDefaults(host: GatewayHost, defaults?: SessionDefaultsSnapshot) {\n if (!defaults?.mainSessionKey) {\n return;\n }\n const resolvedSessionKey = normalizeSessionKeyForDefaults(host.sessionKey, defaults);\n const resolvedSettingsSessionKey = normalizeSessionKeyForDefaults(\n host.settings.sessionKey,\n defaults,\n );\n const resolvedLastActiveSessionKey = normalizeSessionKeyForDefaults(\n host.settings.lastActiveSessionKey,\n defaults,\n );\n const nextSessionKey = resolvedSessionKey || resolvedSettingsSessionKey || host.sessionKey;\n const nextSettings = {\n ...host.settings,\n sessionKey: resolvedSettingsSessionKey || nextSessionKey,\n lastActiveSessionKey: resolvedLastActiveSessionKey || nextSessionKey,\n };\n const shouldUpdateSettings =\n nextSettings.sessionKey !== host.settings.sessionKey ||\n nextSettings.lastActiveSessionKey !== host.settings.lastActiveSessionKey;\n if (nextSessionKey !== host.sessionKey) {\n host.sessionKey = nextSessionKey;\n }\n if (shouldUpdateSettings) {\n applySettings(host as unknown as Parameters<typeof applySettings>[0], nextSettings);\n }\n}\n\nexport function connectGateway(host: GatewayHost) {\n host.lastError = null;\n host.lastErrorCode = null;\n host.hello = null;\n host.connected = false;\n host.execApprovalQueue = [];\n host.execApprovalError = null;\n\n const previousClient = host.client;\n const client = new GatewayBrowserClient({\n url: host.settings.gatewayUrl,\n token: host.settings.token.trim() ? host.settings.token : undefined,\n password: host.password.trim() ? host.password : undefined,\n clientName: \"openclaw-control-ui\",\n mode: \"webchat\",\n instanceId: host.clientInstanceId,\n onHello: (hello) => {\n if (host.client !== client) {\n return;\n }\n try {\n const availability = host.talkController.loadAvailability();\n void availability.catch(() => undefined);\n } catch {\n // A synchronous refresh failure must not prevent the connection from becoming ready.\n }\n void host.talkController.reconnectIfIntended().catch(() => undefined);\n host.connected = true;\n host.lastError = null;\n host.lastErrorCode = null;\n host.hello = hello;\n applySnapshot(host, hello);\n // Reset orphaned chat run state from before disconnect.\n // Any in-flight run's final event was lost during the disconnect window.\n host.chatRunId = null;\n (host as unknown as { chatStream: string | null }).chatStream = null;\n (host as unknown as { chatStreamStartedAt: number | null }).chatStreamStartedAt = null;\n resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);\n void loadAssistantIdentity(host as unknown as OpenClawApp);\n void loadAgents(host as unknown as OpenClawApp);\n void loadToolsCatalog(host as unknown as OpenClawApp);\n void loadNodes(host as unknown as OpenClawApp, { quiet: true });\n void loadDevices(host as unknown as OpenClawApp, { quiet: true });\n void loadSessionRuns(host as unknown as OpenClawApp);\n void loadRecoverableRuns(host as unknown as OpenClawApp);\n void refreshActiveTab(host as unknown as Parameters<typeof refreshActiveTab>[0]);\n },\n onClose: ({ code, reason, error }) => {\n if (host.client !== client) {\n return;\n }\n host.talkController.handleGatewayClose();\n host.connected = false;\n // Code 1012 = Service Restart (expected during config saves, don't show as error)\n host.lastErrorCode =\n resolveGatewayErrorDetailCode(error) ??\n (typeof error?.code === \"string\" ? error.code : null);\n if (code !== 1012) {\n if (error?.message) {\n host.lastError = error.message;\n return;\n }\n host.lastError = `disconnected (${code}): ${reason || \"no reason\"}`;\n } else {\n host.lastError = null;\n host.lastErrorCode = null;\n }\n },\n onEvent: (evt) => {\n if (host.client !== client) {\n return;\n }\n handleGatewayEvent(host, evt);\n },\n onGap: ({ expected, received }) => {\n if (host.client !== client) {\n return;\n }\n host.lastError = `event gap detected (expected seq ${expected}, got ${received}); refresh recommended`;\n host.lastErrorCode = null;\n },\n });\n host.client = client;\n previousClient?.stop();\n client.start();\n}\n\nexport function handleGatewayEvent(host: GatewayHost, evt: GatewayEventFrame) {\n try {\n handleGatewayEventUnsafe(host, evt);\n } catch (err) {\n console.error(\"[gateway] handleGatewayEvent error:\", evt.event, err);\n }\n}\n\nfunction handleTerminalChatEvent(\n host: GatewayHost,\n payload: ChatEventPayload | undefined,\n state: ReturnType<typeof handleChatEvent>,\n) {\n if (state !== \"final\" && state !== \"error\" && state !== \"aborted\") {\n return;\n }\n resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);\n void flushChatQueueForEvent(host as unknown as Parameters<typeof flushChatQueueForEvent>[0]);\n const runId = payload?.runId;\n if (!runId || !host.refreshSessionsAfterChat.has(runId)) {\n return;\n }\n host.refreshSessionsAfterChat.delete(runId);\n if (state === \"final\") {\n void loadSessions(host as unknown as OpenClawApp, {\n activeMinutes: CHAT_SESSIONS_ACTIVE_MINUTES,\n });\n }\n}\n\nfunction handleChatGatewayEvent(host: GatewayHost, payload: ChatEventPayload | undefined) {\n if (payload?.sessionKey) {\n setLastActiveSessionKey(\n host as unknown as Parameters<typeof setLastActiveSessionKey>[0],\n payload.sessionKey,\n );\n }\n const state = handleChatEvent(host as unknown as OpenClawApp, payload);\n handleTerminalChatEvent(host, payload, state);\n if (state === \"final\" && shouldReloadHistoryForFinalEvent(payload)) {\n void loadChatHistory(host as unknown as OpenClawApp);\n }\n}\n\nfunction handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {\n const talkRelayType =\n evt.event === \"talk.realtime.relay\" && typeof evt.payload === \"object\" && evt.payload !== null\n ? (evt.payload as { type?: unknown }).type\n : undefined;\n const bufferedPayload =\n evt.event === \"talk.realtime.relay\"\n ? { type: typeof talkRelayType === \"string\" ? talkRelayType : undefined }\n : evt.payload;\n host.eventLogBuffer = [\n { ts: Date.now(), event: evt.event, payload: bufferedPayload },\n ...host.eventLogBuffer,\n ].slice(0, 250);\n if (host.tab === \"debug\") {\n host.eventLog = host.eventLogBuffer;\n }\n\n if (evt.event === \"talk.realtime.relay\") {\n host.talkController.handleRelayEvent(evt.payload as TalkRealtimeRelayEvent);\n return;\n }\n\n if (evt.event === \"agent\") {\n if (host.onboarding) {\n return;\n }\n handleAgentEvent(\n host as unknown as Parameters<typeof handleAgentEvent>[0],\n evt.payload as AgentEventPayload | undefined,\n );\n return;\n }\n\n if (evt.event === \"chat\") {\n handleChatGatewayEvent(host, evt.payload as ChatEventPayload | undefined);\n return;\n }\n\n if (evt.event === \"presence\") {\n const payload = evt.payload as { presence?: PresenceEntry[] } | undefined;\n if (payload?.presence && Array.isArray(payload.presence)) {\n host.presenceEntries = payload.presence;\n host.presenceError = null;\n host.presenceStatus = null;\n }\n return;\n }\n\n if (evt.event === \"cron\" && host.tab === \"cron\") {\n void loadCron(host as unknown as Parameters<typeof loadCron>[0]);\n }\n\n if (evt.event === \"dreams.update\") {\n handleDreamsUpdate(host as unknown as DreamsHost);\n return;\n }\n\n if (evt.event === \"device.pair.requested\" || evt.event === \"device.pair.resolved\") {\n void loadDevices(host as unknown as OpenClawApp, { quiet: true });\n }\n\n if (evt.event === \"exec.approval.requested\") {\n const entry = parseExecApprovalRequested(evt.payload);\n if (entry) {\n host.execApprovalQueue = addExecApproval(host.execApprovalQueue, entry);\n host.execApprovalError = null;\n const delay = Math.max(0, entry.expiresAtMs - Date.now() + 500);\n window.setTimeout(() => {\n host.execApprovalQueue = removeExecApproval(host.execApprovalQueue, entry.id);\n }, delay);\n }\n return;\n }\n\n if (evt.event === \"exec.approval.resolved\") {\n const resolved = parseExecApprovalResolved(evt.payload);\n if (resolved) {\n host.execApprovalQueue = removeExecApproval(host.execApprovalQueue, resolved.id);\n }\n return;\n }\n\n if (evt.event === \"sessions.runsUpdate\") {\n const payload = evt.payload as SessionRunsResult | undefined;\n if (payload) {\n const app = host as unknown as OpenClawApp;\n const nowTs = Date.now();\n app.recentlyCompletedRuns = updateRecentlyCompletedRuns(\n app.sessionRunsPrevKeys,\n payload.runs,\n app.recentlyCompletedRuns,\n nowTs,\n );\n app.sessionRunsPrevKeys = new Set(payload.runs.map((r) => r.key));\n app.sessionRunsResult = payload;\n app.sessionRunsFetchedAt = nowTs;\n app.sessionRunsError = null;\n }\n return;\n }\n\n if (evt.event === GATEWAY_EVENT_UPDATE_AVAILABLE) {\n const payload = evt.payload as GatewayUpdateAvailableEventPayload | undefined;\n host.updateAvailable = payload?.updateAvailable ?? null;\n }\n}\n\nexport function applySnapshot(host: GatewayHost, hello: GatewayHelloOk) {\n const snapshot = hello.snapshot as\n | {\n presence?: PresenceEntry[];\n health?: HealthSnapshot;\n sessionDefaults?: SessionDefaultsSnapshot;\n updateAvailable?: UpdateAvailable;\n }\n | undefined;\n if (snapshot?.presence && Array.isArray(snapshot.presence)) {\n host.presenceEntries = snapshot.presence;\n }\n if (snapshot?.health) {\n host.debugHealth = snapshot.health;\n }\n if (snapshot?.sessionDefaults) {\n applySessionDefaults(host, snapshot.sessionDefaults);\n }\n host.updateAvailable = snapshot?.updateAvailable ?? null;\n}\n","export const CONTROL_UI_BOOTSTRAP_CONFIG_PATH = \"/__openclaw/control-ui-config.json\";\n\nexport type ControlUiBootstrapConfig = {\n basePath: string;\n /**\n * Path of the default (v2) console, with a trailing slash, e.g. \"/\" at the root or\n * \"/v2/control/\". `null` when the v2 console is disabled, so the classic UI can link to it.\n */\n consolePath: string | null;\n assistantName: string;\n assistantAvatar: string;\n assistantAgentId: string;\n};\n","import {\n CONTROL_UI_BOOTSTRAP_CONFIG_PATH,\n type ControlUiBootstrapConfig,\n} from \"../../../../src/gateway/control-ui-contract.js\";\nimport { normalizeAssistantIdentity } from \"../assistant-identity.ts\";\nimport { normalizeBasePath } from \"../navigation.ts\";\n\nexport type ControlUiBootstrapState = {\n basePath: string;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n consolePath: string | null;\n};\n\nexport async function loadControlUiBootstrapConfig(state: ControlUiBootstrapState) {\n if (typeof window === \"undefined\") {\n return;\n }\n if (typeof fetch !== \"function\") {\n return;\n }\n\n const basePath = normalizeBasePath(state.basePath ?? \"\");\n const url = basePath\n ? `${basePath}${CONTROL_UI_BOOTSTRAP_CONFIG_PATH}`\n : CONTROL_UI_BOOTSTRAP_CONFIG_PATH;\n\n try {\n const res = await fetch(url, {\n method: \"GET\",\n headers: { Accept: \"application/json\" },\n credentials: \"same-origin\",\n });\n if (!res.ok) {\n return;\n }\n const parsed = (await res.json()) as ControlUiBootstrapConfig;\n const normalized = normalizeAssistantIdentity({\n agentId: parsed.assistantAgentId ?? null,\n name: parsed.assistantName,\n avatar: parsed.assistantAvatar ?? null,\n });\n state.assistantName = normalized.name;\n state.assistantAvatar = normalized.avatar;\n state.assistantAgentId = normalized.agentId ?? null;\n state.consolePath = typeof parsed.consolePath === \"string\" ? parsed.consolePath : null;\n } catch {\n // Ignore bootstrap failures; UI will update identity after connecting.\n }\n}\n","import { connectGateway } from \"./app-gateway.ts\";\nimport {\n startLogsPolling,\n startNodesPolling,\n stopLogsPolling,\n stopNodesPolling,\n startDebugPolling,\n stopDebugPolling,\n startSessionRunsPolling,\n stopSessionRunsPolling,\n startSessionRunsTick,\n stopSessionRunsTick,\n startDreamsPolling,\n stopDreamsPolling,\n} from \"./app-polling.ts\";\nimport { observeTopbar, scheduleChatScroll, scheduleLogsScroll } from \"./app-scroll.ts\";\nimport {\n applySettingsFromUrl,\n attachThemeListener,\n detachThemeListener,\n inferBasePath,\n syncTabWithLocation,\n syncThemeWithSettings,\n} from \"./app-settings.ts\";\nimport { loadControlUiBootstrapConfig } from \"./controllers/control-ui-bootstrap.ts\";\nimport { handleDreamsVisibilityChange, type DreamsHost } from \"./controllers/dreams.ts\";\nimport type { TalkController } from \"./controllers/talk.ts\";\nimport type { Tab } from \"./navigation.ts\";\n\ntype LifecycleHost = {\n basePath: string;\n client?: { stop: () => void } | null;\n connected?: boolean;\n tab: Tab;\n assistantName: string;\n assistantAvatar: string | null;\n assistantAgentId: string | null;\n consolePath: string | null;\n chatHasAutoScrolled: boolean;\n chatManualRefreshInFlight: boolean;\n chatLoading: boolean;\n chatMessages: unknown[];\n chatToolMessages: unknown[];\n chatStream: string;\n logsAutoFollow: boolean;\n logsAtBottom: boolean;\n logsEntries: unknown[];\n popStateHandler: () => void;\n visibilityHandler: () => void;\n topbarObserver: ResizeObserver | null;\n talkController: Pick<TalkController, \"stop\">;\n};\n\nexport function handleConnected(host: LifecycleHost) {\n host.basePath = inferBasePath();\n void loadControlUiBootstrapConfig(host);\n applySettingsFromUrl(host as unknown as Parameters<typeof applySettingsFromUrl>[0]);\n syncTabWithLocation(host as unknown as Parameters<typeof syncTabWithLocation>[0], true);\n syncThemeWithSettings(host as unknown as Parameters<typeof syncThemeWithSettings>[0]);\n attachThemeListener(host as unknown as Parameters<typeof attachThemeListener>[0]);\n window.addEventListener(\"popstate\", host.popStateHandler);\n if (typeof document !== \"undefined\") {\n document.addEventListener(\"visibilitychange\", host.visibilityHandler);\n }\n connectGateway(host as unknown as Parameters<typeof connectGateway>[0]);\n startNodesPolling(host as unknown as Parameters<typeof startNodesPolling>[0]);\n startSessionRunsPolling(host as unknown as Parameters<typeof startSessionRunsPolling>[0]);\n startSessionRunsTick(host as unknown as Parameters<typeof startSessionRunsTick>[0]);\n startDreamsPolling(host as unknown as Parameters<typeof startDreamsPolling>[0]);\n if (host.tab === \"logs\") {\n startLogsPolling(host as unknown as Parameters<typeof startLogsPolling>[0]);\n }\n if (host.tab === \"debug\") {\n startDebugPolling(host as unknown as Parameters<typeof startDebugPolling>[0]);\n }\n}\n\nexport function handleVisibilityChange(host: LifecycleHost) {\n handleDreamsVisibilityChange(host as unknown as DreamsHost);\n}\n\nexport function handleFirstUpdated(host: LifecycleHost) {\n observeTopbar(host as unknown as Parameters<typeof observeTopbar>[0]);\n}\n\nexport function handleDisconnected(host: LifecycleHost) {\n try {\n host.talkController.stop().catch(() => undefined);\n } catch {\n // A misbehaving stop() may throw synchronously instead of rejecting; the\n // rest of teardown must still run.\n }\n window.removeEventListener(\"popstate\", host.popStateHandler);\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", host.visibilityHandler);\n }\n stopNodesPolling(host as unknown as Parameters<typeof stopNodesPolling>[0]);\n stopLogsPolling(host as unknown as Parameters<typeof stopLogsPolling>[0]);\n stopDebugPolling(host as unknown as Parameters<typeof stopDebugPolling>[0]);\n stopSessionRunsPolling(host as unknown as Parameters<typeof stopSessionRunsPolling>[0]);\n stopSessionRunsTick(host as unknown as Parameters<typeof stopSessionRunsTick>[0]);\n stopDreamsPolling(host as unknown as Parameters<typeof stopDreamsPolling>[0]);\n host.client?.stop();\n host.client = null;\n host.connected = false;\n detachThemeListener(host as unknown as Parameters<typeof detachThemeListener>[0]);\n host.topbarObserver?.disconnect();\n host.topbarObserver = null;\n}\n\nexport function handleUpdated(host: LifecycleHost, changed: Map<PropertyKey, unknown>) {\n if (host.tab === \"chat\" && host.chatManualRefreshInFlight) {\n return;\n }\n if (\n host.tab === \"chat\" &&\n (changed.has(\"chatMessages\") ||\n changed.has(\"chatToolMessages\") ||\n changed.has(\"chatStream\") ||\n changed.has(\"chatLoading\") ||\n changed.has(\"tab\"))\n ) {\n const forcedByTab = changed.has(\"tab\");\n const forcedByLoad =\n changed.has(\"chatLoading\") && changed.get(\"chatLoading\") === true && !host.chatLoading;\n scheduleChatScroll(\n host as unknown as Parameters<typeof scheduleChatScroll>[0],\n forcedByTab || forcedByLoad || !host.chatHasAutoScrolled,\n );\n }\n if (\n host.tab === \"logs\" &&\n (changed.has(\"logsEntries\") || changed.has(\"logsAutoFollow\") || changed.has(\"tab\"))\n ) {\n if (host.logsAutoFollow && host.logsAtBottom) {\n scheduleLogsScroll(\n host as unknown as Parameters<typeof scheduleLogsScroll>[0],\n changed.has(\"tab\") || changed.has(\"logsAutoFollow\"),\n );\n }\n }\n}\n","import { html, type TemplateResult } from \"lit\";\n\nexport type LazyViewHost = {\n requestUpdate: () => void;\n};\n\nexport function createLazyView<TModule, TProps>(\n loadModule: () => Promise<TModule>,\n selectRenderer: (module: TModule) => (props: TProps) => TemplateResult,\n loadingLabel: string,\n) {\n let moduleValue: TModule | null = null;\n let loadPromise: Promise<TModule> | null = null;\n let loadError: string | null = null;\n // The chunk load is shared by every host that renders this view, so every host\n // that is currently showing the placeholder has to be re-rendered when it\n // settles. Notifying only the host that happened to start the load leaves any\n // later host stuck on \"Loading ...\" forever, because nothing else asks it to\n // update.\n const pendingHosts = new Set<LazyViewHost>();\n\n const notifyPendingHosts = () => {\n const hosts = [...pendingHosts];\n pendingHosts.clear();\n for (const pending of hosts) {\n pending.requestUpdate();\n }\n };\n\n return {\n render(host: LazyViewHost, props: TProps): TemplateResult {\n if (moduleValue) {\n return selectRenderer(moduleValue)(props);\n }\n if (loadError) {\n return html`<div class=\"callout danger\">${loadError}</div>`;\n }\n pendingHosts.add(host);\n loadPromise ??= loadModule()\n .then((loaded) => {\n moduleValue = loaded;\n notifyPendingHosts();\n return loaded;\n })\n .catch((error: unknown) => {\n loadError = error instanceof Error ? error.message : \"View failed to load\";\n notifyPendingHosts();\n throw error;\n });\n void loadPromise.catch(() => undefined);\n return html`<div class=\"muted\">${loadingLabel}</div>`;\n },\n };\n}\n","import { createLazyView } from \"./lazy-view.ts\";\n\nexport const consoleViews = {\n agents: createLazyView(\n () => import(\"./views/agents.ts\"),\n (module) => module.renderAgents,\n \"Loading agents...\",\n ),\n channels: createLazyView(\n () => import(\"./views/channels.ts\"),\n (module) => module.renderChannels,\n \"Loading channels...\",\n ),\n chat: createLazyView(\n () => import(\"./views/chat.ts\"),\n (module) => module.renderChat,\n \"Loading Chat...\",\n ),\n config: createLazyView(\n () => import(\"./views/config.ts\"),\n (module) => module.renderConfig,\n \"Loading config...\",\n ),\n cron: createLazyView(\n () => import(\"./views/cron.ts\"),\n (module) => module.renderCron,\n \"Loading cron...\",\n ),\n debug: createLazyView(\n () => import(\"./views/debug.ts\"),\n (module) => module.renderDebug,\n \"Loading debug...\",\n ),\n instances: createLazyView(\n () => import(\"./views/instances.ts\"),\n (module) => module.renderInstances,\n \"Loading instances...\",\n ),\n logs: createLazyView(\n () => import(\"./views/logs.ts\"),\n (module) => module.renderLogs,\n \"Loading logs...\",\n ),\n dreams: createLazyView(\n () => import(\"./views/dreams.ts\"),\n (module) => module.renderDreams,\n \"Loading dreams...\",\n ),\n learning: createLazyView(\n () => import(\"./views/learning.ts\"),\n (module) => module.renderLearning,\n \"Loading learning...\",\n ),\n nodes: createLazyView(\n () => import(\"./views/nodes.ts\"),\n (module) => module.renderNodes,\n \"Loading nodes...\",\n ),\n overview: createLazyView(\n () => import(\"./views/overview.ts\"),\n (module) => module.renderOverview,\n \"Loading overview...\",\n ),\n sessions: createLazyView(\n () => import(\"./views/sessions.ts\"),\n (module) => module.renderSessions,\n \"Loading sessions...\",\n ),\n skills: createLazyView(\n () => import(\"./views/skills.ts\"),\n (module) => module.renderSkills,\n \"Loading skills...\",\n ),\n talk: createLazyView(\n () => import(\"./views/talk.ts\"),\n (module) => module.renderTalk,\n \"Loading Talk...\",\n ),\n usage: createLazyView(\n () => import(\"./views/usage.ts\"),\n (module) => module.renderUsage,\n \"Loading usage...\",\n ),\n};\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type { SessionsUsageResult, CostUsageSummary, SessionUsageTimeSeries } from \"../types.ts\";\nimport type { SessionLogEntry } from \"../views/usage.ts\";\n\nexport type UsageState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n usageLoading: boolean;\n usageResult: SessionsUsageResult | null;\n usageCostSummary: CostUsageSummary | null;\n usageError: string | null;\n usageStartDate: string;\n usageEndDate: string;\n usageSelectedSessions: string[];\n usageSelectedDays: string[];\n usageTimeSeries: SessionUsageTimeSeries | null;\n usageTimeSeriesLoading: boolean;\n usageTimeSeriesCursorStart: number | null;\n usageTimeSeriesCursorEnd: number | null;\n usageSessionLogs: SessionLogEntry[] | null;\n usageSessionLogsLoading: boolean;\n usageTimeZone: \"local\" | \"utc\";\n settings?: { gatewayUrl?: string };\n};\n\ntype DateInterpretationMode = \"utc\" | \"gateway\" | \"specific\";\n\ntype UsageDateInterpretationParams = {\n mode: DateInterpretationMode;\n utcOffset?: string;\n};\n\nconst LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY = \"openclaw.control.usage.date-params.v1\";\nconst LEGACY_USAGE_DATE_PARAMS_DEFAULT_GATEWAY_KEY = \"__default__\";\nconst LEGACY_USAGE_DATE_PARAMS_MODE_RE = /unexpected property ['\"]mode['\"]/i;\nconst LEGACY_USAGE_DATE_PARAMS_OFFSET_RE = /unexpected property ['\"]utcoffset['\"]/i;\nconst LEGACY_USAGE_DATE_PARAMS_INVALID_RE = /invalid sessions\\.usage params/i;\n\nlet legacyUsageDateParamsCache: Set<string> | null = null;\n\nfunction getLocalStorage(): Storage | null {\n // Support browser runtime and node tests (when localStorage is stubbed globally).\n if (typeof window !== \"undefined\" && window.localStorage) {\n return window.localStorage;\n }\n if (typeof localStorage !== \"undefined\") {\n return localStorage;\n }\n return null;\n}\n\nfunction loadLegacyUsageDateParamsCache(): Set<string> {\n const storage = getLocalStorage();\n if (!storage) {\n return new Set<string>();\n }\n try {\n const raw = storage.getItem(LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY);\n if (!raw) {\n return new Set<string>();\n }\n const parsed = JSON.parse(raw) as { unsupportedGatewayKeys?: unknown } | null;\n if (!parsed || !Array.isArray(parsed.unsupportedGatewayKeys)) {\n return new Set<string>();\n }\n return new Set(\n parsed.unsupportedGatewayKeys\n .filter((entry): entry is string => typeof entry === \"string\")\n .map((entry) => entry.trim())\n .filter(Boolean),\n );\n } catch {\n return new Set<string>();\n }\n}\n\nfunction persistLegacyUsageDateParamsCache(cache: Set<string>) {\n const storage = getLocalStorage();\n if (!storage) {\n return;\n }\n try {\n storage.setItem(\n LEGACY_USAGE_DATE_PARAMS_STORAGE_KEY,\n JSON.stringify({ unsupportedGatewayKeys: Array.from(cache) }),\n );\n } catch {\n // ignore quota/private-mode failures\n }\n}\n\nfunction getLegacyUsageDateParamsCache(): Set<string> {\n if (!legacyUsageDateParamsCache) {\n legacyUsageDateParamsCache = loadLegacyUsageDateParamsCache();\n }\n return legacyUsageDateParamsCache;\n}\n\nfunction normalizeGatewayCompatibilityKey(gatewayUrl?: string): string {\n const trimmed = gatewayUrl?.trim();\n if (!trimmed) {\n return LEGACY_USAGE_DATE_PARAMS_DEFAULT_GATEWAY_KEY;\n }\n try {\n const parsed = new URL(trimmed);\n const pathname = parsed.pathname === \"/\" ? \"\" : parsed.pathname;\n return `${parsed.protocol}//${parsed.host}${pathname}`.toLowerCase();\n } catch {\n return trimmed.toLowerCase();\n }\n}\n\nfunction resolveGatewayCompatibilityKey(state: UsageState): string {\n return normalizeGatewayCompatibilityKey(state.settings?.gatewayUrl);\n}\n\nfunction shouldSendLegacyDateInterpretation(state: UsageState): boolean {\n return !getLegacyUsageDateParamsCache().has(resolveGatewayCompatibilityKey(state));\n}\n\nfunction rememberLegacyDateInterpretation(state: UsageState) {\n const cache = getLegacyUsageDateParamsCache();\n cache.add(resolveGatewayCompatibilityKey(state));\n persistLegacyUsageDateParamsCache(cache);\n}\n\nfunction isLegacyDateInterpretationUnsupportedError(err: unknown): boolean {\n const message = toErrorMessage(err);\n return (\n LEGACY_USAGE_DATE_PARAMS_INVALID_RE.test(message) &&\n (LEGACY_USAGE_DATE_PARAMS_MODE_RE.test(message) ||\n LEGACY_USAGE_DATE_PARAMS_OFFSET_RE.test(message))\n );\n}\n\nconst formatUtcOffset = (timezoneOffsetMinutes: number): string => {\n // `Date#getTimezoneOffset()` is minutes to add to local time to reach UTC.\n // Convert to UTC±H[:MM] where positive means east of UTC.\n const offsetFromUtcMinutes = -timezoneOffsetMinutes;\n const sign = offsetFromUtcMinutes >= 0 ? \"+\" : \"-\";\n const absMinutes = Math.abs(offsetFromUtcMinutes);\n const hours = Math.floor(absMinutes / 60);\n const minutes = absMinutes % 60;\n return minutes === 0\n ? `UTC${sign}${hours}`\n : `UTC${sign}${hours}:${minutes.toString().padStart(2, \"0\")}`;\n};\n\nconst buildDateInterpretationParams = (\n timeZone: \"local\" | \"utc\",\n includeDateInterpretation: boolean,\n): UsageDateInterpretationParams | undefined => {\n if (!includeDateInterpretation) {\n return undefined;\n }\n if (timeZone === \"utc\") {\n return { mode: \"utc\" };\n }\n return {\n mode: \"specific\",\n utcOffset: formatUtcOffset(new Date().getTimezoneOffset()),\n };\n};\n\nfunction toErrorMessage(err: unknown): string {\n if (typeof err === \"string\") {\n return err;\n }\n if (err instanceof Error && typeof err.message === \"string\" && err.message.trim()) {\n return err.message;\n }\n if (err && typeof err === \"object\") {\n try {\n const serialized = JSON.stringify(err);\n if (serialized) {\n return serialized;\n }\n } catch {\n // ignore\n }\n }\n return \"request failed\";\n}\n\nexport async function loadUsage(\n state: UsageState,\n overrides?: {\n startDate?: string;\n endDate?: string;\n },\n) {\n // Capture client for TS18047 work around on it being possibly null\n const client = state.client;\n if (!client || !state.connected) {\n return;\n }\n if (state.usageLoading) {\n return;\n }\n state.usageLoading = true;\n state.usageError = null;\n try {\n const startDate = overrides?.startDate ?? state.usageStartDate;\n const endDate = overrides?.endDate ?? state.usageEndDate;\n const runUsageRequests = async (includeDateInterpretation: boolean) => {\n const dateInterpretation = buildDateInterpretationParams(\n state.usageTimeZone,\n includeDateInterpretation,\n );\n return await Promise.all([\n client.request(\"sessions.usage\", {\n startDate,\n endDate,\n ...dateInterpretation,\n limit: 1000, // Cap at 1000 sessions\n includeContextWeight: true,\n }),\n client.request(\"usage.cost\", {\n startDate,\n endDate,\n ...dateInterpretation,\n }),\n ]);\n };\n\n const applyUsageResults = (sessionsRes: unknown, costRes: unknown) => {\n if (sessionsRes) {\n state.usageResult = sessionsRes as SessionsUsageResult;\n }\n if (costRes) {\n state.usageCostSummary = costRes as CostUsageSummary;\n }\n };\n\n const includeDateInterpretation = shouldSendLegacyDateInterpretation(state);\n try {\n const [sessionsRes, costRes] = await runUsageRequests(includeDateInterpretation);\n applyUsageResults(sessionsRes, costRes);\n } catch (err) {\n if (includeDateInterpretation && isLegacyDateInterpretationUnsupportedError(err)) {\n // Older gateways reject `mode`/`utcOffset` in `sessions.usage`.\n // Remember this per gateway and retry once without those fields.\n rememberLegacyDateInterpretation(state);\n const [sessionsRes, costRes] = await runUsageRequests(false);\n applyUsageResults(sessionsRes, costRes);\n } else {\n throw err;\n }\n }\n } catch (err) {\n state.usageError = toErrorMessage(err);\n } finally {\n state.usageLoading = false;\n }\n}\n\nexport const __test = {\n formatUtcOffset,\n buildDateInterpretationParams,\n toErrorMessage,\n isLegacyDateInterpretationUnsupportedError,\n normalizeGatewayCompatibilityKey,\n shouldSendLegacyDateInterpretation,\n rememberLegacyDateInterpretation,\n resetLegacyUsageDateParamsCache: () => {\n legacyUsageDateParamsCache = null;\n },\n};\n\nexport async function loadSessionTimeSeries(state: UsageState, sessionKey: string) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.usageTimeSeriesLoading) {\n return;\n }\n state.usageTimeSeriesLoading = true;\n state.usageTimeSeries = null;\n try {\n const res = await state.client.request(\"sessions.usage.timeseries\", { key: sessionKey });\n if (res) {\n state.usageTimeSeries = res as SessionUsageTimeSeries;\n }\n } catch {\n // Silently fail - time series is optional\n state.usageTimeSeries = null;\n } finally {\n state.usageTimeSeriesLoading = false;\n }\n}\n\nexport async function loadSessionLogs(state: UsageState, sessionKey: string) {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.usageSessionLogsLoading) {\n return;\n }\n state.usageSessionLogsLoading = true;\n state.usageSessionLogs = null;\n try {\n const res = await state.client.request(\"sessions.usage.logs\", {\n key: sessionKey,\n limit: 1000,\n });\n if (res && Array.isArray((res as { logs: SessionLogEntry[] }).logs)) {\n state.usageSessionLogs = (res as { logs: SessionLogEntry[] }).logs;\n }\n } catch {\n // Silently fail - logs are optional\n state.usageSessionLogs = null;\n } finally {\n state.usageSessionLogsLoading = false;\n }\n}\n","import { nothing } from \"lit\";\nimport { consoleViews } from \"./app-view-dispatcher.ts\";\nimport type { AppViewState } from \"./app-view-state.ts\";\nimport type { UsageState } from \"./controllers/usage.ts\";\nimport { loadUsage, loadSessionTimeSeries, loadSessionLogs } from \"./controllers/usage.ts\";\n\n// Module-scope debounce for usage date changes (avoids type-unsafe hacks on state object)\nlet usageDateDebounceTimeout: number | null = null;\nconst debouncedLoadUsage = (state: UsageState) => {\n if (usageDateDebounceTimeout) {\n clearTimeout(usageDateDebounceTimeout);\n }\n usageDateDebounceTimeout = window.setTimeout(() => void loadUsage(state), 400);\n};\n\nexport function renderUsageTab(state: AppViewState) {\n if (state.tab !== \"usage\") {\n return nothing;\n }\n\n return consoleViews.usage.render(state, {\n loading: state.usageLoading,\n error: state.usageError,\n startDate: state.usageStartDate,\n endDate: state.usageEndDate,\n sessions: state.usageResult?.sessions ?? [],\n sessionsLimitReached: (state.usageResult?.sessions?.length ?? 0) >= 1000,\n totals: state.usageResult?.totals ?? null,\n aggregates: state.usageResult?.aggregates ?? null,\n costDaily: state.usageCostSummary?.daily ?? [],\n selectedSessions: state.usageSelectedSessions,\n selectedDays: state.usageSelectedDays,\n selectedHours: state.usageSelectedHours,\n chartMode: state.usageChartMode,\n dailyChartMode: state.usageDailyChartMode,\n timeSeriesMode: state.usageTimeSeriesMode,\n timeSeriesBreakdownMode: state.usageTimeSeriesBreakdownMode,\n timeSeries: state.usageTimeSeries,\n timeSeriesLoading: state.usageTimeSeriesLoading,\n timeSeriesCursorStart: state.usageTimeSeriesCursorStart,\n timeSeriesCursorEnd: state.usageTimeSeriesCursorEnd,\n sessionLogs: state.usageSessionLogs,\n sessionLogsLoading: state.usageSessionLogsLoading,\n sessionLogsExpanded: state.usageSessionLogsExpanded,\n logFilterRoles: state.usageLogFilterRoles,\n logFilterTools: state.usageLogFilterTools,\n logFilterHasTools: state.usageLogFilterHasTools,\n logFilterQuery: state.usageLogFilterQuery,\n query: state.usageQuery,\n queryDraft: state.usageQueryDraft,\n sessionSort: state.usageSessionSort,\n sessionSortDir: state.usageSessionSortDir,\n recentSessions: state.usageRecentSessions,\n sessionsTab: state.usageSessionsTab,\n visibleColumns: state.usageVisibleColumns as import(\"./views/usage.ts\").UsageColumnId[],\n timeZone: state.usageTimeZone,\n contextExpanded: state.usageContextExpanded,\n headerPinned: state.usageHeaderPinned,\n onStartDateChange: (date) => {\n state.usageStartDate = date;\n state.usageSelectedDays = [];\n state.usageSelectedHours = [];\n state.usageSelectedSessions = [];\n debouncedLoadUsage(state);\n },\n onEndDateChange: (date) => {\n state.usageEndDate = date;\n state.usageSelectedDays = [];\n state.usageSelectedHours = [];\n state.usageSelectedSessions = [];\n debouncedLoadUsage(state);\n },\n onRefresh: () => loadUsage(state),\n onTimeZoneChange: (zone) => {\n state.usageTimeZone = zone;\n state.usageSelectedDays = [];\n state.usageSelectedHours = [];\n state.usageSelectedSessions = [];\n void loadUsage(state);\n },\n onToggleContextExpanded: () => {\n state.usageContextExpanded = !state.usageContextExpanded;\n },\n onToggleSessionLogsExpanded: () => {\n state.usageSessionLogsExpanded = !state.usageSessionLogsExpanded;\n },\n onLogFilterRolesChange: (next) => {\n state.usageLogFilterRoles = next;\n },\n onLogFilterToolsChange: (next) => {\n state.usageLogFilterTools = next;\n },\n onLogFilterHasToolsChange: (next) => {\n state.usageLogFilterHasTools = next;\n },\n onLogFilterQueryChange: (next) => {\n state.usageLogFilterQuery = next;\n },\n onLogFilterClear: () => {\n state.usageLogFilterRoles = [];\n state.usageLogFilterTools = [];\n state.usageLogFilterHasTools = false;\n state.usageLogFilterQuery = \"\";\n },\n onToggleHeaderPinned: () => {\n state.usageHeaderPinned = !state.usageHeaderPinned;\n },\n onSelectHour: (hour, shiftKey) => {\n if (shiftKey && state.usageSelectedHours.length > 0) {\n const allHours = Array.from({ length: 24 }, (_, i) => i);\n const lastSelected = state.usageSelectedHours[state.usageSelectedHours.length - 1];\n const lastIdx = allHours.indexOf(lastSelected);\n const thisIdx = allHours.indexOf(hour);\n if (lastIdx !== -1 && thisIdx !== -1) {\n const [start, end] = lastIdx < thisIdx ? [lastIdx, thisIdx] : [thisIdx, lastIdx];\n const range = allHours.slice(start, end + 1);\n state.usageSelectedHours = [...new Set([...state.usageSelectedHours, ...range])];\n }\n } else {\n if (state.usageSelectedHours.includes(hour)) {\n state.usageSelectedHours = state.usageSelectedHours.filter((h) => h !== hour);\n } else {\n state.usageSelectedHours = [...state.usageSelectedHours, hour];\n }\n }\n },\n onQueryDraftChange: (query) => {\n state.usageQueryDraft = query;\n if (state.usageQueryDebounceTimer) {\n window.clearTimeout(state.usageQueryDebounceTimer);\n }\n state.usageQueryDebounceTimer = window.setTimeout(() => {\n state.usageQuery = state.usageQueryDraft;\n state.usageQueryDebounceTimer = null;\n }, 250);\n },\n onApplyQuery: () => {\n if (state.usageQueryDebounceTimer) {\n window.clearTimeout(state.usageQueryDebounceTimer);\n state.usageQueryDebounceTimer = null;\n }\n state.usageQuery = state.usageQueryDraft;\n },\n onClearQuery: () => {\n if (state.usageQueryDebounceTimer) {\n window.clearTimeout(state.usageQueryDebounceTimer);\n state.usageQueryDebounceTimer = null;\n }\n state.usageQueryDraft = \"\";\n state.usageQuery = \"\";\n },\n onSessionSortChange: (sort) => {\n state.usageSessionSort = sort;\n },\n onSessionSortDirChange: (dir) => {\n state.usageSessionSortDir = dir;\n },\n onSessionsTabChange: (tab) => {\n state.usageSessionsTab = tab;\n },\n onToggleColumn: (column) => {\n if (state.usageVisibleColumns.includes(column)) {\n state.usageVisibleColumns = state.usageVisibleColumns.filter((entry) => entry !== column);\n } else {\n state.usageVisibleColumns = [...state.usageVisibleColumns, column];\n }\n },\n onSelectSession: (key, shiftKey) => {\n state.usageTimeSeries = null;\n state.usageSessionLogs = null;\n state.usageRecentSessions = [\n key,\n ...state.usageRecentSessions.filter((entry) => entry !== key),\n ].slice(0, 8);\n\n if (shiftKey && state.usageSelectedSessions.length > 0) {\n // Shift-click: select range from last selected to this session\n // Sort sessions same way as displayed (by tokens or cost descending)\n const isTokenMode = state.usageChartMode === \"tokens\";\n const sortedSessions = [...(state.usageResult?.sessions ?? [])].toSorted((a, b) => {\n const valA = isTokenMode ? (a.usage?.totalTokens ?? 0) : (a.usage?.totalCost ?? 0);\n const valB = isTokenMode ? (b.usage?.totalTokens ?? 0) : (b.usage?.totalCost ?? 0);\n return valB - valA;\n });\n const allKeys = sortedSessions.map((s) => s.key);\n const lastSelected = state.usageSelectedSessions[state.usageSelectedSessions.length - 1];\n const lastIdx = allKeys.indexOf(lastSelected);\n const thisIdx = allKeys.indexOf(key);\n if (lastIdx !== -1 && thisIdx !== -1) {\n const [start, end] = lastIdx < thisIdx ? [lastIdx, thisIdx] : [thisIdx, lastIdx];\n const range = allKeys.slice(start, end + 1);\n const newSelection = [...new Set([...state.usageSelectedSessions, ...range])];\n state.usageSelectedSessions = newSelection;\n }\n } else {\n // Regular click: focus a single session (so details always open).\n // Click the focused session again to clear selection.\n if (state.usageSelectedSessions.length === 1 && state.usageSelectedSessions[0] === key) {\n state.usageSelectedSessions = [];\n } else {\n state.usageSelectedSessions = [key];\n }\n }\n\n // Reset range selection when switching sessions\n state.usageTimeSeriesCursorStart = null;\n state.usageTimeSeriesCursorEnd = null;\n\n // Load timeseries/logs only if exactly one session selected\n if (state.usageSelectedSessions.length === 1) {\n void loadSessionTimeSeries(state, state.usageSelectedSessions[0]);\n void loadSessionLogs(state, state.usageSelectedSessions[0]);\n }\n },\n onSelectDay: (day, shiftKey) => {\n if (shiftKey && state.usageSelectedDays.length > 0) {\n // Shift-click: select range from last selected to this day\n const allDays = (state.usageCostSummary?.daily ?? []).map((d) => d.date);\n const lastSelected = state.usageSelectedDays[state.usageSelectedDays.length - 1];\n const lastIdx = allDays.indexOf(lastSelected);\n const thisIdx = allDays.indexOf(day);\n if (lastIdx !== -1 && thisIdx !== -1) {\n const [start, end] = lastIdx < thisIdx ? [lastIdx, thisIdx] : [thisIdx, lastIdx];\n const range = allDays.slice(start, end + 1);\n // Merge with existing selection\n const newSelection = [...new Set([...state.usageSelectedDays, ...range])];\n state.usageSelectedDays = newSelection;\n }\n } else {\n // Regular click: toggle single day\n if (state.usageSelectedDays.includes(day)) {\n state.usageSelectedDays = state.usageSelectedDays.filter((d) => d !== day);\n } else {\n state.usageSelectedDays = [day];\n }\n }\n },\n onChartModeChange: (mode) => {\n state.usageChartMode = mode;\n },\n onDailyChartModeChange: (mode) => {\n state.usageDailyChartMode = mode;\n },\n onTimeSeriesModeChange: (mode) => {\n state.usageTimeSeriesMode = mode;\n },\n onTimeSeriesBreakdownChange: (mode) => {\n state.usageTimeSeriesBreakdownMode = mode;\n },\n onTimeSeriesCursorRangeChange: (start, end) => {\n state.usageTimeSeriesCursorStart = start;\n state.usageTimeSeriesCursorEnd = end;\n },\n onClearDays: () => {\n state.usageSelectedDays = [];\n },\n onClearHours: () => {\n state.usageSelectedHours = [];\n },\n onClearSessions: () => {\n state.usageSelectedSessions = [];\n state.usageTimeSeries = null;\n state.usageSessionLogs = null;\n },\n onClearFilters: () => {\n state.usageSelectedDays = [];\n state.usageSelectedHours = [];\n state.usageSelectedSessions = [];\n state.usageTimeSeries = null;\n state.usageSessionLogs = null;\n },\n });\n}\n","import { html, nothing } from \"lit\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { t } from \"../i18n/index.ts\";\nimport { refreshChat } from \"./app-chat.ts\";\nimport { syncUrlWithSessionKey } from \"./app-settings.ts\";\nimport type { AppViewState } from \"./app-view-state.ts\";\nimport { OpenClawApp } from \"./app.ts\";\nimport { ChatState, loadChatHistory } from \"./controllers/chat.ts\";\nimport { icons } from \"./icons.ts\";\nimport { iconForTab, pathForTab, titleForTab, type Tab } from \"./navigation.ts\";\nimport type { ThemeTransitionContext } from \"./theme-transition.ts\";\nimport type { ThemeMode } from \"./theme.ts\";\nimport type { SessionsListResult } from \"./types.ts\";\n\ntype SessionDefaultsSnapshot = {\n mainSessionKey?: string;\n mainKey?: string;\n};\n\nfunction resolveSidebarChatSessionKey(state: AppViewState): string {\n const snapshot = state.hello?.snapshot as\n | { sessionDefaults?: SessionDefaultsSnapshot }\n | undefined;\n const mainSessionKey = snapshot?.sessionDefaults?.mainSessionKey?.trim();\n if (mainSessionKey) {\n return mainSessionKey;\n }\n const mainKey = snapshot?.sessionDefaults?.mainKey?.trim();\n if (mainKey) {\n return mainKey;\n }\n return \"main\";\n}\n\nfunction resetChatStateForSessionSwitch(state: AppViewState, sessionKey: string) {\n state.sessionKey = sessionKey;\n state.chatMessage = \"\";\n state.chatStream = null;\n (state as unknown as OpenClawApp).chatStreamStartedAt = null;\n state.chatRunId = null;\n (state as unknown as OpenClawApp).resetToolStream();\n (state as unknown as OpenClawApp).resetChatScroll();\n state.applySettings({\n ...state.settings,\n sessionKey,\n lastActiveSessionKey: sessionKey,\n });\n}\n\nexport function renderTab(state: AppViewState, tab: Tab) {\n const href = pathForTab(tab, state.basePath);\n return html`\n <a\n href=${href}\n class=\"nav-item ${state.tab === tab ? \"active\" : \"\"}\"\n @click=${(event: MouseEvent) => {\n if (\n event.defaultPrevented ||\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n event.preventDefault();\n if (tab === \"chat\") {\n const mainSessionKey = resolveSidebarChatSessionKey(state);\n if (state.sessionKey !== mainSessionKey) {\n resetChatStateForSessionSwitch(state, mainSessionKey);\n void state.loadAssistantIdentity();\n }\n }\n state.setTab(tab);\n }}\n title=${titleForTab(tab)}\n >\n <span class=\"nav-item__icon\" aria-hidden=\"true\">${icons[iconForTab(tab)]}</span>\n <span class=\"nav-item__text\">${titleForTab(tab)}</span>\n ${\n tab === \"learning\" && (state.overview?.proposals?.pending ?? 0) > 0\n ? html`<span class=\"nav-item__badge\">${state.overview?.proposals?.pending}</span>`\n : nothing\n }\n </a>\n `;\n}\n\nfunction renderCronFilterIcon(hiddenCount: number) {\n return html`\n <span style=\"position: relative; display: inline-flex; align-items: center;\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <polyline points=\"12 6 12 12 16 14\"></polyline>\n </svg>\n ${\n hiddenCount > 0\n ? html`<span\n style=\"\n position: absolute;\n top: -5px;\n right: -6px;\n background: var(--accent);\n color: #fff;\n border-radius: 999px;\n font-size: 9px;\n line-height: 1;\n padding: 1px 3px;\n pointer-events: none;\n \"\n >${hiddenCount}</span\n >`\n : \"\"\n }\n </span>\n `;\n}\n\nexport function renderChatControls(state: AppViewState) {\n const mainSessionKey = resolveMainSessionKey(state.hello, state.sessionsResult);\n const hideCron = state.sessionsHideCron ?? true;\n const hiddenCronCount = hideCron\n ? countHiddenCronSessions(state.sessionKey, state.sessionsResult)\n : 0;\n const sessionOptions = resolveSessionOptions(\n state.sessionKey,\n state.sessionsResult,\n mainSessionKey,\n hideCron,\n );\n const disableThinkingToggle = state.onboarding;\n const disableFocusToggle = state.onboarding;\n const showThinking = state.onboarding ? false : state.settings.chatShowThinking;\n const focusActive = state.onboarding ? true : state.settings.chatFocusMode;\n // Refresh icon\n const refreshIcon = html`\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\"></path>\n <path d=\"M21 3v5h-5\"></path>\n </svg>\n `;\n const focusIcon = html`\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M4 7V4h3\"></path>\n <path d=\"M20 7V4h-3\"></path>\n <path d=\"M4 17v3h3\"></path>\n <path d=\"M20 17v3h-3\"></path>\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\n </svg>\n `;\n return html`\n <div class=\"chat-controls\">\n <label class=\"field chat-controls__session\">\n <select\n .value=${state.sessionKey}\n ?disabled=${!state.connected}\n @change=${(e: Event) => {\n const next = (e.target as HTMLSelectElement).value;\n state.sessionKey = next;\n state.chatMessage = \"\";\n state.chatStream = null;\n (state as unknown as OpenClawApp).chatStreamStartedAt = null;\n state.chatRunId = null;\n (state as unknown as OpenClawApp).resetToolStream();\n (state as unknown as OpenClawApp).resetChatScroll();\n state.applySettings({\n ...state.settings,\n sessionKey: next,\n lastActiveSessionKey: next,\n });\n void state.loadAssistantIdentity();\n syncUrlWithSessionKey(\n state as unknown as Parameters<typeof syncUrlWithSessionKey>[0],\n next,\n true,\n );\n void loadChatHistory(state as unknown as ChatState);\n }}\n >\n ${repeat(\n sessionOptions,\n (entry) => entry.key,\n (entry) =>\n html`<option value=${entry.key} title=${entry.key}>\n ${entry.displayName ?? entry.key}\n </option>`,\n )}\n </select>\n </label>\n <button\n class=\"btn btn--sm btn--icon\"\n ?disabled=${state.chatLoading || !state.connected}\n @click=${async () => {\n const app = state as unknown as OpenClawApp;\n app.chatManualRefreshInFlight = true;\n app.chatNewMessagesBelow = false;\n await app.updateComplete;\n app.resetToolStream();\n try {\n await refreshChat(state as unknown as Parameters<typeof refreshChat>[0], {\n scheduleScroll: false,\n });\n app.scrollToBottom({ smooth: true });\n } finally {\n requestAnimationFrame(() => {\n app.chatManualRefreshInFlight = false;\n app.chatNewMessagesBelow = false;\n });\n }\n }}\n title=${t(\"chat.refreshTitle\")}\n >\n ${refreshIcon}\n </button>\n <span class=\"chat-controls__separator\">|</span>\n <button\n class=\"btn btn--sm btn--icon ${showThinking ? \"active\" : \"\"}\"\n ?disabled=${disableThinkingToggle}\n @click=${() => {\n if (disableThinkingToggle) {\n return;\n }\n state.applySettings({\n ...state.settings,\n chatShowThinking: !state.settings.chatShowThinking,\n });\n }}\n aria-pressed=${showThinking}\n title=${disableThinkingToggle ? t(\"chat.onboardingDisabled\") : t(\"chat.thinkingToggle\")}\n >\n ${icons.brain}\n </button>\n <button\n class=\"btn btn--sm btn--icon ${focusActive ? \"active\" : \"\"}\"\n ?disabled=${disableFocusToggle}\n @click=${() => {\n if (disableFocusToggle) {\n return;\n }\n state.applySettings({\n ...state.settings,\n chatFocusMode: !state.settings.chatFocusMode,\n });\n }}\n aria-pressed=${focusActive}\n title=${disableFocusToggle ? t(\"chat.onboardingDisabled\") : t(\"chat.focusToggle\")}\n >\n ${focusIcon}\n </button>\n <button\n class=\"btn btn--sm btn--icon ${hideCron ? \"active\" : \"\"}\"\n @click=${() => {\n state.sessionsHideCron = !hideCron;\n }}\n aria-pressed=${hideCron}\n title=${\n hideCron\n ? hiddenCronCount > 0\n ? t(\"chat.showCronSessionsHidden\", { count: String(hiddenCronCount) })\n : t(\"chat.showCronSessions\")\n : t(\"chat.hideCronSessions\")\n }\n >\n ${renderCronFilterIcon(hiddenCronCount)}\n </button>\n </div>\n `;\n}\n\nfunction resolveMainSessionKey(\n hello: AppViewState[\"hello\"],\n sessions: SessionsListResult | null,\n): string | null {\n const snapshot = hello?.snapshot as { sessionDefaults?: SessionDefaultsSnapshot } | undefined;\n const mainSessionKey = snapshot?.sessionDefaults?.mainSessionKey?.trim();\n if (mainSessionKey) {\n return mainSessionKey;\n }\n const mainKey = snapshot?.sessionDefaults?.mainKey?.trim();\n if (mainKey) {\n return mainKey;\n }\n if (sessions?.sessions?.some((row) => row.key === \"main\")) {\n return \"main\";\n }\n return null;\n}\n\n/* ── Channel display labels ────────────────────────────── */\nconst CHANNEL_LABELS: Record<string, string> = {\n bluebubbles: \"iMessage\",\n telegram: \"Telegram\",\n discord: \"Discord\",\n signal: \"Signal\",\n slack: \"Slack\",\n whatsapp: \"WhatsApp\",\n matrix: \"Matrix\",\n email: \"Email\",\n sms: \"SMS\",\n};\n\nconst KNOWN_CHANNEL_KEYS = Object.keys(CHANNEL_LABELS);\n\n/** Parsed type / context extracted from a session key. */\nexport type SessionKeyInfo = {\n /** Prefix for typed sessions (Subagent:/Cron:). Empty for others. */\n prefix: string;\n /** Human-readable fallback when no label / displayName is available. */\n fallbackName: string;\n};\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/**\n * Parse a session key to extract type information and a human-readable\n * fallback display name. When a gateway row is supplied, its actor-backed\n * `channel`/`kind` take precedence over the key text (whose channel slot is\n * ambiguous — accounts may be named \"direct\"/\"group\"/\"channel\"); the regexes\n * below are the fallback for rows without them. Exported for testing.\n */\nexport function parseSessionKey(\n key: string,\n row?: SessionsListResult[\"sessions\"][number],\n): SessionKeyInfo {\n const normalized = key.toLowerCase();\n\n // ── Main session ─────────────────────────────────\n if (key === \"main\" || key === \"agent:main:main\") {\n return { prefix: \"\", fallbackName: \"Main Session\" };\n }\n\n // ── Subagent ─────────────────────────────────────\n if (key.includes(\":subagent:\")) {\n return { prefix: \"Subagent:\", fallbackName: \"Subagent:\" };\n }\n\n // ── Cron job ─────────────────────────────────────\n if (normalized.startsWith(\"cron:\") || key.includes(\":cron:\")) {\n return { prefix: \"Cron:\", fallbackName: \"Cron Job:\" };\n }\n\n // ── Gateway row channel/kind (actor-backed) ──────\n const rowChannel = row?.channel?.trim();\n const rowKind = row?.kind;\n if (rowChannel && (rowKind === \"direct\" || rowKind === \"group\")) {\n const channelLabel = CHANNEL_LABELS[rowChannel] ?? capitalize(rowChannel);\n if (rowKind === \"group\") {\n return { prefix: \"\", fallbackName: `${channelLabel} Group` };\n }\n const marker = \":direct:\";\n const markerAt = key.lastIndexOf(marker);\n const peerText =\n markerAt >= 0 ? key.slice(markerAt + marker.length) : key.slice(key.lastIndexOf(\":\") + 1);\n return { prefix: \"\", fallbackName: `${channelLabel} · ${peerText}` };\n }\n\n // ── Direct chat (agent:<x>:<channel>:direct:<id>) ──\n const directMatch = key.match(/^agent:[^:]+:([^:]+):direct:(.+)$/);\n if (directMatch) {\n const channel = directMatch[1];\n const identifier = directMatch[2];\n const channelLabel = CHANNEL_LABELS[channel] ?? capitalize(channel);\n return { prefix: \"\", fallbackName: `${channelLabel} · ${identifier}` };\n }\n\n // ── Group chat (agent:<x>:<channel>:group:<id>) ────\n const groupMatch = key.match(/^agent:[^:]+:([^:]+):group:(.+)$/);\n if (groupMatch) {\n const channel = groupMatch[1];\n const channelLabel = CHANNEL_LABELS[channel] ?? capitalize(channel);\n return { prefix: \"\", fallbackName: `${channelLabel} Group` };\n }\n\n // ── Channel-prefixed legacy keys (e.g. \"bluebubbles:g-…\") ──\n for (const ch of KNOWN_CHANNEL_KEYS) {\n if (key === ch || key.startsWith(`${ch}:`)) {\n return { prefix: \"\", fallbackName: `${CHANNEL_LABELS[ch]} Session` };\n }\n }\n\n // ── Unknown — return key as-is ───────────────────\n return { prefix: \"\", fallbackName: key };\n}\n\nexport function resolveSessionDisplayName(\n key: string,\n row?: SessionsListResult[\"sessions\"][number],\n): string {\n const label = row?.label?.trim() || \"\";\n const displayName = row?.displayName?.trim() || \"\";\n const { prefix, fallbackName } = parseSessionKey(key, row);\n\n const applyTypedPrefix = (name: string): string => {\n if (!prefix) {\n return name;\n }\n const prefixPattern = new RegExp(`^${prefix.replace(/[.*+?^${}()|[\\\\]\\\\]/g, \"\\\\$&\")}\\\\s*`, \"i\");\n return prefixPattern.test(name) ? name : `${prefix} ${name}`;\n };\n\n if (label && label !== key) {\n return applyTypedPrefix(label);\n }\n if (displayName && displayName !== key) {\n return applyTypedPrefix(displayName);\n }\n return fallbackName;\n}\n\nexport function isCronSessionKey(key: string): boolean {\n const normalized = key.trim().toLowerCase();\n if (!normalized) {\n return false;\n }\n if (normalized.startsWith(\"cron:\")) {\n return true;\n }\n if (!normalized.startsWith(\"agent:\")) {\n return false;\n }\n const parts = normalized.split(\":\").filter(Boolean);\n if (parts.length < 3) {\n return false;\n }\n const rest = parts.slice(2).join(\":\");\n return rest.startsWith(\"cron:\");\n}\n\nfunction resolveSessionOptions(\n sessionKey: string,\n sessions: SessionsListResult | null,\n mainSessionKey?: string | null,\n hideCron = false,\n) {\n const seen = new Set<string>();\n const options: Array<{ key: string; displayName?: string }> = [];\n\n const resolvedMain = mainSessionKey && sessions?.sessions?.find((s) => s.key === mainSessionKey);\n const resolvedCurrent = sessions?.sessions?.find((s) => s.key === sessionKey);\n\n // Add main session key first\n if (mainSessionKey) {\n seen.add(mainSessionKey);\n options.push({\n key: mainSessionKey,\n displayName: resolveSessionDisplayName(mainSessionKey, resolvedMain || undefined),\n });\n }\n\n // Add current session key next — always include it even if it's a cron session,\n // so the active session is never silently dropped from the select.\n if (!seen.has(sessionKey)) {\n seen.add(sessionKey);\n options.push({\n key: sessionKey,\n displayName: resolveSessionDisplayName(sessionKey, resolvedCurrent),\n });\n }\n\n // Add sessions from the result, optionally filtering out cron sessions.\n if (sessions?.sessions) {\n for (const s of sessions.sessions) {\n if (!seen.has(s.key) && !(hideCron && isCronSessionKey(s.key))) {\n seen.add(s.key);\n options.push({\n key: s.key,\n displayName: resolveSessionDisplayName(s.key, s),\n });\n }\n }\n }\n\n return options;\n}\n\n/** Count sessions with a cron: key that would be hidden when hideCron=true. */\nfunction countHiddenCronSessions(sessionKey: string, sessions: SessionsListResult | null): number {\n if (!sessions?.sessions) {\n return 0;\n }\n // Don't count the currently active session even if it's a cron.\n return sessions.sessions.filter((s) => isCronSessionKey(s.key) && s.key !== sessionKey).length;\n}\n\nconst THEME_ORDER: ThemeMode[] = [\"system\", \"light\", \"dark\"];\n\nexport function renderThemeToggle(state: AppViewState) {\n const index = Math.max(0, THEME_ORDER.indexOf(state.theme));\n const applyTheme = (next: ThemeMode) => (event: MouseEvent) => {\n const element = event.currentTarget as HTMLElement;\n const context: ThemeTransitionContext = { element };\n if (event.clientX || event.clientY) {\n context.pointerClientX = event.clientX;\n context.pointerClientY = event.clientY;\n }\n state.setTheme(next, context);\n };\n\n return html`\n <div class=\"theme-toggle\" style=\"--theme-index: ${index};\">\n <div class=\"theme-toggle__track\" role=\"group\" aria-label=\"Theme\">\n <span class=\"theme-toggle__indicator\"></span>\n <button\n class=\"theme-toggle__button ${state.theme === \"system\" ? \"active\" : \"\"}\"\n @click=${applyTheme(\"system\")}\n aria-pressed=${state.theme === \"system\"}\n aria-label=\"System theme\"\n title=\"System\"\n >\n ${renderMonitorIcon()}\n </button>\n <button\n class=\"theme-toggle__button ${state.theme === \"light\" ? \"active\" : \"\"}\"\n @click=${applyTheme(\"light\")}\n aria-pressed=${state.theme === \"light\"}\n aria-label=\"Light theme\"\n title=\"Light\"\n >\n ${renderSunIcon()}\n </button>\n <button\n class=\"theme-toggle__button ${state.theme === \"dark\" ? \"active\" : \"\"}\"\n @click=${applyTheme(\"dark\")}\n aria-pressed=${state.theme === \"dark\"}\n aria-label=\"Dark theme\"\n title=\"Dark\"\n >\n ${renderMoonIcon()}\n </button>\n </div>\n </div>\n `;\n}\n\nfunction renderSunIcon() {\n return html`\n <svg class=\"theme-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\n <path d=\"M12 2v2\"></path>\n <path d=\"M12 20v2\"></path>\n <path d=\"m4.93 4.93 1.41 1.41\"></path>\n <path d=\"m17.66 17.66 1.41 1.41\"></path>\n <path d=\"M2 12h2\"></path>\n <path d=\"M20 12h2\"></path>\n <path d=\"m6.34 17.66-1.41 1.41\"></path>\n <path d=\"m19.07 4.93-1.41 1.41\"></path>\n </svg>\n `;\n}\n\nfunction renderMoonIcon() {\n return html`\n <svg class=\"theme-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\n ></path>\n </svg>\n `;\n}\n\nfunction renderMonitorIcon() {\n return html`\n <svg class=\"theme-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"3\" rx=\"2\"></rect>\n <line x1=\"8\" x2=\"16\" y1=\"21\" y2=\"21\"></line>\n <line x1=\"12\" x2=\"12\" y1=\"17\" y2=\"21\"></line>\n </svg>\n `;\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\nimport type {\n AgentFileEntry,\n AgentsFilesGetResult,\n AgentsFilesListResult,\n AgentsFilesSetResult,\n} from \"../types.ts\";\n\nexport type AgentFilesState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n agentFilesLoading: boolean;\n agentFilesError: string | null;\n agentFilesList: AgentsFilesListResult | null;\n agentFileContents: Record<string, string>;\n agentFileDrafts: Record<string, string>;\n agentFileActive: string | null;\n agentFileSaving: boolean;\n};\n\nfunction mergeFileEntry(\n list: AgentsFilesListResult | null,\n entry: AgentFileEntry,\n): AgentsFilesListResult | null {\n if (!list) {\n return list;\n }\n const hasEntry = list.files.some((file) => file.name === entry.name);\n const nextFiles = hasEntry\n ? list.files.map((file) => (file.name === entry.name ? entry : file))\n : [...list.files, entry];\n return { ...list, files: nextFiles };\n}\n\nexport async function loadAgentFiles(state: AgentFilesState, agentId: string) {\n if (!state.client || !state.connected || state.agentFilesLoading) {\n return;\n }\n state.agentFilesLoading = true;\n state.agentFilesError = null;\n try {\n const res = await state.client.request<AgentsFilesListResult | null>(\"agents.files.list\", {\n agentId,\n });\n if (res) {\n state.agentFilesList = res;\n if (state.agentFileActive && !res.files.some((file) => file.name === state.agentFileActive)) {\n state.agentFileActive = null;\n }\n }\n } catch (err) {\n state.agentFilesError = String(err);\n } finally {\n state.agentFilesLoading = false;\n }\n}\n\nexport async function loadAgentFileContent(\n state: AgentFilesState,\n agentId: string,\n name: string,\n opts?: { force?: boolean; preserveDraft?: boolean },\n) {\n if (!state.client || !state.connected || state.agentFilesLoading) {\n return;\n }\n if (!opts?.force && Object.hasOwn(state.agentFileContents, name)) {\n return;\n }\n state.agentFilesLoading = true;\n state.agentFilesError = null;\n try {\n const res = await state.client.request<AgentsFilesGetResult | null>(\"agents.files.get\", {\n agentId,\n name,\n });\n if (res?.file) {\n const content = res.file.content ?? \"\";\n const previousBase = state.agentFileContents[name] ?? \"\";\n const currentDraft = state.agentFileDrafts[name];\n const preserveDraft = opts?.preserveDraft ?? true;\n state.agentFilesList = mergeFileEntry(state.agentFilesList, res.file);\n state.agentFileContents = { ...state.agentFileContents, [name]: content };\n if (\n !preserveDraft ||\n !Object.hasOwn(state.agentFileDrafts, name) ||\n currentDraft === previousBase\n ) {\n state.agentFileDrafts = { ...state.agentFileDrafts, [name]: content };\n }\n }\n } catch (err) {\n state.agentFilesError = String(err);\n } finally {\n state.agentFilesLoading = false;\n }\n}\n\nexport async function saveAgentFile(\n state: AgentFilesState,\n agentId: string,\n name: string,\n content: string,\n) {\n if (!state.client || !state.connected || state.agentFileSaving) {\n return;\n }\n state.agentFileSaving = true;\n state.agentFilesError = null;\n try {\n const res = await state.client.request<AgentsFilesSetResult | null>(\"agents.files.set\", {\n agentId,\n name,\n content,\n });\n if (res?.file) {\n state.agentFilesList = mergeFileEntry(state.agentFilesList, res.file);\n state.agentFileContents = { ...state.agentFileContents, [name]: content };\n state.agentFileDrafts = { ...state.agentFileDrafts, [name]: content };\n }\n } catch (err) {\n state.agentFilesError = String(err);\n } finally {\n state.agentFileSaving = false;\n }\n}\n","import { html, nothing } from \"lit\";\nimport type { AppViewState } from \"../app-view-state.ts\";\n\nfunction formatRemaining(ms: number): string {\n const remaining = Math.max(0, ms);\n const totalSeconds = Math.floor(remaining / 1000);\n if (totalSeconds < 60) {\n return `${totalSeconds}s`;\n }\n const minutes = Math.floor(totalSeconds / 60);\n if (minutes < 60) {\n return `${minutes}m`;\n }\n const hours = Math.floor(minutes / 60);\n return `${hours}h`;\n}\n\nfunction renderMetaRow(label: string, value?: string | null) {\n if (!value) {\n return nothing;\n }\n return html`<div class=\"exec-approval-meta-row\"><span>${label}</span><span>${value}</span></div>`;\n}\n\nexport function renderExecApprovalPrompt(state: AppViewState) {\n const active = state.execApprovalQueue[0];\n if (!active) {\n return nothing;\n }\n const request = active.request;\n const remainingMs = active.expiresAtMs - Date.now();\n const remaining = remainingMs > 0 ? `expires in ${formatRemaining(remainingMs)}` : \"expired\";\n const queueCount = state.execApprovalQueue.length;\n return html`\n <div class=\"exec-approval-overlay\" role=\"dialog\" aria-live=\"polite\">\n <div class=\"exec-approval-card\">\n <div class=\"exec-approval-header\">\n <div>\n <div class=\"exec-approval-title\">Exec approval needed</div>\n <div class=\"exec-approval-sub\">${remaining}</div>\n </div>\n ${\n queueCount > 1\n ? html`<div class=\"exec-approval-queue\">${queueCount} pending</div>`\n : nothing\n }\n </div>\n <div class=\"exec-approval-command mono\">${request.command}</div>\n <div class=\"exec-approval-meta\">\n ${renderMetaRow(\"Host\", request.host)}\n ${renderMetaRow(\"Agent\", request.agentId)}\n ${renderMetaRow(\"Session\", request.sessionKey)}\n ${renderMetaRow(\"CWD\", request.cwd)}\n ${renderMetaRow(\"Resolved\", request.resolvedPath)}\n ${renderMetaRow(\"Security\", request.security)}\n ${renderMetaRow(\"Ask\", request.ask)}\n </div>\n ${\n state.execApprovalError\n ? html`<div class=\"exec-approval-error\">${state.execApprovalError}</div>`\n : nothing\n }\n <div class=\"exec-approval-actions\">\n <button\n class=\"btn primary\"\n ?disabled=${state.execApprovalBusy}\n @click=${() => state.handleExecApprovalDecision(\"allow-once\")}\n >\n Allow once\n </button>\n <button\n class=\"btn\"\n ?disabled=${state.execApprovalBusy}\n @click=${() => state.handleExecApprovalDecision(\"allow-always\")}\n >\n Always allow\n </button>\n <button\n class=\"btn danger\"\n ?disabled=${state.execApprovalBusy}\n @click=${() => state.handleExecApprovalDecision(\"deny\")}\n >\n Deny\n </button>\n </div>\n </div>\n </div>\n `;\n}\n","import { html, nothing } from \"lit\";\nimport type { AppViewState } from \"../app-view-state.ts\";\n\nexport function renderGatewayUrlConfirmation(state: AppViewState) {\n const { pendingGatewayUrl } = state;\n if (!pendingGatewayUrl) {\n return nothing;\n }\n\n return html`\n <div class=\"exec-approval-overlay\" role=\"dialog\" aria-modal=\"true\" aria-live=\"polite\">\n <div class=\"exec-approval-card\">\n <div class=\"exec-approval-header\">\n <div>\n <div class=\"exec-approval-title\">Change Gateway URL</div>\n <div class=\"exec-approval-sub\">This will reconnect to a different gateway server</div>\n </div>\n </div>\n <div class=\"exec-approval-command mono\">${pendingGatewayUrl}</div>\n <div class=\"callout danger\" style=\"margin-top: 12px;\">\n Only confirm if you trust this URL. Malicious URLs can compromise your system.\n </div>\n <div class=\"exec-approval-actions\">\n <button\n class=\"btn primary\"\n @click=${() => state.handleGatewayUrlConfirm()}\n >\n Confirm\n </button>\n <button\n class=\"btn\"\n @click=${() => state.handleGatewayUrlCancel()}\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n `;\n}\n","import { html, nothing } from \"lit\";\nimport { DOCS_SITE_URL } from \"../../../src/infra/docs-site.js\";\nimport { parseAgentSessionKey } from \"../../../src/routing/session-key.js\";\nimport { t } from \"../i18n/index.ts\";\nimport { refreshChatAvatar } from \"./app-chat.ts\";\nimport { renderUsageTab } from \"./app-render-usage-tab.ts\";\nimport { renderChatControls, renderTab, renderThemeToggle } from \"./app-render.helpers.ts\";\nimport { consoleViews } from \"./app-view-dispatcher.ts\";\nimport type { AppViewState } from \"./app-view-state.ts\";\nimport { loadAgentFileContent, loadAgentFiles, saveAgentFile } from \"./controllers/agent-files.ts\";\nimport { loadAgentIdentities, loadAgentIdentity } from \"./controllers/agent-identity.ts\";\nimport { loadAgentSkills } from \"./controllers/agent-skills.ts\";\nimport { loadAgents, loadToolsCatalog, nudgeAgent } from \"./controllers/agents.ts\";\nimport { loadChannels } from \"./controllers/channels.ts\";\nimport { loadChatHistory } from \"./controllers/chat.ts\";\nimport {\n applyConfig,\n loadConfig,\n runUpdate,\n saveConfig,\n updateConfigFormValue,\n removeConfigFormValue,\n} from \"./controllers/config.ts\";\nimport {\n loadCronRuns,\n loadMoreCronJobs,\n loadMoreCronRuns,\n reloadCronJobs,\n toggleCronJob,\n runCronJob,\n removeCronJob,\n addCronJob,\n startCronCreate,\n startCronEdit,\n startCronClone,\n cancelCronEdit,\n validateCronForm,\n hasCronFormErrors,\n normalizeCronFormState,\n getVisibleCronJobs,\n updateCronJobsFilter,\n updateCronRunsFilter,\n} from \"./controllers/cron.ts\";\nimport { loadDebug, callDebugMethod } from \"./controllers/debug.ts\";\nimport {\n approveDevicePairing,\n loadDevices,\n rejectDevicePairing,\n revokeDeviceToken,\n rotateDeviceToken,\n} from \"./controllers/devices.ts\";\nimport {\n loadExecApprovals,\n removeExecApprovalsFormValue,\n saveExecApprovals,\n updateExecApprovalsFormValue,\n} from \"./controllers/exec-approvals.ts\";\nimport { loadLogs } from \"./controllers/logs.ts\";\nimport { loadNodes } from \"./controllers/nodes.ts\";\nimport { loadPresence } from \"./controllers/presence.ts\";\nimport {\n cancelRun,\n continueRun,\n deleteSessionAndRefresh,\n interruptSession,\n loadRecoverableRuns,\n loadSessionRuns,\n loadSessionThresholds,\n loadSessions,\n patchSession,\n} from \"./controllers/sessions.ts\";\nimport {\n installSkill,\n loadSkills,\n saveSkillApiKey,\n updateSkillEdit,\n updateSkillEnabled,\n} from \"./controllers/skills.ts\";\nimport { docsHrefForTab } from \"./docs-refs.ts\";\nimport { buildExternalLinkRel, EXTERNAL_LINK_TARGET } from \"./external-link.ts\";\nimport { icons } from \"./icons.ts\";\nimport {\n normalizeBasePath,\n pathForTab,\n TAB_GROUPS,\n subtitleForTab,\n titleForTab,\n} from \"./navigation.ts\";\nimport { resolveConfiguredCronModelSuggestions, sortLocaleStrings } from \"./views/agents-utils.ts\";\nimport { renderExecApprovalPrompt } from \"./views/exec-approval.ts\";\nimport { renderGatewayUrlConfirmation } from \"./views/gateway-url-confirmation.ts\";\n\nconst AVATAR_DATA_RE = /^data:/i;\nconst AVATAR_HTTP_RE = /^https?:\\/\\//i;\nconst CRON_THINKING_SUGGESTIONS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\"];\nconst CRON_TIMEZONE_SUGGESTIONS = [\n \"UTC\",\n \"America/Los_Angeles\",\n \"America/Denver\",\n \"America/Chicago\",\n \"America/New_York\",\n \"Europe/London\",\n \"Europe/Berlin\",\n \"Asia/Tokyo\",\n];\n\nfunction isHttpUrl(value: string): boolean {\n return /^https?:\\/\\//i.test(value.trim());\n}\n\nfunction normalizeSuggestionValue(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction uniquePreserveOrder(values: string[]): string[] {\n const seen = new Set<string>();\n const output: string[] = [];\n for (const value of values) {\n const normalized = value.trim();\n if (!normalized) {\n continue;\n }\n const key = normalized.toLowerCase();\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n output.push(normalized);\n }\n return output;\n}\n\nfunction resolveAssistantAvatarUrl(state: AppViewState): string | undefined {\n const list = state.agentsList?.agents ?? [];\n const parsed = parseAgentSessionKey(state.sessionKey);\n const agentId = parsed?.agentId ?? state.agentsList?.defaultId ?? \"main\";\n const agent = list.find((entry) => entry.id === agentId);\n const identity = agent?.identity;\n const candidate = identity?.avatarUrl ?? identity?.avatar;\n if (!candidate) {\n return undefined;\n }\n if (AVATAR_DATA_RE.test(candidate) || AVATAR_HTTP_RE.test(candidate)) {\n return candidate;\n }\n return identity?.avatarUrl;\n}\n\nfunction isTalkAvailable(state: AppViewState): boolean {\n const availability = state.talkState.availability;\n return (\n state.connected &&\n availability.resolved &&\n !availability.loading &&\n !availability.error &&\n availability.enabled &&\n availability.available\n );\n}\n\nfunction renderTalkAvailabilityGuard(state: AppViewState, message: string) {\n return html`\n <div class=\"callout\" role=\"status\">\n <span>${message}</span>\n ${\n state.talkState.lifecycle === \"idle\"\n ? nothing\n : html`\n <button class=\"btn btn--sm\" type=\"button\" @click=${() => void state.handleTalkStop()}>\n ${t(\"talk.stop\")}\n </button>\n `\n }\n </div>\n `;\n}\n\nexport function renderApp(state: AppViewState) {\n const openClawVersion =\n (typeof state.hello?.server?.version === \"string\" && state.hello.server.version.trim()) ||\n state.updateAvailable?.currentVersion ||\n t(\"common.na\");\n const availableUpdate =\n state.updateAvailable &&\n state.updateAvailable.latestVersion !== state.updateAvailable.currentVersion\n ? state.updateAvailable\n : null;\n const versionStatusClass = availableUpdate ? \"warn\" : \"ok\";\n const presenceCount = state.presenceEntries.length;\n const sessionsCount = state.sessionsResult?.count ?? null;\n const cronNext = state.cronStatus?.nextWakeAtMs ?? null;\n const chatDisabledReason = state.connected ? null : t(\"chat.disconnected\");\n const isChat = state.tab === \"chat\";\n const docsHref = docsHrefForTab(state.tab);\n const chatFocus = isChat && (state.settings.chatFocusMode || state.onboarding);\n const showThinking = state.onboarding ? false : state.settings.chatShowThinking;\n const assistantAvatarUrl = resolveAssistantAvatarUrl(state);\n const chatAvatarUrl = state.chatAvatarUrl ?? assistantAvatarUrl ?? null;\n const talkAvailability = state.talkState.availability;\n const talkAvailable = isTalkAvailable(state);\n const configValue =\n state.configForm ?? (state.configSnapshot?.config as Record<string, unknown> | null);\n const basePath = normalizeBasePath(state.basePath ?? \"\");\n const resolvedAgentId =\n state.agentsSelectedId ??\n state.agentsList?.defaultId ??\n state.agentsList?.agents?.[0]?.id ??\n null;\n const cronAgentSuggestions = sortLocaleStrings(\n new Set(\n [\n ...(state.agentsList?.agents?.map((entry) => entry.id.trim()) ?? []),\n ...state.cronJobs\n .map((job) => (typeof job.agentId === \"string\" ? job.agentId.trim() : \"\"))\n .filter(Boolean),\n ].filter(Boolean),\n ),\n );\n const cronModelSuggestions = sortLocaleStrings(\n new Set(\n [\n ...state.cronModelSuggestions,\n ...resolveConfiguredCronModelSuggestions(configValue),\n ...state.cronJobs\n .map((job) => {\n if (job.payload.kind !== \"agentTurn\" || typeof job.payload.model !== \"string\") {\n return \"\";\n }\n return job.payload.model.trim();\n })\n .filter(Boolean),\n ].filter(Boolean),\n ),\n );\n const visibleCronJobs = getVisibleCronJobs(state);\n const selectedCronJob =\n state.cronRunsJobId == null\n ? null\n : (state.cronJobs.find((job) => job.id === state.cronRunsJobId) ?? null);\n const selectedDeliveryChannel =\n state.cronForm.deliveryChannel && state.cronForm.deliveryChannel.trim()\n ? state.cronForm.deliveryChannel.trim()\n : \"last\";\n const jobToSuggestions = state.cronJobs\n .map((job) => normalizeSuggestionValue(job.delivery?.to))\n .filter(Boolean);\n const accountToSuggestions = (\n selectedDeliveryChannel === \"last\"\n ? Object.values(state.channelsSnapshot?.channelAccounts ?? {}).flat()\n : (state.channelsSnapshot?.channelAccounts?.[selectedDeliveryChannel] ?? [])\n )\n .flatMap((account) => [\n normalizeSuggestionValue(account.accountId),\n normalizeSuggestionValue(account.name),\n ])\n .filter(Boolean);\n const rawDeliveryToSuggestions = uniquePreserveOrder([\n ...jobToSuggestions,\n ...accountToSuggestions,\n ]);\n const accountSuggestions = uniquePreserveOrder(accountToSuggestions);\n const deliveryToSuggestions =\n state.cronForm.deliveryMode === \"webhook\"\n ? rawDeliveryToSuggestions.filter((value) => isHttpUrl(value))\n : rawDeliveryToSuggestions;\n\n return html`\n <div class=\"shell ${isChat ? \"shell--chat\" : \"\"} ${chatFocus ? \"shell--chat-focus\" : \"\"} ${state.settings.navCollapsed ? \"shell--nav-collapsed\" : \"\"} ${state.onboarding ? \"shell--onboarding\" : \"\"}\">\n <header class=\"topbar\">\n <div class=\"topbar-left\">\n <button\n class=\"nav-collapse-toggle\"\n @click=${() =>\n state.applySettings({\n ...state.settings,\n navCollapsed: !state.settings.navCollapsed,\n })}\n title=\"${state.settings.navCollapsed ? t(\"nav.expand\") : t(\"nav.collapse\")}\"\n aria-label=\"${state.settings.navCollapsed ? t(\"nav.expand\") : t(\"nav.collapse\")}\"\n aria-controls=\"primary-nav\"\n aria-expanded=\"${!state.settings.navCollapsed}\"\n >\n <span class=\"nav-collapse-toggle__icon\" aria-hidden=\"true\">${icons.panelLeft}</span>\n </button>\n <div class=\"brand\">\n <div class=\"brand-logo\">\n <img\n src=${basePath ? `${basePath}/brand/wednesdayai-logo-mark.png` : \"/brand/wednesdayai-logo-mark.png\"}\n alt=\"WednesdayAI\"\n />\n </div>\n <div class=\"brand-text\">\n <div class=\"brand-title\">WednesdayAI</div>\n <div class=\"brand-sub\">Operations Console</div>\n </div>\n </div>\n </div>\n <div class=\"topbar-status\">\n <div class=\"pill\">\n <span class=\"statusDot ${versionStatusClass}\"></span>\n <span>${t(\"common.version\")}</span>\n <span class=\"mono\">${openClawVersion}</span>\n </div>\n <div class=\"pill\">\n <span class=\"statusDot ${state.connected ? \"ok\" : \"\"}\"></span>\n <span>${t(\"common.health\")}</span>\n <span class=\"mono\">${state.connected ? t(\"common.ok\") : t(\"common.offline\")}</span>\n </div>\n ${renderThemeToggle(state)}\n </div>\n </header>\n <aside id=\"primary-nav\" class=\"nav ${state.settings.navCollapsed ? \"nav--collapsed\" : \"\"}\">\n ${TAB_GROUPS.map((group) => {\n const tabs = group.tabs.filter((tab) => tab !== \"talk\" || talkAvailable);\n const isGroupCollapsed = state.settings.navGroupsCollapsed[group.label] ?? false;\n const hasActiveTab = tabs.some((tab) => tab === state.tab);\n return html`\n <div class=\"nav-group ${isGroupCollapsed && !hasActiveTab ? \"nav-group--collapsed\" : \"\"}\">\n <button\n class=\"nav-label\"\n @click=${() => {\n const next = { ...state.settings.navGroupsCollapsed };\n next[group.label] = !isGroupCollapsed;\n state.applySettings({\n ...state.settings,\n navGroupsCollapsed: next,\n });\n }}\n aria-expanded=${!isGroupCollapsed}\n >\n <span class=\"nav-label__text\">${t(`nav.${group.label}`)}</span>\n <span class=\"nav-label__chevron\">${isGroupCollapsed ? \"+\" : \"−\"}</span>\n </button>\n <div class=\"nav-group__items\">\n ${tabs.map((tab) => renderTab(state, tab))}\n </div>\n </div>\n `;\n })}\n <div class=\"nav-group nav-group--links\">\n <div class=\"nav-label nav-label--static\">\n <span class=\"nav-label__text\">${t(\"common.resources\")}</span>\n </div>\n <div class=\"nav-group__items\">\n <a\n class=\"nav-item nav-item--external\"\n href=${DOCS_SITE_URL}\n target=${EXTERNAL_LINK_TARGET}\n rel=${buildExternalLinkRel()}\n title=\"${t(\"common.docs\")} (opens in new tab)\"\n >\n <span class=\"nav-item__icon\" aria-hidden=\"true\">${icons.book}</span>\n <span class=\"nav-item__text\">${t(\"common.docs\")}</span>\n </a>\n </div>\n </div>\n </aside>\n <main class=\"content ${isChat ? \"content--chat\" : \"\"}\">\n <div class=\"callout info classic-deprecation\" role=\"status\">\n The classic console is deprecated and will be removed in the next release.\n ${state.consolePath ? html`<a href=${state.consolePath}>Open the new console</a>` : nothing}\n </div>\n ${\n availableUpdate\n ? html`<div class=\"update-banner callout danger\" role=\"alert\">\n <strong>Update available:</strong> v${availableUpdate.latestVersion}\n (running v${availableUpdate.currentVersion}).\n <button\n class=\"btn btn--sm update-banner__btn\"\n ?disabled=${state.updateRunning || !state.connected}\n @click=${() => runUpdate(state)}\n >${state.updateRunning ? \"Updating…\" : \"Update now\"}</button>\n </div>`\n : nothing\n }\n <section class=\"content-header\">\n <div>\n ${state.tab === \"usage\" ? nothing : html`<div class=\"page-title\">${titleForTab(state.tab)}</div>`}\n ${state.tab === \"usage\" ? nothing : html`<div class=\"page-sub\">${subtitleForTab(state.tab)}</div>`}\n </div>\n <div class=\"page-meta\">\n ${state.lastError ? html`<div class=\"pill danger\">${state.lastError}</div>` : nothing}\n <a\n class=\"btn btn--sm\"\n href=${docsHref}\n target=${EXTERNAL_LINK_TARGET}\n rel=${buildExternalLinkRel()}\n title=\"${t(\"common.help\")} (opens in new tab)\"\n >\n ${icons.book}\n <span>${t(\"common.help\")}</span>\n </a>\n ${isChat ? renderChatControls(state) : nothing}\n </div>\n </section>\n\n ${\n state.tab === \"overview\"\n ? consoleViews.overview.render(state, {\n connected: state.connected,\n hello: state.hello,\n settings: state.settings,\n password: state.password,\n lastError: state.lastError,\n lastErrorCode: state.lastErrorCode,\n presenceCount,\n sessionsCount,\n cronEnabled: state.cronStatus?.enabled ?? null,\n cronNext,\n lastChannelsRefresh: state.channelsLastSuccess,\n onSettingsChange: (next) => state.applySettings(next),\n onPasswordChange: (next) => (state.password = next),\n onSessionKeyChange: (next) => {\n state.sessionKey = next;\n state.chatMessage = \"\";\n state.resetToolStream();\n state.applySettings({\n ...state.settings,\n sessionKey: next,\n lastActiveSessionKey: next,\n });\n void state.loadAssistantIdentity();\n },\n onConnect: () => state.connect(),\n onRefresh: () => state.loadOverview(),\n })\n : nothing\n }\n\n ${\n state.tab === \"channels\"\n ? consoleViews.channels.render(state, {\n connected: state.connected,\n loading: state.channelsLoading,\n snapshot: state.channelsSnapshot,\n lastError: state.channelsError,\n lastSuccessAt: state.channelsLastSuccess,\n whatsappMessage: state.whatsappLoginMessage,\n whatsappQrDataUrl: state.whatsappLoginQrDataUrl,\n whatsappConnected: state.whatsappLoginConnected,\n whatsappBusy: state.whatsappBusy,\n configSchema: state.configSchema,\n configSchemaLoading: state.configSchemaLoading,\n configForm: state.configForm,\n configUiHints: state.configUiHints,\n configSaving: state.configSaving,\n configFormDirty: state.configFormDirty,\n nostrProfileFormState: state.nostrProfileFormState,\n nostrProfileAccountId: state.nostrProfileAccountId,\n activeRuns: state.sessionRunsResult?.runs ?? [],\n onRefresh: (probe) => loadChannels(state, probe),\n onWhatsAppStart: (force) => state.handleWhatsAppStart(force),\n onWhatsAppWait: () => state.handleWhatsAppWait(),\n onWhatsAppLogout: () => state.handleWhatsAppLogout(),\n onConfigPatch: (path, value) => updateConfigFormValue(state, path, value),\n onConfigSave: () => state.handleChannelConfigSave(),\n onConfigReload: () => state.handleChannelConfigReload(),\n onNostrProfileEdit: (accountId, profile) =>\n state.handleNostrProfileEdit(accountId, profile),\n onNostrProfileCancel: () => state.handleNostrProfileCancel(),\n onNostrProfileFieldChange: (field, value) =>\n state.handleNostrProfileFieldChange(field, value),\n onNostrProfileSave: () => state.handleNostrProfileSave(),\n onNostrProfileImport: () => state.handleNostrProfileImport(),\n onNostrProfileToggleAdvanced: () => state.handleNostrProfileToggleAdvanced(),\n })\n : nothing\n }\n\n ${\n state.tab === \"instances\"\n ? consoleViews.instances.render(state, {\n loading: state.presenceLoading,\n entries: state.presenceEntries,\n lastError: state.presenceError,\n statusMessage: state.presenceStatus,\n onRefresh: () => loadPresence(state),\n })\n : nothing\n }\n\n ${\n state.tab === \"sessions\"\n ? consoleViews.sessions.render(state, {\n loading: state.sessionsLoading,\n result: state.sessionsResult,\n error: state.sessionsError,\n activeMinutes: state.sessionsFilterActive,\n limit: state.sessionsFilterLimit,\n includeGlobal: state.sessionsIncludeGlobal,\n includeUnknown: state.sessionsIncludeUnknown,\n basePath: state.basePath,\n runs: state.sessionRunsResult?.runs ?? [],\n runsCapturedAt: state.sessionRunsResult?.capturedAt ?? 0,\n runsFetchedAt: state.sessionRunsFetchedAt,\n runsStuckThresholdMs: state.sessionRunsResult?.stuckThresholdMs ?? 0,\n perAgentThresholdMs: state.sessionsThresholdsResult?.byAgentId ?? {},\n runsError: state.sessionRunsError,\n runsThresholdsError: state.sessionsThresholdsError,\n recentlyCompletedRuns: state.recentlyCompletedRuns,\n onFiltersChange: (next) => {\n state.sessionsFilterActive = next.activeMinutes;\n state.sessionsFilterLimit = next.limit;\n state.sessionsIncludeGlobal = next.includeGlobal;\n state.sessionsIncludeUnknown = next.includeUnknown;\n },\n onRefresh: () => {\n void loadSessions(state);\n void loadSessionRuns(state);\n void loadSessionThresholds(state);\n void loadRecoverableRuns(state);\n },\n onPatch: (key, patch) => patchSession(state, key, patch),\n onDelete: (key) => deleteSessionAndRefresh(state, key),\n onInterrupt: (key) => void interruptSession(state, key),\n interruptingKeys: state.sessionRunsInterruptingKeys,\n recoverableRuns: state.recoverableRuns,\n recoveryError: state.recoveryError,\n decidingRunIds: state.decidingRunIds,\n onContinue: (sessionRunId, decisionVersion) => {\n if (state.decidingRunIds.has(sessionRunId)) {\n return;\n }\n state.decidingRunIds = new Set([...state.decidingRunIds, sessionRunId]);\n void continueRun(state, sessionRunId, decisionVersion)\n .then((res) => {\n if (res.conflict || !res.ok) {\n void loadRecoverableRuns(state);\n } else {\n state.recoverableRuns = state.recoverableRuns.filter(\n (r) => r.sessionRunId !== sessionRunId,\n );\n }\n })\n .catch(() => {\n void loadRecoverableRuns(state);\n })\n .finally(() => {\n state.decidingRunIds = new Set(\n [...state.decidingRunIds].filter((id) => id !== sessionRunId),\n );\n });\n },\n onCancel: (sessionRunId, decisionVersion) => {\n if (state.decidingRunIds.has(sessionRunId)) {\n return;\n }\n state.decidingRunIds = new Set([...state.decidingRunIds, sessionRunId]);\n void cancelRun(state, sessionRunId, decisionVersion)\n .then((res) => {\n if (res.conflict || !res.ok) {\n void loadRecoverableRuns(state);\n } else {\n state.recoverableRuns = state.recoverableRuns.filter(\n (r) => r.sessionRunId !== sessionRunId,\n );\n }\n })\n .catch(() => {\n void loadRecoverableRuns(state);\n })\n .finally(() => {\n state.decidingRunIds = new Set(\n [...state.decidingRunIds].filter((id) => id !== sessionRunId),\n );\n });\n },\n })\n : nothing\n }\n\n ${renderUsageTab(state)}\n\n ${\n state.tab === \"cron\"\n ? consoleViews.cron.render(state, {\n basePath: state.basePath,\n loading: state.cronLoading,\n jobsLoadingMore: state.cronJobsLoadingMore,\n status: state.cronStatus,\n jobs: visibleCronJobs,\n selectedJob: selectedCronJob,\n jobsTotal: state.cronJobsTotal,\n jobsHasMore: state.cronJobsHasMore,\n jobsQuery: state.cronJobsQuery,\n jobsEnabledFilter: state.cronJobsEnabledFilter,\n jobsScheduleKindFilter: state.cronJobsScheduleKindFilter,\n jobsLastStatusFilter: state.cronJobsLastStatusFilter,\n jobsSortBy: state.cronJobsSortBy,\n jobsSortDir: state.cronJobsSortDir,\n error: state.cronError,\n busy: state.cronBusy,\n lastRunSessionKey: state.cronLastRunSessionKey,\n lastRunJobId: state.cronLastRunJobId,\n runningJobId: state.cronRunningJobId,\n form: state.cronForm,\n fieldErrors: state.cronFieldErrors,\n canSubmit: !hasCronFormErrors(state.cronFieldErrors),\n editingJobId: state.cronEditingJobId,\n creatingJob: state.cronCreatingJob,\n channels: state.channelsSnapshot?.channelMeta?.length\n ? state.channelsSnapshot.channelMeta.map((entry) => entry.id)\n : (state.channelsSnapshot?.channelOrder ?? []),\n channelLabels: state.channelsSnapshot?.channelLabels ?? {},\n channelMeta: state.channelsSnapshot?.channelMeta ?? [],\n runsJobId: state.cronRunsJobId,\n runs: state.cronRuns,\n runsTotal: state.cronRunsTotal,\n runsHasMore: state.cronRunsHasMore,\n runsLoadingMore: state.cronRunsLoadingMore,\n runsScope: state.cronRunsScope,\n runsStatuses: state.cronRunsStatuses,\n runsDeliveryStatuses: state.cronRunsDeliveryStatuses,\n runsStatusFilter: state.cronRunsStatusFilter,\n runsQuery: state.cronRunsQuery,\n runsSortDir: state.cronRunsSortDir,\n agentSuggestions: cronAgentSuggestions,\n modelSuggestions: cronModelSuggestions,\n thinkingSuggestions: CRON_THINKING_SUGGESTIONS,\n timezoneSuggestions: CRON_TIMEZONE_SUGGESTIONS,\n deliveryToSuggestions,\n accountSuggestions,\n onFormChange: (patch) => {\n state.cronForm = normalizeCronFormState({ ...state.cronForm, ...patch });\n state.cronFieldErrors = validateCronForm(state.cronForm, {\n defaultAgentId: state.agentsList?.defaultId,\n });\n },\n onRefresh: () => state.loadCron(),\n onAdd: () => addCronJob(state),\n onCreate: () => startCronCreate(state),\n onEdit: (job) => startCronEdit(state, job),\n onClone: (job) => startCronClone(state, job),\n onCancelEdit: () => cancelCronEdit(state),\n onToggle: (job, enabled) => toggleCronJob(state, job, enabled),\n onRun: (job, mode) => runCronJob(state, job, mode ?? \"force\"),\n onRemove: (job) => removeCronJob(state, job),\n onLoadRuns: async (jobId) => {\n updateCronRunsFilter(state, { cronRunsScope: \"job\" });\n await loadCronRuns(state, jobId);\n },\n onLoadMoreJobs: () => loadMoreCronJobs(state),\n onJobsFiltersChange: async (patch) => {\n updateCronJobsFilter(state, patch);\n const shouldReload =\n typeof patch.cronJobsQuery === \"string\" ||\n Boolean(patch.cronJobsEnabledFilter) ||\n Boolean(patch.cronJobsSortBy) ||\n Boolean(patch.cronJobsSortDir);\n if (shouldReload) {\n await reloadCronJobs(state);\n }\n },\n onJobsFiltersReset: async () => {\n updateCronJobsFilter(state, {\n cronJobsQuery: \"\",\n cronJobsEnabledFilter: \"all\",\n cronJobsScheduleKindFilter: \"all\",\n cronJobsLastStatusFilter: \"all\",\n cronJobsSortBy: \"nextRunAtMs\",\n cronJobsSortDir: \"asc\",\n });\n await reloadCronJobs(state);\n },\n onLoadMoreRuns: () => loadMoreCronRuns(state),\n onRunsFiltersChange: async (patch) => {\n updateCronRunsFilter(state, patch);\n if (state.cronRunsScope === \"all\") {\n await loadCronRuns(state, null);\n return;\n }\n await loadCronRuns(state, state.cronRunsJobId);\n },\n })\n : nothing\n }\n\n ${\n state.tab === \"learning\"\n ? consoleViews.learning.render(state, {\n subView: state.learningSubView,\n loading: state.learningLoading,\n error: state.learningError,\n busy: state.learningBusy,\n overview: state.overview,\n proposals: state.proposals,\n lessons: state.lessons,\n selectedProposal: state.selectedProposal,\n pendingApplyId: state.learningPendingApplyId,\n onSelectSubView: (v) => {\n state.learningSubView = v;\n },\n onOpenProposal: (id) => void state.openLearningProposal(id),\n onDecide: (id, action) => void state.decideLearningProposal(id, action),\n onRequestApply: (id) => {\n state.learningPendingApplyId = id;\n },\n onConfirmApply: (id) => {\n state.learningPendingApplyId = null;\n void state.decideLearningProposal(id, \"apply\");\n },\n onCancelApply: () => {\n state.learningPendingApplyId = null;\n },\n onOpenLesson: () => {},\n })\n : nothing\n }\n\n ${\n state.tab === \"dreams\"\n ? consoleViews.dreams.render(state, {\n state: state.dreams,\n nowMs: Date.now(),\n learningHref: pathForTab(\"learning\", state.basePath),\n onSelectRun: (taskRunId) => state.selectDreamsRun(taskRunId),\n onRefresh: () => void state.loadDreams(),\n onOpenLearning: () => state.setTab(\"learning\"),\n })\n : nothing\n }\n\n ${\n state.tab === \"agents\"\n ? consoleViews.agents.render(state, {\n loading: state.agentsLoading,\n error: state.agentsError,\n agentsList: state.agentsList,\n selectedAgentId: resolvedAgentId,\n activePanel: state.agentsPanel,\n configForm: configValue,\n configLoading: state.configLoading,\n configSaving: state.configSaving,\n configDirty: state.configFormDirty,\n channelsLoading: state.channelsLoading,\n channelsError: state.channelsError,\n channelsSnapshot: state.channelsSnapshot,\n channelsLastSuccess: state.channelsLastSuccess,\n cronLoading: state.cronLoading,\n cronStatus: state.cronStatus,\n cronJobs: state.cronJobs,\n cronError: state.cronError,\n agentFilesLoading: state.agentFilesLoading,\n agentFilesError: state.agentFilesError,\n agentFilesList: state.agentFilesList,\n agentFileActive: state.agentFileActive,\n agentFileContents: state.agentFileContents,\n agentFileDrafts: state.agentFileDrafts,\n agentFileSaving: state.agentFileSaving,\n agentIdentityLoading: state.agentIdentityLoading,\n agentIdentityError: state.agentIdentityError,\n agentIdentityById: state.agentIdentityById,\n agentSkillsLoading: state.agentSkillsLoading,\n agentSkillsReport: state.agentSkillsReport,\n agentSkillsError: state.agentSkillsError,\n agentSkillsAgentId: state.agentSkillsAgentId,\n toolsCatalogLoading: state.toolsCatalogLoading,\n toolsCatalogError: state.toolsCatalogError,\n toolsCatalogResult: state.toolsCatalogResult,\n skillsFilter: state.skillsFilter,\n onRefresh: async () => {\n await loadAgents(state);\n const nextSelected =\n state.agentsSelectedId ??\n state.agentsList?.defaultId ??\n state.agentsList?.agents?.[0]?.id ??\n null;\n await loadToolsCatalog(state, nextSelected);\n const agentIds = state.agentsList?.agents?.map((entry) => entry.id) ?? [];\n if (agentIds.length > 0) {\n void loadAgentIdentities(state, agentIds);\n }\n },\n onSelectAgent: (agentId) => {\n if (state.agentsSelectedId === agentId) {\n return;\n }\n state.agentsSelectedId = agentId;\n state.agentFilesList = null;\n state.agentFilesError = null;\n state.agentFilesLoading = false;\n state.agentFileActive = null;\n state.agentFileContents = {};\n state.agentFileDrafts = {};\n state.agentSkillsReport = null;\n state.agentSkillsError = null;\n state.agentSkillsAgentId = null;\n void loadAgentIdentity(state, agentId);\n if (state.agentsPanel === \"tools\") {\n void loadToolsCatalog(state, agentId);\n }\n if (state.agentsPanel === \"files\") {\n void loadAgentFiles(state, agentId);\n }\n if (state.agentsPanel === \"skills\") {\n void loadAgentSkills(state, agentId);\n }\n },\n onNudgeAgent: (agentId: string) => {\n void nudgeAgent(state, agentId, \"Check in\");\n },\n onSelectPanel: (panel) => {\n state.agentsPanel = panel;\n if (panel === \"files\" && resolvedAgentId) {\n if (state.agentFilesList?.agentId !== resolvedAgentId) {\n state.agentFilesList = null;\n state.agentFilesError = null;\n state.agentFileActive = null;\n state.agentFileContents = {};\n state.agentFileDrafts = {};\n void loadAgentFiles(state, resolvedAgentId);\n }\n }\n if (panel === \"tools\") {\n void loadToolsCatalog(state, resolvedAgentId);\n }\n if (panel === \"skills\") {\n if (resolvedAgentId) {\n void loadAgentSkills(state, resolvedAgentId);\n }\n }\n if (panel === \"channels\") {\n void loadChannels(state, false);\n }\n if (panel === \"cron\") {\n void state.loadCron();\n }\n },\n onLoadFiles: (agentId) => loadAgentFiles(state, agentId),\n onSelectFile: (name) => {\n state.agentFileActive = name;\n if (!resolvedAgentId) {\n return;\n }\n void loadAgentFileContent(state, resolvedAgentId, name);\n },\n onFileDraftChange: (name, content) => {\n state.agentFileDrafts = { ...state.agentFileDrafts, [name]: content };\n },\n onFileReset: (name) => {\n const base = state.agentFileContents[name] ?? \"\";\n state.agentFileDrafts = { ...state.agentFileDrafts, [name]: base };\n },\n onFileSave: (name) => {\n if (!resolvedAgentId) {\n return;\n }\n const content =\n state.agentFileDrafts[name] ?? state.agentFileContents[name] ?? \"\";\n void saveAgentFile(state, resolvedAgentId, name, content);\n },\n onToolsProfileChange: (agentId, profile, clearAllow) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"tools\"];\n if (profile) {\n updateConfigFormValue(state, [...basePath, \"profile\"], profile);\n } else {\n removeConfigFormValue(state, [...basePath, \"profile\"]);\n }\n if (clearAllow) {\n removeConfigFormValue(state, [...basePath, \"allow\"]);\n }\n },\n onToolsExecPresetChange: (agentId, preset) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"tools\"];\n if (preset) {\n updateConfigFormValue(state, [...basePath, \"exec\", \"preset\"], preset);\n } else {\n removeConfigFormValue(state, [...basePath, \"exec\", \"preset\"]);\n }\n },\n onToolsOverridesChange: (agentId, alsoAllow, deny) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"tools\"];\n if (alsoAllow.length > 0) {\n updateConfigFormValue(state, [...basePath, \"alsoAllow\"], alsoAllow);\n } else {\n removeConfigFormValue(state, [...basePath, \"alsoAllow\"]);\n }\n if (deny.length > 0) {\n updateConfigFormValue(state, [...basePath, \"deny\"], deny);\n } else {\n removeConfigFormValue(state, [...basePath, \"deny\"]);\n }\n },\n onConfigReload: () => loadConfig(state),\n onConfigSave: async () => {\n await saveConfig(state);\n if (state.agentsPanel === \"tools\" && resolvedAgentId) {\n void loadToolsCatalog(state, resolvedAgentId);\n }\n },\n onChannelsRefresh: () => loadChannels(state, false),\n onCronRefresh: () => state.loadCron(),\n onSkillsFilterChange: (next) => (state.skillsFilter = next),\n onSkillsRefresh: () => {\n if (resolvedAgentId) {\n void loadAgentSkills(state, resolvedAgentId);\n }\n },\n onAgentSkillToggle: (agentId, skillName, enabled) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const entry = list[index] as { skills?: unknown };\n const normalizedSkill = skillName.trim();\n if (!normalizedSkill) {\n return;\n }\n const allSkills =\n state.agentSkillsReport?.skills?.map((skill) => skill.name).filter(Boolean) ??\n [];\n const existing = Array.isArray(entry.skills)\n ? entry.skills.map((name) => String(name).trim()).filter(Boolean)\n : undefined;\n const base = existing ?? allSkills;\n const next = new Set(base);\n if (enabled) {\n next.add(normalizedSkill);\n } else {\n next.delete(normalizedSkill);\n }\n updateConfigFormValue(state, [\"agents\", \"list\", index, \"skills\"], [...next]);\n },\n onAgentSkillsClear: (agentId) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n removeConfigFormValue(state, [\"agents\", \"list\", index, \"skills\"]);\n },\n onAgentSkillsDisableAll: (agentId) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n updateConfigFormValue(state, [\"agents\", \"list\", index, \"skills\"], []);\n },\n onModelChange: (agentId, modelId) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"model\"];\n if (!modelId) {\n removeConfigFormValue(state, basePath);\n return;\n }\n const entry = list[index] as { model?: unknown };\n const existing = entry?.model;\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\n const fallbacks = (existing as { fallbacks?: unknown }).fallbacks;\n const next = {\n primary: modelId,\n ...(Array.isArray(fallbacks) ? { fallbacks } : {}),\n };\n updateConfigFormValue(state, basePath, next);\n } else {\n updateConfigFormValue(state, basePath, modelId);\n }\n },\n onModelFallbacksChange: (agentId, fallbacks) => {\n if (!configValue) {\n return;\n }\n const list = (configValue as { agents?: { list?: unknown[] } }).agents?.list;\n if (!Array.isArray(list)) {\n return;\n }\n const index = list.findIndex(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n (entry as { id?: string }).id === agentId,\n );\n if (index < 0) {\n return;\n }\n const basePath = [\"agents\", \"list\", index, \"model\"];\n const entry = list[index] as { model?: unknown };\n const normalized = fallbacks.map((name) => name.trim()).filter(Boolean);\n const existing = entry.model;\n const resolvePrimary = () => {\n if (typeof existing === \"string\") {\n return existing.trim() || null;\n }\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\n const primary = (existing as { primary?: unknown }).primary;\n if (typeof primary === \"string\") {\n const trimmed = primary.trim();\n return trimmed || null;\n }\n }\n return null;\n };\n const primary = resolvePrimary();\n if (normalized.length === 0) {\n if (primary) {\n updateConfigFormValue(state, basePath, primary);\n } else {\n removeConfigFormValue(state, basePath);\n }\n return;\n }\n const next = primary\n ? { primary, fallbacks: normalized }\n : { fallbacks: normalized };\n updateConfigFormValue(state, basePath, next);\n },\n })\n : nothing\n }\n\n ${\n state.tab === \"skills\"\n ? consoleViews.skills.render(state, {\n loading: state.skillsLoading,\n report: state.skillsReport,\n error: state.skillsError,\n filter: state.skillsFilter,\n edits: state.skillEdits,\n messages: state.skillMessages,\n busyKey: state.skillsBusyKey,\n onFilterChange: (next) => (state.skillsFilter = next),\n onRefresh: () => loadSkills(state, { clearMessages: true }),\n onToggle: (key, enabled) => updateSkillEnabled(state, key, enabled),\n onEdit: (key, value) => updateSkillEdit(state, key, value),\n onSaveKey: (key) => saveSkillApiKey(state, key),\n onInstall: (skillKey, name, installId) =>\n installSkill(state, skillKey, name, installId),\n })\n : nothing\n }\n\n ${\n state.tab === \"nodes\"\n ? consoleViews.nodes.render(state, {\n loading: state.nodesLoading,\n nodes: state.nodes,\n devicesLoading: state.devicesLoading,\n devicesError: state.devicesError,\n devicesList: state.devicesList,\n configForm:\n state.configForm ??\n (state.configSnapshot?.config as Record<string, unknown> | null),\n configLoading: state.configLoading,\n configSaving: state.configSaving,\n configDirty: state.configFormDirty,\n configFormMode: state.configFormMode,\n execApprovalsLoading: state.execApprovalsLoading,\n execApprovalsSaving: state.execApprovalsSaving,\n execApprovalsDirty: state.execApprovalsDirty,\n execApprovalsSnapshot: state.execApprovalsSnapshot,\n execApprovalsForm: state.execApprovalsForm,\n execApprovalsSelectedAgent: state.execApprovalsSelectedAgent,\n execApprovalsTarget: state.execApprovalsTarget,\n execApprovalsTargetNodeId: state.execApprovalsTargetNodeId,\n onRefresh: () => loadNodes(state),\n onDevicesRefresh: () => loadDevices(state),\n onDeviceApprove: (requestId) => approveDevicePairing(state, requestId),\n onDeviceReject: (requestId) => rejectDevicePairing(state, requestId),\n onDeviceRotate: (deviceId, role, scopes) =>\n rotateDeviceToken(state, { deviceId, role, scopes }),\n onDeviceRevoke: (deviceId, role) => revokeDeviceToken(state, { deviceId, role }),\n onLoadConfig: () => loadConfig(state),\n onLoadExecApprovals: () => {\n const target =\n state.execApprovalsTarget === \"node\" && state.execApprovalsTargetNodeId\n ? { kind: \"node\" as const, nodeId: state.execApprovalsTargetNodeId }\n : { kind: \"gateway\" as const };\n return loadExecApprovals(state, target);\n },\n onBindDefault: (nodeId) => {\n if (nodeId) {\n updateConfigFormValue(state, [\"tools\", \"exec\", \"node\"], nodeId);\n } else {\n removeConfigFormValue(state, [\"tools\", \"exec\", \"node\"]);\n }\n },\n onBindAgent: (agentIndex, nodeId) => {\n const basePath = [\"agents\", \"list\", agentIndex, \"tools\", \"exec\", \"node\"];\n if (nodeId) {\n updateConfigFormValue(state, basePath, nodeId);\n } else {\n removeConfigFormValue(state, basePath);\n }\n },\n onSaveBindings: () => saveConfig(state),\n onExecApprovalsTargetChange: (kind, nodeId) => {\n state.execApprovalsTarget = kind;\n state.execApprovalsTargetNodeId = nodeId;\n state.execApprovalsSnapshot = null;\n state.execApprovalsForm = null;\n state.execApprovalsDirty = false;\n state.execApprovalsSelectedAgent = null;\n },\n onExecApprovalsSelectAgent: (agentId) => {\n state.execApprovalsSelectedAgent = agentId;\n },\n onExecApprovalsPatch: (path, value) =>\n updateExecApprovalsFormValue(state, path, value),\n onExecApprovalsRemove: (path) => removeExecApprovalsFormValue(state, path),\n onSaveExecApprovals: () => {\n const target =\n state.execApprovalsTarget === \"node\" && state.execApprovalsTargetNodeId\n ? { kind: \"node\" as const, nodeId: state.execApprovalsTargetNodeId }\n : { kind: \"gateway\" as const };\n return saveExecApprovals(state, target);\n },\n })\n : nothing\n }\n\n ${\n state.onboarding && isChat\n ? html`\n <div class=\"brand-hero\">\n <img\n src=${basePath ? `${basePath}/brand/wednesdayai-logo-bricks.png` : \"/brand/wednesdayai-logo-bricks.png\"}\n alt=\"\"\n class=\"brand-hero__img\"\n />\n </div>\n `\n : nothing\n }\n\n ${\n state.tab === \"chat\"\n ? consoleViews.chat.render(state, {\n sessionKey: state.sessionKey,\n onSessionKeyChange: (next) => {\n state.sessionKey = next;\n state.chatMessage = \"\";\n state.chatAttachments = [];\n state.chatStream = null;\n state.chatStreamStartedAt = null;\n state.chatRunId = null;\n state.chatQueue = [];\n state.resetToolStream();\n state.resetChatScroll();\n state.applySettings({\n ...state.settings,\n sessionKey: next,\n lastActiveSessionKey: next,\n });\n void state.loadAssistantIdentity();\n void loadChatHistory(state);\n void refreshChatAvatar(state);\n },\n thinkingLevel: state.chatThinkingLevel,\n showThinking,\n loading: state.chatLoading,\n sending: state.chatSending,\n compactionStatus: state.compactionStatus,\n fallbackStatus: state.fallbackStatus,\n assistantAvatarUrl: chatAvatarUrl,\n messages: state.chatMessages,\n toolMessages: state.chatToolMessages,\n stream: state.chatStream,\n streamStartedAt: state.chatStreamStartedAt,\n draft: state.chatMessage,\n queue: state.chatQueue,\n connected: state.connected,\n canSend: state.connected,\n disabledReason: chatDisabledReason,\n error: state.lastError,\n sessions: state.sessionsResult,\n focusMode: chatFocus,\n onRefresh: () => {\n state.resetToolStream();\n return Promise.all([loadChatHistory(state), refreshChatAvatar(state)]);\n },\n onToggleFocusMode: () => {\n if (state.onboarding) {\n return;\n }\n state.applySettings({\n ...state.settings,\n chatFocusMode: !state.settings.chatFocusMode,\n });\n },\n onChatScroll: (event) => state.handleChatScroll(event),\n onDraftChange: (next) => (state.chatMessage = next),\n attachments: state.chatAttachments,\n onAttachmentsChange: (next) => (state.chatAttachments = next),\n onSend: () => state.handleSendChat(),\n canAbort: Boolean(state.chatRunId),\n onAbort: () => void state.handleAbortChat(),\n onQueueRemove: (id) => state.removeQueuedMessage(id),\n onNewSession: () => state.handleSendChat(\"/new\", { restoreDraft: true }),\n showNewMessages: state.chatNewMessagesBelow && !state.chatManualRefreshInFlight,\n onScrollToBottom: () => state.scrollToBottom(),\n // Sidebar props for tool output viewing\n sidebarOpen: state.sidebarOpen,\n sidebarContent: state.sidebarContent,\n sidebarError: state.sidebarError,\n splitRatio: state.splitRatio,\n onOpenSidebar: (content: string) => state.handleOpenSidebar(content),\n onCloseSidebar: () => state.handleCloseSidebar(),\n onSplitRatioChange: (ratio: number) => state.handleSplitRatioChange(ratio),\n assistantName: state.assistantName,\n assistantAvatar: state.assistantAvatar,\n })\n : nothing\n }\n\n ${\n state.tab === \"talk\"\n ? !state.connected\n ? renderTalkAvailabilityGuard(state, t(\"talk.reconnecting\"))\n : !talkAvailability.resolved || talkAvailability.loading\n ? renderTalkAvailabilityGuard(state, t(\"talk.loading\"))\n : talkAvailable\n ? consoleViews.talk.render(state, {\n ...state.talkState,\n unavailable: null,\n onStart: () => void state.handleTalkStart(),\n onStop: () => void state.handleTalkStop(),\n onRetry: () => void state.handleTalkRetry(),\n })\n : renderTalkAvailabilityGuard(state, t(\"talk.unavailable\"))\n : nothing\n }\n\n ${\n state.tab === \"config\"\n ? consoleViews.config.render(state, {\n raw: state.configRaw,\n originalRaw: state.configRawOriginal,\n valid: state.configValid,\n issues: state.configIssues,\n loading: state.configLoading,\n saving: state.configSaving,\n applying: state.configApplying,\n updating: state.updateRunning,\n connected: state.connected,\n schema: state.configSchema,\n schemaLoading: state.configSchemaLoading,\n uiHints: state.configUiHints,\n formMode: state.configFormMode,\n formValue: state.configForm,\n originalValue: state.configFormOriginal,\n searchQuery: state.configSearchQuery,\n activeSection: state.configActiveSection,\n activeSubsection: state.configActiveSubsection,\n onRawChange: (next) => {\n state.configRaw = next;\n },\n onFormModeChange: (mode) => (state.configFormMode = mode),\n onFormPatch: (path, value) => updateConfigFormValue(state, path, value),\n onSearchChange: (query) => (state.configSearchQuery = query),\n onSectionChange: (section) => {\n state.configActiveSection = section;\n state.configActiveSubsection = null;\n },\n onSubsectionChange: (section) => (state.configActiveSubsection = section),\n onReload: () => loadConfig(state),\n onSave: () => saveConfig(state),\n onApply: () => applyConfig(state),\n onUpdate: () => runUpdate(state),\n })\n : nothing\n }\n\n ${\n state.tab === \"debug\"\n ? consoleViews.debug.render(state, {\n loading: state.debugLoading,\n status: state.debugStatus,\n health: state.debugHealth,\n models: state.debugModels,\n heartbeat: state.debugHeartbeat,\n eventLog: state.eventLog,\n callMethod: state.debugCallMethod,\n callParams: state.debugCallParams,\n callResult: state.debugCallResult,\n callError: state.debugCallError,\n onCallMethodChange: (next) => (state.debugCallMethod = next),\n onCallParamsChange: (next) => (state.debugCallParams = next),\n onRefresh: () => loadDebug(state),\n onCall: () => callDebugMethod(state),\n })\n : nothing\n }\n\n ${\n state.tab === \"logs\"\n ? consoleViews.logs.render(state, {\n loading: state.logsLoading,\n error: state.logsError,\n file: state.logsFile,\n entries: state.logsEntries,\n filterText: state.logsFilterText,\n levelFilters: state.logsLevelFilters,\n autoFollow: state.logsAutoFollow,\n truncated: state.logsTruncated,\n onFilterTextChange: (next) => (state.logsFilterText = next),\n onLevelToggle: (level, enabled) => {\n state.logsLevelFilters = { ...state.logsLevelFilters, [level]: enabled };\n },\n onToggleAutoFollow: (next) => (state.logsAutoFollow = next),\n onRefresh: () => loadLogs(state, { reset: true }),\n onExport: (lines, label) => state.exportLogs(lines, label),\n onScroll: (event) => state.handleLogsScroll(event),\n })\n : nothing\n }\n </main>\n ${renderExecApprovalPrompt(state)}\n ${renderGatewayUrlConfirmation(state)}\n </div>\n `;\n}\n","import type { GatewayBrowserClient } from \"../gateway.ts\";\n\nexport type ScopeLabel = {\n workspaceId?: string;\n agentId?: string;\n workspaceLabel: string;\n agentLabel: string;\n};\n\nexport type LearningProposalRow = {\n id: string;\n title: string;\n status: \"pending\" | \"applied\" | \"rejected\" | \"quarantined\";\n scopeLabel?: ScopeLabel;\n findingCount?: number;\n};\n\nexport type LearningLessonRow = {\n id: string;\n kind: \"correction\" | \"preference\" | \"procedure\" | \"failure\";\n text: string;\n confidence?: number;\n occurrences?: number;\n distinctSessions?: number;\n scopeLabel?: ScopeLabel;\n recordKind?: \"lesson\" | \"skill\";\n durability?: \"durable\" | \"decaying\" | \"ephemeral\";\n validFrom?: string;\n invalidAt?: string;\n supersedesId?: string;\n sessionId?: string;\n};\n\nexport type LearningOverview = {\n proposals: { pending: number; applied: number; rejected: number; quarantined: number };\n lessons: number;\n scopes: number;\n backend?: \"sqlite\" | \"postgres\";\n capability?: \"full\";\n};\n\nexport type LearningProposalDetail = {\n id: string;\n body: string;\n scannerFindings: unknown[];\n sourceLessonIds: string[];\n history: unknown[];\n scopeLabel?: ScopeLabel;\n};\n\nexport type LearningDecisionAction = \"apply\" | \"reject\" | \"quarantine\";\n\nexport type LearningState = {\n client: GatewayBrowserClient | null;\n connected: boolean;\n learningLoading: boolean;\n learningError: string | null;\n overview: LearningOverview | null;\n proposals: LearningProposalRow[];\n lessons: LearningLessonRow[];\n selectedProposal: LearningProposalDetail | null;\n learningBusy: boolean;\n searchGeneration: number;\n};\n\nexport function createDefaultLearningState(): LearningState {\n return {\n client: null,\n connected: false,\n learningLoading: false,\n learningError: null,\n overview: null,\n proposals: [],\n lessons: [],\n selectedProposal: null,\n learningBusy: false,\n searchGeneration: 0,\n };\n}\n\nexport async function loadLearningOverview(state: LearningState): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<LearningOverview>(\"learning.overview\", {});\n state.overview = res;\n } catch (err) {\n state.learningError = String(err);\n }\n}\n\nexport async function loadProposals(state: LearningState): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<{ proposals: LearningProposalRow[] }>(\n \"learning.listProposals\",\n {},\n );\n state.proposals = res.proposals ?? [];\n } catch (err) {\n state.learningError = String(err);\n }\n}\n\nexport async function loadLessons(state: LearningState): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<{ lessons: LearningLessonRow[] }>(\n \"learning.listLessons\",\n {},\n );\n state.lessons = res.lessons ?? [];\n } catch (err) {\n state.learningError = String(err);\n }\n}\n\nexport async function inspectProposal(state: LearningState, proposalId: string): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n try {\n const res = await state.client.request<LearningProposalDetail>(\"learning.inspectProposal\", {\n proposalId,\n });\n state.selectedProposal = res;\n } catch (err) {\n state.learningError = String(err);\n }\n}\n\nexport async function decideProposal(\n state: LearningState,\n proposalId: string,\n action: LearningDecisionAction,\n): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n if (state.learningBusy) {\n return;\n }\n state.learningBusy = true;\n try {\n await state.client.request(\"learning.decideProposal\", { proposalId, action });\n await loadProposals(state);\n await loadLearningOverview(state);\n } catch (err) {\n state.learningError = String(err);\n } finally {\n state.learningBusy = false;\n }\n}\n\nexport async function searchLessons(state: LearningState, query: string): Promise<void> {\n if (!state.client || !state.connected) {\n return;\n }\n const trimmed = query.trim();\n const token = state.searchGeneration + 1;\n state.searchGeneration = token;\n if (!trimmed) {\n await loadLessons(state);\n return;\n }\n try {\n const res = await state.client.request<{\n hits: Array<{ lesson: LearningLessonRow; score: number; sessionId?: string }>;\n }>(\"learning.searchLessons\", { query: trimmed, k: 20 });\n if (state.searchGeneration !== token) {\n return;\n }\n state.lessons = (res.hits ?? []).map((hit) => ({\n ...hit.lesson,\n sessionId: hit.sessionId ?? hit.lesson.sessionId,\n }));\n } catch (err) {\n if (state.searchGeneration !== token) {\n return;\n }\n state.learningError = String(err);\n }\n}\n\nexport async function decideProposals(\n state: LearningState,\n ids: string[],\n action: LearningDecisionAction,\n): Promise<void> {\n if (!state.client || !state.connected || ids.length === 0) {\n return;\n }\n if (state.learningBusy) {\n return;\n }\n state.learningBusy = true;\n try {\n await state.client.request(\"learning.decideProposals\", { ids, action });\n await loadProposals(state);\n await loadLearningOverview(state);\n } catch (err) {\n state.learningError = String(err);\n } finally {\n state.learningBusy = false;\n }\n}\n","import type {\n TalkLifecycle,\n TalkRealtimeRelayEvent,\n TalkRealtimeTranscriptStatus,\n TalkSessionClient,\n TalkSessionClientState,\n} from \"talk-client\";\n\nexport type TalkTranscriptEntry = {\n id: string;\n relaySessionId: string;\n role: \"user\" | \"assistant\";\n text: string;\n final: boolean;\n itemId?: string;\n responseId?: string;\n contentIndex?: number;\n itemOrder?: number;\n status?: TalkRealtimeTranscriptStatus;\n startedAtMs: number;\n completedAtMs?: number;\n};\n\nexport type TalkAvailabilityState = {\n resolved: boolean;\n loading: boolean;\n enabled: boolean;\n available: boolean;\n configuredProviderIds: string[];\n error: string | null;\n};\n\nexport type TalkState = {\n lifecycle: TalkLifecycle;\n relaySessionId: string | null;\n provider: string | null;\n transcript: TalkTranscriptEntry[];\n error: string | null;\n recording: boolean;\n playing: boolean;\n droppedAudioFrames: number;\n availability: TalkAvailabilityState;\n};\n\nexport const DEFAULT_TALK_STATE: TalkState = {\n lifecycle: \"idle\",\n relaySessionId: null,\n provider: null,\n transcript: [],\n error: null,\n recording: false,\n playing: false,\n droppedAudioFrames: 0,\n availability: {\n resolved: false,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: null,\n },\n};\n\nexport function createDefaultTalkState(): TalkState {\n return {\n ...DEFAULT_TALK_STATE,\n transcript: DEFAULT_TALK_STATE.transcript.map((entry) => ({ ...entry })),\n availability: {\n ...DEFAULT_TALK_STATE.availability,\n configuredProviderIds: [...DEFAULT_TALK_STATE.availability.configuredProviderIds],\n },\n };\n}\n\nexport type TalkController = {\n start(): Promise<void>;\n stop(): Promise<void>;\n retry(): Promise<void>;\n reconnectIfIntended(): Promise<void>;\n handleRelayEvent(event: TalkRealtimeRelayEvent): void;\n handleSessionEvent(event: TalkRealtimeRelayEvent): void;\n handleSessionState(state: TalkSessionClientState): void;\n handleGatewayClose(): void;\n loadAvailability(): Promise<void>;\n};\n\nexport type TalkControllerOptions = {\n sessionClient: TalkSessionClient;\n onState: (state: TalkState) => void;\n now?: () => number;\n request?: <T>(method: string, params?: unknown) => Promise<T>;\n};\n\nfunction normalizeError(error: unknown, fallback: string): string {\n if (error instanceof Error && error.message.trim()) {\n return error.message.trim();\n }\n if (typeof error === \"string\" && error.trim()) {\n return error.trim();\n }\n return fallback;\n}\n\ntype TalkCommand = {\n generation: number;\n promise: Promise<void>;\n resolve: () => void;\n reject: (error: unknown) => void;\n gatewayCloseError?: string | null;\n};\n\nfunction createTalkCommand(generation: number): TalkCommand {\n let resolve!: () => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<void>((promiseResolve, promiseReject) => {\n resolve = () => promiseResolve();\n reject = promiseReject;\n });\n return { generation, promise, resolve, reject };\n}\n\nexport function createTalkController(options: TalkControllerOptions): TalkController {\n const now = options.now ?? Date.now;\n const MAX_EPOCH_MS = 8.64e15;\n const validEpochMs = (value: unknown): value is number =>\n Number.isInteger(value) && (value as number) >= 0 && (value as number) <= MAX_EPOCH_MS;\n const readNow = (): number => {\n const value = now();\n if (!validEpochMs(value)) {\n throw new Error(\"Talk clock returned an invalid epoch millisecond value\");\n }\n return value;\n };\n let state: TalkState = createDefaultTalkState();\n let commandGeneration = 0;\n let availabilityGeneration = 0;\n let transcriptSequence = 0;\n let relaySessionSequence = 0;\n const relaySessionOrders = new Map<string, number>();\n let startCommand: TalkCommand | null = null;\n let stopCommand: TalkCommand | null = null;\n let startBarrier: Promise<void> | null = null;\n let intendedActive = false;\n let intentGeneration = 0;\n let reconnectInFlight: Promise<void> | null = null;\n let reconnectIntentGeneration: number | null = null;\n let pendingInterruptState: TalkSessionClientState | null = null;\n let activePartialTranscriptIds: Record<TalkTranscriptEntry[\"role\"], string | null> = {\n user: null,\n assistant: null,\n };\n let preReducedCloseRelaySessionId: string | null = null;\n let delegatedRelayEvent: TalkRealtimeRelayEvent | null = null;\n let delegatedRelayGeneration: number | null = null;\n\n function publish(patch: Partial<TalkState>) {\n state = { ...state, ...patch };\n options.onState(state);\n }\n\n function publishAvailability(availability: TalkAvailabilityState) {\n publish({\n availability: {\n ...availability,\n configuredProviderIds: [...availability.configuredProviderIds],\n },\n });\n }\n\n function loadAvailability(): Promise<void> {\n const generation = ++availabilityGeneration;\n publishAvailability({\n resolved: false,\n loading: true,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: null,\n });\n\n const request = options.request;\n if (!request) {\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: \"Talk availability requester is unavailable\",\n });\n return Promise.resolve();\n }\n\n let responsePromise: Promise<unknown>;\n try {\n responsePromise = request<unknown>(\"talk.realtime.status\", {});\n } catch (error) {\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: normalizeError(error, \"Talk availability request failed\").slice(0, 200),\n });\n return Promise.resolve();\n }\n\n return responsePromise\n .then((result) => {\n if (!isTalkAvailabilityResponse(result)) {\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: \"Malformed Talk availability response\",\n });\n return;\n }\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: result.enabled,\n available: result.available,\n configuredProviderIds: result.configuredProviderIds,\n error: null,\n });\n })\n .catch((error: unknown) => {\n publishAvailabilityIfCurrent(generation, {\n resolved: true,\n loading: false,\n enabled: false,\n available: false,\n configuredProviderIds: [],\n error: normalizeError(error, \"Talk availability request failed\").slice(0, 200),\n });\n });\n }\n\n function publishAvailabilityIfCurrent(\n generation: number,\n availability: TalkAvailabilityState,\n ): void {\n if (availabilityGeneration === generation) {\n publishAvailability(availability);\n }\n }\n\n function isTalkAvailabilityResponse(value: unknown): value is {\n enabled: boolean;\n available: boolean;\n configuredProviderIds: string[];\n } {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const response = value as Record<string, unknown>;\n const configuredProviderIds = response.configuredProviderIds;\n return (\n typeof response.enabled === \"boolean\" &&\n typeof response.available === \"boolean\" &&\n Array.isArray(configuredProviderIds) &&\n configuredProviderIds.every((providerId) => typeof providerId === \"string\") &&\n !(response.available && (!response.enabled || configuredProviderIds.length === 0))\n );\n }\n\n function resetActivePartialTranscripts() {\n activePartialTranscriptIds = { user: null, assistant: null };\n }\n\n function resetToIdle(error: string | null = state.error) {\n pendingInterruptState = null;\n resetActivePartialTranscripts();\n publish({\n lifecycle: \"idle\",\n relaySessionId: null,\n provider: null,\n error,\n recording: false,\n playing: false,\n });\n }\n\n function retainStartBarrier(promise: Promise<void>) {\n const barrier = promise.catch(() => undefined);\n startBarrier = barrier;\n void barrier.then(() => {\n if (startBarrier === barrier) {\n startBarrier = null;\n }\n });\n }\n\n function disassociateStartCommand() {\n if (startCommand) {\n retainStartBarrier(startCommand.promise);\n }\n startCommand = null;\n }\n\n function beginStart(generation: number, waitFor?: Promise<void>): Promise<void> {\n resetActivePartialTranscripts();\n const command = createTalkCommand(generation);\n startCommand = command;\n void command.promise.then(\n () => {\n if (startCommand === command) {\n startCommand = null;\n }\n },\n () => {\n if (startCommand === command) {\n startCommand = null;\n }\n },\n );\n publish({ lifecycle: \"starting\", error: null, recording: false, playing: false });\n if (commandGeneration !== command.generation || startCommand !== command) {\n command.resolve();\n return command.promise;\n }\n const run = (async () => {\n if (waitFor) {\n await waitFor;\n if (commandGeneration !== command.generation || startCommand !== command) {\n return;\n }\n }\n try {\n await options.sessionClient.start();\n } catch (error) {\n if (commandGeneration === command.generation && startCommand === command) {\n resetToIdle(normalizeError(error, \"Unable to start Talk\"));\n }\n return;\n }\n if (commandGeneration !== command.generation || startCommand !== command) {\n return;\n }\n })();\n void run.then(command.resolve, command.reject);\n return command.promise;\n }\n\n function start(): Promise<void> {\n intendedActive = true;\n intentGeneration += 1;\n if (startCommand) {\n return startCommand.promise;\n }\n if (!stopCommand && (state.lifecycle === \"active\" || state.lifecycle === \"interrupting\")) {\n return Promise.resolve();\n }\n const generation = ++commandGeneration;\n // A reconnect still in flight after the intent bump above is dead; the new\n // start must chain after it settles or handleSessionState would swallow\n // its client echoes for as long as the stale reconnect is in flight.\n const staleReconnect =\n reconnectInFlight !== null && reconnectIntentGeneration !== intentGeneration\n ? reconnectInFlight\n : null;\n const barriers = [stopCommand?.promise, startBarrier, staleReconnect].filter(\n (barrier): barrier is Promise<void> => barrier !== undefined && barrier !== null,\n );\n const waitFor =\n barriers.length === 0\n ? undefined\n : barriers.length === 1\n ? barriers[0]\n : Promise.all(barriers).then(() => undefined);\n return beginStart(generation, waitFor);\n }\n\n function associateStopCommand(command: TalkCommand) {\n stopCommand = command;\n void command.promise.then(\n () => {\n if (stopCommand === command) {\n stopCommand = null;\n }\n },\n () => {\n if (stopCommand === command) {\n stopCommand = null;\n }\n },\n );\n }\n\n function runStopCommand(command: TalkCommand) {\n const run = (async () => {\n let stopError: string | null = null;\n try {\n await options.sessionClient.stop();\n } catch (error) {\n stopError = normalizeError(error, \"Unable to stop Talk\");\n }\n if (commandGeneration === command.generation && stopCommand === command) {\n resetToIdle(stopError ?? command.gatewayCloseError ?? null);\n }\n })();\n void run.then(command.resolve, command.reject);\n }\n\n function beginStop(generation: number): Promise<void> {\n const command = createTalkCommand(generation);\n associateStopCommand(command);\n publish({\n lifecycle: \"stopping\",\n relaySessionId: null,\n provider: null,\n recording: false,\n playing: false,\n });\n runStopCommand(command);\n return command.promise;\n }\n\n function stop(): Promise<void> {\n const wasIntendedActive = intendedActive;\n intendedActive = false;\n intentGeneration += 1;\n const generation = ++commandGeneration;\n resetActivePartialTranscripts();\n disassociateStartCommand();\n if (stopCommand) {\n stopCommand.generation = generation;\n delete stopCommand.gatewayCloseError;\n return stopCommand.promise;\n }\n // A stop while idle is silent once nothing is left to tear down: either no\n // start intent was ever recorded, or a gateway close already ran its\n // teardown, kept the intent, and settled. While a reconnect or a pending\n // start barrier is in flight the full stop cycle still runs so the client\n // attempt is cancelled and observers see the stopping transition.\n if (!wasIntendedActive && state.lifecycle === \"idle\") {\n return Promise.resolve();\n }\n if (\n wasIntendedActive &&\n state.lifecycle === \"idle\" &&\n startBarrier === null &&\n reconnectInFlight === null\n ) {\n return Promise.resolve();\n }\n return beginStop(generation);\n }\n\n function reconnectIfIntended(): Promise<void> {\n if (!intendedActive) {\n return Promise.resolve();\n }\n if (reconnectInFlight) {\n return reconnectInFlight;\n }\n const capturedIntentGeneration = intentGeneration;\n const pending = (async () => {\n try {\n await options.sessionClient.start();\n if (intentGeneration === capturedIntentGeneration) {\n publish({ error: null });\n }\n } catch (error) {\n if (intentGeneration === capturedIntentGeneration) {\n resetToIdle(normalizeError(error, \"Unable to start Talk\"));\n }\n }\n })();\n reconnectInFlight = pending;\n reconnectIntentGeneration = capturedIntentGeneration;\n void pending.finally(() => {\n if (reconnectInFlight === pending) {\n reconnectInFlight = null;\n reconnectIntentGeneration = null;\n }\n });\n return pending;\n }\n\n function ensureRelaySessionOrder(relaySessionId: string): number {\n const existing = relaySessionOrders.get(relaySessionId);\n if (existing !== undefined) {\n return existing;\n }\n relaySessionSequence += 1;\n relaySessionOrders.set(relaySessionId, relaySessionSequence);\n return relaySessionSequence;\n }\n\n function hasTranscriptIdentity(\n event: Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }>,\n ): event is Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }> & {\n itemId: string;\n contentIndex: number;\n itemOrder?: number;\n } {\n return (\n typeof event.itemId === \"string\" &&\n event.itemId.length > 0 &&\n Number.isInteger(event.contentIndex) &&\n (event.contentIndex ?? -1) >= 0\n );\n }\n\n function hasValidTranscriptItemOrder(value: number | undefined): value is number {\n return value !== undefined && Number.isInteger(value) && value >= 0;\n }\n\n type TranscriptEvent = Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }>;\n type TranscriptTiming = { startedAtMs: number; completedAtMs?: number };\n\n function terminalState(event: TranscriptEvent): \"open\" | \"terminal\" | \"contradictory\" {\n if ((event.status === \"pending\" || event.status === \"streaming\") && event.final) {\n return \"contradictory\";\n }\n if (event.status === \"final\" || event.status === \"failed\") {\n return \"terminal\";\n }\n return event.status === undefined && event.final ? \"terminal\" : \"open\";\n }\n\n function resolveTranscriptTiming(\n event: TranscriptEvent,\n existing?: TalkTranscriptEntry,\n ): TranscriptTiming {\n const terminal = terminalState(event) === \"terminal\";\n const needsStart = existing === undefined && !validEpochMs(event.startedAtMs);\n const needsCompletion =\n terminal && existing?.completedAtMs === undefined && !validEpochMs(event.completedAtMs);\n const observedAt = needsStart || needsCompletion ? readNow() : undefined;\n const startedAtMs =\n existing?.startedAtMs ?? (validEpochMs(event.startedAtMs) ? event.startedAtMs : observedAt!);\n const completedAtMs =\n existing?.completedAtMs ??\n (terminal\n ? validEpochMs(event.completedAtMs)\n ? event.completedAtMs\n : observedAt!\n : undefined);\n return {\n startedAtMs,\n ...(completedAtMs !== undefined ? { completedAtMs } : {}),\n };\n }\n\n function orderTranscript(entries: TalkTranscriptEntry[]): TalkTranscriptEntry[] {\n const groups = new Map<string, TalkTranscriptEntry[]>();\n for (const entry of entries) {\n const group = groups.get(entry.relaySessionId) ?? [];\n group.push(entry);\n groups.set(entry.relaySessionId, group);\n }\n // Array.from already produced a fresh array, so it is sorted in place.\n const orderedGroups = Array.from(groups.entries());\n orderedGroups.sort(\n ([leftSessionId], [rightSessionId]) =>\n ensureRelaySessionOrder(leftSessionId) - ensureRelaySessionOrder(rightSessionId),\n );\n return orderedGroups.flatMap(([, group]) => {\n const identifiedIndexes: number[] = [];\n const identifiedEntries: TalkTranscriptEntry[] = [];\n group.forEach((entry, index) => {\n if (entry.itemOrder !== undefined) {\n identifiedIndexes.push(index);\n identifiedEntries.push(entry);\n }\n });\n identifiedEntries.sort((left, right) => left.itemOrder! - right.itemOrder!);\n const ordered = [...group];\n identifiedIndexes.forEach((index, identifiedIndex) => {\n ordered[index] = identifiedEntries[identifiedIndex];\n });\n return ordered;\n });\n }\n\n function upsertIdentifiedTranscript(\n event: Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }> & {\n itemId: string;\n contentIndex: number;\n itemOrder?: number;\n },\n ): void {\n ensureRelaySessionOrder(event.relaySessionId);\n const id = JSON.stringify([event.relaySessionId, event.itemId, event.contentIndex]);\n const existingIndex = state.transcript.findIndex((entry) => entry.id === id);\n const existing = existingIndex >= 0 ? state.transcript[existingIndex] : undefined;\n if (\n existing &&\n (existing.final || existing.status === \"final\" || existing.status === \"failed\")\n ) {\n return;\n }\n if (existing && event.status === \"pending\") {\n return;\n }\n const replaceText = terminalState(event) === \"terminal\";\n const timing = resolveTranscriptTiming(event, existing);\n // An invalid item order keeps identified handling but is ignored (treated\n // as absent); a valid order survives updates that omit it.\n const itemOrder = hasValidTranscriptItemOrder(event.itemOrder) ? event.itemOrder : undefined;\n const entry: TalkTranscriptEntry = {\n id,\n relaySessionId: event.relaySessionId,\n role: event.role,\n text: existing && !replaceText ? `${existing.text}${event.text}` : event.text,\n final: event.final,\n itemId: event.itemId,\n ...(event.responseId !== undefined || existing?.responseId !== undefined\n ? { responseId: event.responseId ?? existing?.responseId }\n : {}),\n contentIndex: event.contentIndex,\n ...(itemOrder !== undefined || existing?.itemOrder !== undefined\n ? { itemOrder: itemOrder ?? existing?.itemOrder }\n : {}),\n ...(event.status !== undefined ? { status: event.status } : {}),\n ...timing,\n };\n const transcript = [...state.transcript];\n if (existingIndex >= 0) {\n transcript[existingIndex] = entry;\n } else {\n transcript.push(entry);\n }\n publish({ transcript: orderTranscript(transcript) });\n }\n\n function appendTranscript(event: Extract<TalkRealtimeRelayEvent, { type: \"transcript\" }>) {\n const eventState = terminalState(event);\n if (eventState === \"contradictory\") {\n return;\n }\n if (hasTranscriptIdentity(event)) {\n upsertIdentifiedTranscript(event);\n return;\n }\n ensureRelaySessionOrder(event.relaySessionId);\n const activePartialTranscriptId = activePartialTranscriptIds[event.role];\n const activeIndex = activePartialTranscriptId\n ? state.transcript.findIndex((entry) => entry.id === activePartialTranscriptId)\n : -1;\n const active = activeIndex >= 0 ? state.transcript[activeIndex] : undefined;\n const activeIsOpen =\n active !== undefined &&\n active.role === event.role &&\n !active.final &&\n active.status !== \"final\" &&\n active.status !== \"failed\";\n if (activeIsOpen) {\n const timing = resolveTranscriptTiming(event, active);\n const transcript = [...state.transcript];\n transcript[activeIndex] = {\n id: active.id,\n relaySessionId: active.relaySessionId,\n role: active.role,\n text: eventState === \"terminal\" ? event.text : `${active.text}${event.text}`,\n final: event.final,\n ...(event.status !== undefined ? { status: event.status } : {}),\n ...timing,\n };\n if (eventState === \"terminal\") {\n activePartialTranscriptIds[event.role] = null;\n }\n publish({\n transcript,\n });\n return;\n }\n transcriptSequence += 1;\n const id = `transcript-${transcriptSequence}`;\n const timing = resolveTranscriptTiming(event);\n activePartialTranscriptIds[event.role] = eventState === \"terminal\" ? null : id;\n publish({\n transcript: [\n ...state.transcript,\n {\n id,\n relaySessionId: event.relaySessionId,\n role: event.role,\n text: event.text,\n final: event.final,\n ...(event.status !== undefined ? { status: event.status } : {}),\n ...timing,\n },\n ],\n });\n }\n\n function handleSessionEvent(event: TalkRealtimeRelayEvent) {\n const invalidatedDelegatedEvent =\n delegatedRelayEvent === event &&\n delegatedRelayGeneration !== null &&\n delegatedRelayGeneration !== commandGeneration;\n const acceptedPreReducedClose =\n event.type === \"close\" && preReducedCloseRelaySessionId === event.relaySessionId;\n if (invalidatedDelegatedEvent && !acceptedPreReducedClose) {\n return;\n }\n switch (event.type) {\n case \"audio\":\n publish({\n lifecycle: state.lifecycle === \"interrupting\" ? \"active\" : state.lifecycle,\n playing: true,\n });\n break;\n case \"clear\": {\n const pendingRecording = pendingInterruptState?.recording;\n const captureStarting = state.lifecycle === \"starting\";\n pendingInterruptState = null;\n publish({\n lifecycle: captureStarting\n ? \"starting\"\n : event.reason === \"barge-in\"\n ? \"interrupting\"\n : state.lifecycle === \"idle\" || state.lifecycle === \"stopping\"\n ? state.lifecycle\n : \"active\",\n recording:\n !captureStarting &&\n (pendingRecording ?? (state.lifecycle !== \"idle\" && state.lifecycle !== \"stopping\")),\n playing: false,\n });\n break;\n }\n case \"vadBargeIn\": {\n const captureStarting = state.lifecycle === \"starting\";\n publish({\n lifecycle: captureStarting\n ? \"starting\"\n : state.lifecycle === \"idle\" || state.lifecycle === \"stopping\"\n ? state.lifecycle\n : \"interrupting\",\n recording:\n !captureStarting &&\n (pendingInterruptState?.recording ??\n (state.lifecycle !== \"idle\" && state.lifecycle !== \"stopping\")),\n playing: false,\n });\n break;\n }\n case \"ready\":\n if (state.lifecycle === \"interrupting\") {\n publish({ lifecycle: \"active\" });\n }\n break;\n case \"transcript\":\n appendTranscript(event);\n if (event.role === \"assistant\" && state.lifecycle === \"interrupting\") {\n publish({ lifecycle: \"active\" });\n }\n break;\n case \"error\":\n publish({ error: normalizeError(event.message, \"Talk provider error\") });\n break;\n case \"close\":\n if (preReducedCloseRelaySessionId === event.relaySessionId) {\n preReducedCloseRelaySessionId = null;\n break;\n }\n commandGeneration += 1;\n preReducedCloseRelaySessionId = null;\n disassociateStartCommand();\n resetToIdle();\n break;\n default:\n break;\n }\n }\n\n options.onState(state);\n\n return {\n start,\n stop,\n reconnectIfIntended,\n async retry() {\n intendedActive = true;\n intentGeneration += 1;\n const generation = ++commandGeneration;\n resetActivePartialTranscripts();\n disassociateStartCommand();\n // Same barrier as start(): a reconnect in flight is dead after the intent\n // bump, and the retried start must chain after it settles.\n const staleReconnect =\n reconnectInFlight !== null && reconnectIntentGeneration !== intentGeneration\n ? reconnectInFlight\n : null;\n const stopped = stopCommand?.promise ?? beginStop(generation);\n await stopped;\n if (commandGeneration !== generation) {\n return;\n }\n const started = beginStart(generation, staleReconnect ?? undefined);\n await started;\n if (commandGeneration !== generation) {\n return;\n }\n },\n handleRelayEvent(event) {\n const previousEvent = delegatedRelayEvent;\n const previousGeneration = delegatedRelayGeneration;\n delegatedRelayEvent = event;\n delegatedRelayGeneration = commandGeneration;\n try {\n options.sessionClient.handleRelayEvent(event);\n } finally {\n delegatedRelayEvent = previousEvent;\n delegatedRelayGeneration = previousGeneration;\n }\n },\n handleSessionEvent,\n handleSessionState(sessionState) {\n // A reconnect whose intent generation was superseded (user stop or a new\n // user start) is dead; its client echoes must never install session\n // state. New user starts chain after the dead reconnect settles, so\n // their states arrive only after this ignore window closes.\n if (reconnectIntentGeneration !== null && reconnectIntentGeneration !== intentGeneration) {\n return;\n }\n const supersededStopIdle =\n sessionState.lifecycle === \"idle\" &&\n state.lifecycle === \"starting\" &&\n startCommand?.generation === commandGeneration &&\n stopCommand !== null &&\n stopCommand.generation < commandGeneration;\n if (supersededStopIdle) {\n return;\n }\n const delegatedClose =\n delegatedRelayEvent?.type === \"close\" ? delegatedRelayEvent : undefined;\n const closeInducedIdle =\n sessionState.lifecycle === \"idle\" &&\n sessionState.relaySessionId === null &&\n (delegatedClose !== undefined ||\n (state.relaySessionId !== null &&\n (state.lifecycle === \"active\" || state.lifecycle === \"interrupting\")));\n if (closeInducedIdle) {\n commandGeneration += 1;\n preReducedCloseRelaySessionId = delegatedClose?.relaySessionId ?? state.relaySessionId;\n disassociateStartCommand();\n resetActivePartialTranscripts();\n }\n if (sessionState.lifecycle === \"interrupting\") {\n pendingInterruptState = sessionState;\n publish({\n relaySessionId: sessionState.relaySessionId,\n provider: sessionState.provider,\n recording: state.lifecycle === \"starting\" ? false : sessionState.recording,\n playing: sessionState.playing,\n droppedAudioFrames: sessionState.droppedAudioFrames,\n });\n return;\n }\n pendingInterruptState = null;\n publish({\n lifecycle: sessionState.lifecycle,\n relaySessionId: sessionState.relaySessionId,\n provider: sessionState.provider,\n recording: sessionState.recording,\n playing: sessionState.playing,\n droppedAudioFrames: sessionState.droppedAudioFrames,\n });\n },\n handleGatewayClose() {\n const generation = ++commandGeneration;\n resetActivePartialTranscripts();\n preReducedCloseRelaySessionId = null;\n disassociateStartCommand();\n let teardown = stopCommand;\n const createdTeardown = !teardown;\n if (teardown) {\n teardown.generation = generation;\n } else {\n teardown = createTalkCommand(generation);\n associateStopCommand(teardown);\n }\n if (createdTeardown || Object.hasOwn(teardown, \"gatewayCloseError\")) {\n teardown.gatewayCloseError = state.error;\n }\n options.sessionClient.handleGatewayClose();\n if (commandGeneration === generation && stopCommand === teardown) {\n resetToIdle();\n }\n if (createdTeardown) {\n runStopCommand(teardown);\n }\n },\n loadAvailability,\n };\n}\n\nexport type { TalkLifecycle, TalkRealtimeRelayEvent };\n","import { LitElement } from \"lit\";\nimport { customElement, state } from \"lit/decorators.js\";\nimport {\n createTalkAudioCapture,\n createTalkAudioPlayback,\n createTalkSessionClient,\n type TalkSessionClient,\n} from \"talk-client\";\nimport { i18n, I18nController, isSupportedLocale } from \"../i18n/index.ts\";\nimport {\n handleChannelConfigReload as handleChannelConfigReloadInternal,\n handleChannelConfigSave as handleChannelConfigSaveInternal,\n handleNostrProfileCancel as handleNostrProfileCancelInternal,\n handleNostrProfileEdit as handleNostrProfileEditInternal,\n handleNostrProfileFieldChange as handleNostrProfileFieldChangeInternal,\n handleNostrProfileImport as handleNostrProfileImportInternal,\n handleNostrProfileSave as handleNostrProfileSaveInternal,\n handleNostrProfileToggleAdvanced as handleNostrProfileToggleAdvancedInternal,\n handleWhatsAppLogout as handleWhatsAppLogoutInternal,\n handleWhatsAppStart as handleWhatsAppStartInternal,\n handleWhatsAppWait as handleWhatsAppWaitInternal,\n} from \"./app-channels.ts\";\nimport {\n handleAbortChat as handleAbortChatInternal,\n handleSendChat as handleSendChatInternal,\n removeQueuedMessage as removeQueuedMessageInternal,\n} from \"./app-chat.ts\";\nimport { DEFAULT_CRON_FORM, DEFAULT_LOG_LEVEL_FILTERS } from \"./app-defaults.ts\";\nimport type { EventLogEntry } from \"./app-events.ts\";\nimport { connectGateway as connectGatewayInternal, createGatewayRequester } from \"./app-gateway.ts\";\nimport {\n handleConnected,\n handleDisconnected,\n handleFirstUpdated,\n handleUpdated,\n handleVisibilityChange as handleVisibilityChangeInternal,\n} from \"./app-lifecycle.ts\";\nimport { renderApp } from \"./app-render.ts\";\nimport {\n exportLogs as exportLogsInternal,\n handleChatScroll as handleChatScrollInternal,\n handleLogsScroll as handleLogsScrollInternal,\n resetChatScroll as resetChatScrollInternal,\n scheduleChatScroll as scheduleChatScrollInternal,\n} from \"./app-scroll.ts\";\nimport {\n applySettings as applySettingsInternal,\n loadCron as loadCronInternal,\n loadOverview as loadOverviewInternal,\n setTab as setTabInternal,\n setTheme as setThemeInternal,\n onPopState as onPopStateInternal,\n} from \"./app-settings.ts\";\nimport {\n resetToolStream as resetToolStreamInternal,\n type ToolStreamEntry,\n type CompactionStatus,\n type FallbackStatus,\n} from \"./app-tool-stream.ts\";\nimport type { AppViewState } from \"./app-view-state.ts\";\nimport { normalizeAssistantIdentity } from \"./assistant-identity.ts\";\nimport { loadAssistantIdentity as loadAssistantIdentityInternal } from \"./controllers/assistant-identity.ts\";\nimport type { CronFieldErrors } from \"./controllers/cron.ts\";\nimport type { DevicePairingList } from \"./controllers/devices.ts\";\nimport {\n createDefaultDreamsState,\n loadDreams as loadDreamsInternal,\n type DreamsViewState,\n} from \"./controllers/dreams.ts\";\nimport type { ExecApprovalRequest } from \"./controllers/exec-approval.ts\";\nimport type { ExecApprovalsFile, ExecApprovalsSnapshot } from \"./controllers/exec-approvals.ts\";\nimport {\n loadLearningOverview,\n loadProposals,\n loadLessons,\n inspectProposal,\n decideProposal,\n} from \"./controllers/learning.ts\";\nimport type { SkillMessage } from \"./controllers/skills.ts\";\nimport {\n createDefaultTalkState,\n createTalkController,\n type TalkController,\n type TalkState,\n} from \"./controllers/talk.ts\";\nimport type { GatewayBrowserClient, GatewayHelloOk } from \"./gateway.ts\";\nimport type { Tab } from \"./navigation.ts\";\nimport { loadSettings, type UiSettings } from \"./storage.ts\";\nimport type { ResolvedTheme, ThemeMode } from \"./theme.ts\";\nimport type {\n AgentsListResult,\n AgentsFilesListResult,\n AgentIdentityResult,\n ConfigSnapshot,\n ConfigUiHints,\n CronJob,\n CronRunLogEntry,\n CronStatus,\n HealthSnapshot,\n LogEntry,\n LogLevel,\n PresenceEntry,\n ChannelsStatusSnapshot,\n SessionRunsResult,\n SessionsThresholdsResult,\n SessionsListResult,\n SkillStatusReport,\n ToolsCatalogResult,\n StatusSummary,\n NostrProfile,\n} from \"./types.ts\";\nimport { type ChatAttachment, type ChatQueueItem, type CronFormState } from \"./ui-types.ts\";\nimport { generateUUID } from \"./uuid.ts\";\nimport type { NostrProfileFormState } from \"./views/channels.nostr-profile-form.ts\";\n\ndeclare global {\n interface Window {\n __OPENCLAW_CONTROL_UI_BASE_PATH__?: string;\n }\n}\n\nconst bootAssistantIdentity = normalizeAssistantIdentity({});\n\nfunction resolveOnboardingMode(): boolean {\n if (!window.location.search) {\n return false;\n }\n const params = new URLSearchParams(window.location.search);\n const raw = params.get(\"onboarding\");\n if (!raw) {\n return false;\n }\n const normalized = raw.trim().toLowerCase();\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\" || normalized === \"on\";\n}\n\n@customElement(\"openclaw-app\")\nexport class OpenClawApp extends LitElement {\n private i18nController = new I18nController(this);\n clientInstanceId = generateUUID();\n @state() settings: UiSettings = loadSettings();\n constructor() {\n super();\n if (isSupportedLocale(this.settings.locale)) {\n void i18n.setLocale(this.settings.locale);\n }\n const request = createGatewayRequester(this);\n this.talkSessionClient = createTalkSessionClient({\n request,\n capture: createTalkAudioCapture,\n playback: createTalkAudioPlayback,\n onState: (next) => this.talkController.handleSessionState(next),\n onEvent: (event) => this.talkController.handleSessionEvent(event),\n });\n this.talkController = createTalkController({\n sessionClient: this.talkSessionClient,\n request,\n onState: (next) => {\n this.talkState = next;\n },\n });\n }\n @state() password = \"\";\n @state() tab: Tab = \"overview\";\n @state() onboarding = resolveOnboardingMode();\n @state() connected = false;\n @state() theme: ThemeMode = this.settings.theme ?? \"system\";\n @state() themeResolved: ResolvedTheme = \"dark\";\n @state() hello: GatewayHelloOk | null = null;\n @state() lastError: string | null = null;\n @state() lastErrorCode: string | null = null;\n @state() eventLog: EventLogEntry[] = [];\n private eventLogBuffer: EventLogEntry[] = [];\n private toolStreamSyncTimer: number | null = null;\n private sidebarCloseTimer: number | null = null;\n\n @state() assistantName = bootAssistantIdentity.name;\n @state() assistantAvatar = bootAssistantIdentity.avatar;\n @state() assistantAgentId = bootAssistantIdentity.agentId ?? null;\n @state() consolePath: string | null = null;\n\n @state() sessionKey = this.settings.sessionKey;\n @state() chatLoading = false;\n @state() chatSending = false;\n @state() chatMessage = \"\";\n @state() chatMessages: unknown[] = [];\n @state() chatToolMessages: unknown[] = [];\n @state() chatStream: string | null = null;\n @state() chatStreamStartedAt: number | null = null;\n @state() chatRunId: string | null = null;\n @state() compactionStatus: CompactionStatus | null = null;\n @state() fallbackStatus: FallbackStatus | null = null;\n @state() chatAvatarUrl: string | null = null;\n @state() chatThinkingLevel: string | null = null;\n @state() chatQueue: ChatQueueItem[] = [];\n @state() chatAttachments: ChatAttachment[] = [];\n @state() chatManualRefreshInFlight = false;\n // Sidebar state for tool output viewing\n @state() sidebarOpen = false;\n @state() sidebarContent: string | null = null;\n @state() sidebarError: string | null = null;\n @state() splitRatio = this.settings.splitRatio;\n\n @state() nodesLoading = false;\n @state() nodes: Array<Record<string, unknown>> = [];\n @state() devicesLoading = false;\n @state() devicesError: string | null = null;\n @state() devicesList: DevicePairingList | null = null;\n @state() execApprovalsLoading = false;\n @state() execApprovalsSaving = false;\n @state() execApprovalsDirty = false;\n @state() execApprovalsSnapshot: ExecApprovalsSnapshot | null = null;\n @state() execApprovalsForm: ExecApprovalsFile | null = null;\n @state() execApprovalsSelectedAgent: string | null = null;\n @state() execApprovalsTarget: \"gateway\" | \"node\" = \"gateway\";\n @state() execApprovalsTargetNodeId: string | null = null;\n @state() execApprovalQueue: ExecApprovalRequest[] = [];\n @state() execApprovalBusy = false;\n @state() execApprovalError: string | null = null;\n @state() pendingGatewayUrl: string | null = null;\n\n @state() configLoading = false;\n @state() configRaw = \"{\\n}\\n\";\n @state() configRawOriginal = \"\";\n @state() configValid: boolean | null = null;\n @state() configIssues: unknown[] = [];\n @state() configSaving = false;\n @state() configApplying = false;\n @state() updateRunning = false;\n @state() applySessionKey = this.settings.lastActiveSessionKey;\n @state() configSnapshot: ConfigSnapshot | null = null;\n @state() configSchema: unknown = null;\n @state() configSchemaVersion: string | null = null;\n @state() configSchemaLoading = false;\n @state() configUiHints: ConfigUiHints = {};\n @state() configForm: Record<string, unknown> | null = null;\n @state() configFormOriginal: Record<string, unknown> | null = null;\n @state() configFormDirty = false;\n @state() configFormMode: \"form\" | \"raw\" = \"form\";\n @state() configSearchQuery = \"\";\n @state() configActiveSection: string | null = null;\n @state() configActiveSubsection: string | null = null;\n\n @state() channelsLoading = false;\n @state() channelsSnapshot: ChannelsStatusSnapshot | null = null;\n @state() channelsError: string | null = null;\n @state() channelsLastSuccess: number | null = null;\n @state() whatsappLoginMessage: string | null = null;\n @state() whatsappLoginQrDataUrl: string | null = null;\n @state() whatsappLoginConnected: boolean | null = null;\n @state() whatsappBusy = false;\n @state() nostrProfileFormState: NostrProfileFormState | null = null;\n @state() nostrProfileAccountId: string | null = null;\n\n @state() presenceLoading = false;\n @state() presenceEntries: PresenceEntry[] = [];\n @state() presenceError: string | null = null;\n @state() presenceStatus: string | null = null;\n\n @state() agentsLoading = false;\n @state() agentsList: AgentsListResult | null = null;\n @state() agentsError: string | null = null;\n @state() agentsSelectedId: string | null = null;\n @state() toolsCatalogLoading = false;\n @state() toolsCatalogError: string | null = null;\n @state() toolsCatalogResult: ToolsCatalogResult | null = null;\n @state() agentsPanel: \"overview\" | \"files\" | \"tools\" | \"skills\" | \"channels\" | \"cron\" =\n \"overview\";\n @state() agentFilesLoading = false;\n @state() agentFilesError: string | null = null;\n @state() agentFilesList: AgentsFilesListResult | null = null;\n @state() agentFileContents: Record<string, string> = {};\n @state() agentFileDrafts: Record<string, string> = {};\n @state() agentFileActive: string | null = null;\n @state() agentFileSaving = false;\n @state() agentIdentityLoading = false;\n @state() agentIdentityError: string | null = null;\n @state() agentIdentityById: Record<string, AgentIdentityResult> = {};\n @state() agentSkillsLoading = false;\n @state() agentSkillsError: string | null = null;\n @state() agentSkillsReport: SkillStatusReport | null = null;\n @state() agentSkillsAgentId: string | null = null;\n\n @state() sessionsLoading = false;\n @state() sessionsResult: SessionsListResult | null = null;\n @state() sessionsError: string | null = null;\n @state() sessionsFilterActive = \"\";\n @state() sessionsFilterLimit = \"120\";\n @state() sessionsIncludeGlobal = true;\n @state() sessionsIncludeUnknown = false;\n @state() sessionRunsResult: SessionRunsResult | null = null;\n @state() sessionRunsError: string | null = null;\n sessionRunsFetchedAt = 0;\n sessionRunsLoading = false;\n @state() sessionsThresholdsResult: SessionsThresholdsResult | null = null;\n @state() sessionsThresholdsError: string | null = null;\n sessionsThresholdsLoading = false;\n @state() sessionRunsInterruptingKeys = new Set<string>();\n @state() recentlyCompletedRuns: { key: string; completedAt: number }[] = [];\n sessionRunsPrevKeys = new Set<string>();\n @state() recoverableRuns: import(\"./types.js\").DurableSessionRunRecord[] = [];\n @state() recoveryError: string | null = null;\n @state() decidingRunIds = new Set<string>();\n recoverableRunsLoading = false;\n @state() sessionsHideCron = true;\n\n @state() usageLoading = false;\n @state() usageResult: import(\"./types.js\").SessionsUsageResult | null = null;\n @state() usageCostSummary: import(\"./types.js\").CostUsageSummary | null = null;\n @state() usageError: string | null = null;\n @state() usageStartDate = (() => {\n const d = new Date();\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(d.getDate()).padStart(2, \"0\")}`;\n })();\n @state() usageEndDate = (() => {\n const d = new Date();\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(d.getDate()).padStart(2, \"0\")}`;\n })();\n @state() usageSelectedSessions: string[] = [];\n @state() usageSelectedDays: string[] = [];\n @state() usageSelectedHours: number[] = [];\n @state() usageChartMode: \"tokens\" | \"cost\" = \"tokens\";\n @state() usageDailyChartMode: \"total\" | \"by-type\" = \"by-type\";\n @state() usageTimeSeriesMode: \"cumulative\" | \"per-turn\" = \"per-turn\";\n @state() usageTimeSeriesBreakdownMode: \"total\" | \"by-type\" = \"by-type\";\n @state() usageTimeSeries: import(\"./types.js\").SessionUsageTimeSeries | null = null;\n @state() usageTimeSeriesLoading = false;\n @state() usageTimeSeriesCursorStart: number | null = null;\n @state() usageTimeSeriesCursorEnd: number | null = null;\n @state() usageSessionLogs: import(\"./views/usage.js\").SessionLogEntry[] | null = null;\n @state() usageSessionLogsLoading = false;\n @state() usageSessionLogsExpanded = false;\n // Applied query (used to filter the already-loaded sessions list client-side).\n @state() usageQuery = \"\";\n // Draft query text (updates immediately as the user types; applied via debounce or \"Search\").\n @state() usageQueryDraft = \"\";\n @state() usageSessionSort: \"tokens\" | \"cost\" | \"recent\" | \"messages\" | \"errors\" = \"recent\";\n @state() usageSessionSortDir: \"desc\" | \"asc\" = \"desc\";\n @state() usageRecentSessions: string[] = [];\n @state() usageTimeZone: \"local\" | \"utc\" = \"local\";\n @state() usageContextExpanded = false;\n @state() usageHeaderPinned = false;\n @state() usageSessionsTab: \"all\" | \"recent\" = \"all\";\n @state() usageVisibleColumns: string[] = [\n \"channel\",\n \"agent\",\n \"provider\",\n \"model\",\n \"messages\",\n \"tools\",\n \"errors\",\n \"duration\",\n ];\n @state() usageLogFilterRoles: import(\"./views/usage.js\").SessionLogRole[] = [];\n @state() usageLogFilterTools: string[] = [];\n @state() usageLogFilterHasTools = false;\n @state() usageLogFilterQuery = \"\";\n\n // Non-reactive (don’t trigger renders just for timer bookkeeping).\n usageQueryDebounceTimer: number | null = null;\n\n @state() cronLoading = false;\n @state() cronJobsLoadingMore = false;\n @state() cronJobs: CronJob[] = [];\n @state() cronJobsTotal = 0;\n @state() cronJobsHasMore = false;\n @state() cronJobsNextOffset: number | null = null;\n @state() cronJobsLimit = 50;\n @state() cronJobsQuery = \"\";\n @state() cronJobsEnabledFilter: import(\"./types.js\").CronJobsEnabledFilter = \"all\";\n @state() cronJobsScheduleKindFilter: import(\"./controllers/cron.js\").CronJobsScheduleKindFilter =\n \"all\";\n @state() cronJobsLastStatusFilter: import(\"./controllers/cron.js\").CronJobsLastStatusFilter =\n \"all\";\n @state() cronJobsSortBy: import(\"./types.js\").CronJobsSortBy = \"nextRunAtMs\";\n @state() cronJobsSortDir: import(\"./types.js\").CronSortDir = \"asc\";\n @state() cronStatus: CronStatus | null = null;\n @state() cronError: string | null = null;\n @state() cronForm: CronFormState = { ...DEFAULT_CRON_FORM };\n @state() cronFieldErrors: CronFieldErrors = {};\n @state() cronEditingJobId: string | null = null;\n @state() cronCreatingJob = false;\n @state() cronRunsJobId: string | null = null;\n @state() cronRunsLoadingMore = false;\n @state() cronRuns: CronRunLogEntry[] = [];\n @state() cronRunsTotal = 0;\n @state() cronRunsHasMore = false;\n @state() cronRunsNextOffset: number | null = null;\n @state() cronRunsLimit = 50;\n @state() cronRunsScope: import(\"./types.js\").CronRunScope = \"all\";\n @state() cronRunsStatuses: import(\"./types.js\").CronRunsStatusValue[] = [];\n @state() cronRunsDeliveryStatuses: import(\"./types.js\").CronDeliveryStatus[] = [];\n @state() cronRunsStatusFilter: import(\"./types.js\").CronRunsStatusFilter = \"all\";\n @state() cronRunsQuery = \"\";\n @state() cronRunsSortDir: import(\"./types.js\").CronSortDir = \"desc\";\n @state() cronModelSuggestions: string[] = [];\n @state() cronBusy = false;\n @state() cronLastRunSessionKey: string | null = null;\n @state() cronLastRunJobId: string | null = null;\n @state() cronRunningJobId: string | null = null;\n\n // Learning inbox state\n @state() learningLoading = false;\n @state() learningError: string | null = null;\n @state() overview: import(\"./controllers/learning.ts\").LearningOverview | null = null;\n @state() proposals: import(\"./controllers/learning.ts\").LearningProposalRow[] = [];\n @state() lessons: import(\"./controllers/learning.ts\").LearningLessonRow[] = [];\n @state() selectedProposal: import(\"./controllers/learning.ts\").LearningProposalDetail | null =\n null;\n @state() learningBusy = false;\n @state() learningSubView: \"proposals\" | \"lessons\" = \"proposals\";\n @state() learningPendingApplyId: string | null = null;\n\n // Dreams view state: every value is replaced from a durable read, never set optimistically.\n @state() dreams: DreamsViewState = createDefaultDreamsState();\n dreamsGeneration = 0;\n dreamsDirty = false;\n dreamsTrailingTimer: number | null = null;\n dreamsTrailingPending = false;\n dreamsBurstStartedAt: number | null = null;\n dreamsPollInterval: number | null = null;\n\n @state() updateAvailable: import(\"./types.js\").UpdateAvailable | null = null;\n\n @state() skillsLoading = false;\n @state() skillsReport: SkillStatusReport | null = null;\n @state() skillsError: string | null = null;\n @state() skillsFilter = \"\";\n @state() skillEdits: Record<string, string> = {};\n @state() skillsBusyKey: string | null = null;\n @state() skillMessages: Record<string, SkillMessage> = {};\n\n @state() debugLoading = false;\n @state() debugStatus: StatusSummary | null = null;\n @state() debugHealth: HealthSnapshot | null = null;\n @state() debugModels: unknown[] = [];\n @state() debugHeartbeat: unknown = null;\n @state() debugCallMethod = \"\";\n @state() debugCallParams = \"{}\";\n @state() debugCallResult: string | null = null;\n @state() debugCallError: string | null = null;\n\n @state() logsLoading = false;\n @state() logsError: string | null = null;\n @state() logsFile: string | null = null;\n @state() logsEntries: LogEntry[] = [];\n @state() logsFilterText = \"\";\n @state() logsLevelFilters: Record<LogLevel, boolean> = {\n ...DEFAULT_LOG_LEVEL_FILTERS,\n };\n @state() logsAutoFollow = true;\n @state() logsTruncated = false;\n @state() logsCursor: number | null = null;\n @state() logsLastFetchAt: number | null = null;\n @state() logsLimit = 500;\n @state() logsMaxBytes = 250_000;\n @state() logsAtBottom = true;\n @state() talkState: TalkState = createDefaultTalkState();\n\n client: GatewayBrowserClient | null = null;\n private readonly talkSessionClient: TalkSessionClient;\n private readonly talkController: TalkController;\n private chatScrollFrame: number | null = null;\n private chatScrollTimeout: number | null = null;\n private chatHasAutoScrolled = false;\n private chatUserNearBottom = true;\n @state() chatNewMessagesBelow = false;\n private nodesPollInterval: number | null = null;\n private logsPollInterval: number | null = null;\n private debugPollInterval: number | null = null;\n private sessionRunsPollInterval: number | null = null;\n private sessionRunsTickInterval: number | null = null;\n private logsScrollFrame: number | null = null;\n private toolStreamById = new Map<string, ToolStreamEntry>();\n private toolStreamOrder: string[] = [];\n refreshSessionsAfterChat = new Set<string>();\n basePath = \"\";\n private visibilityHandler = () =>\n handleVisibilityChangeInternal(\n this as unknown as Parameters<typeof handleVisibilityChangeInternal>[0],\n );\n private popStateHandler = () =>\n onPopStateInternal(this as unknown as Parameters<typeof onPopStateInternal>[0]);\n private themeMedia: MediaQueryList | null = null;\n private themeMediaHandler: ((event: MediaQueryListEvent) => void) | null = null;\n private topbarObserver: ResizeObserver | null = null;\n\n createRenderRoot() {\n return this;\n }\n\n connectedCallback() {\n super.connectedCallback();\n handleConnected(this as unknown as Parameters<typeof handleConnected>[0]);\n }\n\n protected firstUpdated() {\n handleFirstUpdated(this as unknown as Parameters<typeof handleFirstUpdated>[0]);\n }\n\n disconnectedCallback() {\n handleDisconnected(this as unknown as Parameters<typeof handleDisconnected>[0]);\n super.disconnectedCallback();\n }\n\n protected updated(changed: Map<PropertyKey, unknown>) {\n handleUpdated(this as unknown as Parameters<typeof handleUpdated>[0], changed);\n }\n\n connect() {\n connectGatewayInternal(this as unknown as Parameters<typeof connectGatewayInternal>[0]);\n }\n\n handleChatScroll(event: Event) {\n handleChatScrollInternal(\n this as unknown as Parameters<typeof handleChatScrollInternal>[0],\n event,\n );\n }\n\n handleLogsScroll(event: Event) {\n handleLogsScrollInternal(\n this as unknown as Parameters<typeof handleLogsScrollInternal>[0],\n event,\n );\n }\n\n exportLogs(lines: string[], label: string) {\n exportLogsInternal(lines, label);\n }\n\n resetToolStream() {\n resetToolStreamInternal(this as unknown as Parameters<typeof resetToolStreamInternal>[0]);\n }\n\n resetChatScroll() {\n resetChatScrollInternal(this as unknown as Parameters<typeof resetChatScrollInternal>[0]);\n }\n\n scrollToBottom(opts?: { smooth?: boolean }) {\n resetChatScrollInternal(this as unknown as Parameters<typeof resetChatScrollInternal>[0]);\n scheduleChatScrollInternal(\n this as unknown as Parameters<typeof scheduleChatScrollInternal>[0],\n true,\n Boolean(opts?.smooth),\n );\n }\n\n async loadAssistantIdentity() {\n await loadAssistantIdentityInternal(this);\n }\n\n applySettings(next: UiSettings) {\n applySettingsInternal(this as unknown as Parameters<typeof applySettingsInternal>[0], next);\n }\n\n setTab(next: Tab) {\n setTabInternal(this as unknown as Parameters<typeof setTabInternal>[0], next);\n }\n\n setTheme(next: ThemeMode, context?: Parameters<typeof setThemeInternal>[2]) {\n setThemeInternal(this as unknown as Parameters<typeof setThemeInternal>[0], next, context);\n }\n\n async loadOverview() {\n await loadOverviewInternal(this as unknown as Parameters<typeof loadOverviewInternal>[0]);\n }\n\n async loadCron() {\n await loadCronInternal(this as unknown as Parameters<typeof loadCronInternal>[0]);\n }\n\n async loadLearning(): Promise<void> {\n await Promise.all([\n loadLearningOverview(this as unknown as Parameters<typeof loadLearningOverview>[0]),\n loadProposals(this as unknown as Parameters<typeof loadProposals>[0]),\n loadLessons(this as unknown as Parameters<typeof loadLessons>[0]),\n ]);\n }\n\n async loadDreams(): Promise<void> {\n await loadDreamsInternal(this as unknown as Parameters<typeof loadDreamsInternal>[0]);\n }\n\n selectDreamsRun(taskRunId: string | null) {\n this.dreams = { ...this.dreams, selectedRunId: taskRunId };\n }\n\n async openLearningProposal(id: string): Promise<void> {\n await inspectProposal(this as unknown as Parameters<typeof inspectProposal>[0], id);\n }\n\n async decideLearningProposal(\n id: string,\n action: \"apply\" | \"reject\" | \"quarantine\",\n ): Promise<void> {\n await decideProposal(this as unknown as Parameters<typeof decideProposal>[0], id, action);\n }\n\n async handleTalkStart() {\n await this.talkController.start();\n }\n\n async handleTalkStop() {\n await this.talkController.stop();\n }\n\n async handleTalkRetry() {\n await this.talkController.retry();\n }\n\n async handleAbortChat() {\n await handleAbortChatInternal(this as unknown as Parameters<typeof handleAbortChatInternal>[0]);\n }\n\n removeQueuedMessage(id: string) {\n removeQueuedMessageInternal(\n this as unknown as Parameters<typeof removeQueuedMessageInternal>[0],\n id,\n );\n }\n\n async handleSendChat(\n messageOverride?: string,\n opts?: Parameters<typeof handleSendChatInternal>[2],\n ) {\n await handleSendChatInternal(\n this as unknown as Parameters<typeof handleSendChatInternal>[0],\n messageOverride,\n opts,\n );\n }\n\n async handleWhatsAppStart(force: boolean) {\n await handleWhatsAppStartInternal(this, force);\n }\n\n async handleWhatsAppWait() {\n await handleWhatsAppWaitInternal(this);\n }\n\n async handleWhatsAppLogout() {\n await handleWhatsAppLogoutInternal(this);\n }\n\n async handleChannelConfigSave() {\n await handleChannelConfigSaveInternal(this);\n }\n\n async handleChannelConfigReload() {\n await handleChannelConfigReloadInternal(this);\n }\n\n handleNostrProfileEdit(accountId: string, profile: NostrProfile | null) {\n handleNostrProfileEditInternal(this, accountId, profile);\n }\n\n handleNostrProfileCancel() {\n handleNostrProfileCancelInternal(this);\n }\n\n handleNostrProfileFieldChange(field: keyof NostrProfile, value: string) {\n handleNostrProfileFieldChangeInternal(this, field, value);\n }\n\n async handleNostrProfileSave() {\n await handleNostrProfileSaveInternal(this);\n }\n\n async handleNostrProfileImport() {\n await handleNostrProfileImportInternal(this);\n }\n\n handleNostrProfileToggleAdvanced() {\n handleNostrProfileToggleAdvancedInternal(this);\n }\n\n async handleExecApprovalDecision(decision: \"allow-once\" | \"allow-always\" | \"deny\") {\n const active = this.execApprovalQueue[0];\n if (!active || !this.client || this.execApprovalBusy) {\n return;\n }\n this.execApprovalBusy = true;\n this.execApprovalError = null;\n try {\n await this.client.request(\"exec.approval.resolve\", {\n id: active.id,\n decision,\n });\n this.execApprovalQueue = this.execApprovalQueue.filter((entry) => entry.id !== active.id);\n } catch (err) {\n this.execApprovalError = `Exec approval failed: ${String(err)}`;\n } finally {\n this.execApprovalBusy = false;\n }\n }\n\n handleGatewayUrlConfirm() {\n const nextGatewayUrl = this.pendingGatewayUrl;\n if (!nextGatewayUrl) {\n return;\n }\n this.pendingGatewayUrl = null;\n applySettingsInternal(this as unknown as Parameters<typeof applySettingsInternal>[0], {\n ...this.settings,\n gatewayUrl: nextGatewayUrl,\n });\n this.connect();\n }\n\n handleGatewayUrlCancel() {\n this.pendingGatewayUrl = null;\n }\n\n // Sidebar handlers for tool output viewing\n handleOpenSidebar(content: string) {\n if (this.sidebarCloseTimer != null) {\n window.clearTimeout(this.sidebarCloseTimer);\n this.sidebarCloseTimer = null;\n }\n this.sidebarContent = content;\n this.sidebarError = null;\n this.sidebarOpen = true;\n }\n\n handleCloseSidebar() {\n this.sidebarOpen = false;\n // Clear content after transition\n if (this.sidebarCloseTimer != null) {\n window.clearTimeout(this.sidebarCloseTimer);\n }\n this.sidebarCloseTimer = window.setTimeout(() => {\n if (this.sidebarOpen) {\n return;\n }\n this.sidebarContent = null;\n this.sidebarError = null;\n this.sidebarCloseTimer = null;\n }, 200);\n }\n\n handleSplitRatioChange(ratio: number) {\n const newRatio = Math.max(0.4, Math.min(0.7, ratio));\n this.splitRatio = newRatio;\n this.applySettings({ ...this.settings, splitRatio: newRatio });\n }\n\n render() {\n return renderApp(this as unknown as AppViewState);\n }\n}\n"],"file":"index-CambJeDO.js"}
|