@rubytech/create-maxy-code 0.1.500 → 0.1.501
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/lib/graph-style/dist/index.d.ts +9 -0
- package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-style/dist/index.js +152 -6
- package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-style/src/__tests__/caption-coverage.test.ts +69 -0
- package/payload/platform/lib/graph-style/src/__tests__/coverage-source.ts +73 -0
- package/payload/platform/lib/graph-style/src/__tests__/icons.test.ts +20 -3
- package/payload/platform/lib/graph-style/src/index.ts +166 -5
- package/payload/platform/plugins/admin/PLUGIN.md +1 -0
- package/payload/platform/plugins/admin/skills/agent-builder/SKILL.md +15 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +51 -1
- package/payload/platform/plugins/admin/skills/summarise/SKILL.md +37 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +50 -0
- package/payload/platform/plugins/docs/references/summarise-skill.md +7 -0
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/assets/{AdminLoginScreens-CKg_Dlpv.js → AdminLoginScreens-C3LZOPIY.js} +1 -1
- package/payload/server/public/assets/AdminShell-BlbUNAPc.js +2 -0
- package/payload/server/public/assets/{activity-CKUYOLd2.js → activity-CVdVSw5V.js} +1 -1
- package/payload/server/public/assets/admin-If1QLlS3.js +1 -0
- package/payload/server/public/assets/{arc-CpWWSum8.js → arc-CvlzUHOf.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-BQc779DH.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-D2EzaII0.js → architectureDiagram-Q4EWVU46-I1Hs0RJA.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-8kDpaNSZ.js → blockDiagram-DXYQGD6D-Df5jTGtl.js} +1 -1
- package/payload/server/public/assets/{bot-DESMpxSQ.js → bot-8b26IlQY.js} +1 -1
- package/payload/server/public/assets/{browser-CpLq_DIo.js → browser-F40DXfKA.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CbwmZpK3.js → c4Diagram-AHTNJAMY-B6WY5IDv.js} +1 -1
- package/payload/server/public/assets/{calendar-ClOwyuz-.js → calendar-DZiHiBwV.js} +1 -1
- package/payload/server/public/assets/channel-AqnC3SHu.js +1 -0
- package/payload/server/public/assets/chat-uD28FVCS.js +1 -0
- package/payload/server/public/assets/chevron-left-lBxD57tD.js +1 -0
- package/payload/server/public/assets/chevron-right-C-lDig9Y.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-PFheZ9mw.js → chunk-2KRD3SAO-BsIIFDkc.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-CCFOp5VK.js → chunk-336JU56O-j9z1VtyC.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-CO02gU5d.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-Hz4JWOf2.js → chunk-4BX2VUAB-C9i7prxq.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-4xeV0s85.js → chunk-4TB4RGXK-DH0QVGcv.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-4QKgBpoh.js → chunk-55IACEB6-Dnd_YCPA.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-ms3K6Z5z.js → chunk-5FUZZQ4R-D5sSz3yN.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CIC4GIGi.js → chunk-5PVQY5BW-CJrwWjAT.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-B-XrWVmV.js → chunk-67CJDMHE-SjP6_hUw.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-C7ECOUYQ.js → chunk-7N4EOEYR-fAuhVJD0.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-DOZ6Fxwk.js → chunk-AA7GKIK3-DZxa7KVg.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-4cJ_b0c6.js → chunk-BSJP7CBP-DjeG3eQ-.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT--mhZipWM.js → chunk-CIAEETIT-RYQULNJm.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-jZpVwob_.js → chunk-EDXVE4YY-Cahapnon.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-Nn-p-xIA.js → chunk-ENJZ2VHE-1146X1L4.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-DyNpcKOS.js → chunk-FMBD7UC4-BCFumtcP.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-C0P8q1uz.js → chunk-FOC6F5B3-CkrtX8Zt.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-CdXQ5SfI.js → chunk-ICPOFSXX-Ba1y3DaW.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-BVZJKKsT.js → chunk-K5T4RW27-CF-PI3uQ.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-QlVWTe0V.js → chunk-KGLVRYIC-SFFC6ZC-.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-CpGVZutP.js → chunk-LIHQZDEY-DbOLEP4R.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-WVcS6fUC.js → chunk-ORNJ4GCN-VB963bkN.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-B7hiSTed.js → chunk-OYMX7WX6-DWYY1pQa.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-BiFMbK8t.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-DJPnZxGy.js → chunk-U2HBQHQK-DAH1diYP.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-DilBs1Yc.js → chunk-X2U36JSP-Dmw9coXz.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-B5-uyrJ0.js → chunk-XPW4576I-DaAUON1-.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BNO4z0Mv.js → chunk-YZCP3GAM-BUcfkEef.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BzHMQpip.js → chunk-ZZ45TVLE-BLD-vFRO.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BdRqzScB.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-ChPLgHbS.js +1 -0
- package/payload/server/public/assets/clock-DqRNsY40.js +1 -0
- package/payload/server/public/assets/clone-TKtrjWBC.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-3DWYmn1o.js → cose-bilkent-S5V4N54A-CoZX0uki.js} +1 -1
- package/payload/server/public/assets/{dagre-Cpy31xJW.js → dagre-Bmjs8zJA.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-C8fyxHFd.js → dagre-KV5264BT-BZCP2wnq.js} +1 -1
- package/payload/server/public/assets/data-BsFyBN85.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-ycyhnLvr.js → diagram-5BDNPKRD-8Nt9a4xX.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BkeYicIt.js → diagram-G4DWMVQ6-vh5tcYqJ.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-BcGZU-Q3.js → diagram-MMDJMWI5-DGf--jc8.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-DuBDCFb_.js → diagram-TYMM5635-CsO7TIdw.js} +1 -1
- package/payload/server/public/assets/{dist-BYc_arNy.js → dist-cdnE4DqK.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DmkeOzvp.js → erDiagram-SMLLAGMA-4a78yV8_.js} +1 -1
- package/payload/server/public/assets/file-text-B1HjPFbM.js +1 -0
- package/payload/server/public/assets/{flatten-QjnJ1Gcl.js → flatten-BtIc9jX7.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CkE-pjuB.js → flowDiagram-DWJPFMVM-BoQBXs6t.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-Cjiy3kvE.js → ganttDiagram-T4ZO3ILL-CvzqwCC8.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-DfcaTE9L.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CsI4lKZm.js → gitGraphDiagram-UUTBAWPF-D_nBxay_.js} +1 -1
- package/payload/server/public/assets/graph-CIC-mgKR.js +51 -0
- package/payload/server/public/assets/graph-labels-BnpHCHaQ.js +1 -0
- package/payload/server/public/assets/{graphlib-BkXxC6D5.js → graphlib-D0NdsKJI.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-CD-u6gw9.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-C6gPQCvO.js +2 -0
- package/payload/server/public/assets/{isEmpty-BavJI9Cn.js → isEmpty-Bu4fZ8Kf.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-D8lZtjRc.js → ishikawaDiagram-UXIWVN3A-auW-s0i0.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-kLE7SiR_.js → journeyDiagram-VCZTEJTY-3Q6AWK4A.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-ove6JuD3.js → kanban-definition-6JOO6SKY-B4MPFp98.js} +1 -1
- package/payload/server/public/assets/{line-CZMSoxM6.js → line-26MdeG5Z.js} +1 -1
- package/payload/server/public/assets/{linear-Be8IK9hK.js → linear-Dq9s_bDO.js} +1 -1
- package/payload/server/public/assets/{maximize-2-BbzPm7o8.js → maximize-2-BL7QVTcQ.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-BBADqbnp.js → mermaid-parser.core-vLEpOXgf.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-mH3N7K0I.js → mermaid.core-Durk4m6D.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-BjwwwWil.js → mindmap-definition-QFDTVHPH-DOIg-TyG.js} +1 -1
- package/payload/server/public/assets/{operator-DglDYmdV.js → operator-B62h_TaC.js} +1 -1
- package/payload/server/public/assets/{ordinal-BHeIKG-K.js → ordinal-C2TEWKNu.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-BaLYeIrU.js +1 -0
- package/payload/server/public/assets/page-BUUBseJZ.js +32 -0
- package/payload/server/public/assets/page-Bw-tYjw7.js +1 -0
- package/payload/server/public/assets/{pdf-render-fJz4vym9.js → pdf-render-C257cidb.js} +1 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-CL-XJtk-.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-D-lXWWta.js → pieDiagram-DEJITSTG-DtgBHZfi.js} +1 -1
- package/payload/server/public/assets/{public-DqJjXR4p.js → public-BI21tOkm.js} +1 -1
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-13QyG_AO.js → quadrantDiagram-34T5L4WZ-BTc5Qn2y.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-Cn-g6F_h.js +1 -0
- package/payload/server/public/assets/{reduce-Fm685to3.js → reduce-BGpN5lgn.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-Bx45Bgn4.js → requirementDiagram-MS252O5E-BNgOO5YW.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-L42fL8ey.js → rotate-ccw-C_20Bc3E.js} +1 -1
- package/payload/server/public/assets/routines-Ci3N8wqV.js +1 -0
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Cj-Gq25v.js → sankeyDiagram-XADWPNL6-MyUATmVt.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-B8RDRq93.js → sequenceDiagram-FGHM5R23-CBJrF5Vi.js} +1 -1
- package/payload/server/public/assets/skills-CiflzOko.js +1 -0
- package/payload/server/public/assets/{src-D3VYuW_Z.js → src-DekKlUCp.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DoyFF1Kl.js → stateDiagram-FHFEXIEX-6wbUjn1Q.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdMdfBeC.js +1 -0
- package/payload/server/public/assets/{tasks-GNtvZL8F.js → tasks-DC2Yf2Ev.js} +1 -1
- package/payload/server/public/assets/{time-entry-format-BreNpFLJ.js → time-entry-format-CNcjs2HV.js} +1 -1
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Df4RQXm6.js → timeline-definition-GMOUNBTQ-BHjTMCGY.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CmZoOGlC.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-H27WFS-y.js +1 -0
- package/payload/server/public/assets/{triangle-alert-DumCWC08.js → triangle-alert-CngnWtjD.js} +1 -1
- package/payload/server/public/assets/{useCopyFeedback-DHCtz8qX.js → useCopyFeedback-DZ9Bw5CI.js} +1 -1
- package/payload/server/public/assets/{useSubAccountSwitcher-Bc7XHr0L.js → useSubAccountSwitcher-CHwQhkaI.js} +1 -1
- package/payload/server/public/assets/{useSubAccountSwitcher-DPHQJO7E.css → useSubAccountSwitcher-yFQqnpQ8.css} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-C3G6aqZr.js +2 -0
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-D2o5og9l.js → vennDiagram-DHZGUBPP-yo3-cf0U.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-DNpWIvU4.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BDueObbS.js → wardleyDiagram-NUSXRM2D-DZlyFzrg.js} +1 -1
- package/payload/server/public/assets/{wrench-iWkROE1V.js → wrench-dky2-13x.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BTYs4Fgh.js → xychartDiagram-5P7HB3ND-B5HV5h80.js} +1 -1
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +8 -8
- package/payload/server/public/chat.html +16 -15
- package/payload/server/public/data.html +13 -12
- package/payload/server/public/graph.html +10 -10
- package/payload/server/public/index.html +17 -16
- package/payload/server/public/operator.html +17 -16
- package/payload/server/public/public.html +16 -15
- package/payload/server/public/routines.html +7 -7
- package/payload/server/public/skills.html +19 -0
- package/payload/server/public/tasks.html +7 -7
- package/payload/server/server.js +672 -396
- package/payload/server/public/assets/AdminShell-BFVVkWFC.js +0 -2
- package/payload/server/public/assets/admin-wtSUU5N0.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-D-AX2VuA.js +0 -1
- package/payload/server/public/assets/channel-DZ5sh6YQ.js +0 -1
- package/payload/server/public/assets/chat-DRuIxGtE.js +0 -1
- package/payload/server/public/assets/chevron-left-BzIg4in6.js +0 -1
- package/payload/server/public/assets/chevron-right-BcFSa9C3.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-CcjBLp4a.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-B2WjDYBE.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CT3jNrze.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DJRsjAkC.js +0 -1
- package/payload/server/public/assets/clock-Dr3NGtjR.js +0 -1
- package/payload/server/public/assets/clone-FcEDnoMT.js +0 -1
- package/payload/server/public/assets/data-BdZCvyvN.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-D1uhnP9U.js +0 -1
- package/payload/server/public/assets/graph-B7niLM97.js +0 -51
- package/payload/server/public/assets/graph-labels-DykmXYHA.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-oNm27GAV.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-LxTftqyS.js +0 -2
- package/payload/server/public/assets/packet-4T2RLAQJ-eQNVGiK3.js +0 -1
- package/payload/server/public/assets/page-C-5sTAE-.js +0 -32
- package/payload/server/public/assets/page-C8G5p4jr.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-E1u-48rt.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-Cn2cGN90.js +0 -1
- package/payload/server/public/assets/routines-JOV6xdYh.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Bml-X4-H.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CimabhXy.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-Cg264rpM.js +0 -1
- package/payload/server/public/assets/useVoiceRecorder-Cj-VZDKO.js +0 -2
- package/payload/server/public/assets/wardley-RL74JXVD-tbgfCg0E.js +0 -1
- /package/payload/server/public/assets/{_baseFor-Bvwvhrz4.js → _baseFor-Be3EKK3K.js} +0 -0
- /package/payload/server/public/assets/{array-D3d-WgFW.js → array-X0JlPOfd.js} +0 -0
- /package/payload/server/public/assets/{chunk-fQC6bEKA.js → chunk-CCr-iYLO.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-Cun-OM6a.js → cytoscape.esm-CI2IWMLB.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-CisKV5Ew.js → defaultLocale-B6RGN4id.js} +0 -0
- /package/payload/server/public/assets/{init-D9ZOVaZ3.js → init-BmUWJJHz.js} +0 -0
- /package/payload/server/public/assets/{katex-C-3ZDK8o.js → katex-BjZuzSQn.js} +0 -0
- /package/payload/server/public/assets/{path-BMOgQSLM.js → path-CoPyR7c2.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-DL2DwvxV.js → preload-helper-BQrMkyGX.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-BrTFrov0.js → rough.esm-jSt7UMyi.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -503,7 +503,7 @@ var require_dist3 = __commonJS({
|
|
|
503
503
|
"../lib/graph-style/dist/index.js"(exports) {
|
|
504
504
|
"use strict";
|
|
505
505
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
506
|
-
exports.FALLBACK_LABEL_SHAPE = exports.EXTERNAL_LABEL_SHAPES = exports.ALL_GRAPH_LABELS = exports.ADDITIONAL_BASE_LABELS = exports.FALLBACK_LABEL_COLOUR = exports.GRAPH_LABEL_COLOURS = void 0;
|
|
506
|
+
exports.CODE_EMITTED_NODE_LABELS = exports.FALLBACK_LABEL_SHAPE = exports.EXTERNAL_LABEL_SHAPES = exports.ALL_GRAPH_LABELS = exports.ADDITIONAL_BASE_LABELS = exports.FALLBACK_LABEL_COLOUR = exports.GRAPH_LABEL_COLOURS = void 0;
|
|
507
507
|
exports.pickDisplayLabel = pickDisplayLabel2;
|
|
508
508
|
exports.colourForLabel = colourForLabel2;
|
|
509
509
|
exports.shapeForLabel = shapeForLabel2;
|
|
@@ -531,11 +531,12 @@ var require_dist3 = __commonJS({
|
|
|
531
531
|
// JobLogic service-delivery ontology (Task 1084; supersedes the Task 650/773
|
|
532
532
|
// homegrown set). Muted brick-red / earthy family — the service register sits
|
|
533
533
|
// apart from people-terracotta, viewing-amber, and task-rose bands so
|
|
534
|
-
// sitedesk legends read as their own group.
|
|
535
|
-
// labels
|
|
536
|
-
// JobCost, Contact, PurchaseOrderLine, InvoiceLine,
|
|
537
|
-
//
|
|
538
|
-
//
|
|
534
|
+
// sitedesk legends read as their own group. These are the top-level
|
|
535
|
+
// (operator-entry) labels; the child labels (QuoteLine, Milestone, Valuation,
|
|
536
|
+
// VariationNote, JobCost, Contact, PurchaseOrderLine, InvoiceLine,
|
|
537
|
+
// InvoicePayment, Credit) are coloured in the Task 1965 block appended at the
|
|
538
|
+
// end of this object, not here. :Engineer is an additional label on Person
|
|
539
|
+
// and takes the Person colour; :Supplier is an additional label on
|
|
539
540
|
// Organization and takes the tobacco Organization colour. All hexes here are
|
|
540
541
|
// pairwise-unique across the registry.
|
|
541
542
|
Job: "#8C3B2E",
|
|
@@ -633,7 +634,82 @@ var require_dist3 = __commonJS({
|
|
|
633
634
|
// SHAPE_BY_LABEL assigns shapes by index position in ALL_GRAPH_LABELS
|
|
634
635
|
// (this object's key order), so a mid-table insert would silently change
|
|
635
636
|
// the rendered shape of every label after it.
|
|
636
|
-
CashEntry: "#7D5A2B"
|
|
637
|
+
CashEntry: "#7D5A2B",
|
|
638
|
+
// --- Task 1965: colour every node type that can appear in the graph ---
|
|
639
|
+
// Appended at the END so SHAPE_BY_LABEL indices for the labels above are
|
|
640
|
+
// unchanged. Grouped by family band; each hex is pairwise-unique across the
|
|
641
|
+
// whole registry (except the pre-existing UserMessage/Preference twin).
|
|
642
|
+
// Ledger / money children (brown-gold, beside Invoice and CashEntry).
|
|
643
|
+
InvoiceLine: "#7A5326",
|
|
644
|
+
InvoicePayment: "#8A6230",
|
|
645
|
+
QuoteLine: "#9A7038",
|
|
646
|
+
PurchaseOrderLine: "#A67E42",
|
|
647
|
+
JobCost: "#6A4A22",
|
|
648
|
+
Credit: "#B48A48",
|
|
649
|
+
Retainer: "#C29A55",
|
|
650
|
+
Sale: "#8E5E2A",
|
|
651
|
+
Valuation: "#A06A34",
|
|
652
|
+
Order: "#B87C3E",
|
|
653
|
+
DiningOrder: "#C9954E",
|
|
654
|
+
// Documents / content (steel-blue, hue-adjacent to the business slates).
|
|
655
|
+
Content: "#58708C",
|
|
656
|
+
Report: "#6D8299",
|
|
657
|
+
Page: "#849AAF",
|
|
658
|
+
Post: "#93A7BA",
|
|
659
|
+
VariationNote: "#47617B",
|
|
660
|
+
FileArtifact: "#A9BBCC",
|
|
661
|
+
// Marketing (bright teal-green, apart from workflow and research teals).
|
|
662
|
+
SocialPost: "#2FA69A",
|
|
663
|
+
Campaign: "#3FB8A0",
|
|
664
|
+
BrandDeal: "#57C2AE",
|
|
665
|
+
Recommendation: "#74CDBB",
|
|
666
|
+
// CRM people (terracotta, beside Person and Customer).
|
|
667
|
+
Contact: "#C97E52",
|
|
668
|
+
Lead: "#A85E38",
|
|
669
|
+
Position: "#96522E",
|
|
670
|
+
Audience: "#E0B088",
|
|
671
|
+
// Places / transport / retail (forest-emerald, apart from knowledge moss).
|
|
672
|
+
PostalAddress: "#2E8B57",
|
|
673
|
+
Room: "#3A9B63",
|
|
674
|
+
StoreLocation: "#46A96F",
|
|
675
|
+
Vehicle: "#54B77B",
|
|
676
|
+
Route: "#62C187",
|
|
677
|
+
Stop: "#2A7A4C",
|
|
678
|
+
Shipment: "#6FCB93",
|
|
679
|
+
Reservation: "#7ED4A0",
|
|
680
|
+
TableReservation: "#8CDBAC",
|
|
681
|
+
Menu: "#1F6B41",
|
|
682
|
+
MenuItem: "#98E0B6",
|
|
683
|
+
Product: "#34925E",
|
|
684
|
+
StockMovement: "#4CA574",
|
|
685
|
+
// Work / delivery (indigo, apart from the strategy indigo band).
|
|
686
|
+
Milestone: "#4A5FA8",
|
|
687
|
+
Deliverable: "#6274C0",
|
|
688
|
+
TimeEntry: "#8189CE",
|
|
689
|
+
Engagement: "#9AA0DA",
|
|
690
|
+
Case: "#3B4E92",
|
|
691
|
+
Meeting: "#5566B4",
|
|
692
|
+
// Idea (amber).
|
|
693
|
+
Idea: "#E0A82E",
|
|
694
|
+
// Web analytics (sky-cyan, apart from the research teal).
|
|
695
|
+
Session: "#2AA7C4",
|
|
696
|
+
PageView: "#3DB4CE",
|
|
697
|
+
Click: "#55C0D6",
|
|
698
|
+
ScrollMilestone: "#70CCDE",
|
|
699
|
+
TimelineEvent: "#1E93B0",
|
|
700
|
+
AnonVisitor: "#88D6E6",
|
|
701
|
+
AEOAudit: "#46B0CB",
|
|
702
|
+
// WhatsApp transport (brand green).
|
|
703
|
+
WhatsAppConversation: "#128C7E",
|
|
704
|
+
WhatsAppMessage: "#1FA894",
|
|
705
|
+
// Cloudflare / chain infra (grey-blue).
|
|
706
|
+
CloudflareHostname: "#5B6E82",
|
|
707
|
+
CloudflareTunnel: "#6E8296",
|
|
708
|
+
Chain: "#47586A",
|
|
709
|
+
ChainLink: "#8496AA",
|
|
710
|
+
// Voice (violet).
|
|
711
|
+
VoiceProfile: "#9B59B6",
|
|
712
|
+
VoiceEdit: "#B07CC9"
|
|
637
713
|
};
|
|
638
714
|
exports.FALLBACK_LABEL_COLOUR = "#94A3B8";
|
|
639
715
|
exports.ADDITIONAL_BASE_LABELS = Object.freeze(/* @__PURE__ */ new Set(["Applicant", "Engineer", "GuestProfile", "Supplier"]));
|
|
@@ -669,6 +745,7 @@ var require_dist3 = __commonJS({
|
|
|
669
745
|
function shapeForLabel2(label) {
|
|
670
746
|
return SHAPE_BY_LABEL[label] ?? exports.FALLBACK_LABEL_SHAPE;
|
|
671
747
|
}
|
|
748
|
+
exports.CODE_EMITTED_NODE_LABELS = Object.freeze(/* @__PURE__ */ new Set(["FileArtifact"]));
|
|
672
749
|
var LABEL_ICONS = {
|
|
673
750
|
LocalBusiness: '<path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5"></path><path d="M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244"></path><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05"></path>',
|
|
674
751
|
Service: '<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"></path>',
|
|
@@ -732,7 +809,68 @@ var require_dist3 = __commonJS({
|
|
|
732
809
|
Source: '<path d="M12 7v14"></path><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"></path>',
|
|
733
810
|
Finding: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"></path><path d="M9 18h6"></path><path d="M10 22h4"></path>',
|
|
734
811
|
Hypothesis: '<path d="M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2"></path><path d="M6.453 15h11.094"></path><path d="M8.5 2h7"></path>',
|
|
735
|
-
CashEntry: '<rect width="20" height="12" x="2" y="6" rx="2"></rect><circle cx="12" cy="12" r="2"></circle><path d="M6 12h.01"></path><path d="M18 12h.01"></path>'
|
|
812
|
+
CashEntry: '<rect width="20" height="12" x="2" y="6" rx="2"></rect><circle cx="12" cy="12" r="2"></circle><path d="M6 12h.01"></path><path d="M18 12h.01"></path>',
|
|
813
|
+
// --- Task 1965: glyphs for the 60 previously-uncovered node labels ---
|
|
814
|
+
InvoiceLine: '<path d="M13 16H8" /><path d="M14 8H8" /><path d="M16 12H8" /><path d="M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" />',
|
|
815
|
+
InvoicePayment: '<path d="M11 15h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 17" /><path d="m7 21 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9" /><path d="m2 16 6 6" /><circle cx="16" cy="9" r="2.9" /><circle cx="6" cy="5" r="3" />',
|
|
816
|
+
QuoteLine: '<path d="M3 5h.01" /><path d="M3 12h.01" /><path d="M3 19h.01" /><path d="M8 5h13" /><path d="M8 12h13" /><path d="M8 19h13" />',
|
|
817
|
+
PurchaseOrderLine: '<path d="M11 5h10" /><path d="M11 12h10" /><path d="M11 19h10" /><path d="M4 4h1v5" /><path d="M4 9h2" /><path d="M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02" />',
|
|
818
|
+
JobCost: '<rect width="20" height="12" x="2" y="6" rx="2" /><circle cx="12" cy="12" r="2" /><path d="M6 12h.01M18 12h.01" />',
|
|
819
|
+
Credit: '<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" /><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8" /><path d="M12 18V6" />',
|
|
820
|
+
Retainer: '<path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1" /><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4" />',
|
|
821
|
+
Sale: '<path d="M12 17V7" /><path d="M16 8h-6a2 2 0 0 0 0 4h4a2 2 0 0 1 0 4H8" /><path d="M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" />',
|
|
822
|
+
Valuation: '<path d="M12 3v18" /><path d="m19 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1" /><path d="m5 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M7 21h10" />',
|
|
823
|
+
Order: '<path d="M16 10a4 4 0 0 1-8 0" /><path d="M3.103 6.034h17.794" /><path d="M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z" />',
|
|
824
|
+
DiningOrder: '<path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2" /><path d="M7 2v20" /><path d="M21 15V2a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7" />',
|
|
825
|
+
Content: '<path d="M15 18h-5" /><path d="M18 14h-8" /><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2" /><rect width="8" height="4" x="10" y="6" rx="1" />',
|
|
826
|
+
Report: '<rect width="8" height="4" x="8" y="2" rx="1" ry="1" /><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" /><path d="M12 11h4" /><path d="M12 16h4" /><path d="M8 11h.01" /><path d="M8 16h.01" />',
|
|
827
|
+
Page: '<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /><path d="M14 2v5a1 1 0 0 0 1 1h5" />',
|
|
828
|
+
Post: '<path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" /><path d="M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z" />',
|
|
829
|
+
SocialPost: '<path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z" /><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14" /><path d="M8 6v8" />',
|
|
830
|
+
VariationNote: '<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /><path d="M9 10h6" /><path d="M12 13V7" /><path d="M9 17h6" />',
|
|
831
|
+
Contact: '<path d="M16 2v2" /><path d="M17.915 22a6 6 0 0 0-12 0" /><path d="M8 2v2" /><circle cx="12" cy="12" r="4" /><rect x="3" y="4" width="18" height="18" rx="2" />',
|
|
832
|
+
Lead: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><line x1="19" x2="19" y1="8" y2="14" /><line x1="22" x2="16" y1="11" y2="11" />',
|
|
833
|
+
Position: '<path d="M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16" /><rect width="20" height="14" x="2" y="6" rx="2" />',
|
|
834
|
+
Audience: '<path d="M18 21a8 8 0 0 0-16 0" /><circle cx="10" cy="8" r="5" /><path d="M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3" />',
|
|
835
|
+
PostalAddress: '<path d="M18 8c0 3.613-3.869 7.429-5.393 8.795a1 1 0 0 1-1.214 0C9.87 15.429 6 11.613 6 8a6 6 0 0 1 12 0" /><circle cx="12" cy="8" r="2" /><path d="M8.714 14h-3.71a1 1 0 0 0-.948.683l-2.004 6A1 1 0 0 0 3 22h18a1 1 0 0 0 .948-1.316l-2-6a1 1 0 0 0-.949-.684h-3.712" />',
|
|
836
|
+
Room: '<path d="M11 20H2" /><path d="M11 4.562v16.157a1 1 0 0 0 1.242.97L19 20V5.562a2 2 0 0 0-1.515-1.94l-4-1A2 2 0 0 0 11 4.561z" /><path d="M11 4H8a2 2 0 0 0-2 2v14" /><path d="M14 12h.01" /><path d="M22 20h-3" />',
|
|
837
|
+
StoreLocation: '<path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5" /><path d="M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244" /><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05" />',
|
|
838
|
+
Vehicle: '<path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2" /><circle cx="7" cy="17" r="2" /><path d="M9 17h6" /><circle cx="17" cy="17" r="2" />',
|
|
839
|
+
Route: '<circle cx="6" cy="19" r="3" /><path d="M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15" /><circle cx="18" cy="5" r="3" />',
|
|
840
|
+
Stop: '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" /><circle cx="12" cy="10" r="3" />',
|
|
841
|
+
Shipment: '<path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z" /><path d="M12 22V12" /><polyline points="3.29 7 12 12 20.71 7" /><path d="m7.5 4.27 9 5.15" />',
|
|
842
|
+
Reservation: '<path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" /><path d="m9 16 2 2 4-4" />',
|
|
843
|
+
TableReservation: '<path d="m16 2-2.3 2.3a3 3 0 0 0 0 4.2l1.8 1.8a3 3 0 0 0 4.2 0L22 8" /><path d="M15 15 3.3 3.3a4.2 4.2 0 0 0 0 6l7.3 7.3c.7.7 2 .7 2.8 0L15 15Zm0 0 7 7" /><path d="m2.1 21.8 6.4-6.3" /><path d="m19 5-7 7" />',
|
|
844
|
+
Menu: '<path d="M12 5v16" /><path d="M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z" />',
|
|
845
|
+
MenuItem: '<path d="M7 21h10" /><path d="M12 21a9 9 0 0 0 9-9H3a9 9 0 0 0 9 9Z" /><path d="M11.38 12a2.4 2.4 0 0 1-.4-4.77 2.4 2.4 0 0 1 3.2-2.77 2.4 2.4 0 0 1 3.47-.63 2.4 2.4 0 0 1 3.37 3.37 2.4 2.4 0 0 1-1.1 3.7 2.51 2.51 0 0 1 .03 1.1" /><path d="m13 12 4-4" /><path d="M10.9 7.25A3.99 3.99 0 0 0 4 10c0 .73.2 1.41.54 2" />',
|
|
846
|
+
Product: '<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" /><path d="m3.3 7 8.7 5 8.7-5" /><path d="M12 22V12" />',
|
|
847
|
+
StockMovement: '<path d="m16 3 4 4-4 4" /><path d="M20 7H4" /><path d="m8 21-4-4 4-4" /><path d="M4 17h16" />',
|
|
848
|
+
Milestone: '<path d="M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528" />',
|
|
849
|
+
Deliverable: '<path d="M12 22V12" /><path d="m16 17 2 2 4-4" /><path d="M21 11.127V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l1.32-.753" /><path d="M3.29 7 12 12l8.71-5" /><path d="m7.5 4.27 8.997 5.148" />',
|
|
850
|
+
TimeEntry: '<line x1="10" x2="14" y1="2" y2="2" /><line x1="12" x2="15" y1="14" y2="11" /><circle cx="12" cy="14" r="8" />',
|
|
851
|
+
Engagement: '<path d="m11 17 2 2a1 1 0 1 0 3-3" /><path d="m14 14 2.5 2.5a1 1 0 1 0 3-3l-3.88-3.88a3 3 0 0 0-4.24 0l-.88.88a1 1 0 1 1-3-3l2.81-2.81a5.79 5.79 0 0 1 7.06-.87l.47.28a2 2 0 0 0 1.42.25L21 4" /><path d="m21 3 1 11h-2" /><path d="M3 3 2 14l6.5 6.5a1 1 0 1 0 3-3" /><path d="M3 4h8" />',
|
|
852
|
+
Case: '<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />',
|
|
853
|
+
Meeting: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><path d="M16 3.128a4 4 0 0 1 0 7.744" /><path d="M22 21v-2a4 4 0 0 0-3-3.87" /><circle cx="9" cy="7" r="4" />',
|
|
854
|
+
Idea: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5" /><path d="M9 18h6" /><path d="M10 22h4" />',
|
|
855
|
+
Campaign: '<path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5" /><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09" /><path d="M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z" /><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05" />',
|
|
856
|
+
BrandDeal: '<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" /><path d="m9 12 2 2 4-4" />',
|
|
857
|
+
Recommendation: '<path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" /><path d="M7 10v12" />',
|
|
858
|
+
Session: '<rect width="20" height="14" x="2" y="3" rx="2" /><line x1="8" x2="16" y1="21" y2="21" /><line x1="12" x2="12" y1="17" y2="21" />',
|
|
859
|
+
PageView: '<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" /><circle cx="12" cy="12" r="3" />',
|
|
860
|
+
Click: '<path d="M14 4.1 12 6" /><path d="m5.1 8-2.9-.8" /><path d="m6 12-1.9 2" /><path d="M7.2 2.2 8 5.1" /><path d="M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z" />',
|
|
861
|
+
ScrollMilestone: '<path d="m7 6 5 5 5-5" /><path d="m7 13 5 5 5-5" />',
|
|
862
|
+
TimelineEvent: '<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" /><path d="M3 3v5h5" /><path d="M12 7v5l4 2" />',
|
|
863
|
+
AnonVisitor: '<path d="M9 10h.01" /><path d="M15 10h.01" /><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z" />',
|
|
864
|
+
AEOAudit: '<path d="m8 11 2 2 4-4" /><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" />',
|
|
865
|
+
WhatsAppConversation: '<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719" />',
|
|
866
|
+
WhatsAppMessage: '<path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" /><path d="M7 11h10" /><path d="M7 15h6" /><path d="M7 7h8" />',
|
|
867
|
+
CloudflareHostname: '<circle cx="12" cy="12" r="10" /><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" /><path d="M2 12h20" />',
|
|
868
|
+
CloudflareTunnel: '<rect x="16" y="16" width="6" height="6" rx="1" /><rect x="2" y="16" width="6" height="6" rx="1" /><rect x="9" y="2" width="6" height="6" rx="1" /><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3" /><path d="M12 12V8" />',
|
|
869
|
+
Chain: '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />',
|
|
870
|
+
ChainLink: '<path d="M9 17H7A5 5 0 0 1 7 7h2" /><path d="M15 7h2a5 5 0 1 1 0 10h-2" /><line x1="8" x2="16" y1="12" y2="12" />',
|
|
871
|
+
FileArtifact: '<path d="M13.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v11.5" /><path d="M14 2v5a1 1 0 0 0 1 1h5" /><path d="M8 12v-1" /><path d="M8 18v-2" /><path d="M8 7V6" /><circle cx="8" cy="20" r="2" />',
|
|
872
|
+
VoiceProfile: '<path d="M12 19v3" /><path d="M19 10v2a7 7 0 0 1-14 0v-2" /><rect x="9" y="2" width="6" height="13" rx="3" />',
|
|
873
|
+
VoiceEdit: '<path d="M2 10v3" /><path d="M6 6v11" /><path d="M10 3v18" /><path d="M14 8v7" /><path d="M18 5v13" /><path d="M22 10v3" />'
|
|
736
874
|
};
|
|
737
875
|
function iconForLabel2(label) {
|
|
738
876
|
return Object.prototype.hasOwnProperty.call(LABEL_ICONS, label) ? LABEL_ICONS[label] : null;
|
|
@@ -1615,10 +1753,10 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
1615
1753
|
};
|
|
1616
1754
|
|
|
1617
1755
|
// server/index.ts
|
|
1618
|
-
import { readFileSync as
|
|
1756
|
+
import { readFileSync as readFileSync46, existsSync as existsSync43, watchFile, readdirSync as readdirSync27, statSync as statSync18 } from "fs";
|
|
1619
1757
|
import { spawn as spawn3 } from "child_process";
|
|
1620
1758
|
import { createHash as createHash7 } from "crypto";
|
|
1621
|
-
import { resolve as
|
|
1759
|
+
import { resolve as resolve42, join as join47, basename as basename13 } from "path";
|
|
1622
1760
|
import { homedir as homedir4 } from "os";
|
|
1623
1761
|
import { monitorEventLoopDelay } from "perf_hooks";
|
|
1624
1762
|
|
|
@@ -2892,7 +3030,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
2892
3030
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
2893
3031
|
console.error(`${TAG6} draining credential save queue\u2026`);
|
|
2894
3032
|
const timer = new Promise(
|
|
2895
|
-
(
|
|
3033
|
+
(resolve43) => setTimeout(() => resolve43("timeout"), timeoutMs)
|
|
2896
3034
|
);
|
|
2897
3035
|
const result = await Promise.race([
|
|
2898
3036
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -3069,11 +3207,11 @@ async function createWaSocket(opts) {
|
|
|
3069
3207
|
return sock;
|
|
3070
3208
|
}
|
|
3071
3209
|
async function waitForConnection(sock) {
|
|
3072
|
-
return new Promise((
|
|
3210
|
+
return new Promise((resolve43, reject) => {
|
|
3073
3211
|
const handler = (update) => {
|
|
3074
3212
|
if (update.connection === "open") {
|
|
3075
3213
|
sock.ev.off("connection.update", handler);
|
|
3076
|
-
|
|
3214
|
+
resolve43();
|
|
3077
3215
|
}
|
|
3078
3216
|
if (update.connection === "close") {
|
|
3079
3217
|
sock.ev.off("connection.update", handler);
|
|
@@ -3181,7 +3319,7 @@ function isTimeoutError(err) {
|
|
|
3181
3319
|
return Boolean(err?.__maxyTimeout);
|
|
3182
3320
|
}
|
|
3183
3321
|
function withTimeout(label, promise, timeoutMs) {
|
|
3184
|
-
return new Promise((
|
|
3322
|
+
return new Promise((resolve43, reject) => {
|
|
3185
3323
|
const timer = setTimeout(() => {
|
|
3186
3324
|
const err = new Error(`${label} timed out after ${timeoutMs}ms`);
|
|
3187
3325
|
err.__maxyTimeout = true;
|
|
@@ -3191,7 +3329,7 @@ function withTimeout(label, promise, timeoutMs) {
|
|
|
3191
3329
|
promise.then(
|
|
3192
3330
|
(value) => {
|
|
3193
3331
|
clearTimeout(timer);
|
|
3194
|
-
|
|
3332
|
+
resolve43(value);
|
|
3195
3333
|
},
|
|
3196
3334
|
(err) => {
|
|
3197
3335
|
clearTimeout(timer);
|
|
@@ -4256,8 +4394,8 @@ async function persistWhatsAppMessage(input) {
|
|
|
4256
4394
|
const { givenName, familyName } = splitName(input.pushName);
|
|
4257
4395
|
const prev = sessionWriteLocks.get(input.cacheKey);
|
|
4258
4396
|
let release;
|
|
4259
|
-
const mine = new Promise((
|
|
4260
|
-
release =
|
|
4397
|
+
const mine = new Promise((resolve43) => {
|
|
4398
|
+
release = resolve43;
|
|
4261
4399
|
});
|
|
4262
4400
|
const chained = (prev ?? Promise.resolve()).then(() => mine);
|
|
4263
4401
|
sessionWriteLocks.set(input.cacheKey, chained);
|
|
@@ -5994,11 +6132,11 @@ async function connectWithReconnect(conn) {
|
|
|
5994
6132
|
console.error(
|
|
5995
6133
|
`${TAG17} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
5996
6134
|
);
|
|
5997
|
-
await new Promise((
|
|
5998
|
-
const timer = setTimeout(
|
|
6135
|
+
await new Promise((resolve43) => {
|
|
6136
|
+
const timer = setTimeout(resolve43, delay);
|
|
5999
6137
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
6000
6138
|
clearTimeout(timer);
|
|
6001
|
-
|
|
6139
|
+
resolve43();
|
|
6002
6140
|
}, { once: true });
|
|
6003
6141
|
});
|
|
6004
6142
|
}
|
|
@@ -6006,16 +6144,16 @@ async function connectWithReconnect(conn) {
|
|
|
6006
6144
|
}
|
|
6007
6145
|
}
|
|
6008
6146
|
function waitForDisconnectEvent(conn) {
|
|
6009
|
-
return new Promise((
|
|
6147
|
+
return new Promise((resolve43) => {
|
|
6010
6148
|
if (!conn.sock) {
|
|
6011
|
-
|
|
6149
|
+
resolve43();
|
|
6012
6150
|
return;
|
|
6013
6151
|
}
|
|
6014
6152
|
const sock = conn.sock;
|
|
6015
6153
|
const handler = (update) => {
|
|
6016
6154
|
if (update.connection === "close") {
|
|
6017
6155
|
sock.ev.off("connection.update", handler);
|
|
6018
|
-
|
|
6156
|
+
resolve43();
|
|
6019
6157
|
}
|
|
6020
6158
|
};
|
|
6021
6159
|
sock.ev.on("connection.update", handler);
|
|
@@ -6125,7 +6263,7 @@ function monitorInbound(conn) {
|
|
|
6125
6263
|
}
|
|
6126
6264
|
const entries = messageStore.get(storeKey);
|
|
6127
6265
|
console.error(
|
|
6128
|
-
`${TAG17} stored message ${msg.key.id ?? "?"} for ${remoteJid} (type: ${upsert.type}, store size: ${entries?.length ?? 0}/${MESSAGE_STORE_MAX})
|
|
6266
|
+
`${TAG17} stored message ${msg.key.id ?? "?"} for ${remoteJid} (type: ${upsert.type}, store size: ${entries?.length ?? 0}/${MESSAGE_STORE_MAX}) storeAccount=${persistAccountId} socketOwner=${conn.platformAccountId}`
|
|
6129
6267
|
);
|
|
6130
6268
|
recordActivity({
|
|
6131
6269
|
accountId: conn.accountId,
|
|
@@ -6489,8 +6627,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
6489
6627
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
6490
6628
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
6491
6629
|
let resolvePending;
|
|
6492
|
-
const sttPending = new Promise((
|
|
6493
|
-
resolvePending =
|
|
6630
|
+
const sttPending = new Promise((resolve43) => {
|
|
6631
|
+
resolvePending = resolve43;
|
|
6494
6632
|
});
|
|
6495
6633
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
6496
6634
|
try {
|
|
@@ -6879,20 +7017,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
|
|
|
6879
7017
|
|
|
6880
7018
|
// server/routes/health.ts
|
|
6881
7019
|
function checkPort(port2, timeoutMs = 500) {
|
|
6882
|
-
return new Promise((
|
|
7020
|
+
return new Promise((resolve43) => {
|
|
6883
7021
|
const socket = createConnection2(port2, "127.0.0.1");
|
|
6884
7022
|
socket.setTimeout(timeoutMs);
|
|
6885
7023
|
socket.once("connect", () => {
|
|
6886
7024
|
socket.destroy();
|
|
6887
|
-
|
|
7025
|
+
resolve43(true);
|
|
6888
7026
|
});
|
|
6889
7027
|
socket.once("error", () => {
|
|
6890
7028
|
socket.destroy();
|
|
6891
|
-
|
|
7029
|
+
resolve43(false);
|
|
6892
7030
|
});
|
|
6893
7031
|
socket.once("timeout", () => {
|
|
6894
7032
|
socket.destroy();
|
|
6895
|
-
|
|
7033
|
+
resolve43(false);
|
|
6896
7034
|
});
|
|
6897
7035
|
});
|
|
6898
7036
|
}
|
|
@@ -7147,8 +7285,8 @@ function webchatTurnTimeoutMs() {
|
|
|
7147
7285
|
return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
|
|
7148
7286
|
}
|
|
7149
7287
|
function createChatRoutes(deps) {
|
|
7150
|
-
const
|
|
7151
|
-
|
|
7288
|
+
const app67 = new Hono();
|
|
7289
|
+
app67.post("/", async (c) => {
|
|
7152
7290
|
console.log(`[chat-route] entered route=public method=POST`);
|
|
7153
7291
|
const contentType = c.req.header("content-type") ?? "";
|
|
7154
7292
|
const account = resolveAccount();
|
|
@@ -7412,7 +7550,7 @@ ${result.result.text}` : result.result.text;
|
|
|
7412
7550
|
}
|
|
7413
7551
|
});
|
|
7414
7552
|
});
|
|
7415
|
-
return
|
|
7553
|
+
return app67;
|
|
7416
7554
|
}
|
|
7417
7555
|
|
|
7418
7556
|
// app/lib/channel-pty-bridge/admin-session-id.ts
|
|
@@ -7446,8 +7584,8 @@ function isLoopbackAddr(addr) {
|
|
|
7446
7584
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
7447
7585
|
}
|
|
7448
7586
|
function createScheduleInjectRoutes(deps) {
|
|
7449
|
-
const
|
|
7450
|
-
|
|
7587
|
+
const app67 = new Hono();
|
|
7588
|
+
app67.post("/", async (c) => {
|
|
7451
7589
|
const env = c.env;
|
|
7452
7590
|
const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
|
|
7453
7591
|
if (!isLoopbackAddr(remoteAddr)) {
|
|
@@ -7548,7 +7686,7 @@ function createScheduleInjectRoutes(deps) {
|
|
|
7548
7686
|
console.error(`${TAG20} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
|
|
7549
7687
|
return c.json({ ok: true }, 200);
|
|
7550
7688
|
});
|
|
7551
|
-
return
|
|
7689
|
+
return app67;
|
|
7552
7690
|
}
|
|
7553
7691
|
|
|
7554
7692
|
// server/index.ts
|
|
@@ -8231,8 +8369,8 @@ async function startLogin(opts) {
|
|
|
8231
8369
|
await clearAuth(authDir);
|
|
8232
8370
|
let resolveCode = null;
|
|
8233
8371
|
let rejectCode = null;
|
|
8234
|
-
const codePromise = new Promise((
|
|
8235
|
-
resolveCode =
|
|
8372
|
+
const codePromise = new Promise((resolve43, reject) => {
|
|
8373
|
+
resolveCode = resolve43;
|
|
8236
8374
|
rejectCode = reject;
|
|
8237
8375
|
});
|
|
8238
8376
|
const codeTimer = setTimeout(
|
|
@@ -8814,9 +8952,9 @@ function evaluateCallerScope(c, requestedAccountId) {
|
|
|
8814
8952
|
}
|
|
8815
8953
|
function callerScopeDenial(c, requestedAccountId) {
|
|
8816
8954
|
const { decision, callerAccountId, houseAdminScope } = evaluateCallerScope(c, requestedAccountId);
|
|
8817
|
-
if (decision.authorized) return null;
|
|
8955
|
+
if (decision.authorized) return { denial: null, callerAccountId };
|
|
8818
8956
|
console.error(`[whatsapp-read-tool] op=authz-deny requested=${requestedAccountId} caller=${callerAccountId ?? "none"} houseAdmin=${houseAdminScope ? "y" : "n"}`);
|
|
8819
|
-
return c.json({ error: decision.reason }, 403);
|
|
8957
|
+
return { denial: c.json({ error: decision.reason }, 403), callerAccountId };
|
|
8820
8958
|
}
|
|
8821
8959
|
function houseSocketScopeDenial(c, op) {
|
|
8822
8960
|
const houseAccountId = resolveAccount()?.accountId ?? "";
|
|
@@ -9244,7 +9382,7 @@ app2.get("/activity", (c) => {
|
|
|
9244
9382
|
app2.get("/conversations", (c) => {
|
|
9245
9383
|
try {
|
|
9246
9384
|
const requestedAccountId = validateAccountId(c.req.query("accountId") ?? null);
|
|
9247
|
-
const denial = callerScopeDenial(c, requestedAccountId);
|
|
9385
|
+
const { denial, callerAccountId } = callerScopeDenial(c, requestedAccountId);
|
|
9248
9386
|
if (denial) return denial;
|
|
9249
9387
|
const projection = projectionFor(requestedAccountId);
|
|
9250
9388
|
const storeAccountId = resolveReadStoreKey(projection.storeAccountId);
|
|
@@ -9265,7 +9403,7 @@ app2.get("/conversations", (c) => {
|
|
|
9265
9403
|
};
|
|
9266
9404
|
});
|
|
9267
9405
|
conversations.sort((a, b) => (b.lastMessageTimestamp ?? 0) - (a.lastMessageTimestamp ?? 0));
|
|
9268
|
-
console.error(`${TAG25} conversations requested=${requestedAccountId} account=${storeAccountId} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${allConversations.size > 0} count=${conversations.length}`);
|
|
9406
|
+
console.error(`${TAG25} conversations requested=${requestedAccountId} caller=${callerAccountId ?? "none"} account=${storeAccountId} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${allConversations.size > 0} count=${conversations.length}`);
|
|
9269
9407
|
return c.json({ conversations });
|
|
9270
9408
|
} catch (err) {
|
|
9271
9409
|
console.error(`${TAG25} conversations error: ${String(err)}`);
|
|
@@ -9275,7 +9413,7 @@ app2.get("/conversations", (c) => {
|
|
|
9275
9413
|
app2.get("/messages", (c) => {
|
|
9276
9414
|
try {
|
|
9277
9415
|
const requestedAccountId = validateAccountId(c.req.query("accountId") ?? null);
|
|
9278
|
-
const denial = callerScopeDenial(c, requestedAccountId);
|
|
9416
|
+
const { denial, callerAccountId } = callerScopeDenial(c, requestedAccountId);
|
|
9279
9417
|
if (denial) return denial;
|
|
9280
9418
|
const jid = c.req.query("jid");
|
|
9281
9419
|
if (!jid) {
|
|
@@ -9321,7 +9459,7 @@ app2.get("/messages", (c) => {
|
|
|
9321
9459
|
...reactions && reactions.length > 0 ? { reactions } : {}
|
|
9322
9460
|
};
|
|
9323
9461
|
});
|
|
9324
|
-
console.error(`${TAG25} messages requested=${requestedAccountId} account=${storeAccountId} jid=${jid} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${storeMessages.length > 0} limit=${effectiveLimit ?? "all"} returned=${messages.length} withAttachments=${withAttachments}`);
|
|
9462
|
+
console.error(`${TAG25} messages requested=${requestedAccountId} caller=${callerAccountId ?? "none"} account=${storeAccountId} jid=${jid} projected=${projecting} storeAccount=${projecting ? storeAccountId : "self"} managerPhonesBound=${managerPhonesBound} storeKeyFound=${storeMessages.length > 0} limit=${effectiveLimit ?? "all"} returned=${messages.length} withAttachments=${withAttachments}`);
|
|
9325
9463
|
return c.json({ messages });
|
|
9326
9464
|
} catch (err) {
|
|
9327
9465
|
console.error(`${TAG25} messages error: ${String(err)}`);
|
|
@@ -9334,7 +9472,7 @@ app2.get("/conversation-graph-state", async (c) => {
|
|
|
9334
9472
|
const jid = c.req.query("jid");
|
|
9335
9473
|
const accountIdQuery = c.req.query("accountId");
|
|
9336
9474
|
const t0 = Date.now();
|
|
9337
|
-
const denial = callerScopeDenial(c, validateAccountId(accountIdQuery ?? null));
|
|
9475
|
+
const { denial } = callerScopeDenial(c, validateAccountId(accountIdQuery ?? null));
|
|
9338
9476
|
if (denial) return denial;
|
|
9339
9477
|
if (!directCacheKey && !jid) {
|
|
9340
9478
|
const requestedAccountId = validateAccountId(accountIdQuery ?? null);
|
|
@@ -11657,16 +11795,6 @@ function asString(content) {
|
|
|
11657
11795
|
function tsOf(row) {
|
|
11658
11796
|
return typeof row.timestamp === "string" ? row.timestamp : null;
|
|
11659
11797
|
}
|
|
11660
|
-
function hasWebchatReply(content) {
|
|
11661
|
-
if (!Array.isArray(content)) return false;
|
|
11662
|
-
for (const block of content) {
|
|
11663
|
-
if (block && typeof block === "object") {
|
|
11664
|
-
const b = block;
|
|
11665
|
-
if (b.type === "tool_use" && b.name === WEBCHAT_REPLY_TOOL) return true;
|
|
11666
|
-
}
|
|
11667
|
-
}
|
|
11668
|
-
return false;
|
|
11669
|
-
}
|
|
11670
11798
|
function joinTextBlocks(content) {
|
|
11671
11799
|
if (!Array.isArray(content)) return "";
|
|
11672
11800
|
const parts = [];
|
|
@@ -11789,9 +11917,8 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
11789
11917
|
out.push({ kind: "agent-error", code, raw, ts });
|
|
11790
11918
|
continue;
|
|
11791
11919
|
}
|
|
11792
|
-
if (hasWebchatReply(msg?.content)) turnCtx.repliedThisTurn = true;
|
|
11793
11920
|
const isEnd = msg?.stop_reason === "end_turn";
|
|
11794
|
-
const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat"
|
|
11921
|
+
const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat";
|
|
11795
11922
|
out.push(...assistantTurns(msg?.content, ts, promoteFinal, erroredIds));
|
|
11796
11923
|
continue;
|
|
11797
11924
|
}
|
|
@@ -11800,7 +11927,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
11800
11927
|
if (content !== null && CHANNEL_WRAPPER2.test(content)) {
|
|
11801
11928
|
const u = unwrapChannel(content);
|
|
11802
11929
|
turnCtx.lastChannelSource = u.source;
|
|
11803
|
-
turnCtx.repliedThisTurn = false;
|
|
11804
11930
|
if (!isScheduleSource(content)) {
|
|
11805
11931
|
out.push(operatorInboundTurn(u, ts));
|
|
11806
11932
|
queuedPendingSuppress.set(u.text, (queuedPendingSuppress.get(u.text) ?? 0) + 1);
|
|
@@ -11814,7 +11940,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
11814
11940
|
if (isChannelQueued) {
|
|
11815
11941
|
const u = unwrapChannel(att.prompt);
|
|
11816
11942
|
turnCtx.lastChannelSource = u.source;
|
|
11817
|
-
turnCtx.repliedThisTurn = false;
|
|
11818
11943
|
if (!isScheduleSource(att.prompt)) {
|
|
11819
11944
|
renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
|
|
11820
11945
|
}
|
|
@@ -11844,7 +11969,6 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
11844
11969
|
if (isChannel) {
|
|
11845
11970
|
const u = unwrapChannel(text);
|
|
11846
11971
|
turnCtx.lastChannelSource = u.source;
|
|
11847
|
-
turnCtx.repliedThisTurn = false;
|
|
11848
11972
|
if (!isScheduleSource(text)) {
|
|
11849
11973
|
renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
|
|
11850
11974
|
}
|
|
@@ -13821,8 +13945,8 @@ async function reapplyLeversViaManager() {
|
|
|
13821
13945
|
var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
|
|
13822
13946
|
var sendSeq = 0;
|
|
13823
13947
|
function createWebchatRoutes(deps) {
|
|
13824
|
-
const
|
|
13825
|
-
|
|
13948
|
+
const app67 = new Hono();
|
|
13949
|
+
app67.post("/send", requireAdminSession, async (c) => {
|
|
13826
13950
|
let accountId;
|
|
13827
13951
|
try {
|
|
13828
13952
|
accountId = resolvePlatformAccountId();
|
|
@@ -14025,7 +14149,7 @@ ${note}` : note;
|
|
|
14025
14149
|
if (turnTimer.unref) turnTimer.unref();
|
|
14026
14150
|
return c.json({ ok: true });
|
|
14027
14151
|
});
|
|
14028
|
-
|
|
14152
|
+
app67.post("/interrupt", requireAdminSession, async (c) => {
|
|
14029
14153
|
const cacheKey = c.get("cacheKey");
|
|
14030
14154
|
const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
|
|
14031
14155
|
const primaryUserId = resolvePrimaryAdminUserId();
|
|
@@ -14053,7 +14177,7 @@ ${note}` : note;
|
|
|
14053
14177
|
}
|
|
14054
14178
|
return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
|
|
14055
14179
|
});
|
|
14056
|
-
|
|
14180
|
+
app67.post("/settings", requireAdminSession, async (c) => {
|
|
14057
14181
|
const body = await c.req.json().catch(() => null);
|
|
14058
14182
|
const op = body?.op;
|
|
14059
14183
|
const value = body?.value;
|
|
@@ -14093,7 +14217,7 @@ ${note}` : note;
|
|
|
14093
14217
|
console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
|
|
14094
14218
|
return c.json({ ok: true, settingsApplied });
|
|
14095
14219
|
});
|
|
14096
|
-
|
|
14220
|
+
app67.get("/session", requireAdminSession, async (c) => {
|
|
14097
14221
|
let accountId;
|
|
14098
14222
|
try {
|
|
14099
14223
|
accountId = resolvePlatformAccountId();
|
|
@@ -14171,7 +14295,7 @@ ${note}` : note;
|
|
|
14171
14295
|
const indicators = await fetchComposerIndicators(sessionId);
|
|
14172
14296
|
return c.json({ sessionId, projectDir, source, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
|
|
14173
14297
|
});
|
|
14174
|
-
|
|
14298
|
+
app67.post("/permission-verdict", requireAdminSession, async (c) => {
|
|
14175
14299
|
const body = await c.req.json().catch(() => null);
|
|
14176
14300
|
const sessionId = body?.sessionId;
|
|
14177
14301
|
const requestId = body?.request_id;
|
|
@@ -14188,7 +14312,7 @@ ${note}` : note;
|
|
|
14188
14312
|
const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
|
|
14189
14313
|
return c.json({ ok });
|
|
14190
14314
|
});
|
|
14191
|
-
return
|
|
14315
|
+
return app67;
|
|
14192
14316
|
}
|
|
14193
14317
|
|
|
14194
14318
|
// server/routes/webchat-greeting.ts
|
|
@@ -15544,15 +15668,15 @@ function operatorRoleFor(config, userId) {
|
|
|
15544
15668
|
async function buildAccountOptionList(accounts, userId) {
|
|
15545
15669
|
const houseAccount = accounts.find((a) => a.config.role === "house");
|
|
15546
15670
|
console.log(`[admin-accounts] op=list count=${accounts.length} house=${houseAccount?.accountId ?? "none"}`);
|
|
15547
|
-
const
|
|
15671
|
+
const resolve43 = async (a) => {
|
|
15548
15672
|
const businessName = await fetchAccountName(a.accountId) || void 0;
|
|
15549
15673
|
return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId), isHouse: a.config.role === "house" };
|
|
15550
15674
|
};
|
|
15551
15675
|
const houseOptions = await Promise.all(
|
|
15552
|
-
accounts.filter((a) => a.config.role === "house").map(
|
|
15676
|
+
accounts.filter((a) => a.config.role === "house").map(resolve43)
|
|
15553
15677
|
);
|
|
15554
15678
|
const nonHouseOptions = await Promise.all(
|
|
15555
|
-
accounts.filter((a) => a.config.role !== "house").map(
|
|
15679
|
+
accounts.filter((a) => a.config.role !== "house").map(resolve43)
|
|
15556
15680
|
);
|
|
15557
15681
|
const sortKey = (o) => (o.businessName || o.accountId).toLowerCase();
|
|
15558
15682
|
nonHouseOptions.sort((x, y) => {
|
|
@@ -23746,8 +23870,163 @@ app47.patch("/:eventId", requireAdminSession, async (c) => {
|
|
|
23746
23870
|
await session.close();
|
|
23747
23871
|
}
|
|
23748
23872
|
});
|
|
23873
|
+
app47.delete("/:eventId", requireAdminSession, async (c) => {
|
|
23874
|
+
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
23875
|
+
if (!accountId) {
|
|
23876
|
+
console.error('[admin:routines] op=delete auth-rejected reason="no account for session"');
|
|
23877
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
23878
|
+
}
|
|
23879
|
+
const eventId = c.req.param("eventId");
|
|
23880
|
+
const session = getSession();
|
|
23881
|
+
try {
|
|
23882
|
+
const res = await session.run(
|
|
23883
|
+
`MATCH (e:Event {eventId: $eventId, accountId: $accountId})
|
|
23884
|
+
WHERE ${AUTOMATION_WHERE}
|
|
23885
|
+
WITH e, e.name AS name
|
|
23886
|
+
DETACH DELETE e
|
|
23887
|
+
RETURN name`,
|
|
23888
|
+
{ eventId, accountId }
|
|
23889
|
+
);
|
|
23890
|
+
const found = res.records.length > 0;
|
|
23891
|
+
console.log(`[admin:routines] op=delete id=${eventId.slice(0, 8)} found=${found ? 1 : 0}`);
|
|
23892
|
+
return c.json({ found });
|
|
23893
|
+
} catch (err) {
|
|
23894
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23895
|
+
console.error(`[admin:routines] op=delete-fail id=${eventId.slice(0, 8)} err="${message}"`);
|
|
23896
|
+
return c.json({ error: `Delete failed: ${message}` }, 503);
|
|
23897
|
+
} finally {
|
|
23898
|
+
await session.close();
|
|
23899
|
+
}
|
|
23900
|
+
});
|
|
23749
23901
|
var routines_default = app47;
|
|
23750
23902
|
|
|
23903
|
+
// server/routes/admin/skills.ts
|
|
23904
|
+
import { existsSync as existsSync36, readdirSync as readdirSync24, readFileSync as readFileSync39, rmSync as rmSync3 } from "fs";
|
|
23905
|
+
import { resolve as resolve31 } from "path";
|
|
23906
|
+
var app48 = new Hono();
|
|
23907
|
+
var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
23908
|
+
function splitSkillMd(text) {
|
|
23909
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
23910
|
+
const fm = { name: "", description: "", publicEmbed: false };
|
|
23911
|
+
if (!m) return { frontmatter: fm, body: text };
|
|
23912
|
+
for (const line of m[1].split(/\r?\n/)) {
|
|
23913
|
+
const kv = line.match(/^([A-Za-z][\w-]*):[ \t]*(.*)$/);
|
|
23914
|
+
if (!kv) continue;
|
|
23915
|
+
const [, key, rawVal] = kv;
|
|
23916
|
+
const val = stripQuotes(rawVal.trim());
|
|
23917
|
+
if (key === "name") fm.name = val;
|
|
23918
|
+
else if (key === "description") fm.description = val;
|
|
23919
|
+
else if (key === "publicEmbed") fm.publicEmbed = val === "true";
|
|
23920
|
+
}
|
|
23921
|
+
return { frontmatter: fm, body: text.slice(m[0].length) };
|
|
23922
|
+
}
|
|
23923
|
+
function stripQuotes(s) {
|
|
23924
|
+
if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) return s.slice(1, -1);
|
|
23925
|
+
return s;
|
|
23926
|
+
}
|
|
23927
|
+
function accountDirForSession(cacheKey) {
|
|
23928
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
23929
|
+
if (!accountId) return null;
|
|
23930
|
+
const match = listValidAccounts().find((a) => a.accountId === accountId);
|
|
23931
|
+
return match ? { accountId, accountDir: match.accountDir } : null;
|
|
23932
|
+
}
|
|
23933
|
+
function subdirs(dir) {
|
|
23934
|
+
if (!existsSync36(dir)) return [];
|
|
23935
|
+
try {
|
|
23936
|
+
return readdirSync24(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
23937
|
+
} catch {
|
|
23938
|
+
return [];
|
|
23939
|
+
}
|
|
23940
|
+
}
|
|
23941
|
+
app48.get("/", requireAdminSession, async (c) => {
|
|
23942
|
+
const acct = accountDirForSession(c.var.cacheKey);
|
|
23943
|
+
if (!acct) {
|
|
23944
|
+
console.error('[admin:skills] op=list auth-rejected reason="no account for session"');
|
|
23945
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
23946
|
+
}
|
|
23947
|
+
const pluginsDir = resolve31(acct.accountDir, "plugins");
|
|
23948
|
+
const skills = [];
|
|
23949
|
+
let pluginCount = 0;
|
|
23950
|
+
for (const plugin of subdirs(pluginsDir)) {
|
|
23951
|
+
pluginCount++;
|
|
23952
|
+
const skillsDir = resolve31(pluginsDir, plugin, "skills");
|
|
23953
|
+
for (const skill of subdirs(skillsDir)) {
|
|
23954
|
+
const skillMd = resolve31(skillsDir, skill, "SKILL.md");
|
|
23955
|
+
if (!existsSync36(skillMd)) continue;
|
|
23956
|
+
try {
|
|
23957
|
+
const { frontmatter } = splitSkillMd(readFileSync39(skillMd, "utf-8"));
|
|
23958
|
+
const refsDir = resolve31(skillsDir, skill, "references");
|
|
23959
|
+
const refCount = existsSync36(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
|
|
23960
|
+
skills.push({ plugin, skill, description: frontmatter.description, refCount });
|
|
23961
|
+
} catch (err) {
|
|
23962
|
+
console.error(`[admin:skills] op=list-skip plugin=${plugin} skill=${skill} reason="${err instanceof Error ? err.message : String(err)}"`);
|
|
23963
|
+
}
|
|
23964
|
+
}
|
|
23965
|
+
}
|
|
23966
|
+
skills.sort((a, b) => a.plugin.localeCompare(b.plugin) || a.skill.localeCompare(b.skill));
|
|
23967
|
+
console.log(`[admin:skills] op=list accountId=${acct.accountId.slice(0, 8)} plugins=${pluginCount} skills=${skills.length}`);
|
|
23968
|
+
return c.json({ skills });
|
|
23969
|
+
});
|
|
23970
|
+
app48.get("/:plugin/:skill", requireAdminSession, async (c) => {
|
|
23971
|
+
const acct = accountDirForSession(c.var.cacheKey);
|
|
23972
|
+
if (!acct) return c.json({ error: "Account not found for session" }, 401);
|
|
23973
|
+
const plugin = c.req.param("plugin");
|
|
23974
|
+
const skill = c.req.param("skill");
|
|
23975
|
+
if (!NAME_RE.test(plugin) || !NAME_RE.test(skill)) {
|
|
23976
|
+
console.error(`[admin:skills] op=get outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
|
|
23977
|
+
return c.json({ error: "Invalid plugin or skill name" }, 400);
|
|
23978
|
+
}
|
|
23979
|
+
const skillDir = resolve31(acct.accountDir, "plugins", plugin, "skills", skill);
|
|
23980
|
+
const skillMd = resolve31(skillDir, "SKILL.md");
|
|
23981
|
+
const found = existsSync36(skillMd);
|
|
23982
|
+
console.log(`[admin:skills] op=get plugin=${plugin} skill=${skill} found=${found}`);
|
|
23983
|
+
if (!found) return c.json({ error: "Skill not found" }, 404);
|
|
23984
|
+
try {
|
|
23985
|
+
const { frontmatter, body } = splitSkillMd(readFileSync39(skillMd, "utf-8"));
|
|
23986
|
+
const refsDir = resolve31(skillDir, "references");
|
|
23987
|
+
const references = existsSync36(refsDir) ? readdirSync24(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
|
|
23988
|
+
return c.json({ skill: { plugin, skill, frontmatter, body, references } });
|
|
23989
|
+
} catch (err) {
|
|
23990
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23991
|
+
console.error(`[admin:skills] op=get-fail plugin=${plugin} skill=${skill} err="${message}"`);
|
|
23992
|
+
return c.json({ error: `Skill unavailable: ${message}` }, 503);
|
|
23993
|
+
}
|
|
23994
|
+
});
|
|
23995
|
+
app48.delete("/:plugin/:skill", requireAdminSession, async (c) => {
|
|
23996
|
+
const acct = accountDirForSession(c.var.cacheKey);
|
|
23997
|
+
if (!acct) return c.json({ error: "Account not found for session" }, 401);
|
|
23998
|
+
const plugin = c.req.param("plugin");
|
|
23999
|
+
const skill = c.req.param("skill");
|
|
24000
|
+
if (!NAME_RE.test(plugin) || !NAME_RE.test(skill)) {
|
|
24001
|
+
console.error(`[admin:skills] op=delete outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
|
|
24002
|
+
return c.json({ error: "Invalid plugin or skill name" }, 400);
|
|
24003
|
+
}
|
|
24004
|
+
const pluginDir = resolve31(acct.accountDir, "plugins", plugin);
|
|
24005
|
+
const skillsDir = resolve31(pluginDir, "skills");
|
|
24006
|
+
const skillDir = resolve31(skillsDir, skill);
|
|
24007
|
+
if (!existsSync36(resolve31(skillDir, "SKILL.md"))) {
|
|
24008
|
+
console.error(`[admin:skills] op=delete outcome=rejected reason=not-found plugin=${plugin} skill=${skill}`);
|
|
24009
|
+
return c.json({ error: "Skill not found" }, 404);
|
|
24010
|
+
}
|
|
24011
|
+
try {
|
|
24012
|
+
rmSync3(skillDir, { recursive: true, force: true });
|
|
24013
|
+
const pluginDirRemoved = subdirs(skillsDir).length === 0;
|
|
24014
|
+
if (pluginDirRemoved) rmSync3(pluginDir, { recursive: true, force: true });
|
|
24015
|
+
const skillDirGone = !existsSync36(skillDir);
|
|
24016
|
+
if (!skillDirGone) {
|
|
24017
|
+
console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-incomplete skillDirGone=false`);
|
|
24018
|
+
return c.json({ error: "Delete did not remove the skill directory" }, 503);
|
|
24019
|
+
}
|
|
24020
|
+
console.log(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=ok skillDirGone=${skillDirGone} pluginDirRemoved=${pluginDirRemoved}`);
|
|
24021
|
+
return c.json({ ok: true, skillDirGone, pluginDirRemoved });
|
|
24022
|
+
} catch (err) {
|
|
24023
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
24024
|
+
console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-error err="${message}"`);
|
|
24025
|
+
return c.json({ error: `Delete failed: ${message}` }, 503);
|
|
24026
|
+
}
|
|
24027
|
+
});
|
|
24028
|
+
var skills_default = app48;
|
|
24029
|
+
|
|
23751
24030
|
// app/lib/time-entry-format.ts
|
|
23752
24031
|
function secondsBetween(startIso, endIso) {
|
|
23753
24032
|
const s = Date.parse(startIso);
|
|
@@ -23769,8 +24048,8 @@ function toNum(v) {
|
|
|
23769
24048
|
var TAG39 = "[task-timer]";
|
|
23770
24049
|
var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
|
|
23771
24050
|
var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
|
|
23772
|
-
var
|
|
23773
|
-
|
|
24051
|
+
var app49 = new Hono();
|
|
24052
|
+
app49.get("/", requireAdminSession, async (c) => {
|
|
23774
24053
|
const cacheKey = c.var.cacheKey;
|
|
23775
24054
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23776
24055
|
if (!accountId) {
|
|
@@ -23857,13 +24136,13 @@ app48.get("/", requireAdminSession, async (c) => {
|
|
|
23857
24136
|
await session.close();
|
|
23858
24137
|
}
|
|
23859
24138
|
});
|
|
23860
|
-
var tasks_list_default =
|
|
24139
|
+
var tasks_list_default = app49;
|
|
23861
24140
|
|
|
23862
24141
|
// server/routes/admin/task-timer-start.ts
|
|
23863
24142
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
23864
24143
|
var TAG40 = "[task-timer]";
|
|
23865
|
-
var
|
|
23866
|
-
|
|
24144
|
+
var app50 = new Hono();
|
|
24145
|
+
app50.post("/", requireAdminSession, async (c) => {
|
|
23867
24146
|
const cacheKey = c.var.cacheKey;
|
|
23868
24147
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23869
24148
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -23918,13 +24197,13 @@ app49.post("/", requireAdminSession, async (c) => {
|
|
|
23918
24197
|
await session.close();
|
|
23919
24198
|
}
|
|
23920
24199
|
});
|
|
23921
|
-
var task_timer_start_default =
|
|
24200
|
+
var task_timer_start_default = app50;
|
|
23922
24201
|
|
|
23923
24202
|
// server/routes/admin/task-timer-stop.ts
|
|
23924
24203
|
import neo4j5 from "neo4j-driver";
|
|
23925
24204
|
var TAG41 = "[task-timer]";
|
|
23926
|
-
var
|
|
23927
|
-
|
|
24205
|
+
var app51 = new Hono();
|
|
24206
|
+
app51.post("/", requireAdminSession, async (c) => {
|
|
23928
24207
|
const cacheKey = c.var.cacheKey;
|
|
23929
24208
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23930
24209
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -23991,12 +24270,12 @@ app50.post("/", requireAdminSession, async (c) => {
|
|
|
23991
24270
|
await session.close();
|
|
23992
24271
|
}
|
|
23993
24272
|
});
|
|
23994
|
-
var task_timer_stop_default =
|
|
24273
|
+
var task_timer_stop_default = app51;
|
|
23995
24274
|
|
|
23996
24275
|
// server/routes/admin/task-complete.ts
|
|
23997
24276
|
var TAG42 = "[task-timer]";
|
|
23998
|
-
var
|
|
23999
|
-
|
|
24277
|
+
var app52 = new Hono();
|
|
24278
|
+
app52.post("/", requireAdminSession, async (c) => {
|
|
24000
24279
|
const cacheKey = c.var.cacheKey;
|
|
24001
24280
|
const accountId = getAccountIdForSession(cacheKey);
|
|
24002
24281
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -24034,14 +24313,14 @@ app51.post("/", requireAdminSession, async (c) => {
|
|
|
24034
24313
|
await session.close();
|
|
24035
24314
|
}
|
|
24036
24315
|
});
|
|
24037
|
-
var task_complete_default =
|
|
24316
|
+
var task_complete_default = app52;
|
|
24038
24317
|
|
|
24039
24318
|
// server/routes/admin/task-time-adjust.ts
|
|
24040
24319
|
import { randomUUID as randomUUID15 } from "crypto";
|
|
24041
24320
|
import neo4j6 from "neo4j-driver";
|
|
24042
24321
|
var TAG43 = "[task-time-adjust]";
|
|
24043
|
-
var
|
|
24044
|
-
|
|
24322
|
+
var app53 = new Hono();
|
|
24323
|
+
app53.post("/", requireAdminSession, async (c) => {
|
|
24045
24324
|
const cacheKey = c.var.cacheKey;
|
|
24046
24325
|
const accountId = getAccountIdForSession(cacheKey);
|
|
24047
24326
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -24115,11 +24394,11 @@ app52.post("/", requireAdminSession, async (c) => {
|
|
|
24115
24394
|
await session.close();
|
|
24116
24395
|
}
|
|
24117
24396
|
});
|
|
24118
|
-
var task_time_adjust_default =
|
|
24397
|
+
var task_time_adjust_default = app53;
|
|
24119
24398
|
|
|
24120
24399
|
// server/routes/admin/activity.ts
|
|
24121
|
-
import { readdirSync as
|
|
24122
|
-
var
|
|
24400
|
+
import { readdirSync as readdirSync25 } from "fs";
|
|
24401
|
+
var app54 = new Hono();
|
|
24123
24402
|
var TAG44 = "[activity]";
|
|
24124
24403
|
function resolveHouseAccountId(accounts) {
|
|
24125
24404
|
const houses = accounts.filter((a) => a.config.role === "house");
|
|
@@ -24134,14 +24413,14 @@ function requestToken() {
|
|
|
24134
24413
|
var short = (id) => id ? id.slice(0, 8) : "unset";
|
|
24135
24414
|
function countAccountDirsOnDisk() {
|
|
24136
24415
|
try {
|
|
24137
|
-
return
|
|
24416
|
+
return readdirSync25(ACCOUNTS_DIR, { withFileTypes: true }).filter(
|
|
24138
24417
|
(e) => e.isDirectory() && !e.name.startsWith(".")
|
|
24139
24418
|
).length;
|
|
24140
24419
|
} catch {
|
|
24141
24420
|
return null;
|
|
24142
24421
|
}
|
|
24143
24422
|
}
|
|
24144
|
-
|
|
24423
|
+
app54.get("/", requireAdminSession, async (c) => {
|
|
24145
24424
|
const req = requestToken();
|
|
24146
24425
|
const cacheKey = c.var.cacheKey;
|
|
24147
24426
|
const caller2 = getAccountIdForSession(cacheKey) ?? null;
|
|
@@ -24250,61 +24529,62 @@ app53.get("/", requireAdminSession, async (c) => {
|
|
|
24250
24529
|
}
|
|
24251
24530
|
});
|
|
24252
24531
|
});
|
|
24253
|
-
var activity_default =
|
|
24532
|
+
var activity_default = app54;
|
|
24254
24533
|
|
|
24255
24534
|
// server/routes/admin/index.ts
|
|
24256
|
-
var
|
|
24257
|
-
|
|
24258
|
-
|
|
24259
|
-
|
|
24260
|
-
|
|
24261
|
-
|
|
24262
|
-
|
|
24263
|
-
|
|
24264
|
-
|
|
24265
|
-
|
|
24266
|
-
|
|
24267
|
-
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24271
|
-
|
|
24272
|
-
|
|
24273
|
-
|
|
24274
|
-
|
|
24275
|
-
|
|
24276
|
-
|
|
24277
|
-
|
|
24278
|
-
|
|
24279
|
-
|
|
24280
|
-
|
|
24281
|
-
|
|
24282
|
-
|
|
24283
|
-
|
|
24284
|
-
|
|
24285
|
-
|
|
24286
|
-
|
|
24287
|
-
|
|
24288
|
-
|
|
24289
|
-
|
|
24290
|
-
|
|
24291
|
-
|
|
24292
|
-
|
|
24293
|
-
|
|
24294
|
-
|
|
24295
|
-
|
|
24296
|
-
|
|
24297
|
-
|
|
24298
|
-
|
|
24299
|
-
|
|
24300
|
-
|
|
24535
|
+
var app55 = new Hono();
|
|
24536
|
+
app55.route("/session", session_default);
|
|
24537
|
+
app55.route("/accounts", accounts_default);
|
|
24538
|
+
app55.route("/logs", logs_default);
|
|
24539
|
+
app55.route("/claude-info", claude_info_default);
|
|
24540
|
+
app55.route("/attachment", attachment_default);
|
|
24541
|
+
app55.route("/agents", agents_default);
|
|
24542
|
+
app55.route("/sessions", sessions_default);
|
|
24543
|
+
app55.route("/claude-sessions", claude_sessions_default);
|
|
24544
|
+
app55.route("/log-ingest", log_ingest_default);
|
|
24545
|
+
app55.route("/events", events_default);
|
|
24546
|
+
app55.route("/files", files_default);
|
|
24547
|
+
app55.route("/graph-search", graph_search_default);
|
|
24548
|
+
app55.route("/graph-subgraph", graph_subgraph_default);
|
|
24549
|
+
app55.route("/graph-delete", graph_delete_default);
|
|
24550
|
+
app55.route("/graph-restore", graph_restore_default);
|
|
24551
|
+
app55.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
24552
|
+
app55.route("/graph-default-view", graph_default_view_default);
|
|
24553
|
+
app55.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
24554
|
+
app55.route("/sidebar-sessions", sidebar_sessions_default);
|
|
24555
|
+
app55.route("/session-delete", session_delete_default);
|
|
24556
|
+
app55.route("/session-stop", session_stop_default);
|
|
24557
|
+
app55.route("/session-archive", session_archive_default);
|
|
24558
|
+
app55.route("/session-rename", session_rename_default);
|
|
24559
|
+
app55.route("/session-usage", session_usage_default);
|
|
24560
|
+
app55.route("/browser", browser_default);
|
|
24561
|
+
app55.route("/session-rc-spawn", session_rc_spawn_default);
|
|
24562
|
+
app55.route("/session-reseat", session_reseat_default);
|
|
24563
|
+
app55.route("/system-stats", system_stats_default);
|
|
24564
|
+
app55.route("/health-brand", health_default2);
|
|
24565
|
+
app55.route("/linkedin-ingest", linkedin_ingest_default);
|
|
24566
|
+
app55.route("/post-turn-context", post_turn_context_default);
|
|
24567
|
+
app55.route("/public-session-context", public_session_context_default);
|
|
24568
|
+
app55.route("/public-session-exit", public_session_exit_default);
|
|
24569
|
+
app55.route("/access-session-evict", access_session_evict_default);
|
|
24570
|
+
app55.route("/enrol-person", enrol_person_default);
|
|
24571
|
+
app55.route("/calendar", calendar_default);
|
|
24572
|
+
app55.route("/routines", routines_default);
|
|
24573
|
+
app55.route("/skills", skills_default);
|
|
24574
|
+
app55.route("/tasks-list", tasks_list_default);
|
|
24575
|
+
app55.route("/task-timer-start", task_timer_start_default);
|
|
24576
|
+
app55.route("/task-timer-stop", task_timer_stop_default);
|
|
24577
|
+
app55.route("/task-complete", task_complete_default);
|
|
24578
|
+
app55.route("/task-time-adjust", task_time_adjust_default);
|
|
24579
|
+
app55.route("/activity", activity_default);
|
|
24580
|
+
var admin_default = app55;
|
|
24301
24581
|
|
|
24302
24582
|
// server/routes/access/verify-token.ts
|
|
24303
24583
|
var TAG45 = "[access-verify]";
|
|
24304
24584
|
var MINT_TAG = "[access-session-mint]";
|
|
24305
24585
|
var COOKIE_NAME = "__access_session";
|
|
24306
|
-
var
|
|
24307
|
-
|
|
24586
|
+
var app56 = new Hono();
|
|
24587
|
+
app56.post("/", async (c) => {
|
|
24308
24588
|
const ip = c.var.clientIp || "unknown";
|
|
24309
24589
|
let body;
|
|
24310
24590
|
try {
|
|
@@ -24386,13 +24666,13 @@ app55.post("/", async (c) => {
|
|
|
24386
24666
|
displayName: grant.displayName
|
|
24387
24667
|
});
|
|
24388
24668
|
});
|
|
24389
|
-
var verify_token_default =
|
|
24669
|
+
var verify_token_default = app56;
|
|
24390
24670
|
|
|
24391
24671
|
// app/lib/access-email.ts
|
|
24392
24672
|
import { spawn as spawn2 } from "child_process";
|
|
24393
|
-
import { resolve as
|
|
24394
|
-
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ??
|
|
24395
|
-
var SEND_SCRIPT =
|
|
24673
|
+
import { resolve as resolve32 } from "path";
|
|
24674
|
+
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve32(process.cwd(), "..");
|
|
24675
|
+
var SEND_SCRIPT = resolve32(
|
|
24396
24676
|
PLATFORM_ROOT7,
|
|
24397
24677
|
"plugins",
|
|
24398
24678
|
"email",
|
|
@@ -24449,9 +24729,9 @@ async function sendMagicLinkEmail(payload) {
|
|
|
24449
24729
|
|
|
24450
24730
|
// server/routes/access/request-magic-link.ts
|
|
24451
24731
|
var TAG46 = "[access-request-link]";
|
|
24452
|
-
var
|
|
24732
|
+
var app57 = new Hono();
|
|
24453
24733
|
var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
|
|
24454
|
-
|
|
24734
|
+
app57.post("/", async (c) => {
|
|
24455
24735
|
let body;
|
|
24456
24736
|
try {
|
|
24457
24737
|
body = await c.req.json();
|
|
@@ -24525,17 +24805,17 @@ app56.post("/", async (c) => {
|
|
|
24525
24805
|
);
|
|
24526
24806
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
24527
24807
|
});
|
|
24528
|
-
var request_magic_link_default =
|
|
24808
|
+
var request_magic_link_default = app57;
|
|
24529
24809
|
|
|
24530
24810
|
// server/routes/access/index.ts
|
|
24531
|
-
var
|
|
24532
|
-
|
|
24533
|
-
|
|
24534
|
-
var access_default =
|
|
24811
|
+
var app58 = new Hono();
|
|
24812
|
+
app58.route("/verify-token", verify_token_default);
|
|
24813
|
+
app58.route("/request-magic-link", request_magic_link_default);
|
|
24814
|
+
var access_default = app58;
|
|
24535
24815
|
|
|
24536
24816
|
// server/routes/sites.ts
|
|
24537
|
-
import { existsSync as
|
|
24538
|
-
import { resolve as
|
|
24817
|
+
import { existsSync as existsSync37, readFileSync as readFileSync40, realpathSync as realpathSync7, statSync as statSync15 } from "fs";
|
|
24818
|
+
import { resolve as resolve33 } from "path";
|
|
24539
24819
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
24540
24820
|
var MIME = {
|
|
24541
24821
|
".html": "text/html; charset=utf-8",
|
|
@@ -24566,8 +24846,8 @@ function getExt(p) {
|
|
|
24566
24846
|
if (idx < p.lastIndexOf("/")) return "";
|
|
24567
24847
|
return p.slice(idx).toLowerCase();
|
|
24568
24848
|
}
|
|
24569
|
-
var
|
|
24570
|
-
|
|
24849
|
+
var app59 = new Hono();
|
|
24850
|
+
app59.get("/:rel{.*}", (c) => {
|
|
24571
24851
|
const reqPath = c.req.path;
|
|
24572
24852
|
const rawRel = c.req.param("rel") ?? "";
|
|
24573
24853
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -24592,15 +24872,15 @@ app58.get("/:rel{.*}", (c) => {
|
|
|
24592
24872
|
}
|
|
24593
24873
|
segments.push(seg);
|
|
24594
24874
|
}
|
|
24595
|
-
const rootDir =
|
|
24596
|
-
let filePath = segments.length === 0 ? rootDir :
|
|
24875
|
+
const rootDir = resolve33(account.accountDir, "sites");
|
|
24876
|
+
let filePath = segments.length === 0 ? rootDir : resolve33(rootDir, ...segments);
|
|
24597
24877
|
if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
|
|
24598
24878
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
24599
24879
|
return c.text("Forbidden", 403);
|
|
24600
24880
|
}
|
|
24601
24881
|
let stat11;
|
|
24602
24882
|
try {
|
|
24603
|
-
stat11 =
|
|
24883
|
+
stat11 = existsSync37(filePath) ? statSync15(filePath) : null;
|
|
24604
24884
|
} catch {
|
|
24605
24885
|
stat11 = null;
|
|
24606
24886
|
}
|
|
@@ -24613,13 +24893,13 @@ app58.get("/:rel{.*}", (c) => {
|
|
|
24613
24893
|
return c.redirect(target, 301);
|
|
24614
24894
|
}
|
|
24615
24895
|
if (stat11?.isDirectory()) {
|
|
24616
|
-
filePath =
|
|
24896
|
+
filePath = resolve33(filePath, "index.html");
|
|
24617
24897
|
}
|
|
24618
24898
|
if (!filePath.startsWith(rootDir + "/")) {
|
|
24619
24899
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
24620
24900
|
return c.text("Forbidden", 403);
|
|
24621
24901
|
}
|
|
24622
|
-
if (!
|
|
24902
|
+
if (!existsSync37(filePath)) {
|
|
24623
24903
|
console.error(`[sites] not-found path=${reqPath} status=404`);
|
|
24624
24904
|
return c.text("Not found", 404);
|
|
24625
24905
|
}
|
|
@@ -24638,7 +24918,7 @@ app58.get("/:rel{.*}", (c) => {
|
|
|
24638
24918
|
}
|
|
24639
24919
|
let body;
|
|
24640
24920
|
try {
|
|
24641
|
-
body =
|
|
24921
|
+
body = readFileSync40(realPath);
|
|
24642
24922
|
} catch (err) {
|
|
24643
24923
|
const code = err?.code;
|
|
24644
24924
|
if (code === "EISDIR") {
|
|
@@ -24670,11 +24950,11 @@ app58.get("/:rel{.*}", (c) => {
|
|
|
24670
24950
|
"X-Content-Type-Options": "nosniff"
|
|
24671
24951
|
});
|
|
24672
24952
|
});
|
|
24673
|
-
var sites_default =
|
|
24953
|
+
var sites_default = app59;
|
|
24674
24954
|
|
|
24675
24955
|
// app/lib/visitor-token.ts
|
|
24676
24956
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
24677
|
-
import { mkdirSync as mkdirSync8, readFileSync as
|
|
24957
|
+
import { mkdirSync as mkdirSync8, readFileSync as readFileSync41, writeFileSync as writeFileSync14 } from "fs";
|
|
24678
24958
|
import { dirname as dirname13 } from "path";
|
|
24679
24959
|
var TOKEN_PREFIX = "v1.";
|
|
24680
24960
|
var SECRET_BYTES = 32;
|
|
@@ -24683,7 +24963,7 @@ var cachedSecret = null;
|
|
|
24683
24963
|
function getSecret() {
|
|
24684
24964
|
if (cachedSecret) return cachedSecret;
|
|
24685
24965
|
try {
|
|
24686
|
-
const hex2 =
|
|
24966
|
+
const hex2 = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
|
|
24687
24967
|
if (hex2.length === SECRET_BYTES * 2) {
|
|
24688
24968
|
cachedSecret = Buffer.from(hex2, "hex");
|
|
24689
24969
|
return cachedSecret;
|
|
@@ -24697,7 +24977,7 @@ function getSecret() {
|
|
|
24697
24977
|
console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
|
|
24698
24978
|
} catch {
|
|
24699
24979
|
}
|
|
24700
|
-
const hex =
|
|
24980
|
+
const hex = readFileSync41(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
|
|
24701
24981
|
cachedSecret = Buffer.from(hex, "hex");
|
|
24702
24982
|
return cachedSecret;
|
|
24703
24983
|
}
|
|
@@ -24750,7 +25030,7 @@ var VISITOR_COOKIE_NAME = "mxy_v";
|
|
|
24750
25030
|
var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
|
|
24751
25031
|
|
|
24752
25032
|
// app/lib/brand-config.ts
|
|
24753
|
-
import { existsSync as
|
|
25033
|
+
import { existsSync as existsSync38, readFileSync as readFileSync42 } from "fs";
|
|
24754
25034
|
import { join as join43 } from "path";
|
|
24755
25035
|
var cached2 = null;
|
|
24756
25036
|
var cachedAttempted = false;
|
|
@@ -24760,9 +25040,9 @@ function readBrandConfig() {
|
|
|
24760
25040
|
const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
|
|
24761
25041
|
if (!platformRoot5) return null;
|
|
24762
25042
|
const brandPath = join43(platformRoot5, "config", "brand.json");
|
|
24763
|
-
if (!
|
|
25043
|
+
if (!existsSync38(brandPath)) return null;
|
|
24764
25044
|
try {
|
|
24765
|
-
cached2 = JSON.parse(
|
|
25045
|
+
cached2 = JSON.parse(readFileSync42(brandPath, "utf-8"));
|
|
24766
25046
|
return cached2;
|
|
24767
25047
|
} catch {
|
|
24768
25048
|
return null;
|
|
@@ -24770,7 +25050,7 @@ function readBrandConfig() {
|
|
|
24770
25050
|
}
|
|
24771
25051
|
|
|
24772
25052
|
// server/routes/visitor-consent.ts
|
|
24773
|
-
var
|
|
25053
|
+
var app60 = new Hono();
|
|
24774
25054
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
24775
25055
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
24776
25056
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -24815,17 +25095,17 @@ function siteSlugFromReferer(referer) {
|
|
|
24815
25095
|
return "";
|
|
24816
25096
|
}
|
|
24817
25097
|
}
|
|
24818
|
-
|
|
25098
|
+
app60.options("/consent", (c) => {
|
|
24819
25099
|
const origin = getOrigin(c);
|
|
24820
25100
|
setCorsHeaders(c, origin);
|
|
24821
25101
|
return c.body(null, 204);
|
|
24822
25102
|
});
|
|
24823
|
-
|
|
25103
|
+
app60.options("/brand-config", (c) => {
|
|
24824
25104
|
const origin = getOrigin(c);
|
|
24825
25105
|
setCorsHeaders(c, origin);
|
|
24826
25106
|
return c.body(null, 204);
|
|
24827
25107
|
});
|
|
24828
|
-
|
|
25108
|
+
app60.post("/consent", async (c) => {
|
|
24829
25109
|
const origin = getOrigin(c);
|
|
24830
25110
|
setCorsHeaders(c, origin);
|
|
24831
25111
|
let raw;
|
|
@@ -24865,7 +25145,7 @@ app59.post("/consent", async (c) => {
|
|
|
24865
25145
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
24866
25146
|
return c.body(null, 204);
|
|
24867
25147
|
});
|
|
24868
|
-
|
|
25148
|
+
app60.get("/brand-config", (c) => {
|
|
24869
25149
|
const origin = getOrigin(c);
|
|
24870
25150
|
setCorsHeaders(c, origin);
|
|
24871
25151
|
const brand = readBrandConfig();
|
|
@@ -24875,7 +25155,7 @@ app59.get("/brand-config", (c) => {
|
|
|
24875
25155
|
c.header("Cache-Control", "public, max-age=300");
|
|
24876
25156
|
return c.json({ consent: { copy, palette } });
|
|
24877
25157
|
});
|
|
24878
|
-
var visitor_consent_default =
|
|
25158
|
+
var visitor_consent_default = app60;
|
|
24879
25159
|
|
|
24880
25160
|
// server/routes/listings.ts
|
|
24881
25161
|
function getCookie(headerValue, name) {
|
|
@@ -24902,8 +25182,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
24902
25182
|
}
|
|
24903
25183
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
24904
25184
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
24905
|
-
var
|
|
24906
|
-
|
|
25185
|
+
var app61 = new Hono();
|
|
25186
|
+
app61.get("/:slug/click", async (c) => {
|
|
24907
25187
|
const slug = c.req.param("slug") ?? "";
|
|
24908
25188
|
const rawSession = c.req.query("session") ?? "";
|
|
24909
25189
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -24967,10 +25247,10 @@ app60.get("/:slug/click", async (c) => {
|
|
|
24967
25247
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
24968
25248
|
return c.redirect(redirectUrl, 302);
|
|
24969
25249
|
});
|
|
24970
|
-
var listings_default =
|
|
25250
|
+
var listings_default = app61;
|
|
24971
25251
|
|
|
24972
25252
|
// server/routes/visitor-event.ts
|
|
24973
|
-
var
|
|
25253
|
+
var app62 = new Hono();
|
|
24974
25254
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
24975
25255
|
var buckets = /* @__PURE__ */ new Map();
|
|
24976
25256
|
var RATE_LIMIT = 60;
|
|
@@ -25046,12 +25326,12 @@ function originAllowed(origin, allowlist) {
|
|
|
25046
25326
|
return false;
|
|
25047
25327
|
}
|
|
25048
25328
|
}
|
|
25049
|
-
|
|
25329
|
+
app62.options("/event", (c) => {
|
|
25050
25330
|
const origin = getOrigin2(c);
|
|
25051
25331
|
setCorsHeaders2(c, origin);
|
|
25052
25332
|
return c.body(null, 204);
|
|
25053
25333
|
});
|
|
25054
|
-
|
|
25334
|
+
app62.post("/event", async (c) => {
|
|
25055
25335
|
const origin = getOrigin2(c);
|
|
25056
25336
|
setCorsHeaders2(c, origin);
|
|
25057
25337
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -25256,17 +25536,17 @@ async function writeEvent(opts) {
|
|
|
25256
25536
|
);
|
|
25257
25537
|
}
|
|
25258
25538
|
}
|
|
25259
|
-
var visitor_event_default =
|
|
25539
|
+
var visitor_event_default = app62;
|
|
25260
25540
|
|
|
25261
25541
|
// server/routes/session.ts
|
|
25262
|
-
import { resolve as
|
|
25263
|
-
import { existsSync as
|
|
25542
|
+
import { resolve as resolve34 } from "path";
|
|
25543
|
+
import { existsSync as existsSync39, writeFileSync as writeFileSync15, mkdirSync as mkdirSync9 } from "fs";
|
|
25264
25544
|
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
25265
25545
|
function writeBrandingCache(accountId, agentSlug, branding) {
|
|
25266
25546
|
try {
|
|
25267
|
-
const cacheDir =
|
|
25547
|
+
const cacheDir = resolve34(MAXY_DIR, "branding-cache", accountId);
|
|
25268
25548
|
mkdirSync9(cacheDir, { recursive: true });
|
|
25269
|
-
writeFileSync15(
|
|
25549
|
+
writeFileSync15(resolve34(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
|
|
25270
25550
|
} catch (err) {
|
|
25271
25551
|
console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
25272
25552
|
}
|
|
@@ -25302,8 +25582,8 @@ function withVisitorCookie(response, visitorId) {
|
|
|
25302
25582
|
headers
|
|
25303
25583
|
});
|
|
25304
25584
|
}
|
|
25305
|
-
var
|
|
25306
|
-
|
|
25585
|
+
var app63 = new Hono();
|
|
25586
|
+
app63.post("/", async (c) => {
|
|
25307
25587
|
let body;
|
|
25308
25588
|
try {
|
|
25309
25589
|
body = await c.req.json();
|
|
@@ -25343,8 +25623,8 @@ app62.post("/", async (c) => {
|
|
|
25343
25623
|
}
|
|
25344
25624
|
let agentConfig = null;
|
|
25345
25625
|
if (account) {
|
|
25346
|
-
const agentDir =
|
|
25347
|
-
if (!
|
|
25626
|
+
const agentDir = resolve34(account.accountDir, "agents", agentSlug);
|
|
25627
|
+
if (!existsSync39(agentDir) || !existsSync39(resolve34(agentDir, "config.json"))) {
|
|
25348
25628
|
return c.json({ error: "Agent not found" }, 404);
|
|
25349
25629
|
}
|
|
25350
25630
|
agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
|
|
@@ -25450,7 +25730,7 @@ app62.post("/", async (c) => {
|
|
|
25450
25730
|
newVisitorId
|
|
25451
25731
|
);
|
|
25452
25732
|
});
|
|
25453
|
-
var session_default2 =
|
|
25733
|
+
var session_default2 = app63;
|
|
25454
25734
|
|
|
25455
25735
|
// server/lib/calendar-slots.ts
|
|
25456
25736
|
var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
@@ -25533,17 +25813,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
|
|
|
25533
25813
|
}
|
|
25534
25814
|
|
|
25535
25815
|
// server/routes/calendar-public.ts
|
|
25536
|
-
var
|
|
25816
|
+
var app64 = new Hono();
|
|
25537
25817
|
function setCors(c) {
|
|
25538
25818
|
c.header("Access-Control-Allow-Origin", "*");
|
|
25539
25819
|
c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
25540
25820
|
c.header("Access-Control-Allow-Headers", "content-type");
|
|
25541
25821
|
}
|
|
25542
|
-
|
|
25822
|
+
app64.options("/free-busy", (c) => {
|
|
25543
25823
|
setCors(c);
|
|
25544
25824
|
return c.body(null, 204);
|
|
25545
25825
|
});
|
|
25546
|
-
|
|
25826
|
+
app64.get("/free-busy", async (c) => {
|
|
25547
25827
|
setCors(c);
|
|
25548
25828
|
const from = c.req.query("from");
|
|
25549
25829
|
const to = c.req.query("to");
|
|
@@ -25599,14 +25879,14 @@ app63.get("/free-busy", async (c) => {
|
|
|
25599
25879
|
await session.close();
|
|
25600
25880
|
}
|
|
25601
25881
|
});
|
|
25602
|
-
var calendar_public_default =
|
|
25882
|
+
var calendar_public_default = app64;
|
|
25603
25883
|
|
|
25604
25884
|
// server/routes/portal-fetch.ts
|
|
25605
25885
|
import { createReadStream as createReadStream3 } from "fs";
|
|
25606
25886
|
import { stat as stat8, readFile as readFile8, realpath } from "fs/promises";
|
|
25607
|
-
import { join as join44, resolve as
|
|
25887
|
+
import { join as join44, resolve as resolve35, sep as sep9 } from "path";
|
|
25608
25888
|
import { Readable as Readable3 } from "stream";
|
|
25609
|
-
var
|
|
25889
|
+
var app65 = new Hono();
|
|
25610
25890
|
var TAG47 = "[portal-fetch]";
|
|
25611
25891
|
async function verifySignature(secret, accountId, relPath, expiresAtMs, signature, nowMs) {
|
|
25612
25892
|
if (!secret || !signature) return false;
|
|
@@ -25657,7 +25937,7 @@ ${expiresAtMs}`)
|
|
|
25657
25937
|
return diff === 0;
|
|
25658
25938
|
}
|
|
25659
25939
|
async function readAccountSecret(accountId) {
|
|
25660
|
-
const path3 =
|
|
25940
|
+
const path3 = resolve35(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
|
|
25661
25941
|
let text;
|
|
25662
25942
|
try {
|
|
25663
25943
|
text = await readFile8(path3, "utf8");
|
|
@@ -25693,7 +25973,7 @@ async function resolveFetchTarget(accountDir, relPath, ownerId) {
|
|
|
25693
25973
|
const exposeFolders = await readExposeFolders2(accountDir);
|
|
25694
25974
|
const { exposed } = resolveExposedDirs(schemaText, exposeFolders);
|
|
25695
25975
|
if (exposed.length === 0 && !ownerId) return { ok: false, reason: "not-exposed" };
|
|
25696
|
-
const lexical =
|
|
25976
|
+
const lexical = resolve35(accountDir, relPath);
|
|
25697
25977
|
let root;
|
|
25698
25978
|
let absolute;
|
|
25699
25979
|
try {
|
|
@@ -25742,7 +26022,7 @@ async function handle(c, headOnly) {
|
|
|
25742
26022
|
return c.json({ ok: false, error: "denied" }, 401);
|
|
25743
26023
|
}
|
|
25744
26024
|
const target = await resolveFetchTarget(
|
|
25745
|
-
|
|
26025
|
+
resolve35(DATA_ROOT, "accounts", accountId),
|
|
25746
26026
|
relPath,
|
|
25747
26027
|
owner || void 0
|
|
25748
26028
|
);
|
|
@@ -25769,9 +26049,9 @@ async function handle(c, headOnly) {
|
|
|
25769
26049
|
}
|
|
25770
26050
|
});
|
|
25771
26051
|
}
|
|
25772
|
-
|
|
25773
|
-
|
|
25774
|
-
var portal_fetch_default =
|
|
26052
|
+
app65.get("/fetch", (c) => handle(c, false));
|
|
26053
|
+
app65.on("HEAD", "/fetch", (c) => handle(c, true));
|
|
26054
|
+
var portal_fetch_default = app65;
|
|
25775
26055
|
|
|
25776
26056
|
// app/lib/timeentry-census.ts
|
|
25777
26057
|
var TAG48 = "[timeentry-census]";
|
|
@@ -25856,7 +26136,7 @@ function startTimeEntryCensus(openSession, opts = {}) {
|
|
|
25856
26136
|
}
|
|
25857
26137
|
|
|
25858
26138
|
// app/lib/ledger-census.ts
|
|
25859
|
-
import { readdirSync as
|
|
26139
|
+
import { readdirSync as readdirSync26, readFileSync as readFileSync43, statSync as statSync16 } from "fs";
|
|
25860
26140
|
import { join as join45 } from "path";
|
|
25861
26141
|
|
|
25862
26142
|
// ../lib/ledger-core/dist/reconcile.js
|
|
@@ -25905,7 +26185,7 @@ var DAY_MS = 864e5;
|
|
|
25905
26185
|
function countWriteRejects24h(logDir, now) {
|
|
25906
26186
|
let entries;
|
|
25907
26187
|
try {
|
|
25908
|
-
entries =
|
|
26188
|
+
entries = readdirSync26(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
|
|
25909
26189
|
} catch {
|
|
25910
26190
|
return 0;
|
|
25911
26191
|
}
|
|
@@ -25913,8 +26193,8 @@ function countWriteRejects24h(logDir, now) {
|
|
|
25913
26193
|
for (const name of entries) {
|
|
25914
26194
|
const path3 = join45(logDir, name);
|
|
25915
26195
|
try {
|
|
25916
|
-
if (now -
|
|
25917
|
-
for (const line of
|
|
26196
|
+
if (now - statSync16(path3).mtimeMs > DAY_MS) continue;
|
|
26197
|
+
for (const line of readFileSync43(path3, "utf8").split("\n")) {
|
|
25918
26198
|
if (line.includes("[graph-write] reject")) total += 1;
|
|
25919
26199
|
}
|
|
25920
26200
|
} catch {
|
|
@@ -26183,7 +26463,7 @@ function startGraphHealthTimer() {
|
|
|
26183
26463
|
|
|
26184
26464
|
// app/lib/file-watcher.ts
|
|
26185
26465
|
import * as fsp2 from "fs/promises";
|
|
26186
|
-
import { resolve as
|
|
26466
|
+
import { resolve as resolve36, sep as sep10 } from "path";
|
|
26187
26467
|
var ACCOUNT_UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
26188
26468
|
var DEFAULT_COALESCE_MS = 500;
|
|
26189
26469
|
var ROOTS = ["accounts"];
|
|
@@ -26202,7 +26482,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
26202
26482
|
const dropFn = opts.drop ?? dropFileIndex;
|
|
26203
26483
|
for (const r of ROOTS) {
|
|
26204
26484
|
try {
|
|
26205
|
-
await fsp2.mkdir(
|
|
26485
|
+
await fsp2.mkdir(resolve36(dataRoot, r), { recursive: true });
|
|
26206
26486
|
} catch (err) {
|
|
26207
26487
|
console.error(
|
|
26208
26488
|
`[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
|
|
@@ -26223,7 +26503,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
26223
26503
|
timers.set(relativePath, t);
|
|
26224
26504
|
}
|
|
26225
26505
|
async function runHook(relativePath, accountId) {
|
|
26226
|
-
const absolute =
|
|
26506
|
+
const absolute = resolve36(dataRoot, relativePath);
|
|
26227
26507
|
let exists = false;
|
|
26228
26508
|
try {
|
|
26229
26509
|
const st = await fsp2.stat(absolute);
|
|
@@ -26247,7 +26527,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
26247
26527
|
}
|
|
26248
26528
|
}
|
|
26249
26529
|
async function watchRoot(rootName) {
|
|
26250
|
-
const absRoot =
|
|
26530
|
+
const absRoot = resolve36(dataRoot, rootName);
|
|
26251
26531
|
try {
|
|
26252
26532
|
const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
|
|
26253
26533
|
for await (const event of iter) {
|
|
@@ -26286,7 +26566,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
26286
26566
|
|
|
26287
26567
|
// app/lib/migrate-uploads.ts
|
|
26288
26568
|
import { mkdir as mkdir6, readdir as readdir6, rename as rename3, rm as rm3 } from "fs/promises";
|
|
26289
|
-
import { dirname as dirname14, relative as relative7, resolve as
|
|
26569
|
+
import { dirname as dirname14, relative as relative7, resolve as resolve37 } from "path";
|
|
26290
26570
|
var ACCOUNT_UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
26291
26571
|
async function walkFiles(dir) {
|
|
26292
26572
|
const out = [];
|
|
@@ -26297,7 +26577,7 @@ async function walkFiles(dir) {
|
|
|
26297
26577
|
return out;
|
|
26298
26578
|
}
|
|
26299
26579
|
for (const e of entries) {
|
|
26300
|
-
const abs =
|
|
26580
|
+
const abs = resolve37(dir, e.name);
|
|
26301
26581
|
if (e.isDirectory()) {
|
|
26302
26582
|
out.push(...await walkFiles(abs));
|
|
26303
26583
|
} else if (e.isFile()) {
|
|
@@ -26317,7 +26597,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
|
|
|
26317
26597
|
let moved = 0;
|
|
26318
26598
|
for (const oldAbs of files) {
|
|
26319
26599
|
const suffix = relative7(srcDir, oldAbs);
|
|
26320
|
-
const newAbs =
|
|
26600
|
+
const newAbs = resolve37(destDir, suffix);
|
|
26321
26601
|
await mkdir6(dirname14(newAbs), { recursive: true });
|
|
26322
26602
|
await rename3(oldAbs, newAbs);
|
|
26323
26603
|
moved++;
|
|
@@ -26344,7 +26624,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
|
|
|
26344
26624
|
}
|
|
26345
26625
|
async function migrateUploads(opts = {}) {
|
|
26346
26626
|
const dataRoot = opts.dataRoot ?? DATA_ROOT;
|
|
26347
|
-
const oldRoot =
|
|
26627
|
+
const oldRoot = resolve37(dataRoot, "uploads");
|
|
26348
26628
|
let topEntries;
|
|
26349
26629
|
try {
|
|
26350
26630
|
topEntries = await readdir6(oldRoot, { withFileTypes: true });
|
|
@@ -26365,8 +26645,8 @@ async function migrateUploads(opts = {}) {
|
|
|
26365
26645
|
const name = entry.name;
|
|
26366
26646
|
if (ACCOUNT_UUID_RE5.test(name)) {
|
|
26367
26647
|
moved += await relocateTree(
|
|
26368
|
-
|
|
26369
|
-
|
|
26648
|
+
resolve37(oldRoot, name),
|
|
26649
|
+
resolve37(dataRoot, "accounts", name, "uploads"),
|
|
26370
26650
|
dataRoot,
|
|
26371
26651
|
name,
|
|
26372
26652
|
session
|
|
@@ -26378,8 +26658,8 @@ async function migrateUploads(opts = {}) {
|
|
|
26378
26658
|
continue;
|
|
26379
26659
|
}
|
|
26380
26660
|
moved += await relocateTree(
|
|
26381
|
-
|
|
26382
|
-
|
|
26661
|
+
resolve37(oldRoot, "public"),
|
|
26662
|
+
resolve37(dataRoot, "accounts", installAccountId, "uploads", "public"),
|
|
26383
26663
|
dataRoot,
|
|
26384
26664
|
null,
|
|
26385
26665
|
// public uploads carry no graph nodes
|
|
@@ -26409,7 +26689,7 @@ async function migrateUploads(opts = {}) {
|
|
|
26409
26689
|
|
|
26410
26690
|
// app/lib/migrate-admin-webchat-sidecars.ts
|
|
26411
26691
|
import { readdir as readdir7, readFile as readFile9, rename as rename4, writeFile as writeFile5, unlink as unlink4 } from "fs/promises";
|
|
26412
|
-
import { existsSync as
|
|
26692
|
+
import { existsSync as existsSync40 } from "fs";
|
|
26413
26693
|
import { join as join46 } from "path";
|
|
26414
26694
|
var ADMIN_ROLE2 = "admin";
|
|
26415
26695
|
var WEBCHAT_CHANNEL2 = "webchat";
|
|
@@ -26439,7 +26719,7 @@ async function writeRaw(path3, obj) {
|
|
|
26439
26719
|
await rename4(tmp, path3);
|
|
26440
26720
|
} catch (err) {
|
|
26441
26721
|
try {
|
|
26442
|
-
if (
|
|
26722
|
+
if (existsSync40(tmp)) await unlink4(tmp);
|
|
26443
26723
|
} catch {
|
|
26444
26724
|
}
|
|
26445
26725
|
throw err;
|
|
@@ -26828,8 +27108,8 @@ var streamSSE = (c, cb, onError) => {
|
|
|
26828
27108
|
|
|
26829
27109
|
// app/lib/whatsapp/gateway/routes.ts
|
|
26830
27110
|
function createWaChannelRoutes(deps) {
|
|
26831
|
-
const
|
|
26832
|
-
|
|
27111
|
+
const app67 = new Hono();
|
|
27112
|
+
app67.get("/wa-channel/inbound", (c) => {
|
|
26833
27113
|
const senderId = c.req.query("senderId");
|
|
26834
27114
|
if (!senderId) return c.json({ error: "senderId required" }, 400);
|
|
26835
27115
|
return streamSSE(c, async (stream2) => {
|
|
@@ -26847,7 +27127,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26847
27127
|
}
|
|
26848
27128
|
});
|
|
26849
27129
|
});
|
|
26850
|
-
|
|
27130
|
+
app67.post("/wa-channel/reply", async (c) => {
|
|
26851
27131
|
const body = await c.req.json().catch(() => null);
|
|
26852
27132
|
const senderId = body?.senderId;
|
|
26853
27133
|
const text = body?.text;
|
|
@@ -26868,7 +27148,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26868
27148
|
console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
|
|
26869
27149
|
return c.json({ ok: true });
|
|
26870
27150
|
});
|
|
26871
|
-
|
|
27151
|
+
app67.post("/wa-channel/reply-document", async (c) => {
|
|
26872
27152
|
const body = await c.req.json().catch(() => null);
|
|
26873
27153
|
const senderId = body?.senderId;
|
|
26874
27154
|
const files = body?.files;
|
|
@@ -26907,7 +27187,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26907
27187
|
}
|
|
26908
27188
|
return c.json({ ok: true, results });
|
|
26909
27189
|
});
|
|
26910
|
-
|
|
27190
|
+
app67.post("/wa-channel/ready", async (c) => {
|
|
26911
27191
|
const body = await c.req.json().catch(() => null);
|
|
26912
27192
|
const senderId = body?.senderId;
|
|
26913
27193
|
if (typeof senderId !== "string") {
|
|
@@ -26916,7 +27196,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26916
27196
|
deps.onReady?.(senderId);
|
|
26917
27197
|
return c.json({ ok: true });
|
|
26918
27198
|
});
|
|
26919
|
-
|
|
27199
|
+
app67.post("/wa-channel/received", async (c) => {
|
|
26920
27200
|
const body = await c.req.json().catch(() => null);
|
|
26921
27201
|
const senderId = body?.senderId;
|
|
26922
27202
|
const waMessageId = body?.waMessageId;
|
|
@@ -26926,7 +27206,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26926
27206
|
deps.onReceived?.(senderId, waMessageId);
|
|
26927
27207
|
return c.json({ ok: true });
|
|
26928
27208
|
});
|
|
26929
|
-
|
|
27209
|
+
app67.post("/wa-channel/turn-end", async (c) => {
|
|
26930
27210
|
const body = await c.req.json().catch(() => null);
|
|
26931
27211
|
const senderId = body?.senderId;
|
|
26932
27212
|
const sessionId = body?.sessionId;
|
|
@@ -26937,7 +27217,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26937
27217
|
const interactive = body?.interactive === true;
|
|
26938
27218
|
const finalText = typeof body?.finalText === "string" ? body.finalText : "";
|
|
26939
27219
|
const sid = sessionId.slice(0, 8);
|
|
26940
|
-
const deliver = interactive && finalText.trim().length > 0;
|
|
27220
|
+
const deliver = interactive && !replied && finalText.trim().length > 0;
|
|
26941
27221
|
if (deliver) {
|
|
26942
27222
|
const bytes = Buffer.byteLength(finalText, "utf8");
|
|
26943
27223
|
try {
|
|
@@ -26959,7 +27239,7 @@ function createWaChannelRoutes(deps) {
|
|
|
26959
27239
|
console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=none`);
|
|
26960
27240
|
return c.json({ ok: true, delivered: "none" });
|
|
26961
27241
|
});
|
|
26962
|
-
return
|
|
27242
|
+
return app67;
|
|
26963
27243
|
}
|
|
26964
27244
|
|
|
26965
27245
|
// app/lib/whatsapp/gateway/wa-gateway.ts
|
|
@@ -27374,8 +27654,8 @@ var InboundHub2 = class {
|
|
|
27374
27654
|
|
|
27375
27655
|
// app/lib/webchat/gateway/routes.ts
|
|
27376
27656
|
function createWebchatChannelRoutes(deps) {
|
|
27377
|
-
const
|
|
27378
|
-
|
|
27657
|
+
const app67 = new Hono();
|
|
27658
|
+
app67.get("/webchat-channel/inbound", (c) => {
|
|
27379
27659
|
const key = c.req.query("key");
|
|
27380
27660
|
if (!key) return c.json({ error: "key required" }, 400);
|
|
27381
27661
|
return streamSSE(c, async (stream2) => {
|
|
@@ -27393,7 +27673,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27393
27673
|
}
|
|
27394
27674
|
});
|
|
27395
27675
|
});
|
|
27396
|
-
|
|
27676
|
+
app67.post("/webchat-channel/reply", async (c) => {
|
|
27397
27677
|
const body = await c.req.json().catch(() => null);
|
|
27398
27678
|
const key = body?.key;
|
|
27399
27679
|
const text = body?.text;
|
|
@@ -27403,7 +27683,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27403
27683
|
deps.onReply?.(key, text);
|
|
27404
27684
|
return c.json({ ok: true });
|
|
27405
27685
|
});
|
|
27406
|
-
|
|
27686
|
+
app67.post("/webchat-channel/connector-auth", async (c) => {
|
|
27407
27687
|
const body = await c.req.json().catch(() => null);
|
|
27408
27688
|
const key = body?.key;
|
|
27409
27689
|
const sessionId = body?.sessionId;
|
|
@@ -27416,7 +27696,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27416
27696
|
const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
|
|
27417
27697
|
return c.json(result);
|
|
27418
27698
|
});
|
|
27419
|
-
|
|
27699
|
+
app67.post("/webchat-channel/ready", async (c) => {
|
|
27420
27700
|
const body = await c.req.json().catch(() => null);
|
|
27421
27701
|
const key = body?.key;
|
|
27422
27702
|
if (typeof key !== "string") {
|
|
@@ -27425,7 +27705,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27425
27705
|
deps.onReady?.(key);
|
|
27426
27706
|
return c.json({ ok: true });
|
|
27427
27707
|
});
|
|
27428
|
-
|
|
27708
|
+
app67.post("/webchat-channel/permission-request", async (c) => {
|
|
27429
27709
|
const body = await c.req.json().catch(() => null);
|
|
27430
27710
|
const key = body?.key;
|
|
27431
27711
|
const requestId = body?.request_id;
|
|
@@ -27439,7 +27719,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27439
27719
|
const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
|
|
27440
27720
|
return c.json(verdict);
|
|
27441
27721
|
});
|
|
27442
|
-
|
|
27722
|
+
app67.post("/webchat-channel/received", async (c) => {
|
|
27443
27723
|
const body = await c.req.json().catch(() => null);
|
|
27444
27724
|
const key = body?.key;
|
|
27445
27725
|
const messageId = body?.messageId;
|
|
@@ -27449,7 +27729,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27449
27729
|
deps.onReceived?.(key, messageId);
|
|
27450
27730
|
return c.json({ ok: true });
|
|
27451
27731
|
});
|
|
27452
|
-
|
|
27732
|
+
app67.post("/webchat-channel/turn-end", async (c) => {
|
|
27453
27733
|
const body = await c.req.json().catch(() => null);
|
|
27454
27734
|
const key = body?.key;
|
|
27455
27735
|
const sessionId = body?.sessionId;
|
|
@@ -27457,22 +27737,13 @@ function createWebchatChannelRoutes(deps) {
|
|
|
27457
27737
|
if (typeof key !== "string" || typeof sessionId !== "string" || typeof replied !== "boolean") {
|
|
27458
27738
|
return c.json({ error: "key, sessionId and replied required" }, 400);
|
|
27459
27739
|
}
|
|
27460
|
-
const interactive = body?.interactive === true;
|
|
27461
27740
|
const finalBytes = typeof body?.finalBytes === "number" && Number.isFinite(body.finalBytes) ? body.finalBytes : 0;
|
|
27462
27741
|
const k = key.slice(0, 8);
|
|
27463
27742
|
const sid = sessionId.slice(0, 8);
|
|
27464
|
-
|
|
27465
|
-
|
|
27466
|
-
return c.json({ ok: true, delivered: "reply" });
|
|
27467
|
-
}
|
|
27468
|
-
if (interactive && finalBytes > 0) {
|
|
27469
|
-
console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=no delivered=fallback bytes=${finalBytes}`);
|
|
27470
|
-
return c.json({ ok: true, delivered: "fallback" });
|
|
27471
|
-
}
|
|
27472
|
-
console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=no delivered=none`);
|
|
27473
|
-
return c.json({ ok: true, delivered: "none" });
|
|
27743
|
+
console.error(`[webchat-native] op=turn-end channel=webchat key=${k} sessionId=${sid} replied=${replied ? "yes" : "no"} trailing=${finalBytes}`);
|
|
27744
|
+
return c.json({ ok: true });
|
|
27474
27745
|
});
|
|
27475
|
-
return
|
|
27746
|
+
return app67;
|
|
27476
27747
|
}
|
|
27477
27748
|
|
|
27478
27749
|
// app/lib/webchat/gateway/webchat-gateway.ts
|
|
@@ -27530,16 +27801,16 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
27530
27801
|
* The public /api/chat route awaits this to return the reply on the same SSE
|
|
27531
27802
|
* response, preserving the pre-756 POST→single-blob browser contract. */
|
|
27532
27803
|
awaitReply(key, timeoutMs) {
|
|
27533
|
-
return new Promise((
|
|
27804
|
+
return new Promise((resolve43) => {
|
|
27534
27805
|
const timer = setTimeout(() => {
|
|
27535
27806
|
this.replyAwaiters.delete(key);
|
|
27536
|
-
|
|
27807
|
+
resolve43({ timeout: true });
|
|
27537
27808
|
}, timeoutMs);
|
|
27538
27809
|
if (timer.unref) timer.unref();
|
|
27539
27810
|
this.replyAwaiters.set(key, (r) => {
|
|
27540
27811
|
clearTimeout(timer);
|
|
27541
27812
|
this.replyAwaiters.delete(key);
|
|
27542
|
-
|
|
27813
|
+
resolve43(r);
|
|
27543
27814
|
});
|
|
27544
27815
|
});
|
|
27545
27816
|
}
|
|
@@ -27550,11 +27821,11 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
27550
27821
|
* terminal dialog stays answerable). */
|
|
27551
27822
|
awaitPermissionVerdict(p, timeoutMs) {
|
|
27552
27823
|
const k = _WebchatGateway.promptKey(p.key, p.requestId);
|
|
27553
|
-
return new Promise((
|
|
27824
|
+
return new Promise((resolve43) => {
|
|
27554
27825
|
this.pendingPrompts.get(k)?.resolve({ timeout: true });
|
|
27555
27826
|
const timer = setTimeout(() => {
|
|
27556
27827
|
this.pendingPrompts.delete(k);
|
|
27557
|
-
|
|
27828
|
+
resolve43({ timeout: true });
|
|
27558
27829
|
}, timeoutMs);
|
|
27559
27830
|
if (timer.unref) timer.unref();
|
|
27560
27831
|
this.pendingPrompts.set(k, {
|
|
@@ -27563,7 +27834,7 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
27563
27834
|
resolve: (r) => {
|
|
27564
27835
|
clearTimeout(timer);
|
|
27565
27836
|
this.pendingPrompts.delete(k);
|
|
27566
|
-
|
|
27837
|
+
resolve43(r);
|
|
27567
27838
|
}
|
|
27568
27839
|
});
|
|
27569
27840
|
console.error(`[webchat:perm] op=open key=${keyDisplay(p.key)} id=${p.requestId} tool=${p.toolName}`);
|
|
@@ -28128,7 +28399,7 @@ async function fanOut(subscribers, text, onError, tag) {
|
|
|
28128
28399
|
|
|
28129
28400
|
// app/lib/webchat/file-delivery.ts
|
|
28130
28401
|
import { realpathSync as realpathSync8 } from "fs";
|
|
28131
|
-
import { resolve as
|
|
28402
|
+
import { resolve as resolve38 } from "path";
|
|
28132
28403
|
|
|
28133
28404
|
// app/lib/channel-pty-bridge/file-delivery.ts
|
|
28134
28405
|
var SEND_USER_FILE = "SendUserFile";
|
|
@@ -28229,7 +28500,7 @@ function makeWebchatSendFile(entry) {
|
|
|
28229
28500
|
console.error(`${TAG51} file-delivery reject reason=no-account sender=${entry.senderId}`);
|
|
28230
28501
|
return { ok: false, error: "no-account" };
|
|
28231
28502
|
}
|
|
28232
|
-
const accountDir =
|
|
28503
|
+
const accountDir = resolve38(platformRoot2(), "..", "data/accounts", entry.accountId);
|
|
28233
28504
|
try {
|
|
28234
28505
|
const resolved = realpathSync8(filePath);
|
|
28235
28506
|
const accountResolved = realpathSync8(accountDir);
|
|
@@ -28556,8 +28827,8 @@ var InboundHub3 = class {
|
|
|
28556
28827
|
|
|
28557
28828
|
// app/lib/telegram/gateway/routes.ts
|
|
28558
28829
|
function createTelegramChannelRoutes(deps) {
|
|
28559
|
-
const
|
|
28560
|
-
|
|
28830
|
+
const app67 = new Hono();
|
|
28831
|
+
app67.get("/tg-channel/inbound", (c) => {
|
|
28561
28832
|
const key = c.req.query("key");
|
|
28562
28833
|
if (!key) return c.json({ error: "key required" }, 400);
|
|
28563
28834
|
return streamSSE(c, async (stream2) => {
|
|
@@ -28575,7 +28846,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28575
28846
|
}
|
|
28576
28847
|
});
|
|
28577
28848
|
});
|
|
28578
|
-
|
|
28849
|
+
app67.post("/tg-channel/reply", async (c) => {
|
|
28579
28850
|
const body = await c.req.json().catch(() => null);
|
|
28580
28851
|
const key = body?.key;
|
|
28581
28852
|
const text = body?.text;
|
|
@@ -28591,7 +28862,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28591
28862
|
console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
|
|
28592
28863
|
return c.json({ ok: true });
|
|
28593
28864
|
});
|
|
28594
|
-
|
|
28865
|
+
app67.post("/tg-channel/ready", async (c) => {
|
|
28595
28866
|
const body = await c.req.json().catch(() => null);
|
|
28596
28867
|
const key = body?.key;
|
|
28597
28868
|
if (typeof key !== "string") {
|
|
@@ -28600,7 +28871,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28600
28871
|
deps.onReady?.(key);
|
|
28601
28872
|
return c.json({ ok: true });
|
|
28602
28873
|
});
|
|
28603
|
-
|
|
28874
|
+
app67.post("/tg-channel/received", async (c) => {
|
|
28604
28875
|
const body = await c.req.json().catch(() => null);
|
|
28605
28876
|
const key = body?.key;
|
|
28606
28877
|
const messageId = body?.messageId;
|
|
@@ -28610,7 +28881,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28610
28881
|
deps.onReceived?.(key, messageId);
|
|
28611
28882
|
return c.json({ ok: true });
|
|
28612
28883
|
});
|
|
28613
|
-
|
|
28884
|
+
app67.post("/tg-channel/turn-end", async (c) => {
|
|
28614
28885
|
const body = await c.req.json().catch(() => null);
|
|
28615
28886
|
const key = body?.key;
|
|
28616
28887
|
const sessionId = body?.sessionId;
|
|
@@ -28621,7 +28892,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28621
28892
|
const interactive = body?.interactive === true;
|
|
28622
28893
|
const finalText = typeof body?.finalText === "string" ? body.finalText : "";
|
|
28623
28894
|
const sid = sessionId.slice(0, 8);
|
|
28624
|
-
const deliver = interactive && finalText.trim().length > 0;
|
|
28895
|
+
const deliver = interactive && !replied && finalText.trim().length > 0;
|
|
28625
28896
|
if (deliver) {
|
|
28626
28897
|
const bytes = Buffer.byteLength(finalText, "utf8");
|
|
28627
28898
|
try {
|
|
@@ -28643,7 +28914,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
28643
28914
|
console.error(`[telegram-native] op=turn-end key=${key} sessionId=${sid} replied=no delivered=none`);
|
|
28644
28915
|
return c.json({ ok: true, delivered: "none" });
|
|
28645
28916
|
});
|
|
28646
|
-
return
|
|
28917
|
+
return app67;
|
|
28647
28918
|
}
|
|
28648
28919
|
|
|
28649
28920
|
// app/lib/telegram/gateway/telegram-gateway.ts
|
|
@@ -28793,7 +29064,7 @@ function buildTelegramSpawnRequest(input) {
|
|
|
28793
29064
|
// app/lib/telegram/outbound/send-document.ts
|
|
28794
29065
|
import { realpathSync as realpathSync9 } from "fs";
|
|
28795
29066
|
import { readFile as readFile10, stat as stat10 } from "fs/promises";
|
|
28796
|
-
import { resolve as
|
|
29067
|
+
import { resolve as resolve39, basename as basename12 } from "path";
|
|
28797
29068
|
var TAG53 = "[telegram:outbound]";
|
|
28798
29069
|
var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
|
|
28799
29070
|
async function sendTelegramDocument(input) {
|
|
@@ -28804,7 +29075,7 @@ async function sendTelegramDocument(input) {
|
|
|
28804
29075
|
if (!maxyAccountId || !platformRoot5) {
|
|
28805
29076
|
return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
|
|
28806
29077
|
}
|
|
28807
|
-
const accountDir =
|
|
29078
|
+
const accountDir = resolve39(platformRoot5, "..", "data/accounts", maxyAccountId);
|
|
28808
29079
|
let accountResolved;
|
|
28809
29080
|
try {
|
|
28810
29081
|
accountResolved = realpathSync9(accountDir);
|
|
@@ -29196,14 +29467,14 @@ function warnOnChannelAdminBindingDrift() {
|
|
|
29196
29467
|
}
|
|
29197
29468
|
|
|
29198
29469
|
// server/lib/booking-site-accounts.ts
|
|
29199
|
-
import { existsSync as
|
|
29200
|
-
import { resolve as
|
|
29470
|
+
import { existsSync as existsSync41, readFileSync as readFileSync44 } from "fs";
|
|
29471
|
+
import { resolve as resolve40 } from "path";
|
|
29201
29472
|
function listBookingSiteAccounts(accounts) {
|
|
29202
29473
|
return accounts.filter((a) => {
|
|
29203
|
-
const availPath =
|
|
29204
|
-
if (!
|
|
29474
|
+
const availPath = resolve40(a.accountDir, "calendar-availability.json");
|
|
29475
|
+
if (!existsSync41(availPath)) return false;
|
|
29205
29476
|
try {
|
|
29206
|
-
const cfg = JSON.parse(
|
|
29477
|
+
const cfg = JSON.parse(readFileSync44(availPath, "utf-8"));
|
|
29207
29478
|
return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
|
|
29208
29479
|
} catch {
|
|
29209
29480
|
return false;
|
|
@@ -29241,8 +29512,8 @@ function broadcastAdminShutdown(reason) {
|
|
|
29241
29512
|
|
|
29242
29513
|
// ../lib/entitlement/src/index.ts
|
|
29243
29514
|
import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
|
|
29244
|
-
import { existsSync as
|
|
29245
|
-
import { resolve as
|
|
29515
|
+
import { existsSync as existsSync42, readFileSync as readFileSync45, statSync as statSync17 } from "fs";
|
|
29516
|
+
import { resolve as resolve41 } from "path";
|
|
29246
29517
|
|
|
29247
29518
|
// ../lib/entitlement/src/canonicalize.ts
|
|
29248
29519
|
function canonicalize(value) {
|
|
@@ -29277,7 +29548,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
|
|
|
29277
29548
|
var GRACE_DAYS = 7;
|
|
29278
29549
|
var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
|
|
29279
29550
|
function pubkeyPath(brand) {
|
|
29280
|
-
return
|
|
29551
|
+
return resolve41(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
|
|
29281
29552
|
}
|
|
29282
29553
|
var memo = null;
|
|
29283
29554
|
function memoKey(mtimeMs, account) {
|
|
@@ -29289,11 +29560,11 @@ function resolveEntitlement(brand, account) {
|
|
|
29289
29560
|
if (brand.commercialMode !== true) {
|
|
29290
29561
|
return logResolved(implicitTrust(account), null);
|
|
29291
29562
|
}
|
|
29292
|
-
const entitlementPath =
|
|
29293
|
-
if (!
|
|
29563
|
+
const entitlementPath = resolve41(brand.configDir, "entitlement.json");
|
|
29564
|
+
if (!existsSync42(entitlementPath)) {
|
|
29294
29565
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
29295
29566
|
}
|
|
29296
|
-
const stat11 =
|
|
29567
|
+
const stat11 = statSync17(entitlementPath);
|
|
29297
29568
|
const key = memoKey(stat11.mtimeMs, account);
|
|
29298
29569
|
if (memo && memo.key === key) {
|
|
29299
29570
|
return memo.result;
|
|
@@ -29305,7 +29576,7 @@ function resolveEntitlement(brand, account) {
|
|
|
29305
29576
|
function verifyAndResolve(brand, entitlementPath, account) {
|
|
29306
29577
|
let pubkeyPem;
|
|
29307
29578
|
try {
|
|
29308
|
-
pubkeyPem =
|
|
29579
|
+
pubkeyPem = readFileSync45(pubkeyPath(brand), "utf-8");
|
|
29309
29580
|
} catch (err) {
|
|
29310
29581
|
return logResolved(anonymousFallback("pubkey-missing"), {
|
|
29311
29582
|
reason: "pubkey-missing"
|
|
@@ -29319,7 +29590,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
|
|
|
29319
29590
|
}
|
|
29320
29591
|
let envelope;
|
|
29321
29592
|
try {
|
|
29322
|
-
envelope = JSON.parse(
|
|
29593
|
+
envelope = JSON.parse(readFileSync45(entitlementPath, "utf-8"));
|
|
29323
29594
|
} catch {
|
|
29324
29595
|
return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
|
|
29325
29596
|
}
|
|
@@ -29483,12 +29754,12 @@ installMediaDownloadGuard();
|
|
|
29483
29754
|
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
29484
29755
|
var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join47(PLATFORM_ROOT8, "config", "brand.json") : "";
|
|
29485
29756
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
|
|
29486
|
-
if (BRAND_JSON_PATH && !
|
|
29757
|
+
if (BRAND_JSON_PATH && !existsSync43(BRAND_JSON_PATH)) {
|
|
29487
29758
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
29488
29759
|
}
|
|
29489
|
-
if (BRAND_JSON_PATH &&
|
|
29760
|
+
if (BRAND_JSON_PATH && existsSync43(BRAND_JSON_PATH)) {
|
|
29490
29761
|
try {
|
|
29491
|
-
const parsed = JSON.parse(
|
|
29762
|
+
const parsed = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
|
|
29492
29763
|
BRAND = { ...BRAND, ...parsed };
|
|
29493
29764
|
} catch (err) {
|
|
29494
29765
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -29523,8 +29794,8 @@ var brandLoginOpts = {
|
|
|
29523
29794
|
var ALIAS_DOMAINS_PATH = join47(homedir4(), BRAND.configDir, "alias-domains.json");
|
|
29524
29795
|
function loadAliasDomains() {
|
|
29525
29796
|
try {
|
|
29526
|
-
if (!
|
|
29527
|
-
const parsed = JSON.parse(
|
|
29797
|
+
if (!existsSync43(ALIAS_DOMAINS_PATH)) return null;
|
|
29798
|
+
const parsed = JSON.parse(readFileSync46(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
29528
29799
|
if (!Array.isArray(parsed)) {
|
|
29529
29800
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
29530
29801
|
return null;
|
|
@@ -29548,7 +29819,7 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
|
|
|
29548
29819
|
function isPublicHost(host) {
|
|
29549
29820
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
29550
29821
|
}
|
|
29551
|
-
var
|
|
29822
|
+
var app66 = new Hono();
|
|
29552
29823
|
function resolveChannelOverride(accountId, channel, senderId) {
|
|
29553
29824
|
try {
|
|
29554
29825
|
const dir = listValidAccounts().find((a) => a.accountId === accountId)?.accountDir;
|
|
@@ -29597,7 +29868,7 @@ var waGateway = new WaGateway({
|
|
|
29597
29868
|
fetchStandingRules: fetchAccountStandingRules,
|
|
29598
29869
|
resolveSessionOverride: (accountId, senderId) => resolveChannelOverride(accountId, "whatsapp", senderId),
|
|
29599
29870
|
gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
|
|
29600
|
-
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ??
|
|
29871
|
+
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
|
|
29601
29872
|
// Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
|
|
29602
29873
|
// path-validation scope) is the sender's effective SESSION account, resolved
|
|
29603
29874
|
// once at the inbound gate and threaded here via the gateway's per-sender doc
|
|
@@ -29612,7 +29883,7 @@ var waGateway = new WaGateway({
|
|
|
29612
29883
|
caption,
|
|
29613
29884
|
accountId,
|
|
29614
29885
|
maxyAccountId,
|
|
29615
|
-
platformRoot:
|
|
29886
|
+
platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."))
|
|
29616
29887
|
});
|
|
29617
29888
|
return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
|
|
29618
29889
|
},
|
|
@@ -29724,7 +29995,7 @@ var waGateway = new WaGateway({
|
|
|
29724
29995
|
nativeFileFollowers.set(senderId, ac);
|
|
29725
29996
|
}
|
|
29726
29997
|
});
|
|
29727
|
-
|
|
29998
|
+
app66.route("/", waGateway.routes());
|
|
29728
29999
|
waGateway.startSweeper();
|
|
29729
30000
|
function runDuplicateSenderAudit() {
|
|
29730
30001
|
try {
|
|
@@ -29847,7 +30118,7 @@ var webchatGateway = new WebchatGateway({
|
|
|
29847
30118
|
firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
|
|
29848
30119
|
});
|
|
29849
30120
|
setWebchatGateway(webchatGateway);
|
|
29850
|
-
|
|
30121
|
+
app66.route("/", webchatGateway.routes());
|
|
29851
30122
|
webchatGateway.startSweeper();
|
|
29852
30123
|
webchatGateway.startPublicReaper();
|
|
29853
30124
|
var telegramFileFollowers = /* @__PURE__ */ new Map();
|
|
@@ -29891,7 +30162,7 @@ var telegramGateway = new TelegramGateway({
|
|
|
29891
30162
|
}
|
|
29892
30163
|
});
|
|
29893
30164
|
setTelegramGateway(telegramGateway);
|
|
29894
|
-
|
|
30165
|
+
app66.route("/", telegramGateway.routes());
|
|
29895
30166
|
telegramGateway.startSweeper();
|
|
29896
30167
|
var chatRoutes = createChatRoutes({
|
|
29897
30168
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
@@ -29925,19 +30196,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
|
|
|
29925
30196
|
return managed.account;
|
|
29926
30197
|
}
|
|
29927
30198
|
});
|
|
29928
|
-
|
|
29929
|
-
|
|
30199
|
+
app66.route("/api/channel/schedule-inject", scheduleInjectRoutes);
|
|
30200
|
+
app66.use("*", clientIpMiddleware);
|
|
29930
30201
|
function allowsSameOriginFraming(path3) {
|
|
29931
30202
|
return path3 === "/vnc-viewer.html" || path3.startsWith("/api/admin/attachment/") || path3.startsWith("/api/public-reader/attachment/") || path3 === "/api/admin/files/download";
|
|
29932
30203
|
}
|
|
29933
|
-
|
|
30204
|
+
app66.use("*", async (c, next) => {
|
|
29934
30205
|
await next();
|
|
29935
30206
|
c.header("X-Content-Type-Options", "nosniff");
|
|
29936
30207
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
29937
30208
|
c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
|
|
29938
30209
|
});
|
|
29939
30210
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
29940
|
-
|
|
30211
|
+
app66.use("*", async (c, next) => {
|
|
29941
30212
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
29942
30213
|
await next();
|
|
29943
30214
|
return;
|
|
@@ -29955,7 +30226,7 @@ app65.use("*", async (c, next) => {
|
|
|
29955
30226
|
});
|
|
29956
30227
|
}
|
|
29957
30228
|
});
|
|
29958
|
-
|
|
30229
|
+
app66.use("*", async (c, next) => {
|
|
29959
30230
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
29960
30231
|
if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
|
|
29961
30232
|
await next();
|
|
@@ -29993,7 +30264,7 @@ function resolveRemoteAuthOpts(c) {
|
|
|
29993
30264
|
return { ...brandLoginOpts, origin };
|
|
29994
30265
|
}
|
|
29995
30266
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
29996
|
-
|
|
30267
|
+
app66.post("/__remote-auth/login", async (c) => {
|
|
29997
30268
|
const client = clientFrom(c);
|
|
29998
30269
|
const clientIp = client.ip || "unknown";
|
|
29999
30270
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -30038,7 +30309,7 @@ app65.post("/__remote-auth/login", async (c) => {
|
|
|
30038
30309
|
}
|
|
30039
30310
|
});
|
|
30040
30311
|
});
|
|
30041
|
-
|
|
30312
|
+
app66.get("/__remote-auth/logout", (c) => {
|
|
30042
30313
|
const client = clientFrom(c);
|
|
30043
30314
|
const clientIp = client.ip || "unknown";
|
|
30044
30315
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -30051,7 +30322,7 @@ app65.get("/__remote-auth/logout", (c) => {
|
|
|
30051
30322
|
}
|
|
30052
30323
|
});
|
|
30053
30324
|
});
|
|
30054
|
-
|
|
30325
|
+
app66.post("/__remote-auth/change-password", async (c) => {
|
|
30055
30326
|
const client = clientFrom(c);
|
|
30056
30327
|
const clientIp = client.ip || "unknown";
|
|
30057
30328
|
const rateLimited = checkRateLimit(client);
|
|
@@ -30110,13 +30381,13 @@ app65.post("/__remote-auth/change-password", async (c) => {
|
|
|
30110
30381
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
30111
30382
|
}
|
|
30112
30383
|
});
|
|
30113
|
-
|
|
30384
|
+
app66.get("/__remote-auth/setup", (c) => {
|
|
30114
30385
|
if (isRemoteAuthConfigured()) {
|
|
30115
30386
|
return c.redirect("/");
|
|
30116
30387
|
}
|
|
30117
30388
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
|
|
30118
30389
|
});
|
|
30119
|
-
|
|
30390
|
+
app66.post("/__remote-auth/set-initial-password", async (c) => {
|
|
30120
30391
|
if (isRemoteAuthConfigured()) {
|
|
30121
30392
|
return c.redirect("/");
|
|
30122
30393
|
}
|
|
@@ -30154,10 +30425,10 @@ app65.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
30154
30425
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
30155
30426
|
}
|
|
30156
30427
|
});
|
|
30157
|
-
|
|
30428
|
+
app66.get("/api/remote-auth/status", (c) => {
|
|
30158
30429
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
30159
30430
|
});
|
|
30160
|
-
|
|
30431
|
+
app66.post("/api/remote-auth/set-password", async (c) => {
|
|
30161
30432
|
let body;
|
|
30162
30433
|
try {
|
|
30163
30434
|
body = await c.req.json();
|
|
@@ -30196,10 +30467,10 @@ app65.post("/api/remote-auth/set-password", async (c) => {
|
|
|
30196
30467
|
return c.json({ error: "Failed to save password" }, 500);
|
|
30197
30468
|
}
|
|
30198
30469
|
});
|
|
30199
|
-
|
|
30470
|
+
app66.route("/api/_client-error", client_error_default);
|
|
30200
30471
|
console.log("[client-error-route] mounted");
|
|
30201
30472
|
var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
|
|
30202
|
-
|
|
30473
|
+
app66.use("*", async (c, next) => {
|
|
30203
30474
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30204
30475
|
const path3 = c.req.path;
|
|
30205
30476
|
if (path3 === "/favicon.ico" || path3.startsWith("/assets/") || path3.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
|
|
@@ -30243,28 +30514,28 @@ app65.use("*", async (c, next) => {
|
|
|
30243
30514
|
}
|
|
30244
30515
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path3 }), 200);
|
|
30245
30516
|
});
|
|
30246
|
-
|
|
30247
|
-
|
|
30248
|
-
|
|
30249
|
-
|
|
30250
|
-
|
|
30251
|
-
|
|
30252
|
-
|
|
30517
|
+
app66.route("/api/health", health_default);
|
|
30518
|
+
app66.route("/api/chat", chatRoutes);
|
|
30519
|
+
app66.route("/api/whatsapp", whatsapp_default);
|
|
30520
|
+
app66.route("/api/storage", storage_broker_default);
|
|
30521
|
+
app66.route("/api/whatsapp-reader", whatsapp_reader_default);
|
|
30522
|
+
app66.route("/api/public-reader", public_reader_default);
|
|
30523
|
+
app66.route("/api/webchat", createWebchatRoutes({
|
|
30253
30524
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
30254
30525
|
// Task 940 — the permission relay's pointer read + verdict write.
|
|
30255
30526
|
pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
|
|
30256
30527
|
deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
|
|
30257
30528
|
resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
|
|
30258
30529
|
}));
|
|
30259
|
-
|
|
30260
|
-
|
|
30261
|
-
|
|
30262
|
-
|
|
30263
|
-
|
|
30264
|
-
|
|
30265
|
-
|
|
30266
|
-
|
|
30267
|
-
|
|
30530
|
+
app66.route("/api/webchat/greeting", webchat_greeting_default);
|
|
30531
|
+
app66.route("/api/telegram", telegram_default);
|
|
30532
|
+
app66.route("/api/quickbooks", quickbooks_default);
|
|
30533
|
+
app66.route("/api/onboarding", onboarding_default);
|
|
30534
|
+
app66.route("/api/admin", admin_default);
|
|
30535
|
+
app66.route("/api/access", access_default);
|
|
30536
|
+
app66.route("/api/session", session_default2);
|
|
30537
|
+
app66.route("/api/calendar", calendar_public_default);
|
|
30538
|
+
app66.route("/api/portal", portal_fetch_default);
|
|
30268
30539
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
30269
30540
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
30270
30541
|
var IMAGE_MIME = {
|
|
@@ -30276,7 +30547,7 @@ var IMAGE_MIME = {
|
|
|
30276
30547
|
".svg": "image/svg+xml",
|
|
30277
30548
|
".ico": "image/x-icon"
|
|
30278
30549
|
};
|
|
30279
|
-
|
|
30550
|
+
app66.get("/agent-assets/:slug/:filename", (c) => {
|
|
30280
30551
|
const slug = c.req.param("slug");
|
|
30281
30552
|
const filename = c.req.param("filename");
|
|
30282
30553
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -30292,26 +30563,26 @@ app65.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
30292
30563
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
30293
30564
|
return c.text("Not found", 404);
|
|
30294
30565
|
}
|
|
30295
|
-
const filePath =
|
|
30296
|
-
const expectedDir =
|
|
30566
|
+
const filePath = resolve42(account.accountDir, "agents", slug, "assets", filename);
|
|
30567
|
+
const expectedDir = resolve42(account.accountDir, "agents", slug, "assets");
|
|
30297
30568
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
30298
30569
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
30299
30570
|
return c.text("Forbidden", 403);
|
|
30300
30571
|
}
|
|
30301
|
-
if (!
|
|
30572
|
+
if (!existsSync43(filePath)) {
|
|
30302
30573
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
30303
30574
|
return c.text("Not found", 404);
|
|
30304
30575
|
}
|
|
30305
30576
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
30306
30577
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
30307
30578
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
30308
|
-
const body =
|
|
30579
|
+
const body = readFileSync46(filePath);
|
|
30309
30580
|
return c.body(body, 200, {
|
|
30310
30581
|
"Content-Type": contentType,
|
|
30311
30582
|
"Cache-Control": "public, max-age=3600"
|
|
30312
30583
|
});
|
|
30313
30584
|
});
|
|
30314
|
-
|
|
30585
|
+
app66.get("/generated/:filename", (c) => {
|
|
30315
30586
|
const filename = c.req.param("filename");
|
|
30316
30587
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
30317
30588
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -30322,35 +30593,35 @@ app65.get("/generated/:filename", (c) => {
|
|
|
30322
30593
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
30323
30594
|
return c.text("Not found", 404);
|
|
30324
30595
|
}
|
|
30325
|
-
const filePath =
|
|
30326
|
-
const expectedDir =
|
|
30596
|
+
const filePath = resolve42(account.accountDir, "generated", filename);
|
|
30597
|
+
const expectedDir = resolve42(account.accountDir, "generated");
|
|
30327
30598
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
30328
30599
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
30329
30600
|
return c.text("Forbidden", 403);
|
|
30330
30601
|
}
|
|
30331
|
-
if (!
|
|
30602
|
+
if (!existsSync43(filePath)) {
|
|
30332
30603
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
30333
30604
|
return c.text("Not found", 404);
|
|
30334
30605
|
}
|
|
30335
30606
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
30336
30607
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
30337
30608
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
30338
|
-
const body =
|
|
30609
|
+
const body = readFileSync46(filePath);
|
|
30339
30610
|
return c.body(body, 200, {
|
|
30340
30611
|
"Content-Type": contentType,
|
|
30341
30612
|
"Cache-Control": "public, max-age=86400"
|
|
30342
30613
|
});
|
|
30343
30614
|
});
|
|
30344
|
-
|
|
30345
|
-
|
|
30346
|
-
|
|
30347
|
-
|
|
30615
|
+
app66.route("/sites", sites_default);
|
|
30616
|
+
app66.route("/listings", listings_default);
|
|
30617
|
+
app66.route("/v", visitor_event_default);
|
|
30618
|
+
app66.route("/v", visitor_consent_default);
|
|
30348
30619
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
30349
30620
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
30350
30621
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
30351
|
-
if (BRAND_JSON_PATH &&
|
|
30622
|
+
if (BRAND_JSON_PATH && existsSync43(BRAND_JSON_PATH)) {
|
|
30352
30623
|
try {
|
|
30353
|
-
const fullBrand = JSON.parse(
|
|
30624
|
+
const fullBrand = JSON.parse(readFileSync46(BRAND_JSON_PATH, "utf-8"));
|
|
30354
30625
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
30355
30626
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
30356
30627
|
} catch {
|
|
@@ -30377,11 +30648,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
30377
30648
|
var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
|
|
30378
30649
|
var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
|
|
30379
30650
|
var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
|
|
30380
|
-
(p) =>
|
|
30651
|
+
(p) => existsSync43(resolve42(process.cwd(), "public", p.replace(/^\//, "")))
|
|
30381
30652
|
);
|
|
30382
30653
|
var SW_SOURCE = (() => {
|
|
30383
30654
|
try {
|
|
30384
|
-
return
|
|
30655
|
+
return readFileSync46(resolve42(process.cwd(), "public", "sw.js"), "utf-8");
|
|
30385
30656
|
} catch {
|
|
30386
30657
|
return null;
|
|
30387
30658
|
}
|
|
@@ -30390,8 +30661,8 @@ function readInstalledVersion() {
|
|
|
30390
30661
|
try {
|
|
30391
30662
|
if (!PLATFORM_ROOT8) return "unknown";
|
|
30392
30663
|
const versionFile = join47(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
|
|
30393
|
-
if (!
|
|
30394
|
-
const content =
|
|
30664
|
+
if (!existsSync43(versionFile)) return "unknown";
|
|
30665
|
+
const content = readFileSync46(versionFile, "utf-8").trim();
|
|
30395
30666
|
return content || "unknown";
|
|
30396
30667
|
} catch {
|
|
30397
30668
|
return "unknown";
|
|
@@ -30432,7 +30703,7 @@ var clientErrorReporterScript = `<script>
|
|
|
30432
30703
|
function cachedHtml(file) {
|
|
30433
30704
|
let html = htmlCache.get(file);
|
|
30434
30705
|
if (!html) {
|
|
30435
|
-
html =
|
|
30706
|
+
html = readFileSync46(resolve42(process.cwd(), "public", file), "utf-8");
|
|
30436
30707
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
30437
30708
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
30438
30709
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -30454,8 +30725,8 @@ function loadBrandingCache(agentSlug) {
|
|
|
30454
30725
|
const accountId = getDefaultAccountId();
|
|
30455
30726
|
if (!accountId) return null;
|
|
30456
30727
|
const cachePath = join47(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
30457
|
-
if (!
|
|
30458
|
-
return JSON.parse(
|
|
30728
|
+
if (!existsSync43(cachePath)) return null;
|
|
30729
|
+
return JSON.parse(readFileSync46(cachePath, "utf-8"));
|
|
30459
30730
|
} catch {
|
|
30460
30731
|
return null;
|
|
30461
30732
|
}
|
|
@@ -30499,7 +30770,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
30499
30770
|
function agentUnavailableHtml() {
|
|
30500
30771
|
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
|
|
30501
30772
|
}
|
|
30502
|
-
|
|
30773
|
+
app66.get("/", (c) => {
|
|
30503
30774
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30504
30775
|
const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
|
|
30505
30776
|
if (klass === "operator") {
|
|
@@ -30521,12 +30792,12 @@ app65.get("/", (c) => {
|
|
|
30521
30792
|
console.log(`[host-class] host=${host} class=admin served=index.html`);
|
|
30522
30793
|
return c.html(cachedHtml("index.html"));
|
|
30523
30794
|
});
|
|
30524
|
-
|
|
30795
|
+
app66.get("/public", (c) => {
|
|
30525
30796
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30526
30797
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30527
30798
|
return c.html(cachedHtml("public.html"));
|
|
30528
30799
|
});
|
|
30529
|
-
|
|
30800
|
+
app66.get("/public-chat", (c) => {
|
|
30530
30801
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30531
30802
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30532
30803
|
return c.html(cachedHtml("public.html"));
|
|
@@ -30545,12 +30816,12 @@ async function logViewerFetch(c, next) {
|
|
|
30545
30816
|
duration_ms: Date.now() - start
|
|
30546
30817
|
});
|
|
30547
30818
|
}
|
|
30548
|
-
|
|
30549
|
-
|
|
30550
|
-
|
|
30819
|
+
app66.use("/vnc-viewer.html", logViewerFetch);
|
|
30820
|
+
app66.use("/vnc-popout.html", logViewerFetch);
|
|
30821
|
+
app66.get("/vnc-popout.html", (c) => {
|
|
30551
30822
|
let html = htmlCache.get("vnc-popout.html");
|
|
30552
30823
|
if (!html) {
|
|
30553
|
-
html =
|
|
30824
|
+
html = readFileSync46(resolve42(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
30554
30825
|
const name = escapeHtml(BRAND.productName);
|
|
30555
30826
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
30556
30827
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -30560,7 +30831,7 @@ app65.get("/vnc-popout.html", (c) => {
|
|
|
30560
30831
|
}
|
|
30561
30832
|
return c.html(html);
|
|
30562
30833
|
});
|
|
30563
|
-
|
|
30834
|
+
app66.post("/api/vnc/client-event", async (c) => {
|
|
30564
30835
|
let body;
|
|
30565
30836
|
try {
|
|
30566
30837
|
body = await c.req.json();
|
|
@@ -30581,11 +30852,11 @@ app65.post("/api/vnc/client-event", async (c) => {
|
|
|
30581
30852
|
});
|
|
30582
30853
|
return c.json({ ok: true });
|
|
30583
30854
|
});
|
|
30584
|
-
|
|
30855
|
+
app66.get("/g/:slug", (c) => {
|
|
30585
30856
|
return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
|
|
30586
30857
|
});
|
|
30587
30858
|
for (const pwa of PWA_SURFACES) {
|
|
30588
|
-
|
|
30859
|
+
app66.get(pwa.manifestPath, (c) => {
|
|
30589
30860
|
const manifest = buildManifest(pwa, {
|
|
30590
30861
|
productName: BRAND.productName,
|
|
30591
30862
|
appIcon192: brandAppIcon192Path,
|
|
@@ -30601,7 +30872,7 @@ for (const pwa of PWA_SURFACES) {
|
|
|
30601
30872
|
return c.body(JSON.stringify(manifest));
|
|
30602
30873
|
});
|
|
30603
30874
|
}
|
|
30604
|
-
|
|
30875
|
+
app66.get("/sw.js", (c) => {
|
|
30605
30876
|
if (SW_SOURCE == null) {
|
|
30606
30877
|
console.error("[pwa] op=sw status=500 reason=sw-source-missing");
|
|
30607
30878
|
return c.text("Service worker unavailable", 500);
|
|
@@ -30610,12 +30881,12 @@ app65.get("/sw.js", (c) => {
|
|
|
30610
30881
|
console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
|
|
30611
30882
|
return c.body(SW_SOURCE);
|
|
30612
30883
|
});
|
|
30613
|
-
|
|
30884
|
+
app66.get("/graph", (c) => {
|
|
30614
30885
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30615
30886
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
30616
30887
|
return c.html(cachedHtml("graph.html"));
|
|
30617
30888
|
});
|
|
30618
|
-
|
|
30889
|
+
app66.get("/chat", (c) => {
|
|
30619
30890
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30620
30891
|
if (isOperatorHost(host, getOperatorDomains())) {
|
|
30621
30892
|
console.log(`[host-class] host=${host} class=operator served=operator.html`);
|
|
@@ -30624,37 +30895,42 @@ app65.get("/chat", (c) => {
|
|
|
30624
30895
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30625
30896
|
return c.html(cachedHtml("chat.html"));
|
|
30626
30897
|
});
|
|
30627
|
-
|
|
30898
|
+
app66.get("/data", (c) => {
|
|
30628
30899
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30629
30900
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30630
30901
|
return c.html(cachedHtml("data.html"));
|
|
30631
30902
|
});
|
|
30632
|
-
|
|
30903
|
+
app66.get("/tasks", (c) => {
|
|
30633
30904
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30634
30905
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30635
30906
|
return c.html(cachedHtml("tasks.html"));
|
|
30636
30907
|
});
|
|
30637
|
-
|
|
30908
|
+
app66.get("/activity", (c) => {
|
|
30638
30909
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30639
30910
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30640
30911
|
return c.html(cachedHtml("activity.html"));
|
|
30641
30912
|
});
|
|
30642
|
-
|
|
30913
|
+
app66.get("/calendar", (c) => {
|
|
30643
30914
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30644
30915
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30645
30916
|
return c.html(cachedHtml("calendar.html"));
|
|
30646
30917
|
});
|
|
30647
|
-
|
|
30918
|
+
app66.get("/routines", (c) => {
|
|
30648
30919
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30649
30920
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30650
30921
|
return c.html(cachedHtml("routines.html"));
|
|
30651
30922
|
});
|
|
30652
|
-
|
|
30923
|
+
app66.get("/skills", (c) => {
|
|
30924
|
+
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30925
|
+
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
30926
|
+
return c.html(cachedHtml("skills.html"));
|
|
30927
|
+
});
|
|
30928
|
+
app66.get("/browser", (c) => {
|
|
30653
30929
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30654
30930
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
30655
30931
|
return c.html(cachedHtml("browser.html"));
|
|
30656
30932
|
});
|
|
30657
|
-
|
|
30933
|
+
app66.get("/:slug", async (c, next) => {
|
|
30658
30934
|
const slug = c.req.param("slug");
|
|
30659
30935
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
30660
30936
|
const account = resolveAccount();
|
|
@@ -30669,13 +30945,13 @@ app65.get("/:slug", async (c, next) => {
|
|
|
30669
30945
|
await next();
|
|
30670
30946
|
});
|
|
30671
30947
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
30672
|
-
|
|
30948
|
+
app66.get("/favicon.ico", (c) => {
|
|
30673
30949
|
c.header("Cache-Control", "public, max-age=300");
|
|
30674
30950
|
return c.redirect(brandFaviconPath, 302);
|
|
30675
30951
|
});
|
|
30676
30952
|
}
|
|
30677
|
-
|
|
30678
|
-
|
|
30953
|
+
app66.use("/*", serveStatic({ root: "./public" }));
|
|
30954
|
+
app66.all("*", (c) => {
|
|
30679
30955
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
30680
30956
|
const path3 = c.req.path;
|
|
30681
30957
|
if (isPublicHost(host)) {
|
|
@@ -30689,13 +30965,13 @@ app65.all("*", (c) => {
|
|
|
30689
30965
|
});
|
|
30690
30966
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
30691
30967
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
30692
|
-
var httpServer = serve({ fetch:
|
|
30968
|
+
var httpServer = serve({ fetch: app66.fetch, port, hostname });
|
|
30693
30969
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
30694
30970
|
{
|
|
30695
30971
|
const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30696
|
-
const reconcileScript =
|
|
30972
|
+
const reconcileScript = resolve42(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
|
|
30697
30973
|
const runReconcile = (ctx) => {
|
|
30698
|
-
if (!
|
|
30974
|
+
if (!existsSync43(reconcileScript)) return;
|
|
30699
30975
|
try {
|
|
30700
30976
|
const child = spawn3(process.execPath, [reconcileScript], {
|
|
30701
30977
|
env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
|
|
@@ -30734,14 +31010,14 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30734
31010
|
{
|
|
30735
31011
|
const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
|
|
30736
31012
|
const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30737
|
-
const dreamSweepScript =
|
|
31013
|
+
const dreamSweepScript = resolve42(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
|
|
30738
31014
|
registerLoop({
|
|
30739
31015
|
name: "dream-cycle-sweep",
|
|
30740
31016
|
intervalMs: DREAM_CYCLE_SWEEP_INTERVAL_MS,
|
|
30741
31017
|
firstRunDelayMs: 3e4,
|
|
30742
31018
|
detached: true,
|
|
30743
31019
|
run: (ctx) => {
|
|
30744
|
-
if (!
|
|
31020
|
+
if (!existsSync43(dreamSweepScript)) return;
|
|
30745
31021
|
try {
|
|
30746
31022
|
const child = spawn3(process.execPath, [dreamSweepScript], {
|
|
30747
31023
|
env: { ...process.env, PLATFORM_ROOT: dreamPlatformRoot },
|
|
@@ -30758,10 +31034,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30758
31034
|
}
|
|
30759
31035
|
{
|
|
30760
31036
|
const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30761
|
-
const outlookScript =
|
|
31037
|
+
const outlookScript = resolve42(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
|
|
30762
31038
|
const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
|
|
30763
31039
|
const runOutlookComplete = (ctx) => {
|
|
30764
|
-
if (!
|
|
31040
|
+
if (!existsSync43(outlookScript)) return;
|
|
30765
31041
|
try {
|
|
30766
31042
|
const child = spawn3(process.execPath, [outlookScript], {
|
|
30767
31043
|
env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
|
|
@@ -30784,19 +31060,19 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30784
31060
|
}
|
|
30785
31061
|
{
|
|
30786
31062
|
const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30787
|
-
const strandedAccountsDir =
|
|
31063
|
+
const strandedAccountsDir = resolve42(auditRoot, "..", "data/accounts");
|
|
30788
31064
|
const STRANDED_AUDIT_INTERVAL_MS = 3e5;
|
|
30789
31065
|
const STRANDED_AGE_MS = 16 * 6e4;
|
|
30790
31066
|
const STRANDED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
30791
31067
|
const runStrandedAudit = () => {
|
|
30792
31068
|
try {
|
|
30793
|
-
if (!
|
|
31069
|
+
if (!existsSync43(strandedAccountsDir)) return;
|
|
30794
31070
|
const now = Date.now();
|
|
30795
|
-
for (const name of
|
|
31071
|
+
for (const name of readdirSync27(strandedAccountsDir)) {
|
|
30796
31072
|
if (!STRANDED_UUID_RE.test(name)) continue;
|
|
30797
|
-
const pendingPath2 =
|
|
30798
|
-
if (!
|
|
30799
|
-
const ageMs2 = now -
|
|
31073
|
+
const pendingPath2 = resolve42(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
|
|
31074
|
+
if (!existsSync43(pendingPath2)) continue;
|
|
31075
|
+
const ageMs2 = now - statSync18(pendingPath2).mtimeMs;
|
|
30800
31076
|
if (ageMs2 > STRANDED_AGE_MS) {
|
|
30801
31077
|
console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
|
|
30802
31078
|
}
|
|
@@ -30814,7 +31090,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30814
31090
|
}
|
|
30815
31091
|
{
|
|
30816
31092
|
const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30817
|
-
const googleAccountsDir =
|
|
31093
|
+
const googleAccountsDir = resolve42(googleRoot, "..", "data/accounts");
|
|
30818
31094
|
const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
|
|
30819
31095
|
const runGooglePendingAuditSafe = () => {
|
|
30820
31096
|
try {
|
|
@@ -30829,10 +31105,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30829
31105
|
firstRunDelayMs: 27e3,
|
|
30830
31106
|
run: runGooglePendingAuditSafe
|
|
30831
31107
|
});
|
|
30832
|
-
const googleAuditScript =
|
|
31108
|
+
const googleAuditScript = resolve42(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
|
|
30833
31109
|
const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
|
|
30834
31110
|
const runGoogleAccountAudit = (ctx) => {
|
|
30835
|
-
if (!
|
|
31111
|
+
if (!existsSync43(googleAuditScript)) return;
|
|
30836
31112
|
try {
|
|
30837
31113
|
const child = spawn3(process.execPath, [googleAuditScript], {
|
|
30838
31114
|
env: { ...process.env, PLATFORM_ROOT: googleRoot },
|
|
@@ -30904,7 +31180,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30904
31180
|
}
|
|
30905
31181
|
{
|
|
30906
31182
|
const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30907
|
-
const publishScript =
|
|
31183
|
+
const publishScript = resolve42(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
|
|
30908
31184
|
const PUBLISH_INTERVAL_MS = 3e5;
|
|
30909
31185
|
const bookingAccounts = () => {
|
|
30910
31186
|
try {
|
|
@@ -30915,7 +31191,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30915
31191
|
}
|
|
30916
31192
|
};
|
|
30917
31193
|
const spawnPublish = (account, ctx) => {
|
|
30918
|
-
if (!
|
|
31194
|
+
if (!existsSync43(publishScript)) return;
|
|
30919
31195
|
try {
|
|
30920
31196
|
const child = spawn3(process.execPath, [publishScript], {
|
|
30921
31197
|
env: {
|
|
@@ -30934,21 +31210,21 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
30934
31210
|
}
|
|
30935
31211
|
};
|
|
30936
31212
|
const auditSnapshotAge = (account) => {
|
|
30937
|
-
const availPath =
|
|
31213
|
+
const availPath = resolve42(account.accountDir, "calendar-availability.json");
|
|
30938
31214
|
let hasBookingSite = false;
|
|
30939
31215
|
try {
|
|
30940
|
-
if (
|
|
30941
|
-
const cfg = JSON.parse(
|
|
31216
|
+
if (existsSync43(availPath)) {
|
|
31217
|
+
const cfg = JSON.parse(readFileSync46(availPath, "utf-8"));
|
|
30942
31218
|
hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
|
|
30943
31219
|
}
|
|
30944
31220
|
} catch {
|
|
30945
31221
|
}
|
|
30946
31222
|
if (!hasBookingSite) return;
|
|
30947
|
-
const statePath =
|
|
31223
|
+
const statePath = resolve42(account.accountDir, "state", "booking-availability", "last-publish.json");
|
|
30948
31224
|
let lastSuccessAt = null;
|
|
30949
|
-
if (
|
|
31225
|
+
if (existsSync43(statePath)) {
|
|
30950
31226
|
try {
|
|
30951
|
-
const rec = JSON.parse(
|
|
31227
|
+
const rec = JSON.parse(readFileSync46(statePath, "utf-8"));
|
|
30952
31228
|
lastSuccessAt = rec.lastSuccessAt ?? null;
|
|
30953
31229
|
} catch {
|
|
30954
31230
|
console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
|
|
@@ -30981,11 +31257,11 @@ startTimeEntryCensus(() => getSession());
|
|
|
30981
31257
|
startLedgerCensus(() => getSession());
|
|
30982
31258
|
{
|
|
30983
31259
|
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..");
|
|
30984
|
-
const auditScript =
|
|
31260
|
+
const auditScript = resolve42(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
|
|
30985
31261
|
const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
|
|
30986
31262
|
const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
|
|
30987
31263
|
const runConnectorAudit = (ctx) => {
|
|
30988
|
-
if (!
|
|
31264
|
+
if (!existsSync43(auditScript)) return;
|
|
30989
31265
|
try {
|
|
30990
31266
|
const child = spawn3(process.execPath, [auditScript], {
|
|
30991
31267
|
env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
|
|
@@ -31065,7 +31341,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
31065
31341
|
}
|
|
31066
31342
|
try {
|
|
31067
31343
|
const registered = [];
|
|
31068
|
-
for (const r of
|
|
31344
|
+
for (const r of app66.routes ?? []) {
|
|
31069
31345
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
31070
31346
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
31071
31347
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -31105,11 +31381,11 @@ try {
|
|
|
31105
31381
|
var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
31106
31382
|
async function runAdminUserReconcileTick() {
|
|
31107
31383
|
try {
|
|
31108
|
-
if (!
|
|
31384
|
+
if (!existsSync43(USERS_FILE)) {
|
|
31109
31385
|
console.error("[adminuser-self-heal] skip reason=no-users-file");
|
|
31110
31386
|
return;
|
|
31111
31387
|
}
|
|
31112
|
-
const usersRaw =
|
|
31388
|
+
const usersRaw = readFileSync46(USERS_FILE, "utf-8").trim();
|
|
31113
31389
|
if (!usersRaw) {
|
|
31114
31390
|
console.error("[adminuser-self-heal] skip reason=empty-users-file");
|
|
31115
31391
|
return;
|
|
@@ -31156,8 +31432,8 @@ registerLoop({
|
|
|
31156
31432
|
});
|
|
31157
31433
|
var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
31158
31434
|
function countUsersRows() {
|
|
31159
|
-
if (!
|
|
31160
|
-
const raw =
|
|
31435
|
+
if (!existsSync43(USERS_FILE)) return 0;
|
|
31436
|
+
const raw = readFileSync46(USERS_FILE, "utf-8").trim();
|
|
31161
31437
|
if (!raw) return 0;
|
|
31162
31438
|
const users = JSON.parse(raw);
|
|
31163
31439
|
return users.filter((u) => typeof u.userId === "string").length;
|
|
@@ -31290,7 +31566,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
31290
31566
|
}
|
|
31291
31567
|
init({
|
|
31292
31568
|
configDir: configDirForWhatsApp,
|
|
31293
|
-
platformRoot:
|
|
31569
|
+
platformRoot: resolve42(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, "..")),
|
|
31294
31570
|
accountConfig: bootAccountConfig,
|
|
31295
31571
|
onMessage: async (msg) => {
|
|
31296
31572
|
if (isObserveAccount(msg.accountId)) {
|