@rubytech/create-maxy-code 0.1.499 → 0.1.501
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/lib/graph-style/dist/index.d.ts +9 -0
- package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-style/dist/index.js +152 -6
- package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-style/src/__tests__/caption-coverage.test.ts +69 -0
- package/payload/platform/lib/graph-style/src/__tests__/coverage-source.ts +73 -0
- package/payload/platform/lib/graph-style/src/__tests__/icons.test.ts +20 -3
- package/payload/platform/lib/graph-style/src/index.ts +166 -5
- package/payload/platform/plugins/admin/PLUGIN.md +2 -1
- package/payload/platform/plugins/admin/hooks/__tests__/admin-authoring-observer.test.sh +135 -0
- package/payload/platform/plugins/admin/hooks/__tests__/prompt-optimiser-directive.test.sh +11 -2
- package/payload/platform/plugins/admin/hooks/prompt-optimiser-directive.sh +6 -3
- package/payload/platform/plugins/admin/mcp/dist/index.js +52 -107
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts +8 -4
- package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js +67 -50
- package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/store-skill-core.d.ts +33 -0
- package/payload/platform/plugins/admin/mcp/dist/store-skill-core.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/store-skill-core.js +122 -0
- package/payload/platform/plugins/admin/mcp/dist/store-skill-core.js.map +1 -0
- package/payload/platform/plugins/admin/skills/agent-builder/SKILL.md +15 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +59 -3
- package/payload/platform/plugins/admin/skills/summarise/SKILL.md +37 -0
- package/payload/platform/plugins/contacts/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/contacts/PLUGIN.md +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/index.js +3 -12
- package/payload/platform/plugins/contacts/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/__tests__/contact-lookup.test.js +105 -2
- package/payload/platform/plugins/contacts/mcp/dist/tools/__tests__/contact-lookup.test.js.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts +11 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js +56 -4
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js.map +1 -1
- package/payload/platform/plugins/docs/references/admin-ui.md +50 -0
- package/payload/platform/plugins/docs/references/contacts-guide.md +2 -0
- package/payload/platform/plugins/docs/references/outlook-guide.md +4 -0
- package/payload/platform/plugins/docs/references/plugins-guide.md +2 -2
- package/payload/platform/plugins/docs/references/summarise-skill.md +7 -0
- package/payload/platform/plugins/email/skills/email-composition/SKILL.md +9 -1
- package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +6 -0
- package/payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/SKILL.md +1 -1
- package/payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.sh +2 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +26 -1
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/skill-registration-drift.d.ts +15 -0
- package/payload/platform/services/claude-session-manager/dist/skill-registration-drift.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/skill-registration-drift.js +61 -0
- package/payload/platform/services/claude-session-manager/dist/skill-registration-drift.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/assets/{AdminLoginScreens-Ce5aBBWF.js → AdminLoginScreens-C3LZOPIY.js} +1 -1
- package/payload/server/public/assets/AdminShell-BlbUNAPc.js +2 -0
- package/payload/server/public/assets/{activity-CKUYOLd2.js → activity-CVdVSw5V.js} +1 -1
- package/payload/server/public/assets/admin-If1QLlS3.js +1 -0
- package/payload/server/public/assets/{arc-CpWWSum8.js → arc-CvlzUHOf.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-BQc779DH.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-D2EzaII0.js → architectureDiagram-Q4EWVU46-I1Hs0RJA.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-8kDpaNSZ.js → blockDiagram-DXYQGD6D-Df5jTGtl.js} +1 -1
- package/payload/server/public/assets/{bot-DESMpxSQ.js → bot-8b26IlQY.js} +1 -1
- package/payload/server/public/assets/{browser-CpLq_DIo.js → browser-F40DXfKA.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CbwmZpK3.js → c4Diagram-AHTNJAMY-B6WY5IDv.js} +1 -1
- package/payload/server/public/assets/{calendar-ClOwyuz-.js → calendar-DZiHiBwV.js} +1 -1
- package/payload/server/public/assets/channel-AqnC3SHu.js +1 -0
- package/payload/server/public/assets/chat-uD28FVCS.js +1 -0
- package/payload/server/public/assets/chevron-left-lBxD57tD.js +1 -0
- package/payload/server/public/assets/chevron-right-C-lDig9Y.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-PFheZ9mw.js → chunk-2KRD3SAO-BsIIFDkc.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-CCFOp5VK.js → chunk-336JU56O-j9z1VtyC.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-CO02gU5d.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-Hz4JWOf2.js → chunk-4BX2VUAB-C9i7prxq.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-4xeV0s85.js → chunk-4TB4RGXK-DH0QVGcv.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-4QKgBpoh.js → chunk-55IACEB6-Dnd_YCPA.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-ms3K6Z5z.js → chunk-5FUZZQ4R-D5sSz3yN.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CIC4GIGi.js → chunk-5PVQY5BW-CJrwWjAT.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-B-XrWVmV.js → chunk-67CJDMHE-SjP6_hUw.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-C7ECOUYQ.js → chunk-7N4EOEYR-fAuhVJD0.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-DOZ6Fxwk.js → chunk-AA7GKIK3-DZxa7KVg.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-4cJ_b0c6.js → chunk-BSJP7CBP-DjeG3eQ-.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT--mhZipWM.js → chunk-CIAEETIT-RYQULNJm.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-jZpVwob_.js → chunk-EDXVE4YY-Cahapnon.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-Nn-p-xIA.js → chunk-ENJZ2VHE-1146X1L4.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-DyNpcKOS.js → chunk-FMBD7UC4-BCFumtcP.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-C0P8q1uz.js → chunk-FOC6F5B3-CkrtX8Zt.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-CdXQ5SfI.js → chunk-ICPOFSXX-Ba1y3DaW.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-BVZJKKsT.js → chunk-K5T4RW27-CF-PI3uQ.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-QlVWTe0V.js → chunk-KGLVRYIC-SFFC6ZC-.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-CpGVZutP.js → chunk-LIHQZDEY-DbOLEP4R.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-WVcS6fUC.js → chunk-ORNJ4GCN-VB963bkN.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-B7hiSTed.js → chunk-OYMX7WX6-DWYY1pQa.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-BiFMbK8t.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-DJPnZxGy.js → chunk-U2HBQHQK-DAH1diYP.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-DilBs1Yc.js → chunk-X2U36JSP-Dmw9coXz.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-B5-uyrJ0.js → chunk-XPW4576I-DaAUON1-.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BNO4z0Mv.js → chunk-YZCP3GAM-BUcfkEef.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BzHMQpip.js → chunk-ZZ45TVLE-BLD-vFRO.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BdRqzScB.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-ChPLgHbS.js +1 -0
- package/payload/server/public/assets/clock-DqRNsY40.js +1 -0
- package/payload/server/public/assets/clone-TKtrjWBC.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-3DWYmn1o.js → cose-bilkent-S5V4N54A-CoZX0uki.js} +1 -1
- package/payload/server/public/assets/{dagre-Cpy31xJW.js → dagre-Bmjs8zJA.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-C8fyxHFd.js → dagre-KV5264BT-BZCP2wnq.js} +1 -1
- package/payload/server/public/assets/data-BsFyBN85.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-ycyhnLvr.js → diagram-5BDNPKRD-8Nt9a4xX.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BkeYicIt.js → diagram-G4DWMVQ6-vh5tcYqJ.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-BcGZU-Q3.js → diagram-MMDJMWI5-DGf--jc8.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-DuBDCFb_.js → diagram-TYMM5635-CsO7TIdw.js} +1 -1
- package/payload/server/public/assets/{dist-BYc_arNy.js → dist-cdnE4DqK.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DmkeOzvp.js → erDiagram-SMLLAGMA-4a78yV8_.js} +1 -1
- package/payload/server/public/assets/file-text-B1HjPFbM.js +1 -0
- package/payload/server/public/assets/{flatten-QjnJ1Gcl.js → flatten-BtIc9jX7.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CkE-pjuB.js → flowDiagram-DWJPFMVM-BoQBXs6t.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-Cjiy3kvE.js → ganttDiagram-T4ZO3ILL-CvzqwCC8.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-DfcaTE9L.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CsI4lKZm.js → gitGraphDiagram-UUTBAWPF-D_nBxay_.js} +1 -1
- package/payload/server/public/assets/graph-CIC-mgKR.js +51 -0
- package/payload/server/public/assets/graph-labels-BnpHCHaQ.js +1 -0
- package/payload/server/public/assets/{graphlib-BkXxC6D5.js → graphlib-D0NdsKJI.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-CD-u6gw9.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-C6gPQCvO.js +2 -0
- package/payload/server/public/assets/{isEmpty-BavJI9Cn.js → isEmpty-Bu4fZ8Kf.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-D8lZtjRc.js → ishikawaDiagram-UXIWVN3A-auW-s0i0.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-kLE7SiR_.js → journeyDiagram-VCZTEJTY-3Q6AWK4A.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-ove6JuD3.js → kanban-definition-6JOO6SKY-B4MPFp98.js} +1 -1
- package/payload/server/public/assets/{line-CZMSoxM6.js → line-26MdeG5Z.js} +1 -1
- package/payload/server/public/assets/{linear-Be8IK9hK.js → linear-Dq9s_bDO.js} +1 -1
- package/payload/server/public/assets/{maximize-2-BbzPm7o8.js → maximize-2-BL7QVTcQ.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-BBADqbnp.js → mermaid-parser.core-vLEpOXgf.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-mH3N7K0I.js → mermaid.core-Durk4m6D.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-BjwwwWil.js → mindmap-definition-QFDTVHPH-DOIg-TyG.js} +1 -1
- package/payload/server/public/assets/{operator-DCNWUKP_.js → operator-B62h_TaC.js} +1 -1
- package/payload/server/public/assets/{ordinal-BHeIKG-K.js → ordinal-C2TEWKNu.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-BaLYeIrU.js +1 -0
- package/payload/server/public/assets/page-BUUBseJZ.js +32 -0
- package/payload/server/public/assets/page-Bw-tYjw7.js +1 -0
- package/payload/server/public/assets/{pdf-render-fJz4vym9.js → pdf-render-C257cidb.js} +1 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-CL-XJtk-.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-D-lXWWta.js → pieDiagram-DEJITSTG-DtgBHZfi.js} +1 -1
- package/payload/server/public/assets/{public-DXJXQPwe.js → public-BI21tOkm.js} +1 -1
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-13QyG_AO.js → quadrantDiagram-34T5L4WZ-BTc5Qn2y.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-Cn-g6F_h.js +1 -0
- package/payload/server/public/assets/{reduce-Fm685to3.js → reduce-BGpN5lgn.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-Bx45Bgn4.js → requirementDiagram-MS252O5E-BNgOO5YW.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-L42fL8ey.js → rotate-ccw-C_20Bc3E.js} +1 -1
- package/payload/server/public/assets/routines-Ci3N8wqV.js +1 -0
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Cj-Gq25v.js → sankeyDiagram-XADWPNL6-MyUATmVt.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-B8RDRq93.js → sequenceDiagram-FGHM5R23-CBJrF5Vi.js} +1 -1
- package/payload/server/public/assets/skills-CiflzOko.js +1 -0
- package/payload/server/public/assets/{src-D3VYuW_Z.js → src-DekKlUCp.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DoyFF1Kl.js → stateDiagram-FHFEXIEX-6wbUjn1Q.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdMdfBeC.js +1 -0
- package/payload/server/public/assets/{tasks-GNtvZL8F.js → tasks-DC2Yf2Ev.js} +1 -1
- package/payload/server/public/assets/{time-entry-format-BreNpFLJ.js → time-entry-format-CNcjs2HV.js} +1 -1
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Df4RQXm6.js → timeline-definition-GMOUNBTQ-BHjTMCGY.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CmZoOGlC.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-H27WFS-y.js +1 -0
- package/payload/server/public/assets/{triangle-alert-DumCWC08.js → triangle-alert-CngnWtjD.js} +1 -1
- package/payload/server/public/assets/{useCopyFeedback-DHCtz8qX.js → useCopyFeedback-DZ9Bw5CI.js} +1 -1
- package/payload/server/public/assets/{useSubAccountSwitcher-Bc7XHr0L.js → useSubAccountSwitcher-CHwQhkaI.js} +1 -1
- package/payload/server/public/assets/{useSubAccountSwitcher-DPHQJO7E.css → useSubAccountSwitcher-yFQqnpQ8.css} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-C3G6aqZr.js +2 -0
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-D2o5og9l.js → vennDiagram-DHZGUBPP-yo3-cf0U.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-DNpWIvU4.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BDueObbS.js → wardleyDiagram-NUSXRM2D-DZlyFzrg.js} +1 -1
- package/payload/server/public/assets/{wrench-iWkROE1V.js → wrench-dky2-13x.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BTYs4Fgh.js → xychartDiagram-5P7HB3ND-B5HV5h80.js} +1 -1
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +8 -8
- package/payload/server/public/chat.html +16 -15
- package/payload/server/public/data.html +13 -12
- package/payload/server/public/graph.html +10 -10
- package/payload/server/public/index.html +17 -16
- package/payload/server/public/operator.html +17 -16
- package/payload/server/public/public.html +16 -15
- package/payload/server/public/routines.html +7 -7
- package/payload/server/public/skills.html +19 -0
- package/payload/server/public/tasks.html +7 -7
- package/payload/server/server.js +714 -402
- package/payload/server/public/assets/AdminShell-BFVVkWFC.js +0 -2
- package/payload/server/public/assets/admin-BWb8me-E.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-D-AX2VuA.js +0 -1
- package/payload/server/public/assets/channel-DZ5sh6YQ.js +0 -1
- package/payload/server/public/assets/chat-MvnxPJZ5.js +0 -1
- package/payload/server/public/assets/chevron-left-BzIg4in6.js +0 -1
- package/payload/server/public/assets/chevron-right-BcFSa9C3.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-CcjBLp4a.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-B2WjDYBE.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CT3jNrze.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DJRsjAkC.js +0 -1
- package/payload/server/public/assets/clock-Dr3NGtjR.js +0 -1
- package/payload/server/public/assets/clone-FcEDnoMT.js +0 -1
- package/payload/server/public/assets/data-BjqC4hyM.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-D1uhnP9U.js +0 -1
- package/payload/server/public/assets/graph-B7niLM97.js +0 -51
- package/payload/server/public/assets/graph-labels-DykmXYHA.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-oNm27GAV.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-LxTftqyS.js +0 -2
- package/payload/server/public/assets/packet-4T2RLAQJ-eQNVGiK3.js +0 -1
- package/payload/server/public/assets/page-C4TrTU6r.js +0 -32
- package/payload/server/public/assets/page-DUgrGrJp.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-E1u-48rt.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-Cn2cGN90.js +0 -1
- package/payload/server/public/assets/routines-JOV6xdYh.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Bml-X4-H.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CimabhXy.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-Cg264rpM.js +0 -1
- package/payload/server/public/assets/useVoiceRecorder-Cu6zvuFx.js +0 -2
- package/payload/server/public/assets/wardley-RL74JXVD-tbgfCg0E.js +0 -1
- /package/payload/server/public/assets/{_baseFor-Bvwvhrz4.js → _baseFor-Be3EKK3K.js} +0 -0
- /package/payload/server/public/assets/{array-D3d-WgFW.js → array-X0JlPOfd.js} +0 -0
- /package/payload/server/public/assets/{chunk-fQC6bEKA.js → chunk-CCr-iYLO.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-Cun-OM6a.js → cytoscape.esm-CI2IWMLB.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-CisKV5Ew.js → defaultLocale-B6RGN4id.js} +0 -0
- /package/payload/server/public/assets/{init-D9ZOVaZ3.js → init-BmUWJJHz.js} +0 -0
- /package/payload/server/public/assets/{katex-C-3ZDK8o.js → katex-BjZuzSQn.js} +0 -0
- /package/payload/server/public/assets/{path-BMOgQSLM.js → path-CoPyR7c2.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-DL2DwvxV.js → preload-helper-BQrMkyGX.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-BrTFrov0.js → rough.esm-jSt7UMyi.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -503,7 +503,7 @@ var require_dist3 = __commonJS({
|
|
|
503
503
|
"../lib/graph-style/dist/index.js"(exports) {
|
|
504
504
|
"use strict";
|
|
505
505
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
506
|
-
exports.FALLBACK_LABEL_SHAPE = exports.EXTERNAL_LABEL_SHAPES = exports.ALL_GRAPH_LABELS = exports.ADDITIONAL_BASE_LABELS = exports.FALLBACK_LABEL_COLOUR = exports.GRAPH_LABEL_COLOURS = void 0;
|
|
506
|
+
exports.CODE_EMITTED_NODE_LABELS = exports.FALLBACK_LABEL_SHAPE = exports.EXTERNAL_LABEL_SHAPES = exports.ALL_GRAPH_LABELS = exports.ADDITIONAL_BASE_LABELS = exports.FALLBACK_LABEL_COLOUR = exports.GRAPH_LABEL_COLOURS = void 0;
|
|
507
507
|
exports.pickDisplayLabel = pickDisplayLabel2;
|
|
508
508
|
exports.colourForLabel = colourForLabel2;
|
|
509
509
|
exports.shapeForLabel = shapeForLabel2;
|
|
@@ -531,11 +531,12 @@ var require_dist3 = __commonJS({
|
|
|
531
531
|
// JobLogic service-delivery ontology (Task 1084; supersedes the Task 650/773
|
|
532
532
|
// homegrown set). Muted brick-red / earthy family — the service register sits
|
|
533
533
|
// apart from people-terracotta, viewing-amber, and task-rose bands so
|
|
534
|
-
// sitedesk legends read as their own group.
|
|
535
|
-
// labels
|
|
536
|
-
// JobCost, Contact, PurchaseOrderLine, InvoiceLine,
|
|
537
|
-
//
|
|
538
|
-
//
|
|
534
|
+
// sitedesk legends read as their own group. These are the top-level
|
|
535
|
+
// (operator-entry) labels; the child labels (QuoteLine, Milestone, Valuation,
|
|
536
|
+
// VariationNote, JobCost, Contact, PurchaseOrderLine, InvoiceLine,
|
|
537
|
+
// InvoicePayment, Credit) are coloured in the Task 1965 block appended at the
|
|
538
|
+
// end of this object, not here. :Engineer is an additional label on Person
|
|
539
|
+
// and takes the Person colour; :Supplier is an additional label on
|
|
539
540
|
// Organization and takes the tobacco Organization colour. All hexes here are
|
|
540
541
|
// pairwise-unique across the registry.
|
|
541
542
|
Job: "#8C3B2E",
|
|
@@ -633,7 +634,82 @@ var require_dist3 = __commonJS({
|
|
|
633
634
|
// SHAPE_BY_LABEL assigns shapes by index position in ALL_GRAPH_LABELS
|
|
634
635
|
// (this object's key order), so a mid-table insert would silently change
|
|
635
636
|
// the rendered shape of every label after it.
|
|
636
|
-
CashEntry: "#7D5A2B"
|
|
637
|
+
CashEntry: "#7D5A2B",
|
|
638
|
+
// --- Task 1965: colour every node type that can appear in the graph ---
|
|
639
|
+
// Appended at the END so SHAPE_BY_LABEL indices for the labels above are
|
|
640
|
+
// unchanged. Grouped by family band; each hex is pairwise-unique across the
|
|
641
|
+
// whole registry (except the pre-existing UserMessage/Preference twin).
|
|
642
|
+
// Ledger / money children (brown-gold, beside Invoice and CashEntry).
|
|
643
|
+
InvoiceLine: "#7A5326",
|
|
644
|
+
InvoicePayment: "#8A6230",
|
|
645
|
+
QuoteLine: "#9A7038",
|
|
646
|
+
PurchaseOrderLine: "#A67E42",
|
|
647
|
+
JobCost: "#6A4A22",
|
|
648
|
+
Credit: "#B48A48",
|
|
649
|
+
Retainer: "#C29A55",
|
|
650
|
+
Sale: "#8E5E2A",
|
|
651
|
+
Valuation: "#A06A34",
|
|
652
|
+
Order: "#B87C3E",
|
|
653
|
+
DiningOrder: "#C9954E",
|
|
654
|
+
// Documents / content (steel-blue, hue-adjacent to the business slates).
|
|
655
|
+
Content: "#58708C",
|
|
656
|
+
Report: "#6D8299",
|
|
657
|
+
Page: "#849AAF",
|
|
658
|
+
Post: "#93A7BA",
|
|
659
|
+
VariationNote: "#47617B",
|
|
660
|
+
FileArtifact: "#A9BBCC",
|
|
661
|
+
// Marketing (bright teal-green, apart from workflow and research teals).
|
|
662
|
+
SocialPost: "#2FA69A",
|
|
663
|
+
Campaign: "#3FB8A0",
|
|
664
|
+
BrandDeal: "#57C2AE",
|
|
665
|
+
Recommendation: "#74CDBB",
|
|
666
|
+
// CRM people (terracotta, beside Person and Customer).
|
|
667
|
+
Contact: "#C97E52",
|
|
668
|
+
Lead: "#A85E38",
|
|
669
|
+
Position: "#96522E",
|
|
670
|
+
Audience: "#E0B088",
|
|
671
|
+
// Places / transport / retail (forest-emerald, apart from knowledge moss).
|
|
672
|
+
PostalAddress: "#2E8B57",
|
|
673
|
+
Room: "#3A9B63",
|
|
674
|
+
StoreLocation: "#46A96F",
|
|
675
|
+
Vehicle: "#54B77B",
|
|
676
|
+
Route: "#62C187",
|
|
677
|
+
Stop: "#2A7A4C",
|
|
678
|
+
Shipment: "#6FCB93",
|
|
679
|
+
Reservation: "#7ED4A0",
|
|
680
|
+
TableReservation: "#8CDBAC",
|
|
681
|
+
Menu: "#1F6B41",
|
|
682
|
+
MenuItem: "#98E0B6",
|
|
683
|
+
Product: "#34925E",
|
|
684
|
+
StockMovement: "#4CA574",
|
|
685
|
+
// Work / delivery (indigo, apart from the strategy indigo band).
|
|
686
|
+
Milestone: "#4A5FA8",
|
|
687
|
+
Deliverable: "#6274C0",
|
|
688
|
+
TimeEntry: "#8189CE",
|
|
689
|
+
Engagement: "#9AA0DA",
|
|
690
|
+
Case: "#3B4E92",
|
|
691
|
+
Meeting: "#5566B4",
|
|
692
|
+
// Idea (amber).
|
|
693
|
+
Idea: "#E0A82E",
|
|
694
|
+
// Web analytics (sky-cyan, apart from the research teal).
|
|
695
|
+
Session: "#2AA7C4",
|
|
696
|
+
PageView: "#3DB4CE",
|
|
697
|
+
Click: "#55C0D6",
|
|
698
|
+
ScrollMilestone: "#70CCDE",
|
|
699
|
+
TimelineEvent: "#1E93B0",
|
|
700
|
+
AnonVisitor: "#88D6E6",
|
|
701
|
+
AEOAudit: "#46B0CB",
|
|
702
|
+
// WhatsApp transport (brand green).
|
|
703
|
+
WhatsAppConversation: "#128C7E",
|
|
704
|
+
WhatsAppMessage: "#1FA894",
|
|
705
|
+
// Cloudflare / chain infra (grey-blue).
|
|
706
|
+
CloudflareHostname: "#5B6E82",
|
|
707
|
+
CloudflareTunnel: "#6E8296",
|
|
708
|
+
Chain: "#47586A",
|
|
709
|
+
ChainLink: "#8496AA",
|
|
710
|
+
// Voice (violet).
|
|
711
|
+
VoiceProfile: "#9B59B6",
|
|
712
|
+
VoiceEdit: "#B07CC9"
|
|
637
713
|
};
|
|
638
714
|
exports.FALLBACK_LABEL_COLOUR = "#94A3B8";
|
|
639
715
|
exports.ADDITIONAL_BASE_LABELS = Object.freeze(/* @__PURE__ */ new Set(["Applicant", "Engineer", "GuestProfile", "Supplier"]));
|
|
@@ -669,6 +745,7 @@ var require_dist3 = __commonJS({
|
|
|
669
745
|
function shapeForLabel2(label) {
|
|
670
746
|
return SHAPE_BY_LABEL[label] ?? exports.FALLBACK_LABEL_SHAPE;
|
|
671
747
|
}
|
|
748
|
+
exports.CODE_EMITTED_NODE_LABELS = Object.freeze(/* @__PURE__ */ new Set(["FileArtifact"]));
|
|
672
749
|
var LABEL_ICONS = {
|
|
673
750
|
LocalBusiness: '<path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5"></path><path d="M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244"></path><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05"></path>',
|
|
674
751
|
Service: '<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"></path>',
|
|
@@ -732,7 +809,68 @@ var require_dist3 = __commonJS({
|
|
|
732
809
|
Source: '<path d="M12 7v14"></path><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"></path>',
|
|
733
810
|
Finding: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"></path><path d="M9 18h6"></path><path d="M10 22h4"></path>',
|
|
734
811
|
Hypothesis: '<path d="M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2"></path><path d="M6.453 15h11.094"></path><path d="M8.5 2h7"></path>',
|
|
735
|
-
CashEntry: '<rect width="20" height="12" x="2" y="6" rx="2"></rect><circle cx="12" cy="12" r="2"></circle><path d="M6 12h.01"></path><path d="M18 12h.01"></path>'
|
|
812
|
+
CashEntry: '<rect width="20" height="12" x="2" y="6" rx="2"></rect><circle cx="12" cy="12" r="2"></circle><path d="M6 12h.01"></path><path d="M18 12h.01"></path>',
|
|
813
|
+
// --- Task 1965: glyphs for the 60 previously-uncovered node labels ---
|
|
814
|
+
InvoiceLine: '<path d="M13 16H8" /><path d="M14 8H8" /><path d="M16 12H8" /><path d="M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" />',
|
|
815
|
+
InvoicePayment: '<path d="M11 15h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 17" /><path d="m7 21 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9" /><path d="m2 16 6 6" /><circle cx="16" cy="9" r="2.9" /><circle cx="6" cy="5" r="3" />',
|
|
816
|
+
QuoteLine: '<path d="M3 5h.01" /><path d="M3 12h.01" /><path d="M3 19h.01" /><path d="M8 5h13" /><path d="M8 12h13" /><path d="M8 19h13" />',
|
|
817
|
+
PurchaseOrderLine: '<path d="M11 5h10" /><path d="M11 12h10" /><path d="M11 19h10" /><path d="M4 4h1v5" /><path d="M4 9h2" /><path d="M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02" />',
|
|
818
|
+
JobCost: '<rect width="20" height="12" x="2" y="6" rx="2" /><circle cx="12" cy="12" r="2" /><path d="M6 12h.01M18 12h.01" />',
|
|
819
|
+
Credit: '<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" /><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8" /><path d="M12 18V6" />',
|
|
820
|
+
Retainer: '<path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1" /><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4" />',
|
|
821
|
+
Sale: '<path d="M12 17V7" /><path d="M16 8h-6a2 2 0 0 0 0 4h4a2 2 0 0 1 0 4H8" /><path d="M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" />',
|
|
822
|
+
Valuation: '<path d="M12 3v18" /><path d="m19 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1" /><path d="m5 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M7 21h10" />',
|
|
823
|
+
Order: '<path d="M16 10a4 4 0 0 1-8 0" /><path d="M3.103 6.034h17.794" /><path d="M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z" />',
|
|
824
|
+
DiningOrder: '<path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2" /><path d="M7 2v20" /><path d="M21 15V2a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7" />',
|
|
825
|
+
Content: '<path d="M15 18h-5" /><path d="M18 14h-8" /><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2" /><rect width="8" height="4" x="10" y="6" rx="1" />',
|
|
826
|
+
Report: '<rect width="8" height="4" x="8" y="2" rx="1" ry="1" /><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" /><path d="M12 11h4" /><path d="M12 16h4" /><path d="M8 11h.01" /><path d="M8 16h.01" />',
|
|
827
|
+
Page: '<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /><path d="M14 2v5a1 1 0 0 0 1 1h5" />',
|
|
828
|
+
Post: '<path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" /><path d="M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z" />',
|
|
829
|
+
SocialPost: '<path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z" /><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14" /><path d="M8 6v8" />',
|
|
830
|
+
VariationNote: '<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /><path d="M9 10h6" /><path d="M12 13V7" /><path d="M9 17h6" />',
|
|
831
|
+
Contact: '<path d="M16 2v2" /><path d="M17.915 22a6 6 0 0 0-12 0" /><path d="M8 2v2" /><circle cx="12" cy="12" r="4" /><rect x="3" y="4" width="18" height="18" rx="2" />',
|
|
832
|
+
Lead: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><line x1="19" x2="19" y1="8" y2="14" /><line x1="22" x2="16" y1="11" y2="11" />',
|
|
833
|
+
Position: '<path d="M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16" /><rect width="20" height="14" x="2" y="6" rx="2" />',
|
|
834
|
+
Audience: '<path d="M18 21a8 8 0 0 0-16 0" /><circle cx="10" cy="8" r="5" /><path d="M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3" />',
|
|
835
|
+
PostalAddress: '<path d="M18 8c0 3.613-3.869 7.429-5.393 8.795a1 1 0 0 1-1.214 0C9.87 15.429 6 11.613 6 8a6 6 0 0 1 12 0" /><circle cx="12" cy="8" r="2" /><path d="M8.714 14h-3.71a1 1 0 0 0-.948.683l-2.004 6A1 1 0 0 0 3 22h18a1 1 0 0 0 .948-1.316l-2-6a1 1 0 0 0-.949-.684h-3.712" />',
|
|
836
|
+
Room: '<path d="M11 20H2" /><path d="M11 4.562v16.157a1 1 0 0 0 1.242.97L19 20V5.562a2 2 0 0 0-1.515-1.94l-4-1A2 2 0 0 0 11 4.561z" /><path d="M11 4H8a2 2 0 0 0-2 2v14" /><path d="M14 12h.01" /><path d="M22 20h-3" />',
|
|
837
|
+
StoreLocation: '<path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5" /><path d="M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244" /><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05" />',
|
|
838
|
+
Vehicle: '<path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2" /><circle cx="7" cy="17" r="2" /><path d="M9 17h6" /><circle cx="17" cy="17" r="2" />',
|
|
839
|
+
Route: '<circle cx="6" cy="19" r="3" /><path d="M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15" /><circle cx="18" cy="5" r="3" />',
|
|
840
|
+
Stop: '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" /><circle cx="12" cy="10" r="3" />',
|
|
841
|
+
Shipment: '<path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z" /><path d="M12 22V12" /><polyline points="3.29 7 12 12 20.71 7" /><path d="m7.5 4.27 9 5.15" />',
|
|
842
|
+
Reservation: '<path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" /><path d="m9 16 2 2 4-4" />',
|
|
843
|
+
TableReservation: '<path d="m16 2-2.3 2.3a3 3 0 0 0 0 4.2l1.8 1.8a3 3 0 0 0 4.2 0L22 8" /><path d="M15 15 3.3 3.3a4.2 4.2 0 0 0 0 6l7.3 7.3c.7.7 2 .7 2.8 0L15 15Zm0 0 7 7" /><path d="m2.1 21.8 6.4-6.3" /><path d="m19 5-7 7" />',
|
|
844
|
+
Menu: '<path d="M12 5v16" /><path d="M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z" />',
|
|
845
|
+
MenuItem: '<path d="M7 21h10" /><path d="M12 21a9 9 0 0 0 9-9H3a9 9 0 0 0 9 9Z" /><path d="M11.38 12a2.4 2.4 0 0 1-.4-4.77 2.4 2.4 0 0 1 3.2-2.77 2.4 2.4 0 0 1 3.47-.63 2.4 2.4 0 0 1 3.37 3.37 2.4 2.4 0 0 1-1.1 3.7 2.51 2.51 0 0 1 .03 1.1" /><path d="m13 12 4-4" /><path d="M10.9 7.25A3.99 3.99 0 0 0 4 10c0 .73.2 1.41.54 2" />',
|
|
846
|
+
Product: '<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" /><path d="m3.3 7 8.7 5 8.7-5" /><path d="M12 22V12" />',
|
|
847
|
+
StockMovement: '<path d="m16 3 4 4-4 4" /><path d="M20 7H4" /><path d="m8 21-4-4 4-4" /><path d="M4 17h16" />',
|
|
848
|
+
Milestone: '<path d="M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528" />',
|
|
849
|
+
Deliverable: '<path d="M12 22V12" /><path d="m16 17 2 2 4-4" /><path d="M21 11.127V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l1.32-.753" /><path d="M3.29 7 12 12l8.71-5" /><path d="m7.5 4.27 8.997 5.148" />',
|
|
850
|
+
TimeEntry: '<line x1="10" x2="14" y1="2" y2="2" /><line x1="12" x2="15" y1="14" y2="11" /><circle cx="12" cy="14" r="8" />',
|
|
851
|
+
Engagement: '<path d="m11 17 2 2a1 1 0 1 0 3-3" /><path d="m14 14 2.5 2.5a1 1 0 1 0 3-3l-3.88-3.88a3 3 0 0 0-4.24 0l-.88.88a1 1 0 1 1-3-3l2.81-2.81a5.79 5.79 0 0 1 7.06-.87l.47.28a2 2 0 0 0 1.42.25L21 4" /><path d="m21 3 1 11h-2" /><path d="M3 3 2 14l6.5 6.5a1 1 0 1 0 3-3" /><path d="M3 4h8" />',
|
|
852
|
+
Case: '<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />',
|
|
853
|
+
Meeting: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><path d="M16 3.128a4 4 0 0 1 0 7.744" /><path d="M22 21v-2a4 4 0 0 0-3-3.87" /><circle cx="9" cy="7" r="4" />',
|
|
854
|
+
Idea: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5" /><path d="M9 18h6" /><path d="M10 22h4" />',
|
|
855
|
+
Campaign: '<path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5" /><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09" /><path d="M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z" /><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05" />',
|
|
856
|
+
BrandDeal: '<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" /><path d="m9 12 2 2 4-4" />',
|
|
857
|
+
Recommendation: '<path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" /><path d="M7 10v12" />',
|
|
858
|
+
Session: '<rect width="20" height="14" x="2" y="3" rx="2" /><line x1="8" x2="16" y1="21" y2="21" /><line x1="12" x2="12" y1="17" y2="21" />',
|
|
859
|
+
PageView: '<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" /><circle cx="12" cy="12" r="3" />',
|
|
860
|
+
Click: '<path d="M14 4.1 12 6" /><path d="m5.1 8-2.9-.8" /><path d="m6 12-1.9 2" /><path d="M7.2 2.2 8 5.1" /><path d="M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z" />',
|
|
861
|
+
ScrollMilestone: '<path d="m7 6 5 5 5-5" /><path d="m7 13 5 5 5-5" />',
|
|
862
|
+
TimelineEvent: '<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" /><path d="M3 3v5h5" /><path d="M12 7v5l4 2" />',
|
|
863
|
+
AnonVisitor: '<path d="M9 10h.01" /><path d="M15 10h.01" /><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z" />',
|
|
864
|
+
AEOAudit: '<path d="m8 11 2 2 4-4" /><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" />',
|
|
865
|
+
WhatsAppConversation: '<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719" />',
|
|
866
|
+
WhatsAppMessage: '<path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" /><path d="M7 11h10" /><path d="M7 15h6" /><path d="M7 7h8" />',
|
|
867
|
+
CloudflareHostname: '<circle cx="12" cy="12" r="10" /><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" /><path d="M2 12h20" />',
|
|
868
|
+
CloudflareTunnel: '<rect x="16" y="16" width="6" height="6" rx="1" /><rect x="2" y="16" width="6" height="6" rx="1" /><rect x="9" y="2" width="6" height="6" rx="1" /><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3" /><path d="M12 12V8" />',
|
|
869
|
+
Chain: '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />',
|
|
870
|
+
ChainLink: '<path d="M9 17H7A5 5 0 0 1 7 7h2" /><path d="M15 7h2a5 5 0 1 1 0 10h-2" /><line x1="8" x2="16" y1="12" y2="12" />',
|
|
871
|
+
FileArtifact: '<path d="M13.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v11.5" /><path d="M14 2v5a1 1 0 0 0 1 1h5" /><path d="M8 12v-1" /><path d="M8 18v-2" /><path d="M8 7V6" /><circle cx="8" cy="20" r="2" />',
|
|
872
|
+
VoiceProfile: '<path d="M12 19v3" /><path d="M19 10v2a7 7 0 0 1-14 0v-2" /><rect x="9" y="2" width="6" height="13" rx="3" />',
|
|
873
|
+
VoiceEdit: '<path d="M2 10v3" /><path d="M6 6v11" /><path d="M10 3v18" /><path d="M14 8v7" /><path d="M18 5v13" /><path d="M22 10v3" />'
|
|
736
874
|
};
|
|
737
875
|
function iconForLabel2(label) {
|
|
738
876
|
return Object.prototype.hasOwnProperty.call(LABEL_ICONS, label) ? LABEL_ICONS[label] : null;
|
|
@@ -1615,10 +1753,10 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
1615
1753
|
};
|
|
1616
1754
|
|
|
1617
1755
|
// server/index.ts
|
|
1618
|
-
import { readFileSync as
|
|
1756
|
+
import { readFileSync as readFileSync46, existsSync as existsSync43, watchFile, readdirSync as readdirSync27, statSync as statSync18 } from "fs";
|
|
1619
1757
|
import { spawn as spawn3 } from "child_process";
|
|
1620
1758
|
import { createHash as createHash7 } from "crypto";
|
|
1621
|
-
import { resolve as
|
|
1759
|
+
import { resolve as resolve42, join as join47, basename as basename13 } from "path";
|
|
1622
1760
|
import { homedir as homedir4 } from "os";
|
|
1623
1761
|
import { monitorEventLoopDelay } from "perf_hooks";
|
|
1624
1762
|
|
|
@@ -2892,7 +3030,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
2892
3030
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
2893
3031
|
console.error(`${TAG6} draining credential save queue\u2026`);
|
|
2894
3032
|
const timer = new Promise(
|
|
2895
|
-
(
|
|
3033
|
+
(resolve43) => setTimeout(() => resolve43("timeout"), timeoutMs)
|
|
2896
3034
|
);
|
|
2897
3035
|
const result = await Promise.race([
|
|
2898
3036
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -3069,11 +3207,11 @@ async function createWaSocket(opts) {
|
|
|
3069
3207
|
return sock;
|
|
3070
3208
|
}
|
|
3071
3209
|
async function waitForConnection(sock) {
|
|
3072
|
-
return new Promise((
|
|
3210
|
+
return new Promise((resolve43, reject) => {
|
|
3073
3211
|
const handler = (update) => {
|
|
3074
3212
|
if (update.connection === "open") {
|
|
3075
3213
|
sock.ev.off("connection.update", handler);
|
|
3076
|
-
|
|
3214
|
+
resolve43();
|
|
3077
3215
|
}
|
|
3078
3216
|
if (update.connection === "close") {
|
|
3079
3217
|
sock.ev.off("connection.update", handler);
|
|
@@ -3181,7 +3319,7 @@ function isTimeoutError(err) {
|
|
|
3181
3319
|
return Boolean(err?.__maxyTimeout);
|
|
3182
3320
|
}
|
|
3183
3321
|
function withTimeout(label, promise, timeoutMs) {
|
|
3184
|
-
return new Promise((
|
|
3322
|
+
return new Promise((resolve43, reject) => {
|
|
3185
3323
|
const timer = setTimeout(() => {
|
|
3186
3324
|
const err = new Error(`${label} timed out after ${timeoutMs}ms`);
|
|
3187
3325
|
err.__maxyTimeout = true;
|
|
@@ -3191,7 +3329,7 @@ function withTimeout(label, promise, timeoutMs) {
|
|
|
3191
3329
|
promise.then(
|
|
3192
3330
|
(value) => {
|
|
3193
3331
|
clearTimeout(timer);
|
|
3194
|
-
|
|
3332
|
+
resolve43(value);
|
|
3195
3333
|
},
|
|
3196
3334
|
(err) => {
|
|
3197
3335
|
clearTimeout(timer);
|
|
@@ -4256,8 +4394,8 @@ async function persistWhatsAppMessage(input) {
|
|
|
4256
4394
|
const { givenName, familyName } = splitName(input.pushName);
|
|
4257
4395
|
const prev = sessionWriteLocks.get(input.cacheKey);
|
|
4258
4396
|
let release;
|
|
4259
|
-
const mine = new Promise((
|
|
4260
|
-
release =
|
|
4397
|
+
const mine = new Promise((resolve43) => {
|
|
4398
|
+
release = resolve43;
|
|
4261
4399
|
});
|
|
4262
4400
|
const chained = (prev ?? Promise.resolve()).then(() => mine);
|
|
4263
4401
|
sessionWriteLocks.set(input.cacheKey, chained);
|
|
@@ -5994,11 +6132,11 @@ async function connectWithReconnect(conn) {
|
|
|
5994
6132
|
console.error(
|
|
5995
6133
|
`${TAG17} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
5996
6134
|
);
|
|
5997
|
-
await new Promise((
|
|
5998
|
-
const timer = setTimeout(
|
|
6135
|
+
await new Promise((resolve43) => {
|
|
6136
|
+
const timer = setTimeout(resolve43, delay);
|
|
5999
6137
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
6000
6138
|
clearTimeout(timer);
|
|
6001
|
-
|
|
6139
|
+
resolve43();
|
|
6002
6140
|
}, { once: true });
|
|
6003
6141
|
});
|
|
6004
6142
|
}
|
|
@@ -6006,16 +6144,16 @@ async function connectWithReconnect(conn) {
|
|
|
6006
6144
|
}
|
|
6007
6145
|
}
|
|
6008
6146
|
function waitForDisconnectEvent(conn) {
|
|
6009
|
-
return new Promise((
|
|
6147
|
+
return new Promise((resolve43) => {
|
|
6010
6148
|
if (!conn.sock) {
|
|
6011
|
-
|
|
6149
|
+
resolve43();
|
|
6012
6150
|
return;
|
|
6013
6151
|
}
|
|
6014
6152
|
const sock = conn.sock;
|
|
6015
6153
|
const handler = (update) => {
|
|
6016
6154
|
if (update.connection === "close") {
|
|
6017
6155
|
sock.ev.off("connection.update", handler);
|
|
6018
|
-
|
|
6156
|
+
resolve43();
|
|
6019
6157
|
}
|
|
6020
6158
|
};
|
|
6021
6159
|
sock.ev.on("connection.update", handler);
|
|
@@ -6125,7 +6263,7 @@ function monitorInbound(conn) {
|
|
|
6125
6263
|
}
|
|
6126
6264
|
const entries = messageStore.get(storeKey);
|
|
6127
6265
|
console.error(
|
|
6128
|
-
`${TAG17} stored message ${msg.key.id ?? "?"} for ${remoteJid} (type: ${upsert.type}, store size: ${entries?.length ?? 0}/${MESSAGE_STORE_MAX})
|
|
6266
|
+
`${TAG17} stored message ${msg.key.id ?? "?"} for ${remoteJid} (type: ${upsert.type}, store size: ${entries?.length ?? 0}/${MESSAGE_STORE_MAX}) storeAccount=${persistAccountId} socketOwner=${conn.platformAccountId}`
|
|
6129
6267
|
);
|
|
6130
6268
|
recordActivity({
|
|
6131
6269
|
accountId: conn.accountId,
|
|
@@ -6489,8 +6627,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
6489
6627
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
6490
6628
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
6491
6629
|
let resolvePending;
|
|
6492
|
-
const sttPending = new Promise((
|
|
6493
|
-
resolvePending =
|
|
6630
|
+
const sttPending = new Promise((resolve43) => {
|
|
6631
|
+
resolvePending = resolve43;
|
|
6494
6632
|
});
|
|
6495
6633
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
6496
6634
|
try {
|
|
@@ -6879,20 +7017,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
|
|
|
6879
7017
|
|
|
6880
7018
|
// server/routes/health.ts
|
|
6881
7019
|
function checkPort(port2, timeoutMs = 500) {
|
|
6882
|
-
return new Promise((
|
|
7020
|
+
return new Promise((resolve43) => {
|
|
6883
7021
|
const socket = createConnection2(port2, "127.0.0.1");
|
|
6884
7022
|
socket.setTimeout(timeoutMs);
|
|
6885
7023
|
socket.once("connect", () => {
|
|
6886
7024
|
socket.destroy();
|
|
6887
|
-
|
|
7025
|
+
resolve43(true);
|
|
6888
7026
|
});
|
|
6889
7027
|
socket.once("error", () => {
|
|
6890
7028
|
socket.destroy();
|
|
6891
|
-
|
|
7029
|
+
resolve43(false);
|
|
6892
7030
|
});
|
|
6893
7031
|
socket.once("timeout", () => {
|
|
6894
7032
|
socket.destroy();
|
|
6895
|
-
|
|
7033
|
+
resolve43(false);
|
|
6896
7034
|
});
|
|
6897
7035
|
});
|
|
6898
7036
|
}
|
|
@@ -7147,8 +7285,8 @@ function webchatTurnTimeoutMs() {
|
|
|
7147
7285
|
return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
|
|
7148
7286
|
}
|
|
7149
7287
|
function createChatRoutes(deps) {
|
|
7150
|
-
const
|
|
7151
|
-
|
|
7288
|
+
const app67 = new Hono();
|
|
7289
|
+
app67.post("/", async (c) => {
|
|
7152
7290
|
console.log(`[chat-route] entered route=public method=POST`);
|
|
7153
7291
|
const contentType = c.req.header("content-type") ?? "";
|
|
7154
7292
|
const account = resolveAccount();
|
|
@@ -7412,7 +7550,7 @@ ${result.result.text}` : result.result.text;
|
|
|
7412
7550
|
}
|
|
7413
7551
|
});
|
|
7414
7552
|
});
|
|
7415
|
-
return
|
|
7553
|
+
return app67;
|
|
7416
7554
|
}
|
|
7417
7555
|
|
|
7418
7556
|
// app/lib/channel-pty-bridge/admin-session-id.ts
|
|
@@ -7446,8 +7584,8 @@ function isLoopbackAddr(addr) {
|
|
|
7446
7584
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
7447
7585
|
}
|
|
7448
7586
|
function createScheduleInjectRoutes(deps) {
|
|
7449
|
-
const
|
|
7450
|
-
|
|
7587
|
+
const app67 = new Hono();
|
|
7588
|
+
app67.post("/", async (c) => {
|
|
7451
7589
|
const env = c.env;
|
|
7452
7590
|
const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
|
|
7453
7591
|
if (!isLoopbackAddr(remoteAddr)) {
|
|
@@ -7548,7 +7686,7 @@ function createScheduleInjectRoutes(deps) {
|
|
|
7548
7686
|
console.error(`${TAG20} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
|
|
7549
7687
|
return c.json({ ok: true }, 200);
|
|
7550
7688
|
});
|
|
7551
|
-
return
|
|
7689
|
+
return app67;
|
|
7552
7690
|
}
|
|
7553
7691
|
|
|
7554
7692
|
// server/index.ts
|
|
@@ -8231,8 +8369,8 @@ async function startLogin(opts) {
|
|
|
8231
8369
|
await clearAuth(authDir);
|
|
8232
8370
|
let resolveCode = null;
|
|
8233
8371
|
let rejectCode = null;
|
|
8234
|
-
const codePromise = new Promise((
|
|
8235
|
-
resolveCode =
|
|
8372
|
+
const codePromise = new Promise((resolve43, reject) => {
|
|
8373
|
+
resolveCode = resolve43;
|
|
8236
8374
|
rejectCode = reject;
|
|
8237
8375
|
});
|
|
8238
8376
|
const codeTimer = setTimeout(
|
|
@@ -8814,9 +8952,9 @@ function evaluateCallerScope(c, requestedAccountId) {
|
|
|
8814
8952
|
}
|
|
8815
8953
|
function callerScopeDenial(c, requestedAccountId) {
|
|
8816
8954
|
const { decision, callerAccountId, houseAdminScope } = evaluateCallerScope(c, requestedAccountId);
|
|
8817
|
-
if (decision.authorized) return null;
|
|
8955
|
+
if (decision.authorized) return { denial: null, callerAccountId };
|
|
8818
8956
|
console.error(`[whatsapp-read-tool] op=authz-deny requested=${requestedAccountId} caller=${callerAccountId ?? "none"} houseAdmin=${houseAdminScope ? "y" : "n"}`);
|
|
8819
|
-
return c.json({ error: decision.reason }, 403);
|
|
8957
|
+
return { denial: c.json({ error: decision.reason }, 403), callerAccountId };
|
|
8820
8958
|
}
|
|
8821
8959
|
function houseSocketScopeDenial(c, op) {
|
|
8822
8960
|
const houseAccountId = resolveAccount()?.accountId ?? "";
|
|
@@ -9244,7 +9382,7 @@ app2.get("/activity", (c) => {
|
|
|
9244
9382
|
app2.get("/conversations", (c) => {
|
|
9245
9383
|
try {
|
|
9246
9384
|
const requestedAccountId = validateAccountId(c.req.query("accountId") ?? null);
|
|
9247
|
-
const denial = callerScopeDenial(c, requestedAccountId);
|
|
9385
|
+
const { denial, callerAccountId } = callerScopeDenial(c, requestedAccountId);
|
|
9248
9386
|
if (denial) return denial;
|
|
9249
9387
|
const projection = projectionFor(requestedAccountId);
|
|
9250
9388
|
const storeAccountId = resolveReadStoreKey(projection.storeAccountId);
|
|
@@ -9265,7 +9403,7 @@ app2.get("/conversations", (c) => {
|
|
|
9265
9403
|
};
|
|
9266
9404
|
});
|
|
9267
9405
|
conversations.sort((a, b) => (b.lastMessageTimestamp ?? 0) - (a.lastMessageTimestamp ?? 0));
|
|
9268
|
-
console.error(`${TAG25} conversations requested=${requestedAccountId} account=${storeAccountId} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${allConversations.size > 0} count=${conversations.length}`);
|
|
9406
|
+
console.error(`${TAG25} conversations requested=${requestedAccountId} caller=${callerAccountId ?? "none"} account=${storeAccountId} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${allConversations.size > 0} count=${conversations.length}`);
|
|
9269
9407
|
return c.json({ conversations });
|
|
9270
9408
|
} catch (err) {
|
|
9271
9409
|
console.error(`${TAG25} conversations error: ${String(err)}`);
|
|
@@ -9275,7 +9413,7 @@ app2.get("/conversations", (c) => {
|
|
|
9275
9413
|
app2.get("/messages", (c) => {
|
|
9276
9414
|
try {
|
|
9277
9415
|
const requestedAccountId = validateAccountId(c.req.query("accountId") ?? null);
|
|
9278
|
-
const denial = callerScopeDenial(c, requestedAccountId);
|
|
9416
|
+
const { denial, callerAccountId } = callerScopeDenial(c, requestedAccountId);
|
|
9279
9417
|
if (denial) return denial;
|
|
9280
9418
|
const jid = c.req.query("jid");
|
|
9281
9419
|
if (!jid) {
|
|
@@ -9321,7 +9459,7 @@ app2.get("/messages", (c) => {
|
|
|
9321
9459
|
...reactions && reactions.length > 0 ? { reactions } : {}
|
|
9322
9460
|
};
|
|
9323
9461
|
});
|
|
9324
|
-
console.error(`${TAG25} messages requested=${requestedAccountId} account=${storeAccountId} jid=${jid} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${storeMessages.length > 0} limit=${effectiveLimit ?? "all"} returned=${messages.length} withAttachments=${withAttachments}`);
|
|
9462
|
+
console.error(`${TAG25} messages requested=${requestedAccountId} caller=${callerAccountId ?? "none"} account=${storeAccountId} jid=${jid} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${storeMessages.length > 0} limit=${effectiveLimit ?? "all"} returned=${messages.length} withAttachments=${withAttachments}`);
|
|
9325
9463
|
return c.json({ messages });
|
|
9326
9464
|
} catch (err) {
|
|
9327
9465
|
console.error(`${TAG25} messages error: ${String(err)}`);
|
|
@@ -9334,7 +9472,7 @@ app2.get("/conversation-graph-state", async (c) => {
|
|
|
9334
9472
|
const jid = c.req.query("jid");
|
|
9335
9473
|
const accountIdQuery = c.req.query("accountId");
|
|
9336
9474
|
const t0 = Date.now();
|
|
9337
|
-
const denial = callerScopeDenial(c, validateAccountId(accountIdQuery ?? null));
|
|
9475
|
+
const { denial } = callerScopeDenial(c, validateAccountId(accountIdQuery ?? null));
|
|
9338
9476
|
if (denial) return denial;
|
|
9339
9477
|
if (!directCacheKey && !jid) {
|
|
9340
9478
|
const requestedAccountId = validateAccountId(accountIdQuery ?? null);
|
|
@@ -11623,6 +11761,7 @@ function unwrapChannel(text) {
|
|
|
11623
11761
|
return source ? { text: inner, source } : { text: inner };
|
|
11624
11762
|
}
|
|
11625
11763
|
var COMPOSED_ADMIN_FRAME = /^(?:## Scheduled automation \(platform-verified\)\n[\s\S]*?\n\n)?(?:## Standing rules\n[\s\S]*?\n\n)?## Context\n([\s\S]*)\n\n## Instruction\n[\s\S]*$/;
|
|
11764
|
+
var SCHEDULED_MARKER_PREFIX = "## Scheduled automation (platform-verified)\n";
|
|
11626
11765
|
var UPLOAD_ANNOTATION = /(?:\n\n)?\[The operator uploaded \d+ file\(s\): [\s\S]*\]$/;
|
|
11627
11766
|
function rawFromComposedAdminFrame(text) {
|
|
11628
11767
|
const context = text.match(COMPOSED_ADMIN_FRAME)?.[1];
|
|
@@ -11638,6 +11777,7 @@ function uploadCountOf(text) {
|
|
|
11638
11777
|
function operatorInboundTurn(u, ts) {
|
|
11639
11778
|
const rawBody = rawFromComposedAdminFrame(u.text);
|
|
11640
11779
|
const uploadCount = uploadCountOf(u.text);
|
|
11780
|
+
const scheduled = rawBody !== void 0 && u.text.startsWith(SCHEDULED_MARKER_PREFIX);
|
|
11641
11781
|
const text = rawBody === void 0 ? u.text.replace(PUBLIC_UPLOAD_ANNOTATION, "") : u.text;
|
|
11642
11782
|
return {
|
|
11643
11783
|
kind: "operator-inbound",
|
|
@@ -11645,7 +11785,8 @@ function operatorInboundTurn(u, ts) {
|
|
|
11645
11785
|
ts,
|
|
11646
11786
|
...u.source ? { source: u.source } : {},
|
|
11647
11787
|
...rawBody !== void 0 ? { rawBody } : {},
|
|
11648
|
-
...uploadCount !== void 0 ? { uploadCount } : {}
|
|
11788
|
+
...uploadCount !== void 0 ? { uploadCount } : {},
|
|
11789
|
+
...scheduled ? { scheduled: true } : {}
|
|
11649
11790
|
};
|
|
11650
11791
|
}
|
|
11651
11792
|
function asString(content) {
|
|
@@ -11654,16 +11795,6 @@ function asString(content) {
|
|
|
11654
11795
|
function tsOf(row) {
|
|
11655
11796
|
return typeof row.timestamp === "string" ? row.timestamp : null;
|
|
11656
11797
|
}
|
|
11657
|
-
function hasWebchatReply(content) {
|
|
11658
|
-
if (!Array.isArray(content)) return false;
|
|
11659
|
-
for (const block of content) {
|
|
11660
|
-
if (block && typeof block === "object") {
|
|
11661
|
-
const b = block;
|
|
11662
|
-
if (b.type === "tool_use" && b.name === WEBCHAT_REPLY_TOOL) return true;
|
|
11663
|
-
}
|
|
11664
|
-
}
|
|
11665
|
-
return false;
|
|
11666
|
-
}
|
|
11667
11798
|
function joinTextBlocks(content) {
|
|
11668
11799
|
if (!Array.isArray(content)) return "";
|
|
11669
11800
|
const parts = [];
|
|
@@ -11786,9 +11917,8 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
11786
11917
|
out.push({ kind: "agent-error", code, raw, ts });
|
|
11787
11918
|
continue;
|
|
11788
11919
|
}
|
|
11789
|
-
if (hasWebchatReply(msg?.content)) turnCtx.repliedThisTurn = true;
|
|
11790
11920
|
const isEnd = msg?.stop_reason === "end_turn";
|
|
11791
|
-
const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat"
|
|
11921
|
+
const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat";
|
|
11792
11922
|
out.push(...assistantTurns(msg?.content, ts, promoteFinal, erroredIds));
|
|
11793
11923
|
continue;
|
|
11794
11924
|
}
|
|
@@ -11797,7 +11927,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
11797
11927
|
if (content !== null && CHANNEL_WRAPPER2.test(content)) {
|
|
11798
11928
|
const u = unwrapChannel(content);
|
|
11799
11929
|
turnCtx.lastChannelSource = u.source;
|
|
11800
|
-
turnCtx.repliedThisTurn = false;
|
|
11801
11930
|
if (!isScheduleSource(content)) {
|
|
11802
11931
|
out.push(operatorInboundTurn(u, ts));
|
|
11803
11932
|
queuedPendingSuppress.set(u.text, (queuedPendingSuppress.get(u.text) ?? 0) + 1);
|
|
@@ -11811,7 +11940,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
11811
11940
|
if (isChannelQueued) {
|
|
11812
11941
|
const u = unwrapChannel(att.prompt);
|
|
11813
11942
|
turnCtx.lastChannelSource = u.source;
|
|
11814
|
-
turnCtx.repliedThisTurn = false;
|
|
11815
11943
|
if (!isScheduleSource(att.prompt)) {
|
|
11816
11944
|
renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
|
|
11817
11945
|
}
|
|
@@ -11841,7 +11969,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
11841
11969
|
if (isChannel) {
|
|
11842
11970
|
const u = unwrapChannel(text);
|
|
11843
11971
|
turnCtx.lastChannelSource = u.source;
|
|
11844
|
-
turnCtx.repliedThisTurn = false;
|
|
11845
11972
|
if (!isScheduleSource(text)) {
|
|
11846
11973
|
renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
|
|
11847
11974
|
}
|
|
@@ -13818,8 +13945,8 @@ async function reapplyLeversViaManager() {
|
|
|
13818
13945
|
var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
|
|
13819
13946
|
var sendSeq = 0;
|
|
13820
13947
|
function createWebchatRoutes(deps) {
|
|
13821
|
-
const
|
|
13822
|
-
|
|
13948
|
+
const app67 = new Hono();
|
|
13949
|
+
app67.post("/send", requireAdminSession, async (c) => {
|
|
13823
13950
|
let accountId;
|
|
13824
13951
|
try {
|
|
13825
13952
|
accountId = resolvePlatformAccountId();
|
|
@@ -14022,7 +14149,7 @@ ${note}` : note;
|
|
|
14022
14149
|
if (turnTimer.unref) turnTimer.unref();
|
|
14023
14150
|
return c.json({ ok: true });
|
|
14024
14151
|
});
|
|
14025
|
-
|
|
14152
|
+
app67.post("/interrupt", requireAdminSession, async (c) => {
|
|
14026
14153
|
const cacheKey = c.get("cacheKey");
|
|
14027
14154
|
const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
|
|
14028
14155
|
const primaryUserId = resolvePrimaryAdminUserId();
|
|
@@ -14050,7 +14177,7 @@ ${note}` : note;
|
|
|
14050
14177
|
}
|
|
14051
14178
|
return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
|
|
14052
14179
|
});
|
|
14053
|
-
|
|
14180
|
+
app67.post("/settings", requireAdminSession, async (c) => {
|
|
14054
14181
|
const body = await c.req.json().catch(() => null);
|
|
14055
14182
|
const op = body?.op;
|
|
14056
14183
|
const value = body?.value;
|
|
@@ -14090,7 +14217,7 @@ ${note}` : note;
|
|
|
14090
14217
|
console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
|
|
14091
14218
|
return c.json({ ok: true, settingsApplied });
|
|
14092
14219
|
});
|
|
14093
|
-
|
|
14220
|
+
app67.get("/session", requireAdminSession, async (c) => {
|
|
14094
14221
|
let accountId;
|
|
14095
14222
|
try {
|
|
14096
14223
|
accountId = resolvePlatformAccountId();
|
|
@@ -14168,7 +14295,7 @@ ${note}` : note;
|
|
|
14168
14295
|
const indicators = await fetchComposerIndicators(sessionId);
|
|
14169
14296
|
return c.json({ sessionId, projectDir, source, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
|
|
14170
14297
|
});
|
|
14171
|
-
|
|
14298
|
+
app67.post("/permission-verdict", requireAdminSession, async (c) => {
|
|
14172
14299
|
const body = await c.req.json().catch(() => null);
|
|
14173
14300
|
const sessionId = body?.sessionId;
|
|
14174
14301
|
const requestId = body?.request_id;
|
|
@@ -14185,7 +14312,7 @@ ${note}` : note;
|
|
|
14185
14312
|
const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
|
|
14186
14313
|
return c.json({ ok });
|
|
14187
14314
|
});
|
|
14188
|
-
return
|
|
14315
|
+
return app67;
|
|
14189
14316
|
}
|
|
14190
14317
|
|
|
14191
14318
|
// server/routes/webchat-greeting.ts
|
|
@@ -15541,15 +15668,15 @@ function operatorRoleFor(config, userId) {
|
|
|
15541
15668
|
async function buildAccountOptionList(accounts, userId) {
|
|
15542
15669
|
const houseAccount = accounts.find((a) => a.config.role === "house");
|
|
15543
15670
|
console.log(`[admin-accounts] op=list count=${accounts.length} house=${houseAccount?.accountId ?? "none"}`);
|
|
15544
|
-
const
|
|
15671
|
+
const resolve43 = async (a) => {
|
|
15545
15672
|
const businessName = await fetchAccountName(a.accountId) || void 0;
|
|
15546
15673
|
return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId), isHouse: a.config.role === "house" };
|
|
15547
15674
|
};
|
|
15548
15675
|
const houseOptions = await Promise.all(
|
|
15549
|
-
accounts.filter((a) => a.config.role === "house").map(
|
|
15676
|
+
accounts.filter((a) => a.config.role === "house").map(resolve43)
|
|
15550
15677
|
);
|
|
15551
15678
|
const nonHouseOptions = await Promise.all(
|
|
15552
|
-
accounts.filter((a) => a.config.role !== "house").map(
|
|
15679
|
+
accounts.filter((a) => a.config.role !== "house").map(resolve43)
|
|
15553
15680
|
);
|
|
15554
15681
|
const sortKey = (o) => (o.businessName || o.accountId).toLowerCase();
|
|
15555
15682
|
nonHouseOptions.sort((x, y) => {
|
|
@@ -16821,7 +16948,7 @@ function parseSkillPathsFromFrontmatter(fm) {
|
|
|
16821
16948
|
}
|
|
16822
16949
|
return out;
|
|
16823
16950
|
}
|
|
16824
|
-
function listPluginDirs() {
|
|
16951
|
+
function listPluginDirs(accountPluginsDir) {
|
|
16825
16952
|
const out = /* @__PURE__ */ new Map();
|
|
16826
16953
|
const platformPlugins = resolve22(PLATFORM_ROOT, "plugins");
|
|
16827
16954
|
if (existsSync30(platformPlugins)) {
|
|
@@ -16850,8 +16977,38 @@ function listPluginDirs() {
|
|
|
16850
16977
|
}
|
|
16851
16978
|
}
|
|
16852
16979
|
}
|
|
16980
|
+
if (accountPluginsDir && existsSync30(accountPluginsDir)) {
|
|
16981
|
+
try {
|
|
16982
|
+
for (const name of readdirSync22(accountPluginsDir)) {
|
|
16983
|
+
if (out.has(name)) continue;
|
|
16984
|
+
const dir = join33(accountPluginsDir, name);
|
|
16985
|
+
try {
|
|
16986
|
+
if (statSync13(dir).isDirectory()) out.set(name, dir);
|
|
16987
|
+
} catch {
|
|
16988
|
+
}
|
|
16989
|
+
}
|
|
16990
|
+
} catch {
|
|
16991
|
+
}
|
|
16992
|
+
}
|
|
16853
16993
|
return out;
|
|
16854
16994
|
}
|
|
16995
|
+
function accountPluginsDirFor(accountId) {
|
|
16996
|
+
return resolve22(PLATFORM_ROOT, "..", "data/accounts", accountId, "plugins");
|
|
16997
|
+
}
|
|
16998
|
+
function listAccountPluginNames(accountPluginsDir) {
|
|
16999
|
+
if (!existsSync30(accountPluginsDir)) return [];
|
|
17000
|
+
try {
|
|
17001
|
+
return readdirSync22(accountPluginsDir).filter((name) => {
|
|
17002
|
+
try {
|
|
17003
|
+
return statSync13(join33(accountPluginsDir, name)).isDirectory();
|
|
17004
|
+
} catch {
|
|
17005
|
+
return false;
|
|
17006
|
+
}
|
|
17007
|
+
});
|
|
17008
|
+
} catch {
|
|
17009
|
+
return [];
|
|
17010
|
+
}
|
|
17011
|
+
}
|
|
16855
17012
|
function readEnabledPlugins(accountId) {
|
|
16856
17013
|
const accountFile = resolve22(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
|
|
16857
17014
|
if (!existsSync30(accountFile)) return /* @__PURE__ */ new Set();
|
|
@@ -16877,10 +17034,13 @@ function readFrontmatter(path3) {
|
|
|
16877
17034
|
}
|
|
16878
17035
|
function computeActivePlugins(accountId) {
|
|
16879
17036
|
const enabled = readEnabledPlugins(accountId);
|
|
16880
|
-
|
|
16881
|
-
const
|
|
17037
|
+
const accountPluginsDir = accountPluginsDirFor(accountId);
|
|
17038
|
+
const accountPluginNames = listAccountPluginNames(accountPluginsDir);
|
|
17039
|
+
const emitNames = Array.from(/* @__PURE__ */ new Set([...enabled, ...accountPluginNames])).sort();
|
|
17040
|
+
if (emitNames.length === 0) return [];
|
|
17041
|
+
const pluginDirs = listPluginDirs(accountPluginsDir);
|
|
16882
17042
|
const out = [];
|
|
16883
|
-
for (const name of
|
|
17043
|
+
for (const name of emitNames) {
|
|
16884
17044
|
const dir = pluginDirs.get(name);
|
|
16885
17045
|
if (!dir) continue;
|
|
16886
17046
|
const fm = readFrontmatter(join33(dir, "PLUGIN.md"));
|
|
@@ -16934,7 +17094,7 @@ function computeSpecialistDomains(accountId) {
|
|
|
16934
17094
|
} catch {
|
|
16935
17095
|
return [];
|
|
16936
17096
|
}
|
|
16937
|
-
const pluginDirs = listPluginDirs();
|
|
17097
|
+
const pluginDirs = listPluginDirs(accountPluginsDirFor(accountId));
|
|
16938
17098
|
const descByPlugin = /* @__PURE__ */ new Map();
|
|
16939
17099
|
const resolveDesc = (qualified) => {
|
|
16940
17100
|
if (!qualified.startsWith("mcp__")) return void 0;
|
|
@@ -23710,8 +23870,163 @@ app47.patch("/:eventId", requireAdminSession, async (c) => {
|
|
|
23710
23870
|
await session.close();
|
|
23711
23871
|
}
|
|
23712
23872
|
});
|
|
23873
|
+
app47.delete("/:eventId", requireAdminSession, async (c) => {
|
|
23874
|
+
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
23875
|
+
if (!accountId) {
|
|
23876
|
+
console.error('[admin:routines] op=delete auth-rejected reason="no account for session"');
|
|
23877
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
23878
|
+
}
|
|
23879
|
+
const eventId = c.req.param("eventId");
|
|
23880
|
+
const session = getSession();
|
|
23881
|
+
try {
|
|
23882
|
+
const res = await session.run(
|
|
23883
|
+
`MATCH (e:Event {eventId: $eventId, accountId: $accountId})
|
|
23884
|
+
WHERE ${AUTOMATION_WHERE}
|
|
23885
|
+
WITH e, e.name AS name
|
|
23886
|
+
DETACH DELETE e
|
|
23887
|
+
RETURN name`,
|
|
23888
|
+
{ eventId, accountId }
|
|
23889
|
+
);
|
|
23890
|
+
const found = res.records.length > 0;
|
|
23891
|
+
console.log(`[admin:routines] op=delete id=${eventId.slice(0, 8)} found=${found ? 1 : 0}`);
|
|
23892
|
+
return c.json({ found });
|
|
23893
|
+
} catch (err) {
|
|
23894
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23895
|
+
console.error(`[admin:routines] op=delete-fail id=${eventId.slice(0, 8)} err="${message}"`);
|
|
23896
|
+
return c.json({ error: `Delete failed: ${message}` }, 503);
|
|
23897
|
+
} finally {
|
|
23898
|
+
await session.close();
|
|
23899
|
+
}
|
|
23900
|
+
});
|
|
23713
23901
|
var routines_default = app47;
|
|
23714
23902
|
|
|
23903
|
+
// server/routes/admin/skills.ts
|
|
23904
|
+
import { existsSync as existsSync36, readdirSync as readdirSync24, readFileSync as readFileSync39, rmSync as rmSync3 } from "fs";
|
|
23905
|
+
import { resolve as resolve31 } from "path";
|
|
23906
|
+
var app48 = new Hono();
|
|
23907
|
+
var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
23908
|
+
function splitSkillMd(text) {
|
|
23909
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
23910
|
+
const fm = { name: "", description: "", publicEmbed: false };
|
|
23911
|
+
if (!m) return { frontmatter: fm, body: text };
|
|
23912
|
+
for (const line of m[1].split(/\r?\n/)) {
|
|
23913
|
+
const kv = line.match(/^([A-Za-z][\w-]*):[ \t]*(.*)$/);
|
|
23914
|
+
if (!kv) continue;
|
|
23915
|
+
const [, key, rawVal] = kv;
|
|
23916
|
+
const val = stripQuotes(rawVal.trim());
|
|
23917
|
+
if (key === "name") fm.name = val;
|
|
23918
|
+
else if (key === "description") fm.description = val;
|
|
23919
|
+
else if (key === "publicEmbed") fm.publicEmbed = val === "true";
|
|
23920
|
+
}
|
|
23921
|
+
return { frontmatter: fm, body: text.slice(m[0].length) };
|
|
23922
|
+
}
|
|
23923
|
+
function stripQuotes(s) {
|
|
23924
|
+
if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) return s.slice(1, -1);
|
|
23925
|
+
return s;
|
|
23926
|
+
}
|
|
23927
|
+
function accountDirForSession(cacheKey) {
|
|
23928
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
23929
|
+
if (!accountId) return null;
|
|
23930
|
+
const match = listValidAccounts().find((a) => a.accountId === accountId);
|
|
23931
|
+
return match ? { accountId, accountDir: match.accountDir } : null;
|
|
23932
|
+
}
|
|
23933
|
+
function subdirs(dir) {
|
|
23934
|
+
if (!existsSync36(dir)) return [];
|
|
23935
|
+
try {
|
|
23936
|
+
return readdirSync24(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
23937
|
+
} catch {
|
|
23938
|
+
return [];
|
|
23939
|
+
}
|
|
23940
|
+
}
|
|
23941
|
+
app48.get("/", requireAdminSession, async (c) => {
|
|
23942
|
+
const acct = accountDirForSession(c.var.cacheKey);
|
|
23943
|
+
if (!acct) {
|
|
23944
|
+
console.error('[admin:skills] op=list auth-rejected reason="no account for session"');
|
|
23945
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
23946
|
+
}
|
|
23947
|
+
const pluginsDir = resolve31(acct.accountDir, "plugins");
|
|
23948
|
+
const skills = [];
|
|
23949
|
+
let pluginCount = 0;
|
|
23950
|
+
for (const plugin of subdirs(pluginsDir)) {
|
|
23951
|
+
pluginCount++;
|
|
23952
|
+
const skillsDir = resolve31(pluginsDir, plugin, "skills");
|
|
23953
|
+
for (const skill of subdirs(skillsDir)) {
|
|
23954
|
+
const skillMd = resolve31(skillsDir, skill, "SKILL.md");
|
|
23955
|
+
if (!existsSync36(skillMd)) continue;
|
|
23956
|
+
try {
|
|
23957
|
+
const { frontmatter } = splitSkillMd(readFileSync39(skillMd, "utf-8"));
|
|
23958
|
+
const refsDir = resolve31(skillsDir, skill, "references");
|
|
23959
|
+
const refCount = existsSync36(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
|
|
23960
|
+
skills.push({ plugin, skill, description: frontmatter.description, refCount });
|
|
23961
|
+
} catch (err) {
|
|
23962
|
+
console.error(`[admin:skills] op=list-skip plugin=${plugin} skill=${skill} reason="${err instanceof Error ? err.message : String(err)}"`);
|
|
23963
|
+
}
|
|
23964
|
+
}
|
|
23965
|
+
}
|
|
23966
|
+
skills.sort((a, b) => a.plugin.localeCompare(b.plugin) || a.skill.localeCompare(b.skill));
|
|
23967
|
+
console.log(`[admin:skills] op=list accountId=${acct.accountId.slice(0, 8)} plugins=${pluginCount} skills=${skills.length}`);
|
|
23968
|
+
return c.json({ skills });
|
|
23969
|
+
});
|
|
23970
|
+
app48.get("/:plugin/:skill", requireAdminSession, async (c) => {
|
|
23971
|
+
const acct = accountDirForSession(c.var.cacheKey);
|
|
23972
|
+
if (!acct) return c.json({ error: "Account not found for session" }, 401);
|
|
23973
|
+
const plugin = c.req.param("plugin");
|
|
23974
|
+
const skill = c.req.param("skill");
|
|
23975
|
+
if (!NAME_RE.test(plugin) || !NAME_RE.test(skill)) {
|
|
23976
|
+
console.error(`[admin:skills] op=get outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
|
|
23977
|
+
return c.json({ error: "Invalid plugin or skill name" }, 400);
|
|
23978
|
+
}
|
|
23979
|
+
const skillDir = resolve31(acct.accountDir, "plugins", plugin, "skills", skill);
|
|
23980
|
+
const skillMd = resolve31(skillDir, "SKILL.md");
|
|
23981
|
+
const found = existsSync36(skillMd);
|
|
23982
|
+
console.log(`[admin:skills] op=get plugin=${plugin} skill=${skill} found=${found}`);
|
|
23983
|
+
if (!found) return c.json({ error: "Skill not found" }, 404);
|
|
23984
|
+
try {
|
|
23985
|
+
const { frontmatter, body } = splitSkillMd(readFileSync39(skillMd, "utf-8"));
|
|
23986
|
+
const refsDir = resolve31(skillDir, "references");
|
|
23987
|
+
const references = existsSync36(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
|
|
23988
|
+
return c.json({ skill: { plugin, skill, frontmatter, body, references } });
|
|
23989
|
+
} catch (err) {
|
|
23990
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23991
|
+
console.error(`[admin:skills] op=get-fail plugin=${plugin} skill=${skill} err="${message}"`);
|
|
23992
|
+
return c.json({ error: `Skill unavailable: ${message}` }, 503);
|
|
23993
|
+
}
|
|
23994
|
+
});
|
|
23995
|
+
app48.delete("/:plugin/:skill", requireAdminSession, async (c) => {
|
|
23996
|
+
const acct = accountDirForSession(c.var.cacheKey);
|
|
23997
|
+
if (!acct) return c.json({ error: "Account not found for session" }, 401);
|
|
23998
|
+
const plugin = c.req.param("plugin");
|
|
23999
|
+
const skill = c.req.param("skill");
|
|
24000
|
+
if (!NAME_RE.test(plugin) || !NAME_RE.test(skill)) {
|
|
24001
|
+
console.error(`[admin:skills] op=delete outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
|
|
24002
|
+
return c.json({ error: "Invalid plugin or skill name" }, 400);
|
|
24003
|
+
}
|
|
24004
|
+
const pluginDir = resolve31(acct.accountDir, "plugins", plugin);
|
|
24005
|
+
const skillsDir = resolve31(pluginDir, "skills");
|
|
24006
|
+
const skillDir = resolve31(skillsDir, skill);
|
|
24007
|
+
if (!existsSync36(resolve31(skillDir, "SKILL.md"))) {
|
|
24008
|
+
console.error(`[admin:skills] op=delete outcome=rejected reason=not-found plugin=${plugin} skill=${skill}`);
|
|
24009
|
+
return c.json({ error: "Skill not found" }, 404);
|
|
24010
|
+
}
|
|
24011
|
+
try {
|
|
24012
|
+
rmSync3(skillDir, { recursive: true, force: true });
|
|
24013
|
+
const pluginDirRemoved = subdirs(skillsDir).length === 0;
|
|
24014
|
+
if (pluginDirRemoved) rmSync3(pluginDir, { recursive: true, force: true });
|
|
24015
|
+
const skillDirGone = !existsSync36(skillDir);
|
|
24016
|
+
if (!skillDirGone) {
|
|
24017
|
+
console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-incomplete skillDirGone=false`);
|
|
24018
|
+
return c.json({ error: "Delete did not remove the skill directory" }, 503);
|
|
24019
|
+
}
|
|
24020
|
+
console.log(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=ok skillDirGone=${skillDirGone} pluginDirRemoved=${pluginDirRemoved}`);
|
|
24021
|
+
return c.json({ ok: true, skillDirGone, pluginDirRemoved });
|
|
24022
|
+
} catch (err) {
|
|
24023
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
24024
|
+
console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-error err="${message}"`);
|
|
24025
|
+
return c.json({ error: `Delete failed: ${message}` }, 503);
|
|
24026
|
+
}
|
|
24027
|
+
});
|
|
24028
|
+
var skills_default = app48;
|
|
24029
|
+
|
|
23715
24030
|
// app/lib/time-entry-format.ts
|
|
23716
24031
|
function secondsBetween(startIso, endIso) {
|
|
23717
24032
|
const s = Date.parse(startIso);
|
|
@@ -23733,8 +24048,8 @@ function toNum(v) {
|
|
|
23733
24048
|
var TAG39 = "[task-timer]";
|
|
23734
24049
|
var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
|
|
23735
24050
|
var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
|
|
23736
|
-
var
|
|
23737
|
-
|
|
24051
|
+
var app49 = new Hono();
|
|
24052
|
+
app49.get("/", requireAdminSession, async (c) => {
|
|
23738
24053
|
const cacheKey = c.var.cacheKey;
|
|
23739
24054
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23740
24055
|
if (!accountId) {
|
|
@@ -23821,13 +24136,13 @@ app48.get("/", requireAdminSession, async (c) => {
|
|
|
23821
24136
|
await session.close();
|
|
23822
24137
|
}
|
|
23823
24138
|
});
|
|
23824
|
-
var tasks_list_default =
|
|
24139
|
+
var tasks_list_default = app49;
|
|
23825
24140
|
|
|
23826
24141
|
// server/routes/admin/task-timer-start.ts
|
|
23827
24142
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
23828
24143
|
var TAG40 = "[task-timer]";
|
|
23829
|
-
var
|
|
23830
|
-
|
|
24144
|
+
var app50 = new Hono();
|
|
24145
|
+
app50.post("/", requireAdminSession, async (c) => {
|
|
23831
24146
|
const cacheKey = c.var.cacheKey;
|
|
23832
24147
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23833
24148
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -23882,13 +24197,13 @@ app49.post("/", requireAdminSession, async (c) => {
|
|
|
23882
24197
|
await session.close();
|
|
23883
24198
|
}
|
|
23884
24199
|
});
|
|
23885
|
-
var task_timer_start_default =
|
|
24200
|
+
var task_timer_start_default = app50;
|
|
23886
24201
|
|
|
23887
24202
|
// server/routes/admin/task-timer-stop.ts
|
|
23888
24203
|
import neo4j5 from "neo4j-driver";
|
|
23889
24204
|
var TAG41 = "[task-timer]";
|
|
23890
|
-
var
|
|
23891
|
-
|
|
24205
|
+
var app51 = new Hono();
|
|
24206
|
+
app51.post("/", requireAdminSession, async (c) => {
|
|
23892
24207
|
const cacheKey = c.var.cacheKey;
|
|
23893
24208
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23894
24209
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -23955,12 +24270,12 @@ app50.post("/", requireAdminSession, async (c) => {
|
|
|
23955
24270
|
await session.close();
|
|
23956
24271
|
}
|
|
23957
24272
|
});
|
|
23958
|
-
var task_timer_stop_default =
|
|
24273
|
+
var task_timer_stop_default = app51;
|
|
23959
24274
|
|
|
23960
24275
|
// server/routes/admin/task-complete.ts
|
|
23961
24276
|
var TAG42 = "[task-timer]";
|
|
23962
|
-
var
|
|
23963
|
-
|
|
24277
|
+
var app52 = new Hono();
|
|
24278
|
+
app52.post("/", requireAdminSession, async (c) => {
|
|
23964
24279
|
const cacheKey = c.var.cacheKey;
|
|
23965
24280
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23966
24281
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -23998,14 +24313,14 @@ app51.post("/", requireAdminSession, async (c) => {
|
|
|
23998
24313
|
await session.close();
|
|
23999
24314
|
}
|
|
24000
24315
|
});
|
|
24001
|
-
var task_complete_default =
|
|
24316
|
+
var task_complete_default = app52;
|
|
24002
24317
|
|
|
24003
24318
|
// server/routes/admin/task-time-adjust.ts
|
|
24004
24319
|
import { randomUUID as randomUUID15 } from "crypto";
|
|
24005
24320
|
import neo4j6 from "neo4j-driver";
|
|
24006
24321
|
var TAG43 = "[task-time-adjust]";
|
|
24007
|
-
var
|
|
24008
|
-
|
|
24322
|
+
var app53 = new Hono();
|
|
24323
|
+
app53.post("/", requireAdminSession, async (c) => {
|
|
24009
24324
|
const cacheKey = c.var.cacheKey;
|
|
24010
24325
|
const accountId = getAccountIdForSession(cacheKey);
|
|
24011
24326
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -24079,11 +24394,11 @@ app52.post("/", requireAdminSession, async (c) => {
|
|
|
24079
24394
|
await session.close();
|
|
24080
24395
|
}
|
|
24081
24396
|
});
|
|
24082
|
-
var task_time_adjust_default =
|
|
24397
|
+
var task_time_adjust_default = app53;
|
|
24083
24398
|
|
|
24084
24399
|
// server/routes/admin/activity.ts
|
|
24085
|
-
import { readdirSync as
|
|
24086
|
-
var
|
|
24400
|
+
import { readdirSync as readdirSync25 } from "fs";
|
|
24401
|
+
var app54 = new Hono();
|
|
24087
24402
|
var TAG44 = "[activity]";
|
|
24088
24403
|
function resolveHouseAccountId(accounts) {
|
|
24089
24404
|
const houses = accounts.filter((a) => a.config.role === "house");
|
|
@@ -24098,14 +24413,14 @@ function requestToken() {
|
|
|
24098
24413
|
var short = (id) => id ? id.slice(0, 8) : "unset";
|
|
24099
24414
|
function countAccountDirsOnDisk() {
|
|
24100
24415
|
try {
|
|
24101
|
-
return
|
|
24416
|
+
return readdirSync25(ACCOUNTS_DIR, { withFileTypes: true }).filter(
|
|
24102
24417
|
(e) => e.isDirectory() && !e.name.startsWith(".")
|
|
24103
24418
|
).length;
|
|
24104
24419
|
} catch {
|
|
24105
24420
|
return null;
|
|
24106
24421
|
}
|
|
24107
24422
|
}
|
|
24108
|
-
|
|
24423
|
+
app54.get("/", requireAdminSession, async (c) => {
|
|
24109
24424
|
const req = requestToken();
|
|
24110
24425
|
const cacheKey = c.var.cacheKey;
|
|
24111
24426
|
const caller2 = getAccountIdForSession(cacheKey) ?? null;
|
|
@@ -24214,61 +24529,62 @@ app53.get("/", requireAdminSession, async (c) => {
|
|
|
24214
24529
|
}
|
|
24215
24530
|
});
|
|
24216
24531
|
});
|
|
24217
|
-
var activity_default =
|
|
24532
|
+
var activity_default = app54;
|
|
24218
24533
|
|
|
24219
24534
|
// server/routes/admin/index.ts
|
|
24220
|
-
var
|
|
24221
|
-
|
|
24222
|
-
|
|
24223
|
-
|
|
24224
|
-
|
|
24225
|
-
|
|
24226
|
-
|
|
24227
|
-
|
|
24228
|
-
|
|
24229
|
-
|
|
24230
|
-
|
|
24231
|
-
|
|
24232
|
-
|
|
24233
|
-
|
|
24234
|
-
|
|
24235
|
-
|
|
24236
|
-
|
|
24237
|
-
|
|
24238
|
-
|
|
24239
|
-
|
|
24240
|
-
|
|
24241
|
-
|
|
24242
|
-
|
|
24243
|
-
|
|
24244
|
-
|
|
24245
|
-
|
|
24246
|
-
|
|
24247
|
-
|
|
24248
|
-
|
|
24249
|
-
|
|
24250
|
-
|
|
24251
|
-
|
|
24252
|
-
|
|
24253
|
-
|
|
24254
|
-
|
|
24255
|
-
|
|
24256
|
-
|
|
24257
|
-
|
|
24258
|
-
|
|
24259
|
-
|
|
24260
|
-
|
|
24261
|
-
|
|
24262
|
-
|
|
24263
|
-
|
|
24264
|
-
|
|
24535
|
+
var app55 = new Hono();
|
|
24536
|
+
app55.route("/session", session_default);
|
|
24537
|
+
app55.route("/accounts", accounts_default);
|
|
24538
|
+
app55.route("/logs", logs_default);
|
|
24539
|
+
app55.route("/claude-info", claude_info_default);
|
|
24540
|
+
app55.route("/attachment", attachment_default);
|
|
24541
|
+
app55.route("/agents", agents_default);
|
|
24542
|
+
app55.route("/sessions", sessions_default);
|
|
24543
|
+
app55.route("/claude-sessions", claude_sessions_default);
|
|
24544
|
+
app55.route("/log-ingest", log_ingest_default);
|
|
24545
|
+
app55.route("/events", events_default);
|
|
24546
|
+
app55.route("/files", files_default);
|
|
24547
|
+
app55.route("/graph-search", graph_search_default);
|
|
24548
|
+
app55.route("/graph-subgraph", graph_subgraph_default);
|
|
24549
|
+
app55.route("/graph-delete", graph_delete_default);
|
|
24550
|
+
app55.route("/graph-restore", graph_restore_default);
|
|
24551
|
+
app55.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
24552
|
+
app55.route("/graph-default-view", graph_default_view_default);
|
|
24553
|
+
app55.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
24554
|
+
app55.route("/sidebar-sessions", sidebar_sessions_default);
|
|
24555
|
+
app55.route("/session-delete", session_delete_default);
|
|
24556
|
+
app55.route("/session-stop", session_stop_default);
|
|
24557
|
+
app55.route("/session-archive", session_archive_default);
|
|
24558
|
+
app55.route("/session-rename", session_rename_default);
|
|
24559
|
+
app55.route("/session-usage", session_usage_default);
|
|
24560
|
+
app55.route("/browser", browser_default);
|
|
24561
|
+
app55.route("/session-rc-spawn", session_rc_spawn_default);
|
|
24562
|
+
app55.route("/session-reseat", session_reseat_default);
|
|
24563
|
+
app55.route("/system-stats", system_stats_default);
|
|
24564
|
+
app55.route("/health-brand", health_default2);
|
|
24565
|
+
app55.route("/linkedin-ingest", linkedin_ingest_default);
|
|
24566
|
+
app55.route("/post-turn-context", post_turn_context_default);
|
|
24567
|
+
app55.route("/public-session-context", public_session_context_default);
|
|
24568
|
+
app55.route("/public-session-exit", public_session_exit_default);
|
|
24569
|
+
app55.route("/access-session-evict", access_session_evict_default);
|
|
24570
|
+
app55.route("/enrol-person", enrol_person_default);
|
|
24571
|
+
app55.route("/calendar", calendar_default);
|
|
24572
|
+
app55.route("/routines", routines_default);
|
|
24573
|
+
app55.route("/skills", skills_default);
|
|
24574
|
+
app55.route("/tasks-list", tasks_list_default);
|
|
24575
|
+
app55.route("/task-timer-start", task_timer_start_default);
|
|
24576
|
+
app55.route("/task-timer-stop", task_timer_stop_default);
|
|
24577
|
+
app55.route("/task-complete", task_complete_default);
|
|
24578
|
+
app55.route("/task-time-adjust", task_time_adjust_default);
|
|
24579
|
+
app55.route("/activity", activity_default);
|
|
24580
|
+
var admin_default = app55;
|
|
24265
24581
|
|
|
24266
24582
|
// server/routes/access/verify-token.ts
|
|
24267
24583
|
var TAG45 = "[access-verify]";
|
|
24268
24584
|
var MINT_TAG = "[access-session-mint]";
|
|
24269
24585
|
var COOKIE_NAME = "__access_session";
|
|
24270
|
-
var
|
|
24271
|
-
|
|
24586
|
+
var app56 = new Hono();
|
|
24587
|
+
app56.post("/", async (c) => {
|
|
24272
24588
|
const ip = c.var.clientIp || "unknown";
|
|
24273
24589
|
let body;
|
|
24274
24590
|
try {
|
|
@@ -24350,13 +24666,13 @@ app55.post("/", async (c) => {
|
|
|
24350
24666
|
displayName: grant.displayName
|
|
24351
24667
|
});
|
|
24352
24668
|
});
|
|
24353
|
-
var verify_token_default =
|
|
24669
|
+
var verify_token_default = app56;
|
|
24354
24670
|
|
|
24355
24671
|
// app/lib/access-email.ts
|
|
24356
24672
|
import { spawn as spawn2 } from "child_process";
|
|
24357
|
-
import { resolve as
|
|
24358
|
-
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ??
|
|
24359
|
-
var SEND_SCRIPT =
|
|
24673
|
+
import { resolve as resolve32 } from "path";
|
|
24674
|
+
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve32(process.cwd(), "..");
|
|
24675
|
+
var SEND_SCRIPT = resolve32(
|
|
24360
24676
|
PLATFORM_ROOT7,
|
|
24361
24677
|
"plugins",
|
|
24362
24678
|
"email",
|
|
@@ -24413,9 +24729,9 @@ async function sendMagicLinkEmail(payload) {
|
|
|
24413
24729
|
|
|
24414
24730
|
// server/routes/access/request-magic-link.ts
|
|
24415
24731
|
var TAG46 = "[access-request-link]";
|
|
24416
|
-
var
|
|
24732
|
+
var app57 = new Hono();
|
|
24417
24733
|
var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
|
|
24418
|
-
|
|
24734
|
+
app57.post("/", async (c) => {
|
|
24419
24735
|
let body;
|
|
24420
24736
|
try {
|
|
24421
24737
|
body = await c.req.json();
|
|
@@ -24489,17 +24805,17 @@ app56.post("/", async (c) => {
|
|
|
24489
24805
|
);
|
|
24490
24806
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
24491
24807
|
});
|
|
24492
|
-
var request_magic_link_default =
|
|
24808
|
+
var request_magic_link_default = app57;
|
|
24493
24809
|
|
|
24494
24810
|
// server/routes/access/index.ts
|
|
24495
|
-
var
|
|
24496
|
-
|
|
24497
|
-
|
|
24498
|
-
var access_default =
|
|
24811
|
+
var app58 = new Hono();
|
|
24812
|
+
app58.route("/verify-token", verify_token_default);
|
|
24813
|
+
app58.route("/request-magic-link", request_magic_link_default);
|
|
24814
|
+
var access_default = app58;
|
|
24499
24815
|
|
|
24500
24816
|
// server/routes/sites.ts
|
|
24501
|
-
import { existsSync as
|
|
24502
|
-
import { resolve as
|
|
24817
|
+
import { existsSync as existsSync37, readFileSync as readFileSync40, realpathSync as realpathSync7, statSync as statSync15 } from "fs";
|
|
24818
|
+
import { resolve as resolve33 } from "path";
|
|
24503
24819
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
24504
24820
|
var MIME = {
|
|
24505
24821
|
".html": "text/html; charset=utf-8",
|
|
@@ -24530,8 +24846,8 @@ function getExt(p) {
|
|
|
24530
24846
|
if (idx < p.lastIndexOf("/")) return "";
|
|
24531
24847
|
return p.slice(idx).toLowerCase();
|
|
24532
24848
|
}
|
|
24533
|
-
var
|
|
24534
|
-
|
|
24849
|
+
var app59 = new Hono();
|
|
24850
|
+
app59.get("/:rel{.*}", (c) => {
|
|
24535
24851
|
const reqPath = c.req.path;
|
|
24536
24852
|
const rawRel = c.req.param("rel") ?? "";
|
|
24537
24853
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -24556,15 +24872,15 @@ app58.get("/:rel{.*}", (c) => {
|
|
|
24556
24872
|
}
|
|
24557
24873
|
segments.push(seg);
|
|
24558
24874
|
}
|
|
24559
|
-
const rootDir =
|
|
24560
|
-
let filePath = segments.length === 0 ? rootDir :
|
|
24875
|
+
const rootDir = resolve33(account.accountDir, "sites");
|
|
24876
|
+
let filePath = segments.length === 0 ? rootDir : resolve33(rootDir, ...segments);
|
|
24561
24877
|
if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
|
|
24562
24878
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
24563
24879
|
return c.text("Forbidden", 403);
|
|
24564
24880
|
}
|
|
24565
24881
|
let stat11;
|
|
24566
24882
|
try {
|
|
24567
|
-
stat11 =
|
|
24883
|
+
stat11 = existsSync37(filePath) ? statSync15(filePath) : null;
|
|
24568
24884
|
} catch {
|
|
24569
24885
|
stat11 = null;
|
|
24570
24886
|
}
|
|
@@ -24577,13 +24893,13 @@ app58.get("/:rel{.*}", (c) => {
|
|
|
24577
24893
|
return c.redirect(target, 301);
|
|
24578
24894
|
}
|
|
24579
24895
|
if (stat11?.isDirectory()) {
|
|
24580
|
-
filePath =
|
|
24896
|
+
filePath = resolve33(filePath, "index.html");
|
|
24581
24897
|
}
|
|
24582
24898
|
if (!filePath.startsWith(rootDir + "/")) {
|
|
24583
24899
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
24584
24900
|
return c.text("Forbidden", 403);
|
|
24585
24901
|
}
|
|
24586
|
-
if (!
|
|
24902
|
+
if (!existsSync37(filePath)) {
|
|
24587
24903
|
console.error(`[sites] not-found path=${reqPath} status=404`);
|
|
24588
24904
|
return c.text("Not found", 404);
|
|
24589
24905
|
}
|
|
@@ -24602,7 +24918,7 @@ app58.get("/:rel{.*}", (c) => {
|
|
|
24602
24918
|
}
|
|
24603
24919
|
let body;
|
|
24604
24920
|
try {
|
|
24605
|
-
body =
|
|
24921
|
+
body = readFileSync40(realPath);
|
|
24606
24922
|
} catch (err) {
|
|
24607
24923
|
const code = err?.code;
|
|
24608
24924
|
if (code === "EISDIR") {
|
|
@@ -24634,11 +24950,11 @@ app58.get("/:rel{.*}", (c) => {
|
|
|
24634
24950
|
"X-Content-Type-Options": "nosniff"
|
|
24635
24951
|
});
|
|
24636
24952
|
});
|
|
24637
|
-
var sites_default =
|
|
24953
|
+
var sites_default = app59;
|
|
24638
24954
|
|
|
24639
24955
|
// app/lib/visitor-token.ts
|
|
24640
24956
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
24641
|
-
import { mkdirSync as mkdirSync8, readFileSync as
|
|
24957
|
+
import { mkdirSync as mkdirSync8, readFileSync as readFileSync41, writeFileSync as writeFileSync14 } from "fs";
|
|
24642
24958
|
import { dirname as dirname13 } from "path";
|
|
24643
24959
|
var TOKEN_PREFIX = "v1.";
|
|
24644
24960
|
var SECRET_BYTES = 32;
|
|
@@ -24647,7 +24963,7 @@ var cachedSecret = null;
|
|
|
24647
24963
|
function getSecret() {
|
|
24648
24964
|
if (cachedSecret) return cachedSecret;
|
|
24649
24965
|
try {
|
|
24650
|
-
const hex2 =
|
|
24966
|
+
const hex2 = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
|
|
24651
24967
|
if (hex2.length === SECRET_BYTES * 2) {
|
|
24652
24968
|
cachedSecret = Buffer.from(hex2, "hex");
|
|
24653
24969
|
return cachedSecret;
|
|
@@ -24661,7 +24977,7 @@ function getSecret() {
|
|
|
24661
24977
|
console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
|
|
24662
24978
|
} catch {
|
|
24663
24979
|
}
|
|
24664
|
-
const hex =
|
|
24980
|
+
const hex = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
|
|
24665
24981
|
cachedSecret = Buffer.from(hex, "hex");
|
|
24666
24982
|
return cachedSecret;
|
|
24667
24983
|
}
|
|
@@ -24714,7 +25030,7 @@ var VISITOR_COOKIE_NAME = "mxy_v";
|
|
|
24714
25030
|
var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
|
|
24715
25031
|
|
|
24716
25032
|
// app/lib/brand-config.ts
|
|
24717
|
-
import { existsSync as
|
|
25033
|
+
import { existsSync as existsSync38, readFileSync as readFileSync42 } from "fs";
|
|
24718
25034
|
import { join as join43 } from "path";
|
|
24719
25035
|
var cached2 = null;
|
|
24720
25036
|
var cachedAttempted = false;
|
|
@@ -24724,9 +25040,9 @@ function readBrandConfig() {
|
|
|
24724
25040
|
const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
|
|
24725
25041
|
if (!platformRoot5) return null;
|
|
24726
25042
|
const brandPath = join43(platformRoot5, "config", "brand.json");
|
|
24727
|
-
if (!
|
|
25043
|
+
if (!existsSync38(brandPath)) return null;
|
|
24728
25044
|
try {
|
|
24729
|
-
cached2 = JSON.parse(
|
|
25045
|
+
cached2 = JSON.parse(readFileSync42(brandPath, "utf-8"));
|
|
24730
25046
|
return cached2;
|
|
24731
25047
|
} catch {
|
|
24732
25048
|
return null;
|
|
@@ -24734,7 +25050,7 @@ function readBrandConfig() {
|
|
|
24734
25050
|
}
|
|
24735
25051
|
|
|
24736
25052
|
// server/routes/visitor-consent.ts
|
|
24737
|
-
var
|
|
25053
|
+
var app60 = new Hono();
|
|
24738
25054
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
24739
25055
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
24740
25056
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -24779,17 +25095,17 @@ function siteSlugFromReferer(referer) {
|
|
|
24779
25095
|
return "";
|
|
24780
25096
|
}
|
|
24781
25097
|
}
|
|
24782
|
-
|
|
25098
|
+
app60.options("/consent", (c) => {
|
|
24783
25099
|
const origin = getOrigin(c);
|
|
24784
25100
|
setCorsHeaders(c, origin);
|
|
24785
25101
|
return c.body(null, 204);
|
|
24786
25102
|
});
|
|
24787
|
-
|
|
25103
|
+
app60.options("/brand-config", (c) => {
|
|
24788
25104
|
const origin = getOrigin(c);
|
|
24789
25105
|
setCorsHeaders(c, origin);
|
|
24790
25106
|
return c.body(null, 204);
|
|
24791
25107
|
});
|
|
24792
|
-
|
|
25108
|
+
app60.post("/consent", async (c) => {
|
|
24793
25109
|
const origin = getOrigin(c);
|
|
24794
25110
|
setCorsHeaders(c, origin);
|
|
24795
25111
|
let raw;
|
|
@@ -24829,7 +25145,7 @@ app59.post("/consent", async (c) => {
|
|
|
24829
25145
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
24830
25146
|
return c.body(null, 204);
|
|
24831
25147
|
});
|
|
24832
|
-
|
|
25148
|
+
app60.get("/brand-config", (c) => {
|
|
24833
25149
|
const origin = getOrigin(c);
|
|
24834
25150
|
setCorsHeaders(c, origin);
|
|
24835
25151
|
const brand = readBrandConfig();
|
|
@@ -24839,7 +25155,7 @@ app59.get("/brand-config", (c) => {
|
|
|
24839
25155
|
c.header("Cache-Control", "public, max-age=300");
|
|
24840
25156
|
return c.json({ consent: { copy, palette } });
|
|
24841
25157
|
});
|
|
24842
|
-
var visitor_consent_default =
|
|
25158
|
+
var visitor_consent_default = app60;
|
|
24843
25159
|
|
|
24844
25160
|
// server/routes/listings.ts
|
|
24845
25161
|
function getCookie(headerValue, name) {
|
|
@@ -24866,8 +25182,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
24866
25182
|
}
|
|
24867
25183
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
24868
25184
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
24869
|
-
var
|
|
24870
|
-
|
|
25185
|
+
var app61 = new Hono();
|
|
25186
|
+
app61.get("/:slug/click", async (c) => {
|
|
24871
25187
|
const slug = c.req.param("slug") ?? "";
|
|
24872
25188
|
const rawSession = c.req.query("session") ?? "";
|
|
24873
25189
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -24931,10 +25247,10 @@ app60.get("/:slug/click", async (c) => {
|
|
|
24931
25247
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
24932
25248
|
return c.redirect(redirectUrl, 302);
|
|
24933
25249
|
});
|
|
24934
|
-
var listings_default =
|
|
25250
|
+
var listings_default = app61;
|
|
24935
25251
|
|
|
24936
25252
|
// server/routes/visitor-event.ts
|
|
24937
|
-
var
|
|
25253
|
+
var app62 = new Hono();
|
|
24938
25254
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
24939
25255
|
var buckets = /* @__PURE__ */ new Map();
|
|
24940
25256
|
var RATE_LIMIT = 60;
|
|
@@ -25010,12 +25326,12 @@ function originAllowed(origin, allowlist) {
|
|
|
25010
25326
|
return false;
|
|
25011
25327
|
}
|
|
25012
25328
|
}
|
|
25013
|
-
|
|
25329
|
+
app62.options("/event", (c) => {
|
|
25014
25330
|
const origin = getOrigin2(c);
|
|
25015
25331
|
setCorsHeaders2(c, origin);
|
|
25016
25332
|
return c.body(null, 204);
|
|
25017
25333
|
});
|
|
25018
|
-
|
|
25334
|
+
app62.post("/event", async (c) => {
|
|
25019
25335
|
const origin = getOrigin2(c);
|
|
25020
25336
|
setCorsHeaders2(c, origin);
|
|
25021
25337
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -25220,17 +25536,17 @@ async function writeEvent(opts) {
|
|
|
25220
25536
|
);
|
|
25221
25537
|
}
|
|
25222
25538
|
}
|
|
25223
|
-
var visitor_event_default =
|
|
25539
|
+
var visitor_event_default = app62;
|
|
25224
25540
|
|
|
25225
25541
|
// server/routes/session.ts
|
|
25226
|
-
import { resolve as
|
|
25227
|
-
import { existsSync as
|
|
25542
|
+
import { resolve as resolve34 } from "path";
|
|
25543
|
+
import { existsSync as existsSync39, writeFileSync as writeFileSync15, mkdirSync as mkdirSync9 } from "fs";
|
|
25228
25544
|
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
25229
25545
|
function writeBrandingCache(accountId, agentSlug, branding) {
|
|
25230
25546
|
try {
|
|
25231
|
-
const cacheDir =
|
|
25547
|
+
const cacheDir = resolve34(MAXY_DIR, "branding-cache", accountId);
|
|
25232
25548
|
mkdirSync9(cacheDir, { recursive: true });
|
|
25233
|
-
writeFileSync15(
|
|
25549
|
+
writeFileSync15(resolve34(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
|
|
25234
25550
|
} catch (err) {
|
|
25235
25551
|
console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
25236
25552
|
}
|
|
@@ -25266,8 +25582,8 @@ function withVisitorCookie(response, visitorId) {
|
|
|
25266
25582
|
headers
|
|
25267
25583
|
});
|
|
25268
25584
|
}
|
|
25269
|
-
var
|
|
25270
|
-
|
|
25585
|
+
var app63 = new Hono();
|
|
25586
|
+
app63.post("/", async (c) => {
|
|
25271
25587
|
let body;
|
|
25272
25588
|
try {
|
|
25273
25589
|
body = await c.req.json();
|
|
@@ -25307,8 +25623,8 @@ app62.post("/", async (c) => {
|
|
|
25307
25623
|
}
|
|
25308
25624
|
let agentConfig = null;
|
|
25309
25625
|
if (account) {
|
|
25310
|
-
const agentDir =
|
|
25311
|
-
if (!
|
|
25626
|
+
const agentDir = resolve34(account.accountDir, "agents", agentSlug);
|
|
25627
|
+
if (!existsSync39(agentDir) || !existsSync39(resolve34(agentDir, "config.json"))) {
|
|
25312
25628
|
return c.json({ error: "Agent not found" }, 404);
|
|
25313
25629
|
}
|
|
25314
25630
|
agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
|
|
@@ -25414,7 +25730,7 @@ app62.post("/", async (c) => {
|
|
|
25414
25730
|
newVisitorId
|
|
25415
25731
|
);
|
|
25416
25732
|
});
|
|
25417
|
-
var session_default2 =
|
|
25733
|
+
var session_default2 = app63;
|
|
25418
25734
|
|
|
25419
25735
|
// server/lib/calendar-slots.ts
|
|
25420
25736
|
var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
@@ -25497,17 +25813,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
|
|
|
25497
25813
|
}
|
|
25498
25814
|
|
|
25499
25815
|
// server/routes/calendar-public.ts
|
|
25500
|
-
var
|
|
25816
|
+
var app64 = new Hono();
|
|
25501
25817
|
function setCors(c) {
|
|
25502
25818
|
c.header("Access-Control-Allow-Origin", "*");
|
|
25503
25819
|
c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
25504
25820
|
c.header("Access-Control-Allow-Headers", "content-type");
|
|
25505
25821
|
}
|
|
25506
|
-
|
|
25822
|
+
app64.options("/free-busy", (c) => {
|
|
25507
25823
|
setCors(c);
|
|
25508
25824
|
return c.body(null, 204);
|
|
25509
25825
|
});
|
|
25510
|
-
|
|
25826
|
+
app64.get("/free-busy", async (c) => {
|
|
25511
25827
|
setCors(c);
|
|
25512
25828
|
const from = c.req.query("from");
|
|
25513
25829
|
const to = c.req.query("to");
|
|
@@ -25563,14 +25879,14 @@ app63.get("/free-busy", async (c) => {
|
|
|
25563
25879
|
await session.close();
|
|
25564
25880
|
}
|
|
25565
25881
|
});
|
|
25566
|
-
var calendar_public_default =
|
|
25882
|
+
var calendar_public_default = app64;
|
|
25567
25883
|
|
|
25568
25884
|
// server/routes/portal-fetch.ts
|
|
25569
25885
|
import { createReadStream as createReadStream3 } from "fs";
|
|
25570
25886
|
import { stat as stat8, readFile as readFile8, realpath } from "fs/promises";
|
|
25571
|
-
import { join as join44, resolve as
|
|
25887
|
+
import { join as join44, resolve as resolve35, sep as sep9 } from "path";
|
|
25572
25888
|
import { Readable as Readable3 } from "stream";
|
|
25573
|
-
var
|
|
25889
|
+
var app65 = new Hono();
|
|
25574
25890
|
var TAG47 = "[portal-fetch]";
|
|
25575
25891
|
async function verifySignature(secret, accountId, relPath, expiresAtMs, signature, nowMs) {
|
|
25576
25892
|
if (!secret || !signature) return false;
|
|
@@ -25621,7 +25937,7 @@ ${expiresAtMs}`)
|
|
|
25621
25937
|
return diff === 0;
|
|
25622
25938
|
}
|
|
25623
25939
|
async function readAccountSecret(accountId) {
|
|
25624
|
-
const path3 =
|
|
25940
|
+
const path3 = resolve35(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
|
|
25625
25941
|
let text;
|
|
25626
25942
|
try {
|
|
25627
25943
|
text = await readFile8(path3, "utf8");
|
|
@@ -25657,7 +25973,7 @@ async function resolveFetchTarget(accountDir, relPath, ownerId) {
|
|
|
25657
25973
|
const exposeFolders = await readExposeFolders2(accountDir);
|
|
25658
25974
|
const { exposed } = resolveExposedDirs(schemaText, exposeFolders);
|
|
25659
25975
|
if (exposed.length === 0 && !ownerId) return { ok: false, reason: "not-exposed" };
|
|
25660
|
-
const lexical =
|
|
25976
|
+
const lexical = resolve35(accountDir, relPath);
|
|
25661
25977
|
let root;
|
|
25662
25978
|
let absolute;
|
|
25663
25979
|
try {
|
|
@@ -25706,7 +26022,7 @@ async function handle(c, headOnly) {
|
|
|
25706
26022
|
return c.json({ ok: false, error: "denied" }, 401);
|
|
25707
26023
|
}
|
|
25708
26024
|
const target = await resolveFetchTarget(
|
|
25709
|
-
|
|
26025
|
+
resolve35(DATA_ROOT, "accounts", accountId),
|
|
25710
26026
|
relPath,
|
|
25711
26027
|
owner || void 0
|
|
25712
26028
|
);
|
|
@@ -25733,9 +26049,9 @@ async function handle(c, headOnly) {
|
|
|
25733
26049
|
}
|
|
25734
26050
|
});
|
|
25735
26051
|
}
|
|
25736
|
-
|
|
25737
|
-
|
|
25738
|
-
var portal_fetch_default =
|
|
26052
|
+
app65.get("/fetch", (c) => handle(c, false));
|
|
26053
|
+
app65.on("HEAD", "/fetch", (c) => handle(c, true));
|
|
26054
|
+
var portal_fetch_default = app65;
|
|
25739
26055
|
|
|
25740
26056
|
// app/lib/timeentry-census.ts
|
|
25741
26057
|
var TAG48 = "[timeentry-census]";
|
|
@@ -25820,7 +26136,7 @@ function startTimeEntryCensus(openSession, opts = {}) {
|
|
|
25820
26136
|
}
|
|
25821
26137
|
|
|
25822
26138
|
// app/lib/ledger-census.ts
|
|
25823
|
-
import { readdirSync as
|
|
26139
|
+
import { readdirSync as readdirSync26, readFileSync as readFileSync43, statSync as statSync16 } from "fs";
|
|
25824
26140
|
import { join as join45 } from "path";
|
|
25825
26141
|
|
|
25826
26142
|
// ../lib/ledger-core/dist/reconcile.js
|
|
@@ -25869,7 +26185,7 @@ var DAY_MS = 864e5;
|
|
|
25869
26185
|
function countWriteRejects24h(logDir, now) {
|
|
25870
26186
|
let entries;
|
|
25871
26187
|
try {
|
|
25872
|
-
entries =
|
|
26188
|
+
entries = readdirSync26(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
|
|
25873
26189
|
} catch {
|
|
25874
26190
|
return 0;
|
|
25875
26191
|
}
|
|
@@ -25877,8 +26193,8 @@ function countWriteRejects24h(logDir, now) {
|
|
|
25877
26193
|
for (const name of entries) {
|
|
25878
26194
|
const path3 = join45(logDir, name);
|
|
25879
26195
|
try {
|
|
25880
|
-
if (now -
|
|
25881
|
-
for (const line of
|
|
26196
|
+
if (now - statSync16(path3).mtimeMs > DAY_MS) continue;
|
|
26197
|
+
for (const line of readFileSync43(path3, "utf8").split("\n")) {
|
|
25882
26198
|
if (line.includes("[graph-write] reject")) total += 1;
|
|
25883
26199
|
}
|
|
25884
26200
|
} catch {
|
|
@@ -26147,7 +26463,7 @@ function startGraphHealthTimer() {
|
|
|
26147
26463
|
|
|
26148
26464
|
// app/lib/file-watcher.ts
|
|
26149
26465
|
import * as fsp2 from "fs/promises";
|
|
26150
|
-
import { resolve as
|
|
26466
|
+
import { resolve as resolve36, sep as sep10 } from "path";
|
|
26151
26467
|
var ACCOUNT_UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
26152
26468
|
var DEFAULT_COALESCE_MS = 500;
|
|
26153
26469
|
var ROOTS = ["accounts"];
|
|
@@ -26166,7 +26482,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
26166
26482
|
const dropFn = opts.drop ?? dropFileIndex;
|
|
26167
26483
|
for (const r of ROOTS) {
|
|
26168
26484
|
try {
|
|
26169
|
-
await fsp2.mkdir(
|
|
26485
|
+
await fsp2.mkdir(resolve36(dataRoot, r), { recursive: true });
|
|
26170
26486
|
} catch (err) {
|
|
26171
26487
|
console.error(
|
|
26172
26488
|
`[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
|
|
@@ -26187,7 +26503,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
26187
26503
|
timers.set(relativePath, t);
|
|
26188
26504
|
}
|
|
26189
26505
|
async function runHook(relativePath, accountId) {
|
|
26190
|
-
const absolute =
|
|
26506
|
+
const absolute = resolve36(dataRoot, relativePath);
|
|
26191
26507
|
let exists = false;
|
|
26192
26508
|
try {
|
|
26193
26509
|
const st = await fsp2.stat(absolute);
|
|
@@ -26211,7 +26527,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
26211
26527
|
}
|
|
26212
26528
|
}
|
|
26213
26529
|
async function watchRoot(rootName) {
|
|
26214
|
-
const absRoot =
|
|
26530
|
+
const absRoot = resolve36(dataRoot, rootName);
|
|
26215
26531
|
try {
|
|
26216
26532
|
const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
|
|
26217
26533
|
for await (const event of iter) {
|
|
@@ -26250,7 +26566,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
26250
26566
|
|
|
26251
26567
|
// app/lib/migrate-uploads.ts
|
|
26252
26568
|
import { mkdir as mkdir6, readdir as readdir6, rename as rename3, rm as rm3 } from "fs/promises";
|
|
26253
|
-
import { dirname as dirname14, relative as relative7, resolve as
|
|
26569
|
+
import { dirname as dirname14, relative as relative7, resolve as resolve37 } from "path";
|
|
26254
26570
|
var ACCOUNT_UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
26255
26571
|
async function walkFiles(dir) {
|
|
26256
26572
|
const out = [];
|
|
@@ -26261,7 +26577,7 @@ async function walkFiles(dir) {
|
|
|
26261
26577
|
return out;
|
|
26262
26578
|
}
|
|
26263
26579
|
for (const e of entries) {
|
|
26264
|
-
const abs =
|
|
26580
|
+
const abs = resolve37(dir, e.name);
|
|
26265
26581
|
if (e.isDirectory()) {
|
|
26266
26582
|
out.push(...await walkFiles(abs));
|
|
26267
26583
|
} else if (e.isFile()) {
|
|
@@ -26281,7 +26597,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
|
|
|
26281
26597
|
let moved = 0;
|
|
26282
26598
|
for (const oldAbs of files) {
|
|
26283
26599
|
const suffix = relative7(srcDir, oldAbs);
|
|
26284
|
-
const newAbs =
|
|
26600
|
+
const newAbs = resolve37(destDir, suffix);
|
|
26285
26601
|
await mkdir6(dirname14(newAbs), { recursive: true });
|
|
26286
26602
|
await rename3(oldAbs, newAbs);
|
|
26287
26603
|
moved++;
|
|
@@ -26308,7 +26624,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
|
|
|
26308
26624
|
}
|
|
26309
26625
|
async function migrateUploads(opts = {}) {
|
|
26310
26626
|
const dataRoot = opts.dataRoot ?? DATA_ROOT;
|
|
26311
|
-
const oldRoot =
|
|
26627
|
+
const oldRoot = resolve37(dataRoot, "uploads");
|
|
26312
26628
|
let topEntries;
|
|
26313
26629
|
try {
|
|
26314
26630
|
topEntries = await readdir6(oldRoot, { withFileTypes: true });
|
|
@@ -26329,8 +26645,8 @@ async function migrateUploads(opts = {}) {
|
|
|
26329
26645
|
const name = entry.name;
|
|
26330
26646
|
if (ACCOUNT_UUID_RE5.test(name)) {
|
|
26331
26647
|
moved += await relocateTree(
|
|
26332
|
-
|
|
26333
|
-
|
|
26648
|
+
resolve37(oldRoot, name),
|
|
26649
|
+
resolve37(dataRoot, "accounts", name, "uploads"),
|
|
26334
26650
|
dataRoot,
|
|
26335
26651
|
name,
|
|
26336
26652
|
session
|
|
@@ -26342,8 +26658,8 @@ async function migrateUploads(opts = {}) {
|
|
|
26342
26658
|
continue;
|
|
26343
26659
|
}
|
|
26344
26660
|
moved += await relocateTree(
|
|
26345
|
-
|
|
26346
|
-
|
|
26661
|
+
resolve37(oldRoot, "public"),
|
|
26662
|
+
resolve37(dataRoot, "accounts", installAccountId, "uploads", "public"),
|
|
26347
26663
|
dataRoot,
|
|
26348
26664
|
null,
|
|
26349
26665
|
// public uploads carry no graph nodes
|
|
@@ -26373,7 +26689,7 @@ async function migrateUploads(opts = {}) {
|
|
|
26373
26689
|
|
|
26374
26690
|
// app/lib/migrate-admin-webchat-sidecars.ts
|
|
26375
26691
|
import { readdir as readdir7, readFile as readFile9, rename as rename4, writeFile as writeFile5, unlink as unlink4 } from "fs/promises";
|
|
26376
|
-
import { existsSync as
|
|
26692
|
+
import { existsSync as existsSync40 } from "fs";
|
|
26377
26693
|
import { join as join46 } from "path";
|
|
26378
26694
|
var ADMIN_ROLE2 = "admin";
|
|
26379
26695
|
var WEBCHAT_CHANNEL2 = "webchat";
|
|
@@ -26403,7 +26719,7 @@ async function writeRaw(path3, obj) {
|
|
|
26403
26719
|
await rename4(tmp, path3);
|
|
26404
26720
|
} catch (err) {
|
|
26405
26721
|
try {
|
|
26406
|
-
if (
|
|
26722
|
+
if (existsSync40(tmp)) await unlink4(tmp);
|
|
26407
26723
|
} catch {
|
|
26408
26724
|
}
|
|
26409
26725
|
throw err;
|
|
@@ -26792,8 +27108,8 @@ var streamSSE = (c, cb, onError) => {
|
|
|
26792
27108
|
|
|
26793
27109
|
// app/lib/whatsapp/gateway/routes.ts
|
|
26794
27110
|
function createWaChannelRoutes(deps) {
|
|
26795
|
-
const
|
|
26796
|
-
|
|
27111
|
+
const app67 = new Hono();
|
|
27112
|
+
app67.get("/wa-channel/inbound", (c) => {
|
|
26797
27113
|
const senderId = c.req.query("senderId");
|
|
26798
27114
|
if (!senderId) return c.json({ error: "senderId required" }, 400);
|
|
26799
27115
|
return streamSSE(c, async (stream2) => {
|
|
@@ -26811,7 +27127,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26811
27127
|
}
|
|
26812
27128
|
});
|
|
26813
27129
|
});
|
|
26814
|
-
|
|
27130
|
+
app67.post("/wa-channel/reply", async (c) => {
|
|
26815
27131
|
const body = await c.req.json().catch(() => null);
|
|
26816
27132
|
const senderId = body?.senderId;
|
|
26817
27133
|
const text = body?.text;
|
|
@@ -26832,7 +27148,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26832
27148
|
console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
|
|
26833
27149
|
return c.json({ ok: true });
|
|
26834
27150
|
});
|
|
26835
|
-
|
|
27151
|
+
app67.post("/wa-channel/reply-document", async (c) => {
|
|
26836
27152
|
const body = await c.req.json().catch(() => null);
|
|
26837
27153
|
const senderId = body?.senderId;
|
|
26838
27154
|
const files = body?.files;
|
|
@@ -26871,7 +27187,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26871
27187
|
}
|
|
26872
27188
|
return c.json({ ok: true, results });
|
|
26873
27189
|
});
|
|
26874
|
-
|
|
27190
|
+
app67.post("/wa-channel/ready", async (c) => {
|
|
26875
27191
|
const body = await c.req.json().catch(() => null);
|
|
26876
27192
|
const senderId = body?.senderId;
|
|
26877
27193
|
if (typeof senderId !== "string") {
|
|
@@ -26880,7 +27196,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26880
27196
|
deps.onReady?.(senderId);
|
|
26881
27197
|
return c.json({ ok: true });
|
|
26882
27198
|
});
|
|
26883
|
-
|
|
27199
|
+
app67.post("/wa-channel/received", async (c) => {
|
|
26884
27200
|
const body = await c.req.json().catch(() => null);
|
|
26885
27201
|
const senderId = body?.senderId;
|
|
26886
27202
|
const waMessageId = body?.waMessageId;
|
|
@@ -26890,7 +27206,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26890
27206
|
deps.onReceived?.(senderId, waMessageId);
|
|
26891
27207
|
return c.json({ ok: true });
|
|
26892
27208
|
});
|
|
26893
|
-
|
|
27209
|
+
app67.post("/wa-channel/turn-end", async (c) => {
|
|
26894
27210
|
const body = await c.req.json().catch(() => null);
|
|
26895
27211
|
const senderId = body?.senderId;
|
|
26896
27212
|
const sessionId = body?.sessionId;
|
|
@@ -26901,7 +27217,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26901
27217
|
const interactive = body?.interactive === true;
|
|
26902
27218
|
const finalText = typeof body?.finalText === "string" ? body.finalText : "";
|
|
26903
27219
|
const sid = sessionId.slice(0, 8);
|
|
26904
|
-
const deliver = interactive && finalText.trim().length > 0;
|
|
27220
|
+
const deliver = interactive && !replied && finalText.trim().length > 0;
|
|
26905
27221
|
if (deliver) {
|
|
26906
27222
|
const bytes = Buffer.byteLength(finalText, "utf8");
|
|
26907
27223
|
try {
|
|
@@ -26923,7 +27239,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26923
27239
|
console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=none`);
|
|
26924
27240
|
return c.json({ ok: true, delivered: "none" });
|
|
26925
27241
|
});
|
|
26926
|
-
return
|
|
27242
|
+
return app67;
|
|
26927
27243
|
}
|
|
26928
27244
|
|
|
26929
27245
|
// app/lib/whatsapp/gateway/wa-gateway.ts
|
|
@@ -27338,8 +27654,8 @@ var InboundHub2 = class {
|
|
|
27338
27654
|
|
|
27339
27655
|
// app/lib/webchat/gateway/routes.ts
|
|
27340
27656
|
function createWebchatChannelRoutes(deps) {
|
|
27341
|
-
const
|
|
27342
|
-
|
|
27657
|
+
const app67 = new Hono();
|
|
27658
|
+
app67.get("/webchat-channel/inbound", (c) => {
|
|
27343
27659
|
const key = c.req.query("key");
|
|
27344
27660
|
if (!key) return c.json({ error: "key required" }, 400);
|
|
27345
27661
|
return streamSSE(c, async (stream2) => {
|
|
@@ -27357,7 +27673,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27357
27673
|
}
|
|
27358
27674
|
});
|
|
27359
27675
|
});
|
|
27360
|
-
|
|
27676
|
+
app67.post("/webchat-channel/reply", async (c) => {
|
|
27361
27677
|
const body = await c.req.json().catch(() => null);
|
|
27362
27678
|
const key = body?.key;
|
|
27363
27679
|
const text = body?.text;
|
|
@@ -27367,7 +27683,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27367
27683
|
deps.onReply?.(key, text);
|
|
27368
27684
|
return c.json({ ok: true });
|
|
27369
27685
|
});
|
|
27370
|
-
|
|
27686
|
+
app67.post("/webchat-channel/connector-auth", async (c) => {
|
|
27371
27687
|
const body = await c.req.json().catch(() => null);
|
|
27372
27688
|
const key = body?.key;
|
|
27373
27689
|
const sessionId = body?.sessionId;
|
|
@@ -27380,7 +27696,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27380
27696
|
const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
|
|
27381
27697
|
return c.json(result);
|
|
27382
27698
|
});
|
|
27383
|
-
|
|
27699
|
+
app67.post("/webchat-channel/ready", async (c) => {
|
|
27384
27700
|
const body = await c.req.json().catch(() => null);
|
|
27385
27701
|
const key = body?.key;
|
|
27386
27702
|
if (typeof key !== "string") {
|
|
@@ -27389,7 +27705,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27389
27705
|
deps.onReady?.(key);
|
|
27390
27706
|
return c.json({ ok: true });
|
|
27391
27707
|
});
|
|
27392
|
-
|
|
27708
|
+
app67.post("/webchat-channel/permission-request", async (c) => {
|
|
27393
27709
|
const body = await c.req.json().catch(() => null);
|
|
27394
27710
|
const key = body?.key;
|
|
27395
27711
|
const requestId = body?.request_id;
|
|
@@ -27403,7 +27719,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27403
27719
|
const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
|
|
27404
27720
|
return c.json(verdict);
|
|
27405
27721
|
});
|
|
27406
|
-
|
|
27722
|
+
app67.post("/webchat-channel/received", async (c) => {
|
|
27407
27723
|
const body = await c.req.json().catch(() => null);
|
|
27408
27724
|
const key = body?.key;
|
|
27409
27725
|
const messageId = body?.messageId;
|
|
@@ -27413,7 +27729,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27413
27729
|
deps.onReceived?.(key, messageId);
|
|
27414
27730
|
return c.json({ ok: true });
|
|
27415
27731
|
});
|
|
27416
|
-
|
|
27732
|
+
app67.post("/webchat-channel/turn-end", async (c) => {
|
|
27417
27733
|
const body = await c.req.json().catch(() => null);
|
|
27418
27734
|
const key = body?.key;
|
|
27419
27735
|
const sessionId = body?.sessionId;
|
|
@@ -27421,22 +27737,13 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27421
27737
|
if (typeof key !== "string" || typeof sessionId !== "string" || typeof replied !== "boolean") {
|
|
27422
27738
|
return c.json({ error: "key, sessionId and replied required" }, 400);
|
|
27423
27739
|
}
|
|
27424
|
-
const interactive = body?.interactive === true;
|
|
27425
27740
|
const finalBytes = typeof body?.finalBytes === "number" && Number.isFinite(body.finalBytes) ? body.finalBytes : 0;
|
|
27426
27741
|
const k = key.slice(0, 8);
|
|
27427
27742
|
const sid = sessionId.slice(0, 8);
|
|
27428
|
-
|
|
27429
|
-
|
|
27430
|
-
return c.json({ ok: true, delivered: "reply" });
|
|
27431
|
-
}
|
|
27432
|
-
if (interactive && finalBytes > 0) {
|
|
27433
|
-
console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=no delivered=fallback bytes=${finalBytes}`);
|
|
27434
|
-
return c.json({ ok: true, delivered: "fallback" });
|
|
27435
|
-
}
|
|
27436
|
-
console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=no delivered=none`);
|
|
27437
|
-
return c.json({ ok: true, delivered: "none" });
|
|
27743
|
+
console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=${replied ? "yes" : "no"} trailing=${finalBytes}`);
|
|
27744
|
+
return c.json({ ok: true });
|
|
27438
27745
|
});
|
|
27439
|
-
return
|
|
27746
|
+
return app67;
|
|
27440
27747
|
}
|
|
27441
27748
|
|
|
27442
27749
|
// app/lib/webchat/gateway/webchat-gateway.ts
|
|
@@ -27494,16 +27801,16 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
27494
27801
|
* The public /api/chat route awaits this to return the reply on the same SSE
|
|
27495
27802
|
* response, preserving the pre-756 POST→single-blob browser contract. */
|
|
27496
27803
|
awaitReply(key, timeoutMs) {
|
|
27497
|
-
return new Promise((
|
|
27804
|
+
return new Promise((resolve43) => {
|
|
27498
27805
|
const timer = setTimeout(() => {
|
|
27499
27806
|
this.replyAwaiters.delete(key);
|
|
27500
|
-
|
|
27807
|
+
resolve43({ timeout: true });
|
|
27501
27808
|
}, timeoutMs);
|
|
27502
27809
|
if (timer.unref) timer.unref();
|
|
27503
27810
|
this.replyAwaiters.set(key, (r) => {
|
|
27504
27811
|
clearTimeout(timer);
|
|
27505
27812
|
this.replyAwaiters.delete(key);
|
|
27506
|
-
|
|
27813
|
+
resolve43(r);
|
|
27507
27814
|
});
|
|
27508
27815
|
});
|
|
27509
27816
|
}
|
|
@@ -27514,11 +27821,11 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
27514
27821
|
* terminal dialog stays answerable). */
|
|
27515
27822
|
awaitPermissionVerdict(p, timeoutMs) {
|
|
27516
27823
|
const k = _WebchatGateway.promptKey(p.key, p.requestId);
|
|
27517
|
-
return new Promise((
|
|
27824
|
+
return new Promise((resolve43) => {
|
|
27518
27825
|
this.pendingPrompts.get(k)?.resolve({ timeout: true });
|
|
27519
27826
|
const timer = setTimeout(() => {
|
|
27520
27827
|
this.pendingPrompts.delete(k);
|
|
27521
|
-
|
|
27828
|
+
resolve43({ timeout: true });
|
|
27522
27829
|
}, timeoutMs);
|
|
27523
27830
|
if (timer.unref) timer.unref();
|
|
27524
27831
|
this.pendingPrompts.set(k, {
|
|
@@ -27527,7 +27834,7 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
27527
27834
|
resolve: (r) => {
|
|
27528
27835
|
clearTimeout(timer);
|
|
27529
27836
|
this.pendingPrompts.delete(k);
|
|
27530
|
-
|
|
27837
|
+
resolve43(r);
|
|
27531
27838
|
}
|
|
27532
27839
|
});
|
|
27533
27840
|
console.error(`[webchat:perm] op=open key=${keyDisplay(p.key)} id=${p.requestId} tool=${p.toolName}`);
|
|
@@ -28092,7 +28399,7 @@ async function fanOut(subscribers, text, onError, tag) {
|
|
|
28092
28399
|
|
|
28093
28400
|
// app/lib/webchat/file-delivery.ts
|
|
28094
28401
|
import { realpathSync as realpathSync8 } from "fs";
|
|
28095
|
-
import { resolve as
|
|
28402
|
+
import { resolve as resolve38 } from "path";
|
|
28096
28403
|
|
|
28097
28404
|
// app/lib/channel-pty-bridge/file-delivery.ts
|
|
28098
28405
|
var SEND_USER_FILE = "SendUserFile";
|
|
@@ -28193,7 +28500,7 @@ function makeWebchatSendFile(entry) {
|
|
|
28193
28500
|
console.error(`${TAG51} file-delivery reject reason=no-account sender=${entry.senderId}`);
|
|
28194
28501
|
return { ok: false, error: "no-account" };
|
|
28195
28502
|
}
|
|
28196
|
-
const accountDir =
|
|
28503
|
+
const accountDir = resolve38(platformRoot2(), "..", "data/accounts", entry.accountId);
|
|
28197
28504
|
try {
|
|
28198
28505
|
const resolved = realpathSync8(filePath);
|
|
28199
28506
|
const accountResolved = realpathSync8(accountDir);
|
|
@@ -28520,8 +28827,8 @@ var InboundHub3 = class {
|
|
|
28520
28827
|
|
|
28521
28828
|
// app/lib/telegram/gateway/routes.ts
|
|
28522
28829
|
function createTelegramChannelRoutes(deps) {
|
|
28523
|
-
const
|
|
28524
|
-
|
|
28830
|
+
const app67 = new Hono();
|
|
28831
|
+
app67.get("/tg-channel/inbound", (c) => {
|
|
28525
28832
|
const key = c.req.query("key");
|
|
28526
28833
|
if (!key) return c.json({ error: "key required" }, 400);
|
|
28527
28834
|
return streamSSE(c, async (stream2) => {
|
|
@@ -28539,7 +28846,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28539
28846
|
}
|
|
28540
28847
|
});
|
|
28541
28848
|
});
|
|
28542
|
-
|
|
28849
|
+
app67.post("/tg-channel/reply", async (c) => {
|
|
28543
28850
|
const body = await c.req.json().catch(() => null);
|
|
28544
28851
|
const key = body?.key;
|
|
28545
28852
|
const text = body?.text;
|
|
@@ -28555,7 +28862,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28555
28862
|
console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
|
|
28556
28863
|
return c.json({ ok: true });
|
|
28557
28864
|
});
|
|
28558
|
-
|
|
28865
|
+
app67.post("/tg-channel/ready", async (c) => {
|
|
28559
28866
|
const body = await c.req.json().catch(() => null);
|
|
28560
28867
|
const key = body?.key;
|
|
28561
28868
|
if (typeof key !== "string") {
|
|
@@ -28564,7 +28871,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28564
28871
|
deps.onReady?.(key);
|
|
28565
28872
|
return c.json({ ok: true });
|
|
28566
28873
|
});
|
|
28567
|
-
|
|
28874
|
+
app67.post("/tg-channel/received", async (c) => {
|
|
28568
28875
|
const body = await c.req.json().catch(() => null);
|
|
28569
28876
|
const key = body?.key;
|
|
28570
28877
|
const messageId = body?.messageId;
|
|
@@ -28574,7 +28881,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28574
28881
|
deps.onReceived?.(key, messageId);
|
|
28575
28882
|
return c.json({ ok: true });
|
|
28576
28883
|
});
|
|
28577
|
-
|
|
28884
|
+
app67.post("/tg-channel/turn-end", async (c) => {
|
|
28578
28885
|
const body = await c.req.json().catch(() => null);
|
|
28579
28886
|
const key = body?.key;
|
|
28580
28887
|
const sessionId = body?.sessionId;
|
|
@@ -28585,7 +28892,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28585
28892
|
const interactive = body?.interactive === true;
|
|
28586
28893
|
const finalText = typeof body?.finalText === "string" ? body.finalText : "";
|
|
28587
28894
|
const sid = sessionId.slice(0, 8);
|
|
28588
|
-
const deliver = interactive && finalText.trim().length > 0;
|
|
28895
|
+
const deliver = interactive && !replied && finalText.trim().length > 0;
|
|
28589
28896
|
if (deliver) {
|
|
28590
28897
|
const bytes = Buffer.byteLength(finalText, "utf8");
|
|
28591
28898
|
try {
|
|
@@ -28607,7 +28914,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28607
28914
|
console.error(`[telegram-native] op=turn-end key=${key} sessionId=${sid} replied=no delivered=none`);
|
|
28608
28915
|
return c.json({ ok: true, delivered: "none" });
|
|
28609
28916
|
});
|
|
28610
|
-
return
|
|
28917
|
+
return app67;
|
|
28611
28918
|
}
|
|
28612
28919
|
|
|
28613
28920
|
// app/lib/telegram/gateway/telegram-gateway.ts
|
|
@@ -28757,7 +29064,7 @@ function buildTelegramSpawnRequest(input) {
|
|
|
28757
29064
|
// app/lib/telegram/outbound/send-document.ts
|
|
28758
29065
|
import { realpathSync as realpathSync9 } from "fs";
|
|
28759
29066
|
import { readFile as readFile10, stat as stat10 } from "fs/promises";
|
|
28760
|
-
import { resolve as
|
|
29067
|
+
import { resolve as resolve39, basename as basename12 } from "path";
|
|
28761
29068
|
var TAG53 = "[telegram:outbound]";
|
|
28762
29069
|
var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
|
|
28763
29070
|
async function sendTelegramDocument(input) {
|
|
@@ -28768,7 +29075,7 @@ async function sendTelegramDocument(input) {
|
|
|
28768
29075
|
if (!maxyAccountId || !platformRoot5) {
|
|
28769
29076
|
return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
|
|
28770
29077
|
}
|
|
28771
|
-
const accountDir =
|
|
29078
|
+
const accountDir = resolve39(platformRoot5, "..", "data/accounts", maxyAccountId);
|
|
28772
29079
|
let accountResolved;
|
|
28773
29080
|
try {
|
|
28774
29081
|
accountResolved = realpathSync9(accountDir);
|
|
@@ -29160,14 +29467,14 @@ function warnOnChannelAdminBindingDrift() {
|
|
|
29160
29467
|
}
|
|
29161
29468
|
|
|
29162
29469
|
// server/lib/booking-site-accounts.ts
|
|
29163
|
-
import { existsSync as
|
|
29164
|
-
import { resolve as
|
|
29470
|
+
import { existsSync as existsSync41, readFileSync as readFileSync44 } from "fs";
|
|
29471
|
+
import { resolve as resolve40 } from "path";
|
|
29165
29472
|
function listBookingSiteAccounts(accounts) {
|
|
29166
29473
|
return accounts.filter((a) => {
|
|
29167
|
-
const availPath =
|
|
29168
|
-
if (!
|
|
29474
|
+
const availPath = resolve40(a.accountDir, "calendar-availability.json");
|
|
29475
|
+
if (!existsSync41(availPath)) return false;
|
|
29169
29476
|
try {
|
|
29170
|
-
const cfg = JSON.parse(
|
|
29477
|
+
const cfg = JSON.parse(readFileSync44(availPath, "utf-8"));
|
|
29171
29478
|
return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
|
|
29172
29479
|
} catch {
|
|
29173
29480
|
return false;
|
|
@@ -29205,8 +29512,8 @@ function broadcastAdminShutdown(reason) {
|
|
|
29205
29512
|
|
|
29206
29513
|
// ../lib/entitlement/src/index.ts
|
|
29207
29514
|
import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
|
|
29208
|
-
import { existsSync as
|
|
29209
|
-
import { resolve as
|
|
29515
|
+
import { existsSync as existsSync42, readFileSync as readFileSync45, statSync as statSync17 } from "fs";
|
|
29516
|
+
import { resolve as resolve41 } from "path";
|
|
29210
29517
|
|
|
29211
29518
|
// ../lib/entitlement/src/canonicalize.ts
|
|
29212
29519
|
function canonicalize(value) {
|
|
@@ -29241,7 +29548,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
|
|
|
29241
29548
|
var GRACE_DAYS = 7;
|
|
29242
29549
|
var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
|
|
29243
29550
|
function pubkeyPath(brand) {
|
|
29244
|
-
return
|
|
29551
|
+
return resolve41(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
|
|
29245
29552
|
}
|
|
29246
29553
|
var memo = null;
|
|
29247
29554
|
function memoKey(mtimeMs, account) {
|
|
@@ -29253,11 +29560,11 @@ function resolveEntitlement(brand, account) {
|
|
|
29253
29560
|
if (brand.commercialMode !== true) {
|
|
29254
29561
|
return logResolved(implicitTrust(account), null);
|
|
29255
29562
|
}
|
|
29256
|
-
const entitlementPath =
|
|
29257
|
-
if (!
|
|
29563
|
+
const entitlementPath = resolve41(brand.configDir, "entitlement.json");
|
|
29564
|
+
if (!existsSync42(entitlementPath)) {
|
|
29258
29565
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
29259
29566
|
}
|
|
29260
|
-
const stat11 =
|
|
29567
|
+
const stat11 = statSync17(entitlementPath);
|
|
29261
29568
|
const key = memoKey(stat11.mtimeMs, account);
|
|
29262
29569
|
if (memo && memo.key === key) {
|
|
29263
29570
|
return memo.result;
|
|
@@ -29269,7 +29576,7 @@ function resolveEntitlement(brand, account) {
|
|
|
29269
29576
|
function verifyAndResolve(brand, entitlementPath, account) {
|
|
29270
29577
|
let pubkeyPem;
|
|
29271
29578
|
try {
|
|
29272
|
-
pubkeyPem =
|
|
29579
|
+
pubkeyPem = readFileSync45(pubkeyPath(brand), "utf-8");
|
|
29273
29580
|
} catch (err) {
|
|
29274
29581
|
return logResolved(anonymousFallback("pubkey-missing"), {
|
|
29275
29582
|
reason: "pubkey-missing"
|
|
@@ -29283,7 +29590,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
|
|
|
29283
29590
|
}
|
|
29284
29591
|
let envelope;
|
|
29285
29592
|
try {
|
|
29286
|
-
envelope = JSON.parse(
|
|
29593
|
+
envelope = JSON.parse(readFileSync45(entitlementPath, "utf-8"));
|
|
29287
29594
|
} catch {
|
|
29288
29595
|
return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
|
|
29289
29596
|
}
|
|
@@ -29447,12 +29754,12 @@ installMediaDownloadGuard();
|
|
|
29447
29754
|
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
29448
29755
|
var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join47(PLATFORM_ROOT8, "config", "brand.json") : "";
|
|
29449
29756
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
|
|
29450
|
-
if (BRAND_JSON_PATH && !
|
|
29757
|
+
if (BRAND_JSON_PATH && !existsSync43(BRAND_JSON_PATH)) {
|
|
29451
29758
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
29452
29759
|
}
|
|
29453
|
-
if (BRAND_JSON_PATH &&
|
|
29760
|
+
if (BRAND_JSON_PATH && existsSync43(BRAND_JSON_PATH)) {
|
|
29454
29761
|
try {
|
|
29455
|
-
const parsed = JSON.parse(
|
|
29762
|
+
const parsed = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
|
|
29456
29763
|
BRAND = { ...BRAND, ...parsed };
|
|
29457
29764
|
} catch (err) {
|
|
29458
29765
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -29487,8 +29794,8 @@ var brandLoginOpts = {
|
|
|
29487
29794
|
var ALIAS_DOMAINS_PATH = join47(homedir4(), BRAND.configDir, "alias-domains.json");
|
|
29488
29795
|
function loadAliasDomains() {
|
|
29489
29796
|
try {
|
|
29490
|
-
if (!
|
|
29491
|
-
const parsed = JSON.parse(
|
|
29797
|
+
if (!existsSync43(ALIAS_DOMAINS_PATH)) return null;
|
|
29798
|
+
const parsed = JSON.parse(readFileSync46(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
29492
29799
|
if (!Array.isArray(parsed)) {
|
|
29493
29800
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
29494
29801
|
return null;
|
|
@@ -29512,7 +29819,7 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
|
|
|
29512
29819
|
function isPublicHost(host) {
|
|
29513
29820
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
29514
29821
|
}
|
|
29515
|
-
var
|
|
29822
|
+
var app66 = new Hono();
|
|
29516
29823
|
function resolveChannelOverride(accountId, channel, senderId) {
|
|
29517
29824
|
try {
|
|
29518
29825
|
const dir = listValidAccounts().find((a) => a.accountId === accountId)?.accountDir;
|
|
@@ -29561,7 +29868,7 @@ var waGateway = new WaGateway({
|
|
|
29561
29868
|
fetchStandingRules: fetchAccountStandingRules,
|
|
29562
29869
|
resolveSessionOverride: (accountId, senderId) => resolveChannelOverride(accountId, "whatsapp", senderId),
|
|
29563
29870
|
gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
|
|
29564
|
-
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ??
|
|
29871
|
+
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
|
|
29565
29872
|
// Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
|
|
29566
29873
|
// path-validation scope) is the sender's effective SESSION account, resolved
|
|
29567
29874
|
// once at the inbound gate and threaded here via the gateway's per-sender doc
|
|
@@ -29576,7 +29883,7 @@ var waGateway = new WaGateway({
|
|
|
29576
29883
|
caption,
|
|
29577
29884
|
accountId,
|
|
29578
29885
|
maxyAccountId,
|
|
29579
|
-
platformRoot:
|
|
29886
|
+
platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."))
|
|
29580
29887
|
});
|
|
29581
29888
|
return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
|
|
29582
29889
|
},
|
|
@@ -29688,7 +29995,7 @@ var waGateway = new WaGateway({
|
|
|
29688
29995
|
nativeFileFollowers.set(senderId, ac);
|
|
29689
29996
|
}
|
|
29690
29997
|
});
|
|
29691
|
-
|
|
29998
|
+
app66.route("/", waGateway.routes());
|
|
29692
29999
|
waGateway.startSweeper();
|
|
29693
30000
|
function runDuplicateSenderAudit() {
|
|
29694
30001
|
try {
|
|
@@ -29811,7 +30118,7 @@ var webchatGateway = new WebchatGateway({
|
|
|
29811
30118
|
firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
|
|
29812
30119
|
});
|
|
29813
30120
|
setWebchatGateway(webchatGateway);
|
|
29814
|
-
|
|
30121
|
+
app66.route("/", webchatGateway.routes());
|
|
29815
30122
|
webchatGateway.startSweeper();
|
|
29816
30123
|
webchatGateway.startPublicReaper();
|
|
29817
30124
|
var telegramFileFollowers = /* @__PURE__ */ new Map();
|
|
@@ -29855,7 +30162,7 @@ var telegramGateway = new TelegramGateway({
|
|
|
29855
30162
|
}
|
|
29856
30163
|
});
|
|
29857
30164
|
setTelegramGateway(telegramGateway);
|
|
29858
|
-
|
|
30165
|
+
app66.route("/", telegramGateway.routes());
|
|
29859
30166
|
telegramGateway.startSweeper();
|
|
29860
30167
|
var chatRoutes = createChatRoutes({
|
|
29861
30168
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
@@ -29889,19 +30196,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
|
|
|
29889
30196
|
return managed.account;
|
|
29890
30197
|
}
|
|
29891
30198
|
});
|
|
29892
|
-
|
|
29893
|
-
|
|
30199
|
+
app66.route("/api/channel/schedule-inject", scheduleInjectRoutes);
|
|
30200
|
+
app66.use("*", clientIpMiddleware);
|
|
29894
30201
|
function allowsSameOriginFraming(path3) {
|
|
29895
30202
|
return path3 === "/vnc-viewer.html" || path3.startsWith("/api/admin/attachment/") || path3.startsWith("/api/public-reader/attachment/") || path3 === "/api/admin/files/download";
|
|
29896
30203
|
}
|
|
29897
|
-
|
|
30204
|
+
app66.use("*", async (c, next) => {
|
|
29898
30205
|
await next();
|
|
29899
30206
|
c.header("X-Content-Type-Options", "nosniff");
|
|
29900
30207
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
29901
30208
|
c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
|
|
29902
30209
|
});
|
|
29903
30210
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
29904
|
-
|
|
30211
|
+
app66.use("*", async (c, next) => {
|
|
29905
30212
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
29906
30213
|
await next();
|
|
29907
30214
|
return;
|
|
@@ -29919,7 +30226,7 @@ app65.use("*", async (c, next) => {
|
|
|
29919
30226
|
});
|
|
29920
30227
|
}
|
|
29921
30228
|
});
|
|
29922
|
-
|
|
30229
|
+
app66.use("*", async (c, next) => {
|
|
29923
30230
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
29924
30231
|
if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
|
|
29925
30232
|
await next();
|
|
@@ -29957,7 +30264,7 @@ function resolveRemoteAuthOpts(c) {
|
|
|
29957
30264
|
return { ...brandLoginOpts, origin };
|
|
29958
30265
|
}
|
|
29959
30266
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
29960
|
-
|
|
30267
|
+
app66.post("/__remote-auth/login", async (c) => {
|
|
29961
30268
|
const client = clientFrom(c);
|
|
29962
30269
|
const clientIp = client.ip || "unknown";
|
|
29963
30270
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -30002,7 +30309,7 @@ app65.post("/__remote-auth/login", async (c) => {
|
|
|
30002
30309
|
}
|
|
30003
30310
|
});
|
|
30004
30311
|
});
|
|
30005
|
-
|
|
30312
|
+
app66.get("/__remote-auth/logout", (c) => {
|
|
30006
30313
|
const client = clientFrom(c);
|
|
30007
30314
|
const clientIp = client.ip || "unknown";
|
|
30008
30315
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -30015,7 +30322,7 @@ app65.get("/__remote-auth/logout", (c) => {
|
|
|
30015
30322
|
}
|
|
30016
30323
|
});
|
|
30017
30324
|
});
|
|
30018
|
-
|
|
30325
|
+
app66.post("/__remote-auth/change-password", async (c) => {
|
|
30019
30326
|
const client = clientFrom(c);
|
|
30020
30327
|
const clientIp = client.ip || "unknown";
|
|
30021
30328
|
const rateLimited = checkRateLimit(client);
|
|
@@ -30074,13 +30381,13 @@ app65.post("/__remote-auth/change-password", async (c) => {
|
|
|
30074
30381
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
30075
30382
|
}
|
|
30076
30383
|
});
|
|
30077
|
-
|
|
30384
|
+
app66.get("/__remote-auth/setup", (c) => {
|
|
30078
30385
|
if (isRemoteAuthConfigured()) {
|
|
30079
30386
|
return c.redirect("/");
|
|
30080
30387
|
}
|
|
30081
30388
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
|
|
30082
30389
|
});
|
|
30083
|
-
|
|
30390
|
+
app66.post("/__remote-auth/set-initial-password", async (c) => {
|
|
30084
30391
|
if (isRemoteAuthConfigured()) {
|
|
30085
30392
|
return c.redirect("/");
|
|
30086
30393
|
}
|
|
@@ -30118,10 +30425,10 @@ app65.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
30118
30425
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
30119
30426
|
}
|
|
30120
30427
|
});
|
|
30121
|
-
|
|
30428
|
+
app66.get("/api/remote-auth/status", (c) => {
|
|
30122
30429
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
30123
30430
|
});
|
|
30124
|
-
|
|
30431
|
+
app66.post("/api/remote-auth/set-password", async (c) => {
|
|
30125
30432
|
let body;
|
|
30126
30433
|
try {
|
|
30127
30434
|
body = await c.req.json();
|
|
@@ -30160,10 +30467,10 @@ app65.post("/api/remote-auth/set-password", async (c) => {
|
|
|
30160
30467
|
return c.json({ error: "Failed to save password" }, 500);
|
|
30161
30468
|
}
|
|
30162
30469
|
});
|
|
30163
|
-
|
|
30470
|
+
app66.route("/api/_client-error", client_error_default);
|
|
30164
30471
|
console.log("[client-error-route] mounted");
|
|
30165
30472
|
var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
|
|
30166
|
-
|
|
30473
|
+
app66.use("*", async (c, next) => {
|
|
30167
30474
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30168
30475
|
const path3 = c.req.path;
|
|
30169
30476
|
if (path3 === "/favicon.ico" || path3.startsWith("/assets/") || path3.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
|
|
@@ -30207,28 +30514,28 @@ app65.use("*", async (c, next) => {
|
|
|
30207
30514
|
}
|
|
30208
30515
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path3 }), 200);
|
|
30209
30516
|
});
|
|
30210
|
-
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
|
|
30215
|
-
|
|
30216
|
-
|
|
30517
|
+
app66.route("/api/health", health_default);
|
|
30518
|
+
app66.route("/api/chat", chatRoutes);
|
|
30519
|
+
app66.route("/api/whatsapp", whatsapp_default);
|
|
30520
|
+
app66.route("/api/storage", storage_broker_default);
|
|
30521
|
+
app66.route("/api/whatsapp-reader", whatsapp_reader_default);
|
|
30522
|
+
app66.route("/api/public-reader", public_reader_default);
|
|
30523
|
+
app66.route("/api/webchat", createWebchatRoutes({
|
|
30217
30524
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
30218
30525
|
// Task 940 — the permission relay's pointer read + verdict write.
|
|
30219
30526
|
pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
|
|
30220
30527
|
deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
|
|
30221
30528
|
resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
|
|
30222
30529
|
}));
|
|
30223
|
-
|
|
30224
|
-
|
|
30225
|
-
|
|
30226
|
-
|
|
30227
|
-
|
|
30228
|
-
|
|
30229
|
-
|
|
30230
|
-
|
|
30231
|
-
|
|
30530
|
+
app66.route("/api/webchat/greeting", webchat_greeting_default);
|
|
30531
|
+
app66.route("/api/telegram", telegram_default);
|
|
30532
|
+
app66.route("/api/quickbooks", quickbooks_default);
|
|
30533
|
+
app66.route("/api/onboarding", onboarding_default);
|
|
30534
|
+
app66.route("/api/admin", admin_default);
|
|
30535
|
+
app66.route("/api/access", access_default);
|
|
30536
|
+
app66.route("/api/session", session_default2);
|
|
30537
|
+
app66.route("/api/calendar", calendar_public_default);
|
|
30538
|
+
app66.route("/api/portal", portal_fetch_default);
|
|
30232
30539
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
30233
30540
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
30234
30541
|
var IMAGE_MIME = {
|
|
@@ -30240,7 +30547,7 @@ var IMAGE_MIME = {
|
|
|
30240
30547
|
".svg": "image/svg+xml",
|
|
30241
30548
|
".ico": "image/x-icon"
|
|
30242
30549
|
};
|
|
30243
|
-
|
|
30550
|
+
app66.get("/agent-assets/:slug/:filename", (c) => {
|
|
30244
30551
|
const slug = c.req.param("slug");
|
|
30245
30552
|
const filename = c.req.param("filename");
|
|
30246
30553
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -30256,26 +30563,26 @@ app65.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
30256
30563
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
30257
30564
|
return c.text("Not found", 404);
|
|
30258
30565
|
}
|
|
30259
|
-
const filePath =
|
|
30260
|
-
const expectedDir =
|
|
30566
|
+
const filePath = resolve42(account.accountDir, "agents", slug, "assets", filename);
|
|
30567
|
+
const expectedDir = resolve42(account.accountDir, "agents", slug, "assets");
|
|
30261
30568
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
30262
30569
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
30263
30570
|
return c.text("Forbidden", 403);
|
|
30264
30571
|
}
|
|
30265
|
-
if (!
|
|
30572
|
+
if (!existsSync43(filePath)) {
|
|
30266
30573
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
30267
30574
|
return c.text("Not found", 404);
|
|
30268
30575
|
}
|
|
30269
30576
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
30270
30577
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
30271
30578
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
30272
|
-
const body =
|
|
30579
|
+
const body = readFileSync46(filePath);
|
|
30273
30580
|
return c.body(body, 200, {
|
|
30274
30581
|
"Content-Type": contentType,
|
|
30275
30582
|
"Cache-Control": "public, max-age=3600"
|
|
30276
30583
|
});
|
|
30277
30584
|
});
|
|
30278
|
-
|
|
30585
|
+
app66.get("/generated/:filename", (c) => {
|
|
30279
30586
|
const filename = c.req.param("filename");
|
|
30280
30587
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
30281
30588
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -30286,35 +30593,35 @@ app65.get("/generated/:filename", (c) => {
|
|
|
30286
30593
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
30287
30594
|
return c.text("Not found", 404);
|
|
30288
30595
|
}
|
|
30289
|
-
const filePath =
|
|
30290
|
-
const expectedDir =
|
|
30596
|
+
const filePath = resolve42(account.accountDir, "generated", filename);
|
|
30597
|
+
const expectedDir = resolve42(account.accountDir, "generated");
|
|
30291
30598
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
30292
30599
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
30293
30600
|
return c.text("Forbidden", 403);
|
|
30294
30601
|
}
|
|
30295
|
-
if (!
|
|
30602
|
+
if (!existsSync43(filePath)) {
|
|
30296
30603
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
30297
30604
|
return c.text("Not found", 404);
|
|
30298
30605
|
}
|
|
30299
30606
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
30300
30607
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
30301
30608
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
30302
|
-
const body =
|
|
30609
|
+
const body = readFileSync46(filePath);
|
|
30303
30610
|
return c.body(body, 200, {
|
|
30304
30611
|
"Content-Type": contentType,
|
|
30305
30612
|
"Cache-Control": "public, max-age=86400"
|
|
30306
30613
|
});
|
|
30307
30614
|
});
|
|
30308
|
-
|
|
30309
|
-
|
|
30310
|
-
|
|
30311
|
-
|
|
30615
|
+
app66.route("/sites", sites_default);
|
|
30616
|
+
app66.route("/listings", listings_default);
|
|
30617
|
+
app66.route("/v", visitor_event_default);
|
|
30618
|
+
app66.route("/v", visitor_consent_default);
|
|
30312
30619
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
30313
30620
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
30314
30621
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
30315
|
-
if (BRAND_JSON_PATH &&
|
|
30622
|
+
if (BRAND_JSON_PATH && existsSync43(BRAND_JSON_PATH)) {
|
|
30316
30623
|
try {
|
|
30317
|
-
const fullBrand = JSON.parse(
|
|
30624
|
+
const fullBrand = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
|
|
30318
30625
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
30319
30626
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
30320
30627
|
} catch {
|
|
@@ -30341,11 +30648,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
30341
30648
|
var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
|
|
30342
30649
|
var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
|
|
30343
30650
|
var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
|
|
30344
|
-
(p) =>
|
|
30651
|
+
(p) => existsSync43(resolve42(process.cwd(), "public", p.replace(/^\//, "")))
|
|
30345
30652
|
);
|
|
30346
30653
|
var SW_SOURCE = (() => {
|
|
30347
30654
|
try {
|
|
30348
|
-
return
|
|
30655
|
+
return readFileSync46(resolve42(process.cwd(), "public", "sw.js"), "utf-8");
|
|
30349
30656
|
} catch {
|
|
30350
30657
|
return null;
|
|
30351
30658
|
}
|
|
@@ -30354,8 +30661,8 @@ function readInstalledVersion() {
|
|
|
30354
30661
|
try {
|
|
30355
30662
|
if (!PLATFORM_ROOT8) return "unknown";
|
|
30356
30663
|
const versionFile = join47(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
|
|
30357
|
-
if (!
|
|
30358
|
-
const content =
|
|
30664
|
+
if (!existsSync43(versionFile)) return "unknown";
|
|
30665
|
+
const content = readFileSync46(versionFile, "utf-8").trim();
|
|
30359
30666
|
return content || "unknown";
|
|
30360
30667
|
} catch {
|
|
30361
30668
|
return "unknown";
|
|
@@ -30396,7 +30703,7 @@ var clientErrorReporterScript = `<script>
|
|
|
30396
30703
|
function cachedHtml(file) {
|
|
30397
30704
|
let html = htmlCache.get(file);
|
|
30398
30705
|
if (!html) {
|
|
30399
|
-
html =
|
|
30706
|
+
html = readFileSync46(resolve42(process.cwd(), "public", file), "utf-8");
|
|
30400
30707
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
30401
30708
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
30402
30709
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -30418,8 +30725,8 @@ function loadBrandingCache(agentSlug) {
|
|
|
30418
30725
|
const accountId = getDefaultAccountId();
|
|
30419
30726
|
if (!accountId) return null;
|
|
30420
30727
|
const cachePath = join47(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
30421
|
-
if (!
|
|
30422
|
-
return JSON.parse(
|
|
30728
|
+
if (!existsSync43(cachePath)) return null;
|
|
30729
|
+
return JSON.parse(readFileSync46(cachePath, "utf-8"));
|
|
30423
30730
|
} catch {
|
|
30424
30731
|
return null;
|
|
30425
30732
|
}
|
|
@@ -30463,7 +30770,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
30463
30770
|
function agentUnavailableHtml() {
|
|
30464
30771
|
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>`;
|
|
30465
30772
|
}
|
|
30466
|
-
|
|
30773
|
+
app66.get("/", (c) => {
|
|
30467
30774
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30468
30775
|
const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
|
|
30469
30776
|
if (klass === "operator") {
|
|
@@ -30485,12 +30792,12 @@ app65.get("/", (c) => {
|
|
|
30485
30792
|
console.log(`[host-class] host=${host} class=admin served=index.html`);
|
|
30486
30793
|
return c.html(cachedHtml("index.html"));
|
|
30487
30794
|
});
|
|
30488
|
-
|
|
30795
|
+
app66.get("/public", (c) => {
|
|
30489
30796
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30490
30797
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30491
30798
|
return c.html(cachedHtml("public.html"));
|
|
30492
30799
|
});
|
|
30493
|
-
|
|
30800
|
+
app66.get("/public-chat", (c) => {
|
|
30494
30801
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30495
30802
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30496
30803
|
return c.html(cachedHtml("public.html"));
|
|
@@ -30509,12 +30816,12 @@ async function logViewerFetch(c, next) {
|
|
|
30509
30816
|
duration_ms: Date.now() - start
|
|
30510
30817
|
});
|
|
30511
30818
|
}
|
|
30512
|
-
|
|
30513
|
-
|
|
30514
|
-
|
|
30819
|
+
app66.use("/vnc-viewer.html", logViewerFetch);
|
|
30820
|
+
app66.use("/vnc-popout.html", logViewerFetch);
|
|
30821
|
+
app66.get("/vnc-popout.html", (c) => {
|
|
30515
30822
|
let html = htmlCache.get("vnc-popout.html");
|
|
30516
30823
|
if (!html) {
|
|
30517
|
-
html =
|
|
30824
|
+
html = readFileSync46(resolve42(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
30518
30825
|
const name = escapeHtml(BRAND.productName);
|
|
30519
30826
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
30520
30827
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -30524,7 +30831,7 @@ app65.get("/vnc-popout.html", (c) => {
|
|
|
30524
30831
|
}
|
|
30525
30832
|
return c.html(html);
|
|
30526
30833
|
});
|
|
30527
|
-
|
|
30834
|
+
app66.post("/api/vnc/client-event", async (c) => {
|
|
30528
30835
|
let body;
|
|
30529
30836
|
try {
|
|
30530
30837
|
body = await c.req.json();
|
|
@@ -30545,11 +30852,11 @@ app65.post("/api/vnc/client-event", async (c) => {
|
|
|
30545
30852
|
});
|
|
30546
30853
|
return c.json({ ok: true });
|
|
30547
30854
|
});
|
|
30548
|
-
|
|
30855
|
+
app66.get("/g/:slug", (c) => {
|
|
30549
30856
|
return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
|
|
30550
30857
|
});
|
|
30551
30858
|
for (const pwa of PWA_SURFACES) {
|
|
30552
|
-
|
|
30859
|
+
app66.get(pwa.manifestPath, (c) => {
|
|
30553
30860
|
const manifest = buildManifest(pwa, {
|
|
30554
30861
|
productName: BRAND.productName,
|
|
30555
30862
|
appIcon192: brandAppIcon192Path,
|
|
@@ -30565,7 +30872,7 @@ for (const pwa of PWA_SURFACES) {
|
|
|
30565
30872
|
return c.body(JSON.stringify(manifest));
|
|
30566
30873
|
});
|
|
30567
30874
|
}
|
|
30568
|
-
|
|
30875
|
+
app66.get("/sw.js", (c) => {
|
|
30569
30876
|
if (SW_SOURCE == null) {
|
|
30570
30877
|
console.error("[pwa] op=sw status=500 reason=sw-source-missing");
|
|
30571
30878
|
return c.text("Service worker unavailable", 500);
|
|
@@ -30574,12 +30881,12 @@ app65.get("/sw.js", (c) => {
|
|
|
30574
30881
|
console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
|
|
30575
30882
|
return c.body(SW_SOURCE);
|
|
30576
30883
|
});
|
|
30577
|
-
|
|
30884
|
+
app66.get("/graph", (c) => {
|
|
30578
30885
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30579
30886
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
30580
30887
|
return c.html(cachedHtml("graph.html"));
|
|
30581
30888
|
});
|
|
30582
|
-
|
|
30889
|
+
app66.get("/chat", (c) => {
|
|
30583
30890
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30584
30891
|
if (isOperatorHost(host, getOperatorDomains())) {
|
|
30585
30892
|
console.log(`[host-class] host=${host} class=operator served=operator.html`);
|
|
@@ -30588,37 +30895,42 @@ app65.get("/chat", (c) => {
|
|
|
30588
30895
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30589
30896
|
return c.html(cachedHtml("chat.html"));
|
|
30590
30897
|
});
|
|
30591
|
-
|
|
30898
|
+
app66.get("/data", (c) => {
|
|
30592
30899
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30593
30900
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30594
30901
|
return c.html(cachedHtml("data.html"));
|
|
30595
30902
|
});
|
|
30596
|
-
|
|
30903
|
+
app66.get("/tasks", (c) => {
|
|
30597
30904
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30598
30905
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30599
30906
|
return c.html(cachedHtml("tasks.html"));
|
|
30600
30907
|
});
|
|
30601
|
-
|
|
30908
|
+
app66.get("/activity", (c) => {
|
|
30602
30909
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30603
30910
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30604
30911
|
return c.html(cachedHtml("activity.html"));
|
|
30605
30912
|
});
|
|
30606
|
-
|
|
30913
|
+
app66.get("/calendar", (c) => {
|
|
30607
30914
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30608
30915
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30609
30916
|
return c.html(cachedHtml("calendar.html"));
|
|
30610
30917
|
});
|
|
30611
|
-
|
|
30918
|
+
app66.get("/routines", (c) => {
|
|
30612
30919
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30613
30920
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30614
30921
|
return c.html(cachedHtml("routines.html"));
|
|
30615
30922
|
});
|
|
30616
|
-
|
|
30923
|
+
app66.get("/skills", (c) => {
|
|
30924
|
+
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30925
|
+
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30926
|
+
return c.html(cachedHtml("skills.html"));
|
|
30927
|
+
});
|
|
30928
|
+
app66.get("/browser", (c) => {
|
|
30617
30929
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30618
30930
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
30619
30931
|
return c.html(cachedHtml("browser.html"));
|
|
30620
30932
|
});
|
|
30621
|
-
|
|
30933
|
+
app66.get("/:slug", async (c, next) => {
|
|
30622
30934
|
const slug = c.req.param("slug");
|
|
30623
30935
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
30624
30936
|
const account = resolveAccount();
|
|
@@ -30633,13 +30945,13 @@ app65.get("/:slug", async (c, next) => {
|
|
|
30633
30945
|
await next();
|
|
30634
30946
|
});
|
|
30635
30947
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
30636
|
-
|
|
30948
|
+
app66.get("/favicon.ico", (c) => {
|
|
30637
30949
|
c.header("Cache-Control", "public, max-age=300");
|
|
30638
30950
|
return c.redirect(brandFaviconPath, 302);
|
|
30639
30951
|
});
|
|
30640
30952
|
}
|
|
30641
|
-
|
|
30642
|
-
|
|
30953
|
+
app66.use("/*", serveStatic({ root: "./public" }));
|
|
30954
|
+
app66.all("*", (c) => {
|
|
30643
30955
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30644
30956
|
const path3 = c.req.path;
|
|
30645
30957
|
if (isPublicHost(host)) {
|
|
@@ -30653,13 +30965,13 @@ app65.all("*", (c) => {
|
|
|
30653
30965
|
});
|
|
30654
30966
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
30655
30967
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
30656
|
-
var httpServer = serve({ fetch:
|
|
30968
|
+
var httpServer = serve({ fetch: app66.fetch, port, hostname });
|
|
30657
30969
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
30658
30970
|
{
|
|
30659
30971
|
const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30660
|
-
const reconcileScript =
|
|
30972
|
+
const reconcileScript = resolve42(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
|
|
30661
30973
|
const runReconcile = (ctx) => {
|
|
30662
|
-
if (!
|
|
30974
|
+
if (!existsSync43(reconcileScript)) return;
|
|
30663
30975
|
try {
|
|
30664
30976
|
const child = spawn3(process.execPath, [reconcileScript], {
|
|
30665
30977
|
env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
|
|
@@ -30698,14 +31010,14 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30698
31010
|
{
|
|
30699
31011
|
const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
|
|
30700
31012
|
const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30701
|
-
const dreamSweepScript =
|
|
31013
|
+
const dreamSweepScript = resolve42(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
|
|
30702
31014
|
registerLoop({
|
|
30703
31015
|
name: "dream-cycle-sweep",
|
|
30704
31016
|
intervalMs: DREAM_CYCLE_SWEEP_INTERVAL_MS,
|
|
30705
31017
|
firstRunDelayMs: 3e4,
|
|
30706
31018
|
detached: true,
|
|
30707
31019
|
run: (ctx) => {
|
|
30708
|
-
if (!
|
|
31020
|
+
if (!existsSync43(dreamSweepScript)) return;
|
|
30709
31021
|
try {
|
|
30710
31022
|
const child = spawn3(process.execPath, [dreamSweepScript], {
|
|
30711
31023
|
env: { ...process.env, PLATFORM_ROOT: dreamPlatformRoot },
|
|
@@ -30722,10 +31034,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30722
31034
|
}
|
|
30723
31035
|
{
|
|
30724
31036
|
const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30725
|
-
const outlookScript =
|
|
31037
|
+
const outlookScript = resolve42(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
|
|
30726
31038
|
const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
|
|
30727
31039
|
const runOutlookComplete = (ctx) => {
|
|
30728
|
-
if (!
|
|
31040
|
+
if (!existsSync43(outlookScript)) return;
|
|
30729
31041
|
try {
|
|
30730
31042
|
const child = spawn3(process.execPath, [outlookScript], {
|
|
30731
31043
|
env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
|
|
@@ -30748,19 +31060,19 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30748
31060
|
}
|
|
30749
31061
|
{
|
|
30750
31062
|
const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30751
|
-
const strandedAccountsDir =
|
|
31063
|
+
const strandedAccountsDir = resolve42(auditRoot, "..", "data/accounts");
|
|
30752
31064
|
const STRANDED_AUDIT_INTERVAL_MS = 3e5;
|
|
30753
31065
|
const STRANDED_AGE_MS = 16 * 6e4;
|
|
30754
31066
|
const STRANDED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
30755
31067
|
const runStrandedAudit = () => {
|
|
30756
31068
|
try {
|
|
30757
|
-
if (!
|
|
31069
|
+
if (!existsSync43(strandedAccountsDir)) return;
|
|
30758
31070
|
const now = Date.now();
|
|
30759
|
-
for (const name of
|
|
31071
|
+
for (const name of readdirSync27(strandedAccountsDir)) {
|
|
30760
31072
|
if (!STRANDED_UUID_RE.test(name)) continue;
|
|
30761
|
-
const pendingPath2 =
|
|
30762
|
-
if (!
|
|
30763
|
-
const ageMs2 = now -
|
|
31073
|
+
const pendingPath2 = resolve42(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
|
|
31074
|
+
if (!existsSync43(pendingPath2)) continue;
|
|
31075
|
+
const ageMs2 = now - statSync18(pendingPath2).mtimeMs;
|
|
30764
31076
|
if (ageMs2 > STRANDED_AGE_MS) {
|
|
30765
31077
|
console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
|
|
30766
31078
|
}
|
|
@@ -30778,7 +31090,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30778
31090
|
}
|
|
30779
31091
|
{
|
|
30780
31092
|
const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30781
|
-
const googleAccountsDir =
|
|
31093
|
+
const googleAccountsDir = resolve42(googleRoot, "..", "data/accounts");
|
|
30782
31094
|
const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
|
|
30783
31095
|
const runGooglePendingAuditSafe = () => {
|
|
30784
31096
|
try {
|
|
@@ -30793,10 +31105,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30793
31105
|
firstRunDelayMs: 27e3,
|
|
30794
31106
|
run: runGooglePendingAuditSafe
|
|
30795
31107
|
});
|
|
30796
|
-
const googleAuditScript =
|
|
31108
|
+
const googleAuditScript = resolve42(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
|
|
30797
31109
|
const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
|
|
30798
31110
|
const runGoogleAccountAudit = (ctx) => {
|
|
30799
|
-
if (!
|
|
31111
|
+
if (!existsSync43(googleAuditScript)) return;
|
|
30800
31112
|
try {
|
|
30801
31113
|
const child = spawn3(process.execPath, [googleAuditScript], {
|
|
30802
31114
|
env: { ...process.env, PLATFORM_ROOT: googleRoot },
|
|
@@ -30868,7 +31180,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30868
31180
|
}
|
|
30869
31181
|
{
|
|
30870
31182
|
const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30871
|
-
const publishScript =
|
|
31183
|
+
const publishScript = resolve42(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
|
|
30872
31184
|
const PUBLISH_INTERVAL_MS = 3e5;
|
|
30873
31185
|
const bookingAccounts = () => {
|
|
30874
31186
|
try {
|
|
@@ -30879,7 +31191,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30879
31191
|
}
|
|
30880
31192
|
};
|
|
30881
31193
|
const spawnPublish = (account, ctx) => {
|
|
30882
|
-
if (!
|
|
31194
|
+
if (!existsSync43(publishScript)) return;
|
|
30883
31195
|
try {
|
|
30884
31196
|
const child = spawn3(process.execPath, [publishScript], {
|
|
30885
31197
|
env: {
|
|
@@ -30898,21 +31210,21 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30898
31210
|
}
|
|
30899
31211
|
};
|
|
30900
31212
|
const auditSnapshotAge = (account) => {
|
|
30901
|
-
const availPath =
|
|
31213
|
+
const availPath = resolve42(account.accountDir, "calendar-availability.json");
|
|
30902
31214
|
let hasBookingSite = false;
|
|
30903
31215
|
try {
|
|
30904
|
-
if (
|
|
30905
|
-
const cfg = JSON.parse(
|
|
31216
|
+
if (existsSync43(availPath)) {
|
|
31217
|
+
const cfg = JSON.parse(readFileSync46(availPath, "utf-8"));
|
|
30906
31218
|
hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
|
|
30907
31219
|
}
|
|
30908
31220
|
} catch {
|
|
30909
31221
|
}
|
|
30910
31222
|
if (!hasBookingSite) return;
|
|
30911
|
-
const statePath =
|
|
31223
|
+
const statePath = resolve42(account.accountDir, "state", "booking-availability", "last-publish.json");
|
|
30912
31224
|
let lastSuccessAt = null;
|
|
30913
|
-
if (
|
|
31225
|
+
if (existsSync43(statePath)) {
|
|
30914
31226
|
try {
|
|
30915
|
-
const rec = JSON.parse(
|
|
31227
|
+
const rec = JSON.parse(readFileSync46(statePath, "utf-8"));
|
|
30916
31228
|
lastSuccessAt = rec.lastSuccessAt ?? null;
|
|
30917
31229
|
} catch {
|
|
30918
31230
|
console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
|
|
@@ -30945,11 +31257,11 @@ startTimeEntryCensus(() => getSession());
|
|
|
30945
31257
|
startLedgerCensus(() => getSession());
|
|
30946
31258
|
{
|
|
30947
31259
|
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30948
|
-
const auditScript =
|
|
31260
|
+
const auditScript = resolve42(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
|
|
30949
31261
|
const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
|
|
30950
31262
|
const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
|
|
30951
31263
|
const runConnectorAudit = (ctx) => {
|
|
30952
|
-
if (!
|
|
31264
|
+
if (!existsSync43(auditScript)) return;
|
|
30953
31265
|
try {
|
|
30954
31266
|
const child = spawn3(process.execPath, [auditScript], {
|
|
30955
31267
|
env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
|
|
@@ -31029,7 +31341,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
31029
31341
|
}
|
|
31030
31342
|
try {
|
|
31031
31343
|
const registered = [];
|
|
31032
|
-
for (const r of
|
|
31344
|
+
for (const r of app66.routes ?? []) {
|
|
31033
31345
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
31034
31346
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
31035
31347
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -31069,11 +31381,11 @@ try {
|
|
|
31069
31381
|
var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
31070
31382
|
async function runAdminUserReconcileTick() {
|
|
31071
31383
|
try {
|
|
31072
|
-
if (!
|
|
31384
|
+
if (!existsSync43(USERS_FILE)) {
|
|
31073
31385
|
console.error("[adminuser-self-heal] skip reason=no-users-file");
|
|
31074
31386
|
return;
|
|
31075
31387
|
}
|
|
31076
|
-
const usersRaw =
|
|
31388
|
+
const usersRaw = readFileSync46(USERS_FILE, "utf-8").trim();
|
|
31077
31389
|
if (!usersRaw) {
|
|
31078
31390
|
console.error("[adminuser-self-heal] skip reason=empty-users-file");
|
|
31079
31391
|
return;
|
|
@@ -31120,8 +31432,8 @@ registerLoop({
|
|
|
31120
31432
|
});
|
|
31121
31433
|
var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
31122
31434
|
function countUsersRows() {
|
|
31123
|
-
if (!
|
|
31124
|
-
const raw =
|
|
31435
|
+
if (!existsSync43(USERS_FILE)) return 0;
|
|
31436
|
+
const raw = readFileSync46(USERS_FILE, "utf-8").trim();
|
|
31125
31437
|
if (!raw) return 0;
|
|
31126
31438
|
const users = JSON.parse(raw);
|
|
31127
31439
|
return users.filter((u) => typeof u.userId === "string").length;
|
|
@@ -31254,7 +31566,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
31254
31566
|
}
|
|
31255
31567
|
init({
|
|
31256
31568
|
configDir: configDirForWhatsApp,
|
|
31257
|
-
platformRoot:
|
|
31569
|
+
platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..")),
|
|
31258
31570
|
accountConfig: bootAccountConfig,
|
|
31259
31571
|
onMessage: async (msg) => {
|
|
31260
31572
|
if (isObserveAccount(msg.accountId)) {
|