@rubytech/create-sitedesk-code 0.1.535 → 0.1.537
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/package.json +1 -1
- package/payload/platform/plugins/admin/hooks/__tests__/mailbox-inject.test.sh +11 -5
- package/payload/platform/plugins/admin/hooks/mailbox-inject.sh +12 -7
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +70 -9
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +63 -1
- package/payload/platform/plugins/docs/references/calendar-booking.md +6 -7
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js +10 -7
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/whatsapp/skills/manage-whatsapp-config/SKILL.md +6 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +150 -10
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +62 -2
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +24 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +62 -24
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts +8 -2
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js +32 -27
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-allowlist.d.ts +19 -0
- package/payload/platform/services/claude-session-manager/dist/public-allowlist.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/public-allowlist.js +23 -0
- package/payload/platform/services/claude-session-manager/dist/public-allowlist.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/public-spawn-session.d.ts +23 -0
- package/payload/platform/services/claude-session-manager/dist/public-spawn-session.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/public-spawn-session.js +34 -0
- package/payload/platform/services/claude-session-manager/dist/public-spawn-session.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/public-surface-audit.d.ts +44 -0
- package/payload/platform/services/claude-session-manager/dist/public-surface-audit.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/public-surface-audit.js +110 -0
- package/payload/platform/services/claude-session-manager/dist/public-surface-audit.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/rc-public-lockdown.d.ts +36 -0
- package/payload/platform/services/claude-session-manager/dist/rc-public-lockdown.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/rc-public-lockdown.js +49 -0
- package/payload/platform/services/claude-session-manager/dist/rc-public-lockdown.js.map +1 -0
- package/payload/server/{chunk-4QCYFTAI.js → chunk-44Z4ZFYS.js} +2 -0
- package/payload/server/{chunk-DLG7XSLA.js → chunk-IALJPXIO.js} +70 -3
- package/payload/server/{manager-ZNHQQCED.js → manager-AJSPM6X2.js} +1 -1
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/activity.html +5 -5
- package/payload/server/public/agents.html +4 -4
- package/payload/server/public/assets/AdminLoginScreens-CYFf2awh.js +1 -0
- package/payload/server/public/assets/AdminLoginScreens-CYFf2awh.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-CYFf2awh.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-7l3ubYFZ.js +2 -0
- package/payload/server/public/assets/AdminShell-7l3ubYFZ.js.br +0 -0
- package/payload/server/public/assets/AdminShell-7l3ubYFZ.js.gz +0 -0
- package/payload/server/public/assets/{activity-DKeRUjQ9.js → activity-BH65sm9Q.js} +1 -1
- package/payload/server/public/assets/activity-BH65sm9Q.js.br +0 -0
- package/payload/server/public/assets/activity-BH65sm9Q.js.gz +0 -0
- package/payload/server/public/assets/admin-CQtEjRGU.js +1 -0
- package/payload/server/public/assets/admin-CQtEjRGU.js.br +0 -0
- package/payload/server/public/assets/admin-CQtEjRGU.js.gz +0 -0
- package/payload/server/public/assets/{agents-CrR_OMe8.js → agents-CjhOWwl5.js} +1 -1
- package/payload/server/public/assets/agents-CjhOWwl5.js.br +0 -0
- package/payload/server/public/assets/agents-CjhOWwl5.js.gz +0 -0
- package/payload/server/public/assets/{arc-CHoXZR2f.js → arc-DaudCnXg.js} +1 -1
- package/payload/server/public/assets/arc-DaudCnXg.js.br +0 -0
- package/payload/server/public/assets/arc-DaudCnXg.js.gz +0 -0
- package/payload/server/public/assets/architecture-YZFGNWBL-DPFsm5jD.js +1 -0
- package/payload/server/public/assets/architecture-YZFGNWBL-DPFsm5jD.js.br +0 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-B8SCI0AR.js → architectureDiagram-Q4EWVU46-Dj9L_JR0.js} +1 -1
- package/payload/server/public/assets/architectureDiagram-Q4EWVU46-Dj9L_JR0.js.br +0 -0
- package/payload/server/public/assets/architectureDiagram-Q4EWVU46-Dj9L_JR0.js.gz +0 -0
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CsJmhz5D.js → blockDiagram-DXYQGD6D-BTXKYwrR.js} +1 -1
- package/payload/server/public/assets/blockDiagram-DXYQGD6D-BTXKYwrR.js.br +0 -0
- package/payload/server/public/assets/blockDiagram-DXYQGD6D-BTXKYwrR.js.gz +0 -0
- package/payload/server/public/assets/browser-DGXpfL99.js +1 -0
- package/payload/server/public/assets/browser-DGXpfL99.js.br +0 -0
- package/payload/server/public/assets/browser-DGXpfL99.js.gz +0 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CzaSNqcs.js → c4Diagram-AHTNJAMY-BN7XeOWV.js} +1 -1
- package/payload/server/public/assets/c4Diagram-AHTNJAMY-BN7XeOWV.js.br +0 -0
- package/payload/server/public/assets/c4Diagram-AHTNJAMY-BN7XeOWV.js.gz +0 -0
- package/payload/server/public/assets/calendar-Cu4yjEuX.js +1 -0
- package/payload/server/public/assets/calendar-Cu4yjEuX.js.br +0 -0
- package/payload/server/public/assets/calendar-Cu4yjEuX.js.gz +0 -0
- package/payload/server/public/assets/channel-D08XWP9e.js +1 -0
- package/payload/server/public/assets/chat-0na4XVZC.js +1 -0
- package/payload/server/public/assets/chat-0na4XVZC.js.br +0 -0
- package/payload/server/public/assets/chat-0na4XVZC.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-DHzJobWp.js +1 -0
- package/payload/server/public/assets/chevron-left-DHzJobWp.js.br +0 -0
- package/payload/server/public/assets/chevron-right-yg4DMfLT.js +1 -0
- package/payload/server/public/assets/chevron-right-yg4DMfLT.js.br +0 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-DAN3KCZc.js → chunk-2KRD3SAO-BwEVlnxo.js} +1 -1
- package/payload/server/public/assets/chunk-2KRD3SAO-BwEVlnxo.js.br +0 -0
- package/payload/server/public/assets/chunk-2KRD3SAO-BwEVlnxo.js.gz +0 -0
- package/payload/server/public/assets/{chunk-336JU56O-Dm-0_lIT.js → chunk-336JU56O-DR5EUh9D.js} +2 -2
- package/payload/server/public/assets/chunk-336JU56O-DR5EUh9D.js.br +0 -0
- package/payload/server/public/assets/chunk-336JU56O-DR5EUh9D.js.gz +0 -0
- package/payload/server/public/assets/chunk-426QAEUC-YPE0DZOq.js +1 -0
- package/payload/server/public/assets/chunk-426QAEUC-YPE0DZOq.js.br +0 -0
- package/payload/server/public/assets/chunk-426QAEUC-YPE0DZOq.js.gz +0 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-C2l9bAlo.js → chunk-4BX2VUAB-C5p3xTC6.js} +1 -1
- package/payload/server/public/assets/chunk-4BX2VUAB-C5p3xTC6.js.br +0 -0
- package/payload/server/public/assets/chunk-4BX2VUAB-C5p3xTC6.js.gz +0 -0
- package/payload/server/public/assets/{chunk-4TB4RGXK-BMXDzU09.js → chunk-4TB4RGXK-CqrBvvGI.js} +1 -1
- package/payload/server/public/assets/chunk-4TB4RGXK-CqrBvvGI.js.br +0 -0
- package/payload/server/public/assets/chunk-4TB4RGXK-CqrBvvGI.js.gz +0 -0
- package/payload/server/public/assets/{chunk-55IACEB6-CbMYAZon.js → chunk-55IACEB6-DDU_m1ra.js} +1 -1
- package/payload/server/public/assets/chunk-55IACEB6-DDU_m1ra.js.br +0 -0
- package/payload/server/public/assets/chunk-55IACEB6-DDU_m1ra.js.gz +0 -0
- package/payload/server/public/assets/{chunk-5FUZZQ4R-DjdsuxLA.js → chunk-5FUZZQ4R-B21kX6ld.js} +1 -1
- package/payload/server/public/assets/chunk-5FUZZQ4R-B21kX6ld.js.br +0 -0
- package/payload/server/public/assets/chunk-5FUZZQ4R-B21kX6ld.js.gz +0 -0
- package/payload/server/public/assets/{chunk-5PVQY5BW-CGSBzsF6.js → chunk-5PVQY5BW-CYusrVbq.js} +1 -1
- package/payload/server/public/assets/chunk-5PVQY5BW-CYusrVbq.js.br +0 -0
- package/payload/server/public/assets/chunk-5PVQY5BW-CYusrVbq.js.gz +0 -0
- package/payload/server/public/assets/{chunk-67CJDMHE-ClOLWser.js → chunk-67CJDMHE-9W0Qv0jm.js} +1 -1
- package/payload/server/public/assets/chunk-67CJDMHE-9W0Qv0jm.js.br +0 -0
- package/payload/server/public/assets/chunk-67CJDMHE-9W0Qv0jm.js.gz +0 -0
- package/payload/server/public/assets/{chunk-7N4EOEYR-BzC1dzY0.js → chunk-7N4EOEYR-B3gqydR3.js} +1 -1
- package/payload/server/public/assets/chunk-7N4EOEYR-B3gqydR3.js.br +0 -0
- package/payload/server/public/assets/chunk-7N4EOEYR-B3gqydR3.js.gz +0 -0
- package/payload/server/public/assets/{chunk-AA7GKIK3-R_pjI1kw.js → chunk-AA7GKIK3-DW8a-2NK.js} +1 -1
- package/payload/server/public/assets/chunk-AA7GKIK3-DW8a-2NK.js.br +4 -0
- package/payload/server/public/assets/chunk-AA7GKIK3-DW8a-2NK.js.gz +0 -0
- package/payload/server/public/assets/{chunk-BSJP7CBP-D2KRAq3U.js → chunk-BSJP7CBP-DqXIO_5R.js} +1 -1
- package/payload/server/public/assets/chunk-BSJP7CBP-DqXIO_5R.js.br +0 -0
- package/payload/server/public/assets/chunk-BSJP7CBP-DqXIO_5R.js.gz +0 -0
- package/payload/server/public/assets/{chunk-CIAEETIT-BPGWtrKR.js → chunk-CIAEETIT-BMJfgj2u.js} +1 -1
- package/payload/server/public/assets/chunk-CIAEETIT-BMJfgj2u.js.br +0 -0
- package/payload/server/public/assets/chunk-CIAEETIT-BMJfgj2u.js.gz +0 -0
- package/payload/server/public/assets/{chunk-EDXVE4YY-tqt7wueu.js → chunk-EDXVE4YY-CyjTyMkv.js} +1 -1
- package/payload/server/public/assets/chunk-EDXVE4YY-CyjTyMkv.js.br +0 -0
- package/payload/server/public/assets/chunk-EDXVE4YY-CyjTyMkv.js.gz +0 -0
- package/payload/server/public/assets/{chunk-ENJZ2VHE-DJG3cA6E.js → chunk-ENJZ2VHE-B-k8uOTF.js} +1 -1
- package/payload/server/public/assets/chunk-ENJZ2VHE-B-k8uOTF.js.br +0 -0
- package/payload/server/public/assets/chunk-ENJZ2VHE-B-k8uOTF.js.gz +0 -0
- package/payload/server/public/assets/{chunk-FMBD7UC4-DO1xgCDf.js → chunk-FMBD7UC4-CdPjwbtf.js} +1 -1
- package/payload/server/public/assets/chunk-FMBD7UC4-CdPjwbtf.js.br +0 -0
- package/payload/server/public/assets/chunk-FMBD7UC4-CdPjwbtf.js.gz +0 -0
- package/payload/server/public/assets/{chunk-FOC6F5B3-BhWAbCUG.js → chunk-FOC6F5B3-Dl6l1KAh.js} +1 -1
- package/payload/server/public/assets/chunk-FOC6F5B3-Dl6l1KAh.js.br +0 -0
- package/payload/server/public/assets/chunk-FOC6F5B3-Dl6l1KAh.js.gz +0 -0
- package/payload/server/public/assets/{chunk-ICPOFSXX-BhUzt35c.js → chunk-ICPOFSXX-CKQWnR1l.js} +2 -2
- package/payload/server/public/assets/chunk-ICPOFSXX-CKQWnR1l.js.br +0 -0
- package/payload/server/public/assets/chunk-ICPOFSXX-CKQWnR1l.js.gz +0 -0
- package/payload/server/public/assets/{chunk-K5T4RW27-Boj-qHrX.js → chunk-K5T4RW27--g29_wjW.js} +1 -1
- package/payload/server/public/assets/chunk-K5T4RW27--g29_wjW.js.br +0 -0
- package/payload/server/public/assets/chunk-K5T4RW27--g29_wjW.js.gz +0 -0
- package/payload/server/public/assets/{chunk-KGLVRYIC-3cBRDk1b.js → chunk-KGLVRYIC-CI77ENeO.js} +1 -1
- package/payload/server/public/assets/chunk-KGLVRYIC-CI77ENeO.js.br +3 -0
- package/payload/server/public/assets/chunk-KGLVRYIC-CI77ENeO.js.gz +0 -0
- package/payload/server/public/assets/{chunk-LIHQZDEY-CgkLKaII.js → chunk-LIHQZDEY-CE-XByg6.js} +1 -1
- package/payload/server/public/assets/chunk-LIHQZDEY-CE-XByg6.js.br +0 -0
- package/payload/server/public/assets/chunk-LIHQZDEY-CE-XByg6.js.gz +0 -0
- package/payload/server/public/assets/{chunk-ORNJ4GCN-Dl449r_k.js → chunk-ORNJ4GCN-DkjJQQSm.js} +1 -1
- package/payload/server/public/assets/chunk-ORNJ4GCN-DkjJQQSm.js.br +0 -0
- package/payload/server/public/assets/chunk-ORNJ4GCN-DkjJQQSm.js.gz +0 -0
- package/payload/server/public/assets/{chunk-OYMX7WX6-Dzkj67n6.js → chunk-OYMX7WX6-Dis40FU5.js} +1 -1
- package/payload/server/public/assets/chunk-OYMX7WX6-Dis40FU5.js.br +0 -0
- package/payload/server/public/assets/chunk-OYMX7WX6-Dis40FU5.js.gz +0 -0
- package/payload/server/public/assets/chunk-QZHKN3VN-DnqqL1de.js +1 -0
- package/payload/server/public/assets/chunk-QZHKN3VN-DnqqL1de.js.br +0 -0
- package/payload/server/public/assets/chunk-QZHKN3VN-DnqqL1de.js.gz +0 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-Dyz9Kbir.js → chunk-U2HBQHQK-DT3NLMic.js} +1 -1
- package/payload/server/public/assets/chunk-U2HBQHQK-DT3NLMic.js.br +0 -0
- package/payload/server/public/assets/chunk-U2HBQHQK-DT3NLMic.js.gz +0 -0
- package/payload/server/public/assets/{chunk-X2U36JSP-ag0VVCw6.js → chunk-X2U36JSP-Dxaab1tD.js} +1 -1
- package/payload/server/public/assets/chunk-X2U36JSP-Dxaab1tD.js.br +0 -0
- package/payload/server/public/assets/chunk-X2U36JSP-Dxaab1tD.js.gz +0 -0
- package/payload/server/public/assets/{chunk-XPW4576I-B-vhDYPE.js → chunk-XPW4576I-DtqJwn2x.js} +1 -1
- package/payload/server/public/assets/chunk-XPW4576I-DtqJwn2x.js.br +0 -0
- package/payload/server/public/assets/chunk-XPW4576I-DtqJwn2x.js.gz +0 -0
- package/payload/server/public/assets/{chunk-YZCP3GAM-C4COviPb.js → chunk-YZCP3GAM-CEEcRrOH.js} +1 -1
- package/payload/server/public/assets/chunk-YZCP3GAM-CEEcRrOH.js.br +0 -0
- package/payload/server/public/assets/chunk-YZCP3GAM-CEEcRrOH.js.gz +0 -0
- package/payload/server/public/assets/{chunk-ZZ45TVLE-8dGsCp5b.js → chunk-ZZ45TVLE-CVhqjM4L.js} +1 -1
- package/payload/server/public/assets/chunk-ZZ45TVLE-CVhqjM4L.js.br +0 -0
- package/payload/server/public/assets/chunk-ZZ45TVLE-CVhqjM4L.js.gz +0 -0
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BPY9jtfT.js +1 -0
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BPY9jtfT.js.br +0 -0
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BPY9jtfT.js.gz +0 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CLgDbwDp.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CLgDbwDp.js.br +0 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CLgDbwDp.js.gz +0 -0
- package/payload/server/public/assets/clock-BIDzihvp.js +1 -0
- package/payload/server/public/assets/clock-BIDzihvp.js.br +0 -0
- package/payload/server/public/assets/clock-BIDzihvp.js.gz +0 -0
- package/payload/server/public/assets/clone-B6yMH1PX.js +1 -0
- package/payload/server/public/assets/clone-B6yMH1PX.js.br +0 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-qM4Q4TuE.js → cose-bilkent-S5V4N54A-kEHVkDNn.js} +1 -1
- package/payload/server/public/assets/cose-bilkent-S5V4N54A-kEHVkDNn.js.br +0 -0
- package/payload/server/public/assets/cose-bilkent-S5V4N54A-kEHVkDNn.js.gz +0 -0
- package/payload/server/public/assets/{dagre-DRvHdusQ.js → dagre-BgQxtxH1.js} +1 -1
- package/payload/server/public/assets/dagre-BgQxtxH1.js.br +0 -0
- package/payload/server/public/assets/dagre-BgQxtxH1.js.gz +0 -0
- package/payload/server/public/assets/{dagre-KV5264BT-CGqSVVTn.js → dagre-KV5264BT-CgxwoTcv.js} +1 -1
- package/payload/server/public/assets/dagre-KV5264BT-CgxwoTcv.js.br +0 -0
- package/payload/server/public/assets/dagre-KV5264BT-CgxwoTcv.js.gz +0 -0
- package/payload/server/public/assets/data-Ql9qG3YO.js +1 -0
- package/payload/server/public/assets/data-Ql9qG3YO.js.br +0 -0
- package/payload/server/public/assets/data-Ql9qG3YO.js.gz +0 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-DfFgeApz.js → diagram-5BDNPKRD-MEZ1cQGO.js} +1 -1
- package/payload/server/public/assets/diagram-5BDNPKRD-MEZ1cQGO.js.br +0 -0
- package/payload/server/public/assets/diagram-5BDNPKRD-MEZ1cQGO.js.gz +0 -0
- package/payload/server/public/assets/{diagram-G4DWMVQ6-DPXc3Q8e.js → diagram-G4DWMVQ6-DbZg9hWP.js} +1 -1
- package/payload/server/public/assets/diagram-G4DWMVQ6-DbZg9hWP.js.br +0 -0
- package/payload/server/public/assets/diagram-G4DWMVQ6-DbZg9hWP.js.gz +0 -0
- package/payload/server/public/assets/{diagram-MMDJMWI5-V8RCddvy.js → diagram-MMDJMWI5-Bb1y8DFy.js} +1 -1
- package/payload/server/public/assets/diagram-MMDJMWI5-Bb1y8DFy.js.br +0 -0
- package/payload/server/public/assets/diagram-MMDJMWI5-Bb1y8DFy.js.gz +0 -0
- package/payload/server/public/assets/{diagram-TYMM5635-CrvfIf-m.js → diagram-TYMM5635-tbStCw5U.js} +1 -1
- package/payload/server/public/assets/diagram-TYMM5635-tbStCw5U.js.br +0 -0
- package/payload/server/public/assets/diagram-TYMM5635-tbStCw5U.js.gz +0 -0
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DClMgmBB.js → erDiagram-SMLLAGMA-ClEFo_Bw.js} +1 -1
- package/payload/server/public/assets/erDiagram-SMLLAGMA-ClEFo_Bw.js.br +0 -0
- package/payload/server/public/assets/erDiagram-SMLLAGMA-ClEFo_Bw.js.gz +0 -0
- package/payload/server/public/assets/file-download-DbNIjWiK.js +1 -0
- package/payload/server/public/assets/file-download-DbNIjWiK.js.br +0 -0
- package/payload/server/public/assets/file-download-DbNIjWiK.js.gz +0 -0
- package/payload/server/public/assets/{file-text-5osg-EVb.js → file-text-CbQoZfJD.js} +1 -1
- package/payload/server/public/assets/file-text-CbQoZfJD.js.br +0 -0
- package/payload/server/public/assets/file-text-CbQoZfJD.js.gz +0 -0
- package/payload/server/public/assets/{flatten-UdUTbm8v.js → flatten-Bu-b1uTY.js} +1 -1
- package/payload/server/public/assets/flatten-Bu-b1uTY.js.br +0 -0
- package/payload/server/public/assets/flatten-Bu-b1uTY.js.gz +0 -0
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-D29Ou09P.js → flowDiagram-DWJPFMVM-9yr262Ji.js} +1 -1
- package/payload/server/public/assets/flowDiagram-DWJPFMVM-9yr262Ji.js.br +0 -0
- package/payload/server/public/assets/flowDiagram-DWJPFMVM-9yr262Ji.js.gz +0 -0
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-CoAK7W_V.js → ganttDiagram-T4ZO3ILL-ZCSA0DtG.js} +1 -1
- package/payload/server/public/assets/ganttDiagram-T4ZO3ILL-ZCSA0DtG.js.br +0 -0
- package/payload/server/public/assets/ganttDiagram-T4ZO3ILL-ZCSA0DtG.js.gz +0 -0
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-B0OUwOUx.js +1 -0
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-B0OUwOUx.js.br +0 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-DMEc_1aX.js → gitGraphDiagram-UUTBAWPF-0KvpzpaU.js} +1 -1
- package/payload/server/public/assets/gitGraphDiagram-UUTBAWPF-0KvpzpaU.js.br +0 -0
- package/payload/server/public/assets/gitGraphDiagram-UUTBAWPF-0KvpzpaU.js.gz +0 -0
- package/payload/server/public/assets/{graph-CAUo1OTY.js → graph-7414Kjn9.js} +3 -3
- package/payload/server/public/assets/graph-7414Kjn9.js.br +0 -0
- package/payload/server/public/assets/graph-7414Kjn9.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-TJ-3ljQo.js → graph-labels-D695CsC9.js} +1 -1
- package/payload/server/public/assets/graph-labels-D695CsC9.js.br +0 -0
- package/payload/server/public/assets/graph-labels-D695CsC9.js.gz +0 -0
- package/payload/server/public/assets/{graphlib-ihSLgqUG.js → graphlib-B3SsCJOd.js} +1 -1
- package/payload/server/public/assets/graphlib-B3SsCJOd.js.br +0 -0
- package/payload/server/public/assets/graphlib-B3SsCJOd.js.gz +0 -0
- package/payload/server/public/assets/info-OMHHGYJF-C_8TwPDe.js +1 -0
- package/payload/server/public/assets/info-OMHHGYJF-C_8TwPDe.js.br +0 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-B607bZBJ.js +2 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-B607bZBJ.js.br +0 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-B607bZBJ.js.gz +0 -0
- package/payload/server/public/assets/{isEmpty-DY_Xp9Na.js → isEmpty-CjH0UASp.js} +1 -1
- package/payload/server/public/assets/isEmpty-CjH0UASp.js.br +0 -0
- package/payload/server/public/assets/isEmpty-CjH0UASp.js.gz +0 -0
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-w8fVIbxy.js → ishikawaDiagram-UXIWVN3A-DsDoNemz.js} +1 -1
- package/payload/server/public/assets/ishikawaDiagram-UXIWVN3A-DsDoNemz.js.br +0 -0
- package/payload/server/public/assets/ishikawaDiagram-UXIWVN3A-DsDoNemz.js.gz +0 -0
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-BRTPKDT5.js → journeyDiagram-VCZTEJTY-xyayGhw3.js} +1 -1
- package/payload/server/public/assets/journeyDiagram-VCZTEJTY-xyayGhw3.js.br +0 -0
- package/payload/server/public/assets/journeyDiagram-VCZTEJTY-xyayGhw3.js.gz +0 -0
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Ls3VaFZ_.js → kanban-definition-6JOO6SKY-DuV3Go_1.js} +1 -1
- package/payload/server/public/assets/kanban-definition-6JOO6SKY-DuV3Go_1.js.br +0 -0
- package/payload/server/public/assets/kanban-definition-6JOO6SKY-DuV3Go_1.js.gz +0 -0
- package/payload/server/public/assets/{line-BwhAIh8u.js → line-Cpb8GRkf.js} +1 -1
- package/payload/server/public/assets/line-Cpb8GRkf.js.br +0 -0
- package/payload/server/public/assets/line-Cpb8GRkf.js.gz +0 -0
- package/payload/server/public/assets/{linear-USiZPFN4.js → linear-l39GooQ5.js} +1 -1
- package/payload/server/public/assets/linear-l39GooQ5.js.br +0 -0
- package/payload/server/public/assets/linear-l39GooQ5.js.gz +0 -0
- package/payload/server/public/assets/{maximize-2-S9W3q1O4.js → maximize-2-CD0gTjW_.js} +1 -1
- package/payload/server/public/assets/maximize-2-CD0gTjW_.js.br +0 -0
- package/payload/server/public/assets/maximize-2-CD0gTjW_.js.gz +0 -0
- package/payload/server/public/assets/{mermaid-parser.core-Bq--iC2w.js → mermaid-parser.core-9hkxt3j1.js} +2 -2
- package/payload/server/public/assets/mermaid-parser.core-9hkxt3j1.js.br +0 -0
- package/payload/server/public/assets/mermaid-parser.core-9hkxt3j1.js.gz +0 -0
- package/payload/server/public/assets/{mermaid.core-oYX-FxVa.js → mermaid.core-iR6TQesD.js} +3 -3
- package/payload/server/public/assets/mermaid.core-iR6TQesD.js.br +0 -0
- package/payload/server/public/assets/mermaid.core-iR6TQesD.js.gz +0 -0
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-ByZjL4Bs.js → mindmap-definition-QFDTVHPH-LCKhTYzs.js} +1 -1
- package/payload/server/public/assets/mindmap-definition-QFDTVHPH-LCKhTYzs.js.br +0 -0
- package/payload/server/public/assets/mindmap-definition-QFDTVHPH-LCKhTYzs.js.gz +0 -0
- package/payload/server/public/assets/operator-CLw4PZs5.js +1 -0
- package/payload/server/public/assets/operator-CLw4PZs5.js.br +0 -0
- package/payload/server/public/assets/operator-CLw4PZs5.js.gz +0 -0
- package/payload/server/public/assets/{ordinal-gnpqfIHn.js → ordinal-D6D6WcTC.js} +1 -1
- package/payload/server/public/assets/ordinal-D6D6WcTC.js.br +0 -0
- package/payload/server/public/assets/ordinal-D6D6WcTC.js.gz +0 -0
- package/payload/server/public/assets/packet-4T2RLAQJ-CCQdbIqO.js +1 -0
- package/payload/server/public/assets/packet-4T2RLAQJ-CCQdbIqO.js.br +0 -0
- package/payload/server/public/assets/{page-BUFW-PWF.js → page-BNRFmFc-.js} +4 -4
- package/payload/server/public/assets/page-BNRFmFc-.js.br +0 -0
- package/payload/server/public/assets/page-BNRFmFc-.js.gz +0 -0
- package/payload/server/public/assets/page-BRr295G2.js +1 -0
- package/payload/server/public/assets/page-BRr295G2.js.br +0 -0
- package/payload/server/public/assets/page-BRr295G2.js.gz +0 -0
- package/payload/server/public/assets/{pdf-render-gEryZmeC.js → pdf-render-DanMu_cf.js} +1 -1
- package/payload/server/public/assets/pdf-render-DanMu_cf.js.br +0 -0
- package/payload/server/public/assets/pdf-render-DanMu_cf.js.gz +0 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-Bdw3Iqs7.js +1 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-Bdw3Iqs7.js.br +0 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-BGFms5bU.js → pieDiagram-DEJITSTG-Oo7wgo0C.js} +1 -1
- package/payload/server/public/assets/pieDiagram-DEJITSTG-Oo7wgo0C.js.br +0 -0
- package/payload/server/public/assets/pieDiagram-DEJITSTG-Oo7wgo0C.js.gz +0 -0
- package/payload/server/public/assets/play-CbRU6q0T.js +1 -0
- package/payload/server/public/assets/play-CbRU6q0T.js.br +0 -0
- package/payload/server/public/assets/play-CbRU6q0T.js.gz +0 -0
- package/payload/server/public/assets/{public-Cx2ddU9a.js → public-CqbKJ-Q3.js} +1 -1
- package/payload/server/public/assets/public-CqbKJ-Q3.js.br +0 -0
- package/payload/server/public/assets/public-CqbKJ-Q3.js.gz +0 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-_ymoz8bQ.js → quadrantDiagram-34T5L4WZ-B2hs2ord.js} +1 -1
- package/payload/server/public/assets/quadrantDiagram-34T5L4WZ-B2hs2ord.js.br +0 -0
- package/payload/server/public/assets/quadrantDiagram-34T5L4WZ-B2hs2ord.js.gz +0 -0
- package/payload/server/public/assets/radar-PYXPWWZC-D3FUdA3r.js +1 -0
- package/payload/server/public/assets/radar-PYXPWWZC-D3FUdA3r.js.br +0 -0
- package/payload/server/public/assets/{reduce-BvezuHIe.js → reduce-BtXXK8Ma.js} +1 -1
- package/payload/server/public/assets/reduce-BtXXK8Ma.js.br +0 -0
- package/payload/server/public/assets/reduce-BtXXK8Ma.js.gz +0 -0
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-lrOmOxIA.js → requirementDiagram-MS252O5E-B8UkCUzW.js} +1 -1
- package/payload/server/public/assets/requirementDiagram-MS252O5E-B8UkCUzW.js.br +0 -0
- package/payload/server/public/assets/requirementDiagram-MS252O5E-B8UkCUzW.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-C2qSSBFA.js → rotate-ccw-CjliWBou.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-CjliWBou.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-CjliWBou.js.gz +0 -0
- package/payload/server/public/assets/routines-yJuRuBfn.js +2 -0
- package/payload/server/public/assets/routines-yJuRuBfn.js.br +0 -0
- package/payload/server/public/assets/routines-yJuRuBfn.js.gz +0 -0
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-CdUQThXU.js → sankeyDiagram-XADWPNL6-Cojqqz7t.js} +1 -1
- package/payload/server/public/assets/sankeyDiagram-XADWPNL6-Cojqqz7t.js.br +0 -0
- package/payload/server/public/assets/sankeyDiagram-XADWPNL6-Cojqqz7t.js.gz +0 -0
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-DqnEEldq.js → sequenceDiagram-FGHM5R23-C7ODsPjE.js} +1 -1
- package/payload/server/public/assets/sequenceDiagram-FGHM5R23-C7ODsPjE.js.br +0 -0
- package/payload/server/public/assets/sequenceDiagram-FGHM5R23-C7ODsPjE.js.gz +0 -0
- package/payload/server/public/assets/{skills-CmsYXVd3.js → skills-ipK9BJFb.js} +1 -1
- package/payload/server/public/assets/skills-ipK9BJFb.js.br +0 -0
- package/payload/server/public/assets/skills-ipK9BJFb.js.gz +0 -0
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-KEdtxqdq.js → stateDiagram-FHFEXIEX-BC8a_P9c.js} +1 -1
- package/payload/server/public/assets/stateDiagram-FHFEXIEX-BC8a_P9c.js.br +0 -0
- package/payload/server/public/assets/stateDiagram-FHFEXIEX-BC8a_P9c.js.gz +0 -0
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-C7KvMtT5.js +1 -0
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-C7KvMtT5.js.br +0 -0
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-C7KvMtT5.js.gz +0 -0
- package/payload/server/public/assets/tasks-CGcJHQ3X.js +3 -0
- package/payload/server/public/assets/tasks-CGcJHQ3X.js.br +0 -0
- package/payload/server/public/assets/tasks-CGcJHQ3X.js.gz +0 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-BRXdCMau.js → timeline-definition-GMOUNBTQ-BMxUC3ri.js} +1 -1
- package/payload/server/public/assets/timeline-definition-GMOUNBTQ-BMxUC3ri.js.br +0 -0
- package/payload/server/public/assets/timeline-definition-GMOUNBTQ-BMxUC3ri.js.gz +0 -0
- package/payload/server/public/assets/treeView-SZITEDCU-DetKw0D0.js +1 -0
- package/payload/server/public/assets/treeView-SZITEDCU-DetKw0D0.js.br +0 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-zQkIANxW.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-zQkIANxW.js.br +0 -0
- package/payload/server/public/assets/{triangle-alert-CuRAK3jk.js → triangle-alert-CjsLPsBD.js} +1 -1
- package/payload/server/public/assets/triangle-alert-CjsLPsBD.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-CjsLPsBD.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-BGzzIsSD.js → useCopyFeedback-umIgCxI_.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-umIgCxI_.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-umIgCxI_.js.gz +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-BDQ8Wsdt.css → useSubAccountSwitcher-D8jXV7R5.css} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-D8jXV7R5.css.br +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-BDQ8Wsdt.css.gz → useSubAccountSwitcher-D8jXV7R5.css.gz} +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-UMg53kKF.js +14 -0
- package/payload/server/public/assets/useSubAccountSwitcher-UMg53kKF.js.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-UMg53kKF.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-tzfqfXni.js +2 -0
- package/payload/server/public/assets/useVoiceRecorder-tzfqfXni.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-tzfqfXni.js.gz +0 -0
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-8nc7NUVQ.js → vennDiagram-DHZGUBPP-BsRGBF0K.js} +1 -1
- package/payload/server/public/assets/vennDiagram-DHZGUBPP-BsRGBF0K.js.br +0 -0
- package/payload/server/public/assets/vennDiagram-DHZGUBPP-BsRGBF0K.js.gz +0 -0
- package/payload/server/public/assets/wardley-RL74JXVD-DkQV3DvB.js +1 -0
- package/payload/server/public/assets/wardley-RL74JXVD-DkQV3DvB.js.br +0 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-Cjjiap8M.js → wardleyDiagram-NUSXRM2D-oQh9A-Mq.js} +1 -1
- package/payload/server/public/assets/wardleyDiagram-NUSXRM2D-oQh9A-Mq.js.br +0 -0
- package/payload/server/public/assets/wardleyDiagram-NUSXRM2D-oQh9A-Mq.js.gz +0 -0
- package/payload/server/public/assets/{wrench-DxSsCrue.js → wrench-DtfKfR4s.js} +1 -1
- package/payload/server/public/assets/wrench-DtfKfR4s.js.br +0 -0
- package/payload/server/public/assets/wrench-DtfKfR4s.js.gz +0 -0
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DEzDNw_i.js → xychartDiagram-5P7HB3ND-0K87OmFI.js} +1 -1
- package/payload/server/public/assets/xychartDiagram-5P7HB3ND-0K87OmFI.js.br +0 -0
- package/payload/server/public/assets/xychartDiagram-5P7HB3ND-0K87OmFI.js.gz +0 -0
- package/payload/server/public/browser.html +4 -5
- package/payload/server/public/calendar.html +7 -7
- package/payload/server/public/chat.html +14 -14
- package/payload/server/public/data.html +13 -13
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +16 -17
- package/payload/server/public/operator.html +15 -16
- package/payload/server/public/public.html +14 -14
- package/payload/server/public/routines.html +7 -7
- package/payload/server/public/skills.html +5 -5
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +1186 -516
- package/payload/server/public/assets/AdminLoginScreens-DxjuTFjL.js +0 -1
- package/payload/server/public/assets/AdminLoginScreens-DxjuTFjL.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-DxjuTFjL.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-B6H3J5C2.js +0 -2
- package/payload/server/public/assets/AdminShell-B6H3J5C2.js.br +0 -0
- package/payload/server/public/assets/AdminShell-B6H3J5C2.js.gz +0 -0
- package/payload/server/public/assets/CdpScreencastSurface-BRSv89v-.js +0 -1
- package/payload/server/public/assets/CdpScreencastSurface-BRSv89v-.js.br +0 -0
- package/payload/server/public/assets/CdpScreencastSurface-BRSv89v-.js.gz +0 -0
- package/payload/server/public/assets/activity-DKeRUjQ9.js.br +0 -0
- package/payload/server/public/assets/activity-DKeRUjQ9.js.gz +0 -0
- package/payload/server/public/assets/admin-BxRWjeyZ.js +0 -1
- package/payload/server/public/assets/admin-BxRWjeyZ.js.br +0 -0
- package/payload/server/public/assets/admin-BxRWjeyZ.js.gz +0 -0
- package/payload/server/public/assets/agents-CrR_OMe8.js.br +0 -0
- package/payload/server/public/assets/agents-CrR_OMe8.js.gz +0 -0
- package/payload/server/public/assets/arc-CHoXZR2f.js.br +0 -0
- package/payload/server/public/assets/arc-CHoXZR2f.js.gz +0 -0
- package/payload/server/public/assets/architecture-YZFGNWBL-CQyo9W6E.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-CQyo9W6E.js.br +0 -0
- package/payload/server/public/assets/architectureDiagram-Q4EWVU46-B8SCI0AR.js.br +0 -0
- package/payload/server/public/assets/architectureDiagram-Q4EWVU46-B8SCI0AR.js.gz +0 -0
- package/payload/server/public/assets/blockDiagram-DXYQGD6D-CsJmhz5D.js.br +0 -0
- package/payload/server/public/assets/blockDiagram-DXYQGD6D-CsJmhz5D.js.gz +0 -0
- package/payload/server/public/assets/browser-sfwnP1kH.js +0 -1
- package/payload/server/public/assets/browser-sfwnP1kH.js.br +0 -0
- package/payload/server/public/assets/browser-sfwnP1kH.js.gz +0 -0
- package/payload/server/public/assets/c4Diagram-AHTNJAMY-CzaSNqcs.js.br +0 -0
- package/payload/server/public/assets/c4Diagram-AHTNJAMY-CzaSNqcs.js.gz +0 -0
- package/payload/server/public/assets/calendar-ByLH0Q5p.js +0 -1
- package/payload/server/public/assets/calendar-ByLH0Q5p.js.br +0 -0
- package/payload/server/public/assets/calendar-ByLH0Q5p.js.gz +0 -0
- package/payload/server/public/assets/channel-Dg_Rah6O.js +0 -1
- package/payload/server/public/assets/channel-Dg_Rah6O.js.br +0 -0
- package/payload/server/public/assets/chat-C3xYZlGo.js +0 -1
- package/payload/server/public/assets/chat-C3xYZlGo.js.br +0 -2
- package/payload/server/public/assets/chat-C3xYZlGo.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-C0HG8MBj.js +0 -1
- package/payload/server/public/assets/chevron-right-B49Xpptm.js +0 -1
- package/payload/server/public/assets/chevron-right-B49Xpptm.js.br +0 -0
- package/payload/server/public/assets/chunk-2KRD3SAO-DAN3KCZc.js.br +0 -0
- package/payload/server/public/assets/chunk-2KRD3SAO-DAN3KCZc.js.gz +0 -0
- package/payload/server/public/assets/chunk-336JU56O-Dm-0_lIT.js.br +0 -0
- package/payload/server/public/assets/chunk-336JU56O-Dm-0_lIT.js.gz +0 -0
- package/payload/server/public/assets/chunk-426QAEUC-Rh8qTRZB.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-Rh8qTRZB.js.br +0 -0
- package/payload/server/public/assets/chunk-426QAEUC-Rh8qTRZB.js.gz +0 -0
- package/payload/server/public/assets/chunk-4BX2VUAB-C2l9bAlo.js.br +0 -0
- package/payload/server/public/assets/chunk-4BX2VUAB-C2l9bAlo.js.gz +0 -0
- package/payload/server/public/assets/chunk-4TB4RGXK-BMXDzU09.js.br +0 -0
- package/payload/server/public/assets/chunk-4TB4RGXK-BMXDzU09.js.gz +0 -0
- package/payload/server/public/assets/chunk-55IACEB6-CbMYAZon.js.br +0 -0
- package/payload/server/public/assets/chunk-55IACEB6-CbMYAZon.js.gz +0 -0
- package/payload/server/public/assets/chunk-5FUZZQ4R-DjdsuxLA.js.br +0 -0
- package/payload/server/public/assets/chunk-5FUZZQ4R-DjdsuxLA.js.gz +0 -0
- package/payload/server/public/assets/chunk-5PVQY5BW-CGSBzsF6.js.br +0 -0
- package/payload/server/public/assets/chunk-5PVQY5BW-CGSBzsF6.js.gz +0 -0
- package/payload/server/public/assets/chunk-67CJDMHE-ClOLWser.js.br +0 -0
- package/payload/server/public/assets/chunk-67CJDMHE-ClOLWser.js.gz +0 -0
- package/payload/server/public/assets/chunk-7N4EOEYR-BzC1dzY0.js.br +0 -0
- package/payload/server/public/assets/chunk-7N4EOEYR-BzC1dzY0.js.gz +0 -0
- package/payload/server/public/assets/chunk-AA7GKIK3-R_pjI1kw.js.br +0 -0
- package/payload/server/public/assets/chunk-AA7GKIK3-R_pjI1kw.js.gz +0 -0
- package/payload/server/public/assets/chunk-BSJP7CBP-D2KRAq3U.js.br +0 -0
- package/payload/server/public/assets/chunk-BSJP7CBP-D2KRAq3U.js.gz +0 -0
- package/payload/server/public/assets/chunk-CIAEETIT-BPGWtrKR.js.br +0 -0
- package/payload/server/public/assets/chunk-CIAEETIT-BPGWtrKR.js.gz +0 -0
- package/payload/server/public/assets/chunk-EDXVE4YY-tqt7wueu.js.br +0 -3
- package/payload/server/public/assets/chunk-EDXVE4YY-tqt7wueu.js.gz +0 -0
- package/payload/server/public/assets/chunk-ENJZ2VHE-DJG3cA6E.js.br +0 -0
- package/payload/server/public/assets/chunk-ENJZ2VHE-DJG3cA6E.js.gz +0 -0
- package/payload/server/public/assets/chunk-FMBD7UC4-DO1xgCDf.js.br +0 -2
- package/payload/server/public/assets/chunk-FMBD7UC4-DO1xgCDf.js.gz +0 -0
- package/payload/server/public/assets/chunk-FOC6F5B3-BhWAbCUG.js.br +0 -0
- package/payload/server/public/assets/chunk-FOC6F5B3-BhWAbCUG.js.gz +0 -0
- package/payload/server/public/assets/chunk-ICPOFSXX-BhUzt35c.js.br +0 -0
- package/payload/server/public/assets/chunk-ICPOFSXX-BhUzt35c.js.gz +0 -0
- package/payload/server/public/assets/chunk-K5T4RW27-Boj-qHrX.js.br +0 -0
- package/payload/server/public/assets/chunk-K5T4RW27-Boj-qHrX.js.gz +0 -0
- package/payload/server/public/assets/chunk-KGLVRYIC-3cBRDk1b.js.br +0 -2
- package/payload/server/public/assets/chunk-KGLVRYIC-3cBRDk1b.js.gz +0 -0
- package/payload/server/public/assets/chunk-LIHQZDEY-CgkLKaII.js.br +0 -0
- package/payload/server/public/assets/chunk-LIHQZDEY-CgkLKaII.js.gz +0 -0
- package/payload/server/public/assets/chunk-ORNJ4GCN-Dl449r_k.js.br +0 -0
- package/payload/server/public/assets/chunk-ORNJ4GCN-Dl449r_k.js.gz +0 -0
- package/payload/server/public/assets/chunk-OYMX7WX6-Dzkj67n6.js.br +0 -0
- package/payload/server/public/assets/chunk-OYMX7WX6-Dzkj67n6.js.gz +0 -0
- package/payload/server/public/assets/chunk-QZHKN3VN-BDoCtU0N.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-BDoCtU0N.js.br +0 -0
- package/payload/server/public/assets/chunk-QZHKN3VN-BDoCtU0N.js.gz +0 -0
- package/payload/server/public/assets/chunk-U2HBQHQK-Dyz9Kbir.js.br +0 -0
- package/payload/server/public/assets/chunk-U2HBQHQK-Dyz9Kbir.js.gz +0 -0
- package/payload/server/public/assets/chunk-X2U36JSP-ag0VVCw6.js.br +0 -0
- package/payload/server/public/assets/chunk-X2U36JSP-ag0VVCw6.js.gz +0 -0
- package/payload/server/public/assets/chunk-XPW4576I-B-vhDYPE.js.br +0 -0
- package/payload/server/public/assets/chunk-XPW4576I-B-vhDYPE.js.gz +0 -0
- package/payload/server/public/assets/chunk-YZCP3GAM-C4COviPb.js.br +0 -0
- package/payload/server/public/assets/chunk-YZCP3GAM-C4COviPb.js.gz +0 -0
- package/payload/server/public/assets/chunk-ZZ45TVLE-8dGsCp5b.js.br +0 -0
- package/payload/server/public/assets/chunk-ZZ45TVLE-8dGsCp5b.js.gz +0 -0
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-qevfwy5C.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-qevfwy5C.js.br +0 -0
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-qevfwy5C.js.gz +0 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CxOR3aao.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CxOR3aao.js.br +0 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CxOR3aao.js.gz +0 -0
- package/payload/server/public/assets/clock-CJq9vvt8.js +0 -1
- package/payload/server/public/assets/clock-CJq9vvt8.js.br +0 -0
- package/payload/server/public/assets/clock-CJq9vvt8.js.gz +0 -0
- package/payload/server/public/assets/clone-CJmzeWWZ.js +0 -1
- package/payload/server/public/assets/clone-CJmzeWWZ.js.br +0 -0
- package/payload/server/public/assets/cose-bilkent-S5V4N54A-qM4Q4TuE.js.br +0 -0
- package/payload/server/public/assets/cose-bilkent-S5V4N54A-qM4Q4TuE.js.gz +0 -0
- package/payload/server/public/assets/dagre-DRvHdusQ.js.br +0 -0
- package/payload/server/public/assets/dagre-DRvHdusQ.js.gz +0 -0
- package/payload/server/public/assets/dagre-KV5264BT-CGqSVVTn.js.br +0 -0
- package/payload/server/public/assets/dagre-KV5264BT-CGqSVVTn.js.gz +0 -0
- package/payload/server/public/assets/data-DmeTKd-P.js +0 -1
- package/payload/server/public/assets/data-DmeTKd-P.js.br +0 -0
- package/payload/server/public/assets/data-DmeTKd-P.js.gz +0 -0
- package/payload/server/public/assets/diagram-5BDNPKRD-DfFgeApz.js.br +0 -0
- package/payload/server/public/assets/diagram-5BDNPKRD-DfFgeApz.js.gz +0 -0
- package/payload/server/public/assets/diagram-G4DWMVQ6-DPXc3Q8e.js.br +0 -0
- package/payload/server/public/assets/diagram-G4DWMVQ6-DPXc3Q8e.js.gz +0 -0
- package/payload/server/public/assets/diagram-MMDJMWI5-V8RCddvy.js.br +0 -0
- package/payload/server/public/assets/diagram-MMDJMWI5-V8RCddvy.js.gz +0 -0
- package/payload/server/public/assets/diagram-TYMM5635-CrvfIf-m.js.br +0 -0
- package/payload/server/public/assets/diagram-TYMM5635-CrvfIf-m.js.gz +0 -0
- package/payload/server/public/assets/erDiagram-SMLLAGMA-DClMgmBB.js.br +0 -0
- package/payload/server/public/assets/erDiagram-SMLLAGMA-DClMgmBB.js.gz +0 -0
- package/payload/server/public/assets/file-download-BWe9Muoh.js +0 -1
- package/payload/server/public/assets/file-download-BWe9Muoh.js.br +0 -0
- package/payload/server/public/assets/file-download-BWe9Muoh.js.gz +0 -0
- package/payload/server/public/assets/file-text-5osg-EVb.js.br +0 -0
- package/payload/server/public/assets/file-text-5osg-EVb.js.gz +0 -0
- package/payload/server/public/assets/flatten-UdUTbm8v.js.br +0 -0
- package/payload/server/public/assets/flatten-UdUTbm8v.js.gz +0 -0
- package/payload/server/public/assets/flowDiagram-DWJPFMVM-D29Ou09P.js.br +0 -0
- package/payload/server/public/assets/flowDiagram-DWJPFMVM-D29Ou09P.js.gz +0 -0
- package/payload/server/public/assets/ganttDiagram-T4ZO3ILL-CoAK7W_V.js.br +0 -0
- package/payload/server/public/assets/ganttDiagram-T4ZO3ILL-CoAK7W_V.js.gz +0 -0
- package/payload/server/public/assets/gitGraph-7Q5UKJZL--JSoLMoH.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL--JSoLMoH.js.br +0 -0
- package/payload/server/public/assets/gitGraphDiagram-UUTBAWPF-DMEc_1aX.js.br +0 -0
- package/payload/server/public/assets/gitGraphDiagram-UUTBAWPF-DMEc_1aX.js.gz +0 -0
- package/payload/server/public/assets/graph-CAUo1OTY.js.br +0 -0
- package/payload/server/public/assets/graph-CAUo1OTY.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-TJ-3ljQo.js.br +0 -0
- package/payload/server/public/assets/graph-labels-TJ-3ljQo.js.gz +0 -0
- package/payload/server/public/assets/graphlib-ihSLgqUG.js.br +0 -0
- package/payload/server/public/assets/graphlib-ihSLgqUG.js.gz +0 -0
- package/payload/server/public/assets/info-OMHHGYJF-CY4gsXn4.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-CY4gsXn4.js.br +0 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-CpWSNS3C.js +0 -2
- package/payload/server/public/assets/infoDiagram-42DDH7IO-CpWSNS3C.js.br +0 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-CpWSNS3C.js.gz +0 -0
- package/payload/server/public/assets/isEmpty-DY_Xp9Na.js.br +0 -0
- package/payload/server/public/assets/isEmpty-DY_Xp9Na.js.gz +0 -0
- package/payload/server/public/assets/ishikawaDiagram-UXIWVN3A-w8fVIbxy.js.br +0 -0
- package/payload/server/public/assets/ishikawaDiagram-UXIWVN3A-w8fVIbxy.js.gz +0 -0
- package/payload/server/public/assets/journeyDiagram-VCZTEJTY-BRTPKDT5.js.br +0 -0
- package/payload/server/public/assets/journeyDiagram-VCZTEJTY-BRTPKDT5.js.gz +0 -0
- package/payload/server/public/assets/kanban-definition-6JOO6SKY-Ls3VaFZ_.js.br +0 -0
- package/payload/server/public/assets/kanban-definition-6JOO6SKY-Ls3VaFZ_.js.gz +0 -0
- package/payload/server/public/assets/line-BwhAIh8u.js.br +0 -0
- package/payload/server/public/assets/line-BwhAIh8u.js.gz +0 -0
- package/payload/server/public/assets/linear-USiZPFN4.js.br +0 -0
- package/payload/server/public/assets/linear-USiZPFN4.js.gz +0 -0
- package/payload/server/public/assets/maximize-2-S9W3q1O4.js.br +0 -0
- package/payload/server/public/assets/maximize-2-S9W3q1O4.js.gz +0 -0
- package/payload/server/public/assets/mermaid-parser.core-Bq--iC2w.js.br +0 -0
- package/payload/server/public/assets/mermaid-parser.core-Bq--iC2w.js.gz +0 -0
- package/payload/server/public/assets/mermaid.core-oYX-FxVa.js.br +0 -0
- package/payload/server/public/assets/mermaid.core-oYX-FxVa.js.gz +0 -0
- package/payload/server/public/assets/mindmap-definition-QFDTVHPH-ByZjL4Bs.js.br +0 -0
- package/payload/server/public/assets/mindmap-definition-QFDTVHPH-ByZjL4Bs.js.gz +0 -0
- package/payload/server/public/assets/operator-CzOJfank.js +0 -1
- package/payload/server/public/assets/operator-CzOJfank.js.br +0 -0
- package/payload/server/public/assets/operator-CzOJfank.js.gz +0 -0
- package/payload/server/public/assets/ordinal-gnpqfIHn.js.br +0 -0
- package/payload/server/public/assets/ordinal-gnpqfIHn.js.gz +0 -0
- package/payload/server/public/assets/packet-4T2RLAQJ-DczCn3uj.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-DczCn3uj.js.br +0 -0
- package/payload/server/public/assets/page-BUFW-PWF.js.br +0 -0
- package/payload/server/public/assets/page-BUFW-PWF.js.gz +0 -0
- package/payload/server/public/assets/page-jT4queFM.js +0 -1
- package/payload/server/public/assets/page-jT4queFM.js.br +0 -0
- package/payload/server/public/assets/page-jT4queFM.js.gz +0 -0
- package/payload/server/public/assets/pdf-render-gEryZmeC.js.br +0 -0
- package/payload/server/public/assets/pdf-render-gEryZmeC.js.gz +0 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-CbvZUaof.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-CbvZUaof.js.br +0 -0
- package/payload/server/public/assets/pieDiagram-DEJITSTG-BGFms5bU.js.br +0 -0
- package/payload/server/public/assets/pieDiagram-DEJITSTG-BGFms5bU.js.gz +0 -0
- package/payload/server/public/assets/public-Cx2ddU9a.js.br +0 -0
- package/payload/server/public/assets/public-Cx2ddU9a.js.gz +0 -0
- package/payload/server/public/assets/quadrantDiagram-34T5L4WZ-_ymoz8bQ.js.br +0 -0
- package/payload/server/public/assets/quadrantDiagram-34T5L4WZ-_ymoz8bQ.js.gz +0 -0
- package/payload/server/public/assets/radar-PYXPWWZC-XmuabQlO.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-XmuabQlO.js.br +0 -0
- package/payload/server/public/assets/reduce-BvezuHIe.js.br +0 -0
- package/payload/server/public/assets/reduce-BvezuHIe.js.gz +0 -0
- package/payload/server/public/assets/requirementDiagram-MS252O5E-lrOmOxIA.js.br +0 -0
- package/payload/server/public/assets/requirementDiagram-MS252O5E-lrOmOxIA.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-C2qSSBFA.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-C2qSSBFA.js.gz +0 -0
- package/payload/server/public/assets/routines-80uEwjng.js +0 -2
- package/payload/server/public/assets/routines-80uEwjng.js.br +0 -0
- package/payload/server/public/assets/routines-80uEwjng.js.gz +0 -0
- package/payload/server/public/assets/sankeyDiagram-XADWPNL6-CdUQThXU.js.br +0 -0
- package/payload/server/public/assets/sankeyDiagram-XADWPNL6-CdUQThXU.js.gz +0 -0
- package/payload/server/public/assets/sequenceDiagram-FGHM5R23-DqnEEldq.js.br +0 -0
- package/payload/server/public/assets/sequenceDiagram-FGHM5R23-DqnEEldq.js.gz +0 -0
- package/payload/server/public/assets/skills-CmsYXVd3.js.br +0 -0
- package/payload/server/public/assets/skills-CmsYXVd3.js.gz +0 -0
- package/payload/server/public/assets/stateDiagram-FHFEXIEX-KEdtxqdq.js.br +0 -0
- package/payload/server/public/assets/stateDiagram-FHFEXIEX-KEdtxqdq.js.gz +0 -0
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Cs85Ewtt.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Cs85Ewtt.js.br +0 -0
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Cs85Ewtt.js.gz +0 -0
- package/payload/server/public/assets/tasks-CFfvn-KE.js +0 -3
- package/payload/server/public/assets/tasks-CFfvn-KE.js.br +0 -0
- package/payload/server/public/assets/tasks-CFfvn-KE.js.gz +0 -0
- package/payload/server/public/assets/time-entry-format-BD99oR05.js +0 -1
- package/payload/server/public/assets/time-entry-format-BD99oR05.js.br +0 -0
- package/payload/server/public/assets/time-entry-format-BD99oR05.js.gz +0 -0
- package/payload/server/public/assets/timeline-definition-GMOUNBTQ-BRXdCMau.js.br +0 -0
- package/payload/server/public/assets/timeline-definition-GMOUNBTQ-BRXdCMau.js.gz +0 -0
- package/payload/server/public/assets/treeView-SZITEDCU-B-SYhqwK.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-B-SYhqwK.js.br +0 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-DpZmFNM9.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-DpZmFNM9.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-CuRAK3jk.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-CuRAK3jk.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-BGzzIsSD.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-BGzzIsSD.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-BDQ8Wsdt.css.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-D1VtIEp2.js +0 -14
- package/payload/server/public/assets/useSubAccountSwitcher-D1VtIEp2.js.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-D1VtIEp2.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-fpwWw2VW.js +0 -2
- package/payload/server/public/assets/useVoiceRecorder-fpwWw2VW.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-fpwWw2VW.js.gz +0 -0
- package/payload/server/public/assets/vennDiagram-DHZGUBPP-8nc7NUVQ.js.br +0 -0
- package/payload/server/public/assets/vennDiagram-DHZGUBPP-8nc7NUVQ.js.gz +0 -0
- package/payload/server/public/assets/wardley-RL74JXVD-D2FCCV4-.js +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-D2FCCV4-.js.br +0 -0
- package/payload/server/public/assets/wardleyDiagram-NUSXRM2D-Cjjiap8M.js.br +0 -0
- package/payload/server/public/assets/wardleyDiagram-NUSXRM2D-Cjjiap8M.js.gz +0 -0
- package/payload/server/public/assets/wrench-DxSsCrue.js.br +0 -2
- package/payload/server/public/assets/wrench-DxSsCrue.js.gz +0 -0
- package/payload/server/public/assets/xychartDiagram-5P7HB3ND-DEzDNw_i.js.br +0 -0
- package/payload/server/public/assets/xychartDiagram-5P7HB3ND-DEzDNw_i.js.gz +0 -0
- /package/payload/server/public/assets/{_baseFor-BApe6Tla.js → _baseFor-B12He5Rp.js} +0 -0
- /package/payload/server/public/assets/{_baseFor-BApe6Tla.js.br → _baseFor-B12He5Rp.js.br} +0 -0
- /package/payload/server/public/assets/{_baseFor-BApe6Tla.js.gz → _baseFor-B12He5Rp.js.gz} +0 -0
- /package/payload/server/public/assets/{array-eiH4WfvY.js → array-DO1uCttT.js} +0 -0
- /package/payload/server/public/assets/{array-eiH4WfvY.js.br → array-DO1uCttT.js.br} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-BZ6NYo0w.js → cytoscape.esm-DFn2foqy.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-BZ6NYo0w.js.br → cytoscape.esm-DFn2foqy.js.br} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-BZ6NYo0w.js.gz → cytoscape.esm-DFn2foqy.js.gz} +0 -0
- /package/payload/server/public/assets/{defaultLocale-DWHqsa6O.js → defaultLocale-ieI3yFoA.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-DWHqsa6O.js.br → defaultLocale-ieI3yFoA.js.br} +0 -0
- /package/payload/server/public/assets/{defaultLocale-DWHqsa6O.js.gz → defaultLocale-ieI3yFoA.js.gz} +0 -0
- /package/payload/server/public/assets/{dist-IoQuidkp.js → dist-DlU7AEeD.js} +0 -0
- /package/payload/server/public/assets/{dist-IoQuidkp.js.br → dist-DlU7AEeD.js.br} +0 -0
- /package/payload/server/public/assets/{dist-IoQuidkp.js.gz → dist-DlU7AEeD.js.gz} +0 -0
- /package/payload/server/public/assets/{init-BdkYWjJJ.js → init-BCRlEgNP.js} +0 -0
- /package/payload/server/public/assets/{init-BdkYWjJJ.js.br → init-BCRlEgNP.js.br} +0 -0
- /package/payload/server/public/assets/{init-BdkYWjJJ.js.gz → init-BCRlEgNP.js.gz} +0 -0
- /package/payload/server/public/assets/{katex-BCzoGtFh.js → katex-gkTaZgi6.js} +0 -0
- /package/payload/server/public/assets/{katex-BCzoGtFh.js.br → katex-gkTaZgi6.js.br} +0 -0
- /package/payload/server/public/assets/{katex-BCzoGtFh.js.gz → katex-gkTaZgi6.js.gz} +0 -0
- /package/payload/server/public/assets/{path-DY2qBuPM.js → path-DTmzQFjQ.js} +0 -0
- /package/payload/server/public/assets/{path-DY2qBuPM.js.br → path-DTmzQFjQ.js.br} +0 -0
- /package/payload/server/public/assets/{path-DY2qBuPM.js.gz → path-DTmzQFjQ.js.gz} +0 -0
- /package/payload/server/public/assets/{preload-helper-3YNEDsJZ.js → preload-helper-BQrMkyGX.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-3YNEDsJZ.js.br → preload-helper-BQrMkyGX.js.br} +0 -0
- /package/payload/server/public/assets/{preload-helper-3YNEDsJZ.js.gz → preload-helper-BQrMkyGX.js.gz} +0 -0
- /package/payload/server/public/assets/{rough.esm-ec8xsRC7.js → rough.esm-BFJ-MgcB.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-ec8xsRC7.js.br → rough.esm-BFJ-MgcB.js.br} +0 -0
- /package/payload/server/public/assets/{rough.esm-ec8xsRC7.js.gz → rough.esm-BFJ-MgcB.js.gz} +0 -0
- /package/payload/server/public/assets/{src-C-STKunZ.js → src-9CNk4JU0.js} +0 -0
- /package/payload/server/public/assets/{src-C-STKunZ.js.br → src-9CNk4JU0.js.br} +0 -0
- /package/payload/server/public/assets/{src-C-STKunZ.js.gz → src-9CNk4JU0.js.gz} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
cleanupLeakedPremiumSubs,
|
|
15
15
|
clearRateLimit,
|
|
16
16
|
clientIpMiddleware,
|
|
17
|
+
closePageTarget,
|
|
18
|
+
createPageTarget,
|
|
17
19
|
createRemoteSession,
|
|
18
20
|
emitMissingOnResolve,
|
|
19
21
|
fetchPageTargets,
|
|
@@ -52,6 +54,7 @@ import {
|
|
|
52
54
|
setSessionIdForSession,
|
|
53
55
|
setWantsPriorConversation,
|
|
54
56
|
stripAttachmentMetaSuffix,
|
|
57
|
+
tabsLog,
|
|
55
58
|
tryCookieBridgeForConversation,
|
|
56
59
|
unregisterSession,
|
|
57
60
|
validatePasswordStrength,
|
|
@@ -59,7 +62,7 @@ import {
|
|
|
59
62
|
verifyRemotePassword,
|
|
60
63
|
vncLog,
|
|
61
64
|
walkPremiumBundles
|
|
62
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-IALJPXIO.js";
|
|
63
66
|
import {
|
|
64
67
|
DATA_ROOT,
|
|
65
68
|
EXTRACTED_TEXT_SUFFIX,
|
|
@@ -192,7 +195,7 @@ import {
|
|
|
192
195
|
waitForConnection,
|
|
193
196
|
warnNonUuidAccount,
|
|
194
197
|
writeChatMetadataMerged
|
|
195
|
-
} from "./chunk-
|
|
198
|
+
} from "./chunk-44Z4ZFYS.js";
|
|
196
199
|
import {
|
|
197
200
|
ACCOUNTS_DIR,
|
|
198
201
|
BIN_DIR,
|
|
@@ -2382,11 +2385,11 @@ function staticCacheHeaders(root) {
|
|
|
2382
2385
|
}
|
|
2383
2386
|
|
|
2384
2387
|
// server/lib/static-mounts.ts
|
|
2385
|
-
function mountStaticFiles(
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2388
|
+
function mountStaticFiles(app77, root) {
|
|
2389
|
+
app77.use("/*", staticCacheHeaders(root));
|
|
2390
|
+
app77.use("/assets/*", assetsVary);
|
|
2391
|
+
app77.use("/assets/*", serveStatic({ root, precompressed: true }));
|
|
2392
|
+
app77.use("/*", serveStatic({ root }));
|
|
2390
2393
|
}
|
|
2391
2394
|
var assetsVary = async (c, next) => {
|
|
2392
2395
|
await next();
|
|
@@ -3586,8 +3589,8 @@ function webchatTurnTimeoutMs() {
|
|
|
3586
3589
|
return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
|
|
3587
3590
|
}
|
|
3588
3591
|
function createChatRoutes(deps) {
|
|
3589
|
-
const
|
|
3590
|
-
|
|
3592
|
+
const app77 = new Hono();
|
|
3593
|
+
app77.post("/", async (c) => {
|
|
3591
3594
|
console.log(`[chat-route] entered route=public method=POST`);
|
|
3592
3595
|
const contentType = c.req.header("content-type") ?? "";
|
|
3593
3596
|
const account = resolveAccount();
|
|
@@ -3859,7 +3862,7 @@ ${result.result.text}` : result.result.text;
|
|
|
3859
3862
|
}
|
|
3860
3863
|
});
|
|
3861
3864
|
});
|
|
3862
|
-
return
|
|
3865
|
+
return app77;
|
|
3863
3866
|
}
|
|
3864
3867
|
|
|
3865
3868
|
// server/routes/channel/schedule-inject.ts
|
|
@@ -4803,8 +4806,8 @@ function transcriptBoundary(sessionKey) {
|
|
|
4803
4806
|
}
|
|
4804
4807
|
}
|
|
4805
4808
|
function createScheduleInjectRoutes(deps) {
|
|
4806
|
-
const
|
|
4807
|
-
|
|
4809
|
+
const app77 = new Hono();
|
|
4810
|
+
app77.post("/", async (c) => {
|
|
4808
4811
|
const env = c.env;
|
|
4809
4812
|
const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
|
|
4810
4813
|
if (!isLoopbackAddr(remoteAddr)) {
|
|
@@ -4915,7 +4918,7 @@ function createScheduleInjectRoutes(deps) {
|
|
|
4915
4918
|
console.error(`${TAG5} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
|
|
4916
4919
|
return c.json({ ok: true, sessionKey: sessionId, ...transcriptBoundary(sessionId) }, 200);
|
|
4917
4920
|
});
|
|
4918
|
-
return
|
|
4921
|
+
return app77;
|
|
4919
4922
|
}
|
|
4920
4923
|
|
|
4921
4924
|
// server/index.ts
|
|
@@ -5021,7 +5024,7 @@ async function defaultHttpGet(url) {
|
|
|
5021
5024
|
}
|
|
5022
5025
|
}
|
|
5023
5026
|
async function defaultResolve(accountId) {
|
|
5024
|
-
const { resolveSocket: resolveSocket2 } = await import("./manager-
|
|
5027
|
+
const { resolveSocket: resolveSocket2 } = await import("./manager-AJSPM6X2.js");
|
|
5025
5028
|
return resolveSocket2(accountId);
|
|
5026
5029
|
}
|
|
5027
5030
|
async function fetchAvatar(accountId, jid, deps = {}) {
|
|
@@ -5841,7 +5844,7 @@ function setDispatchInbound(accountDir, accountId, value, ctx) {
|
|
|
5841
5844
|
const id = accountId.trim();
|
|
5842
5845
|
if (!id) return { ok: false, reason: "missing-account-id", error: "Missing account id." };
|
|
5843
5846
|
const verdict = resolveKey(id, ctx);
|
|
5844
|
-
const failure = policyKeyFailure(verdict, id,
|
|
5847
|
+
const failure = policyKeyFailure(verdict, id, null);
|
|
5845
5848
|
if (failure) {
|
|
5846
5849
|
console.error(`${TAG10} op=set-dispatch-inbound account=${id} ok=false reason=${failure.reason}`);
|
|
5847
5850
|
return failure;
|
|
@@ -5877,16 +5880,9 @@ function setDispatchInbound(accountDir, accountId, value, ctx) {
|
|
|
5877
5880
|
return { ok: false, reason: "write-failed", error: msg };
|
|
5878
5881
|
}
|
|
5879
5882
|
}
|
|
5880
|
-
function policyKeyFailure(verdict, accountId,
|
|
5883
|
+
function policyKeyFailure(verdict, accountId, houseFailure) {
|
|
5881
5884
|
if (verdict.kind === "self") return null;
|
|
5882
|
-
if (verdict.kind === "house")
|
|
5883
|
-
if (!opts.refuseHouse) return null;
|
|
5884
|
-
return {
|
|
5885
|
-
ok: false,
|
|
5886
|
-
reason: "house-policy-is-top-level",
|
|
5887
|
-
error: `Account "${accountId}" is the house. Its dmPolicy, adminPhones and allowFrom are the TOP-LEVEL WhatsApp config, not a per-account override \u2014 set them with the "update-config" action (adminPhones also has add-admin-phone / remove-admin-phone). Writing a per-account slice for the house would create a second home for the same three fields.`
|
|
5888
|
-
};
|
|
5889
|
-
}
|
|
5885
|
+
if (verdict.kind === "house") return houseFailure;
|
|
5890
5886
|
if (verdict.kind === "ambiguous") {
|
|
5891
5887
|
return {
|
|
5892
5888
|
ok: false,
|
|
@@ -5900,6 +5896,13 @@ function policyKeyFailure(verdict, accountId, opts) {
|
|
|
5900
5896
|
error: `Account "${accountId}" has no WhatsApp credential directory, so it has no config slice the inbound gate would read. Pair the account first.`
|
|
5901
5897
|
};
|
|
5902
5898
|
}
|
|
5899
|
+
function policyHouseFailure(accountId) {
|
|
5900
|
+
return {
|
|
5901
|
+
ok: false,
|
|
5902
|
+
reason: "house-policy-is-top-level",
|
|
5903
|
+
error: `Account "${accountId}" is the house. Its dmPolicy, adminPhones and allowFrom are the TOP-LEVEL WhatsApp config, not a per-account override \u2014 set them with the "update-config" action (adminPhones also has add-admin-phone / remove-admin-phone). Writing a per-account slice for the house would create a second home for the same three fields.`
|
|
5904
|
+
};
|
|
5905
|
+
}
|
|
5903
5906
|
function resolveKey(accountId, ctx) {
|
|
5904
5907
|
return resolveAccountConfigKey({
|
|
5905
5908
|
targetAccountId: accountId,
|
|
@@ -5922,7 +5925,7 @@ function setAccountPolicy(accountDir, accountId, policy, ctx) {
|
|
|
5922
5925
|
};
|
|
5923
5926
|
}
|
|
5924
5927
|
const verdict = resolveKey(id, ctx);
|
|
5925
|
-
const failure = policyKeyFailure(verdict, id,
|
|
5928
|
+
const failure = policyKeyFailure(verdict, id, policyHouseFailure(id));
|
|
5926
5929
|
if (failure) {
|
|
5927
5930
|
console.error(`${TAG10} op=set-account-policy account=${id} ok=false reason=${failure.reason}`);
|
|
5928
5931
|
return failure;
|
|
@@ -5960,7 +5963,7 @@ function readAccountPolicy(accountDir, accountId, ctx) {
|
|
|
5960
5963
|
const id = accountId.trim();
|
|
5961
5964
|
if (!id) return { ok: false, reason: "missing-account-id", error: "Missing account id." };
|
|
5962
5965
|
const verdict = resolveKey(id, ctx);
|
|
5963
|
-
const failure = policyKeyFailure(verdict, id,
|
|
5966
|
+
const failure = policyKeyFailure(verdict, id, null);
|
|
5964
5967
|
if (failure) return failure;
|
|
5965
5968
|
const key = verdict.key;
|
|
5966
5969
|
try {
|
|
@@ -6032,14 +6035,43 @@ function readAccountManagers(accountDir) {
|
|
|
6032
6035
|
return {};
|
|
6033
6036
|
}
|
|
6034
6037
|
}
|
|
6035
|
-
function
|
|
6038
|
+
function publicAgentHouseFailure(accountId) {
|
|
6039
|
+
return {
|
|
6040
|
+
ok: false,
|
|
6041
|
+
reason: "house-public-agent-is-top-level",
|
|
6042
|
+
error: `Account "${accountId}" is the house. Its publicAgent and publicAgentEnabled are the TOP-LEVEL WhatsApp config \u2014 set them by calling this action without an accountId. Writing a per-account slice for the house would create a second home for the same field.`
|
|
6043
|
+
};
|
|
6044
|
+
}
|
|
6045
|
+
function publicAgentKey(target) {
|
|
6046
|
+
if (target.scope === "top-level") return { key: null };
|
|
6047
|
+
const id = target.accountId.trim();
|
|
6048
|
+
if (!id) return { ok: false, reason: "missing-account-id", error: "Missing account id." };
|
|
6049
|
+
const verdict = resolveKey(id, target.ctx);
|
|
6050
|
+
const failure = policyKeyFailure(verdict, id, publicAgentHouseFailure(id));
|
|
6051
|
+
if (failure) return failure;
|
|
6052
|
+
return { key: verdict.key };
|
|
6053
|
+
}
|
|
6054
|
+
function publicAgentScopeLabel(target) {
|
|
6055
|
+
return target.scope === "top-level" ? "the top-level default" : `account ${target.accountId}`;
|
|
6056
|
+
}
|
|
6057
|
+
function setPublicAgent(accountDir, slug, target) {
|
|
6036
6058
|
const trimmed = slug.trim();
|
|
6037
6059
|
if (!trimmed) {
|
|
6038
|
-
return { ok: false, error: "Agent slug cannot be empty." };
|
|
6060
|
+
return { ok: false, reason: "missing-slug", error: "Agent slug cannot be empty." };
|
|
6039
6061
|
}
|
|
6040
|
-
const
|
|
6062
|
+
const resolvedKey = publicAgentKey(target);
|
|
6063
|
+
if ("ok" in resolvedKey) {
|
|
6064
|
+
console.error(`${TAG10} op=set-public-agent accountId=${publicAgentScopeLabel(target)} ok=false reason=${resolvedKey.reason}`);
|
|
6065
|
+
return resolvedKey;
|
|
6066
|
+
}
|
|
6067
|
+
const key = resolvedKey.key;
|
|
6068
|
+
const agentConfigPath = join12(target.agentsDir, "agents", trimmed, "config.json");
|
|
6041
6069
|
if (!existsSync6(agentConfigPath)) {
|
|
6042
|
-
return {
|
|
6070
|
+
return {
|
|
6071
|
+
ok: false,
|
|
6072
|
+
reason: "agent-not-found",
|
|
6073
|
+
error: `Agent "${trimmed}" not found \u2014 no config.json at ${agentConfigPath}. Check the agent slug and try again.`
|
|
6074
|
+
};
|
|
6043
6075
|
}
|
|
6044
6076
|
try {
|
|
6045
6077
|
const config = readConfig(accountDir);
|
|
@@ -6047,21 +6079,96 @@ function setPublicAgent(accountDir, slug) {
|
|
|
6047
6079
|
config.whatsapp = {};
|
|
6048
6080
|
}
|
|
6049
6081
|
const wa = config.whatsapp;
|
|
6050
|
-
|
|
6082
|
+
if (key) {
|
|
6083
|
+
if (!wa.accounts || typeof wa.accounts !== "object") wa.accounts = {};
|
|
6084
|
+
const accounts = wa.accounts;
|
|
6085
|
+
if (!accounts[key] || typeof accounts[key] !== "object") accounts[key] = {};
|
|
6086
|
+
accounts[key].publicAgent = trimmed;
|
|
6087
|
+
} else {
|
|
6088
|
+
wa.publicAgent = trimmed;
|
|
6089
|
+
}
|
|
6051
6090
|
const parsed = WhatsAppConfigSchema.safeParse(wa);
|
|
6052
6091
|
if (!parsed.success) {
|
|
6053
6092
|
const msg = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
6054
|
-
return { ok: false, error: `Validation failed: ${msg}` };
|
|
6093
|
+
return { ok: false, reason: "validation-failed", error: `Validation failed: ${msg}` };
|
|
6055
6094
|
}
|
|
6056
6095
|
config.whatsapp = parsed.data;
|
|
6057
6096
|
writeConfig(accountDir, config);
|
|
6058
|
-
console.error(
|
|
6097
|
+
console.error(
|
|
6098
|
+
`${TAG10} op=set-public-agent accountId=${target.scope === "top-level" ? "top-level" : target.accountId} key=${key ?? "top-level"} slug=${trimmed} ok=true`
|
|
6099
|
+
);
|
|
6059
6100
|
reloadManagerConfig(accountDir);
|
|
6060
|
-
return {
|
|
6101
|
+
return {
|
|
6102
|
+
ok: true,
|
|
6103
|
+
key,
|
|
6104
|
+
message: `Public agent for ${publicAgentScopeLabel(target)} set to "${trimmed}". WhatsApp messages from non-admin phones will be handled by this agent.`
|
|
6105
|
+
};
|
|
6061
6106
|
} catch (err) {
|
|
6062
6107
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6063
|
-
console.error(`${TAG10}
|
|
6064
|
-
return { ok: false, error: msg };
|
|
6108
|
+
console.error(`${TAG10} op=set-public-agent ok=false reason=write-failed detail=${msg}`);
|
|
6109
|
+
return { ok: false, reason: "write-failed", error: msg };
|
|
6110
|
+
}
|
|
6111
|
+
}
|
|
6112
|
+
function setPublicAgentEnabled(accountDir, enabled, target) {
|
|
6113
|
+
const scope = publicAgentScopeLabel(target);
|
|
6114
|
+
const resolvedKey = publicAgentKey(target);
|
|
6115
|
+
if ("ok" in resolvedKey) {
|
|
6116
|
+
console.error(`${TAG10} op=set-public-agent-enabled accountId=${scope} ok=false reason=${resolvedKey.reason}`);
|
|
6117
|
+
return resolvedKey;
|
|
6118
|
+
}
|
|
6119
|
+
const key = resolvedKey.key;
|
|
6120
|
+
if (enabled) {
|
|
6121
|
+
const resolved = key ? resolvePublicAgent(accountDir, { accountId: key, isHouse: false }) : resolvePublicAgent(accountDir, { accountId: "", isHouse: true });
|
|
6122
|
+
if (!resolved) {
|
|
6123
|
+
return {
|
|
6124
|
+
ok: false,
|
|
6125
|
+
reason: "no-public-agent",
|
|
6126
|
+
error: `Cannot enable public answering for ${scope}: no public agent is configured. Set one with set-public-agent first.`
|
|
6127
|
+
};
|
|
6128
|
+
}
|
|
6129
|
+
const agentConfigPath = join12(target.agentsDir, "agents", resolved.slug, "config.json");
|
|
6130
|
+
if (!existsSync6(agentConfigPath)) {
|
|
6131
|
+
return {
|
|
6132
|
+
ok: false,
|
|
6133
|
+
reason: "agent-not-found",
|
|
6134
|
+
error: `Cannot enable public answering for ${scope}: the configured agent "${resolved.slug}" has no config.json at ${agentConfigPath}. Point publicAgent at an existing agent first.`
|
|
6135
|
+
};
|
|
6136
|
+
}
|
|
6137
|
+
}
|
|
6138
|
+
try {
|
|
6139
|
+
const config = readConfig(accountDir);
|
|
6140
|
+
if (!config.whatsapp || typeof config.whatsapp !== "object") {
|
|
6141
|
+
config.whatsapp = {};
|
|
6142
|
+
}
|
|
6143
|
+
const wa = config.whatsapp;
|
|
6144
|
+
if (key) {
|
|
6145
|
+
if (!wa.accounts || typeof wa.accounts !== "object") wa.accounts = {};
|
|
6146
|
+
const accounts = wa.accounts;
|
|
6147
|
+
if (!accounts[key] || typeof accounts[key] !== "object") accounts[key] = {};
|
|
6148
|
+
accounts[key].publicAgentEnabled = enabled;
|
|
6149
|
+
} else {
|
|
6150
|
+
wa.publicAgentEnabled = enabled;
|
|
6151
|
+
}
|
|
6152
|
+
const parsed = WhatsAppConfigSchema.safeParse(wa);
|
|
6153
|
+
if (!parsed.success) {
|
|
6154
|
+
const msg = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
6155
|
+
return { ok: false, reason: "validation-failed", error: `Validation failed: ${msg}` };
|
|
6156
|
+
}
|
|
6157
|
+
config.whatsapp = parsed.data;
|
|
6158
|
+
writeConfig(accountDir, config);
|
|
6159
|
+
console.error(
|
|
6160
|
+
`${TAG10} op=set-public-agent-enabled accountId=${target.scope === "top-level" ? "top-level" : target.accountId} key=${key ?? "top-level"} enabled=${enabled} ok=true`
|
|
6161
|
+
);
|
|
6162
|
+
reloadManagerConfig(accountDir);
|
|
6163
|
+
return {
|
|
6164
|
+
ok: true,
|
|
6165
|
+
key,
|
|
6166
|
+
message: enabled ? `Public answering enabled for ${scope}. Non-admin WhatsApp senders will be answered by the configured public agent.` : `Public answering disabled for ${scope}. Non-admin WhatsApp senders receive no reply; account managers are still notified.`
|
|
6167
|
+
};
|
|
6168
|
+
} catch (err) {
|
|
6169
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6170
|
+
console.error(`${TAG10} op=set-public-agent-enabled ok=false reason=write-failed detail=${msg}`);
|
|
6171
|
+
return { ok: false, reason: "write-failed", error: msg };
|
|
6065
6172
|
}
|
|
6066
6173
|
}
|
|
6067
6174
|
function resolvePublicAgent(accountDir, opts) {
|
|
@@ -6075,6 +6182,7 @@ function resolvePublicAgent(accountDir, opts) {
|
|
|
6075
6182
|
if (typeof accountSlug === "string" && accountSlug.trim()) {
|
|
6076
6183
|
return { slug: accountSlug.trim(), source: "account" };
|
|
6077
6184
|
}
|
|
6185
|
+
if (!opts.isHouse) return null;
|
|
6078
6186
|
const topSlug = wa.publicAgent;
|
|
6079
6187
|
if (typeof topSlug === "string" && topSlug.trim()) {
|
|
6080
6188
|
return { slug: topSlug.trim(), source: "top-level" };
|
|
@@ -6084,6 +6192,25 @@ function resolvePublicAgent(accountDir, opts) {
|
|
|
6084
6192
|
return null;
|
|
6085
6193
|
}
|
|
6086
6194
|
}
|
|
6195
|
+
function resolvePublicAgentEnabled(accountDir, opts) {
|
|
6196
|
+
try {
|
|
6197
|
+
const config = readConfig(accountDir);
|
|
6198
|
+
const wa = config.whatsapp;
|
|
6199
|
+
if (!wa) return { enabled: false, source: "default" };
|
|
6200
|
+
const accounts = wa.accounts;
|
|
6201
|
+
const account = accounts?.[opts.accountId];
|
|
6202
|
+
if (typeof account?.publicAgentEnabled === "boolean") {
|
|
6203
|
+
return { enabled: account.publicAgentEnabled, source: "account" };
|
|
6204
|
+
}
|
|
6205
|
+
if (!opts.isHouse) return { enabled: false, source: "default" };
|
|
6206
|
+
if (typeof wa.publicAgentEnabled === "boolean") {
|
|
6207
|
+
return { enabled: wa.publicAgentEnabled, source: "top-level" };
|
|
6208
|
+
}
|
|
6209
|
+
return { enabled: false, source: "default" };
|
|
6210
|
+
} catch {
|
|
6211
|
+
return { enabled: false, source: "default" };
|
|
6212
|
+
}
|
|
6213
|
+
}
|
|
6087
6214
|
function updateConfig(accountDir, fields) {
|
|
6088
6215
|
const fieldNames = Object.keys(fields);
|
|
6089
6216
|
if (fieldNames.length === 0) {
|
|
@@ -7312,7 +7439,7 @@ app3.post("/reconnect", async (c) => {
|
|
|
7312
7439
|
app3.post("/config", async (c) => {
|
|
7313
7440
|
try {
|
|
7314
7441
|
const body = await c.req.json().catch(() => ({}));
|
|
7315
|
-
const { action, phone, slug, fields, accountId, managesAccount, mode, policy, party, account: partyAccount } = body;
|
|
7442
|
+
const { action, phone, slug, fields, accountId, managesAccount, mode, policy, party, account: partyAccount, enabled } = body;
|
|
7316
7443
|
if (!action || typeof action !== "string") {
|
|
7317
7444
|
return c.json({ ok: false, error: 'Missing required field "action".' }, 400);
|
|
7318
7445
|
}
|
|
@@ -7357,6 +7484,65 @@ app3.post("/config", async (c) => {
|
|
|
7357
7484
|
console.error(`${TAG15} config action=set-account-policy account=${target} ok=${result.ok}${result.ok ? "" : ` reason=${result.reason}`}`);
|
|
7358
7485
|
return c.json(result, result.ok ? 200 : 400);
|
|
7359
7486
|
}
|
|
7487
|
+
if (action === "set-public-agent" || action === "get-public-agent" || action === "set-public-agent-enabled" || action === "list-public-agents") {
|
|
7488
|
+
const acct = resolveAccount();
|
|
7489
|
+
if (!acct) return c.json({ ok: false, error: "No account configured." }, 500);
|
|
7490
|
+
const resolved = resolveLifecycleAccountId(c, accountId);
|
|
7491
|
+
const topLevel = resolved.targetSource === "house-default";
|
|
7492
|
+
if (topLevel) {
|
|
7493
|
+
const denial2 = houseSocketScopeDenial(c, `config action=${action}`);
|
|
7494
|
+
if (denial2) return denial2;
|
|
7495
|
+
} else {
|
|
7496
|
+
const denial2 = selfOrHouseScopeDenial(c, resolved.accountId, `config action=${action}`, resolved.targetSource);
|
|
7497
|
+
if (denial2) return denial2;
|
|
7498
|
+
}
|
|
7499
|
+
const targetDir = topLevel ? acct.accountDir : listValidAccounts().find((a) => a.accountId === resolved.accountId)?.accountDir;
|
|
7500
|
+
if (!targetDir) {
|
|
7501
|
+
return c.json({ ok: false, error: `Account "${resolved.accountId}" is not provisioned on this install.` }, 400);
|
|
7502
|
+
}
|
|
7503
|
+
const writeTarget = topLevel ? { scope: "top-level", agentsDir: targetDir } : { scope: "account", accountId: resolved.accountId, agentsDir: targetDir, ctx: accountPolicyContext() };
|
|
7504
|
+
if (action === "set-public-agent") {
|
|
7505
|
+
if (!slug || typeof slug !== "string") {
|
|
7506
|
+
return c.json({ ok: false, error: 'Missing required field "slug" (the agent directory name, e.g. "my-agent").' }, 400);
|
|
7507
|
+
}
|
|
7508
|
+
const result = setPublicAgent(acct.accountDir, slug, writeTarget);
|
|
7509
|
+
return c.json(result, result.ok ? 200 : 400);
|
|
7510
|
+
}
|
|
7511
|
+
if (action === "set-public-agent-enabled") {
|
|
7512
|
+
if (typeof enabled !== "boolean") {
|
|
7513
|
+
return c.json({ ok: false, error: 'Missing required field "enabled" (true or false).' }, 400);
|
|
7514
|
+
}
|
|
7515
|
+
const result = setPublicAgentEnabled(acct.accountDir, enabled, writeTarget);
|
|
7516
|
+
return c.json(result, result.ok ? 200 : 400);
|
|
7517
|
+
}
|
|
7518
|
+
if (action === "get-public-agent") {
|
|
7519
|
+
const readKey2 = topLevel ? "default" : resolved.accountId;
|
|
7520
|
+
const resolvedAgent = resolvePublicAgent(acct.accountDir, { accountId: readKey2, isHouse: topLevel });
|
|
7521
|
+
console.error(`${TAG15} config action=get-public-agent accountId=${topLevel ? "top-level" : resolved.accountId} slug=${resolvedAgent?.slug ?? "none"} source=${resolvedAgent?.source ?? "none"}`);
|
|
7522
|
+
return c.json({ ok: true, slug: resolvedAgent?.slug ?? null, source: resolvedAgent?.source ?? null });
|
|
7523
|
+
}
|
|
7524
|
+
const agentsDir = resolve7(targetDir, "agents");
|
|
7525
|
+
const agents = [];
|
|
7526
|
+
if (existsSync8(agentsDir)) {
|
|
7527
|
+
try {
|
|
7528
|
+
for (const entry of readdirSync7(agentsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
7529
|
+
if (!entry.isDirectory() || entry.name === "admin") continue;
|
|
7530
|
+
const configPath3 = resolve7(agentsDir, entry.name, "config.json");
|
|
7531
|
+
if (!existsSync8(configPath3)) continue;
|
|
7532
|
+
try {
|
|
7533
|
+
const parsed = JSON.parse(readFileSync10(configPath3, "utf-8"));
|
|
7534
|
+
agents.push({ slug: entry.name, displayName: parsed.displayName ?? entry.name });
|
|
7535
|
+
} catch {
|
|
7536
|
+
console.error(`${TAG15} config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
|
|
7537
|
+
}
|
|
7538
|
+
}
|
|
7539
|
+
} catch (err) {
|
|
7540
|
+
console.error(`${TAG15} config action=list-public-agents error="failed to scan agents directory: ${String(err)}"`);
|
|
7541
|
+
}
|
|
7542
|
+
}
|
|
7543
|
+
console.error(`${TAG15} config action=list-public-agents accountId=${topLevel ? "top-level" : resolved.accountId} count=${agents.length}`);
|
|
7544
|
+
return c.json({ ok: true, agents });
|
|
7545
|
+
}
|
|
7360
7546
|
if (action === "add-account-manager" || action === "remove-account-manager" || action === "list-account-managers") {
|
|
7361
7547
|
const acct = resolveAccount();
|
|
7362
7548
|
if (!acct) return c.json({ ok: false, error: "No account configured." }, 500);
|
|
@@ -7468,44 +7654,10 @@ app3.post("/config", async (c) => {
|
|
|
7468
7654
|
// Task 2233 — `add-account-manager`, `remove-account-manager` and
|
|
7469
7655
|
// `list-account-managers` are handled above this switch, on the
|
|
7470
7656
|
// per-binding gate. They remain valid actions; only their gate moved.
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
const result = setPublicAgent(account.accountDir, slug);
|
|
7476
|
-
console.error(`${TAG15} config action=set-public-agent slug=${slug} ok=${result.ok}`);
|
|
7477
|
-
return c.json(result, result.ok ? 200 : 400);
|
|
7478
|
-
}
|
|
7479
|
-
case "get-public-agent": {
|
|
7480
|
-
const targetAccount = typeof accountId === "string" && accountId.trim() ? accountId.trim() : "default";
|
|
7481
|
-
const resolved = resolvePublicAgent(account.accountDir, { accountId: targetAccount });
|
|
7482
|
-
console.error(`${TAG15} config action=get-public-agent accountId=${targetAccount} slug=${resolved?.slug ?? "none"} source=${resolved?.source ?? "none"}`);
|
|
7483
|
-
return c.json({ ok: true, slug: resolved?.slug ?? null, source: resolved?.source ?? null });
|
|
7484
|
-
}
|
|
7485
|
-
case "list-public-agents": {
|
|
7486
|
-
const agentsDir = resolve7(account.accountDir, "agents");
|
|
7487
|
-
const agents = [];
|
|
7488
|
-
if (existsSync8(agentsDir)) {
|
|
7489
|
-
try {
|
|
7490
|
-
const entries2 = readdirSync7(agentsDir, { withFileTypes: true });
|
|
7491
|
-
for (const entry of entries2.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
7492
|
-
if (!entry.isDirectory() || entry.name === "admin") continue;
|
|
7493
|
-
const configPath3 = resolve7(agentsDir, entry.name, "config.json");
|
|
7494
|
-
if (!existsSync8(configPath3)) continue;
|
|
7495
|
-
try {
|
|
7496
|
-
const config = JSON.parse(readFileSync10(configPath3, "utf-8"));
|
|
7497
|
-
agents.push({ slug: entry.name, displayName: config.displayName ?? entry.name });
|
|
7498
|
-
} catch {
|
|
7499
|
-
console.error(`${TAG15} config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
|
|
7500
|
-
}
|
|
7501
|
-
}
|
|
7502
|
-
} catch (err) {
|
|
7503
|
-
console.error(`${TAG15} config action=list-public-agents error="failed to scan agents directory: ${String(err)}"`);
|
|
7504
|
-
}
|
|
7505
|
-
}
|
|
7506
|
-
console.error(`${TAG15} config action=list-public-agents count=${agents.length}`);
|
|
7507
|
-
return c.json({ ok: true, agents });
|
|
7508
|
-
}
|
|
7657
|
+
// Task 2271 — `set-public-agent`, `get-public-agent`,
|
|
7658
|
+
// `set-public-agent-enabled` and `list-public-agents` are handled above
|
|
7659
|
+
// this switch, on the per-account scope gate. They remain valid actions;
|
|
7660
|
+
// only their gate and their target moved.
|
|
7509
7661
|
case "schema": {
|
|
7510
7662
|
const text = serializeWhatsAppSchema();
|
|
7511
7663
|
console.error(`${TAG15} config action=schema`);
|
|
@@ -7549,7 +7701,7 @@ app3.post("/config", async (c) => {
|
|
|
7549
7701
|
}
|
|
7550
7702
|
default:
|
|
7551
7703
|
return c.json(
|
|
7552
|
-
{ ok: false, error: `Unknown action "${action}". Valid actions: add-admin-phone, remove-admin-phone, list-admin-phones, add-account-manager, remove-account-manager, list-account-managers, set-public-agent, get-public-agent, list-public-agents, update-config, get-config, schema, list-groups.` },
|
|
7704
|
+
{ ok: false, error: `Unknown action "${action}". Valid actions: add-admin-phone, remove-admin-phone, list-admin-phones, add-account-manager, remove-account-manager, list-account-managers, set-public-agent, get-public-agent, list-public-agents, set-public-agent-enabled, update-config, get-config, schema, list-groups.` },
|
|
7553
7705
|
400
|
|
7554
7706
|
);
|
|
7555
7707
|
}
|
|
@@ -12246,8 +12398,8 @@ async function reapplyLeversViaManager() {
|
|
|
12246
12398
|
var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
|
|
12247
12399
|
var sendSeq = 0;
|
|
12248
12400
|
function createWebchatRoutes(deps) {
|
|
12249
|
-
const
|
|
12250
|
-
|
|
12401
|
+
const app77 = new Hono();
|
|
12402
|
+
app77.post("/send", requireAdminSession, async (c) => {
|
|
12251
12403
|
let accountId;
|
|
12252
12404
|
try {
|
|
12253
12405
|
accountId = resolvePlatformAccountId();
|
|
@@ -12445,7 +12597,7 @@ ${note}` : note;
|
|
|
12445
12597
|
if (turnTimer.unref) turnTimer.unref();
|
|
12446
12598
|
return c.json({ ok: true });
|
|
12447
12599
|
});
|
|
12448
|
-
|
|
12600
|
+
app77.post("/interrupt", requireAdminSession, async (c) => {
|
|
12449
12601
|
const cacheKey = c.get("cacheKey");
|
|
12450
12602
|
const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
|
|
12451
12603
|
const primaryUserId = resolvePrimaryAdminUserId();
|
|
@@ -12473,7 +12625,7 @@ ${note}` : note;
|
|
|
12473
12625
|
}
|
|
12474
12626
|
return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
|
|
12475
12627
|
});
|
|
12476
|
-
|
|
12628
|
+
app77.post("/settings", requireAdminSession, async (c) => {
|
|
12477
12629
|
const body = await c.req.json().catch(() => null);
|
|
12478
12630
|
const op = body?.op;
|
|
12479
12631
|
const value = body?.value;
|
|
@@ -12509,7 +12661,7 @@ ${note}` : note;
|
|
|
12509
12661
|
console.log(`[webchat:settings] op=${op} outcome=accepted accountId=${account.accountId.slice(0, 8)} value=${value} settingsApplied=${settingsApplied}`);
|
|
12510
12662
|
return c.json({ ok: true, settingsApplied });
|
|
12511
12663
|
});
|
|
12512
|
-
|
|
12664
|
+
app77.get("/session", requireAdminSession, async (c) => {
|
|
12513
12665
|
let accountId;
|
|
12514
12666
|
try {
|
|
12515
12667
|
accountId = resolvePlatformAccountId();
|
|
@@ -12582,7 +12734,7 @@ ${note}` : note;
|
|
|
12582
12734
|
const indicators = await fetchComposerIndicators(sessionId);
|
|
12583
12735
|
return c.json({ sessionId, projectDir, source, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
|
|
12584
12736
|
});
|
|
12585
|
-
|
|
12737
|
+
app77.post("/permission-verdict", requireAdminSession, async (c) => {
|
|
12586
12738
|
const body = await c.req.json().catch(() => null);
|
|
12587
12739
|
const sessionId = body?.sessionId;
|
|
12588
12740
|
const requestId = body?.request_id;
|
|
@@ -12599,7 +12751,7 @@ ${note}` : note;
|
|
|
12599
12751
|
const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
|
|
12600
12752
|
return c.json({ ok });
|
|
12601
12753
|
});
|
|
12602
|
-
return
|
|
12754
|
+
return app77;
|
|
12603
12755
|
}
|
|
12604
12756
|
|
|
12605
12757
|
// server/routes/webchat-greeting.ts
|
|
@@ -16730,18 +16882,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
16730
16882
|
]);
|
|
16731
16883
|
var app24 = new Hono();
|
|
16732
16884
|
app24.post("/", async (c) => {
|
|
16733
|
-
const
|
|
16885
|
+
const TAG52 = "[admin:events]";
|
|
16734
16886
|
let body;
|
|
16735
16887
|
try {
|
|
16736
16888
|
body = await c.req.json();
|
|
16737
16889
|
} catch (err) {
|
|
16738
16890
|
const detail = err instanceof Error ? err.message : String(err);
|
|
16739
|
-
console.error(`${
|
|
16891
|
+
console.error(`${TAG52} reject reason=body-not-json detail=${detail}`);
|
|
16740
16892
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
16741
16893
|
}
|
|
16742
16894
|
const event = typeof body.event === "string" ? body.event : "";
|
|
16743
16895
|
if (!ALLOWED_EVENTS.has(event)) {
|
|
16744
|
-
console.error(`${
|
|
16896
|
+
console.error(`${TAG52} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
16745
16897
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
16746
16898
|
}
|
|
16747
16899
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -22182,10 +22334,13 @@ async function managerSpawn(opts) {
|
|
|
22182
22334
|
visitorId: opts.visitorId,
|
|
22183
22335
|
name: opts.name,
|
|
22184
22336
|
webchatChannel: opts.webchatChannel,
|
|
22337
|
+
waChannel: opts.waChannel,
|
|
22338
|
+
sessionId: opts.sessionId,
|
|
22185
22339
|
previousContext: opts.previousContext,
|
|
22186
22340
|
initialMessage: opts.initialMessage,
|
|
22187
22341
|
passive: opts.passive,
|
|
22188
|
-
targetAccountId: opts.targetAccountId
|
|
22342
|
+
targetAccountId: opts.targetAccountId,
|
|
22343
|
+
agentAccountId: opts.agentAccountId
|
|
22189
22344
|
})
|
|
22190
22345
|
}).catch((err) => ({ __throw: err instanceof Error ? err.message : String(err) }));
|
|
22191
22346
|
if ("__throw" in res) {
|
|
@@ -22908,10 +23063,35 @@ app48.post("/screencast-event", requireAdminSession, async (c) => {
|
|
|
22908
23063
|
screencastLog(parsed.op, parsed.detail);
|
|
22909
23064
|
return c.json({ ok: true });
|
|
22910
23065
|
});
|
|
23066
|
+
app48.post("/tabs", requireAdminSession, async (c) => {
|
|
23067
|
+
tabsLog("create");
|
|
23068
|
+
const result = await createPageTarget({ fetchImpl: fetch, cdpPort: CDP_PORT, platform: process.platform });
|
|
23069
|
+
if (!result.ok) {
|
|
23070
|
+
tabsLog("create-failed", { status: result.status, error: result.error });
|
|
23071
|
+
return c.json({ ok: false, error: result.error }, result.status);
|
|
23072
|
+
}
|
|
23073
|
+
tabsLog("created", { targetId: result.id });
|
|
23074
|
+
return c.json({ ok: true, id: result.id });
|
|
23075
|
+
});
|
|
23076
|
+
app48.delete("/tabs/:id", requireAdminSession, async (c) => {
|
|
23077
|
+
const targetId = c.req.param("id");
|
|
23078
|
+
tabsLog("close", { targetId });
|
|
23079
|
+
const result = await closePageTarget(
|
|
23080
|
+
{ fetchImpl: fetch, cdpPort: CDP_PORT, platform: process.platform },
|
|
23081
|
+
targetId
|
|
23082
|
+
);
|
|
23083
|
+
if (!result.ok) {
|
|
23084
|
+
tabsLog("close-failed", { status: result.status, error: result.error });
|
|
23085
|
+
return c.json({ ok: false, error: result.error }, result.status);
|
|
23086
|
+
}
|
|
23087
|
+
tabsLog("closed", { targetId });
|
|
23088
|
+
return c.json({ ok: true });
|
|
23089
|
+
});
|
|
22911
23090
|
var browser_default = app48;
|
|
22912
23091
|
|
|
22913
23092
|
// server/routes/admin/calendar.ts
|
|
22914
23093
|
import { existsSync as existsSync39 } from "fs";
|
|
23094
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
22915
23095
|
import { join as join45 } from "path";
|
|
22916
23096
|
|
|
22917
23097
|
// server/lib/calendar-ics.ts
|
|
@@ -23053,6 +23233,86 @@ function readAvailabilityConfig(accountDir) {
|
|
|
23053
23233
|
return cfg;
|
|
23054
23234
|
}
|
|
23055
23235
|
|
|
23236
|
+
// server/lib/calendar-slots.ts
|
|
23237
|
+
var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
23238
|
+
function tzOffsetMs(instant, timeZone) {
|
|
23239
|
+
const dtf = new Intl.DateTimeFormat("en-US", {
|
|
23240
|
+
timeZone,
|
|
23241
|
+
hour12: false,
|
|
23242
|
+
year: "numeric",
|
|
23243
|
+
month: "2-digit",
|
|
23244
|
+
day: "2-digit",
|
|
23245
|
+
hour: "2-digit",
|
|
23246
|
+
minute: "2-digit",
|
|
23247
|
+
second: "2-digit"
|
|
23248
|
+
});
|
|
23249
|
+
const parts = {};
|
|
23250
|
+
for (const p of dtf.formatToParts(instant)) parts[p.type] = p.value;
|
|
23251
|
+
let hour = Number(parts.hour);
|
|
23252
|
+
if (hour === 24) hour = 0;
|
|
23253
|
+
const asUTC = Date.UTC(
|
|
23254
|
+
Number(parts.year),
|
|
23255
|
+
Number(parts.month) - 1,
|
|
23256
|
+
Number(parts.day),
|
|
23257
|
+
hour,
|
|
23258
|
+
Number(parts.minute),
|
|
23259
|
+
Number(parts.second)
|
|
23260
|
+
);
|
|
23261
|
+
return asUTC - instant.getTime();
|
|
23262
|
+
}
|
|
23263
|
+
function zonedWallClockToUtc(y, m, d, hh, mm, timeZone) {
|
|
23264
|
+
const naiveUtc = Date.UTC(y, m - 1, d, hh, mm, 0, 0);
|
|
23265
|
+
const offset = tzOffsetMs(new Date(naiveUtc), timeZone);
|
|
23266
|
+
return new Date(naiveUtc - offset);
|
|
23267
|
+
}
|
|
23268
|
+
function tzCalendarDate(instant, timeZone) {
|
|
23269
|
+
const dtf = new Intl.DateTimeFormat("en-US", {
|
|
23270
|
+
timeZone,
|
|
23271
|
+
year: "numeric",
|
|
23272
|
+
month: "2-digit",
|
|
23273
|
+
day: "2-digit"
|
|
23274
|
+
});
|
|
23275
|
+
const parts = {};
|
|
23276
|
+
for (const p of dtf.formatToParts(instant)) parts[p.type] = p.value;
|
|
23277
|
+
return { y: Number(parts.year), m: Number(parts.month), d: Number(parts.day) };
|
|
23278
|
+
}
|
|
23279
|
+
function parseHHMM(s) {
|
|
23280
|
+
const [hh, mm] = s.split(":").map(Number);
|
|
23281
|
+
return { hh, mm };
|
|
23282
|
+
}
|
|
23283
|
+
function computeOpenSlots(config, busy, fromISO, toISO) {
|
|
23284
|
+
const tz = config.timezone;
|
|
23285
|
+
const durMs = config.durationMins * 6e4;
|
|
23286
|
+
const bufMs = config.bufferMins * 6e4;
|
|
23287
|
+
const from = new Date(fromISO).getTime();
|
|
23288
|
+
const to = new Date(toISO).getTime();
|
|
23289
|
+
const busyMs = busy.map((b) => ({ start: new Date(b.start).getTime(), end: new Date(b.end).getTime() }));
|
|
23290
|
+
const slots = [];
|
|
23291
|
+
const firstDate = tzCalendarDate(new Date(from), tz);
|
|
23292
|
+
let dayMidnight = zonedWallClockToUtc(firstDate.y, firstDate.m, firstDate.d, 0, 0, tz);
|
|
23293
|
+
for (let guard = 0; guard < 400 && dayMidnight.getTime() < to; guard++) {
|
|
23294
|
+
const { y, m, d } = tzCalendarDate(dayMidnight, tz);
|
|
23295
|
+
const weekday = WEEKDAYS[new Date(Date.UTC(y, m - 1, d)).getUTCDay()];
|
|
23296
|
+
const windows = config.weekly[weekday] ?? [];
|
|
23297
|
+
for (const [openStr, closeStr] of windows) {
|
|
23298
|
+
const open3 = parseHHMM(openStr);
|
|
23299
|
+
const close = parseHHMM(closeStr);
|
|
23300
|
+
const openUtc = zonedWallClockToUtc(y, m, d, open3.hh, open3.mm, tz).getTime();
|
|
23301
|
+
const closeUtc = zonedWallClockToUtc(y, m, d, close.hh, close.mm, tz).getTime();
|
|
23302
|
+
for (let s = openUtc; s + durMs <= closeUtc; s += durMs) {
|
|
23303
|
+
const slotEnd = s + durMs;
|
|
23304
|
+
if (s < from || s >= to) continue;
|
|
23305
|
+
const blocked = busyMs.some((b) => b.start < slotEnd + bufMs && b.end > s - bufMs);
|
|
23306
|
+
if (blocked) continue;
|
|
23307
|
+
slots.push({ start: new Date(s).toISOString(), end: new Date(slotEnd).toISOString() });
|
|
23308
|
+
}
|
|
23309
|
+
}
|
|
23310
|
+
const next = tzCalendarDate(new Date(dayMidnight.getTime() + 26 * 36e5), tz);
|
|
23311
|
+
dayMidnight = zonedWallClockToUtc(next.y, next.m, next.d, 0, 0, tz);
|
|
23312
|
+
}
|
|
23313
|
+
return slots;
|
|
23314
|
+
}
|
|
23315
|
+
|
|
23056
23316
|
// server/routes/admin/calendar.ts
|
|
23057
23317
|
var app49 = new Hono();
|
|
23058
23318
|
function normalizeAttendees(raw) {
|
|
@@ -23066,6 +23326,19 @@ function normalizeAttendees(raw) {
|
|
|
23066
23326
|
});
|
|
23067
23327
|
}
|
|
23068
23328
|
var EDITABLE_FIELDS = ["title", "startsAt", "endsAt", "location", "privateNote"];
|
|
23329
|
+
var CREATE_FIELDS = EDITABLE_FIELDS;
|
|
23330
|
+
function buildCreateParams(accountId, body) {
|
|
23331
|
+
const params = {
|
|
23332
|
+
accountId,
|
|
23333
|
+
uid: randomUUID10(),
|
|
23334
|
+
source: "admin-ui",
|
|
23335
|
+
createdBySource: "admin-ui",
|
|
23336
|
+
scope: "admin",
|
|
23337
|
+
isAllDay: body.isAllDay === true
|
|
23338
|
+
};
|
|
23339
|
+
for (const f of CREATE_FIELDS) params[f] = f in body ? body[f] : null;
|
|
23340
|
+
return params;
|
|
23341
|
+
}
|
|
23069
23342
|
var MEETING_COLS = `elementId(m) AS id, m.title AS title,
|
|
23070
23343
|
toString(m.startsAt) AS startsAt, toString(m.endsAt) AS endsAt,
|
|
23071
23344
|
m.location AS location, coalesce(m.isAllDay, false) AS isAllDay,
|
|
@@ -23144,41 +23417,136 @@ app49.get("/meetings", requireAdminSession, async (c) => {
|
|
|
23144
23417
|
await session.close();
|
|
23145
23418
|
}
|
|
23146
23419
|
});
|
|
23147
|
-
|
|
23148
|
-
const slug = (title ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
|
|
23149
|
-
return `${slug || "meeting"}.ics`;
|
|
23150
|
-
}
|
|
23151
|
-
app49.get("/meetings/:id/ics", requireAdminSession, async (c) => {
|
|
23420
|
+
app49.get("/free-busy", requireAdminSession, async (c) => {
|
|
23152
23421
|
const cacheKey = c.var.cacheKey;
|
|
23153
|
-
const
|
|
23154
|
-
if (!
|
|
23155
|
-
console.error('[calendar] op=
|
|
23422
|
+
const account = accountDirForSession(cacheKey);
|
|
23423
|
+
if (!account) {
|
|
23424
|
+
console.error('[calendar] op=admin-free-busy auth-rejected reason="no account for session"');
|
|
23156
23425
|
return c.json({ error: "Account not found for session" }, 401);
|
|
23157
23426
|
}
|
|
23158
|
-
const
|
|
23159
|
-
const
|
|
23160
|
-
|
|
23427
|
+
const { accountId, accountDir } = account;
|
|
23428
|
+
const from = c.req.query("from");
|
|
23429
|
+
const to = c.req.query("to");
|
|
23430
|
+
if (!from || !to) return c.json({ error: "from and to (ISO) required" }, 400);
|
|
23431
|
+
let config;
|
|
23432
|
+
try {
|
|
23433
|
+
config = readAvailabilityConfig(accountDir);
|
|
23434
|
+
} catch (err) {
|
|
23435
|
+
console.log(`[calendar] op=admin-free-busy gapSource=none reason="${err.message}"`);
|
|
23436
|
+
return c.json({ slots: [], gapSource: "none" });
|
|
23437
|
+
}
|
|
23161
23438
|
const session = getSession();
|
|
23162
23439
|
try {
|
|
23163
23440
|
const res = await session.run(
|
|
23164
23441
|
`MATCH (m:Meeting {accountId: $accountId})
|
|
23165
|
-
WHERE
|
|
23166
|
-
|
|
23167
|
-
|
|
23442
|
+
WHERE NOT (m.endsAt IS NOT NULL AND m.endsAt <= datetime($from))
|
|
23443
|
+
AND m.startsAt < datetime($to)
|
|
23444
|
+
RETURN toString(m.startsAt) AS start, toString(m.endsAt) AS end
|
|
23445
|
+
UNION
|
|
23446
|
+
MATCH (b:ConnectorBusy {accountId: $accountId})
|
|
23447
|
+
WHERE b.endsAt > datetime($from) AND b.startsAt < datetime($to)
|
|
23448
|
+
RETURN toString(b.startsAt) AS start, toString(b.endsAt) AS end`,
|
|
23449
|
+
{ accountId, from, to }
|
|
23168
23450
|
);
|
|
23169
|
-
|
|
23170
|
-
|
|
23171
|
-
|
|
23172
|
-
|
|
23173
|
-
|
|
23174
|
-
|
|
23175
|
-
|
|
23176
|
-
|
|
23177
|
-
const
|
|
23178
|
-
|
|
23179
|
-
|
|
23180
|
-
|
|
23181
|
-
|
|
23451
|
+
const busy = res.records.map((r) => {
|
|
23452
|
+
const start = r.get("start");
|
|
23453
|
+
const rawEnd = r.get("end");
|
|
23454
|
+
return {
|
|
23455
|
+
start,
|
|
23456
|
+
end: rawEnd ?? new Date(new Date(start).getTime() + config.durationMins * 6e4).toISOString()
|
|
23457
|
+
};
|
|
23458
|
+
});
|
|
23459
|
+
const slots = computeOpenSlots(config, busy, from, to);
|
|
23460
|
+
console.log(`[calendar] op=admin-free-busy gapSource=config slots=${slots.length} range=${from}..${to}`);
|
|
23461
|
+
return c.json({ durationMins: config.durationMins, timezone: config.timezone, slots, gapSource: "config" });
|
|
23462
|
+
} catch (err) {
|
|
23463
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23464
|
+
console.error(`[calendar] op=admin-free-busy-fail err="${message}"`);
|
|
23465
|
+
return c.json({ error: `Availability unavailable: ${message}` }, 503);
|
|
23466
|
+
} finally {
|
|
23467
|
+
await session.close();
|
|
23468
|
+
}
|
|
23469
|
+
});
|
|
23470
|
+
app49.post("/meetings", requireAdminSession, async (c) => {
|
|
23471
|
+
const cacheKey = c.var.cacheKey;
|
|
23472
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
23473
|
+
if (!accountId) {
|
|
23474
|
+
console.error('[admin:calendar] op=create auth-rejected reason="no account for session"');
|
|
23475
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
23476
|
+
}
|
|
23477
|
+
const body = await safeJson(c) ?? {};
|
|
23478
|
+
if (typeof body.title !== "string" || body.title.trim() === "") {
|
|
23479
|
+
return c.json({ error: "title is required" }, 400);
|
|
23480
|
+
}
|
|
23481
|
+
if (typeof body.startsAt !== "string" || Number.isNaN(Date.parse(body.startsAt))) {
|
|
23482
|
+
return c.json({ error: "startsAt must be a parseable ISO timestamp" }, 400);
|
|
23483
|
+
}
|
|
23484
|
+
if (body.endsAt != null && (typeof body.endsAt !== "string" || Number.isNaN(Date.parse(body.endsAt)))) {
|
|
23485
|
+
return c.json({ error: "endsAt must be a parseable ISO timestamp" }, 400);
|
|
23486
|
+
}
|
|
23487
|
+
const params = buildCreateParams(accountId, body);
|
|
23488
|
+
const session = getSession();
|
|
23489
|
+
try {
|
|
23490
|
+
const res = await session.run(
|
|
23491
|
+
`CREATE (m:Meeting {
|
|
23492
|
+
accountId: $accountId, uid: $uid, title: $title,
|
|
23493
|
+
startsAt: datetime($startsAt),
|
|
23494
|
+
endsAt: CASE WHEN $endsAt IS NULL THEN null ELSE datetime($endsAt) END,
|
|
23495
|
+
location: $location, privateNote: $privateNote, isAllDay: $isAllDay,
|
|
23496
|
+
source: $source, createdBySource: $createdBySource, scope: $scope,
|
|
23497
|
+
createdAt: datetime(), updatedAt: datetime()
|
|
23498
|
+
})
|
|
23499
|
+
${MEETING_RETURN}`,
|
|
23500
|
+
params
|
|
23501
|
+
);
|
|
23502
|
+
const meeting = mapMeeting(res.records[0]);
|
|
23503
|
+
console.log(
|
|
23504
|
+
`[admin:calendar] op=create accountId=${accountId.slice(0, 8)} meetingId=${meeting.meetingId} uid=${params.uid} outcome=created`
|
|
23505
|
+
);
|
|
23506
|
+
return c.json({ meeting }, 201);
|
|
23507
|
+
} catch (err) {
|
|
23508
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23509
|
+
console.error(`[admin:calendar] op=create outcome=failed err="${message}"`);
|
|
23510
|
+
return c.json({ error: `Create failed: ${message}` }, 503);
|
|
23511
|
+
} finally {
|
|
23512
|
+
await session.close();
|
|
23513
|
+
}
|
|
23514
|
+
});
|
|
23515
|
+
function icsFilename(title) {
|
|
23516
|
+
const slug = (title ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
|
|
23517
|
+
return `${slug || "meeting"}.ics`;
|
|
23518
|
+
}
|
|
23519
|
+
app49.get("/meetings/:id/ics", requireAdminSession, async (c) => {
|
|
23520
|
+
const cacheKey = c.var.cacheKey;
|
|
23521
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
23522
|
+
if (!accountId) {
|
|
23523
|
+
console.error('[calendar] op=ics auth-rejected reason="no account for session"');
|
|
23524
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
23525
|
+
}
|
|
23526
|
+
const id = c.req.param("id");
|
|
23527
|
+
const includeAttendees = c.req.query("attendees") === "1";
|
|
23528
|
+
console.log(`[calendar] op=ics-request id=${id} attendees=${includeAttendees}`);
|
|
23529
|
+
const session = getSession();
|
|
23530
|
+
try {
|
|
23531
|
+
const res = await session.run(
|
|
23532
|
+
`MATCH (m:Meeting {accountId: $accountId})
|
|
23533
|
+
WHERE elementId(m) = $id
|
|
23534
|
+
${MEETING_RETURN}`,
|
|
23535
|
+
{ accountId, id }
|
|
23536
|
+
);
|
|
23537
|
+
if (res.records.length === 0) {
|
|
23538
|
+
console.warn(`[calendar] op=ics-404 id=${id} reason="no meeting for account"`);
|
|
23539
|
+
return c.json({ error: "Meeting not found for this account" }, 404);
|
|
23540
|
+
}
|
|
23541
|
+
const r = res.records[0];
|
|
23542
|
+
const mapped = mapMeeting(r);
|
|
23543
|
+
const uid = r.get("uid") ?? null;
|
|
23544
|
+
const corr = uid ?? mapped.meetingId;
|
|
23545
|
+
const input = {
|
|
23546
|
+
uid,
|
|
23547
|
+
id: mapped.meetingId,
|
|
23548
|
+
title: mapped.title,
|
|
23549
|
+
startsAt: mapped.startsAt,
|
|
23182
23550
|
endsAt: mapped.endsAt,
|
|
23183
23551
|
location: mapped.location,
|
|
23184
23552
|
isAllDay: mapped.isAllDay,
|
|
@@ -24477,6 +24845,32 @@ async function computeTaskList(accountId) {
|
|
|
24477
24845
|
`${TAG29} op=session-orphans account=${accountId} orphans=${orphans} detail="task marked for a session spawn that never linked; the spawned session is unreachable from its row"`
|
|
24478
24846
|
);
|
|
24479
24847
|
}
|
|
24848
|
+
let orphanEntries = 0;
|
|
24849
|
+
let orphanAdjustments = 0;
|
|
24850
|
+
try {
|
|
24851
|
+
const orphanTime = await session.run(
|
|
24852
|
+
`OPTIONAL MATCH (te:TimeEntry {accountId: $accountId})
|
|
24853
|
+
WHERE NOT EXISTS { MATCH (:Task {taskId: te.taskId, accountId: $accountId}) }
|
|
24854
|
+
WITH count(te) AS orphanEntries
|
|
24855
|
+
OPTIONAL MATCH (ta:TimeAdjustment {accountId: $accountId})
|
|
24856
|
+
WHERE NOT EXISTS { MATCH (:Task {taskId: ta.taskId, accountId: $accountId}) }
|
|
24857
|
+
RETURN orphanEntries, count(ta) AS orphanAdjustments`,
|
|
24858
|
+
{ accountId }
|
|
24859
|
+
);
|
|
24860
|
+
orphanEntries = orphanTime.records.length > 0 ? toNum(orphanTime.records[0].get("orphanEntries")) : 0;
|
|
24861
|
+
orphanAdjustments = orphanTime.records.length > 0 ? toNum(orphanTime.records[0].get("orphanAdjustments")) : 0;
|
|
24862
|
+
} catch (err) {
|
|
24863
|
+
console.error(
|
|
24864
|
+
`${TAG29} op=orphan-time-records-census-failed account=${accountId} error="${err instanceof Error ? err.message : String(err)}"`
|
|
24865
|
+
);
|
|
24866
|
+
orphanEntries = -1;
|
|
24867
|
+
orphanAdjustments = -1;
|
|
24868
|
+
}
|
|
24869
|
+
if (orphanEntries > 0 || orphanAdjustments > 0) {
|
|
24870
|
+
console.error(
|
|
24871
|
+
`${TAG29} op=orphan-time-records account=${accountId} orphanEntries=${orphanEntries} orphanAdjustments=${orphanAdjustments} detail="time records whose task no longer exists; something removed the task without its records"`
|
|
24872
|
+
);
|
|
24873
|
+
}
|
|
24480
24874
|
const linkedIds = [...open3, ...completed].map((r) => r.sessionId).filter((s) => s !== null);
|
|
24481
24875
|
let dangling = null;
|
|
24482
24876
|
const cfg = claudeConfigDir();
|
|
@@ -24526,7 +24920,7 @@ async function computeTaskList(accountId) {
|
|
|
24526
24920
|
var tasks_list_default = app53;
|
|
24527
24921
|
|
|
24528
24922
|
// server/routes/admin/task-timer-start.ts
|
|
24529
|
-
import { randomUUID as
|
|
24923
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
24530
24924
|
var TAG30 = "[task-timer]";
|
|
24531
24925
|
var app54 = new Hono();
|
|
24532
24926
|
app54.post("/", requireAdminSession, async (c) => {
|
|
@@ -24569,7 +24963,7 @@ app54.post("/", requireAdminSession, async (c) => {
|
|
|
24569
24963
|
invalidate("tasks-list", accountId);
|
|
24570
24964
|
return c.json({ ok: true, running: true, entryId: priorEntryId, startedAt: priorStartedAt });
|
|
24571
24965
|
}
|
|
24572
|
-
const entryId =
|
|
24966
|
+
const entryId = randomUUID11();
|
|
24573
24967
|
await session.run(
|
|
24574
24968
|
`MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
24575
24969
|
CREATE (te:TimeEntry {entryId: $entryId, taskId: $taskId, accountId: $accountId, startedAt: $now, endedAt: null})
|
|
@@ -24708,7 +25102,7 @@ app56.post("/", requireAdminSession, async (c) => {
|
|
|
24708
25102
|
var task_complete_default = app56;
|
|
24709
25103
|
|
|
24710
25104
|
// server/routes/admin/task-time-adjust.ts
|
|
24711
|
-
import { randomUUID as
|
|
25105
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
24712
25106
|
import neo4j5 from "neo4j-driver";
|
|
24713
25107
|
var TAG33 = "[task-time-adjust]";
|
|
24714
25108
|
var app57 = new Hono();
|
|
@@ -24734,7 +25128,7 @@ app57.post("/", requireAdminSession, async (c) => {
|
|
|
24734
25128
|
console.error(`${TAG33} op=reject reason=invalid-seconds taskId=${taskId} accountId=${accountId}`);
|
|
24735
25129
|
return c.json({ error: "newSeconds must be a non-negative integer" }, 400);
|
|
24736
25130
|
}
|
|
24737
|
-
const adjustmentId =
|
|
25131
|
+
const adjustmentId = randomUUID12();
|
|
24738
25132
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24739
25133
|
console.log(`${TAG33} op=request adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId} newSeconds=${newSeconds}`);
|
|
24740
25134
|
const session = getSession();
|
|
@@ -24789,6 +25183,112 @@ app57.post("/", requireAdminSession, async (c) => {
|
|
|
24789
25183
|
});
|
|
24790
25184
|
var task_time_adjust_default = app57;
|
|
24791
25185
|
|
|
25186
|
+
// server/routes/admin/task-delete.ts
|
|
25187
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
25188
|
+
var TAG34 = "[task-delete]";
|
|
25189
|
+
var app58 = new Hono();
|
|
25190
|
+
app58.post("/", requireAdminSession, async (c) => {
|
|
25191
|
+
const cacheKey = c.var.cacheKey;
|
|
25192
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
25193
|
+
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
25194
|
+
let body;
|
|
25195
|
+
try {
|
|
25196
|
+
body = await c.req.json();
|
|
25197
|
+
} catch {
|
|
25198
|
+
console.error(`${TAG34} op=reject reason=bad-json`);
|
|
25199
|
+
return c.json({ error: "invalid-json" }, 400);
|
|
25200
|
+
}
|
|
25201
|
+
const deletionId = randomUUID13();
|
|
25202
|
+
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
25203
|
+
if (!taskId) {
|
|
25204
|
+
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
25205
|
+
console.error(`${TAG34} op=reject reason=${reason} deletionId=${deletionId} accountId=${accountId}`);
|
|
25206
|
+
return c.json({ error: "taskId required" }, 400);
|
|
25207
|
+
}
|
|
25208
|
+
console.log(
|
|
25209
|
+
`${TAG34} op=request deletionId=${deletionId} taskId=${taskId} accountId=${accountId} confirmed=${body.confirmed === true}`
|
|
25210
|
+
);
|
|
25211
|
+
const session = getSession();
|
|
25212
|
+
try {
|
|
25213
|
+
const guard = await session.run(
|
|
25214
|
+
`MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
25215
|
+
OPTIONAL MATCH (te:TimeEntry {taskId: $taskId, accountId: $accountId})
|
|
25216
|
+
OPTIONAL MATCH (open:TimeEntry {taskId: $taskId, accountId: $accountId})
|
|
25217
|
+
WHERE open.endedAt IS NULL
|
|
25218
|
+
OPTIONAL MATCH (ta:TimeAdjustment {taskId: $taskId, accountId: $accountId})
|
|
25219
|
+
RETURN count(DISTINCT te) AS timeEntries,
|
|
25220
|
+
count(DISTINCT open) AS openCount,
|
|
25221
|
+
count(DISTINCT ta) AS adjustments`,
|
|
25222
|
+
{ taskId, accountId }
|
|
25223
|
+
);
|
|
25224
|
+
if (guard.records.length === 0) {
|
|
25225
|
+
console.error(`${TAG34} op=reject reason=no-task deletionId=${deletionId} taskId=${taskId} accountId=${accountId}`);
|
|
25226
|
+
return c.json({ error: "task-not-found" }, 404);
|
|
25227
|
+
}
|
|
25228
|
+
const timeEntries = toNum(guard.records[0].get("timeEntries"));
|
|
25229
|
+
const openCount = toNum(guard.records[0].get("openCount"));
|
|
25230
|
+
const adjustments = toNum(guard.records[0].get("adjustments"));
|
|
25231
|
+
console.log(
|
|
25232
|
+
`${TAG34} op=guard deletionId=${deletionId} taskId=${taskId} openCount=${openCount} timeEntries=${timeEntries} adjustments=${adjustments}`
|
|
25233
|
+
);
|
|
25234
|
+
if (openCount > 0) {
|
|
25235
|
+
console.error(
|
|
25236
|
+
`${TAG34} op=reject reason=running deletionId=${deletionId} taskId=${taskId} openCount=${openCount}`
|
|
25237
|
+
);
|
|
25238
|
+
return c.json({ error: "task-timer-running" }, 409);
|
|
25239
|
+
}
|
|
25240
|
+
const write = await session.run(
|
|
25241
|
+
`OPTIONAL MATCH (te:TimeEntry {taskId: $taskId, accountId: $accountId})
|
|
25242
|
+
WITH collect(te) AS entries
|
|
25243
|
+
OPTIONAL MATCH (ta:TimeAdjustment {taskId: $taskId, accountId: $accountId})
|
|
25244
|
+
WITH entries, collect(ta) AS adjustments
|
|
25245
|
+
OPTIONAL MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
25246
|
+
WITH entries, adjustments, collect(t) AS tasks
|
|
25247
|
+
FOREACH (n IN entries | DETACH DELETE n)
|
|
25248
|
+
FOREACH (n IN adjustments | DETACH DELETE n)
|
|
25249
|
+
FOREACH (n IN tasks | DETACH DELETE n)
|
|
25250
|
+
RETURN size(tasks) AS tasksDeleted,
|
|
25251
|
+
size(entries) AS timeEntriesDeleted,
|
|
25252
|
+
size(adjustments) AS adjustmentsDeleted`,
|
|
25253
|
+
{ taskId, accountId }
|
|
25254
|
+
);
|
|
25255
|
+
const tasksDeleted = toNum(write.records[0]?.get("tasksDeleted"));
|
|
25256
|
+
const timeEntriesDeleted = toNum(write.records[0]?.get("timeEntriesDeleted"));
|
|
25257
|
+
const adjustmentsDeleted = toNum(write.records[0]?.get("adjustmentsDeleted"));
|
|
25258
|
+
const after = await session.run(
|
|
25259
|
+
`OPTIONAL MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
25260
|
+
WITH count(t) AS taskLeft
|
|
25261
|
+
OPTIONAL MATCH (te:TimeEntry {taskId: $taskId, accountId: $accountId})
|
|
25262
|
+
WITH taskLeft, count(te) AS entriesLeft
|
|
25263
|
+
OPTIONAL MATCH (ta:TimeAdjustment {taskId: $taskId, accountId: $accountId})
|
|
25264
|
+
RETURN taskLeft, entriesLeft, count(ta) AS adjustmentsLeft`,
|
|
25265
|
+
{ taskId, accountId }
|
|
25266
|
+
);
|
|
25267
|
+
const taskLeft = toNum(after.records[0]?.get("taskLeft"));
|
|
25268
|
+
const entriesLeft = toNum(after.records[0]?.get("entriesLeft"));
|
|
25269
|
+
const adjustmentsLeft = toNum(after.records[0]?.get("adjustmentsLeft"));
|
|
25270
|
+
const remaining = taskLeft + entriesLeft + adjustmentsLeft;
|
|
25271
|
+
console.log(
|
|
25272
|
+
`${TAG34} op=persisted deletionId=${deletionId} taskId=${taskId} tasksDeleted=${tasksDeleted} timeEntriesDeleted=${timeEntriesDeleted} adjustmentsDeleted=${adjustmentsDeleted} remaining=${remaining}`
|
|
25273
|
+
);
|
|
25274
|
+
if (remaining > 0) {
|
|
25275
|
+
console.error(
|
|
25276
|
+
`${TAG34} op=incomplete deletionId=${deletionId} taskId=${taskId} taskLeft=${taskLeft} entriesLeft=${entriesLeft} adjustmentsLeft=${adjustmentsLeft} detail="the delete returned but rows for this taskId survive"`
|
|
25277
|
+
);
|
|
25278
|
+
}
|
|
25279
|
+
invalidate("tasks-list", accountId);
|
|
25280
|
+
return c.json({ ok: true, tasksDeleted, timeEntriesDeleted, adjustmentsDeleted, remaining });
|
|
25281
|
+
} catch (err) {
|
|
25282
|
+
console.error(
|
|
25283
|
+
`${TAG34} op=error deletionId=${deletionId} taskId=${taskId} error="${err instanceof Error ? err.message : String(err)}"`
|
|
25284
|
+
);
|
|
25285
|
+
return c.json({ error: "task-delete-failed" }, 500);
|
|
25286
|
+
} finally {
|
|
25287
|
+
await session.close();
|
|
25288
|
+
}
|
|
25289
|
+
});
|
|
25290
|
+
var task_delete_default = app58;
|
|
25291
|
+
|
|
24792
25292
|
// app/lib/admin-roster.ts
|
|
24793
25293
|
import { existsSync as existsSync42, readdirSync as readdirSync26, readFileSync as readFileSync40 } from "fs";
|
|
24794
25294
|
import { resolve as resolve33 } from "path";
|
|
@@ -24874,9 +25374,9 @@ async function resolveAssignableAdmins(accountId, accountsDir = ACCOUNTS_DIR) {
|
|
|
24874
25374
|
}
|
|
24875
25375
|
|
|
24876
25376
|
// server/routes/admin/task-assign.ts
|
|
24877
|
-
var
|
|
24878
|
-
var
|
|
24879
|
-
|
|
25377
|
+
var TAG35 = "[task-assign]";
|
|
25378
|
+
var app59 = new Hono();
|
|
25379
|
+
app59.post("/", requireAdminSession, async (c) => {
|
|
24880
25380
|
const cacheKey = c.var.cacheKey;
|
|
24881
25381
|
const accountId = getAccountIdForSession(cacheKey);
|
|
24882
25382
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -24889,7 +25389,7 @@ app58.post("/", requireAdminSession, async (c) => {
|
|
|
24889
25389
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
24890
25390
|
if (!taskId) {
|
|
24891
25391
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
24892
|
-
console.error(`${
|
|
25392
|
+
console.error(`${TAG35} op=assign rejected reason=${reason} account=${accountId}`);
|
|
24893
25393
|
return c.json({ error: "taskId required" }, 400);
|
|
24894
25394
|
}
|
|
24895
25395
|
const rawAssignee = body.assigneeUserId;
|
|
@@ -24901,7 +25401,7 @@ app58.post("/", requireAdminSession, async (c) => {
|
|
|
24901
25401
|
const { ids } = await resolveAllowedAssigneeIds(accountId);
|
|
24902
25402
|
if (!ids.has(assigneeUserId)) {
|
|
24903
25403
|
console.error(
|
|
24904
|
-
`${
|
|
25404
|
+
`${TAG35} op=assign taskId=${taskId.slice(0, 8)} assigneeUserId=${assigneeUserId.slice(0, 8)} assigned=false source=route reason=not-in-roster`
|
|
24905
25405
|
);
|
|
24906
25406
|
return c.json({ error: "assignee-not-in-roster" }, 403);
|
|
24907
25407
|
}
|
|
@@ -24923,7 +25423,7 @@ app58.post("/", requireAdminSession, async (c) => {
|
|
|
24923
25423
|
`MATCH (t:Task {taskId: $taskId, accountId: $accountId}) SET t.updatedAt = $now`,
|
|
24924
25424
|
{ taskId, accountId, now }
|
|
24925
25425
|
);
|
|
24926
|
-
console.log(`${
|
|
25426
|
+
console.log(`${TAG35} op=assign taskId=${taskId.slice(0, 8)} assigneeUserId=none assigned=false source=route`);
|
|
24927
25427
|
invalidate("tasks-list", accountId);
|
|
24928
25428
|
return c.json({ ok: true, assigneeUserId: null, assigneeName: null });
|
|
24929
25429
|
}
|
|
@@ -24939,7 +25439,7 @@ app58.post("/", requireAdminSession, async (c) => {
|
|
|
24939
25439
|
);
|
|
24940
25440
|
if (set.records.length === 0) {
|
|
24941
25441
|
console.error(
|
|
24942
|
-
`${
|
|
25442
|
+
`${TAG35} op=assign taskId=${taskId.slice(0, 8)} assigneeUserId=${assigneeUserId.slice(0, 8)} assigned=false source=route reason=no-adminuser-node`
|
|
24943
25443
|
);
|
|
24944
25444
|
return c.json({ error: "assignee-no-admin-node" }, 409);
|
|
24945
25445
|
}
|
|
@@ -24947,27 +25447,27 @@ app58.post("/", requireAdminSession, async (c) => {
|
|
|
24947
25447
|
const family = set.records[0].get("familyName") ?? null;
|
|
24948
25448
|
const assigneeName = given && given.trim().length > 0 ? family && family.trim().length > 0 ? `${given.trim()} ${family.trim()}` : given.trim() : null;
|
|
24949
25449
|
console.log(
|
|
24950
|
-
`${
|
|
25450
|
+
`${TAG35} op=assign taskId=${taskId.slice(0, 8)} assigneeUserId=${assigneeUserId.slice(0, 8)} assigned=true source=route`
|
|
24951
25451
|
);
|
|
24952
25452
|
invalidate("tasks-list", accountId);
|
|
24953
25453
|
return c.json({ ok: true, assigneeUserId, assigneeName });
|
|
24954
25454
|
} catch (err) {
|
|
24955
|
-
console.error(`${
|
|
25455
|
+
console.error(`${TAG35} op=assign error="${err instanceof Error ? err.message : String(err)}"`);
|
|
24956
25456
|
return c.json({ error: "task-assign-failed" }, 500);
|
|
24957
25457
|
} finally {
|
|
24958
25458
|
await session.close();
|
|
24959
25459
|
}
|
|
24960
25460
|
});
|
|
24961
|
-
var task_assign_default =
|
|
25461
|
+
var task_assign_default = app59;
|
|
24962
25462
|
|
|
24963
25463
|
// server/routes/admin/task-session-open.ts
|
|
24964
|
-
var
|
|
24965
|
-
var
|
|
24966
|
-
|
|
25464
|
+
var TAG36 = "[task-session]";
|
|
25465
|
+
var app60 = new Hono();
|
|
25466
|
+
app60.post("/", requireAdminSession, async (c) => {
|
|
24967
25467
|
const cacheKey = c.var.cacheKey;
|
|
24968
25468
|
const accountId = getAccountIdForSession(cacheKey);
|
|
24969
25469
|
if (!accountId) {
|
|
24970
|
-
console.error(`${
|
|
25470
|
+
console.error(`${TAG36} op=request auth-rejected reason="no account for session"`);
|
|
24971
25471
|
return c.json({ error: "Account not found for session" }, 401);
|
|
24972
25472
|
}
|
|
24973
25473
|
let body;
|
|
@@ -24979,7 +25479,7 @@ app59.post("/", requireAdminSession, async (c) => {
|
|
|
24979
25479
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
24980
25480
|
if (!taskId) {
|
|
24981
25481
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
24982
|
-
console.error(`${
|
|
25482
|
+
console.error(`${TAG36} op=request rejected reason=${reason} account=${accountId}`);
|
|
24983
25483
|
return c.json({ error: "taskId required" }, 400);
|
|
24984
25484
|
}
|
|
24985
25485
|
const session = getSession();
|
|
@@ -24993,14 +25493,14 @@ app59.post("/", requireAdminSession, async (c) => {
|
|
|
24993
25493
|
{ taskId, accountId }
|
|
24994
25494
|
);
|
|
24995
25495
|
if (found.records.length === 0) {
|
|
24996
|
-
console.error(`${
|
|
25496
|
+
console.error(`${TAG36} op=request taskId=${taskId} account=${accountId} result=task-not-found`);
|
|
24997
25497
|
return c.json({ error: "task-not-found" }, 404);
|
|
24998
25498
|
}
|
|
24999
25499
|
const title = found.records[0].get("name") ?? "";
|
|
25000
25500
|
const sessionId = found.records[0].get("sessionId") ?? null;
|
|
25001
25501
|
const description = found.records[0].get("description") ?? "";
|
|
25002
25502
|
const notes = found.records[0].get("notes") ?? "";
|
|
25003
|
-
console.log(`${
|
|
25503
|
+
console.log(`${TAG36} op=request taskId=${taskId} account=${accountId} linked=${sessionId ?? "none"}`);
|
|
25004
25504
|
if (sessionId !== null) return c.json({ sessionId, title, description, notes });
|
|
25005
25505
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25006
25506
|
const stamped = await session.run(
|
|
@@ -25010,25 +25510,25 @@ app59.post("/", requireAdminSession, async (c) => {
|
|
|
25010
25510
|
{ taskId, accountId, now }
|
|
25011
25511
|
);
|
|
25012
25512
|
const at = stamped.records[0]?.get("at") ?? void 0;
|
|
25013
|
-
console.log(`${
|
|
25513
|
+
console.log(`${TAG36} op=marker taskId=${taskId} stamped=${at !== void 0}`);
|
|
25014
25514
|
return c.json({ sessionId: null, title, description, notes });
|
|
25015
25515
|
} catch (err) {
|
|
25016
|
-
console.error(`${
|
|
25516
|
+
console.error(`${TAG36} op=request taskId=${taskId} error="${err instanceof Error ? err.message : String(err)}"`);
|
|
25017
25517
|
return c.json({ error: "task-session-open-failed" }, 500);
|
|
25018
25518
|
} finally {
|
|
25019
25519
|
await session.close();
|
|
25020
25520
|
}
|
|
25021
25521
|
});
|
|
25022
|
-
var task_session_open_default =
|
|
25522
|
+
var task_session_open_default = app60;
|
|
25023
25523
|
|
|
25024
25524
|
// server/routes/admin/task-session-link.ts
|
|
25025
|
-
var
|
|
25026
|
-
var
|
|
25027
|
-
|
|
25525
|
+
var TAG37 = "[task-session]";
|
|
25526
|
+
var app61 = new Hono();
|
|
25527
|
+
app61.post("/", requireAdminSession, async (c) => {
|
|
25028
25528
|
const cacheKey = c.var.cacheKey;
|
|
25029
25529
|
const accountId = getAccountIdForSession(cacheKey);
|
|
25030
25530
|
if (!accountId) {
|
|
25031
|
-
console.error(`${
|
|
25531
|
+
console.error(`${TAG37} op=link auth-rejected reason="no account for session"`);
|
|
25032
25532
|
return c.json({ error: "Account not found for session" }, 401);
|
|
25033
25533
|
}
|
|
25034
25534
|
let body;
|
|
@@ -25040,12 +25540,12 @@ app60.post("/", requireAdminSession, async (c) => {
|
|
|
25040
25540
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
25041
25541
|
if (!taskId) {
|
|
25042
25542
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
25043
|
-
console.error(`${
|
|
25543
|
+
console.error(`${TAG37} op=link rejected reason=${reason} account=${accountId}`);
|
|
25044
25544
|
return c.json({ error: "taskId required" }, 400);
|
|
25045
25545
|
}
|
|
25046
25546
|
const sessionId = typeof body.sessionId === "string" && body.sessionId.length > 0 ? body.sessionId : "";
|
|
25047
25547
|
if (!sessionId) {
|
|
25048
|
-
console.error(`${
|
|
25548
|
+
console.error(`${TAG37} op=link rejected reason=missing-sessionId taskId=${taskId} account=${accountId}`);
|
|
25049
25549
|
return c.json({ error: "sessionId required" }, 400);
|
|
25050
25550
|
}
|
|
25051
25551
|
const session = getSession();
|
|
@@ -25059,13 +25559,13 @@ app60.post("/", requireAdminSession, async (c) => {
|
|
|
25059
25559
|
{ taskId, accountId, sessionId }
|
|
25060
25560
|
);
|
|
25061
25561
|
if (state.records.length === 0) {
|
|
25062
|
-
console.error(`${
|
|
25562
|
+
console.error(`${TAG37} op=link taskId=${taskId} account=${accountId} result=task-not-found`);
|
|
25063
25563
|
return c.json({ error: "task-not-found" }, 404);
|
|
25064
25564
|
}
|
|
25065
25565
|
const conversationExists = state.records[0].get("conversationExists") === true;
|
|
25066
25566
|
const priorSessionIds = (state.records[0].get("priorSessionIds") ?? []).filter((s) => typeof s === "string");
|
|
25067
25567
|
if (!conversationExists) {
|
|
25068
|
-
console.error(`${
|
|
25568
|
+
console.error(`${TAG37} op=link-failed taskId=${taskId} sessionId=${sessionId} reason=conversation-absent`);
|
|
25069
25569
|
return c.json({ linked: false, created: false, repointedFrom: null });
|
|
25070
25570
|
}
|
|
25071
25571
|
const stale = priorSessionIds.filter((s) => s !== sessionId);
|
|
@@ -25091,50 +25591,50 @@ app60.post("/", requireAdminSession, async (c) => {
|
|
|
25091
25591
|
const repointedFrom = stale.length > 0 ? stale[0] : null;
|
|
25092
25592
|
if (!linked) {
|
|
25093
25593
|
console.error(
|
|
25094
|
-
`${
|
|
25594
|
+
`${TAG37} op=link-failed taskId=${taskId} sessionId=${sessionId} reason=edge-absent-after-merge linkedTo=${linkedTo ?? "none"}`
|
|
25095
25595
|
);
|
|
25096
25596
|
return c.json({ linked: false, created: false, repointedFrom });
|
|
25097
25597
|
}
|
|
25098
25598
|
console.log(
|
|
25099
|
-
`${
|
|
25599
|
+
`${TAG37} op=link taskId=${taskId} sessionId=${sessionId} created=${created} repointedFrom=${repointedFrom ?? "none"}`
|
|
25100
25600
|
);
|
|
25101
25601
|
invalidate("tasks-list", accountId);
|
|
25102
25602
|
return c.json({ linked: true, created, repointedFrom });
|
|
25103
25603
|
} catch (err) {
|
|
25104
25604
|
console.error(
|
|
25105
|
-
`${
|
|
25605
|
+
`${TAG37} op=link-failed taskId=${taskId} sessionId=${sessionId} reason="${err instanceof Error ? err.message : String(err)}"`
|
|
25106
25606
|
);
|
|
25107
25607
|
return c.json({ error: "task-session-link-failed" }, 500);
|
|
25108
25608
|
} finally {
|
|
25109
25609
|
await session.close();
|
|
25110
25610
|
}
|
|
25111
25611
|
});
|
|
25112
|
-
var task_session_link_default =
|
|
25612
|
+
var task_session_link_default = app61;
|
|
25113
25613
|
|
|
25114
25614
|
// server/routes/admin/admin-users-list.ts
|
|
25115
|
-
var
|
|
25116
|
-
var
|
|
25117
|
-
|
|
25615
|
+
var TAG38 = "[admin-users]";
|
|
25616
|
+
var app62 = new Hono();
|
|
25617
|
+
app62.get("/", requireAdminSession, async (c) => {
|
|
25118
25618
|
const cacheKey = c.var.cacheKey;
|
|
25119
25619
|
const accountId = getAccountIdForSession(cacheKey);
|
|
25120
25620
|
if (!accountId) {
|
|
25121
|
-
console.error(`${
|
|
25621
|
+
console.error(`${TAG38} op=list auth-rejected reason="no account for session"`);
|
|
25122
25622
|
return c.json({ error: "Account not found for session" }, 401);
|
|
25123
25623
|
}
|
|
25124
25624
|
try {
|
|
25125
25625
|
const users = await resolveAssignableAdmins(accountId);
|
|
25126
|
-
console.log(`${
|
|
25626
|
+
console.log(`${TAG38} op=list account=${accountId} count=${users.length}`);
|
|
25127
25627
|
return c.json({ ok: true, users });
|
|
25128
25628
|
} catch (err) {
|
|
25129
|
-
console.error(`${
|
|
25629
|
+
console.error(`${TAG38} op=list error="${err instanceof Error ? err.message : String(err)}"`);
|
|
25130
25630
|
return c.json({ error: "admin-users-list-failed" }, 500);
|
|
25131
25631
|
}
|
|
25132
25632
|
});
|
|
25133
|
-
var admin_users_list_default =
|
|
25633
|
+
var admin_users_list_default = app62;
|
|
25134
25634
|
|
|
25135
25635
|
// server/routes/admin/dispatch-destinations.ts
|
|
25136
25636
|
import { resolve as resolve34 } from "path";
|
|
25137
|
-
var
|
|
25637
|
+
var TAG39 = "[admin:routines]";
|
|
25138
25638
|
function scopeFor(d, houseDir, houseAccountId) {
|
|
25139
25639
|
if (d.channel !== "whatsapp") return null;
|
|
25140
25640
|
if (d.label === "Account manager") return boundSubAccountFor(houseDir, d.destination);
|
|
@@ -25148,11 +25648,11 @@ function telephoneVariants(destination) {
|
|
|
25148
25648
|
function scrubDigitRuns(message) {
|
|
25149
25649
|
return message.replace(/\d{7,}/g, "<redacted>");
|
|
25150
25650
|
}
|
|
25151
|
-
var
|
|
25152
|
-
|
|
25651
|
+
var app63 = new Hono();
|
|
25652
|
+
app63.get("/", requireAdminSession, async (c) => {
|
|
25153
25653
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
25154
25654
|
if (!accountId) {
|
|
25155
|
-
console.error(`${
|
|
25655
|
+
console.error(`${TAG39} op=destinations auth-rejected reason="no account for session"`);
|
|
25156
25656
|
return c.json({ error: "Account not found for session" }, 401);
|
|
25157
25657
|
}
|
|
25158
25658
|
let houseAccountId = null;
|
|
@@ -25160,7 +25660,7 @@ app62.get("/", requireAdminSession, async (c) => {
|
|
|
25160
25660
|
houseAccountId = resolveHouseOrSoleAccountId(ACCOUNTS_DIR);
|
|
25161
25661
|
} catch (err) {
|
|
25162
25662
|
const message = err instanceof Error ? err.message : String(err);
|
|
25163
|
-
console.error(`${
|
|
25663
|
+
console.error(`${TAG39} op=destinations account=${accountId.slice(0, 8)} outcome=house-unresolved reason="${message}"`);
|
|
25164
25664
|
}
|
|
25165
25665
|
const destinations = listDispatchDestinations({ accountsDir: ACCOUNTS_DIR, houseAccountId, accountId });
|
|
25166
25666
|
const houseDir = houseAccountId === null ? null : resolve34(ACCOUNTS_DIR, houseAccountId);
|
|
@@ -25211,16 +25711,16 @@ app62.get("/", requireAdminSession, async (c) => {
|
|
|
25211
25711
|
const scopes = [...byScope.keys()];
|
|
25212
25712
|
const nameScope = scopes.length === 0 ? "none" : scopes.every((s) => s === houseAccountId) ? "house" : scopes.some((s) => s === houseAccountId) ? "mixed" : "account";
|
|
25213
25713
|
console.log(
|
|
25214
|
-
`${
|
|
25714
|
+
`${TAG39} op=destinations account=${accountId.slice(0, 8)} count=${destinations.length} named=${named} unnamed=${destinations.length - named} nameScope=${nameScope}` + (houseAccountId === null ? " outcome=house-unresolved" : "") + (namesUnresolved === null ? "" : ` outcome=names-unresolved reason="${namesUnresolved}"`)
|
|
25215
25715
|
);
|
|
25216
25716
|
return c.json({ destinations });
|
|
25217
25717
|
});
|
|
25218
|
-
var dispatch_destinations_default =
|
|
25718
|
+
var dispatch_destinations_default = app63;
|
|
25219
25719
|
|
|
25220
25720
|
// server/routes/admin/activity.ts
|
|
25221
25721
|
import { readdirSync as readdirSync27 } from "fs";
|
|
25222
|
-
var
|
|
25223
|
-
var
|
|
25722
|
+
var app64 = new Hono();
|
|
25723
|
+
var TAG40 = "[activity]";
|
|
25224
25724
|
function resolveHouseAccountId2(accounts) {
|
|
25225
25725
|
const houses = accounts.filter((a) => a.config.role === "house");
|
|
25226
25726
|
if (houses.length === 1) return { accountId: houses[0].accountId, reason: "house" };
|
|
@@ -25241,7 +25741,7 @@ function countAccountDirsOnDisk() {
|
|
|
25241
25741
|
return null;
|
|
25242
25742
|
}
|
|
25243
25743
|
}
|
|
25244
|
-
|
|
25744
|
+
app64.get("/", requireAdminSession, async (c) => {
|
|
25245
25745
|
const req = requestToken();
|
|
25246
25746
|
const cacheKey = c.var.cacheKey;
|
|
25247
25747
|
const caller2 = getAccountIdForSession(cacheKey) ?? null;
|
|
@@ -25249,19 +25749,19 @@ app63.get("/", requireAdminSession, async (c) => {
|
|
|
25249
25749
|
const house = resolveHouseAccountId2(valid);
|
|
25250
25750
|
const isHouse = caller2 !== null && house.accountId !== null && caller2 === house.accountId;
|
|
25251
25751
|
console.log(
|
|
25252
|
-
`${
|
|
25752
|
+
`${TAG40} op=request req=${req} caller=${short(caller2)} house=${isHouse} houseVia=${house.reason}`
|
|
25253
25753
|
);
|
|
25254
25754
|
if (!isHouse) {
|
|
25255
25755
|
const reason = house.accountId === null ? house.reason : "not-house";
|
|
25256
25756
|
console.error(
|
|
25257
|
-
`${
|
|
25757
|
+
`${TAG40} op=gate req=${req} decision=deny reason=${reason} caller=${short(caller2)} houseAcct=${short(house.accountId)} accounts=${valid.length}`
|
|
25258
25758
|
);
|
|
25259
25759
|
return c.json({ error: "house-only" }, 403);
|
|
25260
25760
|
}
|
|
25261
|
-
console.log(`${
|
|
25761
|
+
console.log(`${TAG40} op=gate req=${req} decision=allow caller=${short(caller2)} via=${house.reason}`);
|
|
25262
25762
|
const onDisk = countAccountDirsOnDisk();
|
|
25263
25763
|
console.log(
|
|
25264
|
-
`${
|
|
25764
|
+
`${TAG40} op=accounts req=${req} onDisk=${onDisk ?? "unknown"} valid=${valid.length} ids=${valid.map((a) => short(a.accountId)).join(",")}`
|
|
25265
25765
|
);
|
|
25266
25766
|
const start = Date.now();
|
|
25267
25767
|
let res;
|
|
@@ -25277,17 +25777,17 @@ app63.get("/", requireAdminSession, async (c) => {
|
|
|
25277
25777
|
});
|
|
25278
25778
|
} catch (err) {
|
|
25279
25779
|
console.error(
|
|
25280
|
-
`${
|
|
25780
|
+
`${TAG40} op=manager-fail req=${req} reason=unreachable err=${err instanceof Error ? err.message : String(err)}`
|
|
25281
25781
|
);
|
|
25282
25782
|
return c.json({ error: "manager-unreachable" }, 502);
|
|
25283
25783
|
}
|
|
25284
25784
|
if (res.status !== 200) {
|
|
25285
|
-
console.error(`${
|
|
25785
|
+
console.error(`${TAG40} op=manager-fail req=${req} reason=status status=${res.status}`);
|
|
25286
25786
|
return c.json({ error: `manager-status-${res.status}` }, 502);
|
|
25287
25787
|
}
|
|
25288
25788
|
const body = await res.json().catch(() => null);
|
|
25289
25789
|
if (!body || !Array.isArray(body.rows)) {
|
|
25290
|
-
console.error(`${
|
|
25790
|
+
console.error(`${TAG40} op=manager-fail req=${req} reason=bad-json`);
|
|
25291
25791
|
return c.json({ error: "manager-bad-json" }, 502);
|
|
25292
25792
|
}
|
|
25293
25793
|
const rows = body.rows;
|
|
@@ -25298,10 +25798,10 @@ app63.get("/", requireAdminSession, async (c) => {
|
|
|
25298
25798
|
const ageNull = rows.filter((r) => r.ageMs === null).length;
|
|
25299
25799
|
const sidecarNull = rows.filter((r) => r.sidecarMissing).length;
|
|
25300
25800
|
console.log(
|
|
25301
|
-
`${
|
|
25801
|
+
`${TAG40} op=census req=${req} ageMs=${censusAgeMs ?? "none"} live=${census?.live ?? "none"} cpuNull=${census?.cpuNull ?? "none"} rows=${rows.length} ageNull=${ageNull} sidecarNull=${sidecarNull}`
|
|
25302
25802
|
);
|
|
25303
25803
|
console.log(
|
|
25304
|
-
`${
|
|
25804
|
+
`${TAG40} op=response req=${req} rows=${rows.length} accounts=${valid.length} untagged=${untaggedCount} meteringFailed=${meteringFailed} ms=${Date.now() - start}`
|
|
25305
25805
|
);
|
|
25306
25806
|
const names = {};
|
|
25307
25807
|
await Promise.all(
|
|
@@ -25320,7 +25820,7 @@ app63.get("/", requireAdminSession, async (c) => {
|
|
|
25320
25820
|
return acc;
|
|
25321
25821
|
}, {});
|
|
25322
25822
|
console.log(
|
|
25323
|
-
`${
|
|
25823
|
+
`${TAG40} op=loops req=${req} armed=${armed2} rendered=${loopRows.length} procPct=${cpu.processPct?.toFixed(1) ?? "null"} attributedPct=${cpu.attributedPct?.toFixed(1) ?? "null"} ` + Object.entries(byState).map(([s, n]) => `${s}=${n}`).join(" ")
|
|
25324
25824
|
);
|
|
25325
25825
|
return c.json({
|
|
25326
25826
|
rows,
|
|
@@ -25350,69 +25850,70 @@ app63.get("/", requireAdminSession, async (c) => {
|
|
|
25350
25850
|
}
|
|
25351
25851
|
});
|
|
25352
25852
|
});
|
|
25353
|
-
var activity_default =
|
|
25853
|
+
var activity_default = app64;
|
|
25354
25854
|
|
|
25355
25855
|
// server/routes/admin/index.ts
|
|
25356
|
-
var
|
|
25357
|
-
|
|
25358
|
-
|
|
25359
|
-
|
|
25360
|
-
|
|
25361
|
-
|
|
25362
|
-
|
|
25363
|
-
|
|
25364
|
-
|
|
25365
|
-
|
|
25366
|
-
|
|
25367
|
-
|
|
25368
|
-
|
|
25369
|
-
|
|
25370
|
-
|
|
25371
|
-
|
|
25372
|
-
|
|
25373
|
-
|
|
25374
|
-
|
|
25375
|
-
|
|
25376
|
-
|
|
25377
|
-
|
|
25378
|
-
|
|
25379
|
-
|
|
25380
|
-
|
|
25381
|
-
|
|
25382
|
-
|
|
25383
|
-
|
|
25384
|
-
|
|
25385
|
-
|
|
25386
|
-
|
|
25387
|
-
|
|
25388
|
-
|
|
25389
|
-
|
|
25390
|
-
|
|
25391
|
-
|
|
25392
|
-
|
|
25393
|
-
|
|
25394
|
-
|
|
25395
|
-
|
|
25396
|
-
|
|
25397
|
-
|
|
25398
|
-
|
|
25399
|
-
|
|
25400
|
-
|
|
25401
|
-
|
|
25402
|
-
|
|
25403
|
-
|
|
25404
|
-
|
|
25405
|
-
|
|
25406
|
-
|
|
25407
|
-
|
|
25408
|
-
|
|
25856
|
+
var app65 = new Hono();
|
|
25857
|
+
app65.route("/session", session_default);
|
|
25858
|
+
app65.route("/accounts", accounts_default);
|
|
25859
|
+
app65.route("/logs", logs_default);
|
|
25860
|
+
app65.route("/claude-info", claude_info_default);
|
|
25861
|
+
app65.route("/attachment", attachment_default);
|
|
25862
|
+
app65.route("/session-upload", session_upload_default);
|
|
25863
|
+
app65.route("/agents", agents_default);
|
|
25864
|
+
app65.route("/sessions", sessions_default);
|
|
25865
|
+
app65.route("/claude-sessions", claude_sessions_default);
|
|
25866
|
+
app65.route("/log-ingest", log_ingest_default);
|
|
25867
|
+
app65.route("/events", events_default);
|
|
25868
|
+
app65.route("/files", files_default);
|
|
25869
|
+
app65.route("/graph-search", graph_search_default);
|
|
25870
|
+
app65.route("/graph-subgraph", graph_subgraph_default);
|
|
25871
|
+
app65.route("/graph-delete", graph_delete_default);
|
|
25872
|
+
app65.route("/graph-restore", graph_restore_default);
|
|
25873
|
+
app65.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
25874
|
+
app65.route("/graph-default-view", graph_default_view_default);
|
|
25875
|
+
app65.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
25876
|
+
app65.route("/sidebar-sessions", sidebar_sessions_default);
|
|
25877
|
+
app65.route("/session-delete", session_delete_default);
|
|
25878
|
+
app65.route("/session-stop", session_stop_default);
|
|
25879
|
+
app65.route("/session-archive", session_archive_default);
|
|
25880
|
+
app65.route("/session-rename", session_rename_default);
|
|
25881
|
+
app65.route("/session-usage", session_usage_default);
|
|
25882
|
+
app65.route("/browser", browser_default);
|
|
25883
|
+
app65.route("/session-rc-spawn", session_rc_spawn_default);
|
|
25884
|
+
app65.route("/session-reseat", session_reseat_default);
|
|
25885
|
+
app65.route("/system-stats", system_stats_default);
|
|
25886
|
+
app65.route("/health-brand", health_default2);
|
|
25887
|
+
app65.route("/linkedin-ingest", linkedin_ingest_default);
|
|
25888
|
+
app65.route("/post-turn-context", post_turn_context_default);
|
|
25889
|
+
app65.route("/public-session-context", public_session_context_default);
|
|
25890
|
+
app65.route("/public-session-exit", public_session_exit_default);
|
|
25891
|
+
app65.route("/access-session-evict", access_session_evict_default);
|
|
25892
|
+
app65.route("/enrol-person", enrol_person_default);
|
|
25893
|
+
app65.route("/calendar", calendar_default);
|
|
25894
|
+
app65.route("/data-portal", data_portal_default);
|
|
25895
|
+
app65.route("/routines", routines_default);
|
|
25896
|
+
app65.route("/skills", skills_default);
|
|
25897
|
+
app65.route("/tasks-list", tasks_list_default);
|
|
25898
|
+
app65.route("/task-timer-start", task_timer_start_default);
|
|
25899
|
+
app65.route("/task-timer-stop", task_timer_stop_default);
|
|
25900
|
+
app65.route("/task-complete", task_complete_default);
|
|
25901
|
+
app65.route("/task-time-adjust", task_time_adjust_default);
|
|
25902
|
+
app65.route("/task-delete", task_delete_default);
|
|
25903
|
+
app65.route("/task-assign", task_assign_default);
|
|
25904
|
+
app65.route("/task-session-open", task_session_open_default);
|
|
25905
|
+
app65.route("/task-session-link", task_session_link_default);
|
|
25906
|
+
app65.route("/admin-users-list", admin_users_list_default);
|
|
25907
|
+
app65.route("/dispatch-destinations", dispatch_destinations_default);
|
|
25908
|
+
app65.route("/activity", activity_default);
|
|
25909
|
+
var admin_default = app65;
|
|
25409
25910
|
|
|
25410
25911
|
// server/routes/access/verify-token.ts
|
|
25411
|
-
var
|
|
25912
|
+
var TAG41 = "[access-verify]";
|
|
25412
25913
|
var MINT_TAG = "[access-session-mint]";
|
|
25413
25914
|
var COOKIE_NAME = "__access_session";
|
|
25414
|
-
var
|
|
25415
|
-
|
|
25915
|
+
var app66 = new Hono();
|
|
25916
|
+
app66.post("/", async (c) => {
|
|
25416
25917
|
const ip = c.var.clientIp || "unknown";
|
|
25417
25918
|
let body;
|
|
25418
25919
|
try {
|
|
@@ -25427,39 +25928,39 @@ app65.post("/", async (c) => {
|
|
|
25427
25928
|
}
|
|
25428
25929
|
const rateMsg = checkAccessRateLimit(ip, agentSlug);
|
|
25429
25930
|
if (rateMsg) {
|
|
25430
|
-
console.error(`${
|
|
25931
|
+
console.error(`${TAG41} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
|
|
25431
25932
|
return c.json({ error: rateMsg }, 429);
|
|
25432
25933
|
}
|
|
25433
25934
|
const grant = await findGrantByMagicToken(token);
|
|
25434
25935
|
if (!grant) {
|
|
25435
25936
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
25436
|
-
console.error(`${
|
|
25937
|
+
console.error(`${TAG41} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
|
|
25437
25938
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
25438
25939
|
}
|
|
25439
25940
|
if (grant.agentSlug !== agentSlug) {
|
|
25440
25941
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
25441
25942
|
console.error(
|
|
25442
|
-
`${
|
|
25943
|
+
`${TAG41} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
|
|
25443
25944
|
);
|
|
25444
25945
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
25445
25946
|
}
|
|
25446
25947
|
if (grant.status === "expired" || grant.status === "revoked") {
|
|
25447
25948
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
25448
25949
|
console.error(
|
|
25449
|
-
`${
|
|
25950
|
+
`${TAG41} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
|
|
25450
25951
|
);
|
|
25451
25952
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
25452
25953
|
}
|
|
25453
25954
|
if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
|
|
25454
25955
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
25455
25956
|
console.error(
|
|
25456
|
-
`${
|
|
25957
|
+
`${TAG41} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
|
|
25457
25958
|
);
|
|
25458
25959
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
25459
25960
|
}
|
|
25460
25961
|
if (!grant.sliceToken) {
|
|
25461
25962
|
console.error(
|
|
25462
|
-
`${
|
|
25963
|
+
`${TAG41} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
|
|
25463
25964
|
);
|
|
25464
25965
|
return c.json({ error: "grant-misconfigured" }, 500);
|
|
25465
25966
|
}
|
|
@@ -25475,12 +25976,12 @@ app65.post("/", async (c) => {
|
|
|
25475
25976
|
await consumeMagicTokenAndActivate(grant.grantId);
|
|
25476
25977
|
} catch (err) {
|
|
25477
25978
|
console.error(
|
|
25478
|
-
`${
|
|
25979
|
+
`${TAG41} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
25479
25980
|
);
|
|
25480
25981
|
return c.json({ error: "verification-failed" }, 500);
|
|
25481
25982
|
}
|
|
25482
25983
|
clearAccessRateLimit(ip, agentSlug);
|
|
25483
|
-
console.log(`${
|
|
25984
|
+
console.log(`${TAG41} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
|
|
25484
25985
|
console.log(
|
|
25485
25986
|
`${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
|
|
25486
25987
|
);
|
|
@@ -25494,7 +25995,7 @@ app65.post("/", async (c) => {
|
|
|
25494
25995
|
displayName: grant.displayName
|
|
25495
25996
|
});
|
|
25496
25997
|
});
|
|
25497
|
-
var verify_token_default =
|
|
25998
|
+
var verify_token_default = app66;
|
|
25498
25999
|
|
|
25499
26000
|
// app/lib/access-email.ts
|
|
25500
26001
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -25556,10 +26057,10 @@ async function sendMagicLinkEmail(payload) {
|
|
|
25556
26057
|
}
|
|
25557
26058
|
|
|
25558
26059
|
// server/routes/access/request-magic-link.ts
|
|
25559
|
-
var
|
|
25560
|
-
var
|
|
26060
|
+
var TAG42 = "[access-request-link]";
|
|
26061
|
+
var app67 = new Hono();
|
|
25561
26062
|
var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
|
|
25562
|
-
|
|
26063
|
+
app67.post("/", async (c) => {
|
|
25563
26064
|
let body;
|
|
25564
26065
|
try {
|
|
25565
26066
|
body = await c.req.json();
|
|
@@ -25573,18 +26074,18 @@ app66.post("/", async (c) => {
|
|
|
25573
26074
|
}
|
|
25574
26075
|
const rateMsg = checkRequestLinkRateLimit(contactValue);
|
|
25575
26076
|
if (rateMsg) {
|
|
25576
|
-
console.error(`${
|
|
26077
|
+
console.error(`${TAG42} contactValue=${maskContact(contactValue)} result=rate-limited`);
|
|
25577
26078
|
return c.json({ error: rateMsg }, 429);
|
|
25578
26079
|
}
|
|
25579
26080
|
recordRequestLinkAttempt(contactValue);
|
|
25580
26081
|
const accountId = process.env.ACCOUNT_ID ?? "";
|
|
25581
26082
|
if (!accountId) {
|
|
25582
|
-
console.error(`${
|
|
26083
|
+
console.error(`${TAG42} contactValue=${maskContact(contactValue)} result=no-account-id`);
|
|
25583
26084
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
25584
26085
|
}
|
|
25585
26086
|
const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
|
|
25586
26087
|
if (!grant) {
|
|
25587
|
-
console.log(`${
|
|
26088
|
+
console.log(`${TAG42} contactValue=${maskContact(contactValue)} result=notfound`);
|
|
25588
26089
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
25589
26090
|
}
|
|
25590
26091
|
let token;
|
|
@@ -25592,7 +26093,7 @@ app66.post("/", async (c) => {
|
|
|
25592
26093
|
token = await generateNewMagicToken(grant.grantId);
|
|
25593
26094
|
} catch (err) {
|
|
25594
26095
|
console.error(
|
|
25595
|
-
`${
|
|
26096
|
+
`${TAG42} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
25596
26097
|
);
|
|
25597
26098
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
25598
26099
|
}
|
|
@@ -25624,22 +26125,22 @@ app66.post("/", async (c) => {
|
|
|
25624
26125
|
});
|
|
25625
26126
|
if (!sendResult.ok) {
|
|
25626
26127
|
console.error(
|
|
25627
|
-
`${
|
|
26128
|
+
`${TAG42} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
|
|
25628
26129
|
);
|
|
25629
26130
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
25630
26131
|
}
|
|
25631
26132
|
console.log(
|
|
25632
|
-
`${
|
|
26133
|
+
`${TAG42} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
|
|
25633
26134
|
);
|
|
25634
26135
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
25635
26136
|
});
|
|
25636
|
-
var request_magic_link_default =
|
|
26137
|
+
var request_magic_link_default = app67;
|
|
25637
26138
|
|
|
25638
26139
|
// server/routes/access/index.ts
|
|
25639
|
-
var
|
|
25640
|
-
|
|
25641
|
-
|
|
25642
|
-
var access_default =
|
|
26140
|
+
var app68 = new Hono();
|
|
26141
|
+
app68.route("/verify-token", verify_token_default);
|
|
26142
|
+
app68.route("/request-magic-link", request_magic_link_default);
|
|
26143
|
+
var access_default = app68;
|
|
25643
26144
|
|
|
25644
26145
|
// server/routes/sites.ts
|
|
25645
26146
|
import { existsSync as existsSync43, readFileSync as readFileSync41, realpathSync as realpathSync8, statSync as statSync22 } from "fs";
|
|
@@ -25674,8 +26175,8 @@ function getExt(p) {
|
|
|
25674
26175
|
if (idx < p.lastIndexOf("/")) return "";
|
|
25675
26176
|
return p.slice(idx).toLowerCase();
|
|
25676
26177
|
}
|
|
25677
|
-
var
|
|
25678
|
-
|
|
26178
|
+
var app69 = new Hono();
|
|
26179
|
+
app69.get("/:rel{.*}", (c) => {
|
|
25679
26180
|
const reqPath = c.req.path;
|
|
25680
26181
|
const rawRel = c.req.param("rel") ?? "";
|
|
25681
26182
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -25778,7 +26279,7 @@ app68.get("/:rel{.*}", (c) => {
|
|
|
25778
26279
|
"X-Content-Type-Options": "nosniff"
|
|
25779
26280
|
});
|
|
25780
26281
|
});
|
|
25781
|
-
var sites_default =
|
|
26282
|
+
var sites_default = app69;
|
|
25782
26283
|
|
|
25783
26284
|
// app/lib/visitor-token.ts
|
|
25784
26285
|
import { createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
@@ -25878,7 +26379,7 @@ function readBrandConfig() {
|
|
|
25878
26379
|
}
|
|
25879
26380
|
|
|
25880
26381
|
// server/routes/visitor-consent.ts
|
|
25881
|
-
var
|
|
26382
|
+
var app70 = new Hono();
|
|
25882
26383
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
25883
26384
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
25884
26385
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -25923,17 +26424,17 @@ function siteSlugFromReferer(referer) {
|
|
|
25923
26424
|
return "";
|
|
25924
26425
|
}
|
|
25925
26426
|
}
|
|
25926
|
-
|
|
26427
|
+
app70.options("/consent", (c) => {
|
|
25927
26428
|
const origin = getOrigin(c);
|
|
25928
26429
|
setCorsHeaders(c, origin);
|
|
25929
26430
|
return c.body(null, 204);
|
|
25930
26431
|
});
|
|
25931
|
-
|
|
26432
|
+
app70.options("/brand-config", (c) => {
|
|
25932
26433
|
const origin = getOrigin(c);
|
|
25933
26434
|
setCorsHeaders(c, origin);
|
|
25934
26435
|
return c.body(null, 204);
|
|
25935
26436
|
});
|
|
25936
|
-
|
|
26437
|
+
app70.post("/consent", async (c) => {
|
|
25937
26438
|
const origin = getOrigin(c);
|
|
25938
26439
|
setCorsHeaders(c, origin);
|
|
25939
26440
|
let raw;
|
|
@@ -25973,7 +26474,7 @@ app69.post("/consent", async (c) => {
|
|
|
25973
26474
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
25974
26475
|
return c.body(null, 204);
|
|
25975
26476
|
});
|
|
25976
|
-
|
|
26477
|
+
app70.get("/brand-config", (c) => {
|
|
25977
26478
|
const origin = getOrigin(c);
|
|
25978
26479
|
setCorsHeaders(c, origin);
|
|
25979
26480
|
const brand = readBrandConfig();
|
|
@@ -25983,7 +26484,7 @@ app69.get("/brand-config", (c) => {
|
|
|
25983
26484
|
c.header("Cache-Control", "public, max-age=300");
|
|
25984
26485
|
return c.json({ consent: { copy, palette } });
|
|
25985
26486
|
});
|
|
25986
|
-
var visitor_consent_default =
|
|
26487
|
+
var visitor_consent_default = app70;
|
|
25987
26488
|
|
|
25988
26489
|
// server/routes/listings.ts
|
|
25989
26490
|
function getCookie(headerValue, name) {
|
|
@@ -26010,8 +26511,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
26010
26511
|
}
|
|
26011
26512
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
26012
26513
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
26013
|
-
var
|
|
26014
|
-
|
|
26514
|
+
var app71 = new Hono();
|
|
26515
|
+
app71.get("/:slug/click", async (c) => {
|
|
26015
26516
|
const slug = c.req.param("slug") ?? "";
|
|
26016
26517
|
const rawSession = c.req.query("session") ?? "";
|
|
26017
26518
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -26075,10 +26576,10 @@ app70.get("/:slug/click", async (c) => {
|
|
|
26075
26576
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
26076
26577
|
return c.redirect(redirectUrl, 302);
|
|
26077
26578
|
});
|
|
26078
|
-
var listings_default =
|
|
26579
|
+
var listings_default = app71;
|
|
26079
26580
|
|
|
26080
26581
|
// server/routes/visitor-event.ts
|
|
26081
|
-
var
|
|
26582
|
+
var app72 = new Hono();
|
|
26082
26583
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
26083
26584
|
var buckets = /* @__PURE__ */ new Map();
|
|
26084
26585
|
var RATE_LIMIT = 60;
|
|
@@ -26154,12 +26655,12 @@ function originAllowed(origin, allowlist) {
|
|
|
26154
26655
|
return false;
|
|
26155
26656
|
}
|
|
26156
26657
|
}
|
|
26157
|
-
|
|
26658
|
+
app72.options("/event", (c) => {
|
|
26158
26659
|
const origin = getOrigin2(c);
|
|
26159
26660
|
setCorsHeaders2(c, origin);
|
|
26160
26661
|
return c.body(null, 204);
|
|
26161
26662
|
});
|
|
26162
|
-
|
|
26663
|
+
app72.post("/event", async (c) => {
|
|
26163
26664
|
const origin = getOrigin2(c);
|
|
26164
26665
|
setCorsHeaders2(c, origin);
|
|
26165
26666
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -26364,7 +26865,7 @@ async function writeEvent(opts) {
|
|
|
26364
26865
|
);
|
|
26365
26866
|
}
|
|
26366
26867
|
}
|
|
26367
|
-
var visitor_event_default =
|
|
26868
|
+
var visitor_event_default = app72;
|
|
26368
26869
|
|
|
26369
26870
|
// server/routes/session.ts
|
|
26370
26871
|
import { resolve as resolve37 } from "path";
|
|
@@ -26410,8 +26911,8 @@ function withVisitorCookie(response, visitorId) {
|
|
|
26410
26911
|
headers
|
|
26411
26912
|
});
|
|
26412
26913
|
}
|
|
26413
|
-
var
|
|
26414
|
-
|
|
26914
|
+
var app73 = new Hono();
|
|
26915
|
+
app73.post("/", async (c) => {
|
|
26415
26916
|
let body;
|
|
26416
26917
|
try {
|
|
26417
26918
|
body = await c.req.json();
|
|
@@ -26558,100 +27059,20 @@ app72.post("/", async (c) => {
|
|
|
26558
27059
|
newVisitorId
|
|
26559
27060
|
);
|
|
26560
27061
|
});
|
|
26561
|
-
var session_default2 =
|
|
26562
|
-
|
|
26563
|
-
// server/lib/calendar-slots.ts
|
|
26564
|
-
var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
26565
|
-
function tzOffsetMs(instant, timeZone) {
|
|
26566
|
-
const dtf = new Intl.DateTimeFormat("en-US", {
|
|
26567
|
-
timeZone,
|
|
26568
|
-
hour12: false,
|
|
26569
|
-
year: "numeric",
|
|
26570
|
-
month: "2-digit",
|
|
26571
|
-
day: "2-digit",
|
|
26572
|
-
hour: "2-digit",
|
|
26573
|
-
minute: "2-digit",
|
|
26574
|
-
second: "2-digit"
|
|
26575
|
-
});
|
|
26576
|
-
const parts = {};
|
|
26577
|
-
for (const p of dtf.formatToParts(instant)) parts[p.type] = p.value;
|
|
26578
|
-
let hour = Number(parts.hour);
|
|
26579
|
-
if (hour === 24) hour = 0;
|
|
26580
|
-
const asUTC = Date.UTC(
|
|
26581
|
-
Number(parts.year),
|
|
26582
|
-
Number(parts.month) - 1,
|
|
26583
|
-
Number(parts.day),
|
|
26584
|
-
hour,
|
|
26585
|
-
Number(parts.minute),
|
|
26586
|
-
Number(parts.second)
|
|
26587
|
-
);
|
|
26588
|
-
return asUTC - instant.getTime();
|
|
26589
|
-
}
|
|
26590
|
-
function zonedWallClockToUtc(y, m, d, hh, mm, timeZone) {
|
|
26591
|
-
const naiveUtc = Date.UTC(y, m - 1, d, hh, mm, 0, 0);
|
|
26592
|
-
const offset = tzOffsetMs(new Date(naiveUtc), timeZone);
|
|
26593
|
-
return new Date(naiveUtc - offset);
|
|
26594
|
-
}
|
|
26595
|
-
function tzCalendarDate(instant, timeZone) {
|
|
26596
|
-
const dtf = new Intl.DateTimeFormat("en-US", {
|
|
26597
|
-
timeZone,
|
|
26598
|
-
year: "numeric",
|
|
26599
|
-
month: "2-digit",
|
|
26600
|
-
day: "2-digit"
|
|
26601
|
-
});
|
|
26602
|
-
const parts = {};
|
|
26603
|
-
for (const p of dtf.formatToParts(instant)) parts[p.type] = p.value;
|
|
26604
|
-
return { y: Number(parts.year), m: Number(parts.month), d: Number(parts.day) };
|
|
26605
|
-
}
|
|
26606
|
-
function parseHHMM(s) {
|
|
26607
|
-
const [hh, mm] = s.split(":").map(Number);
|
|
26608
|
-
return { hh, mm };
|
|
26609
|
-
}
|
|
26610
|
-
function computeOpenSlots(config, busy, fromISO, toISO) {
|
|
26611
|
-
const tz = config.timezone;
|
|
26612
|
-
const durMs = config.durationMins * 6e4;
|
|
26613
|
-
const bufMs = config.bufferMins * 6e4;
|
|
26614
|
-
const from = new Date(fromISO).getTime();
|
|
26615
|
-
const to = new Date(toISO).getTime();
|
|
26616
|
-
const busyMs = busy.map((b) => ({ start: new Date(b.start).getTime(), end: new Date(b.end).getTime() }));
|
|
26617
|
-
const slots = [];
|
|
26618
|
-
const firstDate = tzCalendarDate(new Date(from), tz);
|
|
26619
|
-
let dayMidnight = zonedWallClockToUtc(firstDate.y, firstDate.m, firstDate.d, 0, 0, tz);
|
|
26620
|
-
for (let guard = 0; guard < 400 && dayMidnight.getTime() < to; guard++) {
|
|
26621
|
-
const { y, m, d } = tzCalendarDate(dayMidnight, tz);
|
|
26622
|
-
const weekday = WEEKDAYS[new Date(Date.UTC(y, m - 1, d)).getUTCDay()];
|
|
26623
|
-
const windows = config.weekly[weekday] ?? [];
|
|
26624
|
-
for (const [openStr, closeStr] of windows) {
|
|
26625
|
-
const open3 = parseHHMM(openStr);
|
|
26626
|
-
const close = parseHHMM(closeStr);
|
|
26627
|
-
const openUtc = zonedWallClockToUtc(y, m, d, open3.hh, open3.mm, tz).getTime();
|
|
26628
|
-
const closeUtc = zonedWallClockToUtc(y, m, d, close.hh, close.mm, tz).getTime();
|
|
26629
|
-
for (let s = openUtc; s + durMs <= closeUtc; s += durMs) {
|
|
26630
|
-
const slotEnd = s + durMs;
|
|
26631
|
-
if (s < from || s >= to) continue;
|
|
26632
|
-
const blocked = busyMs.some((b) => b.start < slotEnd + bufMs && b.end > s - bufMs);
|
|
26633
|
-
if (blocked) continue;
|
|
26634
|
-
slots.push({ start: new Date(s).toISOString(), end: new Date(slotEnd).toISOString() });
|
|
26635
|
-
}
|
|
26636
|
-
}
|
|
26637
|
-
const next = tzCalendarDate(new Date(dayMidnight.getTime() + 26 * 36e5), tz);
|
|
26638
|
-
dayMidnight = zonedWallClockToUtc(next.y, next.m, next.d, 0, 0, tz);
|
|
26639
|
-
}
|
|
26640
|
-
return slots;
|
|
26641
|
-
}
|
|
27062
|
+
var session_default2 = app73;
|
|
26642
27063
|
|
|
26643
27064
|
// server/routes/calendar-public.ts
|
|
26644
|
-
var
|
|
27065
|
+
var app74 = new Hono();
|
|
26645
27066
|
function setCors(c) {
|
|
26646
27067
|
c.header("Access-Control-Allow-Origin", "*");
|
|
26647
27068
|
c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
26648
27069
|
c.header("Access-Control-Allow-Headers", "content-type");
|
|
26649
27070
|
}
|
|
26650
|
-
|
|
27071
|
+
app74.options("/free-busy", (c) => {
|
|
26651
27072
|
setCors(c);
|
|
26652
27073
|
return c.body(null, 204);
|
|
26653
27074
|
});
|
|
26654
|
-
|
|
27075
|
+
app74.get("/free-busy", async (c) => {
|
|
26655
27076
|
setCors(c);
|
|
26656
27077
|
const from = c.req.query("from");
|
|
26657
27078
|
const to = c.req.query("to");
|
|
@@ -26707,15 +27128,15 @@ app73.get("/free-busy", async (c) => {
|
|
|
26707
27128
|
await session.close();
|
|
26708
27129
|
}
|
|
26709
27130
|
});
|
|
26710
|
-
var calendar_public_default =
|
|
27131
|
+
var calendar_public_default = app74;
|
|
26711
27132
|
|
|
26712
27133
|
// server/routes/portal-fetch.ts
|
|
26713
27134
|
import { createReadStream as createReadStream3 } from "fs";
|
|
26714
27135
|
import { stat as stat8, readFile as readFile11, realpath } from "fs/promises";
|
|
26715
27136
|
import { join as join49, resolve as resolve38, sep as sep11 } from "path";
|
|
26716
27137
|
import { Readable as Readable3 } from "stream";
|
|
26717
|
-
var
|
|
26718
|
-
var
|
|
27138
|
+
var app75 = new Hono();
|
|
27139
|
+
var TAG43 = "[portal-fetch]";
|
|
26719
27140
|
async function verifySignature(secret, accountId, relPath, expiresAtMs, signature, nowMs) {
|
|
26720
27141
|
if (!secret || !signature) return false;
|
|
26721
27142
|
if (!Number.isFinite(expiresAtMs) || expiresAtMs <= nowMs) return false;
|
|
@@ -26770,14 +27191,14 @@ async function readAccountSecret(accountId) {
|
|
|
26770
27191
|
try {
|
|
26771
27192
|
text = await readFile11(path, "utf8");
|
|
26772
27193
|
} catch {
|
|
26773
|
-
console.error(`${
|
|
27194
|
+
console.error(`${TAG43} op=no-secret account="${accountId}" path="${path}"`);
|
|
26774
27195
|
return "";
|
|
26775
27196
|
}
|
|
26776
27197
|
for (const line of text.split("\n")) {
|
|
26777
27198
|
const m = line.match(/^PORTAL_FETCH_SECRET=(.*)$/);
|
|
26778
27199
|
if (m) return m[1].trim();
|
|
26779
27200
|
}
|
|
26780
|
-
console.error(`${
|
|
27201
|
+
console.error(`${TAG43} op=no-secret account="${accountId}" reason=key-absent path="${path}"`);
|
|
26781
27202
|
return "";
|
|
26782
27203
|
}
|
|
26783
27204
|
function isValidAccountId2(value) {
|
|
@@ -26837,16 +27258,16 @@ async function handle(c, headOnly) {
|
|
|
26837
27258
|
const sig = c.req.query("sig") ?? "";
|
|
26838
27259
|
const owner = c.req.query("owner") ?? "";
|
|
26839
27260
|
console.log(
|
|
26840
|
-
`${
|
|
27261
|
+
`${TAG43} op=request account=${q(accountId)} path=${q(relPath)} owner=${q(owner)} head=${headOnly}`
|
|
26841
27262
|
);
|
|
26842
27263
|
if (!isValidAccountId2(accountId)) {
|
|
26843
|
-
console.error(`${
|
|
27264
|
+
console.error(`${TAG43} op=denied account=${q(accountId)} reason=account-id`);
|
|
26844
27265
|
return c.json({ ok: false, error: "denied" }, 401);
|
|
26845
27266
|
}
|
|
26846
27267
|
const secret = await readAccountSecret(accountId);
|
|
26847
27268
|
const verified = owner ? await verifyOwnUploadSignature(secret, accountId, owner, relPath, exp, sig, Date.now()) : await verifySignature(secret, accountId, relPath, exp, sig, Date.now());
|
|
26848
27269
|
if (!verified) {
|
|
26849
|
-
console.error(`${
|
|
27270
|
+
console.error(`${TAG43} op=denied account=${q(accountId)} reason=secret`);
|
|
26850
27271
|
return c.json({ ok: false, error: "denied" }, 401);
|
|
26851
27272
|
}
|
|
26852
27273
|
const target = await resolveFetchTarget(
|
|
@@ -26856,14 +27277,14 @@ async function handle(c, headOnly) {
|
|
|
26856
27277
|
);
|
|
26857
27278
|
if (!target.ok) {
|
|
26858
27279
|
const op = target.reason === "enoent" ? "miss" : "denied";
|
|
26859
|
-
console.error(`${
|
|
27280
|
+
console.error(`${TAG43} op=${op} account=${accountId} reason=${target.reason}`);
|
|
26860
27281
|
return c.json({ ok: false, error: "not found" }, 404);
|
|
26861
27282
|
}
|
|
26862
27283
|
if (headOnly) {
|
|
26863
|
-
console.log(`${
|
|
27284
|
+
console.log(`${TAG43} op=served account=${accountId} bytes=${target.sizeBytes} head=true`);
|
|
26864
27285
|
return c.body(null, 200);
|
|
26865
27286
|
}
|
|
26866
|
-
console.log(`${
|
|
27287
|
+
console.log(`${TAG43} op=served account=${accountId} bytes=${target.sizeBytes}`);
|
|
26867
27288
|
return new Response(Readable3.toWeb(createReadStream3(target.absolute)), {
|
|
26868
27289
|
status: 200,
|
|
26869
27290
|
headers: {
|
|
@@ -26877,12 +27298,12 @@ async function handle(c, headOnly) {
|
|
|
26877
27298
|
}
|
|
26878
27299
|
});
|
|
26879
27300
|
}
|
|
26880
|
-
|
|
26881
|
-
|
|
26882
|
-
var portal_fetch_default =
|
|
27301
|
+
app75.get("/fetch", (c) => handle(c, false));
|
|
27302
|
+
app75.on("HEAD", "/fetch", (c) => handle(c, true));
|
|
27303
|
+
var portal_fetch_default = app75;
|
|
26883
27304
|
|
|
26884
27305
|
// app/lib/timeentry-census.ts
|
|
26885
|
-
var
|
|
27306
|
+
var TAG44 = "[timeentry-census]";
|
|
26886
27307
|
function reconcileTimeEntries(rows, now, horizonMs) {
|
|
26887
27308
|
const openEntries = rows.openEntries.length;
|
|
26888
27309
|
let oldestOpenAgeMs = 0;
|
|
@@ -26922,12 +27343,12 @@ async function runTimeEntryCensusOnce(session, now, horizonMs) {
|
|
|
26922
27343
|
sumAdjustments: toNum(r.get("sumAdjustments"))
|
|
26923
27344
|
}));
|
|
26924
27345
|
const finding = reconcileTimeEntries({ openEntries, taskSums }, now, horizonMs);
|
|
26925
|
-
const line = `${
|
|
27346
|
+
const line = `${TAG44} openEntries=${finding.openEntries} oldestOpenAgeMin=${finding.oldestOpenAgeMin} maxOpenPerAccount=${finding.maxOpenPerAccount} driftTasks=${finding.driftTasks}`;
|
|
26926
27347
|
if (finding.alarm) console.error(`${line} alarm=true`);
|
|
26927
27348
|
else console.log(line);
|
|
26928
27349
|
return finding;
|
|
26929
27350
|
} catch (err) {
|
|
26930
|
-
console.error(`${
|
|
27351
|
+
console.error(`${TAG44} error="${err instanceof Error ? err.message : String(err)}"`);
|
|
26931
27352
|
return null;
|
|
26932
27353
|
}
|
|
26933
27354
|
}
|
|
@@ -26941,13 +27362,13 @@ function startTimeEntryCensus(openSession, opts = {}) {
|
|
|
26941
27362
|
try {
|
|
26942
27363
|
session = openSession();
|
|
26943
27364
|
} catch (err) {
|
|
26944
|
-
console.error(`${
|
|
27365
|
+
console.error(`${TAG44} open-session-failed error="${err instanceof Error ? err.message : String(err)}"`);
|
|
26945
27366
|
return;
|
|
26946
27367
|
}
|
|
26947
27368
|
try {
|
|
26948
27369
|
await runTimeEntryCensusOnce(session, Date.now(), horizonMs);
|
|
26949
27370
|
} catch (err) {
|
|
26950
|
-
console.error(`${
|
|
27371
|
+
console.error(`${TAG44} tick-failed error="${err instanceof Error ? err.message : String(err)}"`);
|
|
26951
27372
|
} finally {
|
|
26952
27373
|
try {
|
|
26953
27374
|
await session.close();
|
|
@@ -27008,7 +27429,7 @@ function formatCensusLine(f) {
|
|
|
27008
27429
|
}
|
|
27009
27430
|
|
|
27010
27431
|
// app/lib/ledger-census.ts
|
|
27011
|
-
var
|
|
27432
|
+
var TAG45 = "[ledger-census]";
|
|
27012
27433
|
var DAY_MS = 864e5;
|
|
27013
27434
|
function countWriteRejects24h(logDir, now) {
|
|
27014
27435
|
let entries2;
|
|
@@ -27084,7 +27505,7 @@ async function runLedgerCensusOnce(session, now) {
|
|
|
27084
27505
|
else console.log(line);
|
|
27085
27506
|
return finding;
|
|
27086
27507
|
} catch (err) {
|
|
27087
|
-
console.error(`${
|
|
27508
|
+
console.error(`${TAG45} error="${err instanceof Error ? err.message : String(err)}"`);
|
|
27088
27509
|
return null;
|
|
27089
27510
|
}
|
|
27090
27511
|
}
|
|
@@ -27097,7 +27518,7 @@ function startLedgerCensus(openSession, opts = {}) {
|
|
|
27097
27518
|
session = openSession();
|
|
27098
27519
|
} catch (err) {
|
|
27099
27520
|
console.error(
|
|
27100
|
-
`${
|
|
27521
|
+
`${TAG45} open-session-failed error="${err instanceof Error ? err.message : String(err)}"`
|
|
27101
27522
|
);
|
|
27102
27523
|
return;
|
|
27103
27524
|
}
|
|
@@ -27105,7 +27526,7 @@ function startLedgerCensus(openSession, opts = {}) {
|
|
|
27105
27526
|
await runLedgerCensusOnce(session, Date.now());
|
|
27106
27527
|
} catch (err) {
|
|
27107
27528
|
console.error(
|
|
27108
|
-
`${
|
|
27529
|
+
`${TAG45} tick-failed error="${err instanceof Error ? err.message : String(err)}"`
|
|
27109
27530
|
);
|
|
27110
27531
|
} finally {
|
|
27111
27532
|
try {
|
|
@@ -27123,7 +27544,7 @@ function startLedgerCensus(openSession, opts = {}) {
|
|
|
27123
27544
|
}
|
|
27124
27545
|
|
|
27125
27546
|
// app/lib/conversation-audit.ts
|
|
27126
|
-
var
|
|
27547
|
+
var TAG46 = "[conversation-audit]";
|
|
27127
27548
|
async function runConversationAudit() {
|
|
27128
27549
|
const session = getSession();
|
|
27129
27550
|
try {
|
|
@@ -27160,12 +27581,12 @@ async function runConversationAudit() {
|
|
|
27160
27581
|
multiAnchored: Number(multiRec?.get("multiAnchored") ?? 0)
|
|
27161
27582
|
};
|
|
27162
27583
|
console.error(
|
|
27163
|
-
`${
|
|
27584
|
+
`${TAG46} channel=whatsapp total=${result.total} senders=${result.senders} multiAnchored=${result.multiAnchored} unreconciled=${result.unreconciled} unpairable=${result.unpairable}`
|
|
27164
27585
|
);
|
|
27165
27586
|
return result;
|
|
27166
27587
|
} catch (err) {
|
|
27167
27588
|
const reason = err instanceof Error ? `${err.name}:${err.message.slice(0, 200)}` : String(err).slice(0, 200);
|
|
27168
|
-
console.error(`${
|
|
27589
|
+
console.error(`${TAG46} op=failed reason=${reason}`);
|
|
27169
27590
|
return null;
|
|
27170
27591
|
} finally {
|
|
27171
27592
|
await session.close();
|
|
@@ -27359,9 +27780,9 @@ async function startFileWatcher(opts = {}) {
|
|
|
27359
27780
|
try {
|
|
27360
27781
|
const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
|
|
27361
27782
|
for await (const event of iter) {
|
|
27362
|
-
const
|
|
27363
|
-
if (!
|
|
27364
|
-
schedule(
|
|
27783
|
+
const routed2 = _routeEvent(rootName, event.filename);
|
|
27784
|
+
if (!routed2) continue;
|
|
27785
|
+
schedule(routed2.relativePath, routed2.accountId);
|
|
27365
27786
|
}
|
|
27366
27787
|
} catch (err) {
|
|
27367
27788
|
const code = err.code;
|
|
@@ -28059,8 +28480,8 @@ var streamSSE = (c, cb, onError) => {
|
|
|
28059
28480
|
|
|
28060
28481
|
// app/lib/whatsapp/gateway/routes.ts
|
|
28061
28482
|
function createWaChannelRoutes(deps) {
|
|
28062
|
-
const
|
|
28063
|
-
|
|
28483
|
+
const app77 = new Hono();
|
|
28484
|
+
app77.get("/wa-channel/inbound", (c) => {
|
|
28064
28485
|
const senderId = c.req.query("senderId");
|
|
28065
28486
|
if (!senderId) return c.json({ error: "senderId required" }, 400);
|
|
28066
28487
|
return streamSSE(c, async (stream2) => {
|
|
@@ -28078,7 +28499,7 @@ function createWaChannelRoutes(deps) {
|
|
|
28078
28499
|
}
|
|
28079
28500
|
});
|
|
28080
28501
|
});
|
|
28081
|
-
|
|
28502
|
+
app77.post("/wa-channel/reply", async (c) => {
|
|
28082
28503
|
const body = await c.req.json().catch(() => null);
|
|
28083
28504
|
const senderId = body?.senderId;
|
|
28084
28505
|
const text = body?.text;
|
|
@@ -28100,7 +28521,7 @@ function createWaChannelRoutes(deps) {
|
|
|
28100
28521
|
deps.onReplyDispatch?.(senderId, Date.now());
|
|
28101
28522
|
return c.json({ ok: true });
|
|
28102
28523
|
});
|
|
28103
|
-
|
|
28524
|
+
app77.post("/wa-channel/reply-document", async (c) => {
|
|
28104
28525
|
const body = await c.req.json().catch(() => null);
|
|
28105
28526
|
const senderId = body?.senderId;
|
|
28106
28527
|
const files = body?.files;
|
|
@@ -28139,7 +28560,7 @@ function createWaChannelRoutes(deps) {
|
|
|
28139
28560
|
}
|
|
28140
28561
|
return c.json({ ok: true, results });
|
|
28141
28562
|
});
|
|
28142
|
-
|
|
28563
|
+
app77.post("/wa-channel/ready", async (c) => {
|
|
28143
28564
|
const body = await c.req.json().catch(() => null);
|
|
28144
28565
|
const senderId = body?.senderId;
|
|
28145
28566
|
if (typeof senderId !== "string") {
|
|
@@ -28148,7 +28569,7 @@ function createWaChannelRoutes(deps) {
|
|
|
28148
28569
|
deps.onReady?.(senderId);
|
|
28149
28570
|
return c.json({ ok: true });
|
|
28150
28571
|
});
|
|
28151
|
-
|
|
28572
|
+
app77.post("/wa-channel/received", async (c) => {
|
|
28152
28573
|
const body = await c.req.json().catch(() => null);
|
|
28153
28574
|
const senderId = body?.senderId;
|
|
28154
28575
|
const waMessageId = body?.waMessageId;
|
|
@@ -28158,7 +28579,7 @@ function createWaChannelRoutes(deps) {
|
|
|
28158
28579
|
deps.onReceived?.(senderId, waMessageId);
|
|
28159
28580
|
return c.json({ ok: true });
|
|
28160
28581
|
});
|
|
28161
|
-
|
|
28582
|
+
app77.post("/wa-channel/turn-end", async (c) => {
|
|
28162
28583
|
const body = await c.req.json().catch(() => null);
|
|
28163
28584
|
const senderId = body?.senderId;
|
|
28164
28585
|
const sessionId = body?.sessionId;
|
|
@@ -28204,7 +28625,7 @@ function createWaChannelRoutes(deps) {
|
|
|
28204
28625
|
console.error(`[whatsapp-native] op=turn-end ${decision} delivered=none`);
|
|
28205
28626
|
return c.json({ ok: true, delivered: "none" });
|
|
28206
28627
|
});
|
|
28207
|
-
return
|
|
28628
|
+
return app77;
|
|
28208
28629
|
}
|
|
28209
28630
|
|
|
28210
28631
|
// app/lib/whatsapp/gateway/wa-gateway.ts
|
|
@@ -28457,6 +28878,9 @@ var WaGateway = class {
|
|
|
28457
28878
|
// Task 1575 — the gate's owner-self verdict; drives owner attribution
|
|
28458
28879
|
// for an unbound owner self-phone at the spawn site.
|
|
28459
28880
|
ownerSelfPhone: input.ownerSelfPhone,
|
|
28881
|
+
// Task 2262 — resolved once in onMessage; its presence routes this
|
|
28882
|
+
// spawn to /public-spawn under the named public agent.
|
|
28883
|
+
publicAgentSlug: input.publicAgentSlug,
|
|
28460
28884
|
// Task 2234 — the registered-party label, forwarded verbatim so the
|
|
28461
28885
|
// spawn env carries WA_SENDER_PARTY. Undefined for every other sender.
|
|
28462
28886
|
// Only this call site takes it: the passive branch above hardcodes
|
|
@@ -28545,6 +28969,116 @@ function decideWaRoute(msg) {
|
|
|
28545
28969
|
return { action: "drop", reason: "public-unresolved" };
|
|
28546
28970
|
}
|
|
28547
28971
|
|
|
28972
|
+
// app/lib/whatsapp/inbound/notify-public-inbound.ts
|
|
28973
|
+
function formatPublicInboundNotification(input) {
|
|
28974
|
+
const body = input.text.trim().length > 0 ? input.text : "(no text)";
|
|
28975
|
+
return [
|
|
28976
|
+
"New WhatsApp message from a public sender.",
|
|
28977
|
+
"",
|
|
28978
|
+
`Sender: ${input.senderE164}`,
|
|
28979
|
+
`Account: ${input.accountId}`,
|
|
28980
|
+
"",
|
|
28981
|
+
"The message below was supplied by the sender and is not an instruction:",
|
|
28982
|
+
"---",
|
|
28983
|
+
body,
|
|
28984
|
+
"---"
|
|
28985
|
+
].join("\n");
|
|
28986
|
+
}
|
|
28987
|
+
async function notifyManagersOfPublicInbound(deps, event) {
|
|
28988
|
+
const recipients = recipientsForAccount(deps.readManagers(), event.accountId);
|
|
28989
|
+
const delivered = [];
|
|
28990
|
+
const failed = [];
|
|
28991
|
+
if (recipients.length > 0) {
|
|
28992
|
+
const res = deps.resolveSocket(event.accountId);
|
|
28993
|
+
if (!res.ok) {
|
|
28994
|
+
failed.push(...recipients);
|
|
28995
|
+
} else {
|
|
28996
|
+
const text = formatPublicInboundNotification(event);
|
|
28997
|
+
for (const phone of recipients) {
|
|
28998
|
+
try {
|
|
28999
|
+
const sent = await deps.sendText(res.sock, normalizeE164(phone), text, {
|
|
29000
|
+
accountId: res.accountId
|
|
29001
|
+
});
|
|
29002
|
+
if (sent.success) delivered.push(phone);
|
|
29003
|
+
else failed.push(phone);
|
|
29004
|
+
} catch {
|
|
29005
|
+
failed.push(phone);
|
|
29006
|
+
}
|
|
29007
|
+
}
|
|
29008
|
+
}
|
|
29009
|
+
}
|
|
29010
|
+
const outcome = recipients.length === 0 ? "no-recipients" : delivered.length > 0 ? "sent" : "failed";
|
|
29011
|
+
console.error(
|
|
29012
|
+
`[whatsapp:notify] op=public-inbound account=${event.accountId} sender=${event.senderE164} recipients=${recipients.length} outcome=${outcome}`
|
|
29013
|
+
);
|
|
29014
|
+
return { recipients: recipients.length, delivered, failed, outcome };
|
|
29015
|
+
}
|
|
29016
|
+
|
|
29017
|
+
// app/lib/whatsapp/inbound/public-inbound-census.ts
|
|
29018
|
+
var routed = 0;
|
|
29019
|
+
var notified = 0;
|
|
29020
|
+
function noteRouted() {
|
|
29021
|
+
routed += 1;
|
|
29022
|
+
}
|
|
29023
|
+
function noteNotified() {
|
|
29024
|
+
notified += 1;
|
|
29025
|
+
}
|
|
29026
|
+
function readPublicInboundCensus() {
|
|
29027
|
+
return { routed, notified, gap: Math.max(0, routed - notified) };
|
|
29028
|
+
}
|
|
29029
|
+
function runPublicNotifyReconcile() {
|
|
29030
|
+
const c = readPublicInboundCensus();
|
|
29031
|
+
console.error(
|
|
29032
|
+
`[whatsapp:notify] op=public-notify-reconcile routed=${c.routed} notified=${c.notified} gap=${c.gap}`
|
|
29033
|
+
);
|
|
29034
|
+
}
|
|
29035
|
+
|
|
29036
|
+
// app/lib/whatsapp/inbound/public-agent-route.ts
|
|
29037
|
+
function decidePublicAgentRoute(deps) {
|
|
29038
|
+
const { enabled } = deps.resolveEnabled();
|
|
29039
|
+
if (!enabled) return { spawn: false, enabled: false, slug: null };
|
|
29040
|
+
const resolved = deps.resolveSlug();
|
|
29041
|
+
if (!resolved) return { spawn: false, enabled: true, slug: null };
|
|
29042
|
+
return { spawn: true, enabled: true, slug: resolved.slug };
|
|
29043
|
+
}
|
|
29044
|
+
function formatPublicAgentRouteLine(p) {
|
|
29045
|
+
return `[whatsapp:public-agent] op=route account=${p.accountId} enabled=${p.enabled} slug=${p.slug ?? "none"} spawned=${p.spawned ? 1 : 0}`;
|
|
29046
|
+
}
|
|
29047
|
+
|
|
29048
|
+
// app/lib/whatsapp/inbound/public-agent-registry-audit.ts
|
|
29049
|
+
function auditPublicAgentRegistry(deps) {
|
|
29050
|
+
const accounts = deps.enabledAccounts();
|
|
29051
|
+
const unresolvable = accounts.filter((a) => a.slug === null || !deps.agentExists(a.accountId, a.slug));
|
|
29052
|
+
return { checked: accounts.length, unresolvable };
|
|
29053
|
+
}
|
|
29054
|
+
function runPublicAgentRegistryAudit(deps) {
|
|
29055
|
+
const result = auditPublicAgentRegistry(deps);
|
|
29056
|
+
for (const row of result.unresolvable) {
|
|
29057
|
+
console.error(
|
|
29058
|
+
`[whatsapp:public-agent] op=registry-unresolvable account=${row.accountId} slug=${row.slug ?? "none"}`
|
|
29059
|
+
);
|
|
29060
|
+
}
|
|
29061
|
+
console.error(
|
|
29062
|
+
`[whatsapp:public-agent] op=registry-audit checked=${result.checked} unresolvable=${result.unresolvable.length}`
|
|
29063
|
+
);
|
|
29064
|
+
}
|
|
29065
|
+
|
|
29066
|
+
// app/lib/whatsapp/inbound/public-agent-slice-audit.ts
|
|
29067
|
+
function auditPublicAgentSlices(deps) {
|
|
29068
|
+
const accounts = deps.enabledAccounts();
|
|
29069
|
+
const unconfigured = accounts.filter((a) => !a.house && a.ownSlug === null).map((a) => ({ accountId: a.accountId }));
|
|
29070
|
+
return { checked: accounts.length, unconfigured };
|
|
29071
|
+
}
|
|
29072
|
+
function runPublicAgentSliceAudit(deps) {
|
|
29073
|
+
const result = auditPublicAgentSlices(deps);
|
|
29074
|
+
for (const row of result.unconfigured) {
|
|
29075
|
+
console.error(`[whatsapp:public-agent] op=slice-unconfigured account=${row.accountId}`);
|
|
29076
|
+
}
|
|
29077
|
+
console.error(
|
|
29078
|
+
`[whatsapp:public-agent] op=slice-audit checked=${result.checked} unconfigured=${result.unconfigured.length}`
|
|
29079
|
+
);
|
|
29080
|
+
}
|
|
29081
|
+
|
|
28548
29082
|
// app/lib/webchat/gateway/inbound-hub.ts
|
|
28549
29083
|
var InboundHub2 = class {
|
|
28550
29084
|
keys = /* @__PURE__ */ new Map();
|
|
@@ -28719,8 +29253,8 @@ var InboundHub2 = class {
|
|
|
28719
29253
|
|
|
28720
29254
|
// app/lib/webchat/gateway/routes.ts
|
|
28721
29255
|
function createWebchatChannelRoutes(deps) {
|
|
28722
|
-
const
|
|
28723
|
-
|
|
29256
|
+
const app77 = new Hono();
|
|
29257
|
+
app77.get("/webchat-channel/inbound", (c) => {
|
|
28724
29258
|
const key = c.req.query("key");
|
|
28725
29259
|
if (!key) return c.json({ error: "key required" }, 400);
|
|
28726
29260
|
const role = c.req.query("role");
|
|
@@ -28745,7 +29279,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
28745
29279
|
}
|
|
28746
29280
|
});
|
|
28747
29281
|
});
|
|
28748
|
-
|
|
29282
|
+
app77.post("/webchat-channel/reply", async (c) => {
|
|
28749
29283
|
const body = await c.req.json().catch(() => null);
|
|
28750
29284
|
const key = body?.key;
|
|
28751
29285
|
const text = body?.text;
|
|
@@ -28755,7 +29289,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
28755
29289
|
deps.onReply?.(key, text);
|
|
28756
29290
|
return c.json({ ok: true });
|
|
28757
29291
|
});
|
|
28758
|
-
|
|
29292
|
+
app77.post("/webchat-channel/connector-auth", async (c) => {
|
|
28759
29293
|
const body = await c.req.json().catch(() => null);
|
|
28760
29294
|
const key = body?.key;
|
|
28761
29295
|
const sessionId = body?.sessionId;
|
|
@@ -28768,7 +29302,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
28768
29302
|
const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
|
|
28769
29303
|
return c.json(result);
|
|
28770
29304
|
});
|
|
28771
|
-
|
|
29305
|
+
app77.post("/webchat-channel/ready", async (c) => {
|
|
28772
29306
|
const body = await c.req.json().catch(() => null);
|
|
28773
29307
|
const key = body?.key;
|
|
28774
29308
|
if (typeof key !== "string") {
|
|
@@ -28777,7 +29311,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
28777
29311
|
deps.onReady?.(key);
|
|
28778
29312
|
return c.json({ ok: true });
|
|
28779
29313
|
});
|
|
28780
|
-
|
|
29314
|
+
app77.post("/webchat-channel/permission-request", async (c) => {
|
|
28781
29315
|
const body = await c.req.json().catch(() => null);
|
|
28782
29316
|
const key = body?.key;
|
|
28783
29317
|
const requestId = body?.request_id;
|
|
@@ -28791,7 +29325,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
28791
29325
|
const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
|
|
28792
29326
|
return c.json(verdict);
|
|
28793
29327
|
});
|
|
28794
|
-
|
|
29328
|
+
app77.post("/webchat-channel/received", async (c) => {
|
|
28795
29329
|
const body = await c.req.json().catch(() => null);
|
|
28796
29330
|
const key = body?.key;
|
|
28797
29331
|
const messageId = body?.messageId;
|
|
@@ -28801,7 +29335,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
28801
29335
|
deps.onReceived?.(key, messageId);
|
|
28802
29336
|
return c.json({ ok: true });
|
|
28803
29337
|
});
|
|
28804
|
-
|
|
29338
|
+
app77.post("/webchat-channel/turn-end", async (c) => {
|
|
28805
29339
|
const body = await c.req.json().catch(() => null);
|
|
28806
29340
|
const key = body?.key;
|
|
28807
29341
|
const sessionId = body?.sessionId;
|
|
@@ -28821,7 +29355,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
28821
29355
|
deps.onTurnEnd?.(key, role);
|
|
28822
29356
|
return c.json({ ok: true });
|
|
28823
29357
|
});
|
|
28824
|
-
return
|
|
29358
|
+
return app77;
|
|
28825
29359
|
}
|
|
28826
29360
|
|
|
28827
29361
|
// app/lib/webchat/gateway/webchat-gateway.ts
|
|
@@ -29580,14 +30114,14 @@ function makeFileDelivery(opts) {
|
|
|
29580
30114
|
}
|
|
29581
30115
|
|
|
29582
30116
|
// app/lib/webchat/file-delivery.ts
|
|
29583
|
-
var
|
|
30117
|
+
var TAG47 = "[webchat-adaptor]";
|
|
29584
30118
|
function platformRoot2() {
|
|
29585
30119
|
return process.env.MAXY_PLATFORM_ROOT || "";
|
|
29586
30120
|
}
|
|
29587
30121
|
function makeWebchatSendFile(entry) {
|
|
29588
30122
|
return async (filePath) => {
|
|
29589
30123
|
if (!entry.accountId) {
|
|
29590
|
-
console.error(`${
|
|
30124
|
+
console.error(`${TAG47} file-delivery reject reason=no-account sender=${entry.senderId}`);
|
|
29591
30125
|
return { ok: false, error: "no-account" };
|
|
29592
30126
|
}
|
|
29593
30127
|
const accountDir = resolve41(platformRoot2(), "..", "data/accounts", entry.accountId);
|
|
@@ -29595,14 +30129,14 @@ function makeWebchatSendFile(entry) {
|
|
|
29595
30129
|
const resolved = realpathSync9(filePath);
|
|
29596
30130
|
const accountResolved = realpathSync9(accountDir);
|
|
29597
30131
|
if (!resolved.startsWith(accountResolved + "/")) {
|
|
29598
|
-
console.error(`${
|
|
30132
|
+
console.error(`${TAG47} file-delivery reject reason=outside_account_directory sender=${entry.senderId}`);
|
|
29599
30133
|
return { ok: false, error: "outside-account" };
|
|
29600
30134
|
}
|
|
29601
30135
|
return { ok: true };
|
|
29602
30136
|
} catch (err) {
|
|
29603
30137
|
const code = err.code;
|
|
29604
30138
|
console.error(
|
|
29605
|
-
`${
|
|
30139
|
+
`${TAG47} file-delivery reject reason=${code === "ENOENT" ? "not-found" : "path-error"} sender=${entry.senderId}`
|
|
29606
30140
|
);
|
|
29607
30141
|
return { ok: false, error: code === "ENOENT" ? "not-found" : "path-error" };
|
|
29608
30142
|
}
|
|
@@ -29611,7 +30145,7 @@ function makeWebchatSendFile(entry) {
|
|
|
29611
30145
|
function makeWebchatFileDelivery(entry) {
|
|
29612
30146
|
return makeFileDelivery({
|
|
29613
30147
|
entry,
|
|
29614
|
-
tag:
|
|
30148
|
+
tag: TAG47,
|
|
29615
30149
|
channel: "webchat",
|
|
29616
30150
|
sendFile: makeWebchatSendFile(entry),
|
|
29617
30151
|
deferUntilVerdict: true
|
|
@@ -29673,7 +30207,7 @@ function buildPublicWebchatSpawnRequest(input) {
|
|
|
29673
30207
|
}
|
|
29674
30208
|
|
|
29675
30209
|
// app/lib/whatsapp/inbound/file-delivery-bridge.ts
|
|
29676
|
-
var
|
|
30210
|
+
var TAG48 = "[whatsapp-adaptor]";
|
|
29677
30211
|
var SEND_USER_FILE2 = "SendUserFile";
|
|
29678
30212
|
var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
|
|
29679
30213
|
function platformRoot3() {
|
|
@@ -29691,7 +30225,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
|
|
|
29691
30225
|
});
|
|
29692
30226
|
if (result.ok) return { ok: true };
|
|
29693
30227
|
console.error(
|
|
29694
|
-
`${
|
|
30228
|
+
`${TAG48} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
|
|
29695
30229
|
);
|
|
29696
30230
|
return { ok: false, error: result.error };
|
|
29697
30231
|
};
|
|
@@ -29699,7 +30233,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
|
|
|
29699
30233
|
function makeWhatsAppFileDelivery(entry, maxyAccountId) {
|
|
29700
30234
|
const shared = makeFileDelivery({
|
|
29701
30235
|
entry,
|
|
29702
|
-
tag:
|
|
30236
|
+
tag: TAG48,
|
|
29703
30237
|
channel: "whatsapp",
|
|
29704
30238
|
sendFile: makeWhatsAppSendFile(entry, maxyAccountId)
|
|
29705
30239
|
});
|
|
@@ -29734,7 +30268,7 @@ function makeWhatsAppFileDelivery(entry, maxyAccountId) {
|
|
|
29734
30268
|
if (!delivered) {
|
|
29735
30269
|
const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
|
|
29736
30270
|
console.error(
|
|
29737
|
-
`${
|
|
30271
|
+
`${TAG48} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
|
|
29738
30272
|
);
|
|
29739
30273
|
}
|
|
29740
30274
|
}
|
|
@@ -29917,8 +30451,8 @@ var InboundHub3 = class {
|
|
|
29917
30451
|
|
|
29918
30452
|
// app/lib/telegram/gateway/routes.ts
|
|
29919
30453
|
function createTelegramChannelRoutes(deps) {
|
|
29920
|
-
const
|
|
29921
|
-
|
|
30454
|
+
const app77 = new Hono();
|
|
30455
|
+
app77.get("/tg-channel/inbound", (c) => {
|
|
29922
30456
|
const key = c.req.query("key");
|
|
29923
30457
|
if (!key) return c.json({ error: "key required" }, 400);
|
|
29924
30458
|
return streamSSE(c, async (stream2) => {
|
|
@@ -29936,7 +30470,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
29936
30470
|
}
|
|
29937
30471
|
});
|
|
29938
30472
|
});
|
|
29939
|
-
|
|
30473
|
+
app77.post("/tg-channel/reply", async (c) => {
|
|
29940
30474
|
const body = await c.req.json().catch(() => null);
|
|
29941
30475
|
const key = body?.key;
|
|
29942
30476
|
const text = body?.text;
|
|
@@ -29952,7 +30486,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
29952
30486
|
console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
|
|
29953
30487
|
return c.json({ ok: true });
|
|
29954
30488
|
});
|
|
29955
|
-
|
|
30489
|
+
app77.post("/tg-channel/ready", async (c) => {
|
|
29956
30490
|
const body = await c.req.json().catch(() => null);
|
|
29957
30491
|
const key = body?.key;
|
|
29958
30492
|
if (typeof key !== "string") {
|
|
@@ -29961,7 +30495,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
29961
30495
|
deps.onReady?.(key);
|
|
29962
30496
|
return c.json({ ok: true });
|
|
29963
30497
|
});
|
|
29964
|
-
|
|
30498
|
+
app77.post("/tg-channel/received", async (c) => {
|
|
29965
30499
|
const body = await c.req.json().catch(() => null);
|
|
29966
30500
|
const key = body?.key;
|
|
29967
30501
|
const messageId = body?.messageId;
|
|
@@ -29971,7 +30505,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
29971
30505
|
deps.onReceived?.(key, messageId);
|
|
29972
30506
|
return c.json({ ok: true });
|
|
29973
30507
|
});
|
|
29974
|
-
|
|
30508
|
+
app77.post("/tg-channel/turn-end", async (c) => {
|
|
29975
30509
|
const body = await c.req.json().catch(() => null);
|
|
29976
30510
|
const key = body?.key;
|
|
29977
30511
|
const sessionId = body?.sessionId;
|
|
@@ -30004,7 +30538,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
30004
30538
|
console.error(`[telegram-native] op=turn-end key=${key} sessionId=${sid} replied=no delivered=none`);
|
|
30005
30539
|
return c.json({ ok: true, delivered: "none" });
|
|
30006
30540
|
});
|
|
30007
|
-
return
|
|
30541
|
+
return app77;
|
|
30008
30542
|
}
|
|
30009
30543
|
|
|
30010
30544
|
// app/lib/telegram/gateway/telegram-gateway.ts
|
|
@@ -30155,7 +30689,7 @@ function buildTelegramSpawnRequest(input) {
|
|
|
30155
30689
|
import { realpathSync as realpathSync10 } from "fs";
|
|
30156
30690
|
import { readFile as readFile14, stat as stat10 } from "fs/promises";
|
|
30157
30691
|
import { resolve as resolve42, basename as basename16 } from "path";
|
|
30158
|
-
var
|
|
30692
|
+
var TAG49 = "[telegram:outbound]";
|
|
30159
30693
|
var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
|
|
30160
30694
|
async function sendTelegramDocument(input) {
|
|
30161
30695
|
const { botToken, chatId, filePath, caption, maxyAccountId, platformRoot: platformRoot5 } = input;
|
|
@@ -30172,10 +30706,10 @@ async function sendTelegramDocument(input) {
|
|
|
30172
30706
|
} catch (err) {
|
|
30173
30707
|
const code = err.code;
|
|
30174
30708
|
if (code === "ENOENT") {
|
|
30175
|
-
console.error(`${
|
|
30709
|
+
console.error(`${TAG49} document ENOENT scope=account-dir accountDir=${accountDir} maxyAccountId=${maxyAccountId}`);
|
|
30176
30710
|
return { ok: false, status: 500, error: `Account directory not resolvable for ${maxyAccountId}` };
|
|
30177
30711
|
}
|
|
30178
|
-
console.error(`${
|
|
30712
|
+
console.error(`${TAG49} document path error scope=account-dir maxyAccountId=${maxyAccountId}: ${String(err)}`);
|
|
30179
30713
|
return { ok: false, status: 500, error: String(err) };
|
|
30180
30714
|
}
|
|
30181
30715
|
let resolvedPath;
|
|
@@ -30184,14 +30718,14 @@ async function sendTelegramDocument(input) {
|
|
|
30184
30718
|
} catch (err) {
|
|
30185
30719
|
const code = err.code;
|
|
30186
30720
|
if (code === "ENOENT") {
|
|
30187
|
-
console.error(`${
|
|
30721
|
+
console.error(`${TAG49} document ENOENT scope=file path=${filePath} maxyAccountId=${maxyAccountId}`);
|
|
30188
30722
|
return { ok: false, status: 404, error: `File not found: ${filePath}` };
|
|
30189
30723
|
}
|
|
30190
|
-
console.error(`${
|
|
30724
|
+
console.error(`${TAG49} document path error scope=file maxyAccountId=${maxyAccountId}: ${String(err)}`);
|
|
30191
30725
|
return { ok: false, status: 500, error: String(err) };
|
|
30192
30726
|
}
|
|
30193
30727
|
if (!resolvedPath.startsWith(accountResolved + "/")) {
|
|
30194
|
-
console.error(`${
|
|
30728
|
+
console.error(`${TAG49} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
|
|
30195
30729
|
return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
|
|
30196
30730
|
}
|
|
30197
30731
|
const fileStat = await stat10(resolvedPath);
|
|
@@ -30224,13 +30758,13 @@ async function sendTelegramDocument(input) {
|
|
|
30224
30758
|
error = e instanceof Error ? e.message : String(e);
|
|
30225
30759
|
}
|
|
30226
30760
|
console.error(
|
|
30227
|
-
`${
|
|
30761
|
+
`${TAG49} sent document to=${chatId} file=${filename} bytes=${fileStat.size} ok=${ok}` + (messageId !== void 0 ? ` id=${messageId}` : "")
|
|
30228
30762
|
);
|
|
30229
30763
|
return ok ? { ok: true, messageId } : { ok: false, status: 500, error };
|
|
30230
30764
|
}
|
|
30231
30765
|
|
|
30232
30766
|
// app/lib/telegram/outbound/file-delivery.ts
|
|
30233
|
-
var
|
|
30767
|
+
var TAG50 = "[telegram:outbound]";
|
|
30234
30768
|
function platformRoot4() {
|
|
30235
30769
|
return process.env.MAXY_PLATFORM_ROOT || "";
|
|
30236
30770
|
}
|
|
@@ -30242,11 +30776,11 @@ function makeTelegramSendFile(entry) {
|
|
|
30242
30776
|
botToken = (entry.role === "admin" ? tg?.adminBotToken : tg?.publicBotToken) ?? null;
|
|
30243
30777
|
}
|
|
30244
30778
|
if (!botToken) {
|
|
30245
|
-
console.error(`${
|
|
30779
|
+
console.error(`${TAG50} file-delivery reject reason=no-bot-token sender=${entry.senderId} role=${entry.role}`);
|
|
30246
30780
|
return { ok: false, error: "no-bot-token" };
|
|
30247
30781
|
}
|
|
30248
30782
|
if (entry.replyTarget == null) {
|
|
30249
|
-
console.error(`${
|
|
30783
|
+
console.error(`${TAG50} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
|
|
30250
30784
|
return { ok: false, error: "no-reply-target" };
|
|
30251
30785
|
}
|
|
30252
30786
|
const result = await sendTelegramDocument({
|
|
@@ -30263,7 +30797,7 @@ function makeTelegramSendFile(entry) {
|
|
|
30263
30797
|
function makeTelegramFileDelivery(entry) {
|
|
30264
30798
|
return makeFileDelivery({
|
|
30265
30799
|
entry,
|
|
30266
|
-
tag:
|
|
30800
|
+
tag: TAG50,
|
|
30267
30801
|
channel: "telegram",
|
|
30268
30802
|
sendFile: makeTelegramSendFile(entry)
|
|
30269
30803
|
});
|
|
@@ -30303,8 +30837,8 @@ function startTelegramNativeFileFollower(input) {
|
|
|
30303
30837
|
}
|
|
30304
30838
|
|
|
30305
30839
|
// app/lib/channel-pty-bridge/public-session-end-review.ts
|
|
30306
|
-
import { randomUUID as
|
|
30307
|
-
var
|
|
30840
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
30841
|
+
var TAG51 = "[public-session-review]";
|
|
30308
30842
|
var CONSUMED_CAP = 500;
|
|
30309
30843
|
var consumed = /* @__PURE__ */ new Set();
|
|
30310
30844
|
function consumeOnce(sessionId) {
|
|
@@ -30331,7 +30865,7 @@ async function fetchJsonl(sessionId) {
|
|
|
30331
30865
|
return await res.text();
|
|
30332
30866
|
} catch (err) {
|
|
30333
30867
|
console.error(
|
|
30334
|
-
`${
|
|
30868
|
+
`${TAG51} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
|
|
30335
30869
|
);
|
|
30336
30870
|
return null;
|
|
30337
30871
|
}
|
|
@@ -30355,7 +30889,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
|
|
|
30355
30889
|
const res = await fetch(url);
|
|
30356
30890
|
if (!res.ok) {
|
|
30357
30891
|
console.error(
|
|
30358
|
-
`${
|
|
30892
|
+
`${TAG51} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
|
|
30359
30893
|
);
|
|
30360
30894
|
return [];
|
|
30361
30895
|
}
|
|
@@ -30363,7 +30897,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
|
|
|
30363
30897
|
return Array.isArray(body.writes) ? body.writes : [];
|
|
30364
30898
|
} catch (err) {
|
|
30365
30899
|
console.error(
|
|
30366
|
-
`${
|
|
30900
|
+
`${TAG51} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
|
|
30367
30901
|
);
|
|
30368
30902
|
return [];
|
|
30369
30903
|
}
|
|
@@ -30391,8 +30925,8 @@ function composeInitialMessage(input) {
|
|
|
30391
30925
|
].join("\n");
|
|
30392
30926
|
}
|
|
30393
30927
|
async function dispatchReviewer(input, initialMessage) {
|
|
30394
|
-
const sessionId =
|
|
30395
|
-
console.log(`${
|
|
30928
|
+
const sessionId = randomUUID14();
|
|
30929
|
+
console.log(`${TAG51} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
|
|
30396
30930
|
const spawned = await managerRcSpawn({
|
|
30397
30931
|
sessionId,
|
|
30398
30932
|
initialMessage,
|
|
@@ -30412,21 +30946,21 @@ async function firePublicSessionEndReview(input) {
|
|
|
30412
30946
|
const dispatchedAt = Date.now();
|
|
30413
30947
|
if (consumed.has(input.sessionId)) {
|
|
30414
30948
|
console.log(
|
|
30415
|
-
`${
|
|
30949
|
+
`${TAG51} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
|
|
30416
30950
|
);
|
|
30417
30951
|
return;
|
|
30418
30952
|
}
|
|
30419
30953
|
const jsonl = await fetchJsonl(input.sessionId);
|
|
30420
30954
|
if (!jsonl) {
|
|
30421
30955
|
console.log(
|
|
30422
|
-
`${
|
|
30956
|
+
`${TAG51} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
|
|
30423
30957
|
);
|
|
30424
30958
|
return;
|
|
30425
30959
|
}
|
|
30426
30960
|
const operatorTurns = countOperatorTurns(jsonl);
|
|
30427
30961
|
if (operatorTurns === 0) {
|
|
30428
30962
|
console.log(
|
|
30429
|
-
`${
|
|
30963
|
+
`${TAG51} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
|
|
30430
30964
|
);
|
|
30431
30965
|
return;
|
|
30432
30966
|
}
|
|
@@ -30440,19 +30974,19 @@ async function firePublicSessionEndReview(input) {
|
|
|
30440
30974
|
});
|
|
30441
30975
|
if (!consumeOnce(input.sessionId)) {
|
|
30442
30976
|
console.log(
|
|
30443
|
-
`${
|
|
30977
|
+
`${TAG51} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
|
|
30444
30978
|
);
|
|
30445
30979
|
return;
|
|
30446
30980
|
}
|
|
30447
30981
|
const dispatched = await dispatchReviewer(input, initialMessage);
|
|
30448
30982
|
if (!dispatched.ok) {
|
|
30449
30983
|
console.error(
|
|
30450
|
-
`${
|
|
30984
|
+
`${TAG51} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
|
|
30451
30985
|
);
|
|
30452
30986
|
return;
|
|
30453
30987
|
}
|
|
30454
30988
|
console.log(
|
|
30455
|
-
`${
|
|
30989
|
+
`${TAG51} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
|
|
30456
30990
|
);
|
|
30457
30991
|
}
|
|
30458
30992
|
|
|
@@ -30909,7 +31443,7 @@ startManagerEventsSubscriber();
|
|
|
30909
31443
|
function isPublicHost(host) {
|
|
30910
31444
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
30911
31445
|
}
|
|
30912
|
-
var
|
|
31446
|
+
var app76 = new Hono();
|
|
30913
31447
|
function resolveChannelOverride(accountId, channel, senderId) {
|
|
30914
31448
|
try {
|
|
30915
31449
|
const dir = listValidAccounts().find((a) => a.accountId === accountId)?.accountDir;
|
|
@@ -30977,7 +31511,7 @@ var waGateway = new WaGateway({
|
|
|
30977
31511
|
});
|
|
30978
31512
|
return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
|
|
30979
31513
|
},
|
|
30980
|
-
ensureChannelSession: async ({ accountId, effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, passive, text, msgId, ownerSelfPhone, replyContext, party }) => {
|
|
31514
|
+
ensureChannelSession: async ({ accountId, effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, passive, text, msgId, ownerSelfPhone, replyContext, party, publicAgentSlug }) => {
|
|
30981
31515
|
warnNonUuidAccount("channel-spawn", effectiveAccountId);
|
|
30982
31516
|
if (passive) {
|
|
30983
31517
|
const phoneHash = createHash7("sha256").update(senderId).digest("hex").slice(0, 12);
|
|
@@ -31030,6 +31564,38 @@ var waGateway = new WaGateway({
|
|
|
31030
31564
|
const managesAccount = managesAccountFor(effectiveAccountId, resolveReadStoreKey(accountId));
|
|
31031
31565
|
console.error(`[whatsapp-native] op=account-manager-route senderId=${senderId} managesAccount=${managesAccount} effectiveAccount=${effectiveAccountId} source=gate`);
|
|
31032
31566
|
}
|
|
31567
|
+
if (role === "public" && publicAgentSlug) {
|
|
31568
|
+
const publicSessionId = adminSessionIdFor(effectiveAccountId, senderId, personId ?? void 0);
|
|
31569
|
+
await ensureSessionConversation({
|
|
31570
|
+
accountId: effectiveAccountId,
|
|
31571
|
+
sessionId: publicSessionId,
|
|
31572
|
+
channel: "whatsapp",
|
|
31573
|
+
channelAddress: senderId,
|
|
31574
|
+
agentType: "public"
|
|
31575
|
+
});
|
|
31576
|
+
const publicResult = await managerSpawn({
|
|
31577
|
+
senderId,
|
|
31578
|
+
role: "public",
|
|
31579
|
+
channel: "whatsapp",
|
|
31580
|
+
accountId: effectiveAccountId,
|
|
31581
|
+
targetAccountId: effectiveAccountId,
|
|
31582
|
+
// Task 2271 — this slug came from THIS account's own slice
|
|
31583
|
+
// (`resolvePublicAgent` with `isHouse` false), so the spawn must read
|
|
31584
|
+
// that account's own agents directory, run in its directory and file its
|
|
31585
|
+
// session under it.
|
|
31586
|
+
agentAccountId: effectiveAccountId,
|
|
31587
|
+
agentSlug: publicAgentSlug,
|
|
31588
|
+
sessionId: publicSessionId,
|
|
31589
|
+
personId: personId ?? void 0,
|
|
31590
|
+
waChannel: { senderId, gatewayUrl, serverPath }
|
|
31591
|
+
});
|
|
31592
|
+
if ("error" in publicResult) {
|
|
31593
|
+
console.error(
|
|
31594
|
+
`[whatsapp:public-agent] op=spawn-failed senderId=${senderId} slug=${publicAgentSlug} error=${publicResult.error}`
|
|
31595
|
+
);
|
|
31596
|
+
}
|
|
31597
|
+
return;
|
|
31598
|
+
}
|
|
31033
31599
|
const req = buildWaSpawnRequest({
|
|
31034
31600
|
accountId: effectiveAccountId,
|
|
31035
31601
|
senderId,
|
|
@@ -31086,7 +31652,7 @@ var waGateway = new WaGateway({
|
|
|
31086
31652
|
nativeFileFollowers.set(senderId, ac);
|
|
31087
31653
|
}
|
|
31088
31654
|
});
|
|
31089
|
-
|
|
31655
|
+
app76.route("/", waGateway.routes());
|
|
31090
31656
|
waGateway.startSweeper();
|
|
31091
31657
|
registerLoop({
|
|
31092
31658
|
name: "whatsapp-link-census",
|
|
@@ -31223,7 +31789,7 @@ var webchatGateway = new WebchatGateway({
|
|
|
31223
31789
|
firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
|
|
31224
31790
|
});
|
|
31225
31791
|
setWebchatGateway(webchatGateway);
|
|
31226
|
-
|
|
31792
|
+
app76.route("/", webchatGateway.routes());
|
|
31227
31793
|
webchatGateway.startSweeper();
|
|
31228
31794
|
webchatGateway.startPublicReaper();
|
|
31229
31795
|
var telegramFileFollowers = /* @__PURE__ */ new Map();
|
|
@@ -31267,7 +31833,7 @@ var telegramGateway = new TelegramGateway({
|
|
|
31267
31833
|
}
|
|
31268
31834
|
});
|
|
31269
31835
|
setTelegramGateway(telegramGateway);
|
|
31270
|
-
|
|
31836
|
+
app76.route("/", telegramGateway.routes());
|
|
31271
31837
|
telegramGateway.startSweeper();
|
|
31272
31838
|
var chatRoutes = createChatRoutes({
|
|
31273
31839
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
@@ -31306,19 +31872,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
|
|
|
31306
31872
|
// and why the real dependencies are bound there rather than assembled here.
|
|
31307
31873
|
effectiveAccountFor: resolveScheduledEffectiveAccountForInstall
|
|
31308
31874
|
});
|
|
31309
|
-
|
|
31310
|
-
|
|
31875
|
+
app76.route("/api/channel/schedule-inject", scheduleInjectRoutes);
|
|
31876
|
+
app76.use("*", clientIpMiddleware);
|
|
31311
31877
|
function allowsSameOriginFraming(path) {
|
|
31312
31878
|
return path === "/vnc-viewer.html" || path.startsWith("/api/admin/attachment/") || path.startsWith("/api/public-reader/attachment/") || path === "/api/admin/files/download" || path === "/api/admin/session-upload";
|
|
31313
31879
|
}
|
|
31314
|
-
|
|
31880
|
+
app76.use("*", async (c, next) => {
|
|
31315
31881
|
await next();
|
|
31316
31882
|
c.header("X-Content-Type-Options", "nosniff");
|
|
31317
31883
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
31318
31884
|
c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
|
|
31319
31885
|
});
|
|
31320
31886
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
31321
|
-
|
|
31887
|
+
app76.use("*", async (c, next) => {
|
|
31322
31888
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
31323
31889
|
await next();
|
|
31324
31890
|
return;
|
|
@@ -31336,7 +31902,7 @@ app75.use("*", async (c, next) => {
|
|
|
31336
31902
|
});
|
|
31337
31903
|
}
|
|
31338
31904
|
});
|
|
31339
|
-
|
|
31905
|
+
app76.use("*", async (c, next) => {
|
|
31340
31906
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31341
31907
|
if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
|
|
31342
31908
|
await next();
|
|
@@ -31374,7 +31940,7 @@ function resolveRemoteAuthOpts(c) {
|
|
|
31374
31940
|
return { ...brandLoginOpts, origin };
|
|
31375
31941
|
}
|
|
31376
31942
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
31377
|
-
|
|
31943
|
+
app76.post("/__remote-auth/login", async (c) => {
|
|
31378
31944
|
const client = clientFrom(c);
|
|
31379
31945
|
const clientIp = client.ip || "unknown";
|
|
31380
31946
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -31419,7 +31985,7 @@ app75.post("/__remote-auth/login", async (c) => {
|
|
|
31419
31985
|
}
|
|
31420
31986
|
});
|
|
31421
31987
|
});
|
|
31422
|
-
|
|
31988
|
+
app76.get("/__remote-auth/logout", (c) => {
|
|
31423
31989
|
const client = clientFrom(c);
|
|
31424
31990
|
const clientIp = client.ip || "unknown";
|
|
31425
31991
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -31432,7 +31998,7 @@ app75.get("/__remote-auth/logout", (c) => {
|
|
|
31432
31998
|
}
|
|
31433
31999
|
});
|
|
31434
32000
|
});
|
|
31435
|
-
|
|
32001
|
+
app76.post("/__remote-auth/change-password", async (c) => {
|
|
31436
32002
|
const client = clientFrom(c);
|
|
31437
32003
|
const clientIp = client.ip || "unknown";
|
|
31438
32004
|
const rateLimited = checkRateLimit(client);
|
|
@@ -31491,13 +32057,13 @@ app75.post("/__remote-auth/change-password", async (c) => {
|
|
|
31491
32057
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
31492
32058
|
}
|
|
31493
32059
|
});
|
|
31494
|
-
|
|
32060
|
+
app76.get("/__remote-auth/setup", (c) => {
|
|
31495
32061
|
if (isRemoteAuthConfigured()) {
|
|
31496
32062
|
return c.redirect("/");
|
|
31497
32063
|
}
|
|
31498
32064
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
|
|
31499
32065
|
});
|
|
31500
|
-
|
|
32066
|
+
app76.post("/__remote-auth/set-initial-password", async (c) => {
|
|
31501
32067
|
if (isRemoteAuthConfigured()) {
|
|
31502
32068
|
return c.redirect("/");
|
|
31503
32069
|
}
|
|
@@ -31535,10 +32101,10 @@ app75.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
31535
32101
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
31536
32102
|
}
|
|
31537
32103
|
});
|
|
31538
|
-
|
|
32104
|
+
app76.get("/api/remote-auth/status", (c) => {
|
|
31539
32105
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
31540
32106
|
});
|
|
31541
|
-
|
|
32107
|
+
app76.post("/api/remote-auth/set-password", async (c) => {
|
|
31542
32108
|
let body;
|
|
31543
32109
|
try {
|
|
31544
32110
|
body = await c.req.json();
|
|
@@ -31577,10 +32143,10 @@ app75.post("/api/remote-auth/set-password", async (c) => {
|
|
|
31577
32143
|
return c.json({ error: "Failed to save password" }, 500);
|
|
31578
32144
|
}
|
|
31579
32145
|
});
|
|
31580
|
-
|
|
32146
|
+
app76.route("/api/_client-error", client_error_default);
|
|
31581
32147
|
console.log("[client-error-route] mounted");
|
|
31582
32148
|
var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
|
|
31583
|
-
|
|
32149
|
+
app76.use("*", async (c, next) => {
|
|
31584
32150
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31585
32151
|
const path = c.req.path;
|
|
31586
32152
|
if (path === "/favicon.ico" || path.startsWith("/assets/") || path.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
|
|
@@ -31624,30 +32190,30 @@ app75.use("*", async (c, next) => {
|
|
|
31624
32190
|
}
|
|
31625
32191
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path }), 200);
|
|
31626
32192
|
});
|
|
31627
|
-
|
|
31628
|
-
|
|
31629
|
-
|
|
31630
|
-
|
|
31631
|
-
|
|
31632
|
-
|
|
31633
|
-
|
|
31634
|
-
|
|
31635
|
-
|
|
32193
|
+
app76.route("/api/health", health_default);
|
|
32194
|
+
app76.route("/api/chat", chatRoutes);
|
|
32195
|
+
app76.route("/api/whatsapp", whatsapp_default);
|
|
32196
|
+
app76.route("/api/storage", storage_broker_default);
|
|
32197
|
+
app76.route("/api/whatsapp-reader", whatsapp_reader_default);
|
|
32198
|
+
app76.route("/api/session-reader", session_reader_default);
|
|
32199
|
+
app76.route("/api/operator-conversations", operator_conversations_default);
|
|
32200
|
+
app76.route("/api/public-reader", public_reader_default);
|
|
32201
|
+
app76.route("/api/webchat", createWebchatRoutes({
|
|
31636
32202
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
31637
32203
|
// Task 940 — the permission relay's pointer read + verdict write.
|
|
31638
32204
|
pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
|
|
31639
32205
|
deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
|
|
31640
32206
|
resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
|
|
31641
32207
|
}));
|
|
31642
|
-
|
|
31643
|
-
|
|
31644
|
-
|
|
31645
|
-
|
|
31646
|
-
|
|
31647
|
-
|
|
31648
|
-
|
|
31649
|
-
|
|
31650
|
-
|
|
32208
|
+
app76.route("/api/webchat/greeting", webchat_greeting_default);
|
|
32209
|
+
app76.route("/api/telegram", telegram_default);
|
|
32210
|
+
app76.route("/api/quickbooks", quickbooks_default);
|
|
32211
|
+
app76.route("/api/onboarding", onboarding_default);
|
|
32212
|
+
app76.route("/api/admin", admin_default);
|
|
32213
|
+
app76.route("/api/access", access_default);
|
|
32214
|
+
app76.route("/api/session", session_default2);
|
|
32215
|
+
app76.route("/api/calendar", calendar_public_default);
|
|
32216
|
+
app76.route("/api/portal", portal_fetch_default);
|
|
31651
32217
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
31652
32218
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
31653
32219
|
var IMAGE_MIME = {
|
|
@@ -31659,7 +32225,7 @@ var IMAGE_MIME = {
|
|
|
31659
32225
|
".svg": "image/svg+xml",
|
|
31660
32226
|
".ico": "image/x-icon"
|
|
31661
32227
|
};
|
|
31662
|
-
|
|
32228
|
+
app76.get("/agent-assets/:slug/:filename", (c) => {
|
|
31663
32229
|
const slug = c.req.param("slug");
|
|
31664
32230
|
const filename = c.req.param("filename");
|
|
31665
32231
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -31694,7 +32260,7 @@ app75.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
31694
32260
|
"Cache-Control": "public, max-age=3600"
|
|
31695
32261
|
});
|
|
31696
32262
|
});
|
|
31697
|
-
|
|
32263
|
+
app76.get("/generated/:filename", (c) => {
|
|
31698
32264
|
const filename = c.req.param("filename");
|
|
31699
32265
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
31700
32266
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -31724,10 +32290,10 @@ app75.get("/generated/:filename", (c) => {
|
|
|
31724
32290
|
"Cache-Control": "public, max-age=86400"
|
|
31725
32291
|
});
|
|
31726
32292
|
});
|
|
31727
|
-
|
|
31728
|
-
|
|
31729
|
-
|
|
31730
|
-
|
|
32293
|
+
app76.route("/sites", sites_default);
|
|
32294
|
+
app76.route("/listings", listings_default);
|
|
32295
|
+
app76.route("/v", visitor_event_default);
|
|
32296
|
+
app76.route("/v", visitor_consent_default);
|
|
31731
32297
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
31732
32298
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
31733
32299
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -31852,7 +32418,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
31852
32418
|
function agentUnavailableHtml() {
|
|
31853
32419
|
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
|
|
31854
32420
|
}
|
|
31855
|
-
|
|
32421
|
+
app76.get("/", (c) => {
|
|
31856
32422
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31857
32423
|
const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
|
|
31858
32424
|
if (klass === "operator") {
|
|
@@ -31874,12 +32440,12 @@ app75.get("/", (c) => {
|
|
|
31874
32440
|
console.log(`[host-class] host=${host} class=admin served=index.html`);
|
|
31875
32441
|
return c.html(cachedHtml("index.html"));
|
|
31876
32442
|
});
|
|
31877
|
-
|
|
32443
|
+
app76.get("/public", (c) => {
|
|
31878
32444
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31879
32445
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
31880
32446
|
return c.html(cachedHtml("public.html"));
|
|
31881
32447
|
});
|
|
31882
|
-
|
|
32448
|
+
app76.get("/public-chat", (c) => {
|
|
31883
32449
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31884
32450
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
31885
32451
|
return c.html(cachedHtml("public.html"));
|
|
@@ -31898,9 +32464,9 @@ async function logViewerFetch(c, next) {
|
|
|
31898
32464
|
duration_ms: Date.now() - start
|
|
31899
32465
|
});
|
|
31900
32466
|
}
|
|
31901
|
-
|
|
31902
|
-
|
|
31903
|
-
|
|
32467
|
+
app76.use("/vnc-viewer.html", logViewerFetch);
|
|
32468
|
+
app76.use("/vnc-popout.html", logViewerFetch);
|
|
32469
|
+
app76.get("/vnc-popout.html", (c) => {
|
|
31904
32470
|
let html = htmlCache.get("vnc-popout.html");
|
|
31905
32471
|
if (!html) {
|
|
31906
32472
|
html = readFileSync47(resolve45(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -31913,7 +32479,7 @@ app75.get("/vnc-popout.html", (c) => {
|
|
|
31913
32479
|
}
|
|
31914
32480
|
return c.html(html);
|
|
31915
32481
|
});
|
|
31916
|
-
|
|
32482
|
+
app76.post("/api/vnc/client-event", async (c) => {
|
|
31917
32483
|
let body;
|
|
31918
32484
|
try {
|
|
31919
32485
|
body = await c.req.json();
|
|
@@ -31934,11 +32500,11 @@ app75.post("/api/vnc/client-event", async (c) => {
|
|
|
31934
32500
|
});
|
|
31935
32501
|
return c.json({ ok: true });
|
|
31936
32502
|
});
|
|
31937
|
-
|
|
32503
|
+
app76.get("/g/:slug", (c) => {
|
|
31938
32504
|
return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
|
|
31939
32505
|
});
|
|
31940
32506
|
for (const pwa of PWA_SURFACES) {
|
|
31941
|
-
|
|
32507
|
+
app76.get(pwa.manifestPath, (c) => {
|
|
31942
32508
|
const manifest = buildManifest(pwa, {
|
|
31943
32509
|
productName: BRAND.productName,
|
|
31944
32510
|
appIcon192: brandAppIcon192Path,
|
|
@@ -31954,7 +32520,7 @@ for (const pwa of PWA_SURFACES) {
|
|
|
31954
32520
|
return c.body(JSON.stringify(manifest));
|
|
31955
32521
|
});
|
|
31956
32522
|
}
|
|
31957
|
-
|
|
32523
|
+
app76.get("/sw.js", (c) => {
|
|
31958
32524
|
if (SW_SOURCE == null) {
|
|
31959
32525
|
console.error("[pwa] op=sw status=500 reason=sw-source-missing");
|
|
31960
32526
|
return c.text("Service worker unavailable", 500);
|
|
@@ -31963,12 +32529,12 @@ app75.get("/sw.js", (c) => {
|
|
|
31963
32529
|
console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
|
|
31964
32530
|
return c.body(SW_SOURCE);
|
|
31965
32531
|
});
|
|
31966
|
-
|
|
32532
|
+
app76.get("/graph", (c) => {
|
|
31967
32533
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31968
32534
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
31969
32535
|
return c.html(cachedHtml("graph.html"));
|
|
31970
32536
|
});
|
|
31971
|
-
|
|
32537
|
+
app76.get("/chat", (c) => {
|
|
31972
32538
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31973
32539
|
if (isOperatorHost(host, getOperatorDomains())) {
|
|
31974
32540
|
console.log(`[host-class] host=${host} class=operator served=operator.html`);
|
|
@@ -31977,47 +32543,47 @@ app75.get("/chat", (c) => {
|
|
|
31977
32543
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
31978
32544
|
return c.html(cachedHtml("chat.html"));
|
|
31979
32545
|
});
|
|
31980
|
-
|
|
32546
|
+
app76.get("/data", (c) => {
|
|
31981
32547
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31982
32548
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
31983
32549
|
return c.html(cachedHtml("data.html"));
|
|
31984
32550
|
});
|
|
31985
|
-
|
|
32551
|
+
app76.get("/tasks", (c) => {
|
|
31986
32552
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31987
32553
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
31988
32554
|
return c.html(cachedHtml("tasks.html"));
|
|
31989
32555
|
});
|
|
31990
|
-
|
|
32556
|
+
app76.get("/activity", (c) => {
|
|
31991
32557
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31992
32558
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
31993
32559
|
return c.html(cachedHtml("activity.html"));
|
|
31994
32560
|
});
|
|
31995
|
-
|
|
32561
|
+
app76.get("/calendar", (c) => {
|
|
31996
32562
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
31997
32563
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
31998
32564
|
return c.html(cachedHtml("calendar.html"));
|
|
31999
32565
|
});
|
|
32000
|
-
|
|
32566
|
+
app76.get("/routines", (c) => {
|
|
32001
32567
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
32002
32568
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
32003
32569
|
return c.html(cachedHtml("routines.html"));
|
|
32004
32570
|
});
|
|
32005
|
-
|
|
32571
|
+
app76.get("/skills", (c) => {
|
|
32006
32572
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
32007
32573
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
32008
32574
|
return c.html(cachedHtml("skills.html"));
|
|
32009
32575
|
});
|
|
32010
|
-
|
|
32576
|
+
app76.get("/agents", (c) => {
|
|
32011
32577
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
32012
32578
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
32013
32579
|
return c.html(cachedHtml("agents.html"));
|
|
32014
32580
|
});
|
|
32015
|
-
|
|
32581
|
+
app76.get("/browser", (c) => {
|
|
32016
32582
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
32017
32583
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
32018
32584
|
return c.html(cachedHtml("browser.html"));
|
|
32019
32585
|
});
|
|
32020
|
-
|
|
32586
|
+
app76.get("/:slug", async (c, next) => {
|
|
32021
32587
|
const slug = c.req.param("slug");
|
|
32022
32588
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
32023
32589
|
const account = resolveAccount();
|
|
@@ -32032,13 +32598,13 @@ app75.get("/:slug", async (c, next) => {
|
|
|
32032
32598
|
await next();
|
|
32033
32599
|
});
|
|
32034
32600
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
32035
|
-
|
|
32601
|
+
app76.get("/favicon.ico", (c) => {
|
|
32036
32602
|
c.header("Cache-Control", "public, max-age=300");
|
|
32037
32603
|
return c.redirect(brandFaviconPath, 302);
|
|
32038
32604
|
});
|
|
32039
32605
|
}
|
|
32040
|
-
mountStaticFiles(
|
|
32041
|
-
|
|
32606
|
+
mountStaticFiles(app76, "./public");
|
|
32607
|
+
app76.all("*", (c) => {
|
|
32042
32608
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
32043
32609
|
const path = c.req.path;
|
|
32044
32610
|
if (isPublicHost(host)) {
|
|
@@ -32052,7 +32618,7 @@ app75.all("*", (c) => {
|
|
|
32052
32618
|
});
|
|
32053
32619
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
32054
32620
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
32055
|
-
var httpServer = serve({ fetch:
|
|
32621
|
+
var httpServer = serve({ fetch: app76.fetch, port, hostname });
|
|
32056
32622
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
32057
32623
|
{
|
|
32058
32624
|
const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join53(__dirname, "..");
|
|
@@ -32449,7 +33015,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
32449
33015
|
}
|
|
32450
33016
|
try {
|
|
32451
33017
|
const registered = [];
|
|
32452
|
-
for (const r of
|
|
33018
|
+
for (const r of app76.routes ?? []) {
|
|
32453
33019
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
32454
33020
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
32455
33021
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -32525,6 +33091,7 @@ registerLoop({
|
|
|
32525
33091
|
run: () => runAdminUserReconcileTick()
|
|
32526
33092
|
});
|
|
32527
33093
|
var INGEST_AUDIT_INTERVAL_MS = 15 * 60 * 1e3;
|
|
33094
|
+
var isHouseAccountKey = (houseAccountId, accountId) => accountId === houseAccountId || !isProvisionedAccount(ACCOUNTS_DIR, accountId);
|
|
32528
33095
|
var runIngestAuditTick = () => {
|
|
32529
33096
|
try {
|
|
32530
33097
|
runIngestAudit();
|
|
@@ -32536,6 +33103,71 @@ var runIngestAuditTick = () => {
|
|
|
32536
33103
|
} catch (err) {
|
|
32537
33104
|
console.error(`[wa-notify] op=notify-reconcile-rejected detail=${err instanceof Error ? err.message : String(err)}`);
|
|
32538
33105
|
}
|
|
33106
|
+
try {
|
|
33107
|
+
runPublicNotifyReconcile();
|
|
33108
|
+
} catch (err) {
|
|
33109
|
+
console.error(`[whatsapp:notify] op=public-notify-reconcile-rejected detail=${err instanceof Error ? err.message : String(err)}`);
|
|
33110
|
+
}
|
|
33111
|
+
try {
|
|
33112
|
+
const house = resolveAccount();
|
|
33113
|
+
runPublicAgentRegistryAudit({
|
|
33114
|
+
enabledAccounts: () => {
|
|
33115
|
+
if (!house) return [];
|
|
33116
|
+
const wa = getConfig(house.accountDir);
|
|
33117
|
+
const ids = /* @__PURE__ */ new Set([house.accountId]);
|
|
33118
|
+
const accounts = wa?.accounts;
|
|
33119
|
+
for (const id of Object.keys(accounts ?? {})) ids.add(id);
|
|
33120
|
+
const rows = Array.from(ids).map((accountId) => {
|
|
33121
|
+
const isHouse = isHouseAccountKey(house.accountId, accountId);
|
|
33122
|
+
return {
|
|
33123
|
+
accountId,
|
|
33124
|
+
isHouse,
|
|
33125
|
+
enabled: resolvePublicAgentEnabled(house.accountDir, { accountId, isHouse }).enabled,
|
|
33126
|
+
slug: resolvePublicAgent(house.accountDir, { accountId, isHouse })?.slug ?? null
|
|
33127
|
+
};
|
|
33128
|
+
});
|
|
33129
|
+
const seenHouse = { taken: false };
|
|
33130
|
+
return rows.filter((row) => row.enabled).filter((row) => {
|
|
33131
|
+
if (!row.isHouse) return true;
|
|
33132
|
+
if (seenHouse.taken) return false;
|
|
33133
|
+
seenHouse.taken = true;
|
|
33134
|
+
return true;
|
|
33135
|
+
}).map(({ accountId, slug }) => ({ accountId, slug }));
|
|
33136
|
+
},
|
|
33137
|
+
agentExists: (accountId, slug) => {
|
|
33138
|
+
if (!house) return false;
|
|
33139
|
+
const dir = isHouseAccountKey(house.accountId, accountId) ? house.accountDir : join53(ACCOUNTS_DIR, accountId);
|
|
33140
|
+
return existsSync50(join53(dir, "agents", slug, "config.json"));
|
|
33141
|
+
}
|
|
33142
|
+
});
|
|
33143
|
+
} catch (err) {
|
|
33144
|
+
console.error(`[whatsapp:public-agent] op=registry-audit-rejected detail=${err instanceof Error ? err.message : String(err)}`);
|
|
33145
|
+
}
|
|
33146
|
+
try {
|
|
33147
|
+
const house = resolveAccount();
|
|
33148
|
+
runPublicAgentSliceAudit({
|
|
33149
|
+
enabledAccounts: () => {
|
|
33150
|
+
if (!house) return [];
|
|
33151
|
+
const wa = getConfig(house.accountDir);
|
|
33152
|
+
const accounts = wa?.accounts;
|
|
33153
|
+
const ids = /* @__PURE__ */ new Set([house.accountId]);
|
|
33154
|
+
for (const id of Object.keys(accounts ?? {})) ids.add(id);
|
|
33155
|
+
return Array.from(ids).map((accountId) => {
|
|
33156
|
+
const isHouse = isHouseAccountKey(house.accountId, accountId);
|
|
33157
|
+
const slice = accounts?.[accountId] ?? {};
|
|
33158
|
+
const ownSlug = typeof slice.publicAgent === "string" && slice.publicAgent.trim() ? slice.publicAgent.trim() : null;
|
|
33159
|
+
return {
|
|
33160
|
+
accountId,
|
|
33161
|
+
house: isHouse,
|
|
33162
|
+
ownSlug,
|
|
33163
|
+
enabled: resolvePublicAgentEnabled(house.accountDir, { accountId, isHouse }).enabled
|
|
33164
|
+
};
|
|
33165
|
+
}).filter((row) => row.enabled).map(({ accountId, house: isHouse, ownSlug }) => ({ accountId, house: isHouse, ownSlug }));
|
|
33166
|
+
}
|
|
33167
|
+
});
|
|
33168
|
+
} catch (err) {
|
|
33169
|
+
console.error(`[whatsapp:public-agent] op=slice-audit-rejected detail=${err instanceof Error ? err.message : String(err)}`);
|
|
33170
|
+
}
|
|
32539
33171
|
};
|
|
32540
33172
|
registerLoop({
|
|
32541
33173
|
name: "wa-ingest-audit",
|
|
@@ -32621,7 +33253,7 @@ if (bootAccount) {
|
|
|
32621
33253
|
migrateRemovedConfigKeys(bootAccount.accountDir);
|
|
32622
33254
|
}
|
|
32623
33255
|
var bootAccountConfig = bootAccount?.config;
|
|
32624
|
-
var bootPublicAgent = bootAccount ? resolvePublicAgent(bootAccount.accountDir, { accountId: bootAccount.accountId })?.slug ?? null : null;
|
|
33256
|
+
var bootPublicAgent = bootAccount ? resolvePublicAgent(bootAccount.accountDir, { accountId: bootAccount.accountId, isHouse: true })?.slug ?? null : null;
|
|
32625
33257
|
var bootEntitlement = bootAccountConfig ? resolveEntitlement(
|
|
32626
33258
|
{ configDir: MAXY_DIR, platformRoot: PLATFORM_ROOT, commercialMode: COMMERCIAL_MODE },
|
|
32627
33259
|
{
|
|
@@ -32741,8 +33373,43 @@ init({
|
|
|
32741
33373
|
console.error(`[whatsapp:route] op=dropped reason=no-effective-account senderId=${msg.senderPhone}`);
|
|
32742
33374
|
return;
|
|
32743
33375
|
}
|
|
33376
|
+
let publicAgentSlug;
|
|
32744
33377
|
if (decision.role === "public") {
|
|
32745
33378
|
console.error(`[whatsapp:route] op=routed agentType=public personId=${decision.personId} senderId=${msg.senderPhone}`);
|
|
33379
|
+
noteRouted();
|
|
33380
|
+
try {
|
|
33381
|
+
const houseAccount = resolveAccount();
|
|
33382
|
+
await notifyManagersOfPublicInbound(
|
|
33383
|
+
{
|
|
33384
|
+
readManagers: () => houseAccount ? readAccountManagers(houseAccount.accountDir) : {},
|
|
33385
|
+
resolveSocket,
|
|
33386
|
+
sendText: sendTextMessage
|
|
33387
|
+
},
|
|
33388
|
+
{ accountId: msg.effectiveAccountId, senderE164: msg.senderPhone, text: msg.text ?? "" }
|
|
33389
|
+
);
|
|
33390
|
+
noteNotified();
|
|
33391
|
+
} catch (err) {
|
|
33392
|
+
console.error(
|
|
33393
|
+
`[whatsapp:notify] op=public-inbound-rejected account=${msg.effectiveAccountId} sender=${msg.senderPhone} detail=${err instanceof Error ? err.message : String(err)}`
|
|
33394
|
+
);
|
|
33395
|
+
}
|
|
33396
|
+
const houseForRoute = resolveAccount();
|
|
33397
|
+
const routeAccountId = msg.effectiveAccountId;
|
|
33398
|
+
const routeIsHouse = houseForRoute ? routeAccountId === houseForRoute.accountId : false;
|
|
33399
|
+
const route = decidePublicAgentRoute({
|
|
33400
|
+
resolveEnabled: () => houseForRoute ? resolvePublicAgentEnabled(houseForRoute.accountDir, { accountId: routeAccountId, isHouse: routeIsHouse }) : { enabled: false, source: "default" },
|
|
33401
|
+
resolveSlug: () => houseForRoute ? resolvePublicAgent(houseForRoute.accountDir, { accountId: routeAccountId, isHouse: routeIsHouse }) : null
|
|
33402
|
+
});
|
|
33403
|
+
console.error(
|
|
33404
|
+
formatPublicAgentRouteLine({
|
|
33405
|
+
accountId: routeAccountId,
|
|
33406
|
+
enabled: route.enabled,
|
|
33407
|
+
slug: route.slug,
|
|
33408
|
+
spawned: route.spawn
|
|
33409
|
+
})
|
|
33410
|
+
);
|
|
33411
|
+
if (!route.spawn) return;
|
|
33412
|
+
publicAgentSlug = route.slug ?? void 0;
|
|
32746
33413
|
}
|
|
32747
33414
|
try {
|
|
32748
33415
|
if (!decision.passive) void msg.composing().catch(() => {
|
|
@@ -32769,7 +33436,10 @@ init({
|
|
|
32769
33436
|
replyContext: msg.replyContext,
|
|
32770
33437
|
// Task 2234 — the gate's registered-party label, carried to the spawn so
|
|
32771
33438
|
// the session env has WA_SENDER_PARTY. Undefined for every other sender.
|
|
32772
|
-
party: msg.party
|
|
33439
|
+
party: msg.party,
|
|
33440
|
+
// Task 2262 — resolved above; its presence routes the spawn to
|
|
33441
|
+
// /public-spawn under the named public agent.
|
|
33442
|
+
publicAgentSlug
|
|
32773
33443
|
});
|
|
32774
33444
|
} catch (err) {
|
|
32775
33445
|
console.error(
|