@rubytech/create-sitedesk-code 0.1.509 → 0.1.510
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/docs/superpowers/plans/2026-07-26-task-1902-account-owned-entry-declarations.md +555 -0
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-2023-sidebar-sessions-async-reads.md +394 -0
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-1902-account-owned-entry-declarations-design.md +232 -0
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-2014-ui-suite-nondeterminism-design.md +169 -0
- package/payload/platform/plugins/admin/PLUGIN.md +1 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
- package/payload/platform/plugins/business-assistant/PLUGIN.md +1 -0
- package/payload/platform/plugins/cloudflare/PLUGIN.md +1 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/schema-exposed-dirs.test.ts +21 -0
- package/payload/platform/plugins/docs/references/troubleshooting.md +1 -1
- package/payload/platform/plugins/scheduling/PLUGIN.md +1 -0
- package/payload/platform/scripts/__tests__/account-schema-owned-dirs.test.sh +112 -4
- package/payload/platform/scripts/lib/account-schema-owned-dirs.py +61 -32
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js +17 -30
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.d.ts +50 -4
- package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.js +58 -15
- package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
- package/payload/server/maxy-edge.js +20 -10
- package/payload/server/public/assets/AdminLoginScreens-CWMpccrR.css.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-CWMpccrR.css.gz +0 -0
- package/payload/server/public/assets/AdminLoginScreens-bksN0XPe.js +1 -0
- package/payload/server/public/assets/AdminLoginScreens-bksN0XPe.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-bksN0XPe.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-BMPEWNZk.js.br +0 -0
- package/payload/server/public/assets/AdminShell-BMPEWNZk.js.gz +0 -0
- package/payload/server/public/assets/_baseFor-Be3EKK3K.js.br +0 -0
- package/payload/server/public/assets/_baseFor-Be3EKK3K.js.gz +0 -0
- package/payload/server/public/assets/activity-ByWYF5dC.js.br +0 -0
- package/payload/server/public/assets/activity-ByWYF5dC.js.gz +0 -0
- package/payload/server/public/assets/{admin-CnUWbKcx.js → admin-DGr1HuPg.js} +1 -1
- package/payload/server/public/assets/admin-DGr1HuPg.js.br +0 -0
- package/payload/server/public/assets/admin-DGr1HuPg.js.gz +0 -0
- package/payload/server/public/assets/agents-C0rTfrYd.js.br +0 -0
- package/payload/server/public/assets/agents-C0rTfrYd.js.gz +0 -0
- package/payload/server/public/assets/arc-DaI5MLTq.js.br +0 -0
- package/payload/server/public/assets/arc-DaI5MLTq.js.gz +0 -0
- package/payload/server/public/assets/architecture-YZFGNWBL-DWZIX5aV.js.br +0 -0
- package/payload/server/public/assets/architectureDiagram-Q4EWVU46-CBGVUEN9.js.br +0 -0
- package/payload/server/public/assets/architectureDiagram-Q4EWVU46-CBGVUEN9.js.gz +0 -0
- package/payload/server/public/assets/array-X0JlPOfd.js.br +0 -0
- package/payload/server/public/assets/blockDiagram-DXYQGD6D-DS6dS4GZ.js.br +0 -0
- package/payload/server/public/assets/blockDiagram-DXYQGD6D-DS6dS4GZ.js.gz +0 -0
- package/payload/server/public/assets/browser-4tTaem8N.js.br +0 -0
- package/payload/server/public/assets/browser-4tTaem8N.js.gz +0 -0
- package/payload/server/public/assets/c4Diagram-AHTNJAMY-hBSBUZPt.js.br +0 -0
- package/payload/server/public/assets/c4Diagram-AHTNJAMY-hBSBUZPt.js.gz +0 -0
- package/payload/server/public/assets/calendar-BEjnkKG1.js.br +0 -0
- package/payload/server/public/assets/calendar-BEjnkKG1.js.gz +0 -0
- package/payload/server/public/assets/channel-BEokjAeE.js.br +0 -0
- package/payload/server/public/assets/chat-DBgzjDIE.js.br +0 -0
- package/payload/server/public/assets/chat-DBgzjDIE.js.gz +0 -0
- package/payload/server/public/assets/chevron-right-CQfPGsFb.js.br +0 -0
- package/payload/server/public/assets/chunk-2KRD3SAO-B6koUoB7.js.br +0 -0
- package/payload/server/public/assets/chunk-2KRD3SAO-B6koUoB7.js.gz +0 -0
- package/payload/server/public/assets/chunk-336JU56O-BF6BRh8u.js.br +0 -0
- package/payload/server/public/assets/chunk-336JU56O-BF6BRh8u.js.gz +0 -0
- package/payload/server/public/assets/chunk-426QAEUC-pbQ4PWBU.js.br +0 -0
- package/payload/server/public/assets/chunk-426QAEUC-pbQ4PWBU.js.gz +0 -0
- package/payload/server/public/assets/chunk-4BX2VUAB-7sO95xR2.js.br +0 -0
- package/payload/server/public/assets/chunk-4BX2VUAB-7sO95xR2.js.gz +0 -0
- package/payload/server/public/assets/chunk-4TB4RGXK-GCTndJYx.js.br +0 -0
- package/payload/server/public/assets/chunk-4TB4RGXK-GCTndJYx.js.gz +0 -0
- package/payload/server/public/assets/chunk-55IACEB6-ggIJf_TC.js.br +0 -0
- package/payload/server/public/assets/chunk-55IACEB6-ggIJf_TC.js.gz +0 -0
- package/payload/server/public/assets/chunk-5FUZZQ4R-DeGmkimt.js.br +0 -0
- package/payload/server/public/assets/chunk-5FUZZQ4R-DeGmkimt.js.gz +0 -0
- package/payload/server/public/assets/chunk-5PVQY5BW-aFIQKk_U.js.br +0 -0
- package/payload/server/public/assets/chunk-5PVQY5BW-aFIQKk_U.js.gz +0 -0
- package/payload/server/public/assets/chunk-67CJDMHE-LS8rUbii.js.br +2 -0
- package/payload/server/public/assets/chunk-67CJDMHE-LS8rUbii.js.gz +0 -0
- package/payload/server/public/assets/chunk-7N4EOEYR-JKOVngS0.js.br +2 -0
- package/payload/server/public/assets/chunk-7N4EOEYR-JKOVngS0.js.gz +0 -0
- package/payload/server/public/assets/chunk-AA7GKIK3-CoXnTVK6.js.br +0 -0
- package/payload/server/public/assets/chunk-AA7GKIK3-CoXnTVK6.js.gz +0 -0
- package/payload/server/public/assets/chunk-BSJP7CBP-CcsqObFg.js.br +0 -0
- package/payload/server/public/assets/chunk-BSJP7CBP-CcsqObFg.js.gz +0 -0
- package/payload/server/public/assets/chunk-CIAEETIT-CpsybR7q.js.br +0 -0
- package/payload/server/public/assets/chunk-CIAEETIT-CpsybR7q.js.gz +0 -0
- package/payload/server/public/assets/chunk-CltuBf4Z.js.br +0 -0
- package/payload/server/public/assets/chunk-CltuBf4Z.js.gz +0 -0
- package/payload/server/public/assets/chunk-EDXVE4YY-BZ2I9PSq.js.br +0 -0
- package/payload/server/public/assets/chunk-EDXVE4YY-BZ2I9PSq.js.gz +0 -0
- package/payload/server/public/assets/chunk-ENJZ2VHE-DbTwt6OZ.js.br +0 -0
- package/payload/server/public/assets/chunk-ENJZ2VHE-DbTwt6OZ.js.gz +0 -0
- package/payload/server/public/assets/chunk-FMBD7UC4-D27VnSCa.js.br +0 -0
- package/payload/server/public/assets/chunk-FMBD7UC4-D27VnSCa.js.gz +0 -0
- package/payload/server/public/assets/chunk-FOC6F5B3-C0tU2UFl.js.br +0 -0
- package/payload/server/public/assets/chunk-FOC6F5B3-C0tU2UFl.js.gz +0 -0
- package/payload/server/public/assets/chunk-ICPOFSXX-UPPu2OIq.js.br +0 -0
- package/payload/server/public/assets/chunk-ICPOFSXX-UPPu2OIq.js.gz +0 -0
- package/payload/server/public/assets/chunk-K5T4RW27-DIKxqyYw.js.br +0 -0
- package/payload/server/public/assets/chunk-K5T4RW27-DIKxqyYw.js.gz +0 -0
- package/payload/server/public/assets/chunk-KGLVRYIC-CiL4YVLo.js.br +0 -0
- package/payload/server/public/assets/chunk-KGLVRYIC-CiL4YVLo.js.gz +0 -0
- package/payload/server/public/assets/chunk-LIHQZDEY-ejKezVlD.js.br +0 -0
- package/payload/server/public/assets/chunk-LIHQZDEY-ejKezVlD.js.gz +0 -0
- package/payload/server/public/assets/chunk-ORNJ4GCN-Cc0vqc-D.js.br +0 -0
- package/payload/server/public/assets/chunk-ORNJ4GCN-Cc0vqc-D.js.gz +0 -0
- package/payload/server/public/assets/chunk-OYMX7WX6-Drxn1qG0.js.br +0 -0
- package/payload/server/public/assets/chunk-OYMX7WX6-Drxn1qG0.js.gz +0 -0
- package/payload/server/public/assets/chunk-QZHKN3VN-Dhlh7Pkk.js.br +0 -0
- package/payload/server/public/assets/chunk-QZHKN3VN-Dhlh7Pkk.js.gz +0 -0
- package/payload/server/public/assets/chunk-U2HBQHQK-DnbQIkRP.js.br +0 -0
- package/payload/server/public/assets/chunk-U2HBQHQK-DnbQIkRP.js.gz +0 -0
- package/payload/server/public/assets/chunk-X2U36JSP-CauTSVWg.js.br +0 -0
- package/payload/server/public/assets/chunk-X2U36JSP-CauTSVWg.js.gz +0 -0
- package/payload/server/public/assets/chunk-XPW4576I-DZqqB9Zi.js.br +0 -0
- package/payload/server/public/assets/chunk-XPW4576I-DZqqB9Zi.js.gz +0 -0
- package/payload/server/public/assets/chunk-YZCP3GAM-BGHo4Li-.js.br +0 -0
- package/payload/server/public/assets/chunk-YZCP3GAM-BGHo4Li-.js.gz +0 -0
- package/payload/server/public/assets/chunk-ZZ45TVLE-DWGJKPd7.js.br +0 -0
- package/payload/server/public/assets/chunk-ZZ45TVLE-DWGJKPd7.js.gz +0 -0
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-D2z_ZV1x.js.br +0 -0
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-D2z_ZV1x.js.gz +0 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BJwJoNEK.js.br +0 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BJwJoNEK.js.gz +0 -0
- package/payload/server/public/assets/clock-Dn6FHB51.js.br +0 -0
- package/payload/server/public/assets/clock-Dn6FHB51.js.gz +0 -0
- package/payload/server/public/assets/clone-Bn7XXVhr.js.br +0 -0
- package/payload/server/public/assets/cose-bilkent-S5V4N54A-D-95BzXL.js.br +0 -0
- package/payload/server/public/assets/cose-bilkent-S5V4N54A-D-95BzXL.js.gz +0 -0
- package/payload/server/public/assets/cytoscape.esm-CI2IWMLB.js.br +0 -0
- package/payload/server/public/assets/cytoscape.esm-CI2IWMLB.js.gz +0 -0
- package/payload/server/public/assets/dagre-BZYNBHvT.js.br +0 -0
- package/payload/server/public/assets/dagre-BZYNBHvT.js.gz +0 -0
- package/payload/server/public/assets/dagre-KV5264BT-DyU4HQLQ.js.br +0 -0
- package/payload/server/public/assets/dagre-KV5264BT-DyU4HQLQ.js.gz +0 -0
- package/payload/server/public/assets/data-D_e6Vdfd.js.br +0 -0
- package/payload/server/public/assets/data-D_e6Vdfd.js.gz +0 -0
- package/payload/server/public/assets/defaultLocale-B6RGN4id.js.br +0 -0
- package/payload/server/public/assets/defaultLocale-B6RGN4id.js.gz +0 -0
- package/payload/server/public/assets/diagram-5BDNPKRD-CCttJ9XA.js.br +0 -0
- package/payload/server/public/assets/diagram-5BDNPKRD-CCttJ9XA.js.gz +0 -0
- package/payload/server/public/assets/diagram-G4DWMVQ6-DvkpgSLO.js.br +0 -0
- package/payload/server/public/assets/diagram-G4DWMVQ6-DvkpgSLO.js.gz +0 -0
- package/payload/server/public/assets/diagram-MMDJMWI5-DHmW5Y9k.js.br +0 -0
- package/payload/server/public/assets/diagram-MMDJMWI5-DHmW5Y9k.js.gz +0 -0
- package/payload/server/public/assets/diagram-TYMM5635-C6T4hwzO.js.br +0 -0
- package/payload/server/public/assets/diagram-TYMM5635-C6T4hwzO.js.gz +0 -0
- package/payload/server/public/assets/dist-QvbmK1IP.js.br +0 -0
- package/payload/server/public/assets/dist-QvbmK1IP.js.gz +0 -0
- package/payload/server/public/assets/erDiagram-SMLLAGMA-5v_o7s3T.js.br +0 -0
- package/payload/server/public/assets/erDiagram-SMLLAGMA-5v_o7s3T.js.gz +0 -0
- package/payload/server/public/assets/file-text-DMKw3nIk.js.br +0 -0
- package/payload/server/public/assets/file-text-DMKw3nIk.js.gz +0 -0
- package/payload/server/public/assets/flatten-BtIc9jX7.js.br +0 -0
- package/payload/server/public/assets/flatten-BtIc9jX7.js.gz +0 -0
- package/payload/server/public/assets/flowDiagram-DWJPFMVM-3UhCDsjt.js.br +0 -0
- package/payload/server/public/assets/flowDiagram-DWJPFMVM-3UhCDsjt.js.gz +0 -0
- package/payload/server/public/assets/ganttDiagram-T4ZO3ILL-F2zgHIIQ.js.br +0 -0
- package/payload/server/public/assets/ganttDiagram-T4ZO3ILL-F2zgHIIQ.js.gz +0 -0
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-C-FvNTHZ.js.br +0 -0
- package/payload/server/public/assets/gitGraphDiagram-UUTBAWPF-oQc1N3dT.js.br +0 -0
- package/payload/server/public/assets/gitGraphDiagram-UUTBAWPF-oQc1N3dT.js.gz +0 -0
- package/payload/server/public/assets/graph-C3vW8lvw.js.br +0 -0
- package/payload/server/public/assets/graph-C3vW8lvw.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-BZgd0L6n.js.br +0 -0
- package/payload/server/public/assets/graph-labels-BZgd0L6n.js.gz +0 -0
- package/payload/server/public/assets/graphlib-DY4-AT2Q.js.br +0 -0
- package/payload/server/public/assets/graphlib-DY4-AT2Q.js.gz +0 -0
- package/payload/server/public/assets/info-OMHHGYJF-BjLPgHAC.js.br +0 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-CXNKLTui.js.br +0 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-CXNKLTui.js.gz +0 -0
- package/payload/server/public/assets/init-BmUWJJHz.js.br +0 -0
- package/payload/server/public/assets/init-BmUWJJHz.js.gz +0 -0
- package/payload/server/public/assets/isEmpty-Bu4fZ8Kf.js.br +0 -0
- package/payload/server/public/assets/isEmpty-Bu4fZ8Kf.js.gz +0 -0
- package/payload/server/public/assets/ishikawaDiagram-UXIWVN3A-wJhSOkuw.js.br +0 -0
- package/payload/server/public/assets/ishikawaDiagram-UXIWVN3A-wJhSOkuw.js.gz +0 -0
- package/payload/server/public/assets/journeyDiagram-VCZTEJTY-DgadC6Pz.js.br +0 -0
- package/payload/server/public/assets/journeyDiagram-VCZTEJTY-DgadC6Pz.js.gz +0 -0
- package/payload/server/public/assets/kanban-definition-6JOO6SKY-Bs4nQqXI.js.br +0 -0
- package/payload/server/public/assets/kanban-definition-6JOO6SKY-Bs4nQqXI.js.gz +0 -0
- package/payload/server/public/assets/katex-BjZuzSQn.js.br +0 -0
- package/payload/server/public/assets/katex-BjZuzSQn.js.gz +0 -0
- package/payload/server/public/assets/line-Bnmxy1hO.js.br +0 -0
- package/payload/server/public/assets/line-Bnmxy1hO.js.gz +0 -0
- package/payload/server/public/assets/linear-RvwZxFzh.js.br +0 -0
- package/payload/server/public/assets/linear-RvwZxFzh.js.gz +0 -0
- package/payload/server/public/assets/maximize-2-la3IBA3M.js.br +0 -0
- package/payload/server/public/assets/maximize-2-la3IBA3M.js.gz +0 -0
- package/payload/server/public/assets/mermaid-parser.core-DeNV8RtA.js.br +0 -0
- package/payload/server/public/assets/mermaid-parser.core-DeNV8RtA.js.gz +0 -0
- package/payload/server/public/assets/mermaid.core-BU9IiSCP.js.br +0 -0
- package/payload/server/public/assets/mermaid.core-BU9IiSCP.js.gz +0 -0
- package/payload/server/public/assets/mindmap-definition-QFDTVHPH-D1PMUxxm.js.br +0 -0
- package/payload/server/public/assets/mindmap-definition-QFDTVHPH-D1PMUxxm.js.gz +0 -0
- package/payload/server/public/assets/{operator-RRRdqoRQ.js → operator-D9NgVL9_.js} +1 -1
- package/payload/server/public/assets/operator-D9NgVL9_.js.br +0 -0
- package/payload/server/public/assets/operator-D9NgVL9_.js.gz +0 -0
- package/payload/server/public/assets/ordinal-C2TEWKNu.js.br +0 -0
- package/payload/server/public/assets/ordinal-C2TEWKNu.js.gz +0 -0
- package/payload/server/public/assets/packet-4T2RLAQJ-BBAZASfb.js.br +0 -0
- package/payload/server/public/assets/page-BWFHRIAH.js.br +0 -0
- package/payload/server/public/assets/page-BWFHRIAH.js.gz +0 -0
- package/payload/server/public/assets/page-DC11gesX.js.br +0 -0
- package/payload/server/public/assets/page-DC11gesX.js.gz +0 -0
- package/payload/server/public/assets/path-CoPyR7c2.js.br +0 -0
- package/payload/server/public/assets/path-CoPyR7c2.js.gz +0 -0
- package/payload/server/public/assets/pdf-render-C257cidb.js.br +0 -0
- package/payload/server/public/assets/pdf-render-C257cidb.js.gz +0 -0
- package/payload/server/public/assets/pdf.worker.min-yatZIOMy.mjs.br +0 -0
- package/payload/server/public/assets/pdf.worker.min-yatZIOMy.mjs.gz +0 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-CCJUnMeG.js.br +0 -0
- package/payload/server/public/assets/pieDiagram-DEJITSTG-BzdNzoKA.js.br +0 -0
- package/payload/server/public/assets/pieDiagram-DEJITSTG-BzdNzoKA.js.gz +0 -0
- package/payload/server/public/assets/preload-helper-BQrMkyGX.js.br +0 -0
- package/payload/server/public/assets/preload-helper-BQrMkyGX.js.gz +0 -0
- package/payload/server/public/assets/public-DQbbLHQN.js.br +0 -0
- package/payload/server/public/assets/public-DQbbLHQN.js.gz +0 -0
- package/payload/server/public/assets/quadrantDiagram-34T5L4WZ-oFr1MJRO.js.br +0 -0
- package/payload/server/public/assets/quadrantDiagram-34T5L4WZ-oFr1MJRO.js.gz +0 -0
- package/payload/server/public/assets/radar-PYXPWWZC-BsRU8Aep.js.br +0 -0
- package/payload/server/public/assets/reduce-BGpN5lgn.js.br +0 -0
- package/payload/server/public/assets/reduce-BGpN5lgn.js.gz +0 -0
- package/payload/server/public/assets/requirementDiagram-MS252O5E-C9QBQxDh.js.br +0 -0
- package/payload/server/public/assets/requirementDiagram-MS252O5E-C9QBQxDh.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-OQD5si8N.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-OQD5si8N.js.gz +0 -0
- package/payload/server/public/assets/rough.esm-jSt7UMyi.js.br +0 -0
- package/payload/server/public/assets/rough.esm-jSt7UMyi.js.gz +0 -0
- package/payload/server/public/assets/routines-asrBGZUR.js.br +0 -0
- package/payload/server/public/assets/routines-asrBGZUR.js.gz +0 -0
- package/payload/server/public/assets/sankeyDiagram-XADWPNL6-c_y3bvVv.js.br +0 -0
- package/payload/server/public/assets/sankeyDiagram-XADWPNL6-c_y3bvVv.js.gz +0 -0
- package/payload/server/public/assets/sequenceDiagram-FGHM5R23-YwlCBPHE.js.br +0 -0
- package/payload/server/public/assets/sequenceDiagram-FGHM5R23-YwlCBPHE.js.gz +0 -0
- package/payload/server/public/assets/skills-D4ECwoxa.js.br +0 -0
- package/payload/server/public/assets/skills-D4ECwoxa.js.gz +0 -0
- package/payload/server/public/assets/src-C2WwTWSY.js.br +0 -0
- package/payload/server/public/assets/src-C2WwTWSY.js.gz +0 -0
- package/payload/server/public/assets/stateDiagram-FHFEXIEX-BFE3e-FM.js.br +0 -0
- package/payload/server/public/assets/stateDiagram-FHFEXIEX-BFE3e-FM.js.gz +0 -0
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CpjB4ykI.js.br +4 -0
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CpjB4ykI.js.gz +0 -0
- package/payload/server/public/assets/tasks-U3QdbUsO.js.br +0 -0
- package/payload/server/public/assets/tasks-U3QdbUsO.js.gz +0 -0
- package/payload/server/public/assets/time-entry-format-BgdTKgYr.js.br +0 -0
- package/payload/server/public/assets/time-entry-format-BgdTKgYr.js.gz +0 -0
- package/payload/server/public/assets/timeline-definition-GMOUNBTQ-azqhmRwZ.js.br +0 -0
- package/payload/server/public/assets/timeline-definition-GMOUNBTQ-azqhmRwZ.js.gz +0 -0
- package/payload/server/public/assets/treeView-SZITEDCU-BDzhKA6v.js.br +0 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-epHpdeWa.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-Ck_3VhT9.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-Ck_3VhT9.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-BdUwyNpa.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-BdUwyNpa.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-CJKjEPNN.js.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-CJKjEPNN.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-DOWQXDT8.css.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-DOWQXDT8.css.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-ChnBrzbZ.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-ChnBrzbZ.js.gz +0 -0
- package/payload/server/public/assets/vennDiagram-DHZGUBPP-Da2RfFs8.js.br +0 -0
- package/payload/server/public/assets/vennDiagram-DHZGUBPP-Da2RfFs8.js.gz +0 -0
- package/payload/server/public/assets/wardley-RL74JXVD-DNSZCrxV.js.br +0 -0
- package/payload/server/public/assets/wardleyDiagram-NUSXRM2D-HdrdBYES.js.br +0 -0
- package/payload/server/public/assets/wardleyDiagram-NUSXRM2D-HdrdBYES.js.gz +0 -0
- package/payload/server/public/assets/wrench-Cpee3C3J.js.br +2 -0
- package/payload/server/public/assets/wrench-Cpee3C3J.js.gz +0 -0
- package/payload/server/public/assets/xychartDiagram-5P7HB3ND-DMk6rTcQ.js.br +0 -0
- package/payload/server/public/assets/xychartDiagram-5P7HB3ND-DMk6rTcQ.js.gz +0 -0
- package/payload/server/public/index.html +2 -2
- package/payload/server/public/operator.html +2 -2
- package/payload/server/server.js +524 -503
- package/payload/server/public/assets/AdminLoginScreens-8Jk7hnWH.js +0 -1
package/payload/server/server.js
CHANGED
|
@@ -1601,230 +1601,8 @@ var require_dist5 = __commonJS({
|
|
|
1601
1601
|
}
|
|
1602
1602
|
});
|
|
1603
1603
|
|
|
1604
|
-
// node_modules/hono/dist/utils/mime.js
|
|
1605
|
-
var getMimeType = (filename, mimes = baseMimes) => {
|
|
1606
|
-
const regexp = /\.([a-zA-Z0-9]+?)$/;
|
|
1607
|
-
const match = filename.match(regexp);
|
|
1608
|
-
if (!match) {
|
|
1609
|
-
return;
|
|
1610
|
-
}
|
|
1611
|
-
let mimeType = mimes[match[1].toLowerCase()];
|
|
1612
|
-
if (mimeType && mimeType.startsWith("text")) {
|
|
1613
|
-
mimeType += "; charset=utf-8";
|
|
1614
|
-
}
|
|
1615
|
-
return mimeType;
|
|
1616
|
-
};
|
|
1617
|
-
var _baseMimes = {
|
|
1618
|
-
aac: "audio/aac",
|
|
1619
|
-
avi: "video/x-msvideo",
|
|
1620
|
-
avif: "image/avif",
|
|
1621
|
-
av1: "video/av1",
|
|
1622
|
-
bin: "application/octet-stream",
|
|
1623
|
-
bmp: "image/bmp",
|
|
1624
|
-
css: "text/css",
|
|
1625
|
-
csv: "text/csv",
|
|
1626
|
-
eot: "application/vnd.ms-fontobject",
|
|
1627
|
-
epub: "application/epub+zip",
|
|
1628
|
-
gif: "image/gif",
|
|
1629
|
-
gz: "application/gzip",
|
|
1630
|
-
htm: "text/html",
|
|
1631
|
-
html: "text/html",
|
|
1632
|
-
ico: "image/x-icon",
|
|
1633
|
-
ics: "text/calendar",
|
|
1634
|
-
jpeg: "image/jpeg",
|
|
1635
|
-
jpg: "image/jpeg",
|
|
1636
|
-
js: "text/javascript",
|
|
1637
|
-
json: "application/json",
|
|
1638
|
-
jsonld: "application/ld+json",
|
|
1639
|
-
map: "application/json",
|
|
1640
|
-
mid: "audio/x-midi",
|
|
1641
|
-
midi: "audio/x-midi",
|
|
1642
|
-
mjs: "text/javascript",
|
|
1643
|
-
mp3: "audio/mpeg",
|
|
1644
|
-
mp4: "video/mp4",
|
|
1645
|
-
mpeg: "video/mpeg",
|
|
1646
|
-
oga: "audio/ogg",
|
|
1647
|
-
ogv: "video/ogg",
|
|
1648
|
-
ogx: "application/ogg",
|
|
1649
|
-
opus: "audio/opus",
|
|
1650
|
-
otf: "font/otf",
|
|
1651
|
-
pdf: "application/pdf",
|
|
1652
|
-
png: "image/png",
|
|
1653
|
-
rtf: "application/rtf",
|
|
1654
|
-
svg: "image/svg+xml",
|
|
1655
|
-
tif: "image/tiff",
|
|
1656
|
-
tiff: "image/tiff",
|
|
1657
|
-
ts: "video/mp2t",
|
|
1658
|
-
ttf: "font/ttf",
|
|
1659
|
-
txt: "text/plain",
|
|
1660
|
-
wasm: "application/wasm",
|
|
1661
|
-
webm: "video/webm",
|
|
1662
|
-
weba: "audio/webm",
|
|
1663
|
-
webmanifest: "application/manifest+json",
|
|
1664
|
-
webp: "image/webp",
|
|
1665
|
-
woff: "font/woff",
|
|
1666
|
-
woff2: "font/woff2",
|
|
1667
|
-
xhtml: "application/xhtml+xml",
|
|
1668
|
-
xml: "application/xml",
|
|
1669
|
-
zip: "application/zip",
|
|
1670
|
-
"3gp": "video/3gpp",
|
|
1671
|
-
"3g2": "video/3gpp2",
|
|
1672
|
-
gltf: "model/gltf+json",
|
|
1673
|
-
glb: "model/gltf-binary"
|
|
1674
|
-
};
|
|
1675
|
-
var baseMimes = _baseMimes;
|
|
1676
|
-
|
|
1677
|
-
// node_modules/@hono/node-server/dist/serve-static.mjs
|
|
1678
|
-
import { createReadStream, statSync, existsSync } from "fs";
|
|
1679
|
-
import { join } from "path";
|
|
1680
|
-
import { versions } from "process";
|
|
1681
|
-
import { Readable } from "stream";
|
|
1682
|
-
var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
|
|
1683
|
-
var ENCODINGS = {
|
|
1684
|
-
br: ".br",
|
|
1685
|
-
zstd: ".zst",
|
|
1686
|
-
gzip: ".gz"
|
|
1687
|
-
};
|
|
1688
|
-
var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
|
|
1689
|
-
var pr54206Applied = () => {
|
|
1690
|
-
const [major, minor] = versions.node.split(".").map((component) => parseInt(component));
|
|
1691
|
-
return major >= 23 || major === 22 && minor >= 7 || major === 20 && minor >= 18;
|
|
1692
|
-
};
|
|
1693
|
-
var useReadableToWeb = pr54206Applied();
|
|
1694
|
-
var createStreamBody = (stream2) => {
|
|
1695
|
-
if (useReadableToWeb) {
|
|
1696
|
-
return Readable.toWeb(stream2);
|
|
1697
|
-
}
|
|
1698
|
-
const body = new ReadableStream({
|
|
1699
|
-
start(controller) {
|
|
1700
|
-
stream2.on("data", (chunk) => {
|
|
1701
|
-
controller.enqueue(chunk);
|
|
1702
|
-
});
|
|
1703
|
-
stream2.on("error", (err) => {
|
|
1704
|
-
controller.error(err);
|
|
1705
|
-
});
|
|
1706
|
-
stream2.on("end", () => {
|
|
1707
|
-
controller.close();
|
|
1708
|
-
});
|
|
1709
|
-
},
|
|
1710
|
-
cancel() {
|
|
1711
|
-
stream2.destroy();
|
|
1712
|
-
}
|
|
1713
|
-
});
|
|
1714
|
-
return body;
|
|
1715
|
-
};
|
|
1716
|
-
var getStats = (path3) => {
|
|
1717
|
-
let stats;
|
|
1718
|
-
try {
|
|
1719
|
-
stats = statSync(path3);
|
|
1720
|
-
} catch {
|
|
1721
|
-
}
|
|
1722
|
-
return stats;
|
|
1723
|
-
};
|
|
1724
|
-
var tryDecode = (str, decoder) => {
|
|
1725
|
-
try {
|
|
1726
|
-
return decoder(str);
|
|
1727
|
-
} catch {
|
|
1728
|
-
return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
|
|
1729
|
-
try {
|
|
1730
|
-
return decoder(match);
|
|
1731
|
-
} catch {
|
|
1732
|
-
return match;
|
|
1733
|
-
}
|
|
1734
|
-
});
|
|
1735
|
-
}
|
|
1736
|
-
};
|
|
1737
|
-
var tryDecodeURI = (str) => tryDecode(str, decodeURI);
|
|
1738
|
-
var serveStatic = (options = { root: "" }) => {
|
|
1739
|
-
const root = options.root || "";
|
|
1740
|
-
const optionPath = options.path;
|
|
1741
|
-
if (root !== "" && !existsSync(root)) {
|
|
1742
|
-
console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
|
|
1743
|
-
}
|
|
1744
|
-
return async (c, next) => {
|
|
1745
|
-
if (c.finalized) {
|
|
1746
|
-
return next();
|
|
1747
|
-
}
|
|
1748
|
-
let filename;
|
|
1749
|
-
if (optionPath) {
|
|
1750
|
-
filename = optionPath;
|
|
1751
|
-
} else {
|
|
1752
|
-
try {
|
|
1753
|
-
filename = tryDecodeURI(c.req.path);
|
|
1754
|
-
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
|
1755
|
-
throw new Error();
|
|
1756
|
-
}
|
|
1757
|
-
} catch {
|
|
1758
|
-
await options.onNotFound?.(c.req.path, c);
|
|
1759
|
-
return next();
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1762
|
-
let path3 = join(
|
|
1763
|
-
root,
|
|
1764
|
-
!optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
|
|
1765
|
-
);
|
|
1766
|
-
let stats = getStats(path3);
|
|
1767
|
-
if (stats && stats.isDirectory()) {
|
|
1768
|
-
const indexFile2 = options.index ?? "index.html";
|
|
1769
|
-
path3 = join(path3, indexFile2);
|
|
1770
|
-
stats = getStats(path3);
|
|
1771
|
-
}
|
|
1772
|
-
if (!stats) {
|
|
1773
|
-
await options.onNotFound?.(path3, c);
|
|
1774
|
-
return next();
|
|
1775
|
-
}
|
|
1776
|
-
const mimeType = getMimeType(path3);
|
|
1777
|
-
c.header("Content-Type", mimeType || "application/octet-stream");
|
|
1778
|
-
if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
|
|
1779
|
-
const acceptEncodingSet = new Set(
|
|
1780
|
-
c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim())
|
|
1781
|
-
);
|
|
1782
|
-
for (const encoding of ENCODINGS_ORDERED_KEYS) {
|
|
1783
|
-
if (!acceptEncodingSet.has(encoding)) {
|
|
1784
|
-
continue;
|
|
1785
|
-
}
|
|
1786
|
-
const precompressedStats = getStats(path3 + ENCODINGS[encoding]);
|
|
1787
|
-
if (precompressedStats) {
|
|
1788
|
-
c.header("Content-Encoding", encoding);
|
|
1789
|
-
c.header("Vary", "Accept-Encoding", { append: true });
|
|
1790
|
-
stats = precompressedStats;
|
|
1791
|
-
path3 = path3 + ENCODINGS[encoding];
|
|
1792
|
-
break;
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
let result;
|
|
1797
|
-
const size = stats.size;
|
|
1798
|
-
const range = c.req.header("range") || "";
|
|
1799
|
-
if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
|
|
1800
|
-
c.header("Content-Length", size.toString());
|
|
1801
|
-
c.status(200);
|
|
1802
|
-
result = c.body(null);
|
|
1803
|
-
} else if (!range) {
|
|
1804
|
-
c.header("Content-Length", size.toString());
|
|
1805
|
-
result = c.body(createStreamBody(createReadStream(path3)), 200);
|
|
1806
|
-
} else {
|
|
1807
|
-
c.header("Accept-Ranges", "bytes");
|
|
1808
|
-
c.header("Date", stats.birthtime.toUTCString());
|
|
1809
|
-
const parts = range.replace(/bytes=/, "").split("-", 2);
|
|
1810
|
-
const start = parseInt(parts[0], 10) || 0;
|
|
1811
|
-
let end = parseInt(parts[1], 10) || size - 1;
|
|
1812
|
-
if (size < end - start + 1) {
|
|
1813
|
-
end = size - 1;
|
|
1814
|
-
}
|
|
1815
|
-
const chunksize = end - start + 1;
|
|
1816
|
-
const stream2 = createReadStream(path3, { start, end });
|
|
1817
|
-
c.header("Content-Length", chunksize.toString());
|
|
1818
|
-
c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
|
|
1819
|
-
result = c.body(createStreamBody(stream2), 206);
|
|
1820
|
-
}
|
|
1821
|
-
await options.onFound?.(path3, c);
|
|
1822
|
-
return result;
|
|
1823
|
-
};
|
|
1824
|
-
};
|
|
1825
|
-
|
|
1826
1604
|
// server/index.ts
|
|
1827
|
-
import { readFileSync as readFileSync48, existsSync as existsSync47, watchFile, readdirSync as readdirSync29, statSync as
|
|
1605
|
+
import { readFileSync as readFileSync48, existsSync as existsSync47, watchFile, readdirSync as readdirSync29, statSync as statSync21 } from "fs";
|
|
1828
1606
|
import { spawn as spawn3 } from "child_process";
|
|
1829
1607
|
import { createHash as createHash8 } from "crypto";
|
|
1830
1608
|
import { resolve as resolve45, join as join49, basename as basename14 } from "path";
|
|
@@ -1950,21 +1728,21 @@ function onInvalidate(fn) {
|
|
|
1950
1728
|
}
|
|
1951
1729
|
|
|
1952
1730
|
// app/lib/whatsapp/message-store.ts
|
|
1953
|
-
import { existsSync
|
|
1954
|
-
import { dirname, join
|
|
1731
|
+
import { existsSync, mkdirSync, readFileSync, appendFileSync, readdirSync, statSync } from "fs";
|
|
1732
|
+
import { dirname, join } from "path";
|
|
1955
1733
|
function isReactionRecord(r) {
|
|
1956
1734
|
return r.kind === "reaction";
|
|
1957
1735
|
}
|
|
1958
|
-
var STORE_ROOT = () =>
|
|
1736
|
+
var STORE_ROOT = () => join(process.env.MAXY_DIR_OVERRIDE ?? MAXY_DIR, "data", "whatsapp-messages");
|
|
1959
1737
|
function conversationFile(platformAccountId, remoteJid) {
|
|
1960
|
-
return
|
|
1738
|
+
return join(STORE_ROOT(), platformAccountId, `${remoteJid}.jsonl`);
|
|
1961
1739
|
}
|
|
1962
1740
|
function listStoredAccountIds() {
|
|
1963
1741
|
const root = STORE_ROOT();
|
|
1964
|
-
if (!
|
|
1742
|
+
if (!existsSync(root)) return [];
|
|
1965
1743
|
return readdirSync(root).filter((name) => {
|
|
1966
1744
|
try {
|
|
1967
|
-
return
|
|
1745
|
+
return statSync(join(root, name)).isDirectory();
|
|
1968
1746
|
} catch {
|
|
1969
1747
|
return false;
|
|
1970
1748
|
}
|
|
@@ -2000,7 +1778,7 @@ function appendMessage(platformAccountId, record, altDedupeRemoteJids = []) {
|
|
|
2000
1778
|
try {
|
|
2001
1779
|
const filesToCheck = [file, ...altDedupeRemoteJids.filter((jid) => jid && jid !== record.remoteJid).map((jid) => conversationFile(platformAccountId, jid))];
|
|
2002
1780
|
for (const candidate of new Set(filesToCheck)) {
|
|
2003
|
-
if (!
|
|
1781
|
+
if (!existsSync(candidate)) continue;
|
|
2004
1782
|
const existing = parseLines(readFileSync(candidate, "utf8"));
|
|
2005
1783
|
if (existing.some((r) => r.messageId === record.messageId)) {
|
|
2006
1784
|
return { created: false };
|
|
@@ -2023,7 +1801,7 @@ function appendMessage(platformAccountId, record, altDedupeRemoteJids = []) {
|
|
|
2023
1801
|
function readConversation(platformAccountId, remoteJid) {
|
|
2024
1802
|
const file = conversationFile(platformAccountId, remoteJid);
|
|
2025
1803
|
try {
|
|
2026
|
-
if (!
|
|
1804
|
+
if (!existsSync(file)) return [];
|
|
2027
1805
|
return parseLines(readFileSync(file, "utf8")).sort(byDateSentAsc);
|
|
2028
1806
|
} catch (err) {
|
|
2029
1807
|
const reason = err instanceof Error ? err.message : String(err);
|
|
@@ -2048,7 +1826,7 @@ function appendReaction(platformAccountId, record) {
|
|
|
2048
1826
|
function readReactions(platformAccountId, remoteJid) {
|
|
2049
1827
|
const file = conversationFile(platformAccountId, remoteJid);
|
|
2050
1828
|
try {
|
|
2051
|
-
if (!
|
|
1829
|
+
if (!existsSync(file)) return [];
|
|
2052
1830
|
const out = [];
|
|
2053
1831
|
for (const line of readFileSync(file, "utf8").split("\n")) {
|
|
2054
1832
|
if (!line.trim()) continue;
|
|
@@ -2094,23 +1872,23 @@ function summariseRecords(records) {
|
|
|
2094
1872
|
};
|
|
2095
1873
|
}
|
|
2096
1874
|
function readConversationSummaries(platformAccountId) {
|
|
2097
|
-
const dir =
|
|
1875
|
+
const dir = join(STORE_ROOT(), platformAccountId);
|
|
2098
1876
|
const out = /* @__PURE__ */ new Map();
|
|
2099
1877
|
const seen = /* @__PURE__ */ new Set();
|
|
2100
1878
|
let fullReads = 0;
|
|
2101
1879
|
let cacheHits = 0;
|
|
2102
1880
|
let bytesRead = 0;
|
|
2103
1881
|
try {
|
|
2104
|
-
if (!
|
|
1882
|
+
if (!existsSync(dir)) return out;
|
|
2105
1883
|
for (const entry of readdirSync(dir)) {
|
|
2106
1884
|
if (!entry.endsWith(".jsonl")) continue;
|
|
2107
1885
|
const remoteJid = entry.slice(0, -".jsonl".length);
|
|
2108
|
-
const file =
|
|
1886
|
+
const file = join(dir, entry);
|
|
2109
1887
|
seen.add(file);
|
|
2110
1888
|
let size;
|
|
2111
1889
|
let mtimeMs;
|
|
2112
1890
|
try {
|
|
2113
|
-
const st =
|
|
1891
|
+
const st = statSync(file);
|
|
2114
1892
|
size = st.size;
|
|
2115
1893
|
mtimeMs = st.mtimeMs;
|
|
2116
1894
|
} catch {
|
|
@@ -2150,10 +1928,10 @@ function readConversationSummaries(platformAccountId) {
|
|
|
2150
1928
|
return out;
|
|
2151
1929
|
}
|
|
2152
1930
|
function readAllConversations(platformAccountId) {
|
|
2153
|
-
const dir =
|
|
1931
|
+
const dir = join(STORE_ROOT(), platformAccountId);
|
|
2154
1932
|
const out = /* @__PURE__ */ new Map();
|
|
2155
1933
|
try {
|
|
2156
|
-
if (!
|
|
1934
|
+
if (!existsSync(dir)) return out;
|
|
2157
1935
|
for (const entry of readdirSync(dir)) {
|
|
2158
1936
|
if (!entry.endsWith(".jsonl")) continue;
|
|
2159
1937
|
const remoteJid = entry.slice(0, -".jsonl".length);
|
|
@@ -2317,92 +2095,314 @@ function handleManagerFrame(raw) {
|
|
|
2317
2095
|
console.error(`${TAG} op=skip reason=no-account sessionId=${sessionId}`);
|
|
2318
2096
|
return null;
|
|
2319
2097
|
}
|
|
2320
|
-
const status = String(body.status ?? "unknown");
|
|
2321
|
-
const fullSessionId = String(body.sessionId ?? "");
|
|
2322
|
-
if (fullSessionId && lastStatusBySession.get(fullSessionId) === status) {
|
|
2323
|
-
return null;
|
|
2098
|
+
const status = String(body.status ?? "unknown");
|
|
2099
|
+
const fullSessionId = String(body.sessionId ?? "");
|
|
2100
|
+
if (fullSessionId && lastStatusBySession.get(fullSessionId) === status) {
|
|
2101
|
+
return null;
|
|
2102
|
+
}
|
|
2103
|
+
if (fullSessionId) lastStatusBySession.set(fullSessionId, status);
|
|
2104
|
+
console.log(
|
|
2105
|
+
`${TAG} op=event sessionId=${sessionId} accountId=${accountId.slice(0, 8)} activity=${status}`
|
|
2106
|
+
);
|
|
2107
|
+
notify("webchat-pointer", accountId);
|
|
2108
|
+
return { resource: "webchat-pointer", accountId };
|
|
2109
|
+
}
|
|
2110
|
+
var connections = 0;
|
|
2111
|
+
var started = false;
|
|
2112
|
+
var abort = null;
|
|
2113
|
+
function startManagerEventsSubscriber() {
|
|
2114
|
+
if (started) return;
|
|
2115
|
+
started = true;
|
|
2116
|
+
abort = new AbortController();
|
|
2117
|
+
void connectLoop(abort.signal);
|
|
2118
|
+
}
|
|
2119
|
+
async function connectLoop(signal) {
|
|
2120
|
+
let backoffMs = 1e3;
|
|
2121
|
+
for (; ; ) {
|
|
2122
|
+
if (signal.aborted) return;
|
|
2123
|
+
let port2;
|
|
2124
|
+
try {
|
|
2125
|
+
port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "webchat-pointer" });
|
|
2126
|
+
} catch {
|
|
2127
|
+
console.error(`${TAG} op=drop reason=manager-port-unset`);
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
const connectedAt = Date.now();
|
|
2131
|
+
try {
|
|
2132
|
+
const res = await fetch(`http://127.0.0.1:${port2}/events`, { signal });
|
|
2133
|
+
if (!res.ok || !res.body) throw new Error(`status ${res.status}`);
|
|
2134
|
+
connections += 1;
|
|
2135
|
+
console.log(`${TAG} op=subscribe upstream-count=${connections}`);
|
|
2136
|
+
const reader = res.body.getReader();
|
|
2137
|
+
const decoder = new TextDecoder();
|
|
2138
|
+
let buffer = "";
|
|
2139
|
+
for (; ; ) {
|
|
2140
|
+
const { done, value } = await reader.read();
|
|
2141
|
+
if (done) break;
|
|
2142
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2143
|
+
let cut = buffer.indexOf("\n\n");
|
|
2144
|
+
while (cut !== -1) {
|
|
2145
|
+
handleManagerFrame(buffer.slice(0, cut));
|
|
2146
|
+
buffer = buffer.slice(cut + 2);
|
|
2147
|
+
cut = buffer.indexOf("\n\n");
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
connections -= 1;
|
|
2151
|
+
} catch (err) {
|
|
2152
|
+
if (connections > 0) connections -= 1;
|
|
2153
|
+
if (signal.aborted) return;
|
|
2154
|
+
console.error(`${TAG} op=drop reason=${err instanceof Error ? err.message : String(err)}`);
|
|
2155
|
+
}
|
|
2156
|
+
if (signal.aborted) return;
|
|
2157
|
+
if (Date.now() - connectedAt >= STABLE_CONNECTION_MS) backoffMs = 1e3;
|
|
2158
|
+
console.log(`${TAG} op=reconnect inMs=${backoffMs} upstream-count=${connections}`);
|
|
2159
|
+
await new Promise((r) => setTimeout(r, backoffMs));
|
|
2160
|
+
backoffMs = Math.min(backoffMs * 2, MAX_BACKOFF_MS);
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
// server/index.ts
|
|
2165
|
+
import { monitorEventLoopDelay } from "perf_hooks";
|
|
2166
|
+
|
|
2167
|
+
// server/lib/event-loop-lag.ts
|
|
2168
|
+
function readAndResetWindow(hist, windowMs) {
|
|
2169
|
+
const toMs = (ns) => Math.round(ns / 1e6);
|
|
2170
|
+
const w = {
|
|
2171
|
+
p50Ms: toMs(hist.percentile(50)),
|
|
2172
|
+
p99Ms: toMs(hist.percentile(99)),
|
|
2173
|
+
maxMs: toMs(hist.max),
|
|
2174
|
+
// Read before the reset.
|
|
2175
|
+
count: hist.count,
|
|
2176
|
+
windowMs
|
|
2177
|
+
};
|
|
2178
|
+
hist.reset();
|
|
2179
|
+
return w;
|
|
2180
|
+
}
|
|
2181
|
+
function formatLagWindow(w) {
|
|
2182
|
+
return `[event-loop] op=lag-window p50=${w.p50Ms} p99=${w.p99Ms} max=${w.maxMs} n=${w.count} windowMs=${w.windowMs}`;
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
// node_modules/hono/dist/utils/mime.js
|
|
2186
|
+
var getMimeType = (filename, mimes = baseMimes) => {
|
|
2187
|
+
const regexp = /\.([a-zA-Z0-9]+?)$/;
|
|
2188
|
+
const match = filename.match(regexp);
|
|
2189
|
+
if (!match) {
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
let mimeType = mimes[match[1].toLowerCase()];
|
|
2193
|
+
if (mimeType && mimeType.startsWith("text")) {
|
|
2194
|
+
mimeType += "; charset=utf-8";
|
|
2195
|
+
}
|
|
2196
|
+
return mimeType;
|
|
2197
|
+
};
|
|
2198
|
+
var _baseMimes = {
|
|
2199
|
+
aac: "audio/aac",
|
|
2200
|
+
avi: "video/x-msvideo",
|
|
2201
|
+
avif: "image/avif",
|
|
2202
|
+
av1: "video/av1",
|
|
2203
|
+
bin: "application/octet-stream",
|
|
2204
|
+
bmp: "image/bmp",
|
|
2205
|
+
css: "text/css",
|
|
2206
|
+
csv: "text/csv",
|
|
2207
|
+
eot: "application/vnd.ms-fontobject",
|
|
2208
|
+
epub: "application/epub+zip",
|
|
2209
|
+
gif: "image/gif",
|
|
2210
|
+
gz: "application/gzip",
|
|
2211
|
+
htm: "text/html",
|
|
2212
|
+
html: "text/html",
|
|
2213
|
+
ico: "image/x-icon",
|
|
2214
|
+
ics: "text/calendar",
|
|
2215
|
+
jpeg: "image/jpeg",
|
|
2216
|
+
jpg: "image/jpeg",
|
|
2217
|
+
js: "text/javascript",
|
|
2218
|
+
json: "application/json",
|
|
2219
|
+
jsonld: "application/ld+json",
|
|
2220
|
+
map: "application/json",
|
|
2221
|
+
mid: "audio/x-midi",
|
|
2222
|
+
midi: "audio/x-midi",
|
|
2223
|
+
mjs: "text/javascript",
|
|
2224
|
+
mp3: "audio/mpeg",
|
|
2225
|
+
mp4: "video/mp4",
|
|
2226
|
+
mpeg: "video/mpeg",
|
|
2227
|
+
oga: "audio/ogg",
|
|
2228
|
+
ogv: "video/ogg",
|
|
2229
|
+
ogx: "application/ogg",
|
|
2230
|
+
opus: "audio/opus",
|
|
2231
|
+
otf: "font/otf",
|
|
2232
|
+
pdf: "application/pdf",
|
|
2233
|
+
png: "image/png",
|
|
2234
|
+
rtf: "application/rtf",
|
|
2235
|
+
svg: "image/svg+xml",
|
|
2236
|
+
tif: "image/tiff",
|
|
2237
|
+
tiff: "image/tiff",
|
|
2238
|
+
ts: "video/mp2t",
|
|
2239
|
+
ttf: "font/ttf",
|
|
2240
|
+
txt: "text/plain",
|
|
2241
|
+
wasm: "application/wasm",
|
|
2242
|
+
webm: "video/webm",
|
|
2243
|
+
weba: "audio/webm",
|
|
2244
|
+
webmanifest: "application/manifest+json",
|
|
2245
|
+
webp: "image/webp",
|
|
2246
|
+
woff: "font/woff",
|
|
2247
|
+
woff2: "font/woff2",
|
|
2248
|
+
xhtml: "application/xhtml+xml",
|
|
2249
|
+
xml: "application/xml",
|
|
2250
|
+
zip: "application/zip",
|
|
2251
|
+
"3gp": "video/3gpp",
|
|
2252
|
+
"3g2": "video/3gpp2",
|
|
2253
|
+
gltf: "model/gltf+json",
|
|
2254
|
+
glb: "model/gltf-binary"
|
|
2255
|
+
};
|
|
2256
|
+
var baseMimes = _baseMimes;
|
|
2257
|
+
|
|
2258
|
+
// node_modules/@hono/node-server/dist/serve-static.mjs
|
|
2259
|
+
import { createReadStream, statSync as statSync2, existsSync as existsSync2 } from "fs";
|
|
2260
|
+
import { join as join2 } from "path";
|
|
2261
|
+
import { versions } from "process";
|
|
2262
|
+
import { Readable } from "stream";
|
|
2263
|
+
var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
|
|
2264
|
+
var ENCODINGS = {
|
|
2265
|
+
br: ".br",
|
|
2266
|
+
zstd: ".zst",
|
|
2267
|
+
gzip: ".gz"
|
|
2268
|
+
};
|
|
2269
|
+
var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
|
|
2270
|
+
var pr54206Applied = () => {
|
|
2271
|
+
const [major, minor] = versions.node.split(".").map((component) => parseInt(component));
|
|
2272
|
+
return major >= 23 || major === 22 && minor >= 7 || major === 20 && minor >= 18;
|
|
2273
|
+
};
|
|
2274
|
+
var useReadableToWeb = pr54206Applied();
|
|
2275
|
+
var createStreamBody = (stream2) => {
|
|
2276
|
+
if (useReadableToWeb) {
|
|
2277
|
+
return Readable.toWeb(stream2);
|
|
2278
|
+
}
|
|
2279
|
+
const body = new ReadableStream({
|
|
2280
|
+
start(controller) {
|
|
2281
|
+
stream2.on("data", (chunk) => {
|
|
2282
|
+
controller.enqueue(chunk);
|
|
2283
|
+
});
|
|
2284
|
+
stream2.on("error", (err) => {
|
|
2285
|
+
controller.error(err);
|
|
2286
|
+
});
|
|
2287
|
+
stream2.on("end", () => {
|
|
2288
|
+
controller.close();
|
|
2289
|
+
});
|
|
2290
|
+
},
|
|
2291
|
+
cancel() {
|
|
2292
|
+
stream2.destroy();
|
|
2293
|
+
}
|
|
2294
|
+
});
|
|
2295
|
+
return body;
|
|
2296
|
+
};
|
|
2297
|
+
var getStats = (path3) => {
|
|
2298
|
+
let stats;
|
|
2299
|
+
try {
|
|
2300
|
+
stats = statSync2(path3);
|
|
2301
|
+
} catch {
|
|
2302
|
+
}
|
|
2303
|
+
return stats;
|
|
2304
|
+
};
|
|
2305
|
+
var tryDecode = (str, decoder) => {
|
|
2306
|
+
try {
|
|
2307
|
+
return decoder(str);
|
|
2308
|
+
} catch {
|
|
2309
|
+
return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
|
|
2310
|
+
try {
|
|
2311
|
+
return decoder(match);
|
|
2312
|
+
} catch {
|
|
2313
|
+
return match;
|
|
2314
|
+
}
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
var tryDecodeURI = (str) => tryDecode(str, decodeURI);
|
|
2319
|
+
var serveStatic = (options = { root: "" }) => {
|
|
2320
|
+
const root = options.root || "";
|
|
2321
|
+
const optionPath = options.path;
|
|
2322
|
+
if (root !== "" && !existsSync2(root)) {
|
|
2323
|
+
console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
|
|
2324
2324
|
}
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
);
|
|
2329
|
-
notify("webchat-pointer", accountId);
|
|
2330
|
-
return { resource: "webchat-pointer", accountId };
|
|
2331
|
-
}
|
|
2332
|
-
var connections = 0;
|
|
2333
|
-
var started = false;
|
|
2334
|
-
var abort = null;
|
|
2335
|
-
function startManagerEventsSubscriber() {
|
|
2336
|
-
if (started) return;
|
|
2337
|
-
started = true;
|
|
2338
|
-
abort = new AbortController();
|
|
2339
|
-
void connectLoop(abort.signal);
|
|
2340
|
-
}
|
|
2341
|
-
async function connectLoop(signal) {
|
|
2342
|
-
let backoffMs = 1e3;
|
|
2343
|
-
for (; ; ) {
|
|
2344
|
-
if (signal.aborted) return;
|
|
2345
|
-
let port2;
|
|
2346
|
-
try {
|
|
2347
|
-
port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "webchat-pointer" });
|
|
2348
|
-
} catch {
|
|
2349
|
-
console.error(`${TAG} op=drop reason=manager-port-unset`);
|
|
2350
|
-
return;
|
|
2325
|
+
return async (c, next) => {
|
|
2326
|
+
if (c.finalized) {
|
|
2327
|
+
return next();
|
|
2351
2328
|
}
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
let buffer = "";
|
|
2361
|
-
for (; ; ) {
|
|
2362
|
-
const { done, value } = await reader.read();
|
|
2363
|
-
if (done) break;
|
|
2364
|
-
buffer += decoder.decode(value, { stream: true });
|
|
2365
|
-
let cut = buffer.indexOf("\n\n");
|
|
2366
|
-
while (cut !== -1) {
|
|
2367
|
-
handleManagerFrame(buffer.slice(0, cut));
|
|
2368
|
-
buffer = buffer.slice(cut + 2);
|
|
2369
|
-
cut = buffer.indexOf("\n\n");
|
|
2329
|
+
let filename;
|
|
2330
|
+
if (optionPath) {
|
|
2331
|
+
filename = optionPath;
|
|
2332
|
+
} else {
|
|
2333
|
+
try {
|
|
2334
|
+
filename = tryDecodeURI(c.req.path);
|
|
2335
|
+
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
|
2336
|
+
throw new Error();
|
|
2370
2337
|
}
|
|
2338
|
+
} catch {
|
|
2339
|
+
await options.onNotFound?.(c.req.path, c);
|
|
2340
|
+
return next();
|
|
2371
2341
|
}
|
|
2372
|
-
connections -= 1;
|
|
2373
|
-
} catch (err) {
|
|
2374
|
-
if (connections > 0) connections -= 1;
|
|
2375
|
-
if (signal.aborted) return;
|
|
2376
|
-
console.error(`${TAG} op=drop reason=${err instanceof Error ? err.message : String(err)}`);
|
|
2377
2342
|
}
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2343
|
+
let path3 = join2(
|
|
2344
|
+
root,
|
|
2345
|
+
!optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
|
|
2346
|
+
);
|
|
2347
|
+
let stats = getStats(path3);
|
|
2348
|
+
if (stats && stats.isDirectory()) {
|
|
2349
|
+
const indexFile2 = options.index ?? "index.html";
|
|
2350
|
+
path3 = join2(path3, indexFile2);
|
|
2351
|
+
stats = getStats(path3);
|
|
2352
|
+
}
|
|
2353
|
+
if (!stats) {
|
|
2354
|
+
await options.onNotFound?.(path3, c);
|
|
2355
|
+
return next();
|
|
2356
|
+
}
|
|
2357
|
+
const mimeType = getMimeType(path3);
|
|
2358
|
+
c.header("Content-Type", mimeType || "application/octet-stream");
|
|
2359
|
+
if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
|
|
2360
|
+
const acceptEncodingSet = new Set(
|
|
2361
|
+
c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim())
|
|
2362
|
+
);
|
|
2363
|
+
for (const encoding of ENCODINGS_ORDERED_KEYS) {
|
|
2364
|
+
if (!acceptEncodingSet.has(encoding)) {
|
|
2365
|
+
continue;
|
|
2366
|
+
}
|
|
2367
|
+
const precompressedStats = getStats(path3 + ENCODINGS[encoding]);
|
|
2368
|
+
if (precompressedStats) {
|
|
2369
|
+
c.header("Content-Encoding", encoding);
|
|
2370
|
+
c.header("Vary", "Accept-Encoding", { append: true });
|
|
2371
|
+
stats = precompressedStats;
|
|
2372
|
+
path3 = path3 + ENCODINGS[encoding];
|
|
2373
|
+
break;
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
let result;
|
|
2378
|
+
const size = stats.size;
|
|
2379
|
+
const range = c.req.header("range") || "";
|
|
2380
|
+
if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
|
|
2381
|
+
c.header("Content-Length", size.toString());
|
|
2382
|
+
c.status(200);
|
|
2383
|
+
result = c.body(null);
|
|
2384
|
+
} else if (!range) {
|
|
2385
|
+
c.header("Content-Length", size.toString());
|
|
2386
|
+
result = c.body(createStreamBody(createReadStream(path3)), 200);
|
|
2387
|
+
} else {
|
|
2388
|
+
c.header("Accept-Ranges", "bytes");
|
|
2389
|
+
c.header("Date", stats.birthtime.toUTCString());
|
|
2390
|
+
const parts = range.replace(/bytes=/, "").split("-", 2);
|
|
2391
|
+
const start = parseInt(parts[0], 10) || 0;
|
|
2392
|
+
let end = parseInt(parts[1], 10) || size - 1;
|
|
2393
|
+
if (size < end - start + 1) {
|
|
2394
|
+
end = size - 1;
|
|
2395
|
+
}
|
|
2396
|
+
const chunksize = end - start + 1;
|
|
2397
|
+
const stream2 = createReadStream(path3, { start, end });
|
|
2398
|
+
c.header("Content-Length", chunksize.toString());
|
|
2399
|
+
c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
|
|
2400
|
+
result = c.body(createStreamBody(stream2), 206);
|
|
2401
|
+
}
|
|
2402
|
+
await options.onFound?.(path3, c);
|
|
2403
|
+
return result;
|
|
2399
2404
|
};
|
|
2400
|
-
|
|
2401
|
-
return w;
|
|
2402
|
-
}
|
|
2403
|
-
function formatLagWindow(w) {
|
|
2404
|
-
return `[event-loop] op=lag-window p50=${w.p50Ms} p99=${w.p99Ms} max=${w.maxMs} n=${w.count} windowMs=${w.windowMs}`;
|
|
2405
|
-
}
|
|
2405
|
+
};
|
|
2406
2406
|
|
|
2407
2407
|
// server/lib/static-cache.ts
|
|
2408
2408
|
import { statSync as statSync3 } from "fs";
|
|
@@ -2459,6 +2459,18 @@ function staticCacheHeaders(root) {
|
|
|
2459
2459
|
};
|
|
2460
2460
|
}
|
|
2461
2461
|
|
|
2462
|
+
// server/lib/static-mounts.ts
|
|
2463
|
+
function mountStaticFiles(app70, root) {
|
|
2464
|
+
app70.use("/*", staticCacheHeaders(root));
|
|
2465
|
+
app70.use("/assets/*", assetsVary);
|
|
2466
|
+
app70.use("/assets/*", serveStatic({ root, precompressed: true }));
|
|
2467
|
+
app70.use("/*", serveStatic({ root }));
|
|
2468
|
+
}
|
|
2469
|
+
var assetsVary = async (c, next) => {
|
|
2470
|
+
await next();
|
|
2471
|
+
if (!c.res.headers.has("Vary")) c.res.headers.set("Vary", "Accept-Encoding");
|
|
2472
|
+
};
|
|
2473
|
+
|
|
2462
2474
|
// app/lib/whatsapp/inbound/media-download-guard.ts
|
|
2463
2475
|
var TAG2 = "[media-guard]";
|
|
2464
2476
|
var inFlight2 = 0;
|
|
@@ -2653,14 +2665,14 @@ function readAllConversationsCached(accountId) {
|
|
|
2653
2665
|
for (const file of dir) {
|
|
2654
2666
|
if (!file.endsWith(".jsonl")) continue;
|
|
2655
2667
|
const path3 = join5(STORE_ROOT(), accountId, file);
|
|
2656
|
-
let
|
|
2668
|
+
let stat12;
|
|
2657
2669
|
try {
|
|
2658
|
-
|
|
2670
|
+
stat12 = statSync4(path3);
|
|
2659
2671
|
} catch {
|
|
2660
2672
|
continue;
|
|
2661
2673
|
}
|
|
2662
2674
|
const hit = idCache.get(path3);
|
|
2663
|
-
if (hit && hit.size ===
|
|
2675
|
+
if (hit && hit.size === stat12.size && hit.mtimeMs === stat12.mtimeMs) {
|
|
2664
2676
|
out.set(file, hit.ids);
|
|
2665
2677
|
continue;
|
|
2666
2678
|
}
|
|
@@ -2677,7 +2689,7 @@ function readAllConversationsCached(accountId) {
|
|
|
2677
2689
|
} catch {
|
|
2678
2690
|
continue;
|
|
2679
2691
|
}
|
|
2680
|
-
idCache.set(path3, { size:
|
|
2692
|
+
idCache.set(path3, { size: stat12.size, mtimeMs: stat12.mtimeMs, ids: parsed });
|
|
2681
2693
|
out.set(file, parsed);
|
|
2682
2694
|
}
|
|
2683
2695
|
return out;
|
|
@@ -11583,11 +11595,12 @@ function runReconcileLivenessAudit(statePath, nowMs, intervalMs, emit) {
|
|
|
11583
11595
|
}
|
|
11584
11596
|
|
|
11585
11597
|
// server/routes/whatsapp-reader.ts
|
|
11586
|
-
import { readFileSync as readFileSync21, watch as watch2, statSync as
|
|
11598
|
+
import { readFileSync as readFileSync21, watch as watch2, statSync as statSync8, openSync, readSync, closeSync, existsSync as existsSync17, readdirSync as readdirSync14, realpathSync as realpathSync6 } from "fs";
|
|
11587
11599
|
import { basename as basename6, dirname as dirname7, isAbsolute, join as join22, relative as relative3, resolve as resolve17, sep as sep5 } from "path";
|
|
11588
11600
|
|
|
11589
11601
|
// server/routes/admin/sidebar-sessions.ts
|
|
11590
|
-
import { readdirSync as readdirSync12, readFileSync as readFileSync19
|
|
11602
|
+
import { readdirSync as readdirSync12, readFileSync as readFileSync19 } from "fs";
|
|
11603
|
+
import { readFile as readFile4, stat as stat5 } from "fs/promises";
|
|
11591
11604
|
import { dirname as dirname5, join as join20, resolve as resolve15 } from "path";
|
|
11592
11605
|
|
|
11593
11606
|
// ../services/claude-session-manager/src/jsonl-path.ts
|
|
@@ -11817,15 +11830,27 @@ async function fetchLiveSessions() {
|
|
|
11817
11830
|
return out;
|
|
11818
11831
|
}
|
|
11819
11832
|
function loadUserTitles(accountDir) {
|
|
11820
|
-
|
|
11821
|
-
if (!accountDir) return out;
|
|
11822
|
-
const path3 = join20(accountDir, "session-titles.json");
|
|
11833
|
+
if (!accountDir) return /* @__PURE__ */ new Map();
|
|
11823
11834
|
let raw;
|
|
11824
11835
|
try {
|
|
11825
|
-
raw = readFileSync19(
|
|
11836
|
+
raw = readFileSync19(join20(accountDir, "session-titles.json"), "utf8");
|
|
11826
11837
|
} catch {
|
|
11827
|
-
return
|
|
11838
|
+
return /* @__PURE__ */ new Map();
|
|
11839
|
+
}
|
|
11840
|
+
return parseUserTitles(raw);
|
|
11841
|
+
}
|
|
11842
|
+
async function loadUserTitlesAsync(accountDir) {
|
|
11843
|
+
if (!accountDir) return /* @__PURE__ */ new Map();
|
|
11844
|
+
let raw;
|
|
11845
|
+
try {
|
|
11846
|
+
raw = await readFile4(join20(accountDir, "session-titles.json"), "utf8");
|
|
11847
|
+
} catch {
|
|
11848
|
+
return /* @__PURE__ */ new Map();
|
|
11828
11849
|
}
|
|
11850
|
+
return parseUserTitles(raw);
|
|
11851
|
+
}
|
|
11852
|
+
function parseUserTitles(raw) {
|
|
11853
|
+
const out = /* @__PURE__ */ new Map();
|
|
11829
11854
|
let parsed;
|
|
11830
11855
|
try {
|
|
11831
11856
|
parsed = JSON.parse(raw);
|
|
@@ -11845,20 +11870,34 @@ function loadUserTitles(accountDir) {
|
|
|
11845
11870
|
return out;
|
|
11846
11871
|
}
|
|
11847
11872
|
function readSidecarMeta(metaPath) {
|
|
11848
|
-
const empty = { bridgeIds: [], role: null, channel: null, senderId: null, startedAt: null, personId: null, adminUserId: null, visitorId: null, agentSlug: null, accountId: null };
|
|
11849
11873
|
let raw;
|
|
11850
11874
|
try {
|
|
11851
11875
|
raw = readFileSync19(metaPath, "utf8");
|
|
11852
11876
|
} catch {
|
|
11853
|
-
return
|
|
11877
|
+
return emptySidecarMeta();
|
|
11878
|
+
}
|
|
11879
|
+
return parseSidecarMeta(raw);
|
|
11880
|
+
}
|
|
11881
|
+
function emptySidecarMeta() {
|
|
11882
|
+
return { bridgeIds: [], role: null, channel: null, senderId: null, startedAt: null, personId: null, adminUserId: null, visitorId: null, agentSlug: null, accountId: null };
|
|
11883
|
+
}
|
|
11884
|
+
async function readSidecarMetaAsync(metaPath) {
|
|
11885
|
+
let raw;
|
|
11886
|
+
try {
|
|
11887
|
+
raw = await readFile4(metaPath, "utf8");
|
|
11888
|
+
} catch {
|
|
11889
|
+
return emptySidecarMeta();
|
|
11854
11890
|
}
|
|
11891
|
+
return parseSidecarMeta(raw);
|
|
11892
|
+
}
|
|
11893
|
+
function parseSidecarMeta(raw) {
|
|
11855
11894
|
let parsed;
|
|
11856
11895
|
try {
|
|
11857
11896
|
parsed = JSON.parse(raw);
|
|
11858
11897
|
} catch {
|
|
11859
|
-
return
|
|
11898
|
+
return emptySidecarMeta();
|
|
11860
11899
|
}
|
|
11861
|
-
if (!parsed || typeof parsed !== "object") return
|
|
11900
|
+
if (!parsed || typeof parsed !== "object") return emptySidecarMeta();
|
|
11862
11901
|
const r = parsed;
|
|
11863
11902
|
const bridgeIds = Array.isArray(r.bridgeIds) ? r.bridgeIds.filter((b) => typeof b === "string" && b.length > 0) : [];
|
|
11864
11903
|
return {
|
|
@@ -11963,8 +12002,8 @@ async function computeSessionList(scopeAccountId) {
|
|
|
11963
12002
|
const jsonls = enumerateJsonls(projectsRoot);
|
|
11964
12003
|
const liveSessions = await fetchLiveSessions();
|
|
11965
12004
|
const accountDir = scopeAccountId ? resolve15(ACCOUNTS_DIR, scopeAccountId) : null;
|
|
11966
|
-
const userTitles =
|
|
11967
|
-
const account = multiAccount ? validAccounts.find((a) => a.accountId === scopeAccountId) ?? null :
|
|
12005
|
+
const userTitles = await loadUserTitlesAsync(accountDir);
|
|
12006
|
+
const account = multiAccount ? validAccounts.find((a) => a.accountId === scopeAccountId) ?? null : validAccounts[0] ?? null;
|
|
11968
12007
|
let channelUsers = [];
|
|
11969
12008
|
if (account) {
|
|
11970
12009
|
try {
|
|
@@ -12003,8 +12042,8 @@ async function computeSessionList(scopeAccountId) {
|
|
|
12003
12042
|
let body;
|
|
12004
12043
|
let mtimeMs;
|
|
12005
12044
|
try {
|
|
12006
|
-
body =
|
|
12007
|
-
mtimeMs =
|
|
12045
|
+
body = await readFile4(path3, "utf8");
|
|
12046
|
+
mtimeMs = (await stat5(path3)).mtimeMs;
|
|
12008
12047
|
} catch {
|
|
12009
12048
|
continue;
|
|
12010
12049
|
}
|
|
@@ -12013,7 +12052,7 @@ async function computeSessionList(scopeAccountId) {
|
|
|
12013
12052
|
const resolved = resolveTitle(body, sessionId, userTitles);
|
|
12014
12053
|
titleSourceCounts[resolved.source] += 1;
|
|
12015
12054
|
const metaPath = join20(projectDir, `${sessionId}.meta.json`);
|
|
12016
|
-
const { bridgeIds, role, channel: sidecarChannel, senderId, personId, adminUserId, accountId: rowAccountId } =
|
|
12055
|
+
const { bridgeIds, role, channel: sidecarChannel, senderId, personId, adminUserId, accountId: rowAccountId } = await readSidecarMetaAsync(metaPath);
|
|
12017
12056
|
if (multiAccount) {
|
|
12018
12057
|
if (rowAccountId === null) untaggedCount += 1;
|
|
12019
12058
|
if (rowAccountId !== scopeAccountId) continue;
|
|
@@ -12414,7 +12453,7 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
12414
12453
|
}
|
|
12415
12454
|
|
|
12416
12455
|
// app/lib/whatsapp-reader/enrich-attachments.ts
|
|
12417
|
-
import { readFileSync as readFileSync20, readdirSync as readdirSync13, existsSync as existsSync16, statSync as
|
|
12456
|
+
import { readFileSync as readFileSync20, readdirSync as readdirSync13, existsSync as existsSync16, statSync as statSync7, realpathSync as realpathSync5 } from "fs";
|
|
12418
12457
|
import { basename as basename5, dirname as dirname6, join as join21, resolve as resolve16, sep as sep4 } from "path";
|
|
12419
12458
|
var ADMIN_UPLOAD_PATH = /\/uploads\/(?!public\/)([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})\//gi;
|
|
12420
12459
|
function adminAttachmentIds(text) {
|
|
@@ -12465,7 +12504,7 @@ function claudeUploadAttachmentsFromText(text, sessionId) {
|
|
|
12465
12504
|
attachmentId: filename,
|
|
12466
12505
|
filename,
|
|
12467
12506
|
mimeType: detectMimeType(filename),
|
|
12468
|
-
sizeBytes:
|
|
12507
|
+
sizeBytes: statSync7(real).size,
|
|
12469
12508
|
source: "claude-upload"
|
|
12470
12509
|
});
|
|
12471
12510
|
accepted.push(m[0]);
|
|
@@ -12885,7 +12924,7 @@ app5.get("/conversations-all", requireAdminSession, async (c) => {
|
|
|
12885
12924
|
return c.json(value);
|
|
12886
12925
|
});
|
|
12887
12926
|
function readFrom(path3, from) {
|
|
12888
|
-
const end =
|
|
12927
|
+
const end = statSync8(path3).size;
|
|
12889
12928
|
if (end <= from) return { buf: Buffer.alloc(0), end: from };
|
|
12890
12929
|
const fd = openSync(path3, "r");
|
|
12891
12930
|
try {
|
|
@@ -13011,7 +13050,7 @@ function runActivityTick(c) {
|
|
|
13011
13050
|
let size = 0;
|
|
13012
13051
|
let mtimeMs = 0;
|
|
13013
13052
|
try {
|
|
13014
|
-
const st =
|
|
13053
|
+
const st = statSync8(join22(c.subagentsDir, name));
|
|
13015
13054
|
size = st.size;
|
|
13016
13055
|
mtimeMs = st.mtimeMs;
|
|
13017
13056
|
} catch {
|
|
@@ -13079,7 +13118,7 @@ data: ${JSON.stringify(turn)}
|
|
|
13079
13118
|
start(controller) {
|
|
13080
13119
|
const fileEnd0 = (() => {
|
|
13081
13120
|
try {
|
|
13082
|
-
return
|
|
13121
|
+
return statSync8(jsonlPath).size;
|
|
13083
13122
|
} catch {
|
|
13084
13123
|
return 0;
|
|
13085
13124
|
}
|
|
@@ -13216,7 +13255,7 @@ app5.get("/directives", requireAdminSession, (c) => {
|
|
|
13216
13255
|
const pid = Number(pidPart);
|
|
13217
13256
|
let len = 0;
|
|
13218
13257
|
try {
|
|
13219
|
-
len =
|
|
13258
|
+
len = statSync8(join22(dir, name)).size;
|
|
13220
13259
|
} catch {
|
|
13221
13260
|
}
|
|
13222
13261
|
return { name, secs, pid, ts: Number.isFinite(secs) ? new Date(secs * 1e3).toISOString() : null, len };
|
|
@@ -13322,7 +13361,7 @@ data: ${JSON.stringify(payload)}
|
|
|
13322
13361
|
};
|
|
13323
13362
|
const fileEnd0 = (() => {
|
|
13324
13363
|
try {
|
|
13325
|
-
return
|
|
13364
|
+
return statSync8(file).size;
|
|
13326
13365
|
} catch {
|
|
13327
13366
|
return 0;
|
|
13328
13367
|
}
|
|
@@ -13540,7 +13579,7 @@ app5.post("/reply", requireAdminSession, async (c) => {
|
|
|
13540
13579
|
const absolute = resolved.absolute;
|
|
13541
13580
|
let size = -1;
|
|
13542
13581
|
try {
|
|
13543
|
-
const st =
|
|
13582
|
+
const st = statSync8(absolute);
|
|
13544
13583
|
size = st.isFile() ? st.size : -1;
|
|
13545
13584
|
} catch {
|
|
13546
13585
|
size = -1;
|
|
@@ -13669,7 +13708,7 @@ app5.post("/reply", requireAdminSession, async (c) => {
|
|
|
13669
13708
|
var whatsapp_reader_default = app5;
|
|
13670
13709
|
|
|
13671
13710
|
// server/routes/public-reader.ts
|
|
13672
|
-
import { statSync as
|
|
13711
|
+
import { statSync as statSync9, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch3, readFileSync as readFileSync22, readdirSync as readdirSync15 } from "fs";
|
|
13673
13712
|
import { basename as basename7, dirname as dirname8, join as join23, resolve as resolve18, sep as sep6 } from "path";
|
|
13674
13713
|
|
|
13675
13714
|
// app/lib/whatsapp-reader/delivered-kinds.ts
|
|
@@ -13803,7 +13842,7 @@ function enrichPublicAttachments(turns, sessionAttachments, cursor) {
|
|
|
13803
13842
|
}
|
|
13804
13843
|
}
|
|
13805
13844
|
function readFrom2(path3, from) {
|
|
13806
|
-
const end =
|
|
13845
|
+
const end = statSync9(path3).size;
|
|
13807
13846
|
if (end <= from) return { buf: Buffer.alloc(0), end: from };
|
|
13808
13847
|
const fd = openSync2(path3, "r");
|
|
13809
13848
|
try {
|
|
@@ -13969,7 +14008,7 @@ var public_reader_default = app6;
|
|
|
13969
14008
|
// server/routes/webchat.ts
|
|
13970
14009
|
import { basename as basename8, dirname as dirname9 } from "path";
|
|
13971
14010
|
import { join as join26 } from "path";
|
|
13972
|
-
import { existsSync as existsSync19, readdirSync as readdirSync17, readFileSync as readFileSync25, renameSync as renameSync4, statSync as
|
|
14011
|
+
import { existsSync as existsSync19, readdirSync as readdirSync17, readFileSync as readFileSync25, renameSync as renameSync4, statSync as statSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
13973
14012
|
|
|
13974
14013
|
// server/canonical-webchat-override.ts
|
|
13975
14014
|
import { readFileSync as readFileSync23, writeFileSync as writeFileSync7, renameSync as renameSync2 } from "fs";
|
|
@@ -14013,6 +14052,31 @@ function writeCanonicalOverrideId(accountDir, userId, sessionId) {
|
|
|
14013
14052
|
renameSync2(tmp, path3);
|
|
14014
14053
|
}
|
|
14015
14054
|
|
|
14055
|
+
// server/routes/admin/_account-scope.ts
|
|
14056
|
+
function accountDirForSession(cacheKey) {
|
|
14057
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
14058
|
+
if (!accountId) return null;
|
|
14059
|
+
const match = listValidAccounts().find((a) => a.accountId === accountId);
|
|
14060
|
+
return match ? { accountId, accountDir: match.accountDir, config: match.config } : null;
|
|
14061
|
+
}
|
|
14062
|
+
function validateAccountId2(accountId) {
|
|
14063
|
+
if (!accountId) return null;
|
|
14064
|
+
const match = listValidAccounts().find((a) => a.accountId === accountId);
|
|
14065
|
+
return match ? { accountId, accountDir: match.accountDir, config: match.config } : null;
|
|
14066
|
+
}
|
|
14067
|
+
async function authorizeAccountWrite(c, accountId) {
|
|
14068
|
+
const remote = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
14069
|
+
const peerIsLoopback = remote === "127.0.0.1" || remote === "::1" || remote === "::ffff:127.0.0.1";
|
|
14070
|
+
if (peerIsLoopback && !c.req.header("x-forwarded-for")) return { ok: true, via: "on-device" };
|
|
14071
|
+
const { fingerprint, signedSessionToken } = await resolveCacheKey(c);
|
|
14072
|
+
if (!fingerprint || !validateSession(fingerprint, "admin", signedSessionToken).ok) {
|
|
14073
|
+
return { ok: false, reason: "no-session" };
|
|
14074
|
+
}
|
|
14075
|
+
const acct = accountDirForSession(fingerprint);
|
|
14076
|
+
if (!acct || acct.accountId !== accountId) return { ok: false, reason: "account-mismatch" };
|
|
14077
|
+
return { ok: true, via: "session" };
|
|
14078
|
+
}
|
|
14079
|
+
|
|
14016
14080
|
// ../lib/models/src/index.ts
|
|
14017
14081
|
var OPUS_MODEL = "claude-opus-5[1m]";
|
|
14018
14082
|
var SONNET_MODEL = "claude-sonnet-5";
|
|
@@ -14231,7 +14295,7 @@ function sessionSidecarExists(sessionId) {
|
|
|
14231
14295
|
function jsonlSizeBytes(projectDir, sessionId) {
|
|
14232
14296
|
if (projectDir === null) return null;
|
|
14233
14297
|
try {
|
|
14234
|
-
return
|
|
14298
|
+
return statSync10(join26(projectDir, `${sessionId}.jsonl`)).size;
|
|
14235
14299
|
} catch {
|
|
14236
14300
|
return null;
|
|
14237
14301
|
}
|
|
@@ -14334,15 +14398,7 @@ async function managerInterrupt(sessionId, trigger, escalate = false) {
|
|
|
14334
14398
|
}
|
|
14335
14399
|
}
|
|
14336
14400
|
var MODEL_ID_PATTERN = /^claude-[a-z0-9][a-z0-9.-]*(\[1m\])?$/;
|
|
14337
|
-
function readLevers(
|
|
14338
|
-
let account = preResolved;
|
|
14339
|
-
if (account === void 0) {
|
|
14340
|
-
try {
|
|
14341
|
-
account = resolveAccount();
|
|
14342
|
-
} catch {
|
|
14343
|
-
return { leverModel: null, leverEffort: null, leverMode: null };
|
|
14344
|
-
}
|
|
14345
|
-
}
|
|
14401
|
+
function readLevers(account) {
|
|
14346
14402
|
if (!account) return { leverModel: null, leverEffort: null, leverMode: null };
|
|
14347
14403
|
const model = account.config.adminModel;
|
|
14348
14404
|
const effort = account.config.effort;
|
|
@@ -14375,7 +14431,7 @@ function latestAdminWebchatSessionId(requesterUserId, primaryUserId, scopeAccoun
|
|
|
14375
14431
|
if (multiAccount && meta.accountId !== scopeAccountId) continue;
|
|
14376
14432
|
let mtimeMs;
|
|
14377
14433
|
try {
|
|
14378
|
-
mtimeMs =
|
|
14434
|
+
mtimeMs = statSync10(path3).mtimeMs;
|
|
14379
14435
|
} catch {
|
|
14380
14436
|
continue;
|
|
14381
14437
|
}
|
|
@@ -14608,12 +14664,7 @@ ${note}` : note;
|
|
|
14608
14664
|
const sendId = sendIdFromResolve ?? ++sendSeq;
|
|
14609
14665
|
let turnSessionId = deliverySessionId;
|
|
14610
14666
|
if (turnSessionId === void 0) {
|
|
14611
|
-
|
|
14612
|
-
try {
|
|
14613
|
-
canonAccount = resolveAccount();
|
|
14614
|
-
} catch {
|
|
14615
|
-
canonAccount = null;
|
|
14616
|
-
}
|
|
14667
|
+
const canonAccount = scopeAccountId ? validateAccountId2(scopeAccountId) : null;
|
|
14617
14668
|
turnSessionId = resolveCanonical(accountId, canonAccount?.accountDir ?? null, requesterUserId, primaryUserId, scopeAccountId, multiAccount).sessionId;
|
|
14618
14669
|
}
|
|
14619
14670
|
const keyDisplay2 = deliveryKey.startsWith("session:") ? deliveryKey.slice(0, "session:".length + 8) : WEBCHAT_ADMIN_KEY;
|
|
@@ -14673,14 +14724,10 @@ ${note}` : note;
|
|
|
14673
14724
|
console.error(`[webchat:settings] op=${op} outcome=refused value=${JSON.stringify(value)} reason=invalid-value`);
|
|
14674
14725
|
return c.json({ error: `invalid ${op} value` }, 400);
|
|
14675
14726
|
}
|
|
14676
|
-
|
|
14677
|
-
|
|
14678
|
-
account = resolveAccount();
|
|
14679
|
-
} catch {
|
|
14680
|
-
account = null;
|
|
14681
|
-
}
|
|
14727
|
+
const cacheKey = c.get("cacheKey");
|
|
14728
|
+
const account = cacheKey ? accountDirForSession(cacheKey) : null;
|
|
14682
14729
|
if (!account) {
|
|
14683
|
-
console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-
|
|
14730
|
+
console.error(`[webchat:settings] op=${op} outcome=refused value=${value} accountId=none reason=no-account-for-session`);
|
|
14684
14731
|
return c.json({ error: "account unresolved" }, 503);
|
|
14685
14732
|
}
|
|
14686
14733
|
const accountJsonPath = join26(account.accountDir, "account.json");
|
|
@@ -14698,7 +14745,7 @@ ${note}` : note;
|
|
|
14698
14745
|
return c.json({ error: "persist failed" }, 500);
|
|
14699
14746
|
}
|
|
14700
14747
|
const settingsApplied = await reapplyLeversViaManager();
|
|
14701
|
-
console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
|
|
14748
|
+
console.log(`[webchat:settings] op=${op} outcome=accepted accountId=${account.accountId.slice(0, 8)} value=${value} settingsApplied=${settingsApplied}`);
|
|
14702
14749
|
return c.json({ ok: true, settingsApplied });
|
|
14703
14750
|
});
|
|
14704
14751
|
app70.get("/session", requireAdminSession, async (c) => {
|
|
@@ -14744,14 +14791,9 @@ ${note}` : note;
|
|
|
14744
14791
|
}
|
|
14745
14792
|
const known = resolvedProjectDir !== null || sessionSidecarExists(target);
|
|
14746
14793
|
const indicators2 = await fetchComposerIndicators(target);
|
|
14747
|
-
return c.json({ sessionId: target, projectDir: resolvedProjectDir, transcriptSessionId, channelBinding: conflictingBinding(channel), known, sizeBytes: jsonlSizeBytes(projectDir2, target), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${target}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${target}`) ?? null, ...indicators2, ...readLevers() });
|
|
14748
|
-
}
|
|
14749
|
-
let account;
|
|
14750
|
-
try {
|
|
14751
|
-
account = resolveAccount();
|
|
14752
|
-
} catch {
|
|
14753
|
-
account = null;
|
|
14794
|
+
return c.json({ sessionId: target, projectDir: resolvedProjectDir, transcriptSessionId, channelBinding: conflictingBinding(channel), known, sizeBytes: jsonlSizeBytes(projectDir2, target), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${target}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${target}`) ?? null, ...indicators2, ...readLevers(scopeAccountId ? validateAccountId2(scopeAccountId) : null) });
|
|
14754
14795
|
}
|
|
14796
|
+
const account = scopeAccountId ? validateAccountId2(scopeAccountId) : null;
|
|
14755
14797
|
const { sessionId, source } = resolveCanonical(accountId, account?.accountDir ?? null, requesterUserId, primaryUserId, scopeAccountId, multiAccount);
|
|
14756
14798
|
if (requesterUserId === null) {
|
|
14757
14799
|
console.error(`[webchat:inbound] op=session-resolve-no-identity key=${sessionId.slice(0, 8)}`);
|
|
@@ -15336,7 +15378,7 @@ function readHostCredsBlob(service) {
|
|
|
15336
15378
|
}
|
|
15337
15379
|
|
|
15338
15380
|
// ../lib/admins-write/src/index.ts
|
|
15339
|
-
import { existsSync as existsSync23, readFileSync as readFileSync29, writeFileSync as writeFileSync11, renameSync as renameSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync19, statSync as
|
|
15381
|
+
import { existsSync as existsSync23, readFileSync as readFileSync29, writeFileSync as writeFileSync11, renameSync as renameSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync19, statSync as statSync11, appendFileSync as appendFileSync3 } from "fs";
|
|
15340
15382
|
import { dirname as dirname10, join as join30 } from "path";
|
|
15341
15383
|
function id8(value) {
|
|
15342
15384
|
return value.slice(0, 8);
|
|
@@ -15460,7 +15502,7 @@ function computeAdminStoreDivergence(input) {
|
|
|
15460
15502
|
if (entry.startsWith(".")) continue;
|
|
15461
15503
|
const accountDir = join30(input.accountsDir, entry);
|
|
15462
15504
|
try {
|
|
15463
|
-
if (!
|
|
15505
|
+
if (!statSync11(accountDir).isDirectory()) continue;
|
|
15464
15506
|
} catch {
|
|
15465
15507
|
continue;
|
|
15466
15508
|
}
|
|
@@ -15907,7 +15949,7 @@ ${body.newPin}
|
|
|
15907
15949
|
var onboarding_default = app10;
|
|
15908
15950
|
|
|
15909
15951
|
// server/routes/client-error.ts
|
|
15910
|
-
import { appendFileSync as appendFileSync4, existsSync as existsSync25, renameSync as renameSync8, statSync as
|
|
15952
|
+
import { appendFileSync as appendFileSync4, existsSync as existsSync25, renameSync as renameSync8, statSync as statSync12 } from "fs";
|
|
15911
15953
|
import { join as join32 } from "path";
|
|
15912
15954
|
var CLIENT_ERRORS_LOG = join32(LOG_DIR, "client-errors.log");
|
|
15913
15955
|
var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
@@ -15967,7 +16009,7 @@ function stackHead(stack) {
|
|
|
15967
16009
|
function rotateIfNeeded() {
|
|
15968
16010
|
try {
|
|
15969
16011
|
if (!existsSync25(CLIENT_ERRORS_LOG)) return;
|
|
15970
|
-
const stats =
|
|
16012
|
+
const stats = statSync12(CLIENT_ERRORS_LOG);
|
|
15971
16013
|
if (stats.size < MAX_LOG_SIZE) return;
|
|
15972
16014
|
renameSync8(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
|
|
15973
16015
|
} catch (err) {
|
|
@@ -16108,7 +16150,7 @@ async function resolveUserIdentity(accountId, userId) {
|
|
|
16108
16150
|
return { userName, avatar: null };
|
|
16109
16151
|
}
|
|
16110
16152
|
async function createAdminSession(accountId, thinkingView, userId, userName, role, avatar) {
|
|
16111
|
-
const account =
|
|
16153
|
+
const account = validateAccountId2(accountId);
|
|
16112
16154
|
const effectiveThinkingView = thinkingView ?? account?.config.thinkingView ?? "default";
|
|
16113
16155
|
const signedSessionToken = randomUUID9();
|
|
16114
16156
|
const cacheKey = fingerprintSessionKey(signedSessionToken);
|
|
@@ -16184,11 +16226,11 @@ app12.get("/", async (c) => {
|
|
|
16184
16226
|
if (!accountId) {
|
|
16185
16227
|
return c.json({ error: "Session has no account binding" }, 401);
|
|
16186
16228
|
}
|
|
16187
|
-
const account =
|
|
16229
|
+
const account = validateAccountId2(accountId);
|
|
16188
16230
|
const thinkingView = account?.config.thinkingView ?? "default";
|
|
16189
16231
|
const businessName = await fetchAccountName(accountId) || void 0;
|
|
16190
16232
|
const role = getRoleForSession(cacheKey);
|
|
16191
|
-
console.log(`[admin-session] role=${role ?? "null"} cacheKey=${cacheKey.slice(0, 8)} phase=restore`);
|
|
16233
|
+
console.log(`[admin-session] role=${role ?? "null"} accountId=${accountId.slice(0, 8)} cacheKey=${cacheKey.slice(0, 8)} phase=restore`);
|
|
16192
16234
|
const restoredUserId = getUserIdForSession(cacheKey);
|
|
16193
16235
|
let restoredUserName = getUserNameForSession(cacheKey);
|
|
16194
16236
|
let restoredAvatar = null;
|
|
@@ -16293,7 +16335,7 @@ app13.get("/", requireAdminSession, async (c) => {
|
|
|
16293
16335
|
var accounts_default = app13;
|
|
16294
16336
|
|
|
16295
16337
|
// server/routes/admin/logs.ts
|
|
16296
|
-
import { existsSync as existsSync27, readdirSync as readdirSync20, readFileSync as readFileSync31, statSync as
|
|
16338
|
+
import { existsSync as existsSync27, readdirSync as readdirSync20, readFileSync as readFileSync31, statSync as statSync13 } from "fs";
|
|
16297
16339
|
import { resolve as resolve21, basename as basename9 } from "path";
|
|
16298
16340
|
|
|
16299
16341
|
// app/lib/logs-read-resolve.ts
|
|
@@ -16320,10 +16362,7 @@ app14.get("/", async (c) => {
|
|
|
16320
16362
|
const sessionIdParam = c.req.query("sessionId");
|
|
16321
16363
|
const cacheKeyParam = c.req.query("cacheKey");
|
|
16322
16364
|
const download = c.req.query("download") === "1";
|
|
16323
|
-
const
|
|
16324
|
-
const accountLogDir = account ? resolve21(account.accountDir, "logs") : null;
|
|
16325
|
-
const logDirs = [];
|
|
16326
|
-
if (accountLogDir) logDirs.push(accountLogDir);
|
|
16365
|
+
const logDirs = listValidAccounts().slice().sort((a, b) => a.accountId.localeCompare(b.accountId)).map((a) => resolve21(a.accountDir, "logs"));
|
|
16327
16366
|
logDirs.push(LOG_DIR);
|
|
16328
16367
|
if (fileParam) {
|
|
16329
16368
|
const safe = basename9(fileParam);
|
|
@@ -16333,13 +16372,13 @@ app14.get("/", async (c) => {
|
|
|
16333
16372
|
searched.push(filePath);
|
|
16334
16373
|
try {
|
|
16335
16374
|
const buffer = readFileSync31(filePath);
|
|
16336
|
-
const onDiskBytes =
|
|
16375
|
+
const onDiskBytes = statSync13(filePath).size;
|
|
16337
16376
|
const headers = {
|
|
16338
16377
|
"Content-Type": "text/plain; charset=utf-8",
|
|
16339
16378
|
"Content-Length": String(buffer.byteLength)
|
|
16340
16379
|
};
|
|
16341
16380
|
if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
|
|
16342
|
-
console.info(`[stream-log-download] file=${safe} bytesServed=${buffer.byteLength} onDiskBytes=${onDiskBytes}`);
|
|
16381
|
+
console.info(`[stream-log-download] file=${safe} dir=${dir} bytesServed=${buffer.byteLength} onDiskBytes=${onDiskBytes}`);
|
|
16343
16382
|
return new Response(buffer, { headers });
|
|
16344
16383
|
} catch (err) {
|
|
16345
16384
|
const reason = err instanceof Error ? err.message : String(err);
|
|
@@ -16398,13 +16437,13 @@ app14.get("/", async (c) => {
|
|
|
16398
16437
|
try {
|
|
16399
16438
|
const filename = basename9(hit.path);
|
|
16400
16439
|
const buffer = readFileSync31(hit.path);
|
|
16401
|
-
const onDiskBytes =
|
|
16440
|
+
const onDiskBytes = statSync13(hit.path).size;
|
|
16402
16441
|
const headers = {
|
|
16403
16442
|
"Content-Type": "text/plain; charset=utf-8",
|
|
16404
16443
|
"Content-Length": String(buffer.byteLength)
|
|
16405
16444
|
};
|
|
16406
16445
|
if (download) headers["Content-Disposition"] = `attachment; filename="${filename}"`;
|
|
16407
|
-
console.info(`[stream-log-download] file=${filename} bytesServed=${buffer.byteLength} onDiskBytes=${onDiskBytes}`);
|
|
16446
|
+
console.info(`[stream-log-download] file=${filename} dir=${hit.dir} bytesServed=${buffer.byteLength} onDiskBytes=${onDiskBytes}`);
|
|
16408
16447
|
return new Response(buffer, { headers });
|
|
16409
16448
|
} catch (err) {
|
|
16410
16449
|
const reason2 = err instanceof Error ? err.message : String(err);
|
|
@@ -16441,7 +16480,7 @@ app14.get("/", async (c) => {
|
|
|
16441
16480
|
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
16442
16481
|
continue;
|
|
16443
16482
|
}
|
|
16444
|
-
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime:
|
|
16483
|
+
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync13(resolve21(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
16445
16484
|
seen.add(name);
|
|
16446
16485
|
try {
|
|
16447
16486
|
const content = readFileSync31(resolve21(dir, name));
|
|
@@ -16461,7 +16500,12 @@ var logs_default = app14;
|
|
|
16461
16500
|
// server/routes/admin/claude-info.ts
|
|
16462
16501
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
16463
16502
|
var app15 = new Hono();
|
|
16464
|
-
app15.get("/", (c) => {
|
|
16503
|
+
app15.get("/", requireAdminSession, (c) => {
|
|
16504
|
+
const account = accountDirForSession(c.var.cacheKey);
|
|
16505
|
+
if (!account) {
|
|
16506
|
+
console.error("[admin/claude-info] auth-rejected reason=no-account-for-session accountId=none");
|
|
16507
|
+
return c.json({ error: "no account for session", reason: "no-account-for-session" }, 401);
|
|
16508
|
+
}
|
|
16465
16509
|
const claudeEnv = { ...process.env };
|
|
16466
16510
|
let version = "unknown";
|
|
16467
16511
|
try {
|
|
@@ -16469,21 +16513,21 @@ app15.get("/", (c) => {
|
|
|
16469
16513
|
version = raw.trim().replace(" (Claude Code)", "");
|
|
16470
16514
|
} catch {
|
|
16471
16515
|
}
|
|
16472
|
-
let
|
|
16516
|
+
let claudeAccount = {};
|
|
16473
16517
|
try {
|
|
16474
16518
|
const raw = execFileSync5(claudeBin(), ["auth", "status"], { env: claudeEnv, encoding: "utf-8", timeout: 5e3 });
|
|
16475
|
-
|
|
16519
|
+
claudeAccount = JSON.parse(raw);
|
|
16476
16520
|
} catch {
|
|
16477
16521
|
}
|
|
16478
|
-
const
|
|
16479
|
-
const
|
|
16480
|
-
|
|
16481
|
-
return c.json({ version, account, model, thinkingView });
|
|
16522
|
+
const model = account.config.adminModel ?? "unknown";
|
|
16523
|
+
const thinkingView = account.config.thinkingView ?? "default";
|
|
16524
|
+
console.log(`[admin/claude-info] op=read accountId=${account.accountId.slice(0, 8)} model=${model}`);
|
|
16525
|
+
return c.json({ version, account: claudeAccount, model, thinkingView });
|
|
16482
16526
|
});
|
|
16483
16527
|
var claude_info_default = app15;
|
|
16484
16528
|
|
|
16485
16529
|
// server/routes/admin/attachment.ts
|
|
16486
|
-
import { readFile as
|
|
16530
|
+
import { readFile as readFile5, readdir as readdir2 } from "fs/promises";
|
|
16487
16531
|
import { existsSync as existsSync28 } from "fs";
|
|
16488
16532
|
import { resolve as resolve22 } from "path";
|
|
16489
16533
|
var app16 = new Hono();
|
|
@@ -16532,7 +16576,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
16532
16576
|
}
|
|
16533
16577
|
let meta;
|
|
16534
16578
|
try {
|
|
16535
|
-
meta = JSON.parse(await
|
|
16579
|
+
meta = JSON.parse(await readFile5(metaPath, "utf-8"));
|
|
16536
16580
|
} catch {
|
|
16537
16581
|
return new Response("Not found", { status: 404 });
|
|
16538
16582
|
}
|
|
@@ -16542,7 +16586,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
16542
16586
|
return new Response("Not found", { status: 404 });
|
|
16543
16587
|
}
|
|
16544
16588
|
const filePath = resolve22(dir, dataFile);
|
|
16545
|
-
const buffer = await
|
|
16589
|
+
const buffer = await readFile5(filePath);
|
|
16546
16590
|
const inlineSafe = isInlineSafeMime(meta.mimeType);
|
|
16547
16591
|
const safeName = meta.filename.replace(/["\\\r\n]/g, "_");
|
|
16548
16592
|
if (!inlineSafe) {
|
|
@@ -16560,8 +16604,8 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
16560
16604
|
var attachment_default = app16;
|
|
16561
16605
|
|
|
16562
16606
|
// server/routes/admin/session-upload.ts
|
|
16563
|
-
import { readFile as
|
|
16564
|
-
import { existsSync as existsSync29, statSync as
|
|
16607
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
16608
|
+
import { existsSync as existsSync29, statSync as statSync14 } from "fs";
|
|
16565
16609
|
var app17 = new Hono();
|
|
16566
16610
|
app17.get("/", requireAdminSession, async (c) => {
|
|
16567
16611
|
const cacheKey = c.var.cacheKey;
|
|
@@ -16582,7 +16626,7 @@ app17.get("/", requireAdminSession, async (c) => {
|
|
|
16582
16626
|
return c.json({ error: "Not found" }, 404);
|
|
16583
16627
|
}
|
|
16584
16628
|
const resolution = resolveClaudeUploadsPath(`${sessionId}/${file}`);
|
|
16585
|
-
if (!resolution.ok || !existsSync29(resolution.absolute) || !
|
|
16629
|
+
if (!resolution.ok || !existsSync29(resolution.absolute) || !statSync14(resolution.absolute).isFile()) {
|
|
16586
16630
|
console.log(`[session-upload] op=miss session=${short2} file=${file} status=404 reason=absent`);
|
|
16587
16631
|
return c.json({ error: "Not found" }, 404);
|
|
16588
16632
|
}
|
|
@@ -16590,7 +16634,7 @@ app17.get("/", requireAdminSession, async (c) => {
|
|
|
16590
16634
|
const inlineSafe = isInlineSafeMime(mimeType);
|
|
16591
16635
|
const safeName = file.replace(/["\\\r\n]/g, "_");
|
|
16592
16636
|
console.log(`[session-upload] op=served session=${short2} file=${file} disposition=${inlineSafe ? "inline" : "attachment"} mime=${mimeType}`);
|
|
16593
|
-
const buffer = await
|
|
16637
|
+
const buffer = await readFile6(resolution.absolute);
|
|
16594
16638
|
return new Response(new Uint8Array(buffer), {
|
|
16595
16639
|
headers: {
|
|
16596
16640
|
"Content-Type": mimeType,
|
|
@@ -16606,33 +16650,8 @@ var session_upload_default = app17;
|
|
|
16606
16650
|
import { resolve as resolve23 } from "path";
|
|
16607
16651
|
import { readdirSync as readdirSync22, readFileSync as readFileSync33, existsSync as existsSync31, rmSync as rmSync2, renameSync as renameSync9, mkdirSync as mkdirSync7, writeFileSync as writeFileSync13 } from "fs";
|
|
16608
16652
|
|
|
16609
|
-
// server/routes/admin/_account-scope.ts
|
|
16610
|
-
function accountDirForSession(cacheKey) {
|
|
16611
|
-
const accountId = getAccountIdForSession(cacheKey);
|
|
16612
|
-
if (!accountId) return null;
|
|
16613
|
-
const match = listValidAccounts().find((a) => a.accountId === accountId);
|
|
16614
|
-
return match ? { accountId, accountDir: match.accountDir } : null;
|
|
16615
|
-
}
|
|
16616
|
-
function validateAccountId2(accountId) {
|
|
16617
|
-
if (!accountId) return null;
|
|
16618
|
-
const match = listValidAccounts().find((a) => a.accountId === accountId);
|
|
16619
|
-
return match ? { accountId, accountDir: match.accountDir } : null;
|
|
16620
|
-
}
|
|
16621
|
-
async function authorizeAccountWrite(c, accountId) {
|
|
16622
|
-
const remote = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
16623
|
-
const peerIsLoopback = remote === "127.0.0.1" || remote === "::1" || remote === "::ffff:127.0.0.1";
|
|
16624
|
-
if (peerIsLoopback && !c.req.header("x-forwarded-for")) return { ok: true, via: "on-device" };
|
|
16625
|
-
const { fingerprint, signedSessionToken } = await resolveCacheKey(c);
|
|
16626
|
-
if (!fingerprint || !validateSession(fingerprint, "admin", signedSessionToken).ok) {
|
|
16627
|
-
return { ok: false, reason: "no-session" };
|
|
16628
|
-
}
|
|
16629
|
-
const acct = accountDirForSession(fingerprint);
|
|
16630
|
-
if (!acct || acct.accountId !== accountId) return { ok: false, reason: "account-mismatch" };
|
|
16631
|
-
return { ok: true, via: "session" };
|
|
16632
|
-
}
|
|
16633
|
-
|
|
16634
16653
|
// ../services/claude-session-manager/src/tool-surface.ts
|
|
16635
|
-
import { readFileSync as readFileSync32, readdirSync as readdirSync21, statSync as
|
|
16654
|
+
import { readFileSync as readFileSync32, readdirSync as readdirSync21, statSync as statSync15, existsSync as existsSync30 } from "fs";
|
|
16636
16655
|
import { createHash as createHash5 } from "crypto";
|
|
16637
16656
|
import { join as join34 } from "path";
|
|
16638
16657
|
|
|
@@ -16889,7 +16908,7 @@ function loadToolSurface(pluginsRoots) {
|
|
|
16889
16908
|
const loadOne = (pluginsRoot, plugin) => {
|
|
16890
16909
|
const pluginDir = join34(pluginsRoot, plugin);
|
|
16891
16910
|
try {
|
|
16892
|
-
if (!
|
|
16911
|
+
if (!statSync15(pluginDir).isDirectory()) return;
|
|
16893
16912
|
} catch {
|
|
16894
16913
|
return;
|
|
16895
16914
|
}
|
|
@@ -16944,7 +16963,7 @@ function loadToolSurface(pluginsRoots) {
|
|
|
16944
16963
|
const subRoot = join34(pluginDir, "plugins");
|
|
16945
16964
|
let subEntries;
|
|
16946
16965
|
try {
|
|
16947
|
-
if (!
|
|
16966
|
+
if (!statSync15(subRoot).isDirectory()) continue;
|
|
16948
16967
|
subEntries = readdirSync21(subRoot).sort();
|
|
16949
16968
|
} catch {
|
|
16950
16969
|
continue;
|
|
@@ -18208,7 +18227,7 @@ app19.put("/:id/label", requireAdminSession, async (c) => {
|
|
|
18208
18227
|
var sessions_default = app19;
|
|
18209
18228
|
|
|
18210
18229
|
// app/lib/claude-agent/spawn-context.ts
|
|
18211
|
-
import { existsSync as existsSync33, readFileSync as readFileSync34, readdirSync as readdirSync23, statSync as
|
|
18230
|
+
import { existsSync as existsSync33, readFileSync as readFileSync34, readdirSync as readdirSync23, statSync as statSync16 } from "fs";
|
|
18212
18231
|
import { dirname as dirname12, resolve as resolve24, join as join35 } from "path";
|
|
18213
18232
|
async function resolveOwnerProfileBlock(accountId, userId) {
|
|
18214
18233
|
if (!userId) return { ok: false, reason: "missing-user-id" };
|
|
@@ -18311,7 +18330,7 @@ function listPluginDirs(accountPluginsDir) {
|
|
|
18311
18330
|
for (const name of readdirSync23(platformPlugins)) {
|
|
18312
18331
|
const dir = join35(platformPlugins, name);
|
|
18313
18332
|
try {
|
|
18314
|
-
if (
|
|
18333
|
+
if (statSync16(dir).isDirectory()) out.set(name, dir);
|
|
18315
18334
|
} catch {
|
|
18316
18335
|
}
|
|
18317
18336
|
}
|
|
@@ -18325,7 +18344,7 @@ function listPluginDirs(accountPluginsDir) {
|
|
|
18325
18344
|
for (const name of readdirSync23(bundlePlugins)) {
|
|
18326
18345
|
const dir = join35(bundlePlugins, name);
|
|
18327
18346
|
try {
|
|
18328
|
-
if (
|
|
18347
|
+
if (statSync16(dir).isDirectory()) out.set(name, dir);
|
|
18329
18348
|
} catch {
|
|
18330
18349
|
}
|
|
18331
18350
|
}
|
|
@@ -18339,7 +18358,7 @@ function listPluginDirs(accountPluginsDir) {
|
|
|
18339
18358
|
if (out.has(name)) continue;
|
|
18340
18359
|
const dir = join35(accountPluginsDir, name);
|
|
18341
18360
|
try {
|
|
18342
|
-
if (
|
|
18361
|
+
if (statSync16(dir).isDirectory()) out.set(name, dir);
|
|
18343
18362
|
} catch {
|
|
18344
18363
|
}
|
|
18345
18364
|
}
|
|
@@ -18356,7 +18375,7 @@ function listAccountPluginNames(accountPluginsDir) {
|
|
|
18356
18375
|
try {
|
|
18357
18376
|
return readdirSync23(accountPluginsDir).filter((name) => {
|
|
18358
18377
|
try {
|
|
18359
|
-
return
|
|
18378
|
+
return statSync16(join35(accountPluginsDir, name)).isDirectory();
|
|
18360
18379
|
} catch {
|
|
18361
18380
|
return false;
|
|
18362
18381
|
}
|
|
@@ -18866,7 +18885,7 @@ var events_default = app22;
|
|
|
18866
18885
|
|
|
18867
18886
|
// server/routes/admin/files.ts
|
|
18868
18887
|
import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync35 } from "fs";
|
|
18869
|
-
import { readdir as readdir4, readFile as
|
|
18888
|
+
import { readdir as readdir4, readFile as readFile8, stat as stat7, mkdir as mkdir4, unlink as unlink3, rename as rename2, rmdir } from "fs/promises";
|
|
18870
18889
|
import { realpathSync as realpathSync7 } from "fs";
|
|
18871
18890
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
18872
18891
|
import { basename as basename11, dirname as dirname13, join as join37, relative as relative5, resolve as resolve27, sep as sep8 } from "path";
|
|
@@ -19725,7 +19744,7 @@ var UPLOAD_TMP_DIR = ".uploads-tmp";
|
|
|
19725
19744
|
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
19726
19745
|
async function readMeta(absDir, baseName) {
|
|
19727
19746
|
try {
|
|
19728
|
-
const raw = await
|
|
19747
|
+
const raw = await readFile8(join37(absDir, `${baseName}.meta.json`), "utf8");
|
|
19729
19748
|
const parsed = JSON.parse(raw);
|
|
19730
19749
|
if (typeof parsed?.filename === "string") {
|
|
19731
19750
|
return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
|
|
@@ -19747,7 +19766,7 @@ async function readAccountNames() {
|
|
|
19747
19766
|
if (!UUID_RE4.test(name)) continue;
|
|
19748
19767
|
const configPath2 = resolve27(accountsDir, name, "account.json");
|
|
19749
19768
|
try {
|
|
19750
|
-
const raw = await
|
|
19769
|
+
const raw = await readFile8(configPath2, "utf8");
|
|
19751
19770
|
const parsed = JSON.parse(raw);
|
|
19752
19771
|
if (typeof parsed?.name === "string" && parsed.name.length > 0) {
|
|
19753
19772
|
map.set(name, parsed.name);
|
|
@@ -19789,7 +19808,7 @@ async function enrich(absolute, entry, accountNames) {
|
|
|
19789
19808
|
let size = null;
|
|
19790
19809
|
let modifiedAt = entry.modifiedAt;
|
|
19791
19810
|
try {
|
|
19792
|
-
const st = await
|
|
19811
|
+
const st = await stat7(join37(dirAbs, innerName));
|
|
19793
19812
|
size = st.size;
|
|
19794
19813
|
modifiedAt = st.mtime.toISOString();
|
|
19795
19814
|
} catch {
|
|
@@ -19964,7 +19983,7 @@ app23.get("/", requireAdminSession, async (c) => {
|
|
|
19964
19983
|
return c.json({ error: "Not found" }, 404);
|
|
19965
19984
|
}
|
|
19966
19985
|
try {
|
|
19967
|
-
const info = await
|
|
19986
|
+
const info = await stat7(absolute);
|
|
19968
19987
|
if (!info.isDirectory()) {
|
|
19969
19988
|
return c.json({ error: "Path is not a directory \u2014 use /api/admin/files/download for files" }, 400);
|
|
19970
19989
|
}
|
|
@@ -19983,7 +20002,7 @@ app23.get("/", requireAdminSession, async (c) => {
|
|
|
19983
20002
|
const protectedEntry = isProtectedFromDeletion(childRel).protected;
|
|
19984
20003
|
try {
|
|
19985
20004
|
const entryPath = join37(absolute, name);
|
|
19986
|
-
const s = await
|
|
20005
|
+
const s = await stat7(entryPath);
|
|
19987
20006
|
entries2.push({
|
|
19988
20007
|
name,
|
|
19989
20008
|
kind: s.isDirectory() ? "directory" : s.isFile() ? "file" : "other",
|
|
@@ -20011,7 +20030,7 @@ app23.get("/", requireAdminSession, async (c) => {
|
|
|
20011
20030
|
const displayPath = buildDisplayPath(relPath, accountNames);
|
|
20012
20031
|
if (groupReq || isAccountRoot(relPath)) {
|
|
20013
20032
|
const acctId = relPath.split("/")[1] ?? accountId;
|
|
20014
|
-
const schemaMd = await
|
|
20033
|
+
const schemaMd = await readFile8(join37(absolute, "SCHEMA.md"), "utf8").catch(() => null);
|
|
20015
20034
|
const groups = classifyAccountRoot(schemaMd, entries2.map((e) => e.name));
|
|
20016
20035
|
console.error(
|
|
20017
20036
|
`[data-schema] op=classify account=${acctId} status=${groups.parsed ? "ok" : "parse-failed"} reason=${groups.reason} entries=${entries2.length} home=${groups.home.join(",") || "none"} system=${groups.system.length} unknown=${groups.unknown.join(",") || "none"}`
|
|
@@ -20141,7 +20160,7 @@ app23.get("/download", requireAdminSession, async (c) => {
|
|
|
20141
20160
|
return c.json({ error: "Not found" }, 404);
|
|
20142
20161
|
}
|
|
20143
20162
|
try {
|
|
20144
|
-
const info = await
|
|
20163
|
+
const info = await stat7(absolute);
|
|
20145
20164
|
if (!info.isFile()) {
|
|
20146
20165
|
return c.json({ error: "Path is not a file" }, 400);
|
|
20147
20166
|
}
|
|
@@ -20238,7 +20257,7 @@ app23.get("/download-zip", requireAdminSession, async (c) => {
|
|
|
20238
20257
|
if (entries2.length >= maxFiles) return c.json({ error: `Too many files (max ${maxFiles})` }, 413);
|
|
20239
20258
|
total += size;
|
|
20240
20259
|
if (total > maxTotalBytes) return c.json({ error: "Selection too large to zip" }, 413);
|
|
20241
|
-
entries2.push({ name: member, data: await
|
|
20260
|
+
entries2.push({ name: member, data: await readFile8(absolute) });
|
|
20242
20261
|
return null;
|
|
20243
20262
|
};
|
|
20244
20263
|
for (const rawPath of rawPaths) {
|
|
@@ -20255,7 +20274,7 @@ app23.get("/download-zip", requireAdminSession, async (c) => {
|
|
|
20255
20274
|
return c.json({ error: "Not found" }, 404);
|
|
20256
20275
|
}
|
|
20257
20276
|
try {
|
|
20258
|
-
const info = await
|
|
20277
|
+
const info = await stat7(absolute);
|
|
20259
20278
|
if (info.isDirectory()) {
|
|
20260
20279
|
dirsWalked++;
|
|
20261
20280
|
const parentAbs = dirname13(absolute);
|
|
@@ -20263,7 +20282,7 @@ app23.get("/download-zip", requireAdminSession, async (c) => {
|
|
|
20263
20282
|
const within = relative5(absolute, fileAbs).split(sep8).join("/");
|
|
20264
20283
|
const fileRel = relPath === "" || relPath === "." ? within : `${relPath}/${within}`;
|
|
20265
20284
|
if (crossesForeignAccountPartition(fileRel, accountId)) continue;
|
|
20266
|
-
const fileInfo = await
|
|
20285
|
+
const fileInfo = await stat7(fileAbs);
|
|
20267
20286
|
const member = relative5(parentAbs, fileAbs).split(sep8).join("/");
|
|
20268
20287
|
const over = await addFile(fileAbs, fileInfo.size, member);
|
|
20269
20288
|
if (over) return over;
|
|
@@ -20334,7 +20353,7 @@ async function resolveUploadTarget(c, accountId, uid) {
|
|
|
20334
20353
|
const firstCreated = await mkdir4(destDir, { recursive: true });
|
|
20335
20354
|
if (firstCreated) console.error(`[data-upload] op=mkdir uid=${uid} token=${token} dir="${destRel}"`);
|
|
20336
20355
|
} else {
|
|
20337
|
-
const info = await
|
|
20356
|
+
const info = await stat7(destDir).catch(() => null);
|
|
20338
20357
|
if (!info || !info.isDirectory()) return { ok: false, status: 400, error: "Upload destination is not a directory" };
|
|
20339
20358
|
}
|
|
20340
20359
|
const dataRootReal = realpathSync7(DATA_ROOT);
|
|
@@ -20686,7 +20705,7 @@ app23.delete("/", requireAdminSession, async (c) => {
|
|
|
20686
20705
|
return c.json({ error: "Protected file \u2014 refusing to delete" }, 403);
|
|
20687
20706
|
}
|
|
20688
20707
|
try {
|
|
20689
|
-
const info = await
|
|
20708
|
+
const info = await stat7(absolute);
|
|
20690
20709
|
if (info.isDirectory()) {
|
|
20691
20710
|
return c.json({ error: "Directory deletion not supported" }, 400);
|
|
20692
20711
|
}
|
|
@@ -20763,7 +20782,7 @@ app23.post("/folder", requireAdminSession, async (c) => {
|
|
|
20763
20782
|
const newAbs = resolve27(parent.absolute, name);
|
|
20764
20783
|
const newRel = `${parent.relative}/${name}`;
|
|
20765
20784
|
try {
|
|
20766
|
-
const info = await
|
|
20785
|
+
const info = await stat7(parent.absolute);
|
|
20767
20786
|
if (!info.isDirectory()) return c.json({ error: "Parent is not a directory" }, 400);
|
|
20768
20787
|
await mkdir4(newAbs, { recursive: false });
|
|
20769
20788
|
} catch (err) {
|
|
@@ -20808,7 +20827,7 @@ app23.post("/rename", requireAdminSession, async (c) => {
|
|
|
20808
20827
|
try {
|
|
20809
20828
|
let collision = true;
|
|
20810
20829
|
try {
|
|
20811
|
-
await
|
|
20830
|
+
await stat7(destAbs);
|
|
20812
20831
|
} catch (e) {
|
|
20813
20832
|
if (e.code === "ENOENT") collision = false;
|
|
20814
20833
|
}
|
|
@@ -23086,7 +23105,7 @@ var WRITE_CYPHER = `
|
|
|
23086
23105
|
var graph_default_view_default = app29;
|
|
23087
23106
|
|
|
23088
23107
|
// server/routes/admin/sidebar-artefacts.ts
|
|
23089
|
-
import { readdir as readdir5, stat as
|
|
23108
|
+
import { readdir as readdir5, stat as stat8 } from "fs/promises";
|
|
23090
23109
|
import { resolve as resolve29, relative as relative6, isAbsolute as isAbsolute2, sep as sep9, basename as basename12 } from "path";
|
|
23091
23110
|
import { existsSync as existsSync36 } from "fs";
|
|
23092
23111
|
var LIMIT = 50;
|
|
@@ -23237,7 +23256,7 @@ async function readAgentTemplateRow(inp) {
|
|
|
23237
23256
|
}
|
|
23238
23257
|
if (!chosenPath) return null;
|
|
23239
23258
|
try {
|
|
23240
|
-
const st = await
|
|
23259
|
+
const st = await stat8(chosenPath);
|
|
23241
23260
|
const dlPath = toDataRootRelPath(chosenPath);
|
|
23242
23261
|
return {
|
|
23243
23262
|
id: inp.id,
|
|
@@ -23803,16 +23822,18 @@ app37.post("/", requireAdminSession, async (c) => {
|
|
|
23803
23822
|
return c.json(parsed ?? { error: text }, res.status);
|
|
23804
23823
|
}
|
|
23805
23824
|
try {
|
|
23806
|
-
const account =
|
|
23825
|
+
const account = cacheKey ? accountDirForSession(cacheKey) : null;
|
|
23807
23826
|
if (account && adminUserId) {
|
|
23808
|
-
const
|
|
23827
|
+
const platformAccountId = resolvePlatformAccountId();
|
|
23809
23828
|
const primaryUserId = resolvePrimaryAdminUserId();
|
|
23810
|
-
const canonicalId = adminSessionIdFor(
|
|
23829
|
+
const canonicalId = adminSessionIdFor(platformAccountId, WEBCHAT_ADMIN_KEY, adminUserId);
|
|
23811
23830
|
const currentOverride = readCanonicalOverrideId(account.accountDir, adminUserId, primaryUserId);
|
|
23812
23831
|
if (fromSessionId === canonicalId || fromSessionId === currentOverride) {
|
|
23813
23832
|
writeCanonicalOverrideId(account.accountDir, adminUserId, plan.sessionId);
|
|
23814
|
-
console.log(`[chat-reseat] op=canonical-forward reseatReqId=${reseatReqId} from=${fromSessionId} to=${plan.sessionId}`);
|
|
23833
|
+
console.log(`[chat-reseat] op=canonical-forward reseatReqId=${reseatReqId} accountId=${account.accountId.slice(0, 8)} from=${fromSessionId} to=${plan.sessionId}`);
|
|
23815
23834
|
}
|
|
23835
|
+
} else if (!account) {
|
|
23836
|
+
console.error(`[chat-reseat] op=canonical-forward-skipped reseatReqId=${reseatReqId} accountId=none reason=no-account-for-session`);
|
|
23816
23837
|
}
|
|
23817
23838
|
} catch (err) {
|
|
23818
23839
|
console.error(`[session-reseat] canonical-forward-failed err=${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -23849,7 +23870,7 @@ app37.post("/", requireAdminSession, async (c) => {
|
|
|
23849
23870
|
var session_reseat_default = app37;
|
|
23850
23871
|
|
|
23851
23872
|
// server/routes/admin/system-stats.ts
|
|
23852
|
-
import { readFile as
|
|
23873
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
23853
23874
|
import { cpus, loadavg, totalmem, freemem } from "os";
|
|
23854
23875
|
function parseCpuStat(blob) {
|
|
23855
23876
|
const line = blob.split("\n", 1)[0] ?? "";
|
|
@@ -23893,11 +23914,11 @@ function parseMeminfo(blob) {
|
|
|
23893
23914
|
}
|
|
23894
23915
|
var SAMPLE_DELAY_MS = 100;
|
|
23895
23916
|
async function sampleLinux() {
|
|
23896
|
-
const a = parseCpuStat(await
|
|
23917
|
+
const a = parseCpuStat(await readFile9("/proc/stat", "utf-8"));
|
|
23897
23918
|
await new Promise((r) => setTimeout(r, SAMPLE_DELAY_MS));
|
|
23898
|
-
const b = parseCpuStat(await
|
|
23899
|
-
const meminfo = parseMeminfo(await
|
|
23900
|
-
const loadavgRaw = (await
|
|
23919
|
+
const b = parseCpuStat(await readFile9("/proc/stat", "utf-8"));
|
|
23920
|
+
const meminfo = parseMeminfo(await readFile9("/proc/meminfo", "utf-8"));
|
|
23921
|
+
const loadavgRaw = (await readFile9("/proc/loadavg", "utf-8")).trim();
|
|
23901
23922
|
const [l1, l5, l15] = loadavgRaw.split(/\s+/, 3).map(Number);
|
|
23902
23923
|
if (![l1, l5, l15].every(Number.isFinite)) {
|
|
23903
23924
|
throw new Error(`malformed /proc/loadavg: ${loadavgRaw}`);
|
|
@@ -25229,25 +25250,26 @@ app47.delete("/meetings/:id", requireAdminSession, async (c) => {
|
|
|
25229
25250
|
}
|
|
25230
25251
|
});
|
|
25231
25252
|
app47.get("/booking-link", requireAdminSession, (c) => {
|
|
25253
|
+
const account = accountDirForSession(c.var.cacheKey);
|
|
25254
|
+
if (!account) {
|
|
25255
|
+
console.error("[calendar] op=booking-link auth-rejected reason=no-account-for-session accountId=none");
|
|
25256
|
+
return c.json({ error: "no account for session", reason: "no-account-for-session" }, 401);
|
|
25257
|
+
}
|
|
25258
|
+
const id82 = account.accountId.slice(0, 8);
|
|
25232
25259
|
try {
|
|
25233
|
-
const account = resolveAccount();
|
|
25234
|
-
if (!account) {
|
|
25235
|
-
console.error('[calendar] op=booking-link-fail err="no account configured"');
|
|
25236
|
-
return c.json({ bookingDomain: null });
|
|
25237
|
-
}
|
|
25238
25260
|
if (!existsSync38(join44(account.accountDir, AVAILABILITY_FILENAME))) {
|
|
25239
|
-
console.log(
|
|
25261
|
+
console.log(`[calendar] op=booking-link accountId=${id82} bookingDomain=none source=availability-config`);
|
|
25240
25262
|
return c.json({ bookingDomain: null });
|
|
25241
25263
|
}
|
|
25242
25264
|
const config = readAvailabilityConfig(account.accountDir);
|
|
25243
25265
|
const bookingDomain = typeof config.bookingDomain === "string" && config.bookingDomain.trim() ? config.bookingDomain.trim() : null;
|
|
25244
25266
|
console.log(
|
|
25245
|
-
`[calendar] op=booking-link bookingDomain=${bookingDomain ?? "none"} source=availability-config`
|
|
25267
|
+
`[calendar] op=booking-link accountId=${id82} bookingDomain=${bookingDomain ?? "none"} source=availability-config`
|
|
25246
25268
|
);
|
|
25247
25269
|
return c.json({ bookingDomain });
|
|
25248
25270
|
} catch (err) {
|
|
25249
25271
|
const message = err instanceof Error ? err.message : String(err);
|
|
25250
|
-
console.error(`[calendar] op=booking-link-fail err="${message}"`);
|
|
25272
|
+
console.error(`[calendar] op=booking-link-fail accountId=${id82} err="${message}"`);
|
|
25251
25273
|
return c.json({ bookingDomain: null });
|
|
25252
25274
|
}
|
|
25253
25275
|
});
|
|
@@ -26568,7 +26590,7 @@ app61.route("/request-magic-link", request_magic_link_default);
|
|
|
26568
26590
|
var access_default = app61;
|
|
26569
26591
|
|
|
26570
26592
|
// server/routes/sites.ts
|
|
26571
|
-
import { existsSync as existsSync41, readFileSync as readFileSync42, realpathSync as realpathSync8, statSync as
|
|
26593
|
+
import { existsSync as existsSync41, readFileSync as readFileSync42, realpathSync as realpathSync8, statSync as statSync18 } from "fs";
|
|
26572
26594
|
import { resolve as resolve36 } from "path";
|
|
26573
26595
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
26574
26596
|
var MIME = {
|
|
@@ -26632,13 +26654,13 @@ app62.get("/:rel{.*}", (c) => {
|
|
|
26632
26654
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
26633
26655
|
return c.text("Forbidden", 403);
|
|
26634
26656
|
}
|
|
26635
|
-
let
|
|
26657
|
+
let stat12;
|
|
26636
26658
|
try {
|
|
26637
|
-
|
|
26659
|
+
stat12 = existsSync41(filePath) ? statSync18(filePath) : null;
|
|
26638
26660
|
} catch {
|
|
26639
|
-
|
|
26661
|
+
stat12 = null;
|
|
26640
26662
|
}
|
|
26641
|
-
if (
|
|
26663
|
+
if (stat12?.isDirectory() && !reqPath.endsWith("/")) {
|
|
26642
26664
|
const search = new URL(c.req.url).search;
|
|
26643
26665
|
const target = `${reqPath}/${search}`;
|
|
26644
26666
|
console.log(
|
|
@@ -26646,7 +26668,7 @@ app62.get("/:rel{.*}", (c) => {
|
|
|
26646
26668
|
);
|
|
26647
26669
|
return c.redirect(target, 301);
|
|
26648
26670
|
}
|
|
26649
|
-
if (
|
|
26671
|
+
if (stat12?.isDirectory()) {
|
|
26650
26672
|
filePath = resolve36(filePath, "index.html");
|
|
26651
26673
|
}
|
|
26652
26674
|
if (!filePath.startsWith(rootDir + "/")) {
|
|
@@ -27637,7 +27659,7 @@ var calendar_public_default = app67;
|
|
|
27637
27659
|
|
|
27638
27660
|
// server/routes/portal-fetch.ts
|
|
27639
27661
|
import { createReadStream as createReadStream3 } from "fs";
|
|
27640
|
-
import { stat as
|
|
27662
|
+
import { stat as stat9, readFile as readFile10, realpath } from "fs/promises";
|
|
27641
27663
|
import { join as join46, resolve as resolve38, sep as sep10 } from "path";
|
|
27642
27664
|
import { Readable as Readable3 } from "stream";
|
|
27643
27665
|
var app68 = new Hono();
|
|
@@ -27694,7 +27716,7 @@ async function readAccountSecret(accountId) {
|
|
|
27694
27716
|
const path3 = resolve38(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
|
|
27695
27717
|
let text;
|
|
27696
27718
|
try {
|
|
27697
|
-
text = await
|
|
27719
|
+
text = await readFile10(path3, "utf8");
|
|
27698
27720
|
} catch {
|
|
27699
27721
|
console.error(`${TAG50} op=no-secret account="${accountId}" path="${path3}"`);
|
|
27700
27722
|
return "";
|
|
@@ -27711,7 +27733,7 @@ function isValidAccountId2(value) {
|
|
|
27711
27733
|
}
|
|
27712
27734
|
async function readExposeFolders2(accountDir) {
|
|
27713
27735
|
try {
|
|
27714
|
-
const cfg = JSON.parse(await
|
|
27736
|
+
const cfg = JSON.parse(await readFile10(join46(accountDir, "data-portal.json"), "utf8"));
|
|
27715
27737
|
return Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
|
|
27716
27738
|
} catch {
|
|
27717
27739
|
return [];
|
|
@@ -27720,7 +27742,7 @@ async function readExposeFolders2(accountDir) {
|
|
|
27720
27742
|
async function resolveFetchTarget(accountDir, relPath, ownerId) {
|
|
27721
27743
|
let schemaText = null;
|
|
27722
27744
|
try {
|
|
27723
|
-
schemaText = await
|
|
27745
|
+
schemaText = await readFile10(join46(accountDir, "SCHEMA.md"), "utf8");
|
|
27724
27746
|
} catch {
|
|
27725
27747
|
schemaText = null;
|
|
27726
27748
|
}
|
|
@@ -27746,7 +27768,7 @@ async function resolveFetchTarget(accountDir, relPath, ownerId) {
|
|
|
27746
27768
|
return { ok: false, reason: "not-exposed" };
|
|
27747
27769
|
}
|
|
27748
27770
|
try {
|
|
27749
|
-
const st = await
|
|
27771
|
+
const st = await stat9(absolute);
|
|
27750
27772
|
if (!st.isFile()) return { ok: false, reason: "enoent" };
|
|
27751
27773
|
return { ok: true, absolute, sizeBytes: st.size };
|
|
27752
27774
|
} catch {
|
|
@@ -27890,7 +27912,7 @@ function startTimeEntryCensus(openSession, opts = {}) {
|
|
|
27890
27912
|
}
|
|
27891
27913
|
|
|
27892
27914
|
// app/lib/ledger-census.ts
|
|
27893
|
-
import { readdirSync as readdirSync28, readFileSync as readFileSync45, statSync as
|
|
27915
|
+
import { readdirSync as readdirSync28, readFileSync as readFileSync45, statSync as statSync19 } from "fs";
|
|
27894
27916
|
import { join as join47 } from "path";
|
|
27895
27917
|
|
|
27896
27918
|
// ../lib/ledger-core/dist/reconcile.js
|
|
@@ -27947,7 +27969,7 @@ function countWriteRejects24h(logDir, now) {
|
|
|
27947
27969
|
for (const name of entries2) {
|
|
27948
27970
|
const path3 = join47(logDir, name);
|
|
27949
27971
|
try {
|
|
27950
|
-
if (now -
|
|
27972
|
+
if (now - statSync19(path3).mtimeMs > DAY_MS) continue;
|
|
27951
27973
|
for (const line of readFileSync45(path3, "utf8").split("\n")) {
|
|
27952
27974
|
if (line.includes("[graph-write] reject")) total += 1;
|
|
27953
27975
|
}
|
|
@@ -28442,7 +28464,7 @@ async function migrateUploads(opts = {}) {
|
|
|
28442
28464
|
}
|
|
28443
28465
|
|
|
28444
28466
|
// app/lib/migrate-admin-webchat-sidecars.ts
|
|
28445
|
-
import { readdir as readdir7, readFile as
|
|
28467
|
+
import { readdir as readdir7, readFile as readFile11, rename as rename4, writeFile as writeFile5, unlink as unlink4 } from "fs/promises";
|
|
28446
28468
|
import { existsSync as existsSync44 } from "fs";
|
|
28447
28469
|
import { join as join48 } from "path";
|
|
28448
28470
|
var ADMIN_ROLE2 = "admin";
|
|
@@ -28455,7 +28477,7 @@ var defaultResolveName = async (_accountId, userId) => {
|
|
|
28455
28477
|
async function readRaw3(path3) {
|
|
28456
28478
|
let raw;
|
|
28457
28479
|
try {
|
|
28458
|
-
raw = await
|
|
28480
|
+
raw = await readFile11(path3, "utf8");
|
|
28459
28481
|
} catch {
|
|
28460
28482
|
return null;
|
|
28461
28483
|
}
|
|
@@ -30819,7 +30841,7 @@ function buildTelegramSpawnRequest(input) {
|
|
|
30819
30841
|
|
|
30820
30842
|
// app/lib/telegram/outbound/send-document.ts
|
|
30821
30843
|
import { realpathSync as realpathSync10 } from "fs";
|
|
30822
|
-
import { readFile as
|
|
30844
|
+
import { readFile as readFile12, stat as stat11 } from "fs/promises";
|
|
30823
30845
|
import { resolve as resolve42, basename as basename13 } from "path";
|
|
30824
30846
|
var TAG56 = "[telegram:outbound]";
|
|
30825
30847
|
var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
|
|
@@ -30860,7 +30882,7 @@ async function sendTelegramDocument(input) {
|
|
|
30860
30882
|
console.error(`${TAG56} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
|
|
30861
30883
|
return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
|
|
30862
30884
|
}
|
|
30863
|
-
const fileStat = await
|
|
30885
|
+
const fileStat = await stat11(resolvedPath);
|
|
30864
30886
|
if (fileStat.size > TELEGRAM_DOCUMENT_MAX_BYTES) {
|
|
30865
30887
|
return {
|
|
30866
30888
|
ok: false,
|
|
@@ -30869,7 +30891,7 @@ async function sendTelegramDocument(input) {
|
|
|
30869
30891
|
};
|
|
30870
30892
|
}
|
|
30871
30893
|
const filename = basename13(resolvedPath);
|
|
30872
|
-
const buffer = Buffer.from(await
|
|
30894
|
+
const buffer = Buffer.from(await readFile12(resolvedPath));
|
|
30873
30895
|
const form = new FormData();
|
|
30874
30896
|
form.append("chat_id", String(chatId));
|
|
30875
30897
|
if (caption) form.append("caption", caption);
|
|
@@ -31268,7 +31290,7 @@ function broadcastAdminShutdown(reason) {
|
|
|
31268
31290
|
|
|
31269
31291
|
// ../lib/entitlement/src/index.ts
|
|
31270
31292
|
import { createPublicKey, createHash as createHash7, verify as cryptoVerify } from "crypto";
|
|
31271
|
-
import { existsSync as existsSync46, readFileSync as readFileSync47, statSync as
|
|
31293
|
+
import { existsSync as existsSync46, readFileSync as readFileSync47, statSync as statSync20 } from "fs";
|
|
31272
31294
|
import { resolve as resolve44 } from "path";
|
|
31273
31295
|
|
|
31274
31296
|
// ../lib/entitlement/src/canonicalize.ts
|
|
@@ -31320,8 +31342,8 @@ function resolveEntitlement(brand, account) {
|
|
|
31320
31342
|
if (!existsSync46(entitlementPath)) {
|
|
31321
31343
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
31322
31344
|
}
|
|
31323
|
-
const
|
|
31324
|
-
const key = memoKey(
|
|
31345
|
+
const stat12 = statSync20(entitlementPath);
|
|
31346
|
+
const key = memoKey(stat12.mtimeMs, account);
|
|
31325
31347
|
if (memo && memo.key === key) {
|
|
31326
31348
|
return memo.result;
|
|
31327
31349
|
}
|
|
@@ -32720,8 +32742,7 @@ if (brandFaviconPath !== "/favicon.ico") {
|
|
|
32720
32742
|
return c.redirect(brandFaviconPath, 302);
|
|
32721
32743
|
});
|
|
32722
32744
|
}
|
|
32723
|
-
app69
|
|
32724
|
-
app69.use("/*", serveStatic({ root: "./public" }));
|
|
32745
|
+
mountStaticFiles(app69, "./public");
|
|
32725
32746
|
app69.all("*", (c) => {
|
|
32726
32747
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
32727
32748
|
const path3 = c.req.path;
|
|
@@ -32843,7 +32864,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
32843
32864
|
if (!STRANDED_UUID_RE.test(name)) continue;
|
|
32844
32865
|
const pendingPath2 = resolve45(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
|
|
32845
32866
|
if (!existsSync47(pendingPath2)) continue;
|
|
32846
|
-
const ageMs2 = now -
|
|
32867
|
+
const ageMs2 = now - statSync21(pendingPath2).mtimeMs;
|
|
32847
32868
|
if (ageMs2 > STRANDED_AGE_MS) {
|
|
32848
32869
|
console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
|
|
32849
32870
|
}
|