@rubytech/create-maxy-code 0.1.297 → 0.1.299
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/models/dist/index.d.ts +7 -0
- package/payload/platform/lib/models/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/models/dist/index.js +16 -1
- package/payload/platform/lib/models/dist/index.js.map +1 -1
- package/payload/platform/lib/models/src/index.ts +16 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
- package/payload/platform/plugins/cloudflare/references/manual-setup.md +33 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
- package/payload/platform/plugins/email/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/email/PLUGIN.md +11 -3
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-edit.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-edit.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-edit.test.js +71 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-edit.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js +95 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft.test.js +56 -2
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js +93 -2
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/send-raw.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/send-raw.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/send-raw.test.js +38 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/send-raw.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/index.js +76 -2
- package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/compose.d.ts +47 -0
- package/payload/platform/plugins/email/mcp/dist/lib/compose.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/compose.js +75 -0
- package/payload/platform/plugins/email/mcp/dist/lib/compose.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +37 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +117 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts +18 -0
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.js +25 -0
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-edit.d.ts +9 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-edit.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-edit.js +23 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-edit.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.d.ts +8 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js +52 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft.d.ts +2 -8
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft.js +6 -34
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js +1 -8
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js.map +1 -1
- package/payload/platform/plugins/email/skills/email-composition/SKILL.md +15 -4
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +13 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +71 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/public/assets/AdminShell-Eo1RXZxq.js +1 -0
- package/payload/server/public/assets/{Checkbox-o5EbM1Sd.js → Checkbox-DHnspkuk.js} +1 -1
- package/payload/server/public/assets/{Transcript-B-roO2vK.js → Transcript-9FlneAzM.js} +1 -1
- package/payload/server/public/assets/admin-ORJGvOqo.js +1 -0
- package/payload/server/public/assets/{arc-DmR-LPIx.js → arc-CPOhuw1V.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-CQHotPO2.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DCLfcVZf.js → architectureDiagram-Q4EWVU46-BaR37f-j.js} +1 -1
- package/payload/server/public/assets/audio-attachment-mime-CFRERhV0.js +1 -0
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DtTb6oGR.js → blockDiagram-DXYQGD6D-Du7NMQfQ.js} +1 -1
- package/payload/server/public/assets/browser--bCCzvRh.js +1 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DHMgkbse.js → c4Diagram-AHTNJAMY-F3GnFLbs.js} +1 -1
- package/payload/server/public/assets/channel-DfO_IgSU.js +1 -0
- package/payload/server/public/assets/chat-DIrzZjdO.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-BYqpHDvA.js → chunk-2KRD3SAO-SUv9UlAA.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-DQja-fc4.js → chunk-336JU56O-DHUrM3QG.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-CBo-Lx7X.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-BeDVr5Tb.js → chunk-4BX2VUAB-D5iKMyHO.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-DViPFnGL.js → chunk-4TB4RGXK-BahbQ7-Z.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-DB18cH4S.js → chunk-55IACEB6-DfF9myIx.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-CdKJ7vdW.js → chunk-5FUZZQ4R-jF6a9UVe.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-BIJiayBe.js → chunk-5PVQY5BW-BOCI-roy.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-Ca9KwdQm.js → chunk-67CJDMHE-E5wGK0dP.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-BDpzHOmv.js → chunk-7N4EOEYR-CtT0GsUT.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-DXo9fZho.js → chunk-AA7GKIK3-CGUj8eo-.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-CTqmM6qI.js → chunk-BSJP7CBP-OPAIjvSk.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-NufEId2j.js → chunk-CIAEETIT-S_D8FhIT.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-CDDqx-TB.js → chunk-EDXVE4YY-CkD4AyZi.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-BVNFvue5.js → chunk-ENJZ2VHE-CmoK-c5f.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-_4wtKsfc.js → chunk-FMBD7UC4-DcyogdNf.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-565zaYb3.js → chunk-FOC6F5B3-8iNobZdv.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DEZQolUW.js → chunk-ICPOFSXX-DeGZE9pw.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-CTZnA5fq.js → chunk-K5T4RW27-CkoKFdgU.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-CeuKp7uR.js → chunk-KGLVRYIC-DyNP1efP.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-DXkzlh3_.js → chunk-LIHQZDEY-WZPpo5Dd.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-DcZUCmgM.js → chunk-ORNJ4GCN-Cr7E0-Df.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-Dn0reHna.js → chunk-OYMX7WX6-BPjxo1Oc.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-CNlL2tiW.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-sqMpBHaS.js → chunk-U2HBQHQK-CuDS7yVX.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-ByhTOa14.js → chunk-X2U36JSP-DEkde3xe.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-CnU6DVpC.js → chunk-XPW4576I-BwRCuKyu.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-CGo_et0d.js → chunk-YZCP3GAM-DD9nUp-w.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-B9aPwq_o.js → chunk-ZZ45TVLE-BDH9b11G.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-Bo-iLGpk.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Bz7DNpvQ.js +1 -0
- package/payload/server/public/assets/clone-Bh_bM_44.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-C04wkJr7.js → cose-bilkent-S5V4N54A-CfeophtW.js} +1 -1
- package/payload/server/public/assets/{dagre-DE88U4Vk.js → dagre-CVxEmku2.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-oeoQWi1f.js → dagre-KV5264BT-TOuVLdjq.js} +1 -1
- package/payload/server/public/assets/{data-6mvcS2_6.js → data-B8Waqy4Q.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-HmWmPhlY.js → diagram-5BDNPKRD-BJQnfJjx.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-Bkao4d6n.js → diagram-G4DWMVQ6-CqK94J29.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-Eh2fnSb-.js → diagram-MMDJMWI5-BCnATv2X.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-C8705_ZE.js → diagram-TYMM5635-Cl3BUrVs.js} +1 -1
- package/payload/server/public/assets/{dist-Pgmncqde.js → dist-BXJR8AkG.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-Bkhe0ZPv.js → erDiagram-SMLLAGMA--Uw0kvib.js} +1 -1
- package/payload/server/public/assets/{file-download-DVUMxBgB.js → file-download-Pk6cNtuB.js} +1 -1
- package/payload/server/public/assets/{flatten-DeFkSYLU.js → flatten-DtM0XAMt.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-rQKH0HF0.js → flowDiagram-DWJPFMVM-B_VGZIbJ.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-C3oSBbAe.js → ganttDiagram-T4ZO3ILL-D-vdf1dC.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-Ds2hoRX4.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-28GEOzIR.js → gitGraphDiagram-UUTBAWPF-CpyAlvu3.js} +1 -1
- package/payload/server/public/assets/{graph-B5R9qDya.js → graph-D-VQpkaS.js} +2 -2
- package/payload/server/public/assets/{graph-labels-Bcq_R9X9.js → graph-labels-cJvlyVxD.js} +1 -1
- package/payload/server/public/assets/{graphlib-DhAwTSya.js → graphlib-DaV4XyBp.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-BuX4gDTt.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-pcFw8-8F.js +2 -0
- package/payload/server/public/assets/{isEmpty-Bn-Se8yT.js → isEmpty-D__iH1WQ.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-B0mYhBS0.js → ishikawaDiagram-UXIWVN3A-_4NvfwwU.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CIcZskca.js → journeyDiagram-VCZTEJTY-PJQ-tPWv.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-CynkhuPm.js → jsx-runtime-B54kfC3e.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-DqAwfhuD.css → jsx-runtime-BjFkEGXb.css} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DWEpWX0D.js → kanban-definition-6JOO6SKY-asCNlyH4.js} +1 -1
- package/payload/server/public/assets/{line-D6evlE4c.js → line-BSXr2IPU.js} +1 -1
- package/payload/server/public/assets/{linear-CgbkJiu6.js → linear-CSAKvvko.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-DyRhDebz.js → mermaid-parser.core-DFxv-h16.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-DaD391Xr.js → mermaid.core-Be34BFtA.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-D7IMib-k.js → mindmap-definition-QFDTVHPH-IxwnMT2Q.js} +1 -1
- package/payload/server/public/assets/operator-DyLRFmNE.js +1 -0
- package/payload/server/public/assets/{ordinal-C-EimP2j.js → ordinal-BRQ5CzZY.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-9qQ2zAJ3.js +1 -0
- package/payload/server/public/assets/page-CFgywgGE.js +1 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-aDbmozld.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CyOSJozN.js → pieDiagram-DEJITSTG-DFqSnPPB.js} +1 -1
- package/payload/server/public/assets/{public-Cj7vjoG1.js → public-_pD6yEQ6.js} +5 -5
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CHWWRW-7.js → quadrantDiagram-34T5L4WZ-1AB3hlEb.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-CEm-iLey.js +1 -0
- package/payload/server/public/assets/{reduce-B0wq8DtH.js → reduce-CkcXOmmJ.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-x4-mHKrQ.js → requirementDiagram-MS252O5E-C2Zpzq3l.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DvKrAe78.js → sankeyDiagram-XADWPNL6-DkmhPhwS.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-DW778VnP.js → sequenceDiagram-FGHM5R23-1hQLpeZ1.js} +1 -1
- package/payload/server/public/assets/{src-CozP7LCe.js → src-CPkr6SrY.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DVnPPuE8.js → stateDiagram-FHFEXIEX-CBHIwm3f.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DHGLsXgi.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CO4Sp85K.js → timeline-definition-GMOUNBTQ-CLRWWipW.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-DYa2gPJa.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-D816ED1y.js +1 -0
- package/payload/server/public/assets/{useSelectionMode-BK4pznA6.js → useSelectionMode-6fff2UIV.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-OCcztoT8.js → vennDiagram-DHZGUBPP-ByFoQMek.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-BniDWDlr.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-C_1o3jux.js → wardleyDiagram-NUSXRM2D-DIkXRSha.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BPJxl9U1.js → xychartDiagram-5P7HB3ND-BNdEcN73.js} +1 -1
- package/payload/server/public/browser.html +7 -7
- package/payload/server/public/chat.html +9 -9
- package/payload/server/public/data.html +6 -6
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +11 -10
- package/payload/server/public/operator.html +24 -0
- package/payload/server/public/public.html +7 -7
- package/payload/server/server.js +300 -229
- package/payload/server/public/assets/AdminShell-DpjiG4KO.js +0 -1
- package/payload/server/public/assets/admin-DmBG61gA.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-CjF2k79a.js +0 -1
- package/payload/server/public/assets/audio-attachment-mime-D_YMUIBb.js +0 -1
- package/payload/server/public/assets/browser-DPqQnY8B.js +0 -1
- package/payload/server/public/assets/channel-BGB5Q-QM.js +0 -1
- package/payload/server/public/assets/chat-BpceL2qA.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-uBZXKz4Z.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-CBWmDBHe.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DdUR3hKH.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-B0ZE2WR0.js +0 -1
- package/payload/server/public/assets/clone-B5aO4uPo.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-DsUTwRUb.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-BV9FyUXQ.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-DnSzN29F.js +0 -2
- package/payload/server/public/assets/packet-4T2RLAQJ-SXjQ83Vr.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-q7TXebDD.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-CXKUHVMS.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B3nWH_hq.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CWuFgUeJ.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-gKO4rbgo.js +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-hDEw8pJN.js +0 -1
- /package/payload/server/public/assets/{_baseFor-BV-TyLWt.js → _baseFor-SRtUHe7G.js} +0 -0
- /package/payload/server/public/assets/{array-lqrvkwy7.js → array-BpsnM-Py.js} +0 -0
- /package/payload/server/public/assets/{chunk-CWOGyPgy.js → chunk-Pqm5yXtL.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-SmEOayFS.js → cytoscape.esm-D4Rl1H5h.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-Dl3Sud5K.js → defaultLocale-C7sQPl-O.js} +0 -0
- /package/payload/server/public/assets/{init-BukMwkmL.js → init-BydxaDEV.js} +0 -0
- /package/payload/server/public/assets/{katex-jl-BtNZi.js → katex-B0fVeDx4.js} +0 -0
- /package/payload/server/public/assets/{admin-CWMpccrR.css → page-CWMpccrR.css} +0 -0
- /package/payload/server/public/assets/{path-DPTRcLku.js → path-jlWYQ2i9.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-VLpapkIG.js → rough.esm-c4PR5shF.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -1215,7 +1215,7 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
1215
1215
|
|
|
1216
1216
|
// server/index.ts
|
|
1217
1217
|
import { readFileSync as readFileSync26, existsSync as existsSync26, watchFile } from "fs";
|
|
1218
|
-
import { resolve as
|
|
1218
|
+
import { resolve as resolve29, join as join22, basename as basename8 } from "path";
|
|
1219
1219
|
import { homedir as homedir3 } from "os";
|
|
1220
1220
|
import { monitorEventLoopDelay } from "perf_hooks";
|
|
1221
1221
|
|
|
@@ -1244,6 +1244,21 @@ function isPublicPathAllowed(path2) {
|
|
|
1244
1244
|
if (PUBLIC_ALLOWED_PREFIXES.some((prefix) => path2.startsWith(prefix))) return true;
|
|
1245
1245
|
return AGENT_SLUG_PATTERN.test(path2);
|
|
1246
1246
|
}
|
|
1247
|
+
function isOperatorHost(host) {
|
|
1248
|
+
return host.startsWith("operator.");
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// server/webchat-descriptor.ts
|
|
1252
|
+
import { resolve, join as join2 } from "path";
|
|
1253
|
+
function webchatGatewayUrl() {
|
|
1254
|
+
return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
|
|
1255
|
+
}
|
|
1256
|
+
function webchatServerPath() {
|
|
1257
|
+
return process.env.MAXY_WEBCHAT_CHANNEL_SERVER_PATH ?? resolve(process.env.MAXY_PLATFORM_ROOT ?? join2(__dirname, ".."), "services/webchat-channel/dist/server.js");
|
|
1258
|
+
}
|
|
1259
|
+
function webchatChannelDescriptor(key) {
|
|
1260
|
+
return { key, gatewayUrl: webchatGatewayUrl(), serverPath: webchatServerPath() };
|
|
1261
|
+
}
|
|
1247
1262
|
|
|
1248
1263
|
// app/lib/claude-auth.ts
|
|
1249
1264
|
import { readFileSync, writeFileSync } from "fs";
|
|
@@ -1794,7 +1809,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
1794
1809
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
1795
1810
|
console.error(`${TAG2} draining credential save queue\u2026`);
|
|
1796
1811
|
const timer2 = new Promise(
|
|
1797
|
-
(
|
|
1812
|
+
(resolve30) => setTimeout(() => resolve30("timeout"), timeoutMs)
|
|
1798
1813
|
);
|
|
1799
1814
|
const result = await Promise.race([
|
|
1800
1815
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -1922,11 +1937,11 @@ async function createWaSocket(opts) {
|
|
|
1922
1937
|
return sock;
|
|
1923
1938
|
}
|
|
1924
1939
|
async function waitForConnection(sock) {
|
|
1925
|
-
return new Promise((
|
|
1940
|
+
return new Promise((resolve30, reject) => {
|
|
1926
1941
|
const handler = (update) => {
|
|
1927
1942
|
if (update.connection === "open") {
|
|
1928
1943
|
sock.ev.off("connection.update", handler);
|
|
1929
|
-
|
|
1944
|
+
resolve30();
|
|
1930
1945
|
}
|
|
1931
1946
|
if (update.connection === "close") {
|
|
1932
1947
|
sock.ev.off("connection.update", handler);
|
|
@@ -2040,14 +2055,14 @@ ${inspected}`;
|
|
|
2040
2055
|
return inspect2(err, INSPECT_OPTS2);
|
|
2041
2056
|
}
|
|
2042
2057
|
function withTimeout(label, promise, timeoutMs) {
|
|
2043
|
-
return new Promise((
|
|
2058
|
+
return new Promise((resolve30, reject) => {
|
|
2044
2059
|
const timer2 = setTimeout(() => {
|
|
2045
2060
|
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
2046
2061
|
}, timeoutMs);
|
|
2047
2062
|
promise.then(
|
|
2048
2063
|
(value) => {
|
|
2049
2064
|
clearTimeout(timer2);
|
|
2050
|
-
|
|
2065
|
+
resolve30(value);
|
|
2051
2066
|
},
|
|
2052
2067
|
(err) => {
|
|
2053
2068
|
clearTimeout(timer2);
|
|
@@ -2646,8 +2661,8 @@ async function persistWhatsAppMessage(input) {
|
|
|
2646
2661
|
const { givenName, familyName } = splitName(input.pushName);
|
|
2647
2662
|
const prev = sessionWriteLocks.get(input.cacheKey);
|
|
2648
2663
|
let release;
|
|
2649
|
-
const mine = new Promise((
|
|
2650
|
-
release =
|
|
2664
|
+
const mine = new Promise((resolve30) => {
|
|
2665
|
+
release = resolve30;
|
|
2651
2666
|
});
|
|
2652
2667
|
const chained = (prev ?? Promise.resolve()).then(() => mine);
|
|
2653
2668
|
sessionWriteLocks.set(input.cacheKey, chained);
|
|
@@ -2833,7 +2848,7 @@ async function ensureWhatsAppConversation(input) {
|
|
|
2833
2848
|
|
|
2834
2849
|
// ../lib/account-enumeration/src/index.ts
|
|
2835
2850
|
import { readdirSync, readFileSync as readFileSync3 } from "fs";
|
|
2836
|
-
import { resolve } from "path";
|
|
2851
|
+
import { resolve as resolve2 } from "path";
|
|
2837
2852
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2838
2853
|
var cache = /* @__PURE__ */ new Map();
|
|
2839
2854
|
function enumerateValidAccountIds(accountsDir) {
|
|
@@ -2852,7 +2867,7 @@ function enumerateValidAccountIds(accountsDir) {
|
|
|
2852
2867
|
const valid = [];
|
|
2853
2868
|
for (const name of names) {
|
|
2854
2869
|
if (!UUID_RE.test(name)) continue;
|
|
2855
|
-
const configPath2 =
|
|
2870
|
+
const configPath2 = resolve2(accountsDir, name, "account.json");
|
|
2856
2871
|
try {
|
|
2857
2872
|
JSON.parse(readFileSync3(configPath2, "utf-8"));
|
|
2858
2873
|
valid.push(name);
|
|
@@ -2871,7 +2886,7 @@ function getAccountsDirFromEnv() {
|
|
|
2871
2886
|
"[graph-write] MAXY_PLATFORM_ROOT not set \u2014 cannot enforce accountId gate. Set MAXY_PLATFORM_ROOT in the spawning process or pass `accountsDir` explicitly."
|
|
2872
2887
|
);
|
|
2873
2888
|
}
|
|
2874
|
-
return
|
|
2889
|
+
return resolve2(root, "..", "data/accounts");
|
|
2875
2890
|
}
|
|
2876
2891
|
function validateAccountIdEnv(envValue, diskIds) {
|
|
2877
2892
|
if (!envValue) {
|
|
@@ -2910,7 +2925,7 @@ function resolvePlatformAccountId(accountsDir = ACCOUNTS_DIR) {
|
|
|
2910
2925
|
// app/lib/whatsapp/inbound/media.ts
|
|
2911
2926
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2912
2927
|
import { writeFile, mkdir } from "fs/promises";
|
|
2913
|
-
import { join as
|
|
2928
|
+
import { join as join3 } from "path";
|
|
2914
2929
|
import {
|
|
2915
2930
|
downloadMediaMessage,
|
|
2916
2931
|
downloadContentFromMessage,
|
|
@@ -2996,7 +3011,7 @@ async function downloadInboundMedia(msg, sock, opts) {
|
|
|
2996
3011
|
await mkdir(MEDIA_DIR, { recursive: true });
|
|
2997
3012
|
const ext = mimeToExt(mimetype ?? "application/octet-stream");
|
|
2998
3013
|
const filename = `${randomUUID2()}.${ext}`;
|
|
2999
|
-
const filePath =
|
|
3014
|
+
const filePath = join3(MEDIA_DIR, filename);
|
|
3000
3015
|
await writeFile(filePath, buffer);
|
|
3001
3016
|
const sizeKB = (buffer.length / 1024).toFixed(0);
|
|
3002
3017
|
console.error(`${TAG9} media downloaded type=${mimetype ?? "unknown"} size=${sizeKB}KB path=${filePath}`);
|
|
@@ -3727,11 +3742,11 @@ async function connectWithReconnect(conn) {
|
|
|
3727
3742
|
console.error(
|
|
3728
3743
|
`${TAG13} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
3729
3744
|
);
|
|
3730
|
-
await new Promise((
|
|
3731
|
-
const timer2 = setTimeout(
|
|
3745
|
+
await new Promise((resolve30) => {
|
|
3746
|
+
const timer2 = setTimeout(resolve30, delay);
|
|
3732
3747
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
3733
3748
|
clearTimeout(timer2);
|
|
3734
|
-
|
|
3749
|
+
resolve30();
|
|
3735
3750
|
}, { once: true });
|
|
3736
3751
|
});
|
|
3737
3752
|
}
|
|
@@ -3739,16 +3754,16 @@ async function connectWithReconnect(conn) {
|
|
|
3739
3754
|
}
|
|
3740
3755
|
}
|
|
3741
3756
|
function waitForDisconnectEvent(conn) {
|
|
3742
|
-
return new Promise((
|
|
3757
|
+
return new Promise((resolve30) => {
|
|
3743
3758
|
if (!conn.sock) {
|
|
3744
|
-
|
|
3759
|
+
resolve30();
|
|
3745
3760
|
return;
|
|
3746
3761
|
}
|
|
3747
3762
|
const sock = conn.sock;
|
|
3748
3763
|
const handler = (update) => {
|
|
3749
3764
|
if (update.connection === "close") {
|
|
3750
3765
|
sock.ev.off("connection.update", handler);
|
|
3751
|
-
|
|
3766
|
+
resolve30();
|
|
3752
3767
|
}
|
|
3753
3768
|
};
|
|
3754
3769
|
sock.ev.on("connection.update", handler);
|
|
@@ -4008,8 +4023,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
4008
4023
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
4009
4024
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
4010
4025
|
let resolvePending;
|
|
4011
|
-
const sttPending = new Promise((
|
|
4012
|
-
resolvePending =
|
|
4026
|
+
const sttPending = new Promise((resolve30) => {
|
|
4027
|
+
resolvePending = resolve30;
|
|
4013
4028
|
});
|
|
4014
4029
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
4015
4030
|
try {
|
|
@@ -4106,9 +4121,9 @@ async function handleInboundMessage(conn, msg) {
|
|
|
4106
4121
|
import { spawnSync, execFileSync } from "child_process";
|
|
4107
4122
|
import { createConnection } from "net";
|
|
4108
4123
|
import { mkdirSync, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
4109
|
-
import { resolve as
|
|
4110
|
-
var PLATFORM_ROOT2 = process.env.MAXY_PLATFORM_ROOT ??
|
|
4111
|
-
var VNC_SCRIPT =
|
|
4124
|
+
import { resolve as resolve3 } from "path";
|
|
4125
|
+
var PLATFORM_ROOT2 = process.env.MAXY_PLATFORM_ROOT ?? resolve3(process.cwd(), "..");
|
|
4126
|
+
var VNC_SCRIPT = resolve3(PLATFORM_ROOT2, "scripts/vnc.sh");
|
|
4112
4127
|
var displayMode = process.env.DISPLAY_MODE ?? "virtual";
|
|
4113
4128
|
if (displayMode === "native") {
|
|
4114
4129
|
console.log(`[vnc] DISPLAY_MODE=native \u2014 local requests use desktop display, remote requests use VNC`);
|
|
@@ -4221,7 +4236,7 @@ function ensureLogDir() {
|
|
|
4221
4236
|
mkdirSync(LOG_DIR, { recursive: true });
|
|
4222
4237
|
}
|
|
4223
4238
|
function logPath(name) {
|
|
4224
|
-
return
|
|
4239
|
+
return resolve3(LOG_DIR, `${name}.log`);
|
|
4225
4240
|
}
|
|
4226
4241
|
async function ensureVnc() {
|
|
4227
4242
|
const up = await waitForPort(RFB_PORT, 1e3);
|
|
@@ -4300,7 +4315,7 @@ function killChromium() {
|
|
|
4300
4315
|
}
|
|
4301
4316
|
function writeChromiumWrapper() {
|
|
4302
4317
|
mkdirSync(BIN_DIR, { recursive: true });
|
|
4303
|
-
const wrapperPath =
|
|
4318
|
+
const wrapperPath = resolve3(BIN_DIR, "chromium");
|
|
4304
4319
|
writeFileSync3(wrapperPath, `#!/bin/bash
|
|
4305
4320
|
LOG="${LOG_DIR}/chromium.log"
|
|
4306
4321
|
echo "==== [$(date)] chromium wrapper ====" >> "$LOG"
|
|
@@ -4400,20 +4415,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
|
|
|
4400
4415
|
|
|
4401
4416
|
// server/routes/health.ts
|
|
4402
4417
|
function checkPort(port2, timeoutMs = 500) {
|
|
4403
|
-
return new Promise((
|
|
4418
|
+
return new Promise((resolve30) => {
|
|
4404
4419
|
const socket = createConnection2(port2, "127.0.0.1");
|
|
4405
4420
|
socket.setTimeout(timeoutMs);
|
|
4406
4421
|
socket.once("connect", () => {
|
|
4407
4422
|
socket.destroy();
|
|
4408
|
-
|
|
4423
|
+
resolve30(true);
|
|
4409
4424
|
});
|
|
4410
4425
|
socket.once("error", () => {
|
|
4411
4426
|
socket.destroy();
|
|
4412
|
-
|
|
4427
|
+
resolve30(false);
|
|
4413
4428
|
});
|
|
4414
4429
|
socket.once("timeout", () => {
|
|
4415
4430
|
socket.destroy();
|
|
4416
|
-
|
|
4431
|
+
resolve30(false);
|
|
4417
4432
|
});
|
|
4418
4433
|
});
|
|
4419
4434
|
}
|
|
@@ -4483,9 +4498,9 @@ var health_default = app;
|
|
|
4483
4498
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
4484
4499
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
4485
4500
|
import { realpathSync } from "fs";
|
|
4486
|
-
import { resolve as
|
|
4487
|
-
var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ??
|
|
4488
|
-
var ATTACHMENTS_ROOT =
|
|
4501
|
+
import { resolve as resolve4, extname } from "path";
|
|
4502
|
+
var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve4(process.cwd(), "../platform");
|
|
4503
|
+
var ATTACHMENTS_ROOT = resolve4(PLATFORM_ROOT3, "..", "data/uploads");
|
|
4489
4504
|
var SUPPORTED_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
4490
4505
|
"image/jpeg",
|
|
4491
4506
|
"image/png",
|
|
@@ -4512,11 +4527,11 @@ function assertSupportedMime(mimeType) {
|
|
|
4512
4527
|
}
|
|
4513
4528
|
async function writeAttachment(scope, filename, mimeType, sizeBytes, buffer) {
|
|
4514
4529
|
const attachmentId = randomUUID3();
|
|
4515
|
-
const dir =
|
|
4530
|
+
const dir = resolve4(ATTACHMENTS_ROOT, scope, attachmentId);
|
|
4516
4531
|
await mkdir2(dir, { recursive: true });
|
|
4517
4532
|
const ext = extname(filename) || "";
|
|
4518
|
-
const storagePath =
|
|
4519
|
-
const metaPath =
|
|
4533
|
+
const storagePath = resolve4(dir, `${attachmentId}${ext}`);
|
|
4534
|
+
const metaPath = resolve4(dir, `${attachmentId}.meta.json`);
|
|
4520
4535
|
const meta = {
|
|
4521
4536
|
attachmentId,
|
|
4522
4537
|
scope,
|
|
@@ -4590,11 +4605,11 @@ async function storeComponentArtefact(accountId, attachmentId, mimeType, content
|
|
|
4590
4605
|
`Component artefact exceeds the 50 MB limit (${(buffer.byteLength / 1024 / 1024).toFixed(1)} MB).`
|
|
4591
4606
|
);
|
|
4592
4607
|
}
|
|
4593
|
-
const dir =
|
|
4608
|
+
const dir = resolve4(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
4594
4609
|
await mkdir2(dir, { recursive: true });
|
|
4595
4610
|
const ext = extname(filename) || (mimeType === "text/html" ? ".html" : ".md");
|
|
4596
|
-
const storagePath =
|
|
4597
|
-
const metaPath =
|
|
4611
|
+
const storagePath = resolve4(dir, `${attachmentId}${ext}`);
|
|
4612
|
+
const metaPath = resolve4(dir, `${attachmentId}.meta.json`);
|
|
4598
4613
|
const meta = {
|
|
4599
4614
|
attachmentId,
|
|
4600
4615
|
scope: accountId,
|
|
@@ -4611,7 +4626,7 @@ async function storeComponentArtefact(accountId, attachmentId, mimeType, content
|
|
|
4611
4626
|
// app/lib/stt/voice-note.ts
|
|
4612
4627
|
import { writeFile as writeFile3, mkdtemp, rm } from "fs/promises";
|
|
4613
4628
|
import { tmpdir } from "os";
|
|
4614
|
-
import { join as
|
|
4629
|
+
import { join as join4 } from "path";
|
|
4615
4630
|
var TAG14 = "[voice]";
|
|
4616
4631
|
var AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
4617
4632
|
"audio/ogg",
|
|
@@ -4655,9 +4670,9 @@ async function transcribeVoiceNote(file, source) {
|
|
|
4655
4670
|
let tempDir;
|
|
4656
4671
|
let tempPath;
|
|
4657
4672
|
try {
|
|
4658
|
-
tempDir = await mkdtemp(
|
|
4673
|
+
tempDir = await mkdtemp(join4(tmpdir(), "voice-"));
|
|
4659
4674
|
const ext = audioExtension(mimeType);
|
|
4660
|
-
tempPath =
|
|
4675
|
+
tempPath = join4(tempDir, `recording${ext}`);
|
|
4661
4676
|
const buffer = Buffer.from(await file.arrayBuffer());
|
|
4662
4677
|
await writeFile3(tempPath, buffer);
|
|
4663
4678
|
} catch (err) {
|
|
@@ -4698,7 +4713,7 @@ async function transcribeVoiceNote(file, source) {
|
|
|
4698
4713
|
}
|
|
4699
4714
|
|
|
4700
4715
|
// app/lib/channel-pty-bridge/bridge.ts
|
|
4701
|
-
import { resolve as
|
|
4716
|
+
import { resolve as resolve6 } from "path";
|
|
4702
4717
|
|
|
4703
4718
|
// app/lib/channel-pty-bridge/manager-client.ts
|
|
4704
4719
|
function managerBase() {
|
|
@@ -5150,7 +5165,7 @@ async function fanOut(subscribers, text, onError, tag) {
|
|
|
5150
5165
|
// app/lib/whatsapp/outbound/send-document.ts
|
|
5151
5166
|
import { realpathSync as realpathSync2 } from "fs";
|
|
5152
5167
|
import { readFile, stat as stat2 } from "fs/promises";
|
|
5153
|
-
import { resolve as
|
|
5168
|
+
import { resolve as resolve5, basename } from "path";
|
|
5154
5169
|
var TAG16 = "[whatsapp:outbound]";
|
|
5155
5170
|
var WHATSAPP_DOCUMENT_MAX_BYTES = 100 * 1024 * 1024;
|
|
5156
5171
|
var lastDocumentOutboundAt = /* @__PURE__ */ new Map();
|
|
@@ -5181,7 +5196,7 @@ async function sendWhatsAppDocument(input) {
|
|
|
5181
5196
|
if (!maxyAccountId || !platformRoot2) {
|
|
5182
5197
|
return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
|
|
5183
5198
|
}
|
|
5184
|
-
const accountDir =
|
|
5199
|
+
const accountDir = resolve5(platformRoot2, "..", "data/accounts", maxyAccountId);
|
|
5185
5200
|
let resolvedPath;
|
|
5186
5201
|
try {
|
|
5187
5202
|
resolvedPath = realpathSync2(filePath);
|
|
@@ -5388,7 +5403,7 @@ async function ensureEntry(input) {
|
|
|
5388
5403
|
});
|
|
5389
5404
|
} else {
|
|
5390
5405
|
console.error(`${tag} route role=${input.role} target=public-spawn senderId=${input.senderId}`);
|
|
5391
|
-
const attachmentDir =
|
|
5406
|
+
const attachmentDir = resolve6(ATTACHMENTS_ROOT, "public", input.senderId);
|
|
5392
5407
|
spawned = await managerSpawn({
|
|
5393
5408
|
senderId: input.senderId,
|
|
5394
5409
|
role: input.role,
|
|
@@ -5520,12 +5535,12 @@ async function dispatchOnce(input) {
|
|
|
5520
5535
|
});
|
|
5521
5536
|
if (!entry) return { error: "spawn-failed" };
|
|
5522
5537
|
entry.lastInboundAt = Date.now();
|
|
5523
|
-
let
|
|
5538
|
+
let resolve30;
|
|
5524
5539
|
const turnPromise = new Promise((r) => {
|
|
5525
|
-
|
|
5540
|
+
resolve30 = r;
|
|
5526
5541
|
});
|
|
5527
5542
|
const listener = (text) => {
|
|
5528
|
-
|
|
5543
|
+
resolve30(text);
|
|
5529
5544
|
};
|
|
5530
5545
|
entry.subscribers.add(listener);
|
|
5531
5546
|
const writeAtMs = Date.now();
|
|
@@ -5895,7 +5910,7 @@ ${result.result.text}` : result.result.text;
|
|
|
5895
5910
|
var chat_default = app2;
|
|
5896
5911
|
|
|
5897
5912
|
// server/routes/whatsapp.ts
|
|
5898
|
-
import { join as
|
|
5913
|
+
import { join as join7, resolve as resolve8 } from "path";
|
|
5899
5914
|
import { readdirSync as readdirSync3, readFileSync as readFileSync7, existsSync as existsSync5 } from "fs";
|
|
5900
5915
|
|
|
5901
5916
|
// app/lib/whatsapp/login.ts
|
|
@@ -5903,10 +5918,10 @@ import { randomUUID as randomUUID6 } from "crypto";
|
|
|
5903
5918
|
|
|
5904
5919
|
// app/lib/whatsapp/config-persist.ts
|
|
5905
5920
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync4 } from "fs";
|
|
5906
|
-
import { resolve as
|
|
5921
|
+
import { resolve as resolve7, join as join5 } from "path";
|
|
5907
5922
|
var TAG18 = "[whatsapp:config]";
|
|
5908
5923
|
function configPath(accountDir) {
|
|
5909
|
-
return
|
|
5924
|
+
return resolve7(accountDir, "account.json");
|
|
5910
5925
|
}
|
|
5911
5926
|
function readConfig(accountDir) {
|
|
5912
5927
|
const path2 = configPath(accountDir);
|
|
@@ -6055,7 +6070,7 @@ function setPublicAgent(accountDir, slug) {
|
|
|
6055
6070
|
if (!trimmed) {
|
|
6056
6071
|
return { ok: false, error: "Agent slug cannot be empty." };
|
|
6057
6072
|
}
|
|
6058
|
-
const agentConfigPath =
|
|
6073
|
+
const agentConfigPath = join5(accountDir, "agents", trimmed, "config.json");
|
|
6059
6074
|
if (!existsSync4(agentConfigPath)) {
|
|
6060
6075
|
return { ok: false, error: `Agent "${trimmed}" not found \u2014 no config.json at ${agentConfigPath}. Check the agent slug and try again.` };
|
|
6061
6076
|
}
|
|
@@ -6313,8 +6328,8 @@ async function startLogin(opts) {
|
|
|
6313
6328
|
await clearAuth(authDir);
|
|
6314
6329
|
let resolveCode = null;
|
|
6315
6330
|
let rejectCode = null;
|
|
6316
|
-
const codePromise = new Promise((
|
|
6317
|
-
resolveCode =
|
|
6331
|
+
const codePromise = new Promise((resolve30, reject) => {
|
|
6332
|
+
resolveCode = resolve30;
|
|
6318
6333
|
rejectCode = reject;
|
|
6319
6334
|
});
|
|
6320
6335
|
const codeTimer = setTimeout(
|
|
@@ -6546,11 +6561,11 @@ function serializeWhatsAppSchema() {
|
|
|
6546
6561
|
|
|
6547
6562
|
// app/lib/whatsapp/status-reconcile.ts
|
|
6548
6563
|
import { readdirSync as readdirSync2 } from "fs";
|
|
6549
|
-
import { join as
|
|
6564
|
+
import { join as join6 } from "path";
|
|
6550
6565
|
var TAG20 = "[whatsapp:reconcile]";
|
|
6551
6566
|
function listCredsAccountIds(credsRoot) {
|
|
6552
6567
|
try {
|
|
6553
|
-
return readdirSync2(credsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && hasCredsSync(
|
|
6568
|
+
return readdirSync2(credsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && hasCredsSync(join6(credsRoot, e.name))).map((e) => e.name);
|
|
6554
6569
|
} catch {
|
|
6555
6570
|
return [];
|
|
6556
6571
|
}
|
|
@@ -6565,7 +6580,7 @@ function reconcileCredsOnDisk(opts) {
|
|
|
6565
6580
|
const entries = [];
|
|
6566
6581
|
for (const accountId of listCredsAccountIds(credsRoot)) {
|
|
6567
6582
|
if (liveAccountIds.has(accountId)) continue;
|
|
6568
|
-
const authDir =
|
|
6583
|
+
const authDir = join6(credsRoot, accountId);
|
|
6569
6584
|
const selfPhone = readSelfId(authDir).e164 ?? void 0;
|
|
6570
6585
|
const configured = accountDir ? isAccountConfigured(accountDir, accountId) : false;
|
|
6571
6586
|
console.error(
|
|
@@ -6592,7 +6607,7 @@ app3.get("/status", (c) => {
|
|
|
6592
6607
|
try {
|
|
6593
6608
|
const live = getStatus();
|
|
6594
6609
|
const liveIds = new Set(live.map((a) => a.accountId));
|
|
6595
|
-
const credsRoot =
|
|
6610
|
+
const credsRoot = join7(MAXY_DIR, "credentials", "whatsapp");
|
|
6596
6611
|
const accountDir = resolveAccount()?.accountDir ?? null;
|
|
6597
6612
|
const reconciled = reconcileCredsOnDisk({ credsRoot, accountDir, liveAccountIds: liveIds });
|
|
6598
6613
|
const accounts = [...live, ...reconciled];
|
|
@@ -6613,7 +6628,7 @@ app3.post("/login/start", async (c) => {
|
|
|
6613
6628
|
if (!phone) {
|
|
6614
6629
|
return c.json({ error: 'Missing required field "phone" (E.164, e.g. +441234567890).' }, 400);
|
|
6615
6630
|
}
|
|
6616
|
-
const authDir =
|
|
6631
|
+
const authDir = join7(MAXY_DIR, "credentials", "whatsapp", accountId);
|
|
6617
6632
|
const accountDir = resolveAccount()?.accountDir ?? null;
|
|
6618
6633
|
const result = await startLogin({ accountId, authDir, phone, accountDir, force });
|
|
6619
6634
|
console.error(`${TAG21} login/start result account=${accountId} hasCode=${!!result.pairingCode}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
|
|
@@ -6711,14 +6726,14 @@ app3.post("/config", async (c) => {
|
|
|
6711
6726
|
return c.json({ ok: true, slug: resolved?.slug ?? null, source: resolved?.source ?? null });
|
|
6712
6727
|
}
|
|
6713
6728
|
case "list-public-agents": {
|
|
6714
|
-
const agentsDir =
|
|
6729
|
+
const agentsDir = resolve8(account.accountDir, "agents");
|
|
6715
6730
|
const agents = [];
|
|
6716
6731
|
if (existsSync5(agentsDir)) {
|
|
6717
6732
|
try {
|
|
6718
6733
|
const entries = readdirSync3(agentsDir, { withFileTypes: true });
|
|
6719
6734
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
6720
6735
|
if (!entry.isDirectory() || entry.name === "admin") continue;
|
|
6721
|
-
const configPath2 =
|
|
6736
|
+
const configPath2 = resolve8(agentsDir, entry.name, "config.json");
|
|
6722
6737
|
if (!existsSync5(configPath2)) continue;
|
|
6723
6738
|
try {
|
|
6724
6739
|
const config = JSON.parse(readFileSync7(configPath2, "utf-8"));
|
|
@@ -6991,11 +7006,11 @@ var whatsapp_default = app3;
|
|
|
6991
7006
|
|
|
6992
7007
|
// server/routes/whatsapp-reader.ts
|
|
6993
7008
|
import { readFileSync as readFileSync10, watch, statSync as statSync4, openSync, readSync, closeSync, existsSync as existsSync7, readdirSync as readdirSync6 } from "fs";
|
|
6994
|
-
import { basename as basename2, dirname, join as
|
|
7009
|
+
import { basename as basename2, dirname, join as join10, resolve as resolve10, sep as sep2 } from "path";
|
|
6995
7010
|
|
|
6996
7011
|
// server/routes/admin/sidebar-sessions.ts
|
|
6997
7012
|
import { readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
6998
|
-
import { join as
|
|
7013
|
+
import { join as join8, resolve as resolve9 } from "path";
|
|
6999
7014
|
var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/i;
|
|
7000
7015
|
var CLI_MARKER_PREFIXES = ["<local-command-", "<command-name>", "<command-message>"];
|
|
7001
7016
|
var PUBLIC_ROLE = "public";
|
|
@@ -7014,7 +7029,7 @@ function enumerateJsonls(projectsRoot) {
|
|
|
7014
7029
|
throw err;
|
|
7015
7030
|
}
|
|
7016
7031
|
for (const slug of slugs) {
|
|
7017
|
-
const slugDir =
|
|
7032
|
+
const slugDir = join8(projectsRoot, slug);
|
|
7018
7033
|
let entries;
|
|
7019
7034
|
try {
|
|
7020
7035
|
entries = readdirSync4(slugDir, { withFileTypes: true });
|
|
@@ -7025,9 +7040,9 @@ function enumerateJsonls(projectsRoot) {
|
|
|
7025
7040
|
}
|
|
7026
7041
|
for (const entry of entries) {
|
|
7027
7042
|
if (entry.isFile() && SESSION_ID_RE.test(entry.name)) {
|
|
7028
|
-
out.push({ path:
|
|
7043
|
+
out.push({ path: join8(slugDir, entry.name), isSubagent: false, archived: false });
|
|
7029
7044
|
} else if (entry.isDirectory() && entry.name === "subagents") {
|
|
7030
|
-
const subDir =
|
|
7045
|
+
const subDir = join8(slugDir, entry.name);
|
|
7031
7046
|
let subEntries;
|
|
7032
7047
|
try {
|
|
7033
7048
|
subEntries = readdirSync4(subDir, { withFileTypes: true });
|
|
@@ -7038,11 +7053,11 @@ function enumerateJsonls(projectsRoot) {
|
|
|
7038
7053
|
}
|
|
7039
7054
|
for (const sub of subEntries) {
|
|
7040
7055
|
if (sub.isFile() && SESSION_ID_RE.test(sub.name)) {
|
|
7041
|
-
out.push({ path:
|
|
7056
|
+
out.push({ path: join8(subDir, sub.name), isSubagent: true, archived: false });
|
|
7042
7057
|
}
|
|
7043
7058
|
}
|
|
7044
7059
|
} else if (entry.isDirectory() && entry.name === "archive") {
|
|
7045
|
-
const archiveDir =
|
|
7060
|
+
const archiveDir = join8(slugDir, entry.name);
|
|
7046
7061
|
let archiveEntries;
|
|
7047
7062
|
try {
|
|
7048
7063
|
archiveEntries = readdirSync4(archiveDir, { withFileTypes: true });
|
|
@@ -7053,7 +7068,7 @@ function enumerateJsonls(projectsRoot) {
|
|
|
7053
7068
|
}
|
|
7054
7069
|
for (const arc of archiveEntries) {
|
|
7055
7070
|
if (arc.isFile() && SESSION_ID_RE.test(arc.name)) {
|
|
7056
|
-
out.push({ path:
|
|
7071
|
+
out.push({ path: join8(archiveDir, arc.name), isSubagent: false, archived: true });
|
|
7057
7072
|
}
|
|
7058
7073
|
}
|
|
7059
7074
|
}
|
|
@@ -7086,7 +7101,7 @@ async function fetchLiveSessions() {
|
|
|
7086
7101
|
function loadUserTitles(accountDir) {
|
|
7087
7102
|
const out = /* @__PURE__ */ new Map();
|
|
7088
7103
|
if (!accountDir) return out;
|
|
7089
|
-
const path2 =
|
|
7104
|
+
const path2 = join8(accountDir, "session-titles.json");
|
|
7090
7105
|
let raw;
|
|
7091
7106
|
try {
|
|
7092
7107
|
raw = readFileSync8(path2, "utf8");
|
|
@@ -7183,10 +7198,10 @@ app4.get("/", requireAdminSession, async (c) => {
|
|
|
7183
7198
|
console.error("[admin-sessions-list] CLAUDE_CONFIG_DIR not set; returning empty list");
|
|
7184
7199
|
return c.json({ sessions: [], accountId });
|
|
7185
7200
|
}
|
|
7186
|
-
const projectsRoot =
|
|
7201
|
+
const projectsRoot = join8(configDir2, "projects");
|
|
7187
7202
|
const jsonls = enumerateJsonls(projectsRoot);
|
|
7188
7203
|
const liveSessions = await fetchLiveSessions();
|
|
7189
|
-
const accountDir = accountId ?
|
|
7204
|
+
const accountDir = accountId ? resolve9(ACCOUNTS_DIR, accountId) : null;
|
|
7190
7205
|
const userTitles = loadUserTitles(accountDir);
|
|
7191
7206
|
const rows = [];
|
|
7192
7207
|
const seenIds = /* @__PURE__ */ new Set();
|
|
@@ -7217,7 +7232,7 @@ app4.get("/", requireAdminSession, async (c) => {
|
|
|
7217
7232
|
const pid = live ? liveSessions.get(sessionId) ?? null : null;
|
|
7218
7233
|
const resolved = resolveTitle(body, sessionId, userTitles);
|
|
7219
7234
|
titleSourceCounts[resolved.source] += 1;
|
|
7220
|
-
const metaPath =
|
|
7235
|
+
const metaPath = join8(projectDir, `${sessionId}.meta.json`);
|
|
7221
7236
|
const { bridgeIds, role, channel } = readSidecarMeta(metaPath);
|
|
7222
7237
|
const resumable = !(role === PUBLIC_ROLE && channel === WEBCHAT_CHANNEL);
|
|
7223
7238
|
rows.push({
|
|
@@ -7264,7 +7279,7 @@ function selectAdminChannelSessions(rows) {
|
|
|
7264
7279
|
// app/lib/admin-identity/pin-validator.ts
|
|
7265
7280
|
import { createHash as createHash2 } from "crypto";
|
|
7266
7281
|
import { existsSync as existsSync6, readFileSync as readFileSync9, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
|
|
7267
|
-
import { join as
|
|
7282
|
+
import { join as join9 } from "path";
|
|
7268
7283
|
function hashPin(pin) {
|
|
7269
7284
|
return createHash2("sha256").update(pin).digest("hex");
|
|
7270
7285
|
}
|
|
@@ -7298,13 +7313,13 @@ function scanForOrphanedAccountAdmins(users, accountsDir) {
|
|
|
7298
7313
|
}
|
|
7299
7314
|
for (const entry of entries) {
|
|
7300
7315
|
if (entry.startsWith(".")) continue;
|
|
7301
|
-
const accountDir =
|
|
7316
|
+
const accountDir = join9(accountsDir, entry);
|
|
7302
7317
|
try {
|
|
7303
7318
|
if (!statSync3(accountDir).isDirectory()) continue;
|
|
7304
7319
|
} catch {
|
|
7305
7320
|
continue;
|
|
7306
7321
|
}
|
|
7307
|
-
const accountJsonPath =
|
|
7322
|
+
const accountJsonPath = join9(accountDir, "account.json");
|
|
7308
7323
|
if (!existsSync6(accountJsonPath)) continue;
|
|
7309
7324
|
try {
|
|
7310
7325
|
const config = JSON.parse(readFileSync9(accountJsonPath, "utf-8"));
|
|
@@ -7484,13 +7499,13 @@ var app5 = new Hono();
|
|
|
7484
7499
|
app5.get("/conversations", requireAdminSession, async (c) => {
|
|
7485
7500
|
const cfg = claudeConfigDir();
|
|
7486
7501
|
if (!cfg) return c.json({ conversations: [] });
|
|
7487
|
-
const projectsRoot =
|
|
7502
|
+
const projectsRoot = join10(cfg, "projects");
|
|
7488
7503
|
const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
|
|
7489
7504
|
const rows = [];
|
|
7490
7505
|
for (const { path: path2 } of enumerateJsonls(projectsRoot)) {
|
|
7491
7506
|
const sessionId = basename2(path2).replace(/\.jsonl$/, "");
|
|
7492
7507
|
const projectDir = dirname(path2);
|
|
7493
|
-
const meta = readSidecarMeta(
|
|
7508
|
+
const meta = readSidecarMeta(join10(projectDir, `${sessionId}.meta.json`));
|
|
7494
7509
|
if (meta.role !== "admin" || meta.channel !== "whatsapp" && meta.channel !== "telegram") continue;
|
|
7495
7510
|
let body = "";
|
|
7496
7511
|
try {
|
|
@@ -7577,11 +7592,11 @@ app5.get("/stream", requireAdminSession, (c) => {
|
|
|
7577
7592
|
const sessionId = c.req.query("sessionId") ?? "";
|
|
7578
7593
|
const projectDir = c.req.query("projectDir") ?? "";
|
|
7579
7594
|
const cfg = claudeConfigDir();
|
|
7580
|
-
const projectsRoot = cfg ?
|
|
7595
|
+
const projectsRoot = cfg ? resolve10(join10(cfg, "projects")) : null;
|
|
7581
7596
|
if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
|
|
7582
7597
|
return c.json({ error: "bad session reference" }, 400);
|
|
7583
7598
|
}
|
|
7584
|
-
const jsonlPath =
|
|
7599
|
+
const jsonlPath = resolve10(join10(projectDir, `${sessionId}.jsonl`));
|
|
7585
7600
|
if (!jsonlPath.startsWith(projectsRoot + sep2)) {
|
|
7586
7601
|
return c.json({ error: "bad session reference" }, 400);
|
|
7587
7602
|
}
|
|
@@ -7668,7 +7683,7 @@ var DIRECTIVE_NAME_RE = /^\d+-\d+\.txt$/;
|
|
|
7668
7683
|
function directiveStoreDir(sessionId) {
|
|
7669
7684
|
const account = resolveAccount();
|
|
7670
7685
|
if (!account) return null;
|
|
7671
|
-
return
|
|
7686
|
+
return resolve10(account.accountDir, "logs", "prompt-optimiser-directives", sessionId);
|
|
7672
7687
|
}
|
|
7673
7688
|
app5.get("/directives", requireAdminSession, (c) => {
|
|
7674
7689
|
const sessionId = c.req.query("sessionId") ?? "";
|
|
@@ -7687,7 +7702,7 @@ app5.get("/directives", requireAdminSession, (c) => {
|
|
|
7687
7702
|
const pid = Number(pidPart);
|
|
7688
7703
|
let len = 0;
|
|
7689
7704
|
try {
|
|
7690
|
-
len = statSync4(
|
|
7705
|
+
len = statSync4(join10(dir, name)).size;
|
|
7691
7706
|
} catch {
|
|
7692
7707
|
}
|
|
7693
7708
|
return { name, secs, pid, ts: Number.isFinite(secs) ? new Date(secs * 1e3).toISOString() : null, len };
|
|
@@ -7702,7 +7717,7 @@ app5.get("/directive", requireAdminSession, (c) => {
|
|
|
7702
7717
|
}
|
|
7703
7718
|
const dir = directiveStoreDir(sessionId);
|
|
7704
7719
|
if (!dir) return c.json({ error: "no account" }, 404);
|
|
7705
|
-
const path2 =
|
|
7720
|
+
const path2 = resolve10(join10(dir, name));
|
|
7706
7721
|
if (!path2.startsWith(dir + sep2)) return c.json({ error: "bad reference" }, 400);
|
|
7707
7722
|
let body;
|
|
7708
7723
|
try {
|
|
@@ -7716,17 +7731,17 @@ var whatsapp_reader_default = app5;
|
|
|
7716
7731
|
|
|
7717
7732
|
// server/routes/webchat.ts
|
|
7718
7733
|
import { basename as basename3, dirname as dirname2 } from "path";
|
|
7719
|
-
import { join as
|
|
7734
|
+
import { join as join11 } from "path";
|
|
7720
7735
|
import { readFileSync as readFileSync11, renameSync, writeFileSync as writeFileSync5 } from "fs";
|
|
7721
7736
|
var WEBCHAT_ADMIN_KEY = "webchat-admin";
|
|
7722
7737
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
7723
7738
|
function locateSession(sessionId) {
|
|
7724
7739
|
const cfg = claudeConfigDir();
|
|
7725
7740
|
if (!cfg) return { projectDir: null, channel: null };
|
|
7726
|
-
for (const { path: path2 } of enumerateJsonls(
|
|
7741
|
+
for (const { path: path2 } of enumerateJsonls(join11(cfg, "projects"))) {
|
|
7727
7742
|
if (basename3(path2) === `${sessionId}.jsonl`) {
|
|
7728
7743
|
const dir = dirname2(path2);
|
|
7729
|
-
const meta = readSidecarMeta(
|
|
7744
|
+
const meta = readSidecarMeta(join11(dir, `${sessionId}.meta.json`));
|
|
7730
7745
|
return { projectDir: dir, channel: meta.channel };
|
|
7731
7746
|
}
|
|
7732
7747
|
}
|
|
@@ -7772,19 +7787,22 @@ async function fetchComposerIndicators(sessionId) {
|
|
|
7772
7787
|
}
|
|
7773
7788
|
var MODEL_ID_PATTERN = /^claude-[a-z0-9][a-z0-9.-]*(\[1m\])?$/;
|
|
7774
7789
|
var EFFORT_LEVELS = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh"]);
|
|
7790
|
+
var PERMISSION_MODE_VALUES = /* @__PURE__ */ new Set(["default", "acceptEdits", "plan", "auto", "bypassPermissions"]);
|
|
7775
7791
|
function readLevers() {
|
|
7776
7792
|
let account;
|
|
7777
7793
|
try {
|
|
7778
7794
|
account = resolveAccount();
|
|
7779
7795
|
} catch {
|
|
7780
|
-
return { leverModel: null, leverEffort: null };
|
|
7796
|
+
return { leverModel: null, leverEffort: null, leverMode: null };
|
|
7781
7797
|
}
|
|
7782
|
-
if (!account) return { leverModel: null, leverEffort: null };
|
|
7798
|
+
if (!account) return { leverModel: null, leverEffort: null, leverMode: null };
|
|
7783
7799
|
const model = account.config.adminModel;
|
|
7784
7800
|
const effort = account.config.effort;
|
|
7801
|
+
const mode = account.config.adminPermissionMode;
|
|
7785
7802
|
return {
|
|
7786
7803
|
leverModel: typeof model === "string" && MODEL_ID_PATTERN.test(model) ? model : null,
|
|
7787
|
-
leverEffort: typeof effort === "string" && EFFORT_LEVELS.has(effort) ? effort : null
|
|
7804
|
+
leverEffort: typeof effort === "string" && EFFORT_LEVELS.has(effort) ? effort : null,
|
|
7805
|
+
leverMode: typeof mode === "string" && PERMISSION_MODE_VALUES.has(mode) ? mode : null
|
|
7788
7806
|
};
|
|
7789
7807
|
}
|
|
7790
7808
|
var REAPPLY_TIMEOUT_MS = 1500;
|
|
@@ -7937,11 +7955,11 @@ ${note}` : note;
|
|
|
7937
7955
|
const body = await c.req.json().catch(() => null);
|
|
7938
7956
|
const op = body?.op;
|
|
7939
7957
|
const value = body?.value;
|
|
7940
|
-
if (op !== "model" && op !== "effort") {
|
|
7958
|
+
if (op !== "model" && op !== "effort" && op !== "mode") {
|
|
7941
7959
|
console.error(`[webchat:settings] op=${String(op)} outcome=refused reason=unknown-op`);
|
|
7942
|
-
return c.json({ error: "op must be model or
|
|
7960
|
+
return c.json({ error: "op must be model, effort, or mode" }, 400);
|
|
7943
7961
|
}
|
|
7944
|
-
if (typeof value !== "string" || op === "model" && !MODEL_ID_PATTERN.test(value) || op === "effort" && !EFFORT_LEVELS.has(value)) {
|
|
7962
|
+
if (typeof value !== "string" || op === "model" && !MODEL_ID_PATTERN.test(value) || op === "effort" && !EFFORT_LEVELS.has(value) || op === "mode" && !PERMISSION_MODE_VALUES.has(value)) {
|
|
7945
7963
|
console.error(`[webchat:settings] op=${op} outcome=refused value=${JSON.stringify(value)} reason=invalid-value`);
|
|
7946
7964
|
return c.json({ error: `invalid ${op} value` }, 400);
|
|
7947
7965
|
}
|
|
@@ -7955,11 +7973,12 @@ ${note}` : note;
|
|
|
7955
7973
|
console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-unresolved`);
|
|
7956
7974
|
return c.json({ error: "account unresolved" }, 503);
|
|
7957
7975
|
}
|
|
7958
|
-
const accountJsonPath =
|
|
7976
|
+
const accountJsonPath = join11(account.accountDir, "account.json");
|
|
7959
7977
|
try {
|
|
7960
7978
|
const parsed = JSON.parse(readFileSync11(accountJsonPath, "utf8"));
|
|
7961
7979
|
if (op === "model") parsed.adminModel = value;
|
|
7962
|
-
else parsed.effort = value;
|
|
7980
|
+
else if (op === "effort") parsed.effort = value;
|
|
7981
|
+
else parsed.adminPermissionMode = value;
|
|
7963
7982
|
const tmp = `${accountJsonPath}.${process.pid}.tmp`;
|
|
7964
7983
|
writeFileSync5(tmp, JSON.stringify(parsed, null, 2), "utf8");
|
|
7965
7984
|
renameSync(tmp, accountJsonPath);
|
|
@@ -7994,7 +8013,7 @@ ${note}` : note;
|
|
|
7994
8013
|
const cfg = claudeConfigDir();
|
|
7995
8014
|
let projectDir = null;
|
|
7996
8015
|
if (cfg) {
|
|
7997
|
-
for (const { path: path2 } of enumerateJsonls(
|
|
8016
|
+
for (const { path: path2 } of enumerateJsonls(join11(cfg, "projects"))) {
|
|
7998
8017
|
if (basename3(path2) === `${sessionId}.jsonl`) {
|
|
7999
8018
|
projectDir = dirname2(path2);
|
|
8000
8019
|
break;
|
|
@@ -8008,11 +8027,11 @@ ${note}` : note;
|
|
|
8008
8027
|
}
|
|
8009
8028
|
|
|
8010
8029
|
// server/routes/webchat-greeting.ts
|
|
8011
|
-
import { resolve as
|
|
8030
|
+
import { resolve as resolve11 } from "path";
|
|
8012
8031
|
|
|
8013
8032
|
// app/lib/claude-agent/specialist-roster.ts
|
|
8014
8033
|
import { existsSync as existsSync8, readFileSync as readFileSync12, readdirSync as readdirSync7 } from "fs";
|
|
8015
|
-
import { join as
|
|
8034
|
+
import { join as join12 } from "path";
|
|
8016
8035
|
function field(fm, name) {
|
|
8017
8036
|
const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
|
|
8018
8037
|
if (!m) return null;
|
|
@@ -8031,7 +8050,7 @@ function readSpecialistRoster(specialistsDir) {
|
|
|
8031
8050
|
if (!file.endsWith(".md")) continue;
|
|
8032
8051
|
let raw;
|
|
8033
8052
|
try {
|
|
8034
|
-
raw = readFileSync12(
|
|
8053
|
+
raw = readFileSync12(join12(specialistsDir, file), "utf-8");
|
|
8035
8054
|
} catch (err) {
|
|
8036
8055
|
skipped.push({ file, reason: err instanceof Error ? err.message : String(err) });
|
|
8037
8056
|
continue;
|
|
@@ -8113,7 +8132,7 @@ app6.get("/", requireAdminSession, async (c) => {
|
|
|
8113
8132
|
let specialists = [];
|
|
8114
8133
|
try {
|
|
8115
8134
|
const roster = readSpecialistRoster(
|
|
8116
|
-
|
|
8135
|
+
resolve11(ACCOUNTS_DIR, accountId, "specialists", "agents")
|
|
8117
8136
|
);
|
|
8118
8137
|
specialists = roster.specialists;
|
|
8119
8138
|
for (const s of roster.skipped) {
|
|
@@ -8148,7 +8167,7 @@ var webchat_greeting_default = app6;
|
|
|
8148
8167
|
|
|
8149
8168
|
// server/routes/telegram.ts
|
|
8150
8169
|
import { homedir } from "os";
|
|
8151
|
-
import { resolve as
|
|
8170
|
+
import { resolve as resolve12, join as join13 } from "path";
|
|
8152
8171
|
import { existsSync as existsSync9, readFileSync as readFileSync13 } from "fs";
|
|
8153
8172
|
|
|
8154
8173
|
// app/lib/telegram/access-control.ts
|
|
@@ -8199,8 +8218,8 @@ function routeTelegramUpdate(input) {
|
|
|
8199
8218
|
var TAG22 = "[telegram-inbound]";
|
|
8200
8219
|
var DISPATCH_TIMEOUT_MS = 12e4;
|
|
8201
8220
|
function configDirName() {
|
|
8202
|
-
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ??
|
|
8203
|
-
const brandPath =
|
|
8221
|
+
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve12(process.cwd(), "..");
|
|
8222
|
+
const brandPath = join13(platformRoot2, "config", "brand.json");
|
|
8204
8223
|
if (existsSync9(brandPath)) {
|
|
8205
8224
|
try {
|
|
8206
8225
|
return JSON.parse(readFileSync13(brandPath, "utf-8")).configDir ?? ".maxy";
|
|
@@ -8211,7 +8230,7 @@ function configDirName() {
|
|
|
8211
8230
|
}
|
|
8212
8231
|
function secretPath(botType) {
|
|
8213
8232
|
const filename = botType === "admin" ? ".telegram-admin-webhook-secret" : ".telegram-webhook-secret";
|
|
8214
|
-
return
|
|
8233
|
+
return resolve12(homedir(), configDirName(), filename);
|
|
8215
8234
|
}
|
|
8216
8235
|
async function sendTelegram(botToken, chatId, text) {
|
|
8217
8236
|
try {
|
|
@@ -8307,7 +8326,7 @@ import { createHash as createHash3, randomUUID as randomUUID7 } from "crypto";
|
|
|
8307
8326
|
|
|
8308
8327
|
// ../lib/admins-write/src/index.ts
|
|
8309
8328
|
import { existsSync as existsSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync6, renameSync as renameSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync8, statSync as statSync5 } from "fs";
|
|
8310
|
-
import { dirname as dirname3, join as
|
|
8329
|
+
import { dirname as dirname3, join as join14 } from "path";
|
|
8311
8330
|
function logLine(input, result) {
|
|
8312
8331
|
const userIdShort = input.userId.slice(0, 8);
|
|
8313
8332
|
console.error(
|
|
@@ -8349,7 +8368,7 @@ function writeAdminEntry(input) {
|
|
|
8349
8368
|
return result;
|
|
8350
8369
|
}
|
|
8351
8370
|
try {
|
|
8352
|
-
const accountJsonPath =
|
|
8371
|
+
const accountJsonPath = join14(input.accountDir, "account.json");
|
|
8353
8372
|
if (!existsSync10(accountJsonPath)) {
|
|
8354
8373
|
throw new Error(`account.json not found at ${accountJsonPath}`);
|
|
8355
8374
|
}
|
|
@@ -8404,13 +8423,13 @@ function checkAdminAuthInvariant(input) {
|
|
|
8404
8423
|
}
|
|
8405
8424
|
for (const entry of entries) {
|
|
8406
8425
|
if (entry.startsWith(".")) continue;
|
|
8407
|
-
const accountDir =
|
|
8426
|
+
const accountDir = join14(input.accountsDir, entry);
|
|
8408
8427
|
try {
|
|
8409
8428
|
if (!statSync5(accountDir).isDirectory()) continue;
|
|
8410
8429
|
} catch {
|
|
8411
8430
|
continue;
|
|
8412
8431
|
}
|
|
8413
|
-
const accountJsonPath =
|
|
8432
|
+
const accountJsonPath = join14(accountDir, "account.json");
|
|
8414
8433
|
if (!existsSync10(accountJsonPath)) continue;
|
|
8415
8434
|
let admins = [];
|
|
8416
8435
|
try {
|
|
@@ -8699,8 +8718,8 @@ var onboarding_default = app8;
|
|
|
8699
8718
|
|
|
8700
8719
|
// server/routes/client-error.ts
|
|
8701
8720
|
import { appendFileSync, existsSync as existsSync12, renameSync as renameSync3, statSync as statSync6 } from "fs";
|
|
8702
|
-
import { join as
|
|
8703
|
-
var CLIENT_ERRORS_LOG =
|
|
8721
|
+
import { join as join15 } from "path";
|
|
8722
|
+
var CLIENT_ERRORS_LOG = join15(LOG_DIR, "client-errors.log");
|
|
8704
8723
|
var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
8705
8724
|
var MAX_BODY_SIZE = 8 * 1024;
|
|
8706
8725
|
var MAX_STACK_LEN = 2e3;
|
|
@@ -9026,16 +9045,16 @@ var session_default = app10;
|
|
|
9026
9045
|
|
|
9027
9046
|
// server/routes/admin/logs.ts
|
|
9028
9047
|
import { existsSync as existsSync14, readdirSync as readdirSync9, readFileSync as readFileSync16, statSync as statSync7 } from "fs";
|
|
9029
|
-
import { resolve as
|
|
9048
|
+
import { resolve as resolve13, basename as basename4 } from "path";
|
|
9030
9049
|
|
|
9031
9050
|
// app/lib/logs-read-resolve.ts
|
|
9032
9051
|
import { existsSync as existsSync13 } from "fs";
|
|
9033
|
-
import { join as
|
|
9052
|
+
import { join as join16 } from "path";
|
|
9034
9053
|
function resolveSessionLogPaths(filename, logDirs) {
|
|
9035
9054
|
const tried = [filename];
|
|
9036
9055
|
const hits = [];
|
|
9037
9056
|
for (const dir of logDirs) {
|
|
9038
|
-
const fullPath =
|
|
9057
|
+
const fullPath = join16(dir, filename);
|
|
9039
9058
|
if (existsSync13(fullPath)) {
|
|
9040
9059
|
hits.push({ path: fullPath, dir });
|
|
9041
9060
|
}
|
|
@@ -9053,7 +9072,7 @@ app11.get("/", async (c) => {
|
|
|
9053
9072
|
const cacheKeyParam = c.req.query("cacheKey");
|
|
9054
9073
|
const download = c.req.query("download") === "1";
|
|
9055
9074
|
const account = resolveAccount();
|
|
9056
|
-
const accountLogDir = account ?
|
|
9075
|
+
const accountLogDir = account ? resolve13(account.accountDir, "logs") : null;
|
|
9057
9076
|
const logDirs = [];
|
|
9058
9077
|
if (accountLogDir) logDirs.push(accountLogDir);
|
|
9059
9078
|
logDirs.push(LOG_DIR);
|
|
@@ -9061,7 +9080,7 @@ app11.get("/", async (c) => {
|
|
|
9061
9080
|
const safe = basename4(fileParam);
|
|
9062
9081
|
const searched = [];
|
|
9063
9082
|
for (const dir of logDirs) {
|
|
9064
|
-
const filePath =
|
|
9083
|
+
const filePath = resolve13(dir, safe);
|
|
9065
9084
|
searched.push(filePath);
|
|
9066
9085
|
try {
|
|
9067
9086
|
const buffer = readFileSync16(filePath);
|
|
@@ -9173,10 +9192,10 @@ app11.get("/", async (c) => {
|
|
|
9173
9192
|
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
9174
9193
|
continue;
|
|
9175
9194
|
}
|
|
9176
|
-
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync7(
|
|
9195
|
+
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync7(resolve13(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
9177
9196
|
seen.add(name);
|
|
9178
9197
|
try {
|
|
9179
|
-
const content = readFileSync16(
|
|
9198
|
+
const content = readFileSync16(resolve13(dir, name));
|
|
9180
9199
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
9181
9200
|
logs[name] = tail.trim() || "(empty)";
|
|
9182
9201
|
} catch (err) {
|
|
@@ -9216,7 +9235,7 @@ var claude_info_default = app12;
|
|
|
9216
9235
|
// server/routes/admin/attachment.ts
|
|
9217
9236
|
import { readFile as readFile2, readdir } from "fs/promises";
|
|
9218
9237
|
import { existsSync as existsSync15 } from "fs";
|
|
9219
|
-
import { resolve as
|
|
9238
|
+
import { resolve as resolve14 } from "path";
|
|
9220
9239
|
var app13 = new Hono();
|
|
9221
9240
|
app13.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
9222
9241
|
const attachmentId = c.req.param("attachmentId");
|
|
@@ -9228,11 +9247,11 @@ app13.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
9228
9247
|
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(attachmentId)) {
|
|
9229
9248
|
return new Response("Not found", { status: 404 });
|
|
9230
9249
|
}
|
|
9231
|
-
const dir =
|
|
9250
|
+
const dir = resolve14(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
9232
9251
|
if (!existsSync15(dir)) {
|
|
9233
9252
|
return new Response("Not found", { status: 404 });
|
|
9234
9253
|
}
|
|
9235
|
-
const metaPath =
|
|
9254
|
+
const metaPath = resolve14(dir, `${attachmentId}.meta.json`);
|
|
9236
9255
|
if (!existsSync15(metaPath)) {
|
|
9237
9256
|
return new Response("Not found", { status: 404 });
|
|
9238
9257
|
}
|
|
@@ -9247,7 +9266,7 @@ app13.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
9247
9266
|
if (!dataFile) {
|
|
9248
9267
|
return new Response("Not found", { status: 404 });
|
|
9249
9268
|
}
|
|
9250
|
-
const filePath =
|
|
9269
|
+
const filePath = resolve14(dir, dataFile);
|
|
9251
9270
|
const buffer = await readFile2(filePath);
|
|
9252
9271
|
return new Response(new Uint8Array(buffer), {
|
|
9253
9272
|
headers: {
|
|
@@ -9260,13 +9279,13 @@ app13.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
9260
9279
|
var attachment_default = app13;
|
|
9261
9280
|
|
|
9262
9281
|
// server/routes/admin/agents.ts
|
|
9263
|
-
import { resolve as
|
|
9282
|
+
import { resolve as resolve15 } from "path";
|
|
9264
9283
|
import { readdirSync as readdirSync10, readFileSync as readFileSync17, existsSync as existsSync16, rmSync } from "fs";
|
|
9265
9284
|
var app14 = new Hono();
|
|
9266
9285
|
app14.get("/", (c) => {
|
|
9267
9286
|
const account = resolveAccount();
|
|
9268
9287
|
if (!account) return c.json({ agents: [] });
|
|
9269
|
-
const agentsDir =
|
|
9288
|
+
const agentsDir = resolve15(account.accountDir, "agents");
|
|
9270
9289
|
if (!existsSync16(agentsDir)) return c.json({ agents: [] });
|
|
9271
9290
|
const agents = [];
|
|
9272
9291
|
try {
|
|
@@ -9274,7 +9293,7 @@ app14.get("/", (c) => {
|
|
|
9274
9293
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
9275
9294
|
if (!entry.isDirectory()) continue;
|
|
9276
9295
|
if (entry.name === "admin") continue;
|
|
9277
|
-
const configPath2 =
|
|
9296
|
+
const configPath2 = resolve15(agentsDir, entry.name, "config.json");
|
|
9278
9297
|
if (!existsSync16(configPath2)) continue;
|
|
9279
9298
|
try {
|
|
9280
9299
|
const config = JSON.parse(readFileSync17(configPath2, "utf-8"));
|
|
@@ -9303,7 +9322,7 @@ app14.delete("/:slug", async (c) => {
|
|
|
9303
9322
|
if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
|
|
9304
9323
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
9305
9324
|
}
|
|
9306
|
-
const agentDir =
|
|
9325
|
+
const agentDir = resolve15(account.accountDir, "agents", slug);
|
|
9307
9326
|
if (!existsSync16(agentDir)) {
|
|
9308
9327
|
return c.json({ error: "Agent not found" }, 404);
|
|
9309
9328
|
}
|
|
@@ -9333,7 +9352,7 @@ app14.post("/:slug/project", async (c) => {
|
|
|
9333
9352
|
if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
|
|
9334
9353
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
9335
9354
|
}
|
|
9336
|
-
const agentDir =
|
|
9355
|
+
const agentDir = resolve15(account.accountDir, "agents", slug);
|
|
9337
9356
|
if (!existsSync16(agentDir)) {
|
|
9338
9357
|
return c.json({ error: "Agent not found on disk" }, 404);
|
|
9339
9358
|
}
|
|
@@ -10037,7 +10056,7 @@ var sessions_default = app15;
|
|
|
10037
10056
|
|
|
10038
10057
|
// app/lib/claude-agent/spawn-context.ts
|
|
10039
10058
|
import { existsSync as existsSync18, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync8 } from "fs";
|
|
10040
|
-
import { dirname as dirname4, resolve as
|
|
10059
|
+
import { dirname as dirname4, resolve as resolve16, join as join17 } from "path";
|
|
10041
10060
|
async function resolveOwnerProfileBlock(accountId, userId) {
|
|
10042
10061
|
if (!userId) return { ok: false, reason: "missing-user-id" };
|
|
10043
10062
|
try {
|
|
@@ -10066,8 +10085,8 @@ function frontmatterField(manifest, field2) {
|
|
|
10066
10085
|
function extractPluginToolDescriptions(pluginDir) {
|
|
10067
10086
|
const out = /* @__PURE__ */ new Map();
|
|
10068
10087
|
const candidates = [
|
|
10069
|
-
|
|
10070
|
-
|
|
10088
|
+
join17(pluginDir, "mcp/dist/index.js"),
|
|
10089
|
+
join17(pluginDir, "mcp/src/index.ts")
|
|
10071
10090
|
];
|
|
10072
10091
|
let raw = null;
|
|
10073
10092
|
for (const path2 of candidates) {
|
|
@@ -10122,24 +10141,24 @@ function parseSkillPathsFromFrontmatter(fm) {
|
|
|
10122
10141
|
}
|
|
10123
10142
|
function listPluginDirs() {
|
|
10124
10143
|
const out = /* @__PURE__ */ new Map();
|
|
10125
|
-
const platformPlugins =
|
|
10144
|
+
const platformPlugins = resolve16(PLATFORM_ROOT, "plugins");
|
|
10126
10145
|
if (existsSync18(platformPlugins)) {
|
|
10127
10146
|
for (const name of readdirSync11(platformPlugins)) {
|
|
10128
|
-
const dir =
|
|
10147
|
+
const dir = join17(platformPlugins, name);
|
|
10129
10148
|
try {
|
|
10130
10149
|
if (statSync8(dir).isDirectory()) out.set(name, dir);
|
|
10131
10150
|
} catch {
|
|
10132
10151
|
}
|
|
10133
10152
|
}
|
|
10134
10153
|
}
|
|
10135
|
-
const premiumRoot =
|
|
10154
|
+
const premiumRoot = resolve16(dirname4(PLATFORM_ROOT), "premium-plugins");
|
|
10136
10155
|
if (existsSync18(premiumRoot)) {
|
|
10137
10156
|
for (const bundle of readdirSync11(premiumRoot)) {
|
|
10138
|
-
const bundlePlugins =
|
|
10157
|
+
const bundlePlugins = join17(premiumRoot, bundle, "plugins");
|
|
10139
10158
|
if (!existsSync18(bundlePlugins)) continue;
|
|
10140
10159
|
try {
|
|
10141
10160
|
for (const name of readdirSync11(bundlePlugins)) {
|
|
10142
|
-
const dir =
|
|
10161
|
+
const dir = join17(bundlePlugins, name);
|
|
10143
10162
|
try {
|
|
10144
10163
|
if (statSync8(dir).isDirectory()) out.set(name, dir);
|
|
10145
10164
|
} catch {
|
|
@@ -10152,7 +10171,7 @@ function listPluginDirs() {
|
|
|
10152
10171
|
return out;
|
|
10153
10172
|
}
|
|
10154
10173
|
function readEnabledPlugins(accountId) {
|
|
10155
|
-
const accountFile =
|
|
10174
|
+
const accountFile = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
|
|
10156
10175
|
if (!existsSync18(accountFile)) return /* @__PURE__ */ new Set();
|
|
10157
10176
|
try {
|
|
10158
10177
|
const parsed = JSON.parse(readFileSync18(accountFile, "utf-8"));
|
|
@@ -10182,7 +10201,7 @@ function computeActivePlugins(accountId) {
|
|
|
10182
10201
|
for (const name of Array.from(enabled).sort()) {
|
|
10183
10202
|
const dir = pluginDirs.get(name);
|
|
10184
10203
|
if (!dir) continue;
|
|
10185
|
-
const fm = readFrontmatter(
|
|
10204
|
+
const fm = readFrontmatter(join17(dir, "PLUGIN.md"));
|
|
10186
10205
|
if (!fm) continue;
|
|
10187
10206
|
const description = frontmatterField(`---
|
|
10188
10207
|
${fm}
|
|
@@ -10199,7 +10218,7 @@ ${fm}
|
|
|
10199
10218
|
`plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
|
|
10200
10219
|
);
|
|
10201
10220
|
if (toolNames.length > 0 && descMap.size === 0) {
|
|
10202
|
-
const hasSource = existsSync18(
|
|
10221
|
+
const hasSource = existsSync18(join17(dir, "mcp/dist/index.js")) || existsSync18(join17(dir, "mcp/src/index.ts"));
|
|
10203
10222
|
if (hasSource) {
|
|
10204
10223
|
console.warn(
|
|
10205
10224
|
`[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
|
|
@@ -10209,7 +10228,7 @@ ${fm}
|
|
|
10209
10228
|
const skillPaths = parseSkillPathsFromFrontmatter(fm);
|
|
10210
10229
|
const skills = [];
|
|
10211
10230
|
for (const relPath of skillPaths) {
|
|
10212
|
-
const skillPath =
|
|
10231
|
+
const skillPath = join17(dir, relPath);
|
|
10213
10232
|
const skillFm = readFrontmatter(skillPath);
|
|
10214
10233
|
if (!skillFm) continue;
|
|
10215
10234
|
const skillName = frontmatterField(`---
|
|
@@ -10225,7 +10244,7 @@ ${skillFm}
|
|
|
10225
10244
|
return out;
|
|
10226
10245
|
}
|
|
10227
10246
|
function computeSpecialistDomains(accountId) {
|
|
10228
|
-
const specialistsDir =
|
|
10247
|
+
const specialistsDir = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
|
|
10229
10248
|
if (!existsSync18(specialistsDir)) return [];
|
|
10230
10249
|
let entries;
|
|
10231
10250
|
try {
|
|
@@ -10253,7 +10272,7 @@ function computeSpecialistDomains(accountId) {
|
|
|
10253
10272
|
const out = [];
|
|
10254
10273
|
for (const file of entries.sort()) {
|
|
10255
10274
|
if (!file.endsWith(".md")) continue;
|
|
10256
|
-
const fm = readFrontmatter(
|
|
10275
|
+
const fm = readFrontmatter(join17(specialistsDir, file));
|
|
10257
10276
|
if (!fm) continue;
|
|
10258
10277
|
const wrapped = `---
|
|
10259
10278
|
${fm}
|
|
@@ -10271,7 +10290,7 @@ ${fm}
|
|
|
10271
10290
|
return out;
|
|
10272
10291
|
}
|
|
10273
10292
|
function computeDormantPlugins(accountId) {
|
|
10274
|
-
const accountFile =
|
|
10293
|
+
const accountFile = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
|
|
10275
10294
|
if (!existsSync18(accountFile)) return [];
|
|
10276
10295
|
let enabled;
|
|
10277
10296
|
try {
|
|
@@ -10286,7 +10305,7 @@ function computeDormantPlugins(accountId) {
|
|
|
10286
10305
|
);
|
|
10287
10306
|
return [];
|
|
10288
10307
|
}
|
|
10289
|
-
const pluginsDir =
|
|
10308
|
+
const pluginsDir = resolve16(PLATFORM_ROOT, "plugins");
|
|
10290
10309
|
if (!existsSync18(pluginsDir)) return [];
|
|
10291
10310
|
let entries;
|
|
10292
10311
|
try {
|
|
@@ -10297,7 +10316,7 @@ function computeDormantPlugins(accountId) {
|
|
|
10297
10316
|
const out = [];
|
|
10298
10317
|
for (const name of entries) {
|
|
10299
10318
|
if (enabled.has(name)) continue;
|
|
10300
|
-
const manifestPath =
|
|
10319
|
+
const manifestPath = resolve16(pluginsDir, name, "PLUGIN.md");
|
|
10301
10320
|
if (!existsSync18(manifestPath)) continue;
|
|
10302
10321
|
let manifest;
|
|
10303
10322
|
try {
|
|
@@ -10316,7 +10335,7 @@ function computeDormantPlugins(accountId) {
|
|
|
10316
10335
|
|
|
10317
10336
|
// server/routes/admin/claude-sessions.ts
|
|
10318
10337
|
import { existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
|
|
10319
|
-
import { resolve as
|
|
10338
|
+
import { resolve as resolve17 } from "path";
|
|
10320
10339
|
function readTunnelState(brandConfigDir) {
|
|
10321
10340
|
const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
|
|
10322
10341
|
if (!existsSync19(statePath)) return null;
|
|
@@ -10332,10 +10351,10 @@ function readTunnelState(brandConfigDir) {
|
|
|
10332
10351
|
}
|
|
10333
10352
|
}
|
|
10334
10353
|
function resolveTunnelUrl() {
|
|
10335
|
-
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ??
|
|
10354
|
+
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve17(process.cwd(), "..");
|
|
10336
10355
|
let brand;
|
|
10337
10356
|
try {
|
|
10338
|
-
brand = JSON.parse(readFileSync19(
|
|
10357
|
+
brand = JSON.parse(readFileSync19(resolve17(platformRoot2, "config", "brand.json"), "utf-8"));
|
|
10339
10358
|
} catch {
|
|
10340
10359
|
return null;
|
|
10341
10360
|
}
|
|
@@ -10580,15 +10599,15 @@ var events_default = app18;
|
|
|
10580
10599
|
import { createReadStream as createReadStream2 } from "fs";
|
|
10581
10600
|
import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
|
|
10582
10601
|
import { realpathSync as realpathSync4 } from "fs";
|
|
10583
|
-
import { basename as basename6, dirname as dirname5, join as
|
|
10602
|
+
import { basename as basename6, dirname as dirname5, join as join19, resolve as resolve20, sep as sep5 } from "path";
|
|
10584
10603
|
import { Readable as Readable2 } from "stream";
|
|
10585
10604
|
|
|
10586
10605
|
// app/lib/data-path.ts
|
|
10587
10606
|
import { realpathSync as realpathSync3 } from "fs";
|
|
10588
|
-
import { resolve as
|
|
10589
|
-
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ??
|
|
10590
|
-
var DATA_ROOT =
|
|
10591
|
-
var CLAUDE_UPLOADS_ROOT = process.env.CLAUDE_CONFIG_DIR ?
|
|
10607
|
+
import { resolve as resolve18, normalize, sep as sep3, relative } from "path";
|
|
10608
|
+
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "../platform");
|
|
10609
|
+
var DATA_ROOT = resolve18(PLATFORM_ROOT5, "..", "data");
|
|
10610
|
+
var CLAUDE_UPLOADS_ROOT = process.env.CLAUDE_CONFIG_DIR ? resolve18(process.env.CLAUDE_CONFIG_DIR, "uploads") : null;
|
|
10592
10611
|
var ACCOUNT_PARTITION_DIRS = /* @__PURE__ */ new Set(["uploads", "accounts"]);
|
|
10593
10612
|
var ACCOUNT_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
10594
10613
|
function crossesForeignAccountPartition(relPath, accountId) {
|
|
@@ -10601,7 +10620,7 @@ function crossesForeignAccountPartition(relPath, accountId) {
|
|
|
10601
10620
|
}
|
|
10602
10621
|
function resolveUnderRoot(raw, rootAbs, rootLabel) {
|
|
10603
10622
|
const cleaned = normalize("/" + (raw ?? "").replace(/\\/g, "/")).replace(/^\/+/, "");
|
|
10604
|
-
const absolute =
|
|
10623
|
+
const absolute = resolve18(rootAbs, cleaned);
|
|
10605
10624
|
let rootReal;
|
|
10606
10625
|
try {
|
|
10607
10626
|
rootReal = realpathSync3(rootAbs);
|
|
@@ -10960,7 +10979,7 @@ async function cascadeDeleteDocument(params) {
|
|
|
10960
10979
|
|
|
10961
10980
|
// app/lib/file-index.ts
|
|
10962
10981
|
import * as fsp from "fs/promises";
|
|
10963
|
-
import { resolve as
|
|
10982
|
+
import { resolve as resolve19, relative as relative2, join as join18, basename as basename5, extname as extname2, sep as sep4 } from "path";
|
|
10964
10983
|
import { tmpdir as tmpdir2 } from "os";
|
|
10965
10984
|
import { execFile as execFile2 } from "child_process";
|
|
10966
10985
|
import { promisify as promisify2 } from "util";
|
|
@@ -11031,7 +11050,7 @@ async function extractPdf(absolute) {
|
|
|
11031
11050
|
return stdout.trim();
|
|
11032
11051
|
}
|
|
11033
11052
|
async function ocrPdf(absolute) {
|
|
11034
|
-
const outPdf =
|
|
11053
|
+
const outPdf = join18(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
|
|
11035
11054
|
try {
|
|
11036
11055
|
await execFileAsync2(
|
|
11037
11056
|
"ocrmypdf",
|
|
@@ -11093,7 +11112,7 @@ async function readDisplayName(absolute) {
|
|
|
11093
11112
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
11094
11113
|
if (base === `${stem}.meta.json`) return null;
|
|
11095
11114
|
try {
|
|
11096
|
-
const raw = await fsp.readFile(
|
|
11115
|
+
const raw = await fsp.readFile(join18(dir, `${stem}.meta.json`), "utf-8");
|
|
11097
11116
|
const meta = JSON.parse(raw);
|
|
11098
11117
|
const dn = meta.displayName ?? meta.filename;
|
|
11099
11118
|
return typeof dn === "string" && dn.length > 0 ? dn : null;
|
|
@@ -11113,7 +11132,7 @@ async function walkSubtree(root, dataRoot, out) {
|
|
|
11113
11132
|
let clean = true;
|
|
11114
11133
|
for (const entry of entries) {
|
|
11115
11134
|
if (entry.isSymbolicLink()) continue;
|
|
11116
|
-
const abs =
|
|
11135
|
+
const abs = join18(root, entry.name);
|
|
11117
11136
|
if (entry.isDirectory()) {
|
|
11118
11137
|
const sub = await walkSubtree(abs, dataRoot, out);
|
|
11119
11138
|
if (!sub.clean) clean = false;
|
|
@@ -11268,8 +11287,8 @@ async function reconcileFileIndex(accountId, opts) {
|
|
|
11268
11287
|
return withSession(opts, async (session) => {
|
|
11269
11288
|
const walked = [];
|
|
11270
11289
|
const subtreeRoots = [
|
|
11271
|
-
|
|
11272
|
-
|
|
11290
|
+
resolve19(dataRoot, "uploads", accountId),
|
|
11291
|
+
resolve19(dataRoot, "accounts", accountId)
|
|
11273
11292
|
];
|
|
11274
11293
|
let clean = true;
|
|
11275
11294
|
for (const root of subtreeRoots) {
|
|
@@ -11350,7 +11369,7 @@ async function reconcileFileIndexDebounced(accountId, opts) {
|
|
|
11350
11369
|
async function indexFile(accountId, relativePath, opts) {
|
|
11351
11370
|
const dataRoot = opts?.dataRoot ?? DATA_ROOT;
|
|
11352
11371
|
const embed2 = opts?.embed ?? embed;
|
|
11353
|
-
const absolute =
|
|
11372
|
+
const absolute = resolve19(dataRoot, relativePath);
|
|
11354
11373
|
await withSession(opts, async (session) => {
|
|
11355
11374
|
const st = await fsp.stat(absolute);
|
|
11356
11375
|
const wf = {
|
|
@@ -11384,7 +11403,7 @@ async function dropFileIndex(accountId, relativePath, opts) {
|
|
|
11384
11403
|
var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
11385
11404
|
async function readMeta(absDir, baseName) {
|
|
11386
11405
|
try {
|
|
11387
|
-
const raw = await readFile4(
|
|
11406
|
+
const raw = await readFile4(join19(absDir, `${baseName}.meta.json`), "utf8");
|
|
11388
11407
|
const parsed = JSON.parse(raw);
|
|
11389
11408
|
if (typeof parsed?.filename === "string") {
|
|
11390
11409
|
return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
|
|
@@ -11395,7 +11414,7 @@ async function readMeta(absDir, baseName) {
|
|
|
11395
11414
|
}
|
|
11396
11415
|
async function readAccountNames() {
|
|
11397
11416
|
const map = /* @__PURE__ */ new Map();
|
|
11398
|
-
const accountsDir =
|
|
11417
|
+
const accountsDir = resolve20(DATA_ROOT, "accounts");
|
|
11399
11418
|
let names;
|
|
11400
11419
|
try {
|
|
11401
11420
|
names = await readdir3(accountsDir);
|
|
@@ -11404,7 +11423,7 @@ async function readAccountNames() {
|
|
|
11404
11423
|
}
|
|
11405
11424
|
for (const name of names) {
|
|
11406
11425
|
if (!UUID_RE3.test(name)) continue;
|
|
11407
|
-
const configPath2 =
|
|
11426
|
+
const configPath2 = resolve20(accountsDir, name, "account.json");
|
|
11408
11427
|
try {
|
|
11409
11428
|
const raw = await readFile4(configPath2, "utf8");
|
|
11410
11429
|
const parsed = JSON.parse(raw);
|
|
@@ -11422,7 +11441,7 @@ async function readAccountNames() {
|
|
|
11422
11441
|
}
|
|
11423
11442
|
async function enrich(absolute, entry, accountNames) {
|
|
11424
11443
|
if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
|
|
11425
|
-
const meta = await readMeta(
|
|
11444
|
+
const meta = await readMeta(join19(absolute, entry.name), entry.name);
|
|
11426
11445
|
if (meta?.filename) {
|
|
11427
11446
|
entry.displayName = meta.filename;
|
|
11428
11447
|
entry.mimeType = meta.mimeType;
|
|
@@ -11520,7 +11539,7 @@ app19.get("/", requireAdminSession, async (c) => {
|
|
|
11520
11539
|
continue;
|
|
11521
11540
|
}
|
|
11522
11541
|
try {
|
|
11523
|
-
const entryPath =
|
|
11542
|
+
const entryPath = join19(absolute, name);
|
|
11524
11543
|
const s = await stat4(entryPath);
|
|
11525
11544
|
entries.push({
|
|
11526
11545
|
name,
|
|
@@ -11645,8 +11664,8 @@ app19.post("/upload", requireAdminSession, async (c) => {
|
|
|
11645
11664
|
}
|
|
11646
11665
|
const safeName = basename6(file.name).replace(/[\0/\\]/g, "_");
|
|
11647
11666
|
const finalName = `${Date.now()}-${safeName}`;
|
|
11648
|
-
const destDir =
|
|
11649
|
-
const destPath =
|
|
11667
|
+
const destDir = resolve20(DATA_ROOT, "uploads", accountId);
|
|
11668
|
+
const destPath = resolve20(destDir, finalName);
|
|
11650
11669
|
try {
|
|
11651
11670
|
await mkdir3(destDir, { recursive: true });
|
|
11652
11671
|
const dataRootReal = realpathSync4(DATA_ROOT);
|
|
@@ -11711,7 +11730,7 @@ app19.delete("/", requireAdminSession, async (c) => {
|
|
|
11711
11730
|
}
|
|
11712
11731
|
const dot = base.lastIndexOf(".");
|
|
11713
11732
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
11714
|
-
const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ?
|
|
11733
|
+
const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join19(dirname5(absolute), `${stem}.meta.json`) : null;
|
|
11715
11734
|
await unlink2(absolute);
|
|
11716
11735
|
if (sidecarPath) {
|
|
11717
11736
|
try {
|
|
@@ -13760,7 +13779,7 @@ var graph_default_view_default = app25;
|
|
|
13760
13779
|
|
|
13761
13780
|
// server/routes/admin/sidebar-artefacts.ts
|
|
13762
13781
|
import { readdir as readdir4, stat as stat5 } from "fs/promises";
|
|
13763
|
-
import { resolve as
|
|
13782
|
+
import { resolve as resolve21, relative as relative3, isAbsolute, sep as sep6, basename as basename7 } from "path";
|
|
13764
13783
|
import { existsSync as existsSync20 } from "fs";
|
|
13765
13784
|
var LIMIT = 50;
|
|
13766
13785
|
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
@@ -13780,7 +13799,7 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
13780
13799
|
if (accountFiles === null) {
|
|
13781
13800
|
return c.json({ error: "Failed to load artefacts" }, 500);
|
|
13782
13801
|
}
|
|
13783
|
-
const accountDir =
|
|
13802
|
+
const accountDir = resolve21(ACCOUNTS_DIR, accountId);
|
|
13784
13803
|
const agents = await fetchAgentTemplateRows(accountDir);
|
|
13785
13804
|
const artefacts = [...accountFiles, ...agents].sort(
|
|
13786
13805
|
(a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
|
|
@@ -13831,8 +13850,8 @@ async function fetchAccountFileArtefacts(accountId) {
|
|
|
13831
13850
|
async function fetchAgentTemplateRows(accountDir) {
|
|
13832
13851
|
const rows = [];
|
|
13833
13852
|
for (const filename of ADMIN_AGENT_FILES) {
|
|
13834
|
-
const overridePath =
|
|
13835
|
-
const bundledPath =
|
|
13853
|
+
const overridePath = resolve21(accountDir, "agents", "admin", filename);
|
|
13854
|
+
const bundledPath = resolve21(PLATFORM_ROOT, "templates", "agents", "admin", filename);
|
|
13836
13855
|
const labelStem = filename.replace(/\.md$/, "");
|
|
13837
13856
|
const row = await readAgentTemplateRow({
|
|
13838
13857
|
id: `agent-template:admin:${filename}`,
|
|
@@ -13845,12 +13864,12 @@ async function fetchAgentTemplateRows(accountDir) {
|
|
|
13845
13864
|
});
|
|
13846
13865
|
if (row) rows.push(row);
|
|
13847
13866
|
}
|
|
13848
|
-
const overrideDir =
|
|
13849
|
-
const bundledDir =
|
|
13867
|
+
const overrideDir = resolve21(accountDir, "specialists", "agents");
|
|
13868
|
+
const bundledDir = resolve21(PLATFORM_ROOT, "templates", "specialists", "agents");
|
|
13850
13869
|
const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
|
|
13851
13870
|
for (const filename of specialistNames) {
|
|
13852
|
-
const overridePath =
|
|
13853
|
-
const bundledPath =
|
|
13871
|
+
const overridePath = resolve21(overrideDir, filename);
|
|
13872
|
+
const bundledPath = resolve21(bundledDir, filename);
|
|
13854
13873
|
const row = await readAgentTemplateRow({
|
|
13855
13874
|
id: `agent-template:specialist:${filename}`,
|
|
13856
13875
|
displayName: filename.replace(/\.md$/, ""),
|
|
@@ -14058,6 +14077,36 @@ app29.post("/", requireAdminSession, async (c) => {
|
|
|
14058
14077
|
var session_archive_default = app29;
|
|
14059
14078
|
|
|
14060
14079
|
// server/routes/admin/session-rc-spawn.ts
|
|
14080
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
14081
|
+
function resolveSpawnPlan(host, body, mintId = randomUUID9) {
|
|
14082
|
+
const operator = isOperatorHost(host);
|
|
14083
|
+
const resumeId = typeof body.sessionId === "string" && body.sessionId.length > 0 ? body.sessionId : void 0;
|
|
14084
|
+
const name = typeof body.name === "string" && body.name.length > 0 ? body.name : void 0;
|
|
14085
|
+
const webchatBind = resumeId === void 0 || operator;
|
|
14086
|
+
const kind = resumeId === void 0 ? "new" : "resume";
|
|
14087
|
+
const origin = operator ? "operator" : "admin";
|
|
14088
|
+
const payload = {};
|
|
14089
|
+
let sessionId;
|
|
14090
|
+
if (webchatBind) {
|
|
14091
|
+
sessionId = resumeId ?? mintId();
|
|
14092
|
+
const key = `session:${sessionId}`;
|
|
14093
|
+
payload.sessionId = sessionId;
|
|
14094
|
+
payload.role = "admin";
|
|
14095
|
+
payload.channel = "webchat";
|
|
14096
|
+
payload.senderId = key;
|
|
14097
|
+
payload.webchatChannel = webchatChannelDescriptor(key);
|
|
14098
|
+
if (name) payload.name = name;
|
|
14099
|
+
} else {
|
|
14100
|
+
sessionId = resumeId;
|
|
14101
|
+
payload.sessionId = resumeId;
|
|
14102
|
+
if (name) payload.name = name;
|
|
14103
|
+
}
|
|
14104
|
+
return { webchatBind, origin, kind, sessionId, payload };
|
|
14105
|
+
}
|
|
14106
|
+
function shapeWebchatResponse(sessionId, manager) {
|
|
14107
|
+
const outcome = typeof manager?.outcome === "string" ? manager.outcome : "bound";
|
|
14108
|
+
return { sessionId, outcome, target: `/chat?session=${sessionId}` };
|
|
14109
|
+
}
|
|
14061
14110
|
var app30 = new Hono();
|
|
14062
14111
|
app30.post("/", requireAdminSession, async (c) => {
|
|
14063
14112
|
let body;
|
|
@@ -14066,19 +14115,26 @@ app30.post("/", requireAdminSession, async (c) => {
|
|
|
14066
14115
|
} catch {
|
|
14067
14116
|
body = {};
|
|
14068
14117
|
}
|
|
14069
|
-
const
|
|
14070
|
-
|
|
14071
|
-
|
|
14118
|
+
const host = c.req.header("host") ?? "";
|
|
14119
|
+
const plan = resolveSpawnPlan(host, body);
|
|
14120
|
+
const spawnReqId = randomUUID9();
|
|
14121
|
+
console.log(
|
|
14122
|
+
`[chat-spawn] op=request spawnReqId=${spawnReqId} origin=${plan.origin} kind=${plan.kind} sessionId=${plan.kind === "new" ? "new" : plan.sessionId}`
|
|
14123
|
+
);
|
|
14124
|
+
if (plan.webchatBind) {
|
|
14125
|
+
console.log(`[chat-spawn] op=args spawnReqId=${spawnReqId} webchatChannel=present sessionId=${plan.sessionId}`);
|
|
14126
|
+
}
|
|
14072
14127
|
let res;
|
|
14073
14128
|
try {
|
|
14074
14129
|
res = await fetch(`${managerBase3("session-rc-spawn:wrapper")}/rc-spawn`, {
|
|
14075
14130
|
method: "POST",
|
|
14076
14131
|
headers: { "content-type": "application/json" },
|
|
14077
|
-
body: JSON.stringify(payload)
|
|
14132
|
+
body: JSON.stringify(plan.payload)
|
|
14078
14133
|
});
|
|
14079
14134
|
} catch (err) {
|
|
14080
14135
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14081
14136
|
console.error(`[session-rc-spawn] manager-unreachable err=${msg}`);
|
|
14137
|
+
console.log(`[chat-spawn] op=exit spawnReqId=${spawnReqId} outcome=spawn-failed`);
|
|
14082
14138
|
return c.json({ error: `session manager unreachable: ${msg}` }, 502);
|
|
14083
14139
|
}
|
|
14084
14140
|
const text = await res.text();
|
|
@@ -14089,8 +14145,18 @@ app30.post("/", requireAdminSession, async (c) => {
|
|
|
14089
14145
|
}
|
|
14090
14146
|
if (!res.ok) {
|
|
14091
14147
|
console.error(`[session-rc-spawn] manager-error status=${res.status} body=${text.slice(0, 200)}`);
|
|
14148
|
+
console.log(`[chat-spawn] op=exit spawnReqId=${spawnReqId} outcome=spawn-failed`);
|
|
14092
14149
|
return c.json(parsed ?? { error: text }, res.status);
|
|
14093
14150
|
}
|
|
14151
|
+
if (plan.webchatBind) {
|
|
14152
|
+
const target = `/chat?session=${plan.sessionId}`;
|
|
14153
|
+
console.log(
|
|
14154
|
+
`[chat-spawn] op=acquired spawnReqId=${spawnReqId} pid=${parsed?.spawnedPid ?? "none"} sessionId=${plan.sessionId}`
|
|
14155
|
+
);
|
|
14156
|
+
console.log(`[chat-spawn] op=navigate spawnReqId=${spawnReqId} target=${target}`);
|
|
14157
|
+
console.log(`[chat-spawn] op=exit spawnReqId=${spawnReqId} outcome=bound`);
|
|
14158
|
+
return c.json(shapeWebchatResponse(plan.sessionId, parsed));
|
|
14159
|
+
}
|
|
14094
14160
|
return c.json(parsed ?? {});
|
|
14095
14161
|
});
|
|
14096
14162
|
var session_rc_spawn_default = app30;
|
|
@@ -14218,10 +14284,10 @@ var system_stats_default = app31;
|
|
|
14218
14284
|
|
|
14219
14285
|
// server/routes/admin/health.ts
|
|
14220
14286
|
import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
|
|
14221
|
-
import { resolve as
|
|
14222
|
-
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ??
|
|
14287
|
+
import { resolve as resolve22, join as join20 } from "path";
|
|
14288
|
+
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve22(process.cwd(), "..");
|
|
14223
14289
|
var brandHostname = "maxy";
|
|
14224
|
-
var brandJsonPath =
|
|
14290
|
+
var brandJsonPath = join20(PLATFORM_ROOT6, "config", "brand.json");
|
|
14225
14291
|
if (existsSync21(brandJsonPath)) {
|
|
14226
14292
|
try {
|
|
14227
14293
|
const brand = JSON.parse(readFileSync20(brandJsonPath, "utf-8"));
|
|
@@ -14229,7 +14295,7 @@ if (existsSync21(brandJsonPath)) {
|
|
|
14229
14295
|
} catch {
|
|
14230
14296
|
}
|
|
14231
14297
|
}
|
|
14232
|
-
var VERSION_FILE =
|
|
14298
|
+
var VERSION_FILE = resolve22(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
|
|
14233
14299
|
var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
14234
14300
|
var PROBE_TIMEOUT_MS = 1e3;
|
|
14235
14301
|
function readVersion() {
|
|
@@ -14285,7 +14351,7 @@ app32.get("/", async (c) => {
|
|
|
14285
14351
|
var health_default2 = app32;
|
|
14286
14352
|
|
|
14287
14353
|
// server/routes/admin/linkedin-ingest.ts
|
|
14288
|
-
import { randomUUID as
|
|
14354
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
14289
14355
|
var TAG25 = "[linkedin-ingest-route]";
|
|
14290
14356
|
var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
14291
14357
|
var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
@@ -14411,7 +14477,7 @@ app33.post("/", requireAdminSession, async (c) => {
|
|
|
14411
14477
|
);
|
|
14412
14478
|
const initialMessage = buildInitialMessage(envelope);
|
|
14413
14479
|
const spawnStart = Date.now();
|
|
14414
|
-
const sessionId =
|
|
14480
|
+
const sessionId = randomUUID10();
|
|
14415
14481
|
console.log(TAG25 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
|
|
14416
14482
|
const spawned = await managerRcSpawn({
|
|
14417
14483
|
sessionId,
|
|
@@ -14777,13 +14843,13 @@ var admin_default = app39;
|
|
|
14777
14843
|
// app/lib/access-gate.ts
|
|
14778
14844
|
import neo4j4 from "neo4j-driver";
|
|
14779
14845
|
import { readFileSync as readFileSync21 } from "fs";
|
|
14780
|
-
import { resolve as
|
|
14781
|
-
import { randomUUID as
|
|
14782
|
-
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ??
|
|
14846
|
+
import { resolve as resolve23 } from "path";
|
|
14847
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
14848
|
+
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve23(process.cwd(), "..");
|
|
14783
14849
|
var driver = null;
|
|
14784
14850
|
function readPassword() {
|
|
14785
14851
|
if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
|
|
14786
|
-
const passwordFile =
|
|
14852
|
+
const passwordFile = resolve23(PLATFORM_ROOT7, "config/.neo4j-password");
|
|
14787
14853
|
try {
|
|
14788
14854
|
return readFileSync21(passwordFile, "utf-8").trim();
|
|
14789
14855
|
} catch {
|
|
@@ -14961,7 +15027,7 @@ async function consumeMagicTokenAndActivate(grantId) {
|
|
|
14961
15027
|
}
|
|
14962
15028
|
}
|
|
14963
15029
|
async function generateNewMagicToken(grantId) {
|
|
14964
|
-
const token =
|
|
15030
|
+
const token = randomUUID11();
|
|
14965
15031
|
const session = getSession3();
|
|
14966
15032
|
try {
|
|
14967
15033
|
const result = await session.run(
|
|
@@ -15073,9 +15139,9 @@ var verify_token_default = app40;
|
|
|
15073
15139
|
|
|
15074
15140
|
// app/lib/access-email.ts
|
|
15075
15141
|
import { spawn as spawn2 } from "child_process";
|
|
15076
|
-
import { resolve as
|
|
15077
|
-
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ??
|
|
15078
|
-
var SEND_SCRIPT =
|
|
15142
|
+
import { resolve as resolve24 } from "path";
|
|
15143
|
+
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
|
|
15144
|
+
var SEND_SCRIPT = resolve24(
|
|
15079
15145
|
PLATFORM_ROOT8,
|
|
15080
15146
|
"plugins",
|
|
15081
15147
|
"email",
|
|
@@ -15218,7 +15284,7 @@ var access_default = app42;
|
|
|
15218
15284
|
|
|
15219
15285
|
// server/routes/sites.ts
|
|
15220
15286
|
import { existsSync as existsSync22, readFileSync as readFileSync22, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
|
|
15221
|
-
import { resolve as
|
|
15287
|
+
import { resolve as resolve25 } from "path";
|
|
15222
15288
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
15223
15289
|
var MIME = {
|
|
15224
15290
|
".html": "text/html; charset=utf-8",
|
|
@@ -15275,8 +15341,8 @@ app43.get("/:rel{.*}", (c) => {
|
|
|
15275
15341
|
}
|
|
15276
15342
|
segments.push(seg);
|
|
15277
15343
|
}
|
|
15278
|
-
const rootDir =
|
|
15279
|
-
let filePath = segments.length === 0 ? rootDir :
|
|
15344
|
+
const rootDir = resolve25(account.accountDir, "sites");
|
|
15345
|
+
let filePath = segments.length === 0 ? rootDir : resolve25(rootDir, ...segments);
|
|
15280
15346
|
if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
|
|
15281
15347
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
15282
15348
|
return c.text("Forbidden", 403);
|
|
@@ -15296,7 +15362,7 @@ app43.get("/:rel{.*}", (c) => {
|
|
|
15296
15362
|
return c.redirect(target, 301);
|
|
15297
15363
|
}
|
|
15298
15364
|
if (stat7?.isDirectory()) {
|
|
15299
|
-
filePath =
|
|
15365
|
+
filePath = resolve25(filePath, "index.html");
|
|
15300
15366
|
}
|
|
15301
15367
|
if (!filePath.startsWith(rootDir + "/")) {
|
|
15302
15368
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
@@ -15434,7 +15500,7 @@ var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
|
|
|
15434
15500
|
|
|
15435
15501
|
// app/lib/brand-config.ts
|
|
15436
15502
|
import { existsSync as existsSync23, readFileSync as readFileSync24 } from "fs";
|
|
15437
|
-
import { join as
|
|
15503
|
+
import { join as join21 } from "path";
|
|
15438
15504
|
var cached2 = null;
|
|
15439
15505
|
var cachedAttempted = false;
|
|
15440
15506
|
function readBrandConfig() {
|
|
@@ -15442,7 +15508,7 @@ function readBrandConfig() {
|
|
|
15442
15508
|
cachedAttempted = true;
|
|
15443
15509
|
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
|
|
15444
15510
|
if (!platformRoot2) return null;
|
|
15445
|
-
const brandPath =
|
|
15511
|
+
const brandPath = join21(platformRoot2, "config", "brand.json");
|
|
15446
15512
|
if (!existsSync23(brandPath)) return null;
|
|
15447
15513
|
try {
|
|
15448
15514
|
cached2 = JSON.parse(readFileSync24(brandPath, "utf-8"));
|
|
@@ -15933,14 +15999,14 @@ async function writeEvent(opts) {
|
|
|
15933
15999
|
var visitor_event_default = app46;
|
|
15934
16000
|
|
|
15935
16001
|
// server/routes/session.ts
|
|
15936
|
-
import { resolve as
|
|
16002
|
+
import { resolve as resolve26 } from "path";
|
|
15937
16003
|
import { existsSync as existsSync24, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5 } from "fs";
|
|
15938
16004
|
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
15939
16005
|
function writeBrandingCache(accountId, agentSlug, branding) {
|
|
15940
16006
|
try {
|
|
15941
|
-
const cacheDir =
|
|
16007
|
+
const cacheDir = resolve26(MAXY_DIR, "branding-cache", accountId);
|
|
15942
16008
|
mkdirSync5(cacheDir, { recursive: true });
|
|
15943
|
-
writeFileSync9(
|
|
16009
|
+
writeFileSync9(resolve26(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
|
|
15944
16010
|
} catch (err) {
|
|
15945
16011
|
console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
15946
16012
|
}
|
|
@@ -16028,8 +16094,8 @@ app47.post("/", async (c) => {
|
|
|
16028
16094
|
}
|
|
16029
16095
|
let agentConfig = null;
|
|
16030
16096
|
if (account) {
|
|
16031
|
-
const agentDir =
|
|
16032
|
-
if (!existsSync24(agentDir) || !existsSync24(
|
|
16097
|
+
const agentDir = resolve26(account.accountDir, "agents", agentSlug);
|
|
16098
|
+
if (!existsSync24(agentDir) || !existsSync24(resolve26(agentDir, "config.json"))) {
|
|
16033
16099
|
return c.json({ error: "Agent not found" }, 404);
|
|
16034
16100
|
}
|
|
16035
16101
|
agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
|
|
@@ -16309,7 +16375,7 @@ function startGraphHealthTimer() {
|
|
|
16309
16375
|
|
|
16310
16376
|
// app/lib/file-watcher.ts
|
|
16311
16377
|
import * as fsp2 from "fs/promises";
|
|
16312
|
-
import { resolve as
|
|
16378
|
+
import { resolve as resolve27, sep as sep7 } from "path";
|
|
16313
16379
|
var ACCOUNT_UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
16314
16380
|
var DEFAULT_COALESCE_MS = 500;
|
|
16315
16381
|
var ROOTS = ["uploads", "accounts"];
|
|
@@ -16328,7 +16394,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
16328
16394
|
const dropFn = opts.drop ?? dropFileIndex;
|
|
16329
16395
|
for (const r of ROOTS) {
|
|
16330
16396
|
try {
|
|
16331
|
-
await fsp2.mkdir(
|
|
16397
|
+
await fsp2.mkdir(resolve27(dataRoot, r), { recursive: true });
|
|
16332
16398
|
} catch (err) {
|
|
16333
16399
|
console.error(
|
|
16334
16400
|
`[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
|
|
@@ -16349,7 +16415,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
16349
16415
|
timers.set(relativePath, t);
|
|
16350
16416
|
}
|
|
16351
16417
|
async function runHook(relativePath, accountId) {
|
|
16352
|
-
const absolute =
|
|
16418
|
+
const absolute = resolve27(dataRoot, relativePath);
|
|
16353
16419
|
let exists = false;
|
|
16354
16420
|
try {
|
|
16355
16421
|
const st = await fsp2.stat(absolute);
|
|
@@ -16373,7 +16439,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
16373
16439
|
}
|
|
16374
16440
|
}
|
|
16375
16441
|
async function watchRoot(rootName) {
|
|
16376
|
-
const absRoot =
|
|
16442
|
+
const absRoot = resolve27(dataRoot, rootName);
|
|
16377
16443
|
try {
|
|
16378
16444
|
const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
|
|
16379
16445
|
for await (const event of iter) {
|
|
@@ -17268,7 +17334,7 @@ function broadcastAdminShutdown(reason) {
|
|
|
17268
17334
|
// ../lib/entitlement/src/index.ts
|
|
17269
17335
|
import { createPublicKey, createHash as createHash5, verify as cryptoVerify } from "crypto";
|
|
17270
17336
|
import { existsSync as existsSync25, readFileSync as readFileSync25, statSync as statSync10 } from "fs";
|
|
17271
|
-
import { resolve as
|
|
17337
|
+
import { resolve as resolve28 } from "path";
|
|
17272
17338
|
|
|
17273
17339
|
// ../lib/entitlement/src/canonicalize.ts
|
|
17274
17340
|
function canonicalize(value) {
|
|
@@ -17303,7 +17369,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
|
|
|
17303
17369
|
var GRACE_DAYS = 7;
|
|
17304
17370
|
var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
|
|
17305
17371
|
function pubkeyPath(brand) {
|
|
17306
|
-
return
|
|
17372
|
+
return resolve28(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
|
|
17307
17373
|
}
|
|
17308
17374
|
var memo = null;
|
|
17309
17375
|
function memoKey(mtimeMs, account) {
|
|
@@ -17315,7 +17381,7 @@ function resolveEntitlement(brand, account) {
|
|
|
17315
17381
|
if (brand.commercialMode !== true) {
|
|
17316
17382
|
return logResolved(implicitTrust(account), null);
|
|
17317
17383
|
}
|
|
17318
|
-
const entitlementPath =
|
|
17384
|
+
const entitlementPath = resolve28(brand.configDir, "entitlement.json");
|
|
17319
17385
|
if (!existsSync25(entitlementPath)) {
|
|
17320
17386
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
17321
17387
|
}
|
|
@@ -17506,7 +17572,7 @@ function clientFrom(c) {
|
|
|
17506
17572
|
);
|
|
17507
17573
|
}
|
|
17508
17574
|
var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
17509
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT9 ?
|
|
17575
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join22(PLATFORM_ROOT9, "config", "brand.json") : "";
|
|
17510
17576
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
|
|
17511
17577
|
if (BRAND_JSON_PATH && !existsSync26(BRAND_JSON_PATH)) {
|
|
17512
17578
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
@@ -17532,7 +17598,7 @@ var brandLoginOpts = {
|
|
|
17532
17598
|
bodyFont: BRAND.defaultFonts?.body,
|
|
17533
17599
|
logoContainsName: !!BRAND.logoContainsName
|
|
17534
17600
|
};
|
|
17535
|
-
var ALIAS_DOMAINS_PATH =
|
|
17601
|
+
var ALIAS_DOMAINS_PATH = join22(homedir3(), BRAND.configDir, "alias-domains.json");
|
|
17536
17602
|
function loadAliasDomains() {
|
|
17537
17603
|
try {
|
|
17538
17604
|
if (!existsSync26(ALIAS_DOMAINS_PATH)) return null;
|
|
@@ -17564,7 +17630,7 @@ var app48 = new Hono();
|
|
|
17564
17630
|
var nativeFileFollowers = /* @__PURE__ */ new Map();
|
|
17565
17631
|
var waGateway = new WaGateway({
|
|
17566
17632
|
gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
|
|
17567
|
-
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ??
|
|
17633
|
+
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve29(process.env.MAXY_PLATFORM_ROOT ?? join22(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
|
|
17568
17634
|
// Task 751 — file delivery on the native channel: resolve the platform
|
|
17569
17635
|
// account + path validation here and funnel through the shared send core.
|
|
17570
17636
|
sendDocument: async ({ senderId, accountId, filePath, caption }) => {
|
|
@@ -17580,7 +17646,7 @@ var waGateway = new WaGateway({
|
|
|
17580
17646
|
caption,
|
|
17581
17647
|
accountId,
|
|
17582
17648
|
maxyAccountId,
|
|
17583
|
-
platformRoot:
|
|
17649
|
+
platformRoot: resolve29(process.env.MAXY_PLATFORM_ROOT ?? join22(__dirname, ".."))
|
|
17584
17650
|
});
|
|
17585
17651
|
return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
|
|
17586
17652
|
},
|
|
@@ -17619,8 +17685,8 @@ var waGateway = new WaGateway({
|
|
|
17619
17685
|
app48.route("/", waGateway.routes());
|
|
17620
17686
|
waGateway.startSweeper();
|
|
17621
17687
|
var webchatGateway = new WebchatGateway({
|
|
17622
|
-
gatewayUrl:
|
|
17623
|
-
serverPath:
|
|
17688
|
+
gatewayUrl: webchatGatewayUrl(),
|
|
17689
|
+
serverPath: webchatServerPath(),
|
|
17624
17690
|
ensureChannelSession: async ({ accountId, key, role, gatewayUrl, serverPath, sessionId }) => {
|
|
17625
17691
|
if (role !== "admin") {
|
|
17626
17692
|
console.error(`[webchat:inbound] op=spawn-refused key=${key} role=${role} reason=public-path-not-wired`);
|
|
@@ -17961,8 +18027,8 @@ app48.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
17961
18027
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
17962
18028
|
return c.text("Not found", 404);
|
|
17963
18029
|
}
|
|
17964
|
-
const filePath =
|
|
17965
|
-
const expectedDir =
|
|
18030
|
+
const filePath = resolve29(account.accountDir, "agents", slug, "assets", filename);
|
|
18031
|
+
const expectedDir = resolve29(account.accountDir, "agents", slug, "assets");
|
|
17966
18032
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
17967
18033
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
17968
18034
|
return c.text("Forbidden", 403);
|
|
@@ -17991,8 +18057,8 @@ app48.get("/generated/:filename", (c) => {
|
|
|
17991
18057
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
17992
18058
|
return c.text("Not found", 404);
|
|
17993
18059
|
}
|
|
17994
|
-
const filePath =
|
|
17995
|
-
const expectedDir =
|
|
18060
|
+
const filePath = resolve29(account.accountDir, "generated", filename);
|
|
18061
|
+
const expectedDir = resolve29(account.accountDir, "generated");
|
|
17996
18062
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
17997
18063
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
17998
18064
|
return c.text("Forbidden", 403);
|
|
@@ -18036,7 +18102,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
18036
18102
|
function readInstalledVersion() {
|
|
18037
18103
|
try {
|
|
18038
18104
|
if (!PLATFORM_ROOT9) return "unknown";
|
|
18039
|
-
const versionFile =
|
|
18105
|
+
const versionFile = join22(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
|
|
18040
18106
|
if (!existsSync26(versionFile)) return "unknown";
|
|
18041
18107
|
const content = readFileSync26(versionFile, "utf-8").trim();
|
|
18042
18108
|
return content || "unknown";
|
|
@@ -18079,7 +18145,7 @@ var clientErrorReporterScript = `<script>
|
|
|
18079
18145
|
function cachedHtml(file) {
|
|
18080
18146
|
let html = htmlCache.get(file);
|
|
18081
18147
|
if (!html) {
|
|
18082
|
-
html = readFileSync26(
|
|
18148
|
+
html = readFileSync26(resolve29(process.cwd(), "public", file), "utf-8");
|
|
18083
18149
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
18084
18150
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
18085
18151
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -18095,11 +18161,11 @@ ${clientErrorReporterScript}
|
|
|
18095
18161
|
}
|
|
18096
18162
|
var brandedHtmlCache = /* @__PURE__ */ new Map();
|
|
18097
18163
|
function loadBrandingCache(agentSlug) {
|
|
18098
|
-
const configDir2 =
|
|
18164
|
+
const configDir2 = join22(homedir3(), BRAND.configDir);
|
|
18099
18165
|
try {
|
|
18100
18166
|
const accountId = getDefaultAccountId();
|
|
18101
18167
|
if (!accountId) return null;
|
|
18102
|
-
const cachePath =
|
|
18168
|
+
const cachePath = join22(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
18103
18169
|
if (!existsSync26(cachePath)) return null;
|
|
18104
18170
|
return JSON.parse(readFileSync26(cachePath, "utf-8"));
|
|
18105
18171
|
} catch {
|
|
@@ -18146,6 +18212,10 @@ function agentUnavailableHtml() {
|
|
|
18146
18212
|
}
|
|
18147
18213
|
app48.get("/", (c) => {
|
|
18148
18214
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
18215
|
+
if (isOperatorHost(host)) {
|
|
18216
|
+
console.log(`[host-class] host=${host} class=operator served=operator.html`);
|
|
18217
|
+
return c.html(cachedHtml("operator.html"));
|
|
18218
|
+
}
|
|
18149
18219
|
if (isPublicHost(host)) {
|
|
18150
18220
|
const defaultSlug = resolveDefaultSlug();
|
|
18151
18221
|
if (!defaultSlug) {
|
|
@@ -18158,6 +18228,7 @@ app48.get("/", (c) => {
|
|
|
18158
18228
|
console.error(`[public-root] op=serve-default slug=${defaultSlug}`);
|
|
18159
18229
|
return c.html(brandedPublicHtml(defaultSlug));
|
|
18160
18230
|
}
|
|
18231
|
+
console.log(`[host-class] host=${host} class=admin served=index.html`);
|
|
18161
18232
|
return c.html(cachedHtml("index.html"));
|
|
18162
18233
|
});
|
|
18163
18234
|
app48.get("/public", (c) => {
|
|
@@ -18189,7 +18260,7 @@ app48.use("/vnc-popout.html", logViewerFetch);
|
|
|
18189
18260
|
app48.get("/vnc-popout.html", (c) => {
|
|
18190
18261
|
let html = htmlCache.get("vnc-popout.html");
|
|
18191
18262
|
if (!html) {
|
|
18192
|
-
html = readFileSync26(
|
|
18263
|
+
html = readFileSync26(resolve29(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
18193
18264
|
const name = escapeHtml(BRAND.productName);
|
|
18194
18265
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
18195
18266
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -18225,7 +18296,7 @@ app48.get("/g/:slug", (c) => {
|
|
|
18225
18296
|
});
|
|
18226
18297
|
app48.get("/graph", (c) => {
|
|
18227
18298
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
18228
|
-
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
18299
|
+
if (isPublicHost(host) || isOperatorHost(host)) return c.text("Not found", 404);
|
|
18229
18300
|
return c.html(cachedHtml("graph.html"));
|
|
18230
18301
|
});
|
|
18231
18302
|
app48.get("/chat", (c) => {
|
|
@@ -18240,7 +18311,7 @@ app48.get("/data", (c) => {
|
|
|
18240
18311
|
});
|
|
18241
18312
|
app48.get("/browser", (c) => {
|
|
18242
18313
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
18243
|
-
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
18314
|
+
if (isPublicHost(host) || isOperatorHost(host)) return c.text("Not found", 404);
|
|
18244
18315
|
return c.html(cachedHtml("browser.html"));
|
|
18245
18316
|
});
|
|
18246
18317
|
app48.get("/:slug", async (c, next) => {
|
|
@@ -18459,7 +18530,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
18459
18530
|
}
|
|
18460
18531
|
init({
|
|
18461
18532
|
configDir: configDirForWhatsApp,
|
|
18462
|
-
platformRoot:
|
|
18533
|
+
platformRoot: resolve29(process.env.MAXY_PLATFORM_ROOT ?? join22(__dirname, "..")),
|
|
18463
18534
|
accountConfig: bootAccountConfig,
|
|
18464
18535
|
onMessage: async (msg) => {
|
|
18465
18536
|
if (msg.isOwnerMirror) {
|