@rubytech/create-maxy-code 0.1.423 → 0.1.427
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/neo4j/schema.cypher +13 -0
- package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +5 -1
- package/payload/platform/plugins/admin/hooks/__tests__/datetime-inject.test.sh +119 -0
- package/payload/platform/plugins/admin/hooks/datetime-inject.sh +115 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +62 -4
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts +44 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js +96 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js.map +1 -1
- package/payload/platform/plugins/admin/skills/datetime/SKILL.md +9 -2
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +14 -2
- package/payload/platform/plugins/docs/references/cross-account-authority.md +8 -0
- package/payload/platform/plugins/docs/references/internals.md +4 -0
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/email/PLUGIN.md +2 -2
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js +73 -4
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/mailbox-resolve.test.js +42 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/mailbox-resolve.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/index.js +1 -0
- package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts +4 -0
- package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/credentials.js +5 -0
- package/payload/platform/plugins/email/mcp/dist/lib/credentials.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +25 -3
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +67 -12
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js.map +1 -1
- package/payload/platform/plugins/email/references/email-reference.md +8 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +5 -2
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch.test.js +50 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/scheduled-seat-id.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/scheduled-seat-id.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/scheduled-seat-id.test.js +22 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/scheduled-seat-id.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.d.ts +35 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.js +36 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/scheduled-seat-id.d.ts +11 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/scheduled-seat-id.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/scheduled-seat-id.js +19 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/scheduled-seat-id.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +85 -3
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/standing-audit.test.js +32 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/standing-audit.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +14 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +94 -4
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +23 -7
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.js +30 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts +29 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js +47 -2
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js.map +1 -1
- package/payload/platform/plugins/whatsapp/PLUGIN.md +2 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/caller-scope-headers.test.d.ts +2 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/caller-scope-headers.test.d.ts.map +1 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/caller-scope-headers.test.js +20 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/caller-scope-headers.test.js.map +1 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/call-api.d.ts +1 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/call-api.d.ts.map +1 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/call-api.js +5 -2
- package/payload/platform/plugins/whatsapp/mcp/dist/call-api.js.map +1 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/caller-scope-headers.d.ts +9 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/caller-scope-headers.d.ts.map +1 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/caller-scope-headers.js +18 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/caller-scope-headers.js.map +1 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js +13 -11
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/work/PLUGIN.md +1 -1
- package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-assigned-admin-env.test.d.ts +2 -0
- package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-assigned-admin-env.test.d.ts.map +1 -0
- package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-assigned-admin-env.test.js +72 -0
- package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-assigned-admin-env.test.js.map +1 -0
- package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-client-fields.test.d.ts +2 -0
- package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-client-fields.test.d.ts.map +1 -0
- package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-client-fields.test.js +67 -0
- package/payload/platform/plugins/work/mcp/dist/__tests__/work-create-client-fields.test.js.map +1 -0
- package/payload/platform/plugins/work/mcp/dist/index.js +3 -0
- package/payload/platform/plugins/work/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/work/mcp/dist/tools/work-create.d.ts +6 -0
- package/payload/platform/plugins/work/mcp/dist/tools/work-create.d.ts.map +1 -1
- package/payload/platform/plugins/work/mcp/dist/tools/work-create.js +34 -1
- package/payload/platform/plugins/work/mcp/dist/tools/work-create.js.map +1 -1
- package/payload/platform/scripts/lib/provision-account-dir.sh +2 -1
- package/payload/platform/services/claude-session-manager/dist/account-admin-census.d.ts +39 -0
- package/payload/platform/services/claude-session-manager/dist/account-admin-census.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/account-admin-census.js +122 -0
- package/payload/platform/services/claude-session-manager/dist/account-admin-census.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/account-timezone.d.ts +40 -0
- package/payload/platform/services/claude-session-manager/dist/account-timezone.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/account-timezone.js +126 -0
- package/payload/platform/services/claude-session-manager/dist/account-timezone.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- 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 +18 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +13 -0
- 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 +11 -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 +28 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.js +8 -1
- package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +22 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.js +22 -1
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/webchat-channel/dist/instructions.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/instructions.js +8 -1
- package/payload/platform/services/webchat-channel/dist/instructions.js.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.d.ts +22 -0
- package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.js +22 -1
- package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +28 -2
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +32 -3
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/templates/account.json +2 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
- package/payload/server/public/assets/{AdminLoginScreens-B1P6PrZ3.js → AdminLoginScreens-yAIhWcGc.js} +1 -1
- package/payload/server/public/assets/AdminShell-Bk1AFQ4D.js +2 -0
- package/payload/server/public/assets/{Checkbox-CgCqOslz.js → Checkbox-B_lfjsqd.js} +1 -1
- package/payload/server/public/assets/Transcript-D67OZnVM.js +2 -0
- package/payload/server/public/assets/admin-DuOhkvrZ.js +1 -0
- package/payload/server/public/assets/{arc-DyzjCWmw.js → arc-dVLpR-ec.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-CgeA3HPD.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-qWfElD16.js → architectureDiagram-Q4EWVU46-C6u_CVzb.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DO2fFHC3.js → blockDiagram-DXYQGD6D-Cy8F5b8O.js} +1 -1
- package/payload/server/public/assets/browser-CCWufeXr.js +1 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Ca-q5gDe.js → c4Diagram-AHTNJAMY-DRXrlepj.js} +1 -1
- package/payload/server/public/assets/calendar-CNk1iPrA.js +1 -0
- package/payload/server/public/assets/channel-B04VBWf7.js +1 -0
- package/payload/server/public/assets/chat-7qB-dwBq.js +1 -0
- package/payload/server/public/assets/chevron-left-CpcDbHIz.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-CX2PxuDw.js → chunk-2KRD3SAO-fEyfhRLz.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-D8l6U4Ne.js → chunk-336JU56O-NUWO4y7q.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-DZkHcXRA.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-CG32Lkbh.js → chunk-4BX2VUAB-BnfiNR3l.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-BnAQbO-v.js → chunk-4TB4RGXK-Bj_aJOz8.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-ejqRH2M5.js → chunk-55IACEB6-aK0DNSKb.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-ClkicQ-T.js → chunk-5FUZZQ4R-DeqAkq5C.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-Be-mE_rx.js → chunk-5PVQY5BW-SShlujAQ.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-DPsemed2.js → chunk-67CJDMHE-CZpzQ0DL.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-BQRQJETl.js → chunk-7N4EOEYR-COnjO6jy.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-B1wcAVCK.js → chunk-AA7GKIK3-C9V31L2z.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-DIua053h.js → chunk-BSJP7CBP-DSwnSGe3.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-C9GHSCS9.js → chunk-CIAEETIT-CnRUTuta.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-C1T3l1xj.js → chunk-EDXVE4YY-BexiL2LH.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-8kPcXEQC.js → chunk-ENJZ2VHE-aTklWdJQ.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-Bhoeq9sD.js → chunk-FMBD7UC4-svcEBQzs.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-BIBpJi8I.js → chunk-FOC6F5B3-CG7R7Xri.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DELXp6fj.js → chunk-ICPOFSXX-CGN7Z4x9.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-DdckXldP.js → chunk-K5T4RW27-CWBh78jw.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-BJhXejKT.js → chunk-KGLVRYIC-Ctiq4q-5.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-BSd8nyM2.js → chunk-LIHQZDEY-BII77Q7K.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-CBi55uxq.js → chunk-ORNJ4GCN-DT7R01H8.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-Dfbzl8xh.js → chunk-OYMX7WX6-y-Jkbd4C.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-D9Mwgzti.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-BN1w8_Cq.js → chunk-U2HBQHQK-DzFo6KbQ.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-CrRay1NJ.js → chunk-X2U36JSP-CYSwgtLV.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-C_ZE776O.js → chunk-XPW4576I-DHlM4tOn.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-CUSlqWBY.js → chunk-YZCP3GAM-B20rTmLl.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BdPUfSiD.js → chunk-ZZ45TVLE-C7hP4J8m.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CIo_TzfF.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-SzQYvAUZ.js +1 -0
- package/payload/server/public/assets/clone-BVjcjsBA.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-D4E9htTz.js → cose-bilkent-S5V4N54A-nKjTv9sR.js} +1 -1
- package/payload/server/public/assets/{dagre-D1B5TQL1.js → dagre-Cx8LiiUZ.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-ByuvYV7N.js → dagre-KV5264BT-BNJYTnls.js} +1 -1
- package/payload/server/public/assets/data-BnHcS27X.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-B-0KduTa.js → diagram-5BDNPKRD-CoAN5_f9.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-CSQmo3eB.js → diagram-G4DWMVQ6-pRmsN4_x.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-DK0kWiB3.js → diagram-MMDJMWI5-CRoylyp4.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-CYbK2reZ.js → diagram-TYMM5635-BT3ZtG5b.js} +1 -1
- package/payload/server/public/assets/{dist-CADCHk0t.js → dist-CRpLAnCP.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-C-JQHvJF.js → erDiagram-SMLLAGMA-DSKws1ZV.js} +1 -1
- package/payload/server/public/assets/file-download-Hf_UILaA.js +1 -0
- package/payload/server/public/assets/{flatten-ROVzlo1u.js → flatten-jn8bZgcI.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-OTOd2czg.js → flowDiagram-DWJPFMVM-C2L38ZE5.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BWJ778ou.js → ganttDiagram-T4ZO3ILL-Bm2h-vjm.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-DzQ18i0T.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CkNcyISe.js → gitGraphDiagram-UUTBAWPF-BoowbF7u.js} +1 -1
- package/payload/server/public/assets/graph-klLugHEK.js +51 -0
- package/payload/server/public/assets/{graph-labels-BfG6FO25.js → graph-labels-BLx-0vyT.js} +1 -1
- package/payload/server/public/assets/{graphlib-8z59Ng6C.js → graphlib-BvT2s_o1.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-CwsoaVzV.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-ieNsH2bV.js +2 -0
- package/payload/server/public/assets/{isEmpty-DXf_sApt.js → isEmpty-Dkk6_L-B.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-Cg7pRRGp.js → ishikawaDiagram-UXIWVN3A-nxcmj-IX.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CZT_4r_Z.js → journeyDiagram-VCZTEJTY-q5SNIvmS.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Dp1Vd5YM.js → kanban-definition-6JOO6SKY-BugG9Q1o.js} +1 -1
- package/payload/server/public/assets/{line-UPAcwY66.js → line-MZCQLR-q.js} +1 -1
- package/payload/server/public/assets/{linear-BeeahLKw.js → linear-DmQGNk-g.js} +1 -1
- package/payload/server/public/assets/{maximize-2-DrBaKD3z.js → maximize-2-CnNQnj_v.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-CLKle8df.js → mermaid-parser.core-DvoeqLxw.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-CwRj5rL5.js → mermaid.core-BLaw7iG4.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CNQUY9UJ.js → mindmap-definition-QFDTVHPH-DMkt10Vc.js} +1 -1
- package/payload/server/public/assets/operator-CRcySYv9.js +1 -0
- package/payload/server/public/assets/{ordinal-B2r5L1v4.js → ordinal-DuJYM7p1.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-DxB-bO4L.js +1 -0
- package/payload/server/public/assets/page-CVo3CWIY.js +1 -0
- package/payload/server/public/assets/page-DPTbZRwl.js +32 -0
- package/payload/server/public/assets/{pdf-render-m08Xm2Nm.js → pdf-render-riHufgrn.js} +1 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-PSdKvB8-.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-Scnq58FX.js → pieDiagram-DEJITSTG-DRp4lD2B.js} +1 -1
- package/payload/server/public/assets/play-yEkd7ouW.js +1 -0
- package/payload/server/public/assets/public-Fi6ccYaE.js +1 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-wPfZo_vs.js → quadrantDiagram-34T5L4WZ-DkT63Dn4.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-D8FqRiWq.js +1 -0
- package/payload/server/public/assets/{reduce-CFlDlJf5.js → reduce-COyotL2V.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-yYkH12K2.js → requirementDiagram-MS252O5E-65GGtDkc.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-xHksz9mr.js +1 -0
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-fVWRBzzV.js → sankeyDiagram-XADWPNL6-D1vRwLWd.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-Dbap3X6h.js → sequenceDiagram-FGHM5R23-Bp47ZSN2.js} +1 -1
- package/payload/server/public/assets/square-BZqaxg7D.js +1 -0
- package/payload/server/public/assets/{src-Bi0fLV9t.js → src-xN1oULc8.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DkPLAqIh.js → stateDiagram-FHFEXIEX-BZHHcP_e.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-qVtoGx56.js +1 -0
- package/payload/server/public/assets/tasks-COWmfts8.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DabKBJyd.js → timeline-definition-GMOUNBTQ-DZ1wUyj-.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-i-w4rJmQ.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-Dij6AlAj.js +1 -0
- package/payload/server/public/assets/useSubAccountSwitcher-DADvGnr1.js +9 -0
- package/payload/server/public/assets/useSubAccountSwitcher-ayajZz8T.css +1 -0
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-CaKT7c-c.js → vennDiagram-DHZGUBPP-CttBahsn.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-BJhOQVqW.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BZ5TTSOL.js → wardleyDiagram-NUSXRM2D-Y5tWieZg.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CLfeklJ9.js → xychartDiagram-5P7HB3ND-C78A9qbe.js} +1 -1
- package/payload/server/public/browser.html +7 -5
- package/payload/server/public/calendar.html +8 -6
- package/payload/server/public/chat.html +15 -12
- package/payload/server/public/data.html +11 -10
- package/payload/server/public/graph.html +12 -10
- package/payload/server/public/index.html +16 -14
- package/payload/server/public/operator.html +17 -14
- package/payload/server/public/public.html +15 -12
- package/payload/server/public/tasks.html +18 -0
- package/payload/server/server.js +604 -224
- package/payload/server/public/assets/AdminShell-Y1fHQApK.js +0 -2
- package/payload/server/public/assets/Transcript-DZzFjhoq.js +0 -2
- package/payload/server/public/assets/admin-BRBjJEci.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-XiVs-N7Z.js +0 -1
- package/payload/server/public/assets/browser-ID7iqIi4.js +0 -1
- package/payload/server/public/assets/calendar-BEQPMTtd.js +0 -1
- package/payload/server/public/assets/channel-CYBkRz7E.js +0 -1
- package/payload/server/public/assets/chat-D0GDSWM-.js +0 -1
- package/payload/server/public/assets/chevron-left-A0HYKwGY.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-CPhOHriU.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-CDnAAZVJ.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BdXUKVrS.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DAq-uJr_.js +0 -1
- package/payload/server/public/assets/clone-DQl28-jK.js +0 -1
- package/payload/server/public/assets/data-CV38dClT.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-BM-KaDZy.js +0 -1
- package/payload/server/public/assets/graph-BK0MjKRy.js +0 -51
- package/payload/server/public/assets/info-OMHHGYJF-CtZajyAB.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-C-_WYlmI.js +0 -2
- package/payload/server/public/assets/operator-CnpNyIJ8.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-T-SYedp7.js +0 -1
- package/payload/server/public/assets/page-DC_L-IS1.js +0 -32
- package/payload/server/public/assets/page-DKHLflh7.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-BWECFVVd.js +0 -1
- package/payload/server/public/assets/public-ByUJr48E.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-Dx0YUklX.js +0 -1
- package/payload/server/public/assets/rotate-ccw-D45TbeAI.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DceWO1u6.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-C3197Rac.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-BPrpx29h.js +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-CCn22f98.css +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-CprHkBnZ.js +0 -9
- package/payload/server/public/assets/wardley-RL74JXVD-DW4Jlbhw.js +0 -1
- /package/payload/server/public/assets/{_baseFor-BVuIxZJh.js → _baseFor-Bjj9It3Q.js} +0 -0
- /package/payload/server/public/assets/{admin-types-hioowVct.js → admin-types-ClHBm0ni.js} +0 -0
- /package/payload/server/public/assets/{array-B9UHiPd-.js → array-BrrxEo12.js} +0 -0
- /package/payload/server/public/assets/{chunk-CAM3fms7.js → chunk-Ck5AOu5v.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-D5_TRwB-.js → cytoscape.esm-CTWJxUxo.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-5eAKkKJC.js → defaultLocale-CFDbRV4k.js} +0 -0
- /package/payload/server/public/assets/{init-DlZdxViB.js → init-dXCzGgLP.js} +0 -0
- /package/payload/server/public/assets/{katex-Xo0SyWvP.js → katex-CHA1JFYJ.js} +0 -0
- /package/payload/server/public/assets/{path-6uRLdFF7.js → path-CCRpdXhK.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-CvXuAEud.js → preload-helper-CH6UZRzu.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-Djo4Abte.js → rough.esm-Bud4g4fh.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -5910,8 +5910,8 @@ function webchatTurnTimeoutMs() {
|
|
|
5910
5910
|
return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
|
|
5911
5911
|
}
|
|
5912
5912
|
function createChatRoutes(deps) {
|
|
5913
|
-
const
|
|
5914
|
-
|
|
5913
|
+
const app61 = new Hono();
|
|
5914
|
+
app61.post("/", async (c) => {
|
|
5915
5915
|
console.log(`[chat-route] entered route=public method=POST`);
|
|
5916
5916
|
const contentType = c.req.header("content-type") ?? "";
|
|
5917
5917
|
const account = resolveAccount();
|
|
@@ -6174,7 +6174,7 @@ ${result.result.text}` : result.result.text;
|
|
|
6174
6174
|
}
|
|
6175
6175
|
});
|
|
6176
6176
|
});
|
|
6177
|
-
return
|
|
6177
|
+
return app61;
|
|
6178
6178
|
}
|
|
6179
6179
|
|
|
6180
6180
|
// app/lib/channel-pty-bridge/admin-session-id.ts
|
|
@@ -6189,14 +6189,28 @@ function adminSessionIdFor(accountId, senderId, personId) {
|
|
|
6189
6189
|
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`;
|
|
6190
6190
|
}
|
|
6191
6191
|
|
|
6192
|
+
// app/lib/channel-pty-bridge/schedule-provenance.ts
|
|
6193
|
+
function parseScheduleProvenance(v) {
|
|
6194
|
+
if (!v || typeof v !== "object") return void 0;
|
|
6195
|
+
const o = v;
|
|
6196
|
+
if (typeof o.accountId !== "string" || typeof o.eventId !== "string" || typeof o.dispatchedAt !== "string") {
|
|
6197
|
+
return void 0;
|
|
6198
|
+
}
|
|
6199
|
+
if (!Array.isArray(o.authoredBy)) return void 0;
|
|
6200
|
+
const authoredBy = o.authoredBy.filter((u) => typeof u === "string" && u.length > 0);
|
|
6201
|
+
const createdByTool = typeof o.createdByTool === "string" && o.createdByTool.length > 0 ? o.createdByTool : null;
|
|
6202
|
+
return { accountId: o.accountId, eventId: o.eventId, authoredBy, createdByTool, dispatchedAt: o.dispatchedAt };
|
|
6203
|
+
}
|
|
6204
|
+
|
|
6192
6205
|
// server/routes/channel/schedule-inject.ts
|
|
6193
6206
|
var TAG16 = "[schedule-inject]";
|
|
6207
|
+
var UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
6194
6208
|
function isLoopbackAddr(addr) {
|
|
6195
6209
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
6196
6210
|
}
|
|
6197
6211
|
function createScheduleInjectRoutes(deps) {
|
|
6198
|
-
const
|
|
6199
|
-
|
|
6212
|
+
const app61 = new Hono();
|
|
6213
|
+
app61.post("/", async (c) => {
|
|
6200
6214
|
const env = c.env;
|
|
6201
6215
|
const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
|
|
6202
6216
|
if (!isLoopbackAddr(remoteAddr)) {
|
|
@@ -6222,6 +6236,8 @@ function createScheduleInjectRoutes(deps) {
|
|
|
6222
6236
|
const destination = typeof body.destination === "string" ? body.destination : "";
|
|
6223
6237
|
const prompt = typeof body.prompt === "string" ? body.prompt : "";
|
|
6224
6238
|
const eventId = typeof body.eventId === "string" ? body.eventId : "";
|
|
6239
|
+
const scheduleProvenance = parseScheduleProvenance(body.scheduleProvenance);
|
|
6240
|
+
const overrideSessionId = typeof body.sessionId === "string" && UUID_V4.test(body.sessionId) ? body.sessionId : void 0;
|
|
6225
6241
|
if (channel !== "whatsapp" && channel !== "telegram" || !destination || !prompt) {
|
|
6226
6242
|
console.error(`${TAG16} reject reason=bad-request channel=${String(channel)} hasDestination=${Boolean(destination)} hasPrompt=${Boolean(prompt)}`);
|
|
6227
6243
|
return c.json({ ok: false, error: "schedule-inject-bad-request" }, 400);
|
|
@@ -6240,7 +6256,7 @@ function createScheduleInjectRoutes(deps) {
|
|
|
6240
6256
|
return c.json({ ok: false, error: "account-manager-unresolved" }, 403);
|
|
6241
6257
|
}
|
|
6242
6258
|
console.error(`${TAG16} op=effective-account eventId=${eventId} effectiveAccount=${effectiveAccount2}`);
|
|
6243
|
-
const sessionId2 = adminSessionIdFor(effectiveAccount2, destination);
|
|
6259
|
+
const sessionId2 = overrideSessionId ?? adminSessionIdFor(effectiveAccount2, destination);
|
|
6244
6260
|
const reply2 = (text) => deps.sendWhatsAppText(houseAccountId, destination, text);
|
|
6245
6261
|
try {
|
|
6246
6262
|
await deps.waHandleInbound({
|
|
@@ -6257,6 +6273,8 @@ function createScheduleInjectRoutes(deps) {
|
|
|
6257
6273
|
text: prompt,
|
|
6258
6274
|
media: [],
|
|
6259
6275
|
source: "schedule",
|
|
6276
|
+
scheduleProvenance,
|
|
6277
|
+
scheduledSessionId: overrideSessionId,
|
|
6260
6278
|
reply: reply2
|
|
6261
6279
|
});
|
|
6262
6280
|
} catch (err) {
|
|
@@ -6274,7 +6292,7 @@ function createScheduleInjectRoutes(deps) {
|
|
|
6274
6292
|
return c.json({ ok: false, error: "no-admin-bot-token" }, 400);
|
|
6275
6293
|
}
|
|
6276
6294
|
const chatId = Number(destination);
|
|
6277
|
-
const sessionId = adminSessionIdFor(effectiveAccount, destination);
|
|
6295
|
+
const sessionId = overrideSessionId ?? adminSessionIdFor(effectiveAccount, destination);
|
|
6278
6296
|
const reply = (text) => deps.sendTelegramText(botToken, chatId, text);
|
|
6279
6297
|
try {
|
|
6280
6298
|
await deps.tgHandleInbound({
|
|
@@ -6285,6 +6303,8 @@ function createScheduleInjectRoutes(deps) {
|
|
|
6285
6303
|
personId: null,
|
|
6286
6304
|
text: prompt,
|
|
6287
6305
|
source: "schedule",
|
|
6306
|
+
scheduleProvenance,
|
|
6307
|
+
scheduledSessionId: overrideSessionId,
|
|
6288
6308
|
reply
|
|
6289
6309
|
});
|
|
6290
6310
|
} catch (err) {
|
|
@@ -6294,7 +6314,7 @@ function createScheduleInjectRoutes(deps) {
|
|
|
6294
6314
|
console.error(`${TAG16} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
|
|
6295
6315
|
return c.json({ ok: true }, 200);
|
|
6296
6316
|
});
|
|
6297
|
-
return
|
|
6317
|
+
return app61;
|
|
6298
6318
|
}
|
|
6299
6319
|
|
|
6300
6320
|
// server/index.ts
|
|
@@ -7380,6 +7400,19 @@ function filterConversationsForSubAccount(conversations, managerPhones) {
|
|
|
7380
7400
|
return out;
|
|
7381
7401
|
}
|
|
7382
7402
|
|
|
7403
|
+
// app/lib/whatsapp/authorize-recall-read.ts
|
|
7404
|
+
function authorizeRecallRead(input) {
|
|
7405
|
+
const { requestedAccountId } = input;
|
|
7406
|
+
const callerAccountId = input.callerAccountId && input.callerAccountId.length > 0 ? input.callerAccountId : null;
|
|
7407
|
+
const houseAdminScope = input.houseAdminScope && input.houseAdminScope.length > 0 ? input.houseAdminScope : null;
|
|
7408
|
+
if (houseAdminScope) return { authorized: true };
|
|
7409
|
+
if (callerAccountId && requestedAccountId === callerAccountId) return { authorized: true };
|
|
7410
|
+
return {
|
|
7411
|
+
authorized: false,
|
|
7412
|
+
reason: `Not authorized to read WhatsApp history for account "${requestedAccountId}". This session may only read its own account.`
|
|
7413
|
+
};
|
|
7414
|
+
}
|
|
7415
|
+
|
|
7383
7416
|
// server/routes/whatsapp.ts
|
|
7384
7417
|
var TAG21 = "[whatsapp:api]";
|
|
7385
7418
|
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
@@ -7401,6 +7434,14 @@ function projectionFor(requestedAccountId) {
|
|
|
7401
7434
|
houseAccountManagers
|
|
7402
7435
|
});
|
|
7403
7436
|
}
|
|
7437
|
+
function callerScopeDenial(c, requestedAccountId) {
|
|
7438
|
+
const callerAccountId = c.req.header("x-maxy-caller-account")?.trim() || null;
|
|
7439
|
+
const houseAdminScope = c.req.header("x-maxy-house-admin-scope")?.trim() || null;
|
|
7440
|
+
const decision = authorizeRecallRead({ requestedAccountId, callerAccountId, houseAdminScope });
|
|
7441
|
+
if (decision.authorized) return null;
|
|
7442
|
+
console.error(`[whatsapp-read-tool] op=authz-deny requested=${requestedAccountId} caller=${callerAccountId ?? "none"} houseAdmin=${houseAdminScope ? "y" : "n"}`);
|
|
7443
|
+
return c.json({ error: decision.reason }, 403);
|
|
7444
|
+
}
|
|
7404
7445
|
var app2 = new Hono();
|
|
7405
7446
|
app2.get("/status", (c) => {
|
|
7406
7447
|
try {
|
|
@@ -7705,6 +7746,8 @@ app2.get("/activity", (c) => {
|
|
|
7705
7746
|
app2.get("/conversations", (c) => {
|
|
7706
7747
|
try {
|
|
7707
7748
|
const accountId = validateAccountId(c.req.query("accountId") ?? null);
|
|
7749
|
+
const denial = callerScopeDenial(c, accountId);
|
|
7750
|
+
if (denial) return denial;
|
|
7708
7751
|
const jids = listConversationJids(accountId);
|
|
7709
7752
|
const conversations = jids.map((jid) => {
|
|
7710
7753
|
const messages = getMessages(accountId, jid);
|
|
@@ -7727,6 +7770,8 @@ app2.get("/conversations", (c) => {
|
|
|
7727
7770
|
app2.get("/messages", (c) => {
|
|
7728
7771
|
try {
|
|
7729
7772
|
const accountId = validateAccountId(c.req.query("accountId") ?? null);
|
|
7773
|
+
const denial = callerScopeDenial(c, accountId);
|
|
7774
|
+
if (denial) return denial;
|
|
7730
7775
|
const jid = c.req.query("jid");
|
|
7731
7776
|
if (!jid) {
|
|
7732
7777
|
return c.json({ error: "Missing required parameter: jid" }, 400);
|
|
@@ -7748,6 +7793,8 @@ app2.get("/conversation-graph-state", async (c) => {
|
|
|
7748
7793
|
const jid = c.req.query("jid");
|
|
7749
7794
|
const accountIdQuery = c.req.query("accountId");
|
|
7750
7795
|
const t0 = Date.now();
|
|
7796
|
+
const denial = callerScopeDenial(c, validateAccountId(accountIdQuery ?? null));
|
|
7797
|
+
if (denial) return denial;
|
|
7751
7798
|
if (!directCacheKey && !jid) {
|
|
7752
7799
|
const requestedAccountId = validateAccountId(accountIdQuery ?? null);
|
|
7753
7800
|
const projection2 = projectionFor(requestedAccountId);
|
|
@@ -9942,8 +9989,8 @@ async function reapplyLeversViaManager() {
|
|
|
9942
9989
|
var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
|
|
9943
9990
|
var sendSeq = 0;
|
|
9944
9991
|
function createWebchatRoutes(deps) {
|
|
9945
|
-
const
|
|
9946
|
-
|
|
9992
|
+
const app61 = new Hono();
|
|
9993
|
+
app61.post("/send", requireAdminSession, async (c) => {
|
|
9947
9994
|
let accountId;
|
|
9948
9995
|
try {
|
|
9949
9996
|
accountId = resolvePlatformAccountId();
|
|
@@ -10143,7 +10190,7 @@ ${note}` : note;
|
|
|
10143
10190
|
if (turnTimer.unref) turnTimer.unref();
|
|
10144
10191
|
return c.json({ ok: true });
|
|
10145
10192
|
});
|
|
10146
|
-
|
|
10193
|
+
app61.post("/interrupt", requireAdminSession, async (c) => {
|
|
10147
10194
|
const cacheKey = c.get("cacheKey");
|
|
10148
10195
|
const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
|
|
10149
10196
|
const primaryUserId = resolvePrimaryAdminUserId();
|
|
@@ -10171,7 +10218,7 @@ ${note}` : note;
|
|
|
10171
10218
|
}
|
|
10172
10219
|
return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
|
|
10173
10220
|
});
|
|
10174
|
-
|
|
10221
|
+
app61.post("/settings", requireAdminSession, async (c) => {
|
|
10175
10222
|
const body = await c.req.json().catch(() => null);
|
|
10176
10223
|
const op = body?.op;
|
|
10177
10224
|
const value = body?.value;
|
|
@@ -10211,7 +10258,7 @@ ${note}` : note;
|
|
|
10211
10258
|
console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
|
|
10212
10259
|
return c.json({ ok: true, settingsApplied });
|
|
10213
10260
|
});
|
|
10214
|
-
|
|
10261
|
+
app61.get("/session", requireAdminSession, async (c) => {
|
|
10215
10262
|
let accountId;
|
|
10216
10263
|
try {
|
|
10217
10264
|
accountId = resolvePlatformAccountId();
|
|
@@ -10289,7 +10336,7 @@ ${note}` : note;
|
|
|
10289
10336
|
const indicators = await fetchComposerIndicators(sessionId);
|
|
10290
10337
|
return c.json({ sessionId, projectDir, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
|
|
10291
10338
|
});
|
|
10292
|
-
|
|
10339
|
+
app61.post("/permission-verdict", requireAdminSession, async (c) => {
|
|
10293
10340
|
const body = await c.req.json().catch(() => null);
|
|
10294
10341
|
const sessionId = body?.sessionId;
|
|
10295
10342
|
const requestId = body?.request_id;
|
|
@@ -10306,7 +10353,7 @@ ${note}` : note;
|
|
|
10306
10353
|
const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
|
|
10307
10354
|
return c.json({ ok });
|
|
10308
10355
|
});
|
|
10309
|
-
return
|
|
10356
|
+
return app61;
|
|
10310
10357
|
}
|
|
10311
10358
|
|
|
10312
10359
|
// server/routes/webchat-greeting.ts
|
|
@@ -13343,18 +13390,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
13343
13390
|
]);
|
|
13344
13391
|
var app20 = new Hono();
|
|
13345
13392
|
app20.post("/", async (c) => {
|
|
13346
|
-
const
|
|
13393
|
+
const TAG44 = "[admin:events]";
|
|
13347
13394
|
let body;
|
|
13348
13395
|
try {
|
|
13349
13396
|
body = await c.req.json();
|
|
13350
13397
|
} catch (err) {
|
|
13351
13398
|
const detail = err instanceof Error ? err.message : String(err);
|
|
13352
|
-
console.error(`${
|
|
13399
|
+
console.error(`${TAG44} reject reason=body-not-json detail=${detail}`);
|
|
13353
13400
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
13354
13401
|
}
|
|
13355
13402
|
const event = typeof body.event === "string" ? body.event : "";
|
|
13356
13403
|
if (!ALLOWED_EVENTS.has(event)) {
|
|
13357
|
-
console.error(`${
|
|
13404
|
+
console.error(`${TAG44} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
13358
13405
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
13359
13406
|
}
|
|
13360
13407
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -19289,52 +19336,307 @@ app45.get("/booking-link", requireAdminSession, (c) => {
|
|
|
19289
19336
|
});
|
|
19290
19337
|
var calendar_default = app45;
|
|
19291
19338
|
|
|
19292
|
-
//
|
|
19339
|
+
// app/lib/time-entry-format.ts
|
|
19340
|
+
function secondsBetween(startIso, endIso) {
|
|
19341
|
+
const s = Date.parse(startIso);
|
|
19342
|
+
const e = Date.parse(endIso);
|
|
19343
|
+
if (!Number.isFinite(s) || !Number.isFinite(e)) return 0;
|
|
19344
|
+
return Math.max(0, Math.round((e - s) / 1e3));
|
|
19345
|
+
}
|
|
19346
|
+
function toNum(v) {
|
|
19347
|
+
if (v == null) return 0;
|
|
19348
|
+
if (typeof v === "number") return v;
|
|
19349
|
+
if (typeof v === "object" && typeof v.toNumber === "function") {
|
|
19350
|
+
return v.toNumber();
|
|
19351
|
+
}
|
|
19352
|
+
const n = Number(v);
|
|
19353
|
+
return Number.isFinite(n) ? n : 0;
|
|
19354
|
+
}
|
|
19355
|
+
|
|
19356
|
+
// server/routes/admin/tasks-list.ts
|
|
19357
|
+
var TAG33 = "[task-timer]";
|
|
19358
|
+
var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
|
|
19359
|
+
var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
|
|
19293
19360
|
var app46 = new Hono();
|
|
19294
|
-
app46.
|
|
19295
|
-
|
|
19296
|
-
|
|
19297
|
-
|
|
19298
|
-
|
|
19299
|
-
|
|
19300
|
-
|
|
19301
|
-
|
|
19302
|
-
|
|
19303
|
-
|
|
19304
|
-
|
|
19305
|
-
|
|
19306
|
-
|
|
19307
|
-
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
|
|
19311
|
-
|
|
19312
|
-
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19318
|
-
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19361
|
+
app46.get("/", requireAdminSession, async (c) => {
|
|
19362
|
+
const cacheKey = c.var.cacheKey;
|
|
19363
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
19364
|
+
if (!accountId) {
|
|
19365
|
+
console.error(`${TAG33} op=list auth-rejected reason="no account for session"`);
|
|
19366
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
19367
|
+
}
|
|
19368
|
+
const session = getSession();
|
|
19369
|
+
try {
|
|
19370
|
+
const result = await session.run(
|
|
19371
|
+
`MATCH (t:Task {accountId: $accountId})
|
|
19372
|
+
OPTIONAL MATCH (te:TimeEntry {taskId: t.taskId, accountId: $accountId})
|
|
19373
|
+
WHERE te.endedAt IS NULL
|
|
19374
|
+
WITH t, te ORDER BY te.startedAt
|
|
19375
|
+
WITH t, head(collect(te)) AS openTe
|
|
19376
|
+
RETURN t.taskId AS taskId, t.name AS name, t.clientName AS clientName,
|
|
19377
|
+
t.propertyAddress AS propertyAddress, t.fee AS fee, t.status AS status,
|
|
19378
|
+
coalesce(t.secondsLogged, 0) AS secondsLogged,
|
|
19379
|
+
openTe.startedAt AS runningStartedAt
|
|
19380
|
+
ORDER BY t.createdAt DESC`,
|
|
19381
|
+
{ accountId }
|
|
19382
|
+
);
|
|
19383
|
+
const open = [];
|
|
19384
|
+
const completed = [];
|
|
19385
|
+
for (const rec of result.records) {
|
|
19386
|
+
const status = rec.get("status") ?? "pending";
|
|
19387
|
+
const runningStartedAt = rec.get("runningStartedAt") ?? null;
|
|
19388
|
+
const fee = rec.get("fee");
|
|
19389
|
+
const row = {
|
|
19390
|
+
taskId: rec.get("taskId"),
|
|
19391
|
+
name: rec.get("name") ?? "",
|
|
19392
|
+
clientName: rec.get("clientName") ?? null,
|
|
19393
|
+
propertyAddress: rec.get("propertyAddress") ?? null,
|
|
19394
|
+
fee: fee == null ? null : toNum(fee),
|
|
19395
|
+
status,
|
|
19396
|
+
secondsLogged: toNum(rec.get("secondsLogged")),
|
|
19397
|
+
running: runningStartedAt !== null,
|
|
19398
|
+
runningStartedAt
|
|
19399
|
+
};
|
|
19400
|
+
if (COMPLETED.has(status)) completed.push(row);
|
|
19401
|
+
else if (!HIDDEN_FROM_OPEN.has(status)) open.push(row);
|
|
19402
|
+
}
|
|
19403
|
+
console.log(`${TAG33} op=list account=${accountId} open=${open.length} completed=${completed.length}`);
|
|
19404
|
+
return c.json({ open, completed });
|
|
19405
|
+
} catch (err) {
|
|
19406
|
+
console.error(`${TAG33} op=list error="${err instanceof Error ? err.message : String(err)}"`);
|
|
19407
|
+
return c.json({ error: "tasks-list-failed" }, 500);
|
|
19408
|
+
} finally {
|
|
19409
|
+
await session.close();
|
|
19410
|
+
}
|
|
19411
|
+
});
|
|
19412
|
+
var tasks_list_default = app46;
|
|
19413
|
+
|
|
19414
|
+
// server/routes/admin/task-timer-start.ts
|
|
19415
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
19416
|
+
import neo4j5 from "neo4j-driver";
|
|
19417
|
+
var TAG34 = "[task-timer]";
|
|
19418
|
+
var app47 = new Hono();
|
|
19419
|
+
app47.post("/", requireAdminSession, async (c) => {
|
|
19420
|
+
const cacheKey = c.var.cacheKey;
|
|
19421
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
19422
|
+
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
19423
|
+
let body;
|
|
19424
|
+
try {
|
|
19425
|
+
body = await c.req.json();
|
|
19426
|
+
} catch {
|
|
19427
|
+
return c.json({ error: "invalid-json" }, 400);
|
|
19428
|
+
}
|
|
19429
|
+
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
19430
|
+
if (!taskId) return c.json({ error: "taskId required" }, 400);
|
|
19431
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19432
|
+
const session = getSession();
|
|
19433
|
+
try {
|
|
19434
|
+
const target = await session.run(
|
|
19435
|
+
`MATCH (t:Task {taskId: $taskId, accountId: $accountId}) RETURN t.taskId AS taskId LIMIT 1`,
|
|
19436
|
+
{ taskId, accountId }
|
|
19437
|
+
);
|
|
19438
|
+
if (target.records.length === 0) {
|
|
19439
|
+
console.error(`${TAG34} op=start taskId=${taskId} accountId=${accountId} result=task-not-found`);
|
|
19440
|
+
return c.json({ error: "task-not-found" }, 404);
|
|
19441
|
+
}
|
|
19442
|
+
const open = await session.run(
|
|
19443
|
+
`MATCH (te:TimeEntry {accountId: $accountId}) WHERE te.endedAt IS NULL
|
|
19444
|
+
RETURN te.entryId AS entryId, te.taskId AS taskId, te.startedAt AS startedAt
|
|
19445
|
+
ORDER BY te.startedAt LIMIT 1`,
|
|
19446
|
+
{ accountId }
|
|
19447
|
+
);
|
|
19448
|
+
const priorEntryId = open.records[0]?.get("entryId");
|
|
19449
|
+
const priorTaskId = open.records[0]?.get("taskId");
|
|
19450
|
+
const priorStartedAt = open.records[0]?.get("startedAt");
|
|
19451
|
+
console.log(`${TAG34} op=start taskId=${taskId} accountId=${accountId} priorOpen=${priorTaskId ?? "none"}`);
|
|
19452
|
+
if (priorEntryId && priorTaskId === taskId) {
|
|
19453
|
+
return c.json({ ok: true, running: true, entryId: priorEntryId, startedAt: priorStartedAt });
|
|
19454
|
+
}
|
|
19455
|
+
if (priorEntryId && priorStartedAt && priorTaskId) {
|
|
19456
|
+
const seconds = secondsBetween(priorStartedAt, now);
|
|
19457
|
+
await session.run(
|
|
19458
|
+
`MATCH (te:TimeEntry {entryId: $priorEntryId}) WHERE te.endedAt IS NULL
|
|
19459
|
+
SET te.endedAt = $now, te.seconds = $seconds
|
|
19460
|
+
WITH te
|
|
19461
|
+
MATCH (t:Task {taskId: $priorTaskId, accountId: $accountId})
|
|
19462
|
+
SET t.secondsLogged = coalesce(t.secondsLogged, 0) + $seconds`,
|
|
19463
|
+
{ priorEntryId, priorTaskId, accountId, now, seconds: neo4j5.int(seconds) }
|
|
19464
|
+
);
|
|
19465
|
+
console.log(`${TAG34} op=autostop taskId=${priorTaskId} entryId=${priorEntryId} seconds=${seconds}`);
|
|
19466
|
+
}
|
|
19467
|
+
const entryId = randomUUID13();
|
|
19468
|
+
await session.run(
|
|
19469
|
+
`MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
19470
|
+
CREATE (te:TimeEntry {entryId: $entryId, taskId: $taskId, accountId: $accountId, startedAt: $now, endedAt: null})
|
|
19471
|
+
CREATE (te)-[:LOGGED_AGAINST]->(t)`,
|
|
19472
|
+
{ taskId, accountId, entryId, now }
|
|
19473
|
+
);
|
|
19474
|
+
console.log(`${TAG34} op=opened taskId=${taskId} entryId=${entryId} startedAt=${now}`);
|
|
19475
|
+
return c.json({ ok: true, running: true, entryId, startedAt: now });
|
|
19476
|
+
} catch (err) {
|
|
19477
|
+
console.error(`${TAG34} op=start error="${err instanceof Error ? err.message : String(err)}"`);
|
|
19478
|
+
return c.json({ error: "task-timer-start-failed" }, 500);
|
|
19479
|
+
} finally {
|
|
19480
|
+
await session.close();
|
|
19481
|
+
}
|
|
19482
|
+
});
|
|
19483
|
+
var task_timer_start_default = app47;
|
|
19484
|
+
|
|
19485
|
+
// server/routes/admin/task-timer-stop.ts
|
|
19486
|
+
import neo4j6 from "neo4j-driver";
|
|
19487
|
+
var TAG35 = "[task-timer]";
|
|
19488
|
+
var app48 = new Hono();
|
|
19489
|
+
app48.post("/", requireAdminSession, async (c) => {
|
|
19490
|
+
const cacheKey = c.var.cacheKey;
|
|
19491
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
19492
|
+
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
19493
|
+
let body;
|
|
19494
|
+
try {
|
|
19495
|
+
body = await c.req.json();
|
|
19496
|
+
} catch {
|
|
19497
|
+
return c.json({ error: "invalid-json" }, 400);
|
|
19498
|
+
}
|
|
19499
|
+
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
19500
|
+
if (!taskId) return c.json({ error: "taskId required" }, 400);
|
|
19501
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19502
|
+
const session = getSession();
|
|
19503
|
+
try {
|
|
19504
|
+
const open = await session.run(
|
|
19505
|
+
`MATCH (te:TimeEntry {taskId: $taskId, accountId: $accountId}) WHERE te.endedAt IS NULL
|
|
19506
|
+
RETURN te.entryId AS entryId, te.startedAt AS startedAt
|
|
19507
|
+
ORDER BY te.startedAt LIMIT 1`,
|
|
19508
|
+
{ taskId, accountId }
|
|
19509
|
+
);
|
|
19510
|
+
const entryId = open.records[0]?.get("entryId");
|
|
19511
|
+
const startedAt = open.records[0]?.get("startedAt");
|
|
19512
|
+
if (!entryId || !startedAt) {
|
|
19513
|
+
const cur = await session.run(
|
|
19514
|
+
`MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
19515
|
+
RETURN coalesce(t.secondsLogged, 0) AS secondsLogged`,
|
|
19516
|
+
{ taskId, accountId }
|
|
19517
|
+
);
|
|
19518
|
+
const secondsLogged2 = toNum(cur.records[0]?.get("secondsLogged"));
|
|
19519
|
+
console.log(`${TAG35} op=stop taskId=${taskId} entryId=none seconds=0 totalAfter=${secondsLogged2}`);
|
|
19520
|
+
return c.json({ ok: true, running: false, seconds: 0, secondsLogged: secondsLogged2 });
|
|
19521
|
+
}
|
|
19522
|
+
const seconds = secondsBetween(startedAt, now);
|
|
19523
|
+
await session.run(
|
|
19524
|
+
`MATCH (te:TimeEntry {entryId: $entryId}) WHERE te.endedAt IS NULL
|
|
19525
|
+
SET te.endedAt = $now, te.seconds = $seconds
|
|
19526
|
+
WITH te
|
|
19527
|
+
MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
19528
|
+
SET t.secondsLogged = coalesce(t.secondsLogged, 0) + $seconds`,
|
|
19529
|
+
{ entryId, taskId, accountId, now, seconds: neo4j6.int(seconds) }
|
|
19530
|
+
);
|
|
19531
|
+
const verify = await session.run(
|
|
19532
|
+
`MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
19533
|
+
OPTIONAL MATCH (te:TimeEntry {taskId: $taskId, accountId: $accountId}) WHERE te.endedAt IS NOT NULL
|
|
19534
|
+
RETURN coalesce(sum(te.seconds), 0) AS sumEntries, coalesce(t.secondsLogged, 0) AS secondsLogged`,
|
|
19535
|
+
{ taskId, accountId }
|
|
19536
|
+
);
|
|
19537
|
+
const sumEntries = toNum(verify.records[0]?.get("sumEntries"));
|
|
19538
|
+
const secondsLogged = toNum(verify.records[0]?.get("secondsLogged"));
|
|
19539
|
+
console.log(`${TAG35} op=stop taskId=${taskId} entryId=${entryId} seconds=${seconds} totalAfter=${secondsLogged}`);
|
|
19540
|
+
console.log(`${TAG35} op=persisted taskId=${taskId} entryId=${entryId} sumEntries=${sumEntries} secondsLogged=${secondsLogged}`);
|
|
19541
|
+
return c.json({ ok: true, running: false, seconds, secondsLogged });
|
|
19542
|
+
} catch (err) {
|
|
19543
|
+
console.error(`${TAG35} op=stop error="${err instanceof Error ? err.message : String(err)}"`);
|
|
19544
|
+
return c.json({ error: "task-timer-stop-failed" }, 500);
|
|
19545
|
+
} finally {
|
|
19546
|
+
await session.close();
|
|
19547
|
+
}
|
|
19548
|
+
});
|
|
19549
|
+
var task_timer_stop_default = app48;
|
|
19550
|
+
|
|
19551
|
+
// server/routes/admin/task-complete.ts
|
|
19552
|
+
var TAG36 = "[task-timer]";
|
|
19553
|
+
var app49 = new Hono();
|
|
19554
|
+
app49.post("/", requireAdminSession, async (c) => {
|
|
19555
|
+
const cacheKey = c.var.cacheKey;
|
|
19556
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
19557
|
+
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
19558
|
+
let body;
|
|
19559
|
+
try {
|
|
19560
|
+
body = await c.req.json();
|
|
19561
|
+
} catch {
|
|
19562
|
+
return c.json({ error: "invalid-json" }, 400);
|
|
19563
|
+
}
|
|
19564
|
+
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
19565
|
+
if (!taskId) return c.json({ error: "taskId required" }, 400);
|
|
19566
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19567
|
+
const session = getSession();
|
|
19568
|
+
try {
|
|
19569
|
+
const result = await session.run(
|
|
19570
|
+
`MATCH (t:Task {taskId: $taskId, accountId: $accountId})
|
|
19571
|
+
SET t.status = 'completed', t.updatedAt = $now
|
|
19572
|
+
RETURN t.taskId AS taskId, coalesce(t.secondsLogged, 0) AS secondsLogged`,
|
|
19573
|
+
{ taskId, accountId, now }
|
|
19574
|
+
);
|
|
19575
|
+
if (result.records.length === 0) {
|
|
19576
|
+
return c.json({ error: "task-not-found" }, 404);
|
|
19577
|
+
}
|
|
19578
|
+
const secondsLogged = toNum(result.records[0].get("secondsLogged"));
|
|
19579
|
+
console.log(`${TAG36} op=complete taskId=${taskId} status=completed secondsLogged=${secondsLogged}`);
|
|
19580
|
+
return c.json({ ok: true, status: "completed", secondsLogged });
|
|
19581
|
+
} catch (err) {
|
|
19582
|
+
console.error(`${TAG36} op=complete error="${err instanceof Error ? err.message : String(err)}"`);
|
|
19583
|
+
return c.json({ error: "task-complete-failed" }, 500);
|
|
19584
|
+
} finally {
|
|
19585
|
+
await session.close();
|
|
19586
|
+
}
|
|
19587
|
+
});
|
|
19588
|
+
var task_complete_default = app49;
|
|
19589
|
+
|
|
19590
|
+
// server/routes/admin/index.ts
|
|
19591
|
+
var app50 = new Hono();
|
|
19592
|
+
app50.route("/session", session_default);
|
|
19593
|
+
app50.route("/accounts", accounts_default);
|
|
19594
|
+
app50.route("/logs", logs_default);
|
|
19595
|
+
app50.route("/claude-info", claude_info_default);
|
|
19596
|
+
app50.route("/attachment", attachment_default);
|
|
19597
|
+
app50.route("/agents", agents_default);
|
|
19598
|
+
app50.route("/sessions", sessions_default);
|
|
19599
|
+
app50.route("/claude-sessions", claude_sessions_default);
|
|
19600
|
+
app50.route("/log-ingest", log_ingest_default);
|
|
19601
|
+
app50.route("/events", events_default);
|
|
19602
|
+
app50.route("/files", files_default);
|
|
19603
|
+
app50.route("/graph-search", graph_search_default);
|
|
19604
|
+
app50.route("/graph-subgraph", graph_subgraph_default);
|
|
19605
|
+
app50.route("/graph-delete", graph_delete_default);
|
|
19606
|
+
app50.route("/graph-restore", graph_restore_default);
|
|
19607
|
+
app50.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
19608
|
+
app50.route("/graph-default-view", graph_default_view_default);
|
|
19609
|
+
app50.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
19610
|
+
app50.route("/sidebar-sessions", sidebar_sessions_default);
|
|
19611
|
+
app50.route("/session-delete", session_delete_default);
|
|
19612
|
+
app50.route("/session-stop", session_stop_default);
|
|
19613
|
+
app50.route("/session-archive", session_archive_default);
|
|
19614
|
+
app50.route("/session-rename", session_rename_default);
|
|
19615
|
+
app50.route("/session-usage", session_usage_default);
|
|
19616
|
+
app50.route("/browser", browser_default);
|
|
19617
|
+
app50.route("/session-rc-spawn", session_rc_spawn_default);
|
|
19618
|
+
app50.route("/session-reseat", session_reseat_default);
|
|
19619
|
+
app50.route("/system-stats", system_stats_default);
|
|
19620
|
+
app50.route("/health-brand", health_default2);
|
|
19621
|
+
app50.route("/linkedin-ingest", linkedin_ingest_default);
|
|
19622
|
+
app50.route("/post-turn-context", post_turn_context_default);
|
|
19623
|
+
app50.route("/public-session-context", public_session_context_default);
|
|
19624
|
+
app50.route("/public-session-exit", public_session_exit_default);
|
|
19625
|
+
app50.route("/access-session-evict", access_session_evict_default);
|
|
19626
|
+
app50.route("/enrol-person", enrol_person_default);
|
|
19627
|
+
app50.route("/calendar", calendar_default);
|
|
19628
|
+
app50.route("/tasks-list", tasks_list_default);
|
|
19629
|
+
app50.route("/task-timer-start", task_timer_start_default);
|
|
19630
|
+
app50.route("/task-timer-stop", task_timer_stop_default);
|
|
19631
|
+
app50.route("/task-complete", task_complete_default);
|
|
19632
|
+
var admin_default = app50;
|
|
19331
19633
|
|
|
19332
19634
|
// server/routes/access/verify-token.ts
|
|
19333
|
-
var
|
|
19635
|
+
var TAG37 = "[access-verify]";
|
|
19334
19636
|
var MINT_TAG = "[access-session-mint]";
|
|
19335
19637
|
var COOKIE_NAME = "__access_session";
|
|
19336
|
-
var
|
|
19337
|
-
|
|
19638
|
+
var app51 = new Hono();
|
|
19639
|
+
app51.post("/", async (c) => {
|
|
19338
19640
|
const ip = c.var.clientIp || "unknown";
|
|
19339
19641
|
let body;
|
|
19340
19642
|
try {
|
|
@@ -19349,39 +19651,39 @@ app47.post("/", async (c) => {
|
|
|
19349
19651
|
}
|
|
19350
19652
|
const rateMsg = checkAccessRateLimit(ip, agentSlug);
|
|
19351
19653
|
if (rateMsg) {
|
|
19352
|
-
console.error(`${
|
|
19654
|
+
console.error(`${TAG37} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
|
|
19353
19655
|
return c.json({ error: rateMsg }, 429);
|
|
19354
19656
|
}
|
|
19355
19657
|
const grant = await findGrantByMagicToken(token);
|
|
19356
19658
|
if (!grant) {
|
|
19357
19659
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
19358
|
-
console.error(`${
|
|
19660
|
+
console.error(`${TAG37} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
|
|
19359
19661
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
19360
19662
|
}
|
|
19361
19663
|
if (grant.agentSlug !== agentSlug) {
|
|
19362
19664
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
19363
19665
|
console.error(
|
|
19364
|
-
`${
|
|
19666
|
+
`${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
|
|
19365
19667
|
);
|
|
19366
19668
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
19367
19669
|
}
|
|
19368
19670
|
if (grant.status === "expired" || grant.status === "revoked") {
|
|
19369
19671
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
19370
19672
|
console.error(
|
|
19371
|
-
`${
|
|
19673
|
+
`${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
|
|
19372
19674
|
);
|
|
19373
19675
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
19374
19676
|
}
|
|
19375
19677
|
if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
|
|
19376
19678
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
19377
19679
|
console.error(
|
|
19378
|
-
`${
|
|
19680
|
+
`${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
|
|
19379
19681
|
);
|
|
19380
19682
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
19381
19683
|
}
|
|
19382
19684
|
if (!grant.sliceToken) {
|
|
19383
19685
|
console.error(
|
|
19384
|
-
`${
|
|
19686
|
+
`${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
|
|
19385
19687
|
);
|
|
19386
19688
|
return c.json({ error: "grant-misconfigured" }, 500);
|
|
19387
19689
|
}
|
|
@@ -19397,12 +19699,12 @@ app47.post("/", async (c) => {
|
|
|
19397
19699
|
await consumeMagicTokenAndActivate(grant.grantId);
|
|
19398
19700
|
} catch (err) {
|
|
19399
19701
|
console.error(
|
|
19400
|
-
`${
|
|
19702
|
+
`${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
19401
19703
|
);
|
|
19402
19704
|
return c.json({ error: "verification-failed" }, 500);
|
|
19403
19705
|
}
|
|
19404
19706
|
clearAccessRateLimit(ip, agentSlug);
|
|
19405
|
-
console.log(`${
|
|
19707
|
+
console.log(`${TAG37} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
|
|
19406
19708
|
console.log(
|
|
19407
19709
|
`${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
|
|
19408
19710
|
);
|
|
@@ -19416,7 +19718,7 @@ app47.post("/", async (c) => {
|
|
|
19416
19718
|
displayName: grant.displayName
|
|
19417
19719
|
});
|
|
19418
19720
|
});
|
|
19419
|
-
var verify_token_default =
|
|
19721
|
+
var verify_token_default = app51;
|
|
19420
19722
|
|
|
19421
19723
|
// app/lib/access-email.ts
|
|
19422
19724
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -19478,10 +19780,10 @@ async function sendMagicLinkEmail(payload) {
|
|
|
19478
19780
|
}
|
|
19479
19781
|
|
|
19480
19782
|
// server/routes/access/request-magic-link.ts
|
|
19481
|
-
var
|
|
19482
|
-
var
|
|
19783
|
+
var TAG38 = "[access-request-link]";
|
|
19784
|
+
var app52 = new Hono();
|
|
19483
19785
|
var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
|
|
19484
|
-
|
|
19786
|
+
app52.post("/", async (c) => {
|
|
19485
19787
|
let body;
|
|
19486
19788
|
try {
|
|
19487
19789
|
body = await c.req.json();
|
|
@@ -19495,18 +19797,18 @@ app48.post("/", async (c) => {
|
|
|
19495
19797
|
}
|
|
19496
19798
|
const rateMsg = checkRequestLinkRateLimit(contactValue);
|
|
19497
19799
|
if (rateMsg) {
|
|
19498
|
-
console.error(`${
|
|
19800
|
+
console.error(`${TAG38} contactValue=${maskContact(contactValue)} result=rate-limited`);
|
|
19499
19801
|
return c.json({ error: rateMsg }, 429);
|
|
19500
19802
|
}
|
|
19501
19803
|
recordRequestLinkAttempt(contactValue);
|
|
19502
19804
|
const accountId = process.env.ACCOUNT_ID ?? "";
|
|
19503
19805
|
if (!accountId) {
|
|
19504
|
-
console.error(`${
|
|
19806
|
+
console.error(`${TAG38} contactValue=${maskContact(contactValue)} result=no-account-id`);
|
|
19505
19807
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
19506
19808
|
}
|
|
19507
19809
|
const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
|
|
19508
19810
|
if (!grant) {
|
|
19509
|
-
console.log(`${
|
|
19811
|
+
console.log(`${TAG38} contactValue=${maskContact(contactValue)} result=notfound`);
|
|
19510
19812
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
19511
19813
|
}
|
|
19512
19814
|
let token;
|
|
@@ -19514,7 +19816,7 @@ app48.post("/", async (c) => {
|
|
|
19514
19816
|
token = await generateNewMagicToken(grant.grantId);
|
|
19515
19817
|
} catch (err) {
|
|
19516
19818
|
console.error(
|
|
19517
|
-
`${
|
|
19819
|
+
`${TAG38} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
19518
19820
|
);
|
|
19519
19821
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
19520
19822
|
}
|
|
@@ -19546,22 +19848,22 @@ app48.post("/", async (c) => {
|
|
|
19546
19848
|
});
|
|
19547
19849
|
if (!sendResult.ok) {
|
|
19548
19850
|
console.error(
|
|
19549
|
-
`${
|
|
19851
|
+
`${TAG38} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
|
|
19550
19852
|
);
|
|
19551
19853
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
19552
19854
|
}
|
|
19553
19855
|
console.log(
|
|
19554
|
-
`${
|
|
19856
|
+
`${TAG38} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
|
|
19555
19857
|
);
|
|
19556
19858
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
19557
19859
|
});
|
|
19558
|
-
var request_magic_link_default =
|
|
19860
|
+
var request_magic_link_default = app52;
|
|
19559
19861
|
|
|
19560
19862
|
// server/routes/access/index.ts
|
|
19561
|
-
var
|
|
19562
|
-
|
|
19563
|
-
|
|
19564
|
-
var access_default =
|
|
19863
|
+
var app53 = new Hono();
|
|
19864
|
+
app53.route("/verify-token", verify_token_default);
|
|
19865
|
+
app53.route("/request-magic-link", request_magic_link_default);
|
|
19866
|
+
var access_default = app53;
|
|
19565
19867
|
|
|
19566
19868
|
// server/routes/sites.ts
|
|
19567
19869
|
import { existsSync as existsSync28, readFileSync as readFileSync31, realpathSync as realpathSync6, statSync as statSync12 } from "fs";
|
|
@@ -19596,8 +19898,8 @@ function getExt(p) {
|
|
|
19596
19898
|
if (idx < p.lastIndexOf("/")) return "";
|
|
19597
19899
|
return p.slice(idx).toLowerCase();
|
|
19598
19900
|
}
|
|
19599
|
-
var
|
|
19600
|
-
|
|
19901
|
+
var app54 = new Hono();
|
|
19902
|
+
app54.get("/:rel{.*}", (c) => {
|
|
19601
19903
|
const reqPath = c.req.path;
|
|
19602
19904
|
const rawRel = c.req.param("rel") ?? "";
|
|
19603
19905
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -19700,7 +20002,7 @@ app50.get("/:rel{.*}", (c) => {
|
|
|
19700
20002
|
"X-Content-Type-Options": "nosniff"
|
|
19701
20003
|
});
|
|
19702
20004
|
});
|
|
19703
|
-
var sites_default =
|
|
20005
|
+
var sites_default = app54;
|
|
19704
20006
|
|
|
19705
20007
|
// app/lib/visitor-token.ts
|
|
19706
20008
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
@@ -19800,7 +20102,7 @@ function readBrandConfig() {
|
|
|
19800
20102
|
}
|
|
19801
20103
|
|
|
19802
20104
|
// server/routes/visitor-consent.ts
|
|
19803
|
-
var
|
|
20105
|
+
var app55 = new Hono();
|
|
19804
20106
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
19805
20107
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
19806
20108
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -19845,17 +20147,17 @@ function siteSlugFromReferer(referer) {
|
|
|
19845
20147
|
return "";
|
|
19846
20148
|
}
|
|
19847
20149
|
}
|
|
19848
|
-
|
|
20150
|
+
app55.options("/consent", (c) => {
|
|
19849
20151
|
const origin = getOrigin(c);
|
|
19850
20152
|
setCorsHeaders(c, origin);
|
|
19851
20153
|
return c.body(null, 204);
|
|
19852
20154
|
});
|
|
19853
|
-
|
|
20155
|
+
app55.options("/brand-config", (c) => {
|
|
19854
20156
|
const origin = getOrigin(c);
|
|
19855
20157
|
setCorsHeaders(c, origin);
|
|
19856
20158
|
return c.body(null, 204);
|
|
19857
20159
|
});
|
|
19858
|
-
|
|
20160
|
+
app55.post("/consent", async (c) => {
|
|
19859
20161
|
const origin = getOrigin(c);
|
|
19860
20162
|
setCorsHeaders(c, origin);
|
|
19861
20163
|
let raw;
|
|
@@ -19895,7 +20197,7 @@ app51.post("/consent", async (c) => {
|
|
|
19895
20197
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
19896
20198
|
return c.body(null, 204);
|
|
19897
20199
|
});
|
|
19898
|
-
|
|
20200
|
+
app55.get("/brand-config", (c) => {
|
|
19899
20201
|
const origin = getOrigin(c);
|
|
19900
20202
|
setCorsHeaders(c, origin);
|
|
19901
20203
|
const brand = readBrandConfig();
|
|
@@ -19905,7 +20207,7 @@ app51.get("/brand-config", (c) => {
|
|
|
19905
20207
|
c.header("Cache-Control", "public, max-age=300");
|
|
19906
20208
|
return c.json({ consent: { copy, palette } });
|
|
19907
20209
|
});
|
|
19908
|
-
var visitor_consent_default =
|
|
20210
|
+
var visitor_consent_default = app55;
|
|
19909
20211
|
|
|
19910
20212
|
// server/routes/listings.ts
|
|
19911
20213
|
function getCookie(headerValue, name) {
|
|
@@ -19932,8 +20234,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
19932
20234
|
}
|
|
19933
20235
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
19934
20236
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
19935
|
-
var
|
|
19936
|
-
|
|
20237
|
+
var app56 = new Hono();
|
|
20238
|
+
app56.get("/:slug/click", async (c) => {
|
|
19937
20239
|
const slug = c.req.param("slug") ?? "";
|
|
19938
20240
|
const rawSession = c.req.query("session") ?? "";
|
|
19939
20241
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -19997,10 +20299,10 @@ app52.get("/:slug/click", async (c) => {
|
|
|
19997
20299
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
19998
20300
|
return c.redirect(redirectUrl, 302);
|
|
19999
20301
|
});
|
|
20000
|
-
var listings_default =
|
|
20302
|
+
var listings_default = app56;
|
|
20001
20303
|
|
|
20002
20304
|
// server/routes/visitor-event.ts
|
|
20003
|
-
var
|
|
20305
|
+
var app57 = new Hono();
|
|
20004
20306
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
20005
20307
|
var buckets = /* @__PURE__ */ new Map();
|
|
20006
20308
|
var RATE_LIMIT = 60;
|
|
@@ -20067,12 +20369,12 @@ function originAllowed(origin, allowlist) {
|
|
|
20067
20369
|
return false;
|
|
20068
20370
|
}
|
|
20069
20371
|
}
|
|
20070
|
-
|
|
20372
|
+
app57.options("/event", (c) => {
|
|
20071
20373
|
const origin = getOrigin2(c);
|
|
20072
20374
|
setCorsHeaders2(c, origin);
|
|
20073
20375
|
return c.body(null, 204);
|
|
20074
20376
|
});
|
|
20075
|
-
|
|
20377
|
+
app57.post("/event", async (c) => {
|
|
20076
20378
|
const origin = getOrigin2(c);
|
|
20077
20379
|
setCorsHeaders2(c, origin);
|
|
20078
20380
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -20277,7 +20579,7 @@ async function writeEvent(opts) {
|
|
|
20277
20579
|
);
|
|
20278
20580
|
}
|
|
20279
20581
|
}
|
|
20280
|
-
var visitor_event_default =
|
|
20582
|
+
var visitor_event_default = app57;
|
|
20281
20583
|
|
|
20282
20584
|
// server/routes/session.ts
|
|
20283
20585
|
import { resolve as resolve27 } from "path";
|
|
@@ -20323,8 +20625,8 @@ function withVisitorCookie(response, visitorId) {
|
|
|
20323
20625
|
headers
|
|
20324
20626
|
});
|
|
20325
20627
|
}
|
|
20326
|
-
var
|
|
20327
|
-
|
|
20628
|
+
var app58 = new Hono();
|
|
20629
|
+
app58.post("/", async (c) => {
|
|
20328
20630
|
let body;
|
|
20329
20631
|
try {
|
|
20330
20632
|
body = await c.req.json();
|
|
@@ -20471,7 +20773,7 @@ app54.post("/", async (c) => {
|
|
|
20471
20773
|
newVisitorId
|
|
20472
20774
|
);
|
|
20473
20775
|
});
|
|
20474
|
-
var session_default2 =
|
|
20776
|
+
var session_default2 = app58;
|
|
20475
20777
|
|
|
20476
20778
|
// server/lib/calendar-slots.ts
|
|
20477
20779
|
var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
@@ -20554,17 +20856,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
|
|
|
20554
20856
|
}
|
|
20555
20857
|
|
|
20556
20858
|
// server/routes/calendar-public.ts
|
|
20557
|
-
var
|
|
20859
|
+
var app59 = new Hono();
|
|
20558
20860
|
function setCors(c) {
|
|
20559
20861
|
c.header("Access-Control-Allow-Origin", "*");
|
|
20560
20862
|
c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
20561
20863
|
c.header("Access-Control-Allow-Headers", "content-type");
|
|
20562
20864
|
}
|
|
20563
|
-
|
|
20865
|
+
app59.options("/free-busy", (c) => {
|
|
20564
20866
|
setCors(c);
|
|
20565
20867
|
return c.body(null, 204);
|
|
20566
20868
|
});
|
|
20567
|
-
|
|
20869
|
+
app59.get("/free-busy", async (c) => {
|
|
20568
20870
|
setCors(c);
|
|
20569
20871
|
const from = c.req.query("from");
|
|
20570
20872
|
const to = c.req.query("to");
|
|
@@ -20606,7 +20908,79 @@ app55.get("/free-busy", async (c) => {
|
|
|
20606
20908
|
await session.close();
|
|
20607
20909
|
}
|
|
20608
20910
|
});
|
|
20609
|
-
var calendar_public_default =
|
|
20911
|
+
var calendar_public_default = app59;
|
|
20912
|
+
|
|
20913
|
+
// app/lib/timeentry-census.ts
|
|
20914
|
+
var TAG39 = "[timeentry-census]";
|
|
20915
|
+
function reconcileTimeEntries(rows, now, horizonMs) {
|
|
20916
|
+
const openEntries = rows.openEntries.length;
|
|
20917
|
+
let oldestOpenAgeMs = 0;
|
|
20918
|
+
const perAccount = /* @__PURE__ */ new Map();
|
|
20919
|
+
for (const e of rows.openEntries) {
|
|
20920
|
+
oldestOpenAgeMs = Math.max(oldestOpenAgeMs, now - e.startedAtMs);
|
|
20921
|
+
perAccount.set(e.accountId, (perAccount.get(e.accountId) ?? 0) + 1);
|
|
20922
|
+
}
|
|
20923
|
+
const maxOpenPerAccount = perAccount.size === 0 ? 0 : Math.max(...perAccount.values());
|
|
20924
|
+
const driftTasks = rows.taskSums.filter((t) => t.secondsLogged !== t.sumEntries).length;
|
|
20925
|
+
const oldestOpenAgeMin = Math.floor(oldestOpenAgeMs / 6e4);
|
|
20926
|
+
const alarm = oldestOpenAgeMs > horizonMs || maxOpenPerAccount > 1 || driftTasks > 0;
|
|
20927
|
+
return { openEntries, oldestOpenAgeMin, maxOpenPerAccount, driftTasks, alarm };
|
|
20928
|
+
}
|
|
20929
|
+
async function runTimeEntryCensusOnce(session, now, horizonMs) {
|
|
20930
|
+
try {
|
|
20931
|
+
const openRes = await session.run(
|
|
20932
|
+
`MATCH (te:TimeEntry) WHERE te.endedAt IS NULL
|
|
20933
|
+
RETURN te.accountId AS accountId, te.startedAt AS startedAt`
|
|
20934
|
+
);
|
|
20935
|
+
const openEntries = openRes.records.map((r) => ({
|
|
20936
|
+
accountId: r.get("accountId") ?? "unknown",
|
|
20937
|
+
startedAtMs: Date.parse(r.get("startedAt") ?? "") || now
|
|
20938
|
+
}));
|
|
20939
|
+
const sumRes = await session.run(
|
|
20940
|
+
`MATCH (t:Task) WHERE t.secondsLogged IS NOT NULL
|
|
20941
|
+
OPTIONAL MATCH (te:TimeEntry {taskId: t.taskId}) WHERE te.endedAt IS NOT NULL
|
|
20942
|
+
RETURN t.taskId AS taskId, coalesce(t.secondsLogged, 0) AS secondsLogged, coalesce(sum(te.seconds), 0) AS sumEntries`
|
|
20943
|
+
);
|
|
20944
|
+
const taskSums = sumRes.records.map((r) => ({
|
|
20945
|
+
taskId: r.get("taskId") ?? "",
|
|
20946
|
+
secondsLogged: toNum(r.get("secondsLogged")),
|
|
20947
|
+
sumEntries: toNum(r.get("sumEntries"))
|
|
20948
|
+
}));
|
|
20949
|
+
const finding = reconcileTimeEntries({ openEntries, taskSums }, now, horizonMs);
|
|
20950
|
+
const line = `${TAG39} openEntries=${finding.openEntries} oldestOpenAgeMin=${finding.oldestOpenAgeMin} maxOpenPerAccount=${finding.maxOpenPerAccount} driftTasks=${finding.driftTasks}`;
|
|
20951
|
+
if (finding.alarm) console.error(`${line} alarm=true`);
|
|
20952
|
+
else console.log(line);
|
|
20953
|
+
return finding;
|
|
20954
|
+
} catch (err) {
|
|
20955
|
+
console.error(`${TAG39} error="${err instanceof Error ? err.message : String(err)}"`);
|
|
20956
|
+
return null;
|
|
20957
|
+
}
|
|
20958
|
+
}
|
|
20959
|
+
var DEFAULT_INTERVAL_MS = 15 * 60 * 1e3;
|
|
20960
|
+
var DEFAULT_HORIZON_MS = 8 * 60 * 60 * 1e3;
|
|
20961
|
+
function startTimeEntryCensus(openSession, opts = {}) {
|
|
20962
|
+
const intervalMs = opts.intervalMs ?? DEFAULT_INTERVAL_MS;
|
|
20963
|
+
const horizonMs = opts.horizonMs ?? DEFAULT_HORIZON_MS;
|
|
20964
|
+
const tick = async () => {
|
|
20965
|
+
const session = openSession();
|
|
20966
|
+
try {
|
|
20967
|
+
await runTimeEntryCensusOnce(session, Date.now(), horizonMs);
|
|
20968
|
+
} finally {
|
|
20969
|
+
try {
|
|
20970
|
+
await session.close();
|
|
20971
|
+
} catch {
|
|
20972
|
+
}
|
|
20973
|
+
}
|
|
20974
|
+
};
|
|
20975
|
+
void tick();
|
|
20976
|
+
const id = setInterval(() => {
|
|
20977
|
+
void tick();
|
|
20978
|
+
}, intervalMs);
|
|
20979
|
+
if (typeof id.unref === "function") {
|
|
20980
|
+
id.unref();
|
|
20981
|
+
}
|
|
20982
|
+
return () => clearInterval(id);
|
|
20983
|
+
}
|
|
20610
20984
|
|
|
20611
20985
|
// app/lib/graph-health.ts
|
|
20612
20986
|
var import_dist4 = __toESM(require_dist4(), 1);
|
|
@@ -21375,8 +21749,8 @@ var streamSSE = (c, cb, onError) => {
|
|
|
21375
21749
|
|
|
21376
21750
|
// app/lib/whatsapp/gateway/routes.ts
|
|
21377
21751
|
function createWaChannelRoutes(deps) {
|
|
21378
|
-
const
|
|
21379
|
-
|
|
21752
|
+
const app61 = new Hono();
|
|
21753
|
+
app61.get("/wa-channel/inbound", (c) => {
|
|
21380
21754
|
const senderId = c.req.query("senderId");
|
|
21381
21755
|
if (!senderId) return c.json({ error: "senderId required" }, 400);
|
|
21382
21756
|
return streamSSE(c, async (stream2) => {
|
|
@@ -21394,7 +21768,7 @@ function createWaChannelRoutes(deps) {
|
|
|
21394
21768
|
}
|
|
21395
21769
|
});
|
|
21396
21770
|
});
|
|
21397
|
-
|
|
21771
|
+
app61.post("/wa-channel/reply", async (c) => {
|
|
21398
21772
|
const body = await c.req.json().catch(() => null);
|
|
21399
21773
|
const senderId = body?.senderId;
|
|
21400
21774
|
const text = body?.text;
|
|
@@ -21415,7 +21789,7 @@ function createWaChannelRoutes(deps) {
|
|
|
21415
21789
|
console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
|
|
21416
21790
|
return c.json({ ok: true });
|
|
21417
21791
|
});
|
|
21418
|
-
|
|
21792
|
+
app61.post("/wa-channel/reply-document", async (c) => {
|
|
21419
21793
|
const body = await c.req.json().catch(() => null);
|
|
21420
21794
|
const senderId = body?.senderId;
|
|
21421
21795
|
const files = body?.files;
|
|
@@ -21454,7 +21828,7 @@ function createWaChannelRoutes(deps) {
|
|
|
21454
21828
|
}
|
|
21455
21829
|
return c.json({ ok: true, results });
|
|
21456
21830
|
});
|
|
21457
|
-
|
|
21831
|
+
app61.post("/wa-channel/ready", async (c) => {
|
|
21458
21832
|
const body = await c.req.json().catch(() => null);
|
|
21459
21833
|
const senderId = body?.senderId;
|
|
21460
21834
|
if (typeof senderId !== "string") {
|
|
@@ -21463,7 +21837,7 @@ function createWaChannelRoutes(deps) {
|
|
|
21463
21837
|
deps.onReady?.(senderId);
|
|
21464
21838
|
return c.json({ ok: true });
|
|
21465
21839
|
});
|
|
21466
|
-
|
|
21840
|
+
app61.post("/wa-channel/received", async (c) => {
|
|
21467
21841
|
const body = await c.req.json().catch(() => null);
|
|
21468
21842
|
const senderId = body?.senderId;
|
|
21469
21843
|
const waMessageId = body?.waMessageId;
|
|
@@ -21473,7 +21847,7 @@ function createWaChannelRoutes(deps) {
|
|
|
21473
21847
|
deps.onReceived?.(senderId, waMessageId);
|
|
21474
21848
|
return c.json({ ok: true });
|
|
21475
21849
|
});
|
|
21476
|
-
|
|
21850
|
+
app61.post("/wa-channel/turn-end", async (c) => {
|
|
21477
21851
|
const body = await c.req.json().catch(() => null);
|
|
21478
21852
|
const senderId = body?.senderId;
|
|
21479
21853
|
const sessionId = body?.sessionId;
|
|
@@ -21489,7 +21863,7 @@ function createWaChannelRoutes(deps) {
|
|
|
21489
21863
|
console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=none`);
|
|
21490
21864
|
return c.json({ ok: true, delivered: "none" });
|
|
21491
21865
|
});
|
|
21492
|
-
return
|
|
21866
|
+
return app61;
|
|
21493
21867
|
}
|
|
21494
21868
|
|
|
21495
21869
|
// app/lib/whatsapp/gateway/wa-gateway.ts
|
|
@@ -21594,7 +21968,8 @@ var WaGateway = class {
|
|
|
21594
21968
|
waMessageId: `wa-${++this.seq}`,
|
|
21595
21969
|
media: input.media,
|
|
21596
21970
|
source,
|
|
21597
|
-
standingRules
|
|
21971
|
+
standingRules,
|
|
21972
|
+
scheduleProvenance: input.scheduleProvenance
|
|
21598
21973
|
},
|
|
21599
21974
|
Date.now()
|
|
21600
21975
|
);
|
|
@@ -21612,7 +21987,9 @@ var WaGateway = class {
|
|
|
21612
21987
|
role: input.role ?? "admin",
|
|
21613
21988
|
personId: input.personId ?? null,
|
|
21614
21989
|
gatewayUrl: this.deps.gatewayUrl,
|
|
21615
|
-
serverPath: this.deps.serverPath
|
|
21990
|
+
serverPath: this.deps.serverPath,
|
|
21991
|
+
// Task 1526 — a scheduled firing's per-firing seat id; absent on real inbound.
|
|
21992
|
+
sessionIdOverride: input.scheduledSessionId
|
|
21616
21993
|
});
|
|
21617
21994
|
} finally {
|
|
21618
21995
|
this.spawning.delete(input.senderId);
|
|
@@ -21638,7 +22015,7 @@ var WaGateway = class {
|
|
|
21638
22015
|
function buildWaSpawnRequest(input) {
|
|
21639
22016
|
const personId = input.role === "public" && input.personId ? input.personId : void 0;
|
|
21640
22017
|
return {
|
|
21641
|
-
sessionId: adminSessionIdFor(input.accountId, input.senderId, personId),
|
|
22018
|
+
sessionId: input.sessionIdOverride && input.sessionIdOverride.length > 0 ? input.sessionIdOverride : adminSessionIdFor(input.accountId, input.senderId, personId),
|
|
21642
22019
|
role: input.role,
|
|
21643
22020
|
channel: "whatsapp",
|
|
21644
22021
|
personId,
|
|
@@ -21822,8 +22199,8 @@ var import_dist6 = __toESM(require_dist(), 1);
|
|
|
21822
22199
|
|
|
21823
22200
|
// app/lib/webchat/gateway/routes.ts
|
|
21824
22201
|
function createWebchatChannelRoutes(deps) {
|
|
21825
|
-
const
|
|
21826
|
-
|
|
22202
|
+
const app61 = new Hono();
|
|
22203
|
+
app61.get("/webchat-channel/inbound", (c) => {
|
|
21827
22204
|
const key = c.req.query("key");
|
|
21828
22205
|
if (!key) return c.json({ error: "key required" }, 400);
|
|
21829
22206
|
return streamSSE(c, async (stream2) => {
|
|
@@ -21841,7 +22218,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
21841
22218
|
}
|
|
21842
22219
|
});
|
|
21843
22220
|
});
|
|
21844
|
-
|
|
22221
|
+
app61.post("/webchat-channel/reply", async (c) => {
|
|
21845
22222
|
const body = await c.req.json().catch(() => null);
|
|
21846
22223
|
const key = body?.key;
|
|
21847
22224
|
const text = body?.text;
|
|
@@ -21851,7 +22228,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
21851
22228
|
deps.onReply?.(key, text);
|
|
21852
22229
|
return c.json({ ok: true });
|
|
21853
22230
|
});
|
|
21854
|
-
|
|
22231
|
+
app61.post("/webchat-channel/connector-auth", async (c) => {
|
|
21855
22232
|
const body = await c.req.json().catch(() => null);
|
|
21856
22233
|
const key = body?.key;
|
|
21857
22234
|
const sessionId = body?.sessionId;
|
|
@@ -21864,7 +22241,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
21864
22241
|
const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
|
|
21865
22242
|
return c.json(result);
|
|
21866
22243
|
});
|
|
21867
|
-
|
|
22244
|
+
app61.post("/webchat-channel/ready", async (c) => {
|
|
21868
22245
|
const body = await c.req.json().catch(() => null);
|
|
21869
22246
|
const key = body?.key;
|
|
21870
22247
|
if (typeof key !== "string") {
|
|
@@ -21873,7 +22250,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
21873
22250
|
deps.onReady?.(key);
|
|
21874
22251
|
return c.json({ ok: true });
|
|
21875
22252
|
});
|
|
21876
|
-
|
|
22253
|
+
app61.post("/webchat-channel/permission-request", async (c) => {
|
|
21877
22254
|
const body = await c.req.json().catch(() => null);
|
|
21878
22255
|
const key = body?.key;
|
|
21879
22256
|
const requestId = body?.request_id;
|
|
@@ -21887,7 +22264,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
21887
22264
|
const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
|
|
21888
22265
|
return c.json(verdict);
|
|
21889
22266
|
});
|
|
21890
|
-
|
|
22267
|
+
app61.post("/webchat-channel/received", async (c) => {
|
|
21891
22268
|
const body = await c.req.json().catch(() => null);
|
|
21892
22269
|
const key = body?.key;
|
|
21893
22270
|
const messageId = body?.messageId;
|
|
@@ -21897,7 +22274,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
21897
22274
|
deps.onReceived?.(key, messageId);
|
|
21898
22275
|
return c.json({ ok: true });
|
|
21899
22276
|
});
|
|
21900
|
-
|
|
22277
|
+
app61.post("/webchat-channel/turn-end", async (c) => {
|
|
21901
22278
|
const body = await c.req.json().catch(() => null);
|
|
21902
22279
|
const key = body?.key;
|
|
21903
22280
|
const sessionId = body?.sessionId;
|
|
@@ -21917,7 +22294,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
21917
22294
|
console.error(`[webchat-native] op=turn-undelivered channel=webchat key=${k} sessionId=${sid} bytes=${finalBytes}`);
|
|
21918
22295
|
return c.json({ ok: true, delivered: "undelivered" });
|
|
21919
22296
|
});
|
|
21920
|
-
return
|
|
22297
|
+
return app61;
|
|
21921
22298
|
}
|
|
21922
22299
|
|
|
21923
22300
|
// app/lib/webchat/gateway/webchat-gateway.ts
|
|
@@ -22548,7 +22925,7 @@ function makeFileDelivery(opts) {
|
|
|
22548
22925
|
}
|
|
22549
22926
|
|
|
22550
22927
|
// app/lib/whatsapp/inbound/file-delivery-bridge.ts
|
|
22551
|
-
var
|
|
22928
|
+
var TAG40 = "[whatsapp-adaptor]";
|
|
22552
22929
|
var SEND_USER_FILE2 = "SendUserFile";
|
|
22553
22930
|
var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
|
|
22554
22931
|
function platformRoot() {
|
|
@@ -22566,7 +22943,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
|
|
|
22566
22943
|
});
|
|
22567
22944
|
if (result.ok) return { ok: true };
|
|
22568
22945
|
console.error(
|
|
22569
|
-
`${
|
|
22946
|
+
`${TAG40} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
|
|
22570
22947
|
);
|
|
22571
22948
|
return { ok: false, error: result.error };
|
|
22572
22949
|
};
|
|
@@ -22574,7 +22951,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
|
|
|
22574
22951
|
function makeWhatsAppFileDelivery(entry, maxyAccountId) {
|
|
22575
22952
|
const shared = makeFileDelivery({
|
|
22576
22953
|
entry,
|
|
22577
|
-
tag:
|
|
22954
|
+
tag: TAG40,
|
|
22578
22955
|
channel: "whatsapp",
|
|
22579
22956
|
sendFile: makeWhatsAppSendFile(entry, maxyAccountId)
|
|
22580
22957
|
});
|
|
@@ -22609,7 +22986,7 @@ function makeWhatsAppFileDelivery(entry, maxyAccountId) {
|
|
|
22609
22986
|
if (!delivered) {
|
|
22610
22987
|
const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
|
|
22611
22988
|
console.error(
|
|
22612
|
-
`${
|
|
22989
|
+
`${TAG40} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
|
|
22613
22990
|
);
|
|
22614
22991
|
}
|
|
22615
22992
|
}
|
|
@@ -22786,8 +23163,8 @@ var import_dist7 = __toESM(require_dist(), 1);
|
|
|
22786
23163
|
|
|
22787
23164
|
// app/lib/telegram/gateway/routes.ts
|
|
22788
23165
|
function createTelegramChannelRoutes(deps) {
|
|
22789
|
-
const
|
|
22790
|
-
|
|
23166
|
+
const app61 = new Hono();
|
|
23167
|
+
app61.get("/tg-channel/inbound", (c) => {
|
|
22791
23168
|
const key = c.req.query("key");
|
|
22792
23169
|
if (!key) return c.json({ error: "key required" }, 400);
|
|
22793
23170
|
return streamSSE(c, async (stream2) => {
|
|
@@ -22805,7 +23182,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
22805
23182
|
}
|
|
22806
23183
|
});
|
|
22807
23184
|
});
|
|
22808
|
-
|
|
23185
|
+
app61.post("/tg-channel/reply", async (c) => {
|
|
22809
23186
|
const body = await c.req.json().catch(() => null);
|
|
22810
23187
|
const key = body?.key;
|
|
22811
23188
|
const text = body?.text;
|
|
@@ -22821,7 +23198,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
22821
23198
|
console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
|
|
22822
23199
|
return c.json({ ok: true });
|
|
22823
23200
|
});
|
|
22824
|
-
|
|
23201
|
+
app61.post("/tg-channel/ready", async (c) => {
|
|
22825
23202
|
const body = await c.req.json().catch(() => null);
|
|
22826
23203
|
const key = body?.key;
|
|
22827
23204
|
if (typeof key !== "string") {
|
|
@@ -22830,7 +23207,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
22830
23207
|
deps.onReady?.(key);
|
|
22831
23208
|
return c.json({ ok: true });
|
|
22832
23209
|
});
|
|
22833
|
-
|
|
23210
|
+
app61.post("/tg-channel/received", async (c) => {
|
|
22834
23211
|
const body = await c.req.json().catch(() => null);
|
|
22835
23212
|
const key = body?.key;
|
|
22836
23213
|
const messageId = body?.messageId;
|
|
@@ -22840,7 +23217,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
22840
23217
|
deps.onReceived?.(key, messageId);
|
|
22841
23218
|
return c.json({ ok: true });
|
|
22842
23219
|
});
|
|
22843
|
-
|
|
23220
|
+
app61.post("/tg-channel/turn-end", async (c) => {
|
|
22844
23221
|
const body = await c.req.json().catch(() => null);
|
|
22845
23222
|
const key = body?.key;
|
|
22846
23223
|
const sessionId = body?.sessionId;
|
|
@@ -22856,7 +23233,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
22856
23233
|
console.error(`[telegram-native] op=turn-end key=${key} sessionId=${sid} replied=no delivered=none`);
|
|
22857
23234
|
return c.json({ ok: true, delivered: "none" });
|
|
22858
23235
|
});
|
|
22859
|
-
return
|
|
23236
|
+
return app61;
|
|
22860
23237
|
}
|
|
22861
23238
|
|
|
22862
23239
|
// app/lib/telegram/gateway/telegram-gateway.ts
|
|
@@ -22923,7 +23300,7 @@ var TelegramGateway = class {
|
|
|
22923
23300
|
);
|
|
22924
23301
|
}
|
|
22925
23302
|
this.hub.deliver(
|
|
22926
|
-
{ key: input.senderId, text: input.text, messageId: `tg-${++this.seq}`, source, standingRules },
|
|
23303
|
+
{ key: input.senderId, text: input.text, messageId: `tg-${++this.seq}`, source, standingRules, scheduleProvenance: input.scheduleProvenance },
|
|
22927
23304
|
Date.now()
|
|
22928
23305
|
);
|
|
22929
23306
|
console.error(
|
|
@@ -22940,7 +23317,9 @@ var TelegramGateway = class {
|
|
|
22940
23317
|
personId: input.personId ?? null,
|
|
22941
23318
|
chatId: input.chatId,
|
|
22942
23319
|
gatewayUrl: this.deps.gatewayUrl,
|
|
22943
|
-
serverPath: this.deps.serverPath
|
|
23320
|
+
serverPath: this.deps.serverPath,
|
|
23321
|
+
// Task 1526 — a scheduled firing's per-firing seat id; absent on real inbound.
|
|
23322
|
+
sessionIdOverride: input.scheduledSessionId
|
|
22944
23323
|
});
|
|
22945
23324
|
} finally {
|
|
22946
23325
|
this.spawning.delete(input.senderId);
|
|
@@ -22958,7 +23337,7 @@ var TelegramGateway = class {
|
|
|
22958
23337
|
function buildTelegramSpawnRequest(input) {
|
|
22959
23338
|
const personId = input.role === "public" && input.personId ? input.personId : void 0;
|
|
22960
23339
|
return {
|
|
22961
|
-
sessionId: adminSessionIdFor(input.accountId, input.senderId, personId),
|
|
23340
|
+
sessionId: input.sessionIdOverride && input.sessionIdOverride.length > 0 ? input.sessionIdOverride : adminSessionIdFor(input.accountId, input.senderId, personId),
|
|
22962
23341
|
role: input.role,
|
|
22963
23342
|
channel: "telegram",
|
|
22964
23343
|
personId,
|
|
@@ -22977,7 +23356,7 @@ function buildTelegramSpawnRequest(input) {
|
|
|
22977
23356
|
import { realpathSync as realpathSync7 } from "fs";
|
|
22978
23357
|
import { readFile as readFile7, stat as stat7 } from "fs/promises";
|
|
22979
23358
|
import { resolve as resolve30, basename as basename12 } from "path";
|
|
22980
|
-
var
|
|
23359
|
+
var TAG41 = "[telegram:outbound]";
|
|
22981
23360
|
var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
|
|
22982
23361
|
async function sendTelegramDocument(input) {
|
|
22983
23362
|
const { botToken, chatId, filePath, caption, maxyAccountId, platformRoot: platformRoot3 } = input;
|
|
@@ -22993,16 +23372,16 @@ async function sendTelegramDocument(input) {
|
|
|
22993
23372
|
resolvedPath = realpathSync7(filePath);
|
|
22994
23373
|
const accountResolved = realpathSync7(accountDir);
|
|
22995
23374
|
if (!resolvedPath.startsWith(accountResolved + "/")) {
|
|
22996
|
-
console.error(`${
|
|
23375
|
+
console.error(`${TAG41} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
|
|
22997
23376
|
return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
|
|
22998
23377
|
}
|
|
22999
23378
|
} catch (err) {
|
|
23000
23379
|
const code = err.code;
|
|
23001
23380
|
if (code === "ENOENT") {
|
|
23002
|
-
console.error(`${
|
|
23381
|
+
console.error(`${TAG41} document ENOENT path=${filePath}`);
|
|
23003
23382
|
return { ok: false, status: 404, error: `File not found: ${filePath}` };
|
|
23004
23383
|
}
|
|
23005
|
-
console.error(`${
|
|
23384
|
+
console.error(`${TAG41} document path error: ${String(err)}`);
|
|
23006
23385
|
return { ok: false, status: 500, error: String(err) };
|
|
23007
23386
|
}
|
|
23008
23387
|
const fileStat = await stat7(resolvedPath);
|
|
@@ -23035,13 +23414,13 @@ async function sendTelegramDocument(input) {
|
|
|
23035
23414
|
error = e instanceof Error ? e.message : String(e);
|
|
23036
23415
|
}
|
|
23037
23416
|
console.error(
|
|
23038
|
-
`${
|
|
23417
|
+
`${TAG41} sent document to=${chatId} file=${filename} bytes=${fileStat.size} ok=${ok}` + (messageId !== void 0 ? ` id=${messageId}` : "")
|
|
23039
23418
|
);
|
|
23040
23419
|
return ok ? { ok: true, messageId } : { ok: false, status: 500, error };
|
|
23041
23420
|
}
|
|
23042
23421
|
|
|
23043
23422
|
// app/lib/telegram/outbound/file-delivery.ts
|
|
23044
|
-
var
|
|
23423
|
+
var TAG42 = "[telegram:outbound]";
|
|
23045
23424
|
function platformRoot2() {
|
|
23046
23425
|
return process.env.MAXY_PLATFORM_ROOT || "";
|
|
23047
23426
|
}
|
|
@@ -23053,11 +23432,11 @@ function makeTelegramSendFile(entry) {
|
|
|
23053
23432
|
botToken = (entry.role === "admin" ? tg?.adminBotToken : tg?.publicBotToken) ?? null;
|
|
23054
23433
|
}
|
|
23055
23434
|
if (!botToken) {
|
|
23056
|
-
console.error(`${
|
|
23435
|
+
console.error(`${TAG42} file-delivery reject reason=no-bot-token sender=${entry.senderId} role=${entry.role}`);
|
|
23057
23436
|
return { ok: false, error: "no-bot-token" };
|
|
23058
23437
|
}
|
|
23059
23438
|
if (entry.replyTarget == null) {
|
|
23060
|
-
console.error(`${
|
|
23439
|
+
console.error(`${TAG42} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
|
|
23061
23440
|
return { ok: false, error: "no-reply-target" };
|
|
23062
23441
|
}
|
|
23063
23442
|
const result = await sendTelegramDocument({
|
|
@@ -23074,7 +23453,7 @@ function makeTelegramSendFile(entry) {
|
|
|
23074
23453
|
function makeTelegramFileDelivery(entry) {
|
|
23075
23454
|
return makeFileDelivery({
|
|
23076
23455
|
entry,
|
|
23077
|
-
tag:
|
|
23456
|
+
tag: TAG42,
|
|
23078
23457
|
channel: "telegram",
|
|
23079
23458
|
sendFile: makeTelegramSendFile(entry)
|
|
23080
23459
|
});
|
|
@@ -23123,8 +23502,8 @@ function telegramServerPath() {
|
|
|
23123
23502
|
}
|
|
23124
23503
|
|
|
23125
23504
|
// app/lib/channel-pty-bridge/public-session-end-review.ts
|
|
23126
|
-
import { randomUUID as
|
|
23127
|
-
var
|
|
23505
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
23506
|
+
var TAG43 = "[public-session-review]";
|
|
23128
23507
|
var CONSUMED_CAP = 500;
|
|
23129
23508
|
var consumed = /* @__PURE__ */ new Set();
|
|
23130
23509
|
function consumeOnce(sessionId) {
|
|
@@ -23151,7 +23530,7 @@ async function fetchJsonl(sessionId) {
|
|
|
23151
23530
|
return await res.text();
|
|
23152
23531
|
} catch (err) {
|
|
23153
23532
|
console.error(
|
|
23154
|
-
`${
|
|
23533
|
+
`${TAG43} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
|
|
23155
23534
|
);
|
|
23156
23535
|
return null;
|
|
23157
23536
|
}
|
|
@@ -23175,7 +23554,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
|
|
|
23175
23554
|
const res = await fetch(url);
|
|
23176
23555
|
if (!res.ok) {
|
|
23177
23556
|
console.error(
|
|
23178
|
-
`${
|
|
23557
|
+
`${TAG43} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
|
|
23179
23558
|
);
|
|
23180
23559
|
return [];
|
|
23181
23560
|
}
|
|
@@ -23183,7 +23562,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
|
|
|
23183
23562
|
return Array.isArray(body.writes) ? body.writes : [];
|
|
23184
23563
|
} catch (err) {
|
|
23185
23564
|
console.error(
|
|
23186
|
-
`${
|
|
23565
|
+
`${TAG43} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
|
|
23187
23566
|
);
|
|
23188
23567
|
return [];
|
|
23189
23568
|
}
|
|
@@ -23211,8 +23590,8 @@ function composeInitialMessage(input) {
|
|
|
23211
23590
|
].join("\n");
|
|
23212
23591
|
}
|
|
23213
23592
|
async function dispatchReviewer(input, initialMessage) {
|
|
23214
|
-
const sessionId =
|
|
23215
|
-
console.log(`${
|
|
23593
|
+
const sessionId = randomUUID14();
|
|
23594
|
+
console.log(`${TAG43} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
|
|
23216
23595
|
const spawned = await managerRcSpawn({
|
|
23217
23596
|
sessionId,
|
|
23218
23597
|
initialMessage,
|
|
@@ -23232,21 +23611,21 @@ async function firePublicSessionEndReview(input) {
|
|
|
23232
23611
|
const dispatchedAt = Date.now();
|
|
23233
23612
|
if (consumed.has(input.sessionId)) {
|
|
23234
23613
|
console.log(
|
|
23235
|
-
`${
|
|
23614
|
+
`${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
|
|
23236
23615
|
);
|
|
23237
23616
|
return;
|
|
23238
23617
|
}
|
|
23239
23618
|
const jsonl = await fetchJsonl(input.sessionId);
|
|
23240
23619
|
if (!jsonl) {
|
|
23241
23620
|
console.log(
|
|
23242
|
-
`${
|
|
23621
|
+
`${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
|
|
23243
23622
|
);
|
|
23244
23623
|
return;
|
|
23245
23624
|
}
|
|
23246
23625
|
const operatorTurns = countOperatorTurns(jsonl);
|
|
23247
23626
|
if (operatorTurns === 0) {
|
|
23248
23627
|
console.log(
|
|
23249
|
-
`${
|
|
23628
|
+
`${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
|
|
23250
23629
|
);
|
|
23251
23630
|
return;
|
|
23252
23631
|
}
|
|
@@ -23260,19 +23639,19 @@ async function firePublicSessionEndReview(input) {
|
|
|
23260
23639
|
});
|
|
23261
23640
|
if (!consumeOnce(input.sessionId)) {
|
|
23262
23641
|
console.log(
|
|
23263
|
-
`${
|
|
23642
|
+
`${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
|
|
23264
23643
|
);
|
|
23265
23644
|
return;
|
|
23266
23645
|
}
|
|
23267
23646
|
const dispatched = await dispatchReviewer(input, initialMessage);
|
|
23268
23647
|
if (!dispatched.ok) {
|
|
23269
23648
|
console.error(
|
|
23270
|
-
`${
|
|
23649
|
+
`${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
|
|
23271
23650
|
);
|
|
23272
23651
|
return;
|
|
23273
23652
|
}
|
|
23274
23653
|
console.log(
|
|
23275
|
-
`${
|
|
23654
|
+
`${TAG43} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
|
|
23276
23655
|
);
|
|
23277
23656
|
}
|
|
23278
23657
|
|
|
@@ -23687,7 +24066,7 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
|
|
|
23687
24066
|
function isPublicHost(host) {
|
|
23688
24067
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
23689
24068
|
}
|
|
23690
|
-
var
|
|
24069
|
+
var app60 = new Hono();
|
|
23691
24070
|
var nativeFileFollowers = /* @__PURE__ */ new Map();
|
|
23692
24071
|
async function fetchAccountStandingRules(accountId) {
|
|
23693
24072
|
const session = getSession();
|
|
@@ -23745,7 +24124,7 @@ var waGateway = new WaGateway({
|
|
|
23745
24124
|
});
|
|
23746
24125
|
return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
|
|
23747
24126
|
},
|
|
23748
|
-
ensureChannelSession: async ({ accountId, effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, passive, text, msgId }) => {
|
|
24127
|
+
ensureChannelSession: async ({ accountId, effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, passive, text, msgId, sessionIdOverride }) => {
|
|
23749
24128
|
if (passive) {
|
|
23750
24129
|
const phoneHash = createHash6("sha256").update(senderId).digest("hex").slice(0, 12);
|
|
23751
24130
|
const prompt = (text ?? "").trim();
|
|
@@ -23793,7 +24172,7 @@ var waGateway = new WaGateway({
|
|
|
23793
24172
|
const managesAccount = effectiveAccountId !== accountId ? effectiveAccountId : "none";
|
|
23794
24173
|
console.error(`[whatsapp-native] op=account-manager-route senderId=${senderId} managesAccount=${managesAccount} effectiveAccount=${effectiveAccountId} source=gate`);
|
|
23795
24174
|
}
|
|
23796
|
-
const req = buildWaSpawnRequest({ accountId: effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath });
|
|
24175
|
+
const req = buildWaSpawnRequest({ accountId: effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, sessionIdOverride });
|
|
23797
24176
|
const userId = role === "admin" ? resolveAdminUserId({ accountId: effectiveAccountId, senderPhone: senderId }) ?? void 0 : void 0;
|
|
23798
24177
|
if (role === "admin") {
|
|
23799
24178
|
console.error(`[whatsapp-native] op=admin-identity senderId=${senderId} userId=${userId ?? "owner-fallback"}`);
|
|
@@ -23822,7 +24201,7 @@ var waGateway = new WaGateway({
|
|
|
23822
24201
|
nativeFileFollowers.set(senderId, ac);
|
|
23823
24202
|
}
|
|
23824
24203
|
});
|
|
23825
|
-
|
|
24204
|
+
app60.route("/", waGateway.routes());
|
|
23826
24205
|
waGateway.startSweeper();
|
|
23827
24206
|
var webchatGateway = new WebchatGateway({
|
|
23828
24207
|
fetchStandingRules: fetchAccountStandingRules,
|
|
@@ -23906,7 +24285,7 @@ var webchatGateway = new WebchatGateway({
|
|
|
23906
24285
|
firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
|
|
23907
24286
|
});
|
|
23908
24287
|
setWebchatGateway(webchatGateway);
|
|
23909
|
-
|
|
24288
|
+
app60.route("/", webchatGateway.routes());
|
|
23910
24289
|
webchatGateway.startSweeper();
|
|
23911
24290
|
webchatGateway.startPublicReaper();
|
|
23912
24291
|
var telegramFileFollowers = /* @__PURE__ */ new Map();
|
|
@@ -23914,8 +24293,8 @@ var telegramGateway = new TelegramGateway({
|
|
|
23914
24293
|
fetchStandingRules: fetchAccountStandingRules,
|
|
23915
24294
|
gatewayUrl: telegramGatewayUrl(),
|
|
23916
24295
|
serverPath: telegramServerPath(),
|
|
23917
|
-
ensureChannelSession: async ({ accountId, senderId, role, personId, chatId, gatewayUrl, serverPath }) => {
|
|
23918
|
-
const req = buildTelegramSpawnRequest({ accountId, senderId, role, personId, gatewayUrl, serverPath });
|
|
24296
|
+
ensureChannelSession: async ({ accountId, senderId, role, personId, chatId, gatewayUrl, serverPath, sessionIdOverride }) => {
|
|
24297
|
+
const req = buildTelegramSpawnRequest({ accountId, senderId, role, personId, gatewayUrl, serverPath, sessionIdOverride });
|
|
23919
24298
|
const result = await managerRcSpawn(req);
|
|
23920
24299
|
if ("error" in result) {
|
|
23921
24300
|
console.error(`[telegram-native] spawn-failed senderId=${senderId} role=${role} error=${result.error} status=${result.status}`);
|
|
@@ -23940,7 +24319,7 @@ var telegramGateway = new TelegramGateway({
|
|
|
23940
24319
|
}
|
|
23941
24320
|
});
|
|
23942
24321
|
setTelegramGateway(telegramGateway);
|
|
23943
|
-
|
|
24322
|
+
app60.route("/", telegramGateway.routes());
|
|
23944
24323
|
telegramGateway.startSweeper();
|
|
23945
24324
|
var chatRoutes = createChatRoutes({
|
|
23946
24325
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
@@ -23973,19 +24352,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
|
|
|
23973
24352
|
return managed.account;
|
|
23974
24353
|
}
|
|
23975
24354
|
});
|
|
23976
|
-
|
|
23977
|
-
|
|
24355
|
+
app60.route("/api/channel/schedule-inject", scheduleInjectRoutes);
|
|
24356
|
+
app60.use("*", clientIpMiddleware);
|
|
23978
24357
|
function allowsSameOriginFraming(path2) {
|
|
23979
24358
|
return path2 === "/vnc-viewer.html" || path2.startsWith("/api/admin/attachment/") || path2.startsWith("/api/public-reader/attachment/") || path2 === "/api/admin/files/download";
|
|
23980
24359
|
}
|
|
23981
|
-
|
|
24360
|
+
app60.use("*", async (c, next) => {
|
|
23982
24361
|
await next();
|
|
23983
24362
|
c.header("X-Content-Type-Options", "nosniff");
|
|
23984
24363
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
23985
24364
|
c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
|
|
23986
24365
|
});
|
|
23987
24366
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
23988
|
-
|
|
24367
|
+
app60.use("*", async (c, next) => {
|
|
23989
24368
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
23990
24369
|
await next();
|
|
23991
24370
|
return;
|
|
@@ -24003,7 +24382,7 @@ app56.use("*", async (c, next) => {
|
|
|
24003
24382
|
});
|
|
24004
24383
|
}
|
|
24005
24384
|
});
|
|
24006
|
-
|
|
24385
|
+
app60.use("*", async (c, next) => {
|
|
24007
24386
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24008
24387
|
if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
|
|
24009
24388
|
await next();
|
|
@@ -24041,7 +24420,7 @@ function resolveRemoteAuthOpts(c) {
|
|
|
24041
24420
|
return { ...brandLoginOpts, origin };
|
|
24042
24421
|
}
|
|
24043
24422
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
24044
|
-
|
|
24423
|
+
app60.post("/__remote-auth/login", async (c) => {
|
|
24045
24424
|
const client = clientFrom(c);
|
|
24046
24425
|
const clientIp = client.ip || "unknown";
|
|
24047
24426
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -24086,7 +24465,7 @@ app56.post("/__remote-auth/login", async (c) => {
|
|
|
24086
24465
|
}
|
|
24087
24466
|
});
|
|
24088
24467
|
});
|
|
24089
|
-
|
|
24468
|
+
app60.get("/__remote-auth/logout", (c) => {
|
|
24090
24469
|
const client = clientFrom(c);
|
|
24091
24470
|
const clientIp = client.ip || "unknown";
|
|
24092
24471
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -24099,7 +24478,7 @@ app56.get("/__remote-auth/logout", (c) => {
|
|
|
24099
24478
|
}
|
|
24100
24479
|
});
|
|
24101
24480
|
});
|
|
24102
|
-
|
|
24481
|
+
app60.post("/__remote-auth/change-password", async (c) => {
|
|
24103
24482
|
const client = clientFrom(c);
|
|
24104
24483
|
const clientIp = client.ip || "unknown";
|
|
24105
24484
|
const rateLimited = checkRateLimit(client);
|
|
@@ -24158,13 +24537,13 @@ app56.post("/__remote-auth/change-password", async (c) => {
|
|
|
24158
24537
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
24159
24538
|
}
|
|
24160
24539
|
});
|
|
24161
|
-
|
|
24540
|
+
app60.get("/__remote-auth/setup", (c) => {
|
|
24162
24541
|
if (isRemoteAuthConfigured()) {
|
|
24163
24542
|
return c.redirect("/");
|
|
24164
24543
|
}
|
|
24165
24544
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
|
|
24166
24545
|
});
|
|
24167
|
-
|
|
24546
|
+
app60.post("/__remote-auth/set-initial-password", async (c) => {
|
|
24168
24547
|
if (isRemoteAuthConfigured()) {
|
|
24169
24548
|
return c.redirect("/");
|
|
24170
24549
|
}
|
|
@@ -24202,10 +24581,10 @@ app56.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
24202
24581
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
24203
24582
|
}
|
|
24204
24583
|
});
|
|
24205
|
-
|
|
24584
|
+
app60.get("/api/remote-auth/status", (c) => {
|
|
24206
24585
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
24207
24586
|
});
|
|
24208
|
-
|
|
24587
|
+
app60.post("/api/remote-auth/set-password", async (c) => {
|
|
24209
24588
|
let body;
|
|
24210
24589
|
try {
|
|
24211
24590
|
body = await c.req.json();
|
|
@@ -24244,10 +24623,10 @@ app56.post("/api/remote-auth/set-password", async (c) => {
|
|
|
24244
24623
|
return c.json({ error: "Failed to save password" }, 500);
|
|
24245
24624
|
}
|
|
24246
24625
|
});
|
|
24247
|
-
|
|
24626
|
+
app60.route("/api/_client-error", client_error_default);
|
|
24248
24627
|
console.log("[client-error-route] mounted");
|
|
24249
24628
|
var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
|
|
24250
|
-
|
|
24629
|
+
app60.use("*", async (c, next) => {
|
|
24251
24630
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24252
24631
|
const path2 = c.req.path;
|
|
24253
24632
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
|
|
@@ -24291,26 +24670,26 @@ app56.use("*", async (c, next) => {
|
|
|
24291
24670
|
}
|
|
24292
24671
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path2 }), 200);
|
|
24293
24672
|
});
|
|
24294
|
-
|
|
24295
|
-
|
|
24296
|
-
|
|
24297
|
-
|
|
24298
|
-
|
|
24299
|
-
|
|
24673
|
+
app60.route("/api/health", health_default);
|
|
24674
|
+
app60.route("/api/chat", chatRoutes);
|
|
24675
|
+
app60.route("/api/whatsapp", whatsapp_default);
|
|
24676
|
+
app60.route("/api/whatsapp-reader", whatsapp_reader_default);
|
|
24677
|
+
app60.route("/api/public-reader", public_reader_default);
|
|
24678
|
+
app60.route("/api/webchat", createWebchatRoutes({
|
|
24300
24679
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
24301
24680
|
// Task 940 — the permission relay's pointer read + verdict write.
|
|
24302
24681
|
pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
|
|
24303
24682
|
deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
|
|
24304
24683
|
resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
|
|
24305
24684
|
}));
|
|
24306
|
-
|
|
24307
|
-
|
|
24308
|
-
|
|
24309
|
-
|
|
24310
|
-
|
|
24311
|
-
|
|
24312
|
-
|
|
24313
|
-
|
|
24685
|
+
app60.route("/api/webchat/greeting", webchat_greeting_default);
|
|
24686
|
+
app60.route("/api/telegram", telegram_default);
|
|
24687
|
+
app60.route("/api/quickbooks", quickbooks_default);
|
|
24688
|
+
app60.route("/api/onboarding", onboarding_default);
|
|
24689
|
+
app60.route("/api/admin", admin_default);
|
|
24690
|
+
app60.route("/api/access", access_default);
|
|
24691
|
+
app60.route("/api/session", session_default2);
|
|
24692
|
+
app60.route("/api/calendar", calendar_public_default);
|
|
24314
24693
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
24315
24694
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
24316
24695
|
var IMAGE_MIME = {
|
|
@@ -24322,7 +24701,7 @@ var IMAGE_MIME = {
|
|
|
24322
24701
|
".svg": "image/svg+xml",
|
|
24323
24702
|
".ico": "image/x-icon"
|
|
24324
24703
|
};
|
|
24325
|
-
|
|
24704
|
+
app60.get("/agent-assets/:slug/:filename", (c) => {
|
|
24326
24705
|
const slug = c.req.param("slug");
|
|
24327
24706
|
const filename = c.req.param("filename");
|
|
24328
24707
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -24357,7 +24736,7 @@ app56.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
24357
24736
|
"Cache-Control": "public, max-age=3600"
|
|
24358
24737
|
});
|
|
24359
24738
|
});
|
|
24360
|
-
|
|
24739
|
+
app60.get("/generated/:filename", (c) => {
|
|
24361
24740
|
const filename = c.req.param("filename");
|
|
24362
24741
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
24363
24742
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -24387,10 +24766,10 @@ app56.get("/generated/:filename", (c) => {
|
|
|
24387
24766
|
"Cache-Control": "public, max-age=86400"
|
|
24388
24767
|
});
|
|
24389
24768
|
});
|
|
24390
|
-
|
|
24391
|
-
|
|
24392
|
-
|
|
24393
|
-
|
|
24769
|
+
app60.route("/sites", sites_default);
|
|
24770
|
+
app60.route("/listings", listings_default);
|
|
24771
|
+
app60.route("/v", visitor_event_default);
|
|
24772
|
+
app60.route("/v", visitor_consent_default);
|
|
24394
24773
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
24395
24774
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
24396
24775
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -24545,7 +24924,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
24545
24924
|
function agentUnavailableHtml() {
|
|
24546
24925
|
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>`;
|
|
24547
24926
|
}
|
|
24548
|
-
|
|
24927
|
+
app60.get("/", (c) => {
|
|
24549
24928
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24550
24929
|
const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
|
|
24551
24930
|
if (klass === "operator") {
|
|
@@ -24567,12 +24946,12 @@ app56.get("/", (c) => {
|
|
|
24567
24946
|
console.log(`[host-class] host=${host} class=admin served=index.html`);
|
|
24568
24947
|
return c.html(cachedHtml("index.html"));
|
|
24569
24948
|
});
|
|
24570
|
-
|
|
24949
|
+
app60.get("/public", (c) => {
|
|
24571
24950
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24572
24951
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
24573
24952
|
return c.html(cachedHtml("public.html"));
|
|
24574
24953
|
});
|
|
24575
|
-
|
|
24954
|
+
app60.get("/public-chat", (c) => {
|
|
24576
24955
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24577
24956
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
24578
24957
|
return c.html(cachedHtml("public.html"));
|
|
@@ -24591,9 +24970,9 @@ async function logViewerFetch(c, next) {
|
|
|
24591
24970
|
duration_ms: Date.now() - start
|
|
24592
24971
|
});
|
|
24593
24972
|
}
|
|
24594
|
-
|
|
24595
|
-
|
|
24596
|
-
|
|
24973
|
+
app60.use("/vnc-viewer.html", logViewerFetch);
|
|
24974
|
+
app60.use("/vnc-popout.html", logViewerFetch);
|
|
24975
|
+
app60.get("/vnc-popout.html", (c) => {
|
|
24597
24976
|
let html = htmlCache.get("vnc-popout.html");
|
|
24598
24977
|
if (!html) {
|
|
24599
24978
|
html = readFileSync35(resolve33(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -24606,7 +24985,7 @@ app56.get("/vnc-popout.html", (c) => {
|
|
|
24606
24985
|
}
|
|
24607
24986
|
return c.html(html);
|
|
24608
24987
|
});
|
|
24609
|
-
|
|
24988
|
+
app60.post("/api/vnc/client-event", async (c) => {
|
|
24610
24989
|
let body;
|
|
24611
24990
|
try {
|
|
24612
24991
|
body = await c.req.json();
|
|
@@ -24627,11 +25006,11 @@ app56.post("/api/vnc/client-event", async (c) => {
|
|
|
24627
25006
|
});
|
|
24628
25007
|
return c.json({ ok: true });
|
|
24629
25008
|
});
|
|
24630
|
-
|
|
25009
|
+
app60.get("/g/:slug", (c) => {
|
|
24631
25010
|
return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
|
|
24632
25011
|
});
|
|
24633
25012
|
for (const pwa of PWA_SURFACES) {
|
|
24634
|
-
|
|
25013
|
+
app60.get(pwa.manifestPath, (c) => {
|
|
24635
25014
|
const manifest = buildManifest(pwa, {
|
|
24636
25015
|
productName: BRAND.productName,
|
|
24637
25016
|
appIcon192: brandAppIcon192Path,
|
|
@@ -24647,7 +25026,7 @@ for (const pwa of PWA_SURFACES) {
|
|
|
24647
25026
|
return c.body(JSON.stringify(manifest));
|
|
24648
25027
|
});
|
|
24649
25028
|
}
|
|
24650
|
-
|
|
25029
|
+
app60.get("/sw.js", (c) => {
|
|
24651
25030
|
if (SW_SOURCE == null) {
|
|
24652
25031
|
console.error("[pwa] op=sw status=500 reason=sw-source-missing");
|
|
24653
25032
|
return c.text("Service worker unavailable", 500);
|
|
@@ -24656,12 +25035,12 @@ app56.get("/sw.js", (c) => {
|
|
|
24656
25035
|
console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
|
|
24657
25036
|
return c.body(SW_SOURCE);
|
|
24658
25037
|
});
|
|
24659
|
-
|
|
25038
|
+
app60.get("/graph", (c) => {
|
|
24660
25039
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24661
25040
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
24662
25041
|
return c.html(cachedHtml("graph.html"));
|
|
24663
25042
|
});
|
|
24664
|
-
|
|
25043
|
+
app60.get("/chat", (c) => {
|
|
24665
25044
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24666
25045
|
if (isOperatorHost(host, getOperatorDomains())) {
|
|
24667
25046
|
console.log(`[host-class] host=${host} class=operator served=operator.html`);
|
|
@@ -24670,22 +25049,22 @@ app56.get("/chat", (c) => {
|
|
|
24670
25049
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
24671
25050
|
return c.html(cachedHtml("chat.html"));
|
|
24672
25051
|
});
|
|
24673
|
-
|
|
25052
|
+
app60.get("/data", (c) => {
|
|
24674
25053
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24675
25054
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
24676
25055
|
return c.html(cachedHtml("data.html"));
|
|
24677
25056
|
});
|
|
24678
|
-
|
|
25057
|
+
app60.get("/calendar", (c) => {
|
|
24679
25058
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24680
25059
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
24681
25060
|
return c.html(cachedHtml("calendar.html"));
|
|
24682
25061
|
});
|
|
24683
|
-
|
|
25062
|
+
app60.get("/browser", (c) => {
|
|
24684
25063
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24685
25064
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
24686
25065
|
return c.html(cachedHtml("browser.html"));
|
|
24687
25066
|
});
|
|
24688
|
-
|
|
25067
|
+
app60.get("/:slug", async (c, next) => {
|
|
24689
25068
|
const slug = c.req.param("slug");
|
|
24690
25069
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
24691
25070
|
const account = resolveAccount();
|
|
@@ -24700,13 +25079,13 @@ app56.get("/:slug", async (c, next) => {
|
|
|
24700
25079
|
await next();
|
|
24701
25080
|
});
|
|
24702
25081
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
24703
|
-
|
|
25082
|
+
app60.get("/favicon.ico", (c) => {
|
|
24704
25083
|
c.header("Cache-Control", "public, max-age=300");
|
|
24705
25084
|
return c.redirect(brandFaviconPath, 302);
|
|
24706
25085
|
});
|
|
24707
25086
|
}
|
|
24708
|
-
|
|
24709
|
-
|
|
25087
|
+
app60.use("/*", serveStatic({ root: "./public" }));
|
|
25088
|
+
app60.all("*", (c) => {
|
|
24710
25089
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
24711
25090
|
const path2 = c.req.path;
|
|
24712
25091
|
if (isPublicHost(host)) {
|
|
@@ -24720,7 +25099,7 @@ app56.all("*", (c) => {
|
|
|
24720
25099
|
});
|
|
24721
25100
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
24722
25101
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
24723
|
-
var httpServer = serve({ fetch:
|
|
25102
|
+
var httpServer = serve({ fetch: app60.fetch, port, hostname });
|
|
24724
25103
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
24725
25104
|
{
|
|
24726
25105
|
const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, "..");
|
|
@@ -24744,6 +25123,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
24744
25123
|
const loop = setInterval(runReconcile, RECONCILE_INTERVAL_MS);
|
|
24745
25124
|
loop.unref();
|
|
24746
25125
|
}
|
|
25126
|
+
startTimeEntryCensus(() => getSession());
|
|
24747
25127
|
{
|
|
24748
25128
|
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, "..");
|
|
24749
25129
|
const auditScript = resolve33(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
|
|
@@ -24820,7 +25200,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
24820
25200
|
}
|
|
24821
25201
|
try {
|
|
24822
25202
|
const registered = [];
|
|
24823
|
-
for (const r of
|
|
25203
|
+
for (const r of app60.routes ?? []) {
|
|
24824
25204
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
24825
25205
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
24826
25206
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|