@rubytech/create-siteoffice-code 0.1.259 → 0.1.264
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/config/brand.json +8 -8
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +14 -5
- package/payload/platform/plugins/docs/references/admin-ui.md +10 -3
- package/payload/platform/plugins/docs/references/deployment.md +1 -1
- package/payload/platform/plugins/docs/references/platform.md +2 -0
- package/payload/platform/scripts/check-no-esm-require.mjs +4 -0
- package/payload/platform/scripts/smoke-boot-services.sh +4 -4
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +47 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.d.ts +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/input-postcondition.d.ts +22 -0
- package/payload/platform/services/claude-session-manager/dist/input-postcondition.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/input-postcondition.js +50 -0
- package/payload/platform/services/claude-session-manager/dist/input-postcondition.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/install-log-sink.d.ts +2 -0
- package/payload/platform/services/claude-session-manager/dist/install-log-sink.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/install-log-sink.js +6 -0
- package/payload/platform/services/claude-session-manager/dist/install-log-sink.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/log-sink.d.ts +12 -0
- package/payload/platform/services/claude-session-manager/dist/log-sink.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/log-sink.js +48 -0
- package/payload/platform/services/claude-session-manager/dist/log-sink.js.map +1 -0
- package/payload/server/{chunk-76HRO7NX.js → chunk-ZC63DFWF.js} +12 -4
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/AdminShell-8JLQM1Mz.js +1 -0
- package/payload/server/public/assets/{Checkbox-DmDxpqVv.js → Checkbox-CuFJh7lI.js} +1 -1
- package/payload/server/public/assets/{admin-COUV-jgt.js → admin-D4nsdmKU.js} +1 -1
- package/payload/server/public/assets/{arc-B2CweJq3.js → arc-BW1WhwmV.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-xHbVjatf.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DP2o-MFV.js → architectureDiagram-Q4EWVU46-D-ODjJS5.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DO4mcYDJ.js → blockDiagram-DXYQGD6D-DFuVe8f9.js} +1 -1
- package/payload/server/public/assets/browser-DIKmvDl5.js +1 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Sy1giHbj.js → c4Diagram-AHTNJAMY-CeVLfznT.js} +1 -1
- package/payload/server/public/assets/channel-Db8J_1Rl.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-CKsCYCsN.js → chunk-2KRD3SAO-CKn-bEkI.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-C0-P-aUF.js → chunk-336JU56O-BTaLfR3a.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-BzTbm4pP.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-B8bqAmBa.js → chunk-4BX2VUAB-B2mSmC97.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-D1k0VSlW.js → chunk-4TB4RGXK-SiUyOXVG.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-B-p_QNqz.js → chunk-55IACEB6-JLT9m7Hd.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-D6U6tV_j.js → chunk-5FUZZQ4R-BcQ33LnT.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CYK76xfs.js → chunk-5PVQY5BW-CT7C1Tik.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-BC9js-lf.js → chunk-67CJDMHE-CCdP3Pdx.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-4j2OqKkv.js → chunk-7N4EOEYR-bXgVzdM9.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-Coen-fXN.js → chunk-AA7GKIK3-CYeDvY8B.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-CAiOBvec.js → chunk-BSJP7CBP-U0Fi-Ers.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-AJzzpZVb.js → chunk-CIAEETIT-C8QrV6Gg.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-BL4BKozX.js → chunk-EDXVE4YY-CK3uI2u6.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-mhAFG8UD.js → chunk-ENJZ2VHE-Ddp8Otnw.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-H231gZA_.js → chunk-FMBD7UC4-DxAQS3UB.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-Cl3ZZjYG.js → chunk-FOC6F5B3-CyIK3zeY.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DOEzvzJa.js → chunk-ICPOFSXX-DHTxymk_.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-C_ipbUDD.js → chunk-K5T4RW27-7GcDzjyJ.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-CTsDNSCU.js → chunk-KGLVRYIC-B7pAr9hf.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-DvSXhkGf.js → chunk-LIHQZDEY-DEoU2jrz.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-p574NOI7.js → chunk-ORNJ4GCN-BwMFuN24.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-BlEgFM6U.js → chunk-OYMX7WX6-Heg3hegz.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-CHE_iZO7.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-B2bDK0jv.js → chunk-U2HBQHQK-Cw2PR7aJ.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-D69BxKFw.js → chunk-X2U36JSP-C7vBCAQQ.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-Dm-PcyUi.js → chunk-XPW4576I-BA0a8Ygs.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-Be8RnXgx.js → chunk-YZCP3GAM-BS8Mybh1.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-Ck8PCTa4.js → chunk-ZZ45TVLE-DmnbQp47.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DjquNGFr.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CcE8sWEP.js +1 -0
- package/payload/server/public/assets/clone-xa7JZYoY.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-CmkW2Eaj.js → cose-bilkent-S5V4N54A-Df_JmB8E.js} +1 -1
- package/payload/server/public/assets/{dagre-Dqp-ns8F.js → dagre-D4i6r8zi.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-ZgWWXPLc.js → dagre-KV5264BT-znWS6Wh2.js} +1 -1
- package/payload/server/public/assets/{data-gy6QH9c1.js → data-CHqF4bkS.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-CTX5-ScM.js → diagram-5BDNPKRD-B6tQBN1Y.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BovIsO6H.js → diagram-G4DWMVQ6-t73WpYIY.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-DcETsQy-.js → diagram-MMDJMWI5-Cm63UOJm.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-yyq6peoZ.js → diagram-TYMM5635-DuTSLjVB.js} +1 -1
- package/payload/server/public/assets/{dist-DB-VPj_8.js → dist-BmvZ8OaX.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-CiNToftB.js → erDiagram-SMLLAGMA-sbHunitX.js} +1 -1
- package/payload/server/public/assets/{flatten-BtFI066E.js → flatten-Bo6YRmWl.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-Xnl3SpIM.js → flowDiagram-DWJPFMVM-BWOrPuqz.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-C1iyWe0f.js → ganttDiagram-T4ZO3ILL-WaLMGard.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-CmHdoS27.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-D97pbMQb.js → gitGraphDiagram-UUTBAWPF-CsbIgKDn.js} +1 -1
- package/payload/server/public/assets/{graph-qz5tFKqU.js → graph-kwyPyf_b.js} +2 -2
- package/payload/server/public/assets/{graph-labels-cZu4pK16.js → graph-labels-pX3uIQys.js} +1 -1
- package/payload/server/public/assets/{graphlib-Lq8ijgON.js → graphlib-B8yKFZvc.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-DTA9msO-.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-Bd55TzsD.js +2 -0
- package/payload/server/public/assets/{isEmpty-D6QovjYR.js → isEmpty-D6Kr-M1M.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-B8XBdjJn.js → ishikawaDiagram-UXIWVN3A-BFdOsA9f.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CZYbiOaQ.js → journeyDiagram-VCZTEJTY-CMQ5XWO9.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-B1PybFoh.js → kanban-definition-6JOO6SKY-_RpNNRN7.js} +1 -1
- package/payload/server/public/assets/{line-D-tw3hHp.js → line-SkFxjGJ8.js} +1 -1
- package/payload/server/public/assets/{linear-BHhXD3cd.js → linear-COm19-p7.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-C9RAnysF.js → mermaid-parser.core-Ddok2IAe.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-B532LT1r.js → mermaid.core-CihAjXBG.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DGlgeeTV.js → mindmap-definition-QFDTVHPH-CJsq3hrO.js} +1 -1
- package/payload/server/public/assets/{ordinal-Bl-aM5b9.js → ordinal-BDi6f4xk.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-6GjqIKgu.js +1 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-T72DJ5JR.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-DV9FIWko.js → pieDiagram-DEJITSTG-CSgg8lBB.js} +1 -1
- package/payload/server/public/assets/{public-Bu2_Xi0a.js → public-BA9P-3ZV.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-Betwya4l.js → quadrantDiagram-34T5L4WZ-TtHxMQtS.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-x-6xW1dE.js +1 -0
- package/payload/server/public/assets/{reduce-BD4xUd2c.js → reduce-CGi9ik8i.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-Cq3vODdg.js → requirementDiagram-MS252O5E-DdYupKtL.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-x8krXWcS.js → sankeyDiagram-XADWPNL6-BVfdyUnO.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-i-_uH-Yl.js → sequenceDiagram-FGHM5R23-aFLOua6n.js} +1 -1
- package/payload/server/public/assets/{src-C1jfwBq0.js → src-DLEIsjER.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-il4KqSgI.js → stateDiagram-FHFEXIEX-_3Ix8SPZ.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-eVQQEyxx.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DATdZkA5.js → timeline-definition-GMOUNBTQ-Bs96WqZ7.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-5-6wEryJ.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-DF48Cc86.js +1 -0
- package/payload/server/public/assets/{useSelectionMode-A5KItZ2T.js → useSelectionMode-Da9Glxvu.js} +1 -1
- package/payload/server/public/assets/{useSelectionMode-C-Ojh7W9.css → useSelectionMode-L9uAHstA.css} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BJh9tJTt.js → vennDiagram-DHZGUBPP-DE_SxsN2.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-duKIa6Hq.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-EMN1Hdfg.js → wardleyDiagram-NUSXRM2D-DTCdKs6v.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DbUWXa7T.js → xychartDiagram-5P7HB3ND-CNIrxADs.js} +1 -1
- package/payload/server/public/brand/maxy-black.png +0 -0
- package/payload/server/public/brand/maxy-monochrome.png +0 -0
- package/payload/server/public/brand/maxy.png +0 -0
- package/payload/server/public/brand/siteoffice-black.png +0 -0
- package/payload/server/public/brand/siteoffice-favicon-180.png +0 -0
- package/payload/server/public/brand/siteoffice-favicon-32.png +0 -0
- package/payload/server/public/brand/siteoffice-favicon-512.png +0 -0
- package/payload/server/public/brand/siteoffice-horizontal-dark.png +0 -0
- package/payload/server/public/brand/siteoffice-horizontal.png +0 -0
- package/payload/server/public/brand/siteoffice-icon.svg +8 -0
- package/payload/server/public/brand/siteoffice-monochrome.png +0 -0
- package/payload/server/public/brand/siteoffice-square.png +0 -0
- package/payload/server/public/brand/siteoffice-stacked.png +0 -0
- package/payload/server/public/brand/siteoffice-white.png +0 -0
- package/payload/server/public/brand-constants.json +2 -2
- package/payload/server/public/brand-defaults.css +4 -4
- package/payload/server/public/browser.html +18 -0
- package/payload/server/public/data.html +6 -6
- package/payload/server/public/graph.html +7 -7
- package/payload/server/public/index.html +6 -6
- package/payload/server/public/public.html +5 -5
- package/payload/server/server-init-line-stamper.cjs +26 -0
- package/payload/server/server-init.cjs +26 -12
- package/payload/server/server.js +343 -252
- package/payload/server/public/assets/AdminShell-T-YknnBn.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-Dnn6Hc65.js +0 -1
- package/payload/server/public/assets/channel-CEpR_0rE.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-DFjEt3Zb.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-DpF06ZZQ.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CYbXvKLI.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DEyHzRhq.js +0 -1
- package/payload/server/public/assets/clone-y8gexbBy.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-CNs-LD5i.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-DsTNigSS.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-C_OarRTA.js +0 -2
- package/payload/server/public/assets/packet-4T2RLAQJ-DGES22b-.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-ChKeDbzt.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-FGG5Fs7N.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B6zNJ6Tv.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-VAQQdbtf.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-DKchO3zI.js +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-CBGtx0bS.js +0 -1
- package/payload/server/public/brand/favicon.ico +0 -0
- package/payload/server/public/brand/maxy-horizontal.png +0 -0
- package/payload/server/public/brand/maxy-square.png +0 -0
- /package/payload/server/public/assets/{_baseFor-Cs8Y-rGh.js → _baseFor-Cam2PbSt.js} +0 -0
- /package/payload/server/public/assets/{array-iHZP4KWJ.js → array-DYRGGQae.js} +0 -0
- /package/payload/server/public/assets/{chunk-DD-I1_y5.js → chunk-CnGqDkHZ.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-BR2GOQ8_.js → cytoscape.esm-nWsJMTNI.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-B9aLeOTg.js → defaultLocale-Du1XY3Dp.js} +0 -0
- /package/payload/server/public/assets/{init-BNFRgqHM.js → init-B5BXBRcm.js} +0 -0
- /package/payload/server/public/assets/{katex-B-EfS3nw.js → katex-HOUACuRw.js} +0 -0
- /package/payload/server/public/assets/{path-DmWWdwp7.js → path-CNO468J-.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-Ci7Kjt46.js → rough.esm-DRO6hWPh.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -93,7 +93,7 @@ import {
|
|
|
93
93
|
vncLog,
|
|
94
94
|
walkPremiumBundles,
|
|
95
95
|
writeAdminUserAndPerson
|
|
96
|
-
} from "./chunk-
|
|
96
|
+
} from "./chunk-ZC63DFWF.js";
|
|
97
97
|
import {
|
|
98
98
|
__commonJS,
|
|
99
99
|
__require,
|
|
@@ -9268,11 +9268,34 @@ async function managerDelete(sessionId) {
|
|
|
9268
9268
|
await fetch(`${managerBase()}/${sessionId}`, { method: "DELETE" }).catch(() => {
|
|
9269
9269
|
});
|
|
9270
9270
|
}
|
|
9271
|
+
async function managerLogDownload(sessionId) {
|
|
9272
|
+
const res = await fetch(`${managerBase()}/${sessionId}/log?download=1`).catch(() => null);
|
|
9273
|
+
if (!res || !res.ok) return null;
|
|
9274
|
+
return res.text().catch(() => null);
|
|
9275
|
+
}
|
|
9271
9276
|
function managerLogFollowUrl(sessionId, opts) {
|
|
9272
9277
|
const base = `${managerBase()}/${sessionId}/log?follow=1`;
|
|
9273
9278
|
return opts?.boundary ? `${base}&boundary=1` : base;
|
|
9274
9279
|
}
|
|
9275
9280
|
|
|
9281
|
+
// app/lib/channel-pty-bridge/timeout-classify.ts
|
|
9282
|
+
function classifyTimeout(ndjson, writeAtMs) {
|
|
9283
|
+
for (const line of ndjson.split("\n")) {
|
|
9284
|
+
if (!line) continue;
|
|
9285
|
+
let rec;
|
|
9286
|
+
try {
|
|
9287
|
+
rec = JSON.parse(line);
|
|
9288
|
+
} catch {
|
|
9289
|
+
continue;
|
|
9290
|
+
}
|
|
9291
|
+
if (rec.type !== "assistant") continue;
|
|
9292
|
+
if (rec.message?.stop_reason !== "end_turn") continue;
|
|
9293
|
+
const ts = rec.timestamp ? Date.parse(rec.timestamp) : NaN;
|
|
9294
|
+
if (Number.isFinite(ts) && ts > writeAtMs) return "relay-missed";
|
|
9295
|
+
}
|
|
9296
|
+
return "no-turn";
|
|
9297
|
+
}
|
|
9298
|
+
|
|
9276
9299
|
// app/lib/channel-pty-bridge/admin-session-id.ts
|
|
9277
9300
|
import { createHash } from "crypto";
|
|
9278
9301
|
function adminSessionIdFor(accountId, senderId) {
|
|
@@ -9970,6 +9993,7 @@ async function dispatchOnce(input) {
|
|
|
9970
9993
|
resolve27(text);
|
|
9971
9994
|
};
|
|
9972
9995
|
entry.subscribers.add(listener);
|
|
9996
|
+
const writeAtMs = Date.now();
|
|
9973
9997
|
const writeOk = await writeInput(entry, input.text);
|
|
9974
9998
|
if (!writeOk) {
|
|
9975
9999
|
entry.subscribers.delete(listener);
|
|
@@ -9991,6 +10015,14 @@ async function dispatchOnce(input) {
|
|
|
9991
10015
|
return { turnText };
|
|
9992
10016
|
} catch (err) {
|
|
9993
10017
|
const message = err instanceof Error ? err.message : String(err);
|
|
10018
|
+
if (message === "timeout") {
|
|
10019
|
+
const ndjson = await managerLogDownload(entry.sessionId) ?? "";
|
|
10020
|
+
const cause = classifyTimeout(ndjson, writeAtMs);
|
|
10021
|
+
console.error(
|
|
10022
|
+
`${tag} op=turn-timeout cause=${cause} senderId=${input.senderId} sessionId=${entry.sessionId.slice(0, 8)}`
|
|
10023
|
+
);
|
|
10024
|
+
return { error: "timeout", cause };
|
|
10025
|
+
}
|
|
9994
10026
|
console.error(
|
|
9995
10027
|
`${tag} reject reason=turn-${message} senderId=${input.senderId} sessionId=${entry.sessionId.slice(0, 8)}`
|
|
9996
10028
|
);
|
|
@@ -10060,6 +10092,21 @@ function handlePublicSessionExit(sessionId) {
|
|
|
10060
10092
|
});
|
|
10061
10093
|
}
|
|
10062
10094
|
|
|
10095
|
+
// app/lib/channel-pty-bridge/inbound-outcome.ts
|
|
10096
|
+
var TAG17 = "[whatsapp-adaptor]";
|
|
10097
|
+
var tallies = /* @__PURE__ */ new Map();
|
|
10098
|
+
function recordInboundOutcome(senderId, outcome) {
|
|
10099
|
+
let t = tallies.get(senderId);
|
|
10100
|
+
if (!t) {
|
|
10101
|
+
t = { "relay-ok": 0, "timeout-no-turn": 0, "timeout-relay-missed": 0 };
|
|
10102
|
+
tallies.set(senderId, t);
|
|
10103
|
+
}
|
|
10104
|
+
t[outcome] += 1;
|
|
10105
|
+
console.error(
|
|
10106
|
+
`${TAG17} op=inbound-outcome sender=${senderId} relay-ok=${t["relay-ok"]} timeout-no-turn=${t["timeout-no-turn"]} timeout-relay-missed=${t["timeout-relay-missed"]}`
|
|
10107
|
+
);
|
|
10108
|
+
}
|
|
10109
|
+
|
|
10063
10110
|
// app/lib/access-session-store.ts
|
|
10064
10111
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
10065
10112
|
var sessions = /* @__PURE__ */ new Map();
|
|
@@ -10332,12 +10379,12 @@ import { readdirSync as readdirSync2, readFileSync as readFileSync6, existsSync
|
|
|
10332
10379
|
// app/lib/whatsapp/login.ts
|
|
10333
10380
|
var import_qrcode = __toESM(require_lib(), 1);
|
|
10334
10381
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
10335
|
-
var
|
|
10382
|
+
var TAG18 = "[whatsapp:login]";
|
|
10336
10383
|
async function renderQrTerminal(qr) {
|
|
10337
10384
|
try {
|
|
10338
10385
|
return await import_qrcode.default.toString(qr, { type: "utf8" });
|
|
10339
10386
|
} catch (err) {
|
|
10340
|
-
console.error(`${
|
|
10387
|
+
console.error(`${TAG18} terminal QR render failed: ${String(err)}`);
|
|
10341
10388
|
return void 0;
|
|
10342
10389
|
}
|
|
10343
10390
|
}
|
|
@@ -10347,7 +10394,7 @@ function closeSocket(sock) {
|
|
|
10347
10394
|
try {
|
|
10348
10395
|
sock.ws?.close?.();
|
|
10349
10396
|
} catch (err) {
|
|
10350
|
-
console.warn(`${
|
|
10397
|
+
console.warn(`${TAG18} socket close error during cleanup: ${String(err)}`);
|
|
10351
10398
|
}
|
|
10352
10399
|
}
|
|
10353
10400
|
function resetActiveLogin(accountId) {
|
|
@@ -10370,7 +10417,7 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
10370
10417
|
const current = activeLogins.get(accountId);
|
|
10371
10418
|
if (current?.id === login.id) {
|
|
10372
10419
|
current.connected = true;
|
|
10373
|
-
console.error(`${
|
|
10420
|
+
console.error(`${TAG18} loginConnectionLoop: connected account=${accountId} attempt=${attempt}`);
|
|
10374
10421
|
}
|
|
10375
10422
|
return;
|
|
10376
10423
|
} catch (err) {
|
|
@@ -10380,7 +10427,7 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
10380
10427
|
if (!classification.shouldRetry || attempt >= LOGIN_MAX_RECONNECTS) {
|
|
10381
10428
|
if (attempt >= LOGIN_MAX_RECONNECTS) {
|
|
10382
10429
|
console.error(
|
|
10383
|
-
`${
|
|
10430
|
+
`${TAG18} login reconnect attempts exhausted (${attempt}/${LOGIN_MAX_RECONNECTS}) \u2014 surfacing error to agent`
|
|
10384
10431
|
);
|
|
10385
10432
|
current.error = `Login failed after ${attempt} reconnect attempts: ${formatError(err)}`;
|
|
10386
10433
|
} else {
|
|
@@ -10392,7 +10439,7 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
10392
10439
|
attempt++;
|
|
10393
10440
|
const delay = LOGIN_RECONNECT_DELAYS[attempt - 1] ?? 8e3;
|
|
10394
10441
|
console.error(
|
|
10395
|
-
`${
|
|
10442
|
+
`${TAG18} status=${classification.statusCode ?? "unknown"} restart required \u2014 reconnecting with saved creds (attempt ${attempt}/${LOGIN_MAX_RECONNECTS}) delay=${delay}ms`
|
|
10396
10443
|
);
|
|
10397
10444
|
closeSocket(current.sock);
|
|
10398
10445
|
await new Promise((r) => setTimeout(r, delay));
|
|
@@ -10403,7 +10450,7 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
10403
10450
|
current.sock = newSock;
|
|
10404
10451
|
} catch (sockErr) {
|
|
10405
10452
|
console.error(
|
|
10406
|
-
`${
|
|
10453
|
+
`${TAG18} reconnect socket creation failed (attempt ${attempt}/${LOGIN_MAX_RECONNECTS}): ${String(sockErr)}`
|
|
10407
10454
|
);
|
|
10408
10455
|
current.error = `Reconnection failed: ${String(sockErr)}`;
|
|
10409
10456
|
return;
|
|
@@ -10417,7 +10464,7 @@ async function startLogin(opts) {
|
|
|
10417
10464
|
const hasAuth = await authExists(authDir);
|
|
10418
10465
|
const selfId = readSelfId(authDir);
|
|
10419
10466
|
console.error(
|
|
10420
|
-
`${
|
|
10467
|
+
`${TAG18} startLogin account=${accountId} force=${!!force} hasAuth=${hasAuth}` + (existing0 ? ` activeLogin={id=${existing0.id.slice(0, 8)},age=${Math.round((Date.now() - existing0.startedAt) / 1e3)}s,hasQr=${!!existing0.qr}}` : " activeLogin=none")
|
|
10421
10468
|
);
|
|
10422
10469
|
if (hasAuth && !force) {
|
|
10423
10470
|
const who = selfId.e164 ?? selfId.jid ?? "unknown";
|
|
@@ -10429,7 +10476,7 @@ async function startLogin(opts) {
|
|
|
10429
10476
|
await clearAuth(authDir);
|
|
10430
10477
|
const existing = activeLogins.get(accountId);
|
|
10431
10478
|
if (existing && isLoginFresh(existing) && existing.qrDataUrl && !force) {
|
|
10432
|
-
console.error(`${
|
|
10479
|
+
console.error(`${TAG18} startLogin account=${accountId} guard: returning existing QR (age=${Math.round((Date.now() - existing.startedAt) / 1e3)}s)`);
|
|
10433
10480
|
return {
|
|
10434
10481
|
qrDataUrl: existing.qrDataUrl,
|
|
10435
10482
|
qrRaw: existing.qr,
|
|
@@ -10438,7 +10485,7 @@ async function startLogin(opts) {
|
|
|
10438
10485
|
};
|
|
10439
10486
|
}
|
|
10440
10487
|
if (existing) {
|
|
10441
|
-
console.error(`${
|
|
10488
|
+
console.error(`${TAG18} startLogin account=${accountId} ${force ? "force override" : "stale/no-QR"}, resetting active login`);
|
|
10442
10489
|
}
|
|
10443
10490
|
resetActiveLogin(accountId);
|
|
10444
10491
|
let resolveQr = null;
|
|
@@ -10460,14 +10507,14 @@ async function startLogin(opts) {
|
|
|
10460
10507
|
onQr: (qr2) => {
|
|
10461
10508
|
loginQrCount++;
|
|
10462
10509
|
if (pendingQr) {
|
|
10463
|
-
console.error(`${
|
|
10510
|
+
console.error(`${TAG18} QR rotation #${loginQrCount} received for account=${accountId} \u2014 not forwarded (initial QR already captured)`);
|
|
10464
10511
|
return;
|
|
10465
10512
|
}
|
|
10466
10513
|
pendingQr = qr2;
|
|
10467
10514
|
const current = activeLogins.get(accountId);
|
|
10468
10515
|
if (current && !current.qr) current.qr = qr2;
|
|
10469
10516
|
clearTimeout(qrTimer);
|
|
10470
|
-
console.error(`${
|
|
10517
|
+
console.error(`${TAG18} QR #${loginQrCount} received for account=${accountId} \u2014 forwarding to caller`);
|
|
10471
10518
|
resolveQr?.(qr2);
|
|
10472
10519
|
}
|
|
10473
10520
|
});
|
|
@@ -10487,7 +10534,7 @@ async function startLogin(opts) {
|
|
|
10487
10534
|
activeLogins.set(accountId, login);
|
|
10488
10535
|
if (pendingQr && !login.qr) login.qr = pendingQr;
|
|
10489
10536
|
loginConnectionLoop(accountId, login).catch((err) => {
|
|
10490
|
-
console.error(`${
|
|
10537
|
+
console.error(`${TAG18} loginConnectionLoop unexpected error: ${String(err)}`);
|
|
10491
10538
|
const current = activeLogins.get(accountId);
|
|
10492
10539
|
if (current?.id === login.id) {
|
|
10493
10540
|
current.error = `Unexpected login error: ${String(err)}`;
|
|
@@ -10513,7 +10560,7 @@ async function waitForLogin(opts) {
|
|
|
10513
10560
|
const { accountId, timeoutMs = 6e4 } = opts;
|
|
10514
10561
|
const login = activeLogins.get(accountId);
|
|
10515
10562
|
console.error(
|
|
10516
|
-
`${
|
|
10563
|
+
`${TAG18} waitForLogin account=${accountId} timeout=${timeoutMs}ms` + (login ? ` login={id=${login.id.slice(0, 8)},age=${Math.round((Date.now() - login.startedAt) / 1e3)}s,connected=${login.connected},hasQr=${!!login.qr}}` : " login=none")
|
|
10517
10564
|
);
|
|
10518
10565
|
if (!login) {
|
|
10519
10566
|
return { connected: false, message: "No active WhatsApp login in progress." };
|
|
@@ -10526,7 +10573,7 @@ async function waitForLogin(opts) {
|
|
|
10526
10573
|
while (Date.now() < deadline) {
|
|
10527
10574
|
if (login.connected) {
|
|
10528
10575
|
const selfId = readSelfId(login.authDir);
|
|
10529
|
-
console.error(`${
|
|
10576
|
+
console.error(`${TAG18} login complete for account=${accountId} phone=${selfId.e164 ?? "unknown"}`);
|
|
10530
10577
|
const sock = login.sock;
|
|
10531
10578
|
const authDir = login.authDir;
|
|
10532
10579
|
activeLogins.delete(accountId);
|
|
@@ -10546,7 +10593,7 @@ async function waitForLogin(opts) {
|
|
|
10546
10593
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
10547
10594
|
}
|
|
10548
10595
|
const elapsed = Math.round((Date.now() - (deadline - timeoutMs)) / 1e3);
|
|
10549
|
-
console.error(`${
|
|
10596
|
+
console.error(`${TAG18} waitForLogin timeout account=${accountId} elapsed=${elapsed}s \u2014 cleaning up active login`);
|
|
10550
10597
|
resetActiveLogin(accountId);
|
|
10551
10598
|
return { connected: false, message: "Login timed out. Try generating a new QR." };
|
|
10552
10599
|
}
|
|
@@ -10554,7 +10601,7 @@ async function waitForLogin(opts) {
|
|
|
10554
10601
|
// app/lib/whatsapp/config-persist.ts
|
|
10555
10602
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync3 } from "fs";
|
|
10556
10603
|
import { resolve as resolve6, join as join4 } from "path";
|
|
10557
|
-
var
|
|
10604
|
+
var TAG19 = "[whatsapp:config]";
|
|
10558
10605
|
function configPath(accountDir) {
|
|
10559
10606
|
return resolve6(accountDir, "account.json");
|
|
10560
10607
|
}
|
|
@@ -10571,9 +10618,9 @@ function reloadManagerConfig(accountDir) {
|
|
|
10571
10618
|
try {
|
|
10572
10619
|
const config = readConfig(accountDir);
|
|
10573
10620
|
reloadConfig(config);
|
|
10574
|
-
console.error(`${
|
|
10621
|
+
console.error(`${TAG19} reloaded manager config`);
|
|
10575
10622
|
} catch (err) {
|
|
10576
|
-
console.error(`${
|
|
10623
|
+
console.error(`${TAG19} manager config reload failed: ${String(err)}`);
|
|
10577
10624
|
}
|
|
10578
10625
|
}
|
|
10579
10626
|
var E164_PATTERN = /^\+\d{7,15}$/;
|
|
@@ -10599,25 +10646,25 @@ function persistAfterPairing(accountDir, accountId, selfPhone) {
|
|
|
10599
10646
|
const adminPhones = wa.adminPhones;
|
|
10600
10647
|
if (!adminPhones.includes(normalized)) {
|
|
10601
10648
|
adminPhones.push(normalized);
|
|
10602
|
-
console.error(`${
|
|
10649
|
+
console.error(`${TAG19} added selfPhone=${normalized} to adminPhones`);
|
|
10603
10650
|
}
|
|
10604
10651
|
} else {
|
|
10605
|
-
console.error(`${
|
|
10652
|
+
console.error(`${TAG19} skipping adminPhones \u2014 selfPhone is null account=${accountId}`);
|
|
10606
10653
|
}
|
|
10607
10654
|
const parsed = WhatsAppConfigSchema.safeParse(wa);
|
|
10608
10655
|
if (!parsed.success) {
|
|
10609
10656
|
const msg = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
10610
|
-
console.error(`${
|
|
10657
|
+
console.error(`${TAG19} validation failed after pairing: ${msg}`);
|
|
10611
10658
|
return { ok: false, error: `Validation failed: ${msg}` };
|
|
10612
10659
|
}
|
|
10613
10660
|
config.whatsapp = parsed.data;
|
|
10614
10661
|
writeConfig(accountDir, config);
|
|
10615
|
-
console.error(`${
|
|
10662
|
+
console.error(`${TAG19} persisted after pairing account=${accountId} phone=${selfPhone ?? "null"}`);
|
|
10616
10663
|
reloadManagerConfig(accountDir);
|
|
10617
10664
|
return { ok: true };
|
|
10618
10665
|
} catch (err) {
|
|
10619
10666
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10620
|
-
console.error(`${
|
|
10667
|
+
console.error(`${TAG19} persist failed account=${accountId}: ${msg}`);
|
|
10621
10668
|
return { ok: false, error: msg };
|
|
10622
10669
|
}
|
|
10623
10670
|
}
|
|
@@ -10647,12 +10694,12 @@ function addAdminPhone(accountDir, phone) {
|
|
|
10647
10694
|
}
|
|
10648
10695
|
config.whatsapp = parsed.data;
|
|
10649
10696
|
writeConfig(accountDir, config);
|
|
10650
|
-
console.error(`${
|
|
10697
|
+
console.error(`${TAG19} added admin phone=${normalized}`);
|
|
10651
10698
|
reloadManagerConfig(accountDir);
|
|
10652
10699
|
return { ok: true, message: `Added ${normalized} as admin phone. Messages from this number will route to the admin agent.` };
|
|
10653
10700
|
} catch (err) {
|
|
10654
10701
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10655
|
-
console.error(`${
|
|
10702
|
+
console.error(`${TAG19} addAdminPhone failed: ${msg}`);
|
|
10656
10703
|
return { ok: false, error: msg };
|
|
10657
10704
|
}
|
|
10658
10705
|
}
|
|
@@ -10680,12 +10727,12 @@ function removeAdminPhone(accountDir, phone) {
|
|
|
10680
10727
|
}
|
|
10681
10728
|
config.whatsapp = parsed.data;
|
|
10682
10729
|
writeConfig(accountDir, config);
|
|
10683
|
-
console.error(`${
|
|
10730
|
+
console.error(`${TAG19} removed admin phone=${normalized}`);
|
|
10684
10731
|
reloadManagerConfig(accountDir);
|
|
10685
10732
|
return { ok: true, message: `Removed ${normalized} from admin phones. Messages from this number will now route to the public agent.` };
|
|
10686
10733
|
} catch (err) {
|
|
10687
10734
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10688
|
-
console.error(`${
|
|
10735
|
+
console.error(`${TAG19} removeAdminPhone failed: ${msg}`);
|
|
10689
10736
|
return { ok: false, error: msg };
|
|
10690
10737
|
}
|
|
10691
10738
|
}
|
|
@@ -10723,12 +10770,12 @@ function setPublicAgent(accountDir, slug) {
|
|
|
10723
10770
|
}
|
|
10724
10771
|
config.whatsapp = parsed.data;
|
|
10725
10772
|
writeConfig(accountDir, config);
|
|
10726
|
-
console.error(`${
|
|
10773
|
+
console.error(`${TAG19} publicAgent set to ${trimmed}`);
|
|
10727
10774
|
reloadManagerConfig(accountDir);
|
|
10728
10775
|
return { ok: true, message: `Public agent set to "${trimmed}". WhatsApp messages from non-admin phones will be handled by this agent.` };
|
|
10729
10776
|
} catch (err) {
|
|
10730
10777
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10731
|
-
console.error(`${
|
|
10778
|
+
console.error(`${TAG19} setPublicAgent failed: ${msg}`);
|
|
10732
10779
|
return { ok: false, error: msg };
|
|
10733
10780
|
}
|
|
10734
10781
|
}
|
|
@@ -10792,12 +10839,12 @@ function setGroupPublicAgent(accountDir, accountId, groupJid, slug) {
|
|
|
10792
10839
|
}
|
|
10793
10840
|
config.whatsapp = parsed.data;
|
|
10794
10841
|
writeConfig(accountDir, config);
|
|
10795
|
-
console.error(`${
|
|
10842
|
+
console.error(`${TAG19} setGroupPublicAgent account=${trimmedAccount} groupJid=${trimmedGroup} slug=${trimmedSlug}`);
|
|
10796
10843
|
reloadManagerConfig(accountDir);
|
|
10797
10844
|
return { ok: true, message: `Per-group public agent set to "${trimmedSlug}" for group ${trimmedGroup}.` };
|
|
10798
10845
|
} catch (err) {
|
|
10799
10846
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10800
|
-
console.error(`${
|
|
10847
|
+
console.error(`${TAG19} setGroupPublicAgent failed: ${msg}`);
|
|
10801
10848
|
return { ok: false, error: msg };
|
|
10802
10849
|
}
|
|
10803
10850
|
}
|
|
@@ -10824,12 +10871,12 @@ function unsetGroupPublicAgent(accountDir, accountId, groupJid) {
|
|
|
10824
10871
|
}
|
|
10825
10872
|
config.whatsapp = parsed.data;
|
|
10826
10873
|
writeConfig(accountDir, config);
|
|
10827
|
-
console.error(`${
|
|
10874
|
+
console.error(`${TAG19} unsetGroupPublicAgent account=${trimmedAccount} groupJid=${trimmedGroup}`);
|
|
10828
10875
|
reloadManagerConfig(accountDir);
|
|
10829
10876
|
return { ok: true, message: `Per-group public agent override removed for group ${trimmedGroup}.` };
|
|
10830
10877
|
} catch (err) {
|
|
10831
10878
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10832
|
-
console.error(`${
|
|
10879
|
+
console.error(`${TAG19} unsetGroupPublicAgent failed: ${msg}`);
|
|
10833
10880
|
return { ok: false, error: msg };
|
|
10834
10881
|
}
|
|
10835
10882
|
}
|
|
@@ -10850,17 +10897,17 @@ function updateConfig(accountDir, fields) {
|
|
|
10850
10897
|
const parsed = WhatsAppConfigSchema.safeParse(wa);
|
|
10851
10898
|
if (!parsed.success) {
|
|
10852
10899
|
const msg = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
10853
|
-
console.error(`${
|
|
10900
|
+
console.error(`${TAG19} update validation failed: ${msg}`);
|
|
10854
10901
|
return { ok: false, error: `Validation failed: ${msg}` };
|
|
10855
10902
|
}
|
|
10856
10903
|
config.whatsapp = parsed.data;
|
|
10857
10904
|
writeConfig(accountDir, config);
|
|
10858
|
-
console.error(`${
|
|
10905
|
+
console.error(`${TAG19} updated fields=[${fieldNames.join(",")}]`);
|
|
10859
10906
|
reloadManagerConfig(accountDir);
|
|
10860
10907
|
return { ok: true, message: `Updated WhatsApp config: ${fieldNames.join(", ")}.` };
|
|
10861
10908
|
} catch (err) {
|
|
10862
10909
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10863
|
-
console.error(`${
|
|
10910
|
+
console.error(`${TAG19} updateConfig failed: ${msg}`);
|
|
10864
10911
|
return { ok: false, error: msg };
|
|
10865
10912
|
}
|
|
10866
10913
|
}
|
|
@@ -10986,17 +11033,17 @@ function serializeWhatsAppSchema() {
|
|
|
10986
11033
|
}
|
|
10987
11034
|
|
|
10988
11035
|
// server/routes/whatsapp.ts
|
|
10989
|
-
var
|
|
11036
|
+
var TAG20 = "[whatsapp:api]";
|
|
10990
11037
|
var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
10991
11038
|
var app3 = new Hono();
|
|
10992
11039
|
app3.get("/status", (c) => {
|
|
10993
11040
|
try {
|
|
10994
11041
|
const status = getStatus();
|
|
10995
11042
|
const summary = status.map((a) => `${a.accountId}:${a.connected ? "up" : "down"}`).join(", ");
|
|
10996
|
-
console.error(`${
|
|
11043
|
+
console.error(`${TAG20} status accounts=${status.length} [${summary}]`);
|
|
10997
11044
|
return c.json({ accounts: status });
|
|
10998
11045
|
} catch (err) {
|
|
10999
|
-
console.error(`${
|
|
11046
|
+
console.error(`${TAG20} status error: ${String(err)}`);
|
|
11000
11047
|
return c.json({ error: String(err) }, 500);
|
|
11001
11048
|
}
|
|
11002
11049
|
});
|
|
@@ -11007,10 +11054,10 @@ app3.post("/login/start", async (c) => {
|
|
|
11007
11054
|
const force = body.force ?? false;
|
|
11008
11055
|
const authDir = join5(MAXY_DIR, "credentials", "whatsapp", accountId);
|
|
11009
11056
|
const result = await startLogin({ accountId, authDir, force });
|
|
11010
|
-
console.error(`${
|
|
11057
|
+
console.error(`${TAG20} login/start result account=${accountId} hasQr=${!!result.qrRaw}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
|
|
11011
11058
|
return c.json(result);
|
|
11012
11059
|
} catch (err) {
|
|
11013
|
-
console.error(`${
|
|
11060
|
+
console.error(`${TAG20} login/start error: ${String(err)}`);
|
|
11014
11061
|
return c.json({ error: String(err) }, 500);
|
|
11015
11062
|
}
|
|
11016
11063
|
});
|
|
@@ -11025,7 +11072,7 @@ app3.post("/login/wait", async (c) => {
|
|
|
11025
11072
|
try {
|
|
11026
11073
|
await registerLoginSocket(accountId, result.sock, result.authDir);
|
|
11027
11074
|
} catch (regErr) {
|
|
11028
|
-
console.error(`${
|
|
11075
|
+
console.error(`${TAG20} registerLoginSocket failed account=${accountId}: ${String(regErr)}`);
|
|
11029
11076
|
}
|
|
11030
11077
|
try {
|
|
11031
11078
|
const account = resolveAccount();
|
|
@@ -11033,16 +11080,16 @@ app3.post("/login/wait", async (c) => {
|
|
|
11033
11080
|
const persistResult = persistAfterPairing(account.accountDir, accountId, result.selfPhone ?? null);
|
|
11034
11081
|
configPersisted = persistResult.ok;
|
|
11035
11082
|
if (!persistResult.ok) {
|
|
11036
|
-
console.error(`${
|
|
11083
|
+
console.error(`${TAG20} config persist failed account=${accountId}: ${persistResult.error}`);
|
|
11037
11084
|
}
|
|
11038
11085
|
} else {
|
|
11039
|
-
console.error(`${
|
|
11086
|
+
console.error(`${TAG20} config persist skipped \u2014 no account resolved`);
|
|
11040
11087
|
}
|
|
11041
11088
|
} catch (persistErr) {
|
|
11042
|
-
console.error(`${
|
|
11089
|
+
console.error(`${TAG20} config persist error account=${accountId}: ${String(persistErr)}`);
|
|
11043
11090
|
}
|
|
11044
11091
|
}
|
|
11045
|
-
console.error(`${
|
|
11092
|
+
console.error(`${TAG20} login/wait result account=${accountId} connected=${result.connected}${result.selfPhone ? ` phone=${result.selfPhone}` : ""} configPersisted=${configPersisted}`);
|
|
11046
11093
|
return c.json({
|
|
11047
11094
|
connected: result.connected,
|
|
11048
11095
|
message: result.message,
|
|
@@ -11050,7 +11097,7 @@ app3.post("/login/wait", async (c) => {
|
|
|
11050
11097
|
configPersisted
|
|
11051
11098
|
});
|
|
11052
11099
|
} catch (err) {
|
|
11053
|
-
console.error(`${
|
|
11100
|
+
console.error(`${TAG20} login/wait error: ${String(err)}`);
|
|
11054
11101
|
return c.json({ error: String(err) }, 500);
|
|
11055
11102
|
}
|
|
11056
11103
|
});
|
|
@@ -11061,7 +11108,7 @@ app3.post("/disconnect", async (c) => {
|
|
|
11061
11108
|
await stopConnection(accountId);
|
|
11062
11109
|
return c.json({ disconnected: true, accountId });
|
|
11063
11110
|
} catch (err) {
|
|
11064
|
-
console.error(`${
|
|
11111
|
+
console.error(`${TAG20} disconnect error: ${String(err)}`);
|
|
11065
11112
|
return c.json({ error: String(err) }, 500);
|
|
11066
11113
|
}
|
|
11067
11114
|
});
|
|
@@ -11072,7 +11119,7 @@ app3.post("/reconnect", async (c) => {
|
|
|
11072
11119
|
await startConnection(accountId);
|
|
11073
11120
|
return c.json({ reconnecting: true, accountId });
|
|
11074
11121
|
} catch (err) {
|
|
11075
|
-
console.error(`${
|
|
11122
|
+
console.error(`${TAG20} reconnect error: ${String(err)}`);
|
|
11076
11123
|
return c.json({ error: String(err) }, 500);
|
|
11077
11124
|
}
|
|
11078
11125
|
});
|
|
@@ -11091,7 +11138,7 @@ app3.post("/send", async (c) => {
|
|
|
11091
11138
|
const result = await sendTextMessage(sock, to, text, { accountId });
|
|
11092
11139
|
return c.json(result);
|
|
11093
11140
|
} catch (err) {
|
|
11094
|
-
console.error(`${
|
|
11141
|
+
console.error(`${TAG20} send error: ${String(err)}`);
|
|
11095
11142
|
return c.json({ error: String(err) }, 500);
|
|
11096
11143
|
}
|
|
11097
11144
|
});
|
|
@@ -11112,7 +11159,7 @@ app3.post("/config", async (c) => {
|
|
|
11112
11159
|
return c.json({ ok: false, error: 'Missing required field "phone" (E.164 format, e.g. +441234567890).' }, 400);
|
|
11113
11160
|
}
|
|
11114
11161
|
const result = addAdminPhone(account.accountDir, phone);
|
|
11115
|
-
console.error(`${
|
|
11162
|
+
console.error(`${TAG20} config action=add-admin-phone phone=${phone} ok=${result.ok}`);
|
|
11116
11163
|
return c.json(result, result.ok ? 200 : 400);
|
|
11117
11164
|
}
|
|
11118
11165
|
case "remove-admin-phone": {
|
|
@@ -11120,12 +11167,12 @@ app3.post("/config", async (c) => {
|
|
|
11120
11167
|
return c.json({ ok: false, error: 'Missing required field "phone".' }, 400);
|
|
11121
11168
|
}
|
|
11122
11169
|
const result = removeAdminPhone(account.accountDir, phone);
|
|
11123
|
-
console.error(`${
|
|
11170
|
+
console.error(`${TAG20} config action=remove-admin-phone phone=${phone} ok=${result.ok}`);
|
|
11124
11171
|
return c.json(result, result.ok ? 200 : 400);
|
|
11125
11172
|
}
|
|
11126
11173
|
case "list-admin-phones": {
|
|
11127
11174
|
const phones = readAdminPhones(account.accountDir);
|
|
11128
|
-
console.error(`${
|
|
11175
|
+
console.error(`${TAG20} config action=list-admin-phones count=${phones.length}`);
|
|
11129
11176
|
return c.json({ ok: true, phones });
|
|
11130
11177
|
}
|
|
11131
11178
|
case "set-public-agent": {
|
|
@@ -11133,14 +11180,14 @@ app3.post("/config", async (c) => {
|
|
|
11133
11180
|
return c.json({ ok: false, error: 'Missing required field "slug" (the agent directory name, e.g. "my-agent").' }, 400);
|
|
11134
11181
|
}
|
|
11135
11182
|
const result = setPublicAgent(account.accountDir, slug);
|
|
11136
|
-
console.error(`${
|
|
11183
|
+
console.error(`${TAG20} config action=set-public-agent slug=${slug} ok=${result.ok}`);
|
|
11137
11184
|
return c.json(result, result.ok ? 200 : 400);
|
|
11138
11185
|
}
|
|
11139
11186
|
case "get-public-agent": {
|
|
11140
11187
|
const targetAccount = typeof accountId === "string" && accountId.trim() ? accountId.trim() : "default";
|
|
11141
11188
|
const targetGroup = typeof groupJid === "string" && groupJid.trim() ? groupJid.trim() : void 0;
|
|
11142
11189
|
const resolved = resolvePublicAgent(account.accountDir, { accountId: targetAccount, groupJid: targetGroup });
|
|
11143
|
-
console.error(`${
|
|
11190
|
+
console.error(`${TAG20} config action=get-public-agent accountId=${targetAccount} groupJid=${targetGroup ?? "none"} slug=${resolved?.slug ?? "none"} source=${resolved?.source ?? "none"}`);
|
|
11144
11191
|
return c.json({ ok: true, slug: resolved?.slug ?? null, source: resolved?.source ?? null });
|
|
11145
11192
|
}
|
|
11146
11193
|
case "set-group-public-agent": {
|
|
@@ -11152,7 +11199,7 @@ app3.post("/config", async (c) => {
|
|
|
11152
11199
|
}
|
|
11153
11200
|
const targetAccount = typeof accountId === "string" && accountId.trim() ? accountId.trim() : "default";
|
|
11154
11201
|
const result = setGroupPublicAgent(account.accountDir, targetAccount, groupJid, slug);
|
|
11155
|
-
console.error(`${
|
|
11202
|
+
console.error(`${TAG20} config action=set-group-public-agent accountId=${targetAccount} groupJid=${groupJid} slug=${slug} ok=${result.ok}`);
|
|
11156
11203
|
return c.json(result, result.ok ? 200 : 400);
|
|
11157
11204
|
}
|
|
11158
11205
|
case "unset-group-public-agent": {
|
|
@@ -11161,7 +11208,7 @@ app3.post("/config", async (c) => {
|
|
|
11161
11208
|
}
|
|
11162
11209
|
const targetAccount = typeof accountId === "string" && accountId.trim() ? accountId.trim() : "default";
|
|
11163
11210
|
const result = unsetGroupPublicAgent(account.accountDir, targetAccount, groupJid);
|
|
11164
|
-
console.error(`${
|
|
11211
|
+
console.error(`${TAG20} config action=unset-group-public-agent accountId=${targetAccount} groupJid=${groupJid} ok=${result.ok}`);
|
|
11165
11212
|
return c.json(result, result.ok ? 200 : 400);
|
|
11166
11213
|
}
|
|
11167
11214
|
case "list-public-agents": {
|
|
@@ -11178,26 +11225,26 @@ app3.post("/config", async (c) => {
|
|
|
11178
11225
|
const config = JSON.parse(readFileSync6(configPath2, "utf-8"));
|
|
11179
11226
|
agents.push({ slug: entry.name, displayName: config.displayName ?? entry.name });
|
|
11180
11227
|
} catch {
|
|
11181
|
-
console.error(`${
|
|
11228
|
+
console.error(`${TAG20} config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
|
|
11182
11229
|
}
|
|
11183
11230
|
}
|
|
11184
11231
|
} catch (err) {
|
|
11185
|
-
console.error(`${
|
|
11232
|
+
console.error(`${TAG20} config action=list-public-agents error="failed to scan agents directory: ${String(err)}"`);
|
|
11186
11233
|
}
|
|
11187
11234
|
}
|
|
11188
|
-
console.error(`${
|
|
11235
|
+
console.error(`${TAG20} config action=list-public-agents count=${agents.length}`);
|
|
11189
11236
|
return c.json({ ok: true, agents });
|
|
11190
11237
|
}
|
|
11191
11238
|
case "schema": {
|
|
11192
11239
|
const text = serializeWhatsAppSchema();
|
|
11193
|
-
console.error(`${
|
|
11240
|
+
console.error(`${TAG20} config action=schema`);
|
|
11194
11241
|
return c.json({ ok: true, text });
|
|
11195
11242
|
}
|
|
11196
11243
|
case "list-groups": {
|
|
11197
11244
|
const groupAccountId = accountId ?? "default";
|
|
11198
11245
|
const sock = getSocket(groupAccountId);
|
|
11199
11246
|
if (!sock) {
|
|
11200
|
-
console.error(`${
|
|
11247
|
+
console.error(`${TAG20} config action=list-groups error="not connected" accountId=${groupAccountId}`);
|
|
11201
11248
|
return c.json({ ok: false, error: `WhatsApp account "${groupAccountId}" is not connected. Connect first, then retry.` });
|
|
11202
11249
|
}
|
|
11203
11250
|
try {
|
|
@@ -11207,10 +11254,10 @@ app3.post("/config", async (c) => {
|
|
|
11207
11254
|
name: g.subject ?? g.id,
|
|
11208
11255
|
participantCount: Array.isArray(g.participants) ? g.participants.length : 0
|
|
11209
11256
|
}));
|
|
11210
|
-
console.error(`${
|
|
11257
|
+
console.error(`${TAG20} config action=list-groups count=${groups.length} accountId=${groupAccountId}`);
|
|
11211
11258
|
return c.json({ ok: true, groups });
|
|
11212
11259
|
} catch (err) {
|
|
11213
|
-
console.error(`${
|
|
11260
|
+
console.error(`${TAG20} config action=list-groups error="${String(err)}" accountId=${groupAccountId}`);
|
|
11214
11261
|
return c.json({ ok: false, error: `Failed to fetch groups: ${String(err)}` });
|
|
11215
11262
|
}
|
|
11216
11263
|
}
|
|
@@ -11220,12 +11267,12 @@ app3.post("/config", async (c) => {
|
|
|
11220
11267
|
}
|
|
11221
11268
|
const result = updateConfig(account.accountDir, fields);
|
|
11222
11269
|
const fieldNames = Object.keys(fields);
|
|
11223
|
-
console.error(`${
|
|
11270
|
+
console.error(`${TAG20} config action=update-config fields=[${fieldNames.join(",")}] ok=${result.ok}`);
|
|
11224
11271
|
return c.json(result, result.ok ? 200 : 400);
|
|
11225
11272
|
}
|
|
11226
11273
|
case "get-config": {
|
|
11227
11274
|
const waConfig = getConfig(account.accountDir);
|
|
11228
|
-
console.error(`${
|
|
11275
|
+
console.error(`${TAG20} config action=get-config`);
|
|
11229
11276
|
return c.json({ ok: true, config: waConfig });
|
|
11230
11277
|
}
|
|
11231
11278
|
default:
|
|
@@ -11235,7 +11282,7 @@ app3.post("/config", async (c) => {
|
|
|
11235
11282
|
);
|
|
11236
11283
|
}
|
|
11237
11284
|
} catch (err) {
|
|
11238
|
-
console.error(`${
|
|
11285
|
+
console.error(`${TAG20} config error: ${String(err)}`);
|
|
11239
11286
|
return c.json({ ok: false, error: String(err) }, 500);
|
|
11240
11287
|
}
|
|
11241
11288
|
});
|
|
@@ -11256,7 +11303,7 @@ app3.post("/send-document", async (c) => {
|
|
|
11256
11303
|
recordRouteDocumentOutbound(to, filePath);
|
|
11257
11304
|
return c.json({ success: true, messageId: result.messageId });
|
|
11258
11305
|
} catch (err) {
|
|
11259
|
-
console.error(`${
|
|
11306
|
+
console.error(`${TAG20} send-document error: ${String(err)}`);
|
|
11260
11307
|
return c.json({ error: String(err) }, 500);
|
|
11261
11308
|
}
|
|
11262
11309
|
});
|
|
@@ -11266,11 +11313,11 @@ app3.get("/activity", (c) => {
|
|
|
11266
11313
|
const result = getChannelActivity(accountId);
|
|
11267
11314
|
const total = result.accounts.reduce((sum, a) => sum + a.total, 0);
|
|
11268
11315
|
console.error(
|
|
11269
|
-
`${
|
|
11316
|
+
`${TAG20} activity accounts=${result.accounts.length} total=${total} recentEvents=${result.recentEvents.length}` + (accountId ? ` filter=${accountId}` : "")
|
|
11270
11317
|
);
|
|
11271
11318
|
return c.json(result);
|
|
11272
11319
|
} catch (err) {
|
|
11273
|
-
console.error(`${
|
|
11320
|
+
console.error(`${TAG20} activity error: ${String(err)}`);
|
|
11274
11321
|
return c.json({ error: String(err) }, 500);
|
|
11275
11322
|
}
|
|
11276
11323
|
});
|
|
@@ -11289,10 +11336,10 @@ app3.get("/conversations", (c) => {
|
|
|
11289
11336
|
};
|
|
11290
11337
|
});
|
|
11291
11338
|
conversations.sort((a, b) => (b.lastMessageTimestamp ?? 0) - (a.lastMessageTimestamp ?? 0));
|
|
11292
|
-
console.error(`${
|
|
11339
|
+
console.error(`${TAG20} conversations account=${accountId} count=${conversations.length}`);
|
|
11293
11340
|
return c.json({ conversations });
|
|
11294
11341
|
} catch (err) {
|
|
11295
|
-
console.error(`${
|
|
11342
|
+
console.error(`${TAG20} conversations error: ${String(err)}`);
|
|
11296
11343
|
return c.json({ error: String(err) }, 500);
|
|
11297
11344
|
}
|
|
11298
11345
|
});
|
|
@@ -11307,10 +11354,10 @@ app3.get("/messages", (c) => {
|
|
|
11307
11354
|
const limit = limitParam ? parseInt(limitParam, 10) : void 0;
|
|
11308
11355
|
const effectiveLimit = limit && !Number.isNaN(limit) && limit > 0 ? limit : void 0;
|
|
11309
11356
|
const messages = getMessages(accountId, jid, effectiveLimit);
|
|
11310
|
-
console.error(`${
|
|
11357
|
+
console.error(`${TAG20} messages account=${accountId} jid=${jid} limit=${effectiveLimit ?? "all"} returned=${messages.length}`);
|
|
11311
11358
|
return c.json({ messages });
|
|
11312
11359
|
} catch (err) {
|
|
11313
|
-
console.error(`${
|
|
11360
|
+
console.error(`${TAG20} messages error: ${String(err)}`);
|
|
11314
11361
|
return c.json({ error: String(err) }, 500);
|
|
11315
11362
|
}
|
|
11316
11363
|
});
|
|
@@ -11391,7 +11438,7 @@ app3.get("/conversation-graph-state", async (c) => {
|
|
|
11391
11438
|
}
|
|
11392
11439
|
} catch (err) {
|
|
11393
11440
|
const msg = err instanceof Error ? err.message : String(err);
|
|
11394
|
-
console.error(`${
|
|
11441
|
+
console.error(`${TAG20} conversation-graph-state ERR cacheKey=${cacheKey} reason=${msg}`);
|
|
11395
11442
|
return c.json({ error: `Graph query failed: ${msg}`, cacheKey, cypher: cypher.trim() }, 500);
|
|
11396
11443
|
}
|
|
11397
11444
|
const ms = Date.now() - t0;
|
|
@@ -11404,7 +11451,7 @@ app3.get("/conversation-graph-state", async (c) => {
|
|
|
11404
11451
|
ms
|
|
11405
11452
|
});
|
|
11406
11453
|
} catch (err) {
|
|
11407
|
-
console.error(`${
|
|
11454
|
+
console.error(`${TAG20} conversation-graph-state error: ${String(err)}`);
|
|
11408
11455
|
return c.json({ error: String(err) }, 500);
|
|
11409
11456
|
}
|
|
11410
11457
|
});
|
|
@@ -11416,12 +11463,12 @@ app3.get("/group-info", async (c) => {
|
|
|
11416
11463
|
return c.json({ error: "Missing required parameter: jid" }, 400);
|
|
11417
11464
|
}
|
|
11418
11465
|
if (!isGroupJid(jid)) {
|
|
11419
|
-
console.error(`${
|
|
11466
|
+
console.error(`${TAG20} group-info error="not a group JID" jid=${jid} account=${accountId}`);
|
|
11420
11467
|
return c.json({ error: `"${jid}" is not a group JID. Group JIDs end with @g.us.` }, 400);
|
|
11421
11468
|
}
|
|
11422
11469
|
const sock = getSocket(accountId);
|
|
11423
11470
|
if (!sock) {
|
|
11424
|
-
console.error(`${
|
|
11471
|
+
console.error(`${TAG20} group-info error="not connected" account=${accountId}`);
|
|
11425
11472
|
return c.json({ error: `WhatsApp account "${accountId}" is not connected. Connect first, then retry.` }, 400);
|
|
11426
11473
|
}
|
|
11427
11474
|
const meta = await sock.groupMetadata(jid);
|
|
@@ -11434,10 +11481,10 @@ app3.get("/group-info", async (c) => {
|
|
|
11434
11481
|
participantCount: meta.participants.length,
|
|
11435
11482
|
participants: meta.participants.map((p) => ({ jid: p.id, admin: p.admin ?? null }))
|
|
11436
11483
|
};
|
|
11437
|
-
console.error(`${
|
|
11484
|
+
console.error(`${TAG20} group-info jid=${jid} subject="${meta.subject}" participants=${meta.participants.length} account=${accountId}`);
|
|
11438
11485
|
return c.json(result);
|
|
11439
11486
|
} catch (err) {
|
|
11440
|
-
console.error(`${
|
|
11487
|
+
console.error(`${TAG20} group-info error="${String(err)}" jid=${jid} account=${accountId}`);
|
|
11441
11488
|
return c.json({ error: `Failed to fetch group info: ${String(err)}` }, 500);
|
|
11442
11489
|
}
|
|
11443
11490
|
});
|
|
@@ -12095,7 +12142,7 @@ async function createAdminSession(accountId, thinkingView, userId, userName, rol
|
|
|
12095
12142
|
} catch (err) {
|
|
12096
12143
|
console.error(`[session] eager-ensureConversation FAILED at boot: ${err instanceof Error ? err.message : String(err)}`);
|
|
12097
12144
|
}
|
|
12098
|
-
console.log(`[session]
|
|
12145
|
+
console.log(`[session] admin session created: userId=${userId ?? "\u2013"} userName=${userName ?? "\u2013"} accountId=${accountId} sessionId=${initialSessionId ?? "unbound"} cacheKey=${cacheKey.slice(0, 8)}`);
|
|
12099
12146
|
console.log(`[admin-session] role=${role ?? "null"} cacheKey=${cacheKey.slice(0, 8)} phase=create eager-ensured=${initialSessionId ? "true" : "false"}`);
|
|
12100
12147
|
return {
|
|
12101
12148
|
session_key: signedSessionToken,
|
|
@@ -12997,7 +13044,7 @@ app11.post("/:id/resume", async (c) => {
|
|
|
12997
13044
|
try {
|
|
12998
13045
|
neo4jMessages = await getRecentMessages(sessionId);
|
|
12999
13046
|
} catch (err) {
|
|
13000
|
-
console.error(`[admin-resume]
|
|
13047
|
+
console.error(`[admin-resume] getRecentMessages failed: sessionId=${sessionId.slice(0, 8)}\u2026 error=${err instanceof Error ? err.message : String(err)}`);
|
|
13001
13048
|
return c.json({ error: "Failed to load conversation messages" }, 500);
|
|
13002
13049
|
}
|
|
13003
13050
|
if (persistedAgentSessionId) {
|
|
@@ -13191,7 +13238,7 @@ app11.post("/:id/resume", async (c) => {
|
|
|
13191
13238
|
} catch {
|
|
13192
13239
|
}
|
|
13193
13240
|
const age = formatAge(updatedAt);
|
|
13194
|
-
console.log(`[admin-resume]
|
|
13241
|
+
console.log(`[admin-resume] reason=${reason} sessionId=${sessionId.slice(0, 8)}\u2026 age=${age} loaded=${messages.length} messages ${tag} components=${totalComponents} attachments=${totalAttachments} syntheticHidden=${syntheticHidden} jsonlMissing=${jsonlMissing} healMissing=${jsonlHealMissing} cacheKey=${cacheKey.slice(0, 8)}\u2026`);
|
|
13195
13242
|
console.log(`[admin-session-restore] cacheKey=${cacheKey.slice(0, 8)} sessionId=${sessionId.slice(0, 8)} messageCount=${rehydrated.length} ms=${Date.now() - t0}`);
|
|
13196
13243
|
return c.json({
|
|
13197
13244
|
sessionId,
|
|
@@ -13544,7 +13591,7 @@ function resolveTunnelUrl() {
|
|
|
13544
13591
|
if (!state) return null;
|
|
13545
13592
|
return `https://${hostname2}.${state.domain}`;
|
|
13546
13593
|
}
|
|
13547
|
-
var
|
|
13594
|
+
var TAG21 = "[claude-session-manager:wrapper]";
|
|
13548
13595
|
async function refuseIfClaudeAuthDead(c, route, sessionId) {
|
|
13549
13596
|
const auth = await ensureAuth();
|
|
13550
13597
|
if (auth.status !== "dead" && auth.status !== "missing") return null;
|
|
@@ -13566,12 +13613,12 @@ async function performSpawnWithInitialMessage(args) {
|
|
|
13566
13613
|
const aboutOwner = await resolveOwnerProfileBlock(args.senderId, args.userId);
|
|
13567
13614
|
const ownerMs = Date.now() - ownerStart;
|
|
13568
13615
|
const aboutOwnerStatus = aboutOwner == null ? "absent" : "ok" in aboutOwner && aboutOwner.ok === false ? `unresolved:${aboutOwner.reason}` : "ok";
|
|
13569
|
-
console.log(`${
|
|
13616
|
+
console.log(`${TAG21} about-owner-resolved status=${aboutOwnerStatus} ms=${ownerMs}`);
|
|
13570
13617
|
const dormantPlugins = computeDormantPlugins(args.senderId);
|
|
13571
13618
|
const activePlugins = computeActivePlugins(args.senderId);
|
|
13572
13619
|
const specialistDomains = computeSpecialistDomains(args.senderId);
|
|
13573
13620
|
const tunnelUrl = resolveTunnelUrl();
|
|
13574
|
-
console.log(`${
|
|
13621
|
+
console.log(`${TAG21} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
|
|
13575
13622
|
const upstreamPayload = JSON.stringify({
|
|
13576
13623
|
senderId: args.senderId,
|
|
13577
13624
|
// Task 205 — pass userId through to the manager so it lands as
|
|
@@ -13598,24 +13645,24 @@ async function performSpawnWithInitialMessage(args) {
|
|
|
13598
13645
|
// unshapely values.
|
|
13599
13646
|
conversationNodeId: args.conversationNodeId
|
|
13600
13647
|
});
|
|
13601
|
-
console.log(`${
|
|
13648
|
+
console.log(`${TAG21} forward-spawn-start managerBase=${managerBase3()} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
|
|
13602
13649
|
const forwardStart = Date.now();
|
|
13603
13650
|
const upstream = await fetch(`${managerBase3()}/public-spawn`, {
|
|
13604
13651
|
method: "POST",
|
|
13605
13652
|
headers: { "content-type": "application/json" },
|
|
13606
13653
|
body: upstreamPayload
|
|
13607
13654
|
}).catch((err) => {
|
|
13608
|
-
console.error(`${
|
|
13655
|
+
console.error(`${TAG21} fetch-failed op=spawn message=${err instanceof Error ? err.message : String(err)} ms=${Date.now() - forwardStart}`);
|
|
13609
13656
|
return null;
|
|
13610
13657
|
});
|
|
13611
13658
|
if (!upstream) return {
|
|
13612
13659
|
response: new Response(JSON.stringify({ error: "manager-unreachable" }), { status: 503, headers: { "content-type": "application/json" } }),
|
|
13613
13660
|
claudeSessionId: null
|
|
13614
13661
|
};
|
|
13615
|
-
console.log(`${
|
|
13662
|
+
console.log(`${TAG21} forward-spawn-done status=${upstream.status} ms=${Date.now() - forwardStart}`);
|
|
13616
13663
|
if (args.initialMessage) {
|
|
13617
13664
|
const inputBytes = Buffer.byteLength(args.initialMessage, "utf8");
|
|
13618
|
-
console.log(`${
|
|
13665
|
+
console.log(`${TAG21} initial-message-inlined bytes=${inputBytes}`);
|
|
13619
13666
|
}
|
|
13620
13667
|
const bodyText = await upstream.text().catch(() => "");
|
|
13621
13668
|
let claudeSessionId = null;
|
|
@@ -13650,7 +13697,7 @@ app12.post("/", async (c) => {
|
|
|
13650
13697
|
if (refusal) return refusal;
|
|
13651
13698
|
const senderId = getAccountIdForSession(cacheKey) ?? "";
|
|
13652
13699
|
if (!senderId) {
|
|
13653
|
-
console.error(`${
|
|
13700
|
+
console.error(`${TAG21} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
|
|
13654
13701
|
return c.json({ error: "admin-account-not-resolved" }, 500);
|
|
13655
13702
|
}
|
|
13656
13703
|
const userId = getUserIdForSession(cacheKey) ?? void 0;
|
|
@@ -13659,7 +13706,7 @@ app12.post("/", async (c) => {
|
|
|
13659
13706
|
const permissionMode = typeof body.permissionMode === "string" ? body.permissionMode : void 0;
|
|
13660
13707
|
const specialist = typeof body.specialist === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(body.specialist) ? body.specialist : void 0;
|
|
13661
13708
|
const model = typeof body.model === "string" && /^[A-Za-z0-9._-]{1,64}$/.test(body.model) ? body.model : void 0;
|
|
13662
|
-
console.log(`${
|
|
13709
|
+
console.log(`${TAG21} spawn-request-in surface=cookie accountId=${senderId.slice(0, 8)} userId=${userId ? userId.slice(0, 8) : "absent"} channel=${channel} permissionMode=${permissionMode ?? "default"} specialist=${specialist ?? "none"} model=${model ?? "default"} initialMessage=${initialMessage ? "yes" : "no"}`);
|
|
13663
13710
|
const conversationNodeId = cacheKey ? getSessionIdForSession(cacheKey) : void 0;
|
|
13664
13711
|
const { response, claudeSessionId } = await performSpawnWithInitialMessage({
|
|
13665
13712
|
senderId,
|
|
@@ -13678,13 +13725,13 @@ app12.post("/", async (c) => {
|
|
|
13678
13725
|
claudeSessionId,
|
|
13679
13726
|
senderId
|
|
13680
13727
|
);
|
|
13681
|
-
console.log(`${
|
|
13728
|
+
console.log(`${TAG21} route-done surface=cookie status=${response.status} route-ms=${Date.now() - routeStart}`);
|
|
13682
13729
|
return response;
|
|
13683
13730
|
});
|
|
13684
13731
|
var claude_sessions_default = app12;
|
|
13685
13732
|
|
|
13686
13733
|
// server/routes/admin/log-ingest.ts
|
|
13687
|
-
var
|
|
13734
|
+
var TAG22 = "[log-ingest]";
|
|
13688
13735
|
var TAG_PATTERN = /^[A-Za-z0-9_:-]{1,32}$/;
|
|
13689
13736
|
var LEVELS = /* @__PURE__ */ new Set(["debug", "info", "warn", "error"]);
|
|
13690
13737
|
var MAX_LINE_BYTES = 4096;
|
|
@@ -13695,7 +13742,7 @@ function isLoopbackAddr(addr) {
|
|
|
13695
13742
|
app13.post("/", async (c) => {
|
|
13696
13743
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
13697
13744
|
if (!isLoopbackAddr(remoteAddr)) {
|
|
13698
|
-
console.error(`${
|
|
13745
|
+
console.error(`${TAG22} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
13699
13746
|
return c.json({ error: "log-ingest-loopback-only" }, 403);
|
|
13700
13747
|
}
|
|
13701
13748
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
@@ -13704,7 +13751,7 @@ app13.post("/", async (c) => {
|
|
|
13704
13751
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
13705
13752
|
const offender = tokens.find((t) => !isLoopbackAddr(t));
|
|
13706
13753
|
if (offender !== void 0) {
|
|
13707
|
-
console.error(`${
|
|
13754
|
+
console.error(`${TAG22} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
13708
13755
|
return c.json({ error: "log-ingest-loopback-only" }, 403);
|
|
13709
13756
|
}
|
|
13710
13757
|
}
|
|
@@ -13746,18 +13793,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
13746
13793
|
]);
|
|
13747
13794
|
var app14 = new Hono();
|
|
13748
13795
|
app14.post("/", async (c) => {
|
|
13749
|
-
const
|
|
13796
|
+
const TAG32 = "[admin:events]";
|
|
13750
13797
|
let body;
|
|
13751
13798
|
try {
|
|
13752
13799
|
body = await c.req.json();
|
|
13753
13800
|
} catch (err) {
|
|
13754
13801
|
const detail = err instanceof Error ? err.message : String(err);
|
|
13755
|
-
console.error(`${
|
|
13802
|
+
console.error(`${TAG32} reject reason=body-not-json detail=${detail}`);
|
|
13756
13803
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
13757
13804
|
}
|
|
13758
13805
|
const event = typeof body.event === "string" ? body.event : "";
|
|
13759
13806
|
if (!ALLOWED_EVENTS.has(event)) {
|
|
13760
|
-
console.error(`${
|
|
13807
|
+
console.error(`${TAG32} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
13761
13808
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
13762
13809
|
}
|
|
13763
13810
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -17783,7 +17830,7 @@ var health_default2 = app27;
|
|
|
17783
17830
|
|
|
17784
17831
|
// server/routes/admin/linkedin-ingest.ts
|
|
17785
17832
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
17786
|
-
var
|
|
17833
|
+
var TAG23 = "[linkedin-ingest-route]";
|
|
17787
17834
|
var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
17788
17835
|
var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
17789
17836
|
var LINKEDIN_URL = /^https:\/\/www\.linkedin\.com\//;
|
|
@@ -17887,29 +17934,29 @@ app28.post("/", requireAdminSession, async (c) => {
|
|
|
17887
17934
|
try {
|
|
17888
17935
|
body = await c.req.json();
|
|
17889
17936
|
} catch {
|
|
17890
|
-
console.error(
|
|
17937
|
+
console.error(TAG23 + " rejected status=400 reason=schema:body-not-json");
|
|
17891
17938
|
return c.json({ ok: false, error: "schema", reason: "body-not-json" }, 400);
|
|
17892
17939
|
}
|
|
17893
17940
|
const v = validate(body);
|
|
17894
17941
|
if (!v.ok) {
|
|
17895
|
-
console.error(
|
|
17942
|
+
console.error(TAG23 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
|
|
17896
17943
|
return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
|
|
17897
17944
|
}
|
|
17898
17945
|
const envelope = v.envelope;
|
|
17899
17946
|
const cacheKey = c.var.cacheKey ?? "";
|
|
17900
17947
|
const senderId = getAccountIdForSession(cacheKey) ?? "";
|
|
17901
17948
|
if (!senderId) {
|
|
17902
|
-
console.error(
|
|
17949
|
+
console.error(TAG23 + " rejected status=500 reason=admin-account-not-resolved");
|
|
17903
17950
|
return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
|
|
17904
17951
|
}
|
|
17905
17952
|
const payloadBytes = JSON.stringify(envelope).length;
|
|
17906
17953
|
console.log(
|
|
17907
|
-
|
|
17954
|
+
TAG23 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
|
|
17908
17955
|
);
|
|
17909
17956
|
const initialMessage = buildInitialMessage(envelope);
|
|
17910
17957
|
const spawnStart = Date.now();
|
|
17911
17958
|
const sessionId = randomUUID9();
|
|
17912
|
-
console.log(
|
|
17959
|
+
console.log(TAG23 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
|
|
17913
17960
|
const spawned = await managerRcSpawn({
|
|
17914
17961
|
sessionId,
|
|
17915
17962
|
initialMessage,
|
|
@@ -17918,12 +17965,12 @@ app28.post("/", requireAdminSession, async (c) => {
|
|
|
17918
17965
|
});
|
|
17919
17966
|
if ("error" in spawned) {
|
|
17920
17967
|
console.error(
|
|
17921
|
-
|
|
17968
|
+
TAG23 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
|
|
17922
17969
|
);
|
|
17923
17970
|
return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: spawned.status, detail: spawned.error }, 502);
|
|
17924
17971
|
}
|
|
17925
17972
|
console.log(
|
|
17926
|
-
|
|
17973
|
+
TAG23 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
|
|
17927
17974
|
);
|
|
17928
17975
|
return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
|
|
17929
17976
|
});
|
|
@@ -17931,7 +17978,7 @@ var linkedin_ingest_default = app28;
|
|
|
17931
17978
|
|
|
17932
17979
|
// server/routes/admin/post-turn-context.ts
|
|
17933
17980
|
import neo4j2 from "neo4j-driver";
|
|
17934
|
-
var
|
|
17981
|
+
var TAG24 = "[post-turn-context]";
|
|
17935
17982
|
var STRIPPED_PROPERTIES2 = /* @__PURE__ */ new Set([
|
|
17936
17983
|
"embedding",
|
|
17937
17984
|
"passwordHash",
|
|
@@ -17973,7 +18020,7 @@ var app29 = new Hono();
|
|
|
17973
18020
|
app29.get("/", async (c) => {
|
|
17974
18021
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
17975
18022
|
if (!isLoopbackAddr2(remoteAddr)) {
|
|
17976
|
-
console.error(`${
|
|
18023
|
+
console.error(`${TAG24} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
17977
18024
|
return c.json({ error: "post-turn-context-loopback-only" }, 403);
|
|
17978
18025
|
}
|
|
17979
18026
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
@@ -17982,7 +18029,7 @@ app29.get("/", async (c) => {
|
|
|
17982
18029
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
17983
18030
|
const offender = tokens.find((t) => !isLoopbackAddr2(t));
|
|
17984
18031
|
if (offender !== void 0) {
|
|
17985
|
-
console.error(`${
|
|
18032
|
+
console.error(`${TAG24} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
17986
18033
|
return c.json({ error: "post-turn-context-loopback-only" }, 403);
|
|
17987
18034
|
}
|
|
17988
18035
|
}
|
|
@@ -18014,7 +18061,7 @@ app29.get("/", async (c) => {
|
|
|
18014
18061
|
writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
|
|
18015
18062
|
const total = Date.now() - started;
|
|
18016
18063
|
console.log(
|
|
18017
|
-
`${
|
|
18064
|
+
`${TAG24} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
|
|
18018
18065
|
);
|
|
18019
18066
|
return c.json({
|
|
18020
18067
|
writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
|
|
@@ -18023,7 +18070,7 @@ app29.get("/", async (c) => {
|
|
|
18023
18070
|
const elapsed = Date.now() - started;
|
|
18024
18071
|
const message = err instanceof Error ? err.message : String(err);
|
|
18025
18072
|
console.error(
|
|
18026
|
-
`${
|
|
18073
|
+
`${TAG24} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
|
|
18027
18074
|
);
|
|
18028
18075
|
return c.json({ error: `post-turn-context unavailable: ${message}` }, 503);
|
|
18029
18076
|
} finally {
|
|
@@ -18034,7 +18081,7 @@ var post_turn_context_default = app29;
|
|
|
18034
18081
|
|
|
18035
18082
|
// server/routes/admin/public-session-context.ts
|
|
18036
18083
|
import neo4j3 from "neo4j-driver";
|
|
18037
|
-
var
|
|
18084
|
+
var TAG25 = "[public-session-context]";
|
|
18038
18085
|
var STRIPPED_PROPERTIES3 = /* @__PURE__ */ new Set([
|
|
18039
18086
|
"embedding",
|
|
18040
18087
|
"passwordHash",
|
|
@@ -18076,7 +18123,7 @@ var app30 = new Hono();
|
|
|
18076
18123
|
app30.get("/", async (c) => {
|
|
18077
18124
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
18078
18125
|
if (!isLoopbackAddr3(remoteAddr)) {
|
|
18079
|
-
console.error(`${
|
|
18126
|
+
console.error(`${TAG25} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
18080
18127
|
return c.json({ error: "public-session-context-loopback-only" }, 403);
|
|
18081
18128
|
}
|
|
18082
18129
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
@@ -18085,7 +18132,7 @@ app30.get("/", async (c) => {
|
|
|
18085
18132
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
18086
18133
|
const offender = tokens.find((t) => !isLoopbackAddr3(t));
|
|
18087
18134
|
if (offender !== void 0) {
|
|
18088
|
-
console.error(`${
|
|
18135
|
+
console.error(`${TAG25} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
18089
18136
|
return c.json({ error: "public-session-context-loopback-only" }, 403);
|
|
18090
18137
|
}
|
|
18091
18138
|
}
|
|
@@ -18116,7 +18163,7 @@ app30.get("/", async (c) => {
|
|
|
18116
18163
|
writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
|
|
18117
18164
|
const total = Date.now() - started;
|
|
18118
18165
|
console.log(
|
|
18119
|
-
`${
|
|
18166
|
+
`${TAG25} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
|
|
18120
18167
|
);
|
|
18121
18168
|
return c.json({
|
|
18122
18169
|
writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
|
|
@@ -18125,7 +18172,7 @@ app30.get("/", async (c) => {
|
|
|
18125
18172
|
const elapsed = Date.now() - started;
|
|
18126
18173
|
const message = err instanceof Error ? err.message : String(err);
|
|
18127
18174
|
console.error(
|
|
18128
|
-
`${
|
|
18175
|
+
`${TAG25} neo4j-unreachable sliceToken=${sliceToken.slice(0, 8)} ms=${elapsed} err="${message}"`
|
|
18129
18176
|
);
|
|
18130
18177
|
return c.json({ error: `public-session-context unavailable: ${message}` }, 503);
|
|
18131
18178
|
} finally {
|
|
@@ -18135,7 +18182,7 @@ app30.get("/", async (c) => {
|
|
|
18135
18182
|
var public_session_context_default = app30;
|
|
18136
18183
|
|
|
18137
18184
|
// server/routes/admin/public-session-exit.ts
|
|
18138
|
-
var
|
|
18185
|
+
var TAG26 = "[public-session-exit-route]";
|
|
18139
18186
|
function isLoopbackAddr4(addr) {
|
|
18140
18187
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
18141
18188
|
}
|
|
@@ -18143,7 +18190,7 @@ var app31 = new Hono();
|
|
|
18143
18190
|
app31.post("/", async (c) => {
|
|
18144
18191
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
18145
18192
|
if (!isLoopbackAddr4(remoteAddr)) {
|
|
18146
|
-
console.error(`${
|
|
18193
|
+
console.error(`${TAG26} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
18147
18194
|
return c.json({ error: "public-session-exit-loopback-only" }, 403);
|
|
18148
18195
|
}
|
|
18149
18196
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
@@ -18152,7 +18199,7 @@ app31.post("/", async (c) => {
|
|
|
18152
18199
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
18153
18200
|
const offender = tokens.find((t) => !isLoopbackAddr4(t));
|
|
18154
18201
|
if (offender !== void 0) {
|
|
18155
|
-
console.error(`${
|
|
18202
|
+
console.error(`${TAG26} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
18156
18203
|
return c.json({ error: "public-session-exit-loopback-only" }, 403);
|
|
18157
18204
|
}
|
|
18158
18205
|
}
|
|
@@ -18170,7 +18217,7 @@ app31.post("/", async (c) => {
|
|
|
18170
18217
|
var public_session_exit_default = app31;
|
|
18171
18218
|
|
|
18172
18219
|
// server/routes/admin/access-session-evict.ts
|
|
18173
|
-
var
|
|
18220
|
+
var TAG27 = "[access-session-evict]";
|
|
18174
18221
|
function isLoopbackAddr5(addr) {
|
|
18175
18222
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
18176
18223
|
}
|
|
@@ -18178,7 +18225,7 @@ var app32 = new Hono();
|
|
|
18178
18225
|
app32.post("/", async (c) => {
|
|
18179
18226
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
18180
18227
|
if (!isLoopbackAddr5(remoteAddr)) {
|
|
18181
|
-
console.error(`${
|
|
18228
|
+
console.error(`${TAG27} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
18182
18229
|
return c.json({ error: "access-session-evict-loopback-only" }, 403);
|
|
18183
18230
|
}
|
|
18184
18231
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
@@ -18187,7 +18234,7 @@ app32.post("/", async (c) => {
|
|
|
18187
18234
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
18188
18235
|
const offender = tokens.find((t) => !isLoopbackAddr5(t));
|
|
18189
18236
|
if (offender !== void 0) {
|
|
18190
|
-
console.error(`${
|
|
18237
|
+
console.error(`${TAG27} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
18191
18238
|
return c.json({ error: "access-session-evict-loopback-only" }, 403);
|
|
18192
18239
|
}
|
|
18193
18240
|
}
|
|
@@ -18200,7 +18247,7 @@ app32.post("/", async (c) => {
|
|
|
18200
18247
|
const grantId = typeof body.grantId === "string" ? body.grantId.trim() : "";
|
|
18201
18248
|
if (!grantId) return c.json({ error: "grantId required" }, 400);
|
|
18202
18249
|
const dropped = evictAccessSessionsByGrant(grantId);
|
|
18203
|
-
console.log(`${
|
|
18250
|
+
console.log(`${TAG27} grantId=${grantId} dropped=${dropped}`);
|
|
18204
18251
|
return c.json({ ok: true, dropped });
|
|
18205
18252
|
});
|
|
18206
18253
|
var access_session_evict_default = app32;
|
|
@@ -18208,7 +18255,7 @@ var access_session_evict_default = app32;
|
|
|
18208
18255
|
// server/routes/admin/identity.ts
|
|
18209
18256
|
var import_dist4 = __toESM(require_dist3(), 1);
|
|
18210
18257
|
var app33 = new Hono();
|
|
18211
|
-
var
|
|
18258
|
+
var TAG28 = "[admin-identity]";
|
|
18212
18259
|
function managerBase5() {
|
|
18213
18260
|
const port2 = (0, import_dist4.requirePortEnv)("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-identity" });
|
|
18214
18261
|
return `http://127.0.0.1:${port2}`;
|
|
@@ -18239,55 +18286,88 @@ app33.post("/validate", async (c) => {
|
|
|
18239
18286
|
const verdict = validatePin(pin, USERS_FILE);
|
|
18240
18287
|
if (verdict.kind !== "match") {
|
|
18241
18288
|
if (verdict.kind === "miss") fireStop();
|
|
18242
|
-
console.log(`${
|
|
18289
|
+
console.log(`${TAG28} op=endpoint-validate result=${verdict.kind}${sessionId ? ` sessionId=${sessionId.slice(0, 8)}` : ""}`);
|
|
18243
18290
|
return c.json({ kind: verdict.kind });
|
|
18244
18291
|
}
|
|
18245
18292
|
const { userId } = verdict;
|
|
18246
18293
|
const accounts = resolveUserAccounts(userId);
|
|
18247
18294
|
if (accounts.length === 0) {
|
|
18248
18295
|
fireStop();
|
|
18249
|
-
console.log(`${
|
|
18296
|
+
console.log(`${TAG28} op=endpoint-validate result=no-account userId=${userId.slice(0, 8)}`);
|
|
18250
18297
|
return c.json({ kind: "miss" });
|
|
18251
18298
|
}
|
|
18252
18299
|
const accountId = accounts[0].accountId;
|
|
18253
18300
|
const { userName } = await resolveUserIdentity(accountId, userId);
|
|
18254
18301
|
const aboutOwner = await resolveOwnerProfileBlock(accountId, userId);
|
|
18255
|
-
console.log(`${
|
|
18302
|
+
console.log(`${TAG28} op=endpoint-validate result=match userId=${userId.slice(0, 8)} aboutOwner=${aboutOwner.ok ? "ok" : `unresolved:${aboutOwner.reason}`}`);
|
|
18256
18303
|
return c.json({ kind: "match", userId, userName, aboutOwner });
|
|
18257
18304
|
});
|
|
18258
18305
|
var identity_default = app33;
|
|
18259
18306
|
|
|
18260
|
-
// server/routes/admin/
|
|
18307
|
+
// server/routes/admin/browser.ts
|
|
18261
18308
|
var app34 = new Hono();
|
|
18262
|
-
app34.
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
|
|
18266
|
-
|
|
18267
|
-
|
|
18268
|
-
|
|
18269
|
-
|
|
18270
|
-
|
|
18271
|
-
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
|
|
18275
|
-
|
|
18276
|
-
|
|
18277
|
-
|
|
18278
|
-
|
|
18279
|
-
|
|
18280
|
-
|
|
18281
|
-
|
|
18282
|
-
|
|
18283
|
-
|
|
18284
|
-
|
|
18285
|
-
|
|
18286
|
-
|
|
18287
|
-
|
|
18288
|
-
|
|
18289
|
-
|
|
18290
|
-
var
|
|
18309
|
+
app34.post("/launch", requireAdminSession, async (c) => {
|
|
18310
|
+
try {
|
|
18311
|
+
const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
|
|
18312
|
+
console.error(`[admin/browser/launch] op=request transport=${transport}`);
|
|
18313
|
+
if (transport === "vnc") {
|
|
18314
|
+
const vncOk = await ensureVnc();
|
|
18315
|
+
console.error(`[admin/browser/launch] op=vnc-ensured ok=${vncOk}`);
|
|
18316
|
+
if (!vncOk) {
|
|
18317
|
+
console.error("[admin/browser/launch] op=vnc-failed");
|
|
18318
|
+
return c.json({ ok: false, error: "VNC failed to start" }, 502);
|
|
18319
|
+
}
|
|
18320
|
+
}
|
|
18321
|
+
const cdpOk = await ensureCdp(transport);
|
|
18322
|
+
console.error(`[admin/browser/launch] op=cdp-ensured ok=${cdpOk}`);
|
|
18323
|
+
if (!cdpOk) {
|
|
18324
|
+
console.error("[admin/browser/launch] op=cdp-failed");
|
|
18325
|
+
return c.json({ ok: false, error: "Chrome failed to start" }, 502);
|
|
18326
|
+
}
|
|
18327
|
+
console.error(`[admin/browser/launch] op=ready transport=${transport}`);
|
|
18328
|
+
return c.json({ ok: true, transport });
|
|
18329
|
+
} catch (err) {
|
|
18330
|
+
console.error("[admin/browser/launch] Failed to start browser:", err);
|
|
18331
|
+
return c.json(
|
|
18332
|
+
{ ok: false, error: err instanceof Error ? err.message : "Unknown error" },
|
|
18333
|
+
500
|
|
18334
|
+
);
|
|
18335
|
+
}
|
|
18336
|
+
});
|
|
18337
|
+
var browser_default = app34;
|
|
18338
|
+
|
|
18339
|
+
// server/routes/admin/index.ts
|
|
18340
|
+
var app35 = new Hono();
|
|
18341
|
+
app35.route("/session", session_default);
|
|
18342
|
+
app35.route("/identity", identity_default);
|
|
18343
|
+
app35.route("/logs", logs_default);
|
|
18344
|
+
app35.route("/claude-info", claude_info_default);
|
|
18345
|
+
app35.route("/attachment", attachment_default);
|
|
18346
|
+
app35.route("/agents", agents_default);
|
|
18347
|
+
app35.route("/sessions", sessions_default);
|
|
18348
|
+
app35.route("/claude-sessions", claude_sessions_default);
|
|
18349
|
+
app35.route("/log-ingest", log_ingest_default);
|
|
18350
|
+
app35.route("/events", events_default);
|
|
18351
|
+
app35.route("/files", files_default);
|
|
18352
|
+
app35.route("/graph-search", graph_search_default);
|
|
18353
|
+
app35.route("/graph-subgraph", graph_subgraph_default);
|
|
18354
|
+
app35.route("/graph-delete", graph_delete_default);
|
|
18355
|
+
app35.route("/graph-restore", graph_restore_default);
|
|
18356
|
+
app35.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
18357
|
+
app35.route("/graph-default-view", graph_default_view_default);
|
|
18358
|
+
app35.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
18359
|
+
app35.route("/sidebar-sessions", sidebar_sessions_default);
|
|
18360
|
+
app35.route("/session-delete", session_delete_default);
|
|
18361
|
+
app35.route("/browser", browser_default);
|
|
18362
|
+
app35.route("/session-rc-spawn", session_rc_spawn_default);
|
|
18363
|
+
app35.route("/system-stats", system_stats_default);
|
|
18364
|
+
app35.route("/health-brand", health_default2);
|
|
18365
|
+
app35.route("/linkedin-ingest", linkedin_ingest_default);
|
|
18366
|
+
app35.route("/post-turn-context", post_turn_context_default);
|
|
18367
|
+
app35.route("/public-session-context", public_session_context_default);
|
|
18368
|
+
app35.route("/public-session-exit", public_session_exit_default);
|
|
18369
|
+
app35.route("/access-session-evict", access_session_evict_default);
|
|
18370
|
+
var admin_default = app35;
|
|
18291
18371
|
|
|
18292
18372
|
// app/lib/access-gate.ts
|
|
18293
18373
|
import neo4j4 from "neo4j-driver";
|
|
@@ -18498,11 +18578,11 @@ async function generateNewMagicToken(grantId) {
|
|
|
18498
18578
|
}
|
|
18499
18579
|
|
|
18500
18580
|
// server/routes/access/verify-token.ts
|
|
18501
|
-
var
|
|
18581
|
+
var TAG29 = "[access-verify]";
|
|
18502
18582
|
var MINT_TAG = "[access-session-mint]";
|
|
18503
18583
|
var COOKIE_NAME = "__access_session";
|
|
18504
|
-
var
|
|
18505
|
-
|
|
18584
|
+
var app36 = new Hono();
|
|
18585
|
+
app36.post("/", async (c) => {
|
|
18506
18586
|
const ip = c.var.clientIp || "unknown";
|
|
18507
18587
|
let body;
|
|
18508
18588
|
try {
|
|
@@ -18517,39 +18597,39 @@ app35.post("/", async (c) => {
|
|
|
18517
18597
|
}
|
|
18518
18598
|
const rateMsg = checkAccessRateLimit(ip, agentSlug);
|
|
18519
18599
|
if (rateMsg) {
|
|
18520
|
-
console.error(`${
|
|
18600
|
+
console.error(`${TAG29} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
|
|
18521
18601
|
return c.json({ error: rateMsg }, 429);
|
|
18522
18602
|
}
|
|
18523
18603
|
const grant = await findGrantByMagicToken(token);
|
|
18524
18604
|
if (!grant) {
|
|
18525
18605
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
18526
|
-
console.error(`${
|
|
18606
|
+
console.error(`${TAG29} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
|
|
18527
18607
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
18528
18608
|
}
|
|
18529
18609
|
if (grant.agentSlug !== agentSlug) {
|
|
18530
18610
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
18531
18611
|
console.error(
|
|
18532
|
-
`${
|
|
18612
|
+
`${TAG29} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
|
|
18533
18613
|
);
|
|
18534
18614
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
18535
18615
|
}
|
|
18536
18616
|
if (grant.status === "expired" || grant.status === "revoked") {
|
|
18537
18617
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
18538
18618
|
console.error(
|
|
18539
|
-
`${
|
|
18619
|
+
`${TAG29} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
|
|
18540
18620
|
);
|
|
18541
18621
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
18542
18622
|
}
|
|
18543
18623
|
if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
|
|
18544
18624
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
18545
18625
|
console.error(
|
|
18546
|
-
`${
|
|
18626
|
+
`${TAG29} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
|
|
18547
18627
|
);
|
|
18548
18628
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
18549
18629
|
}
|
|
18550
18630
|
if (!grant.sliceToken) {
|
|
18551
18631
|
console.error(
|
|
18552
|
-
`${
|
|
18632
|
+
`${TAG29} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
|
|
18553
18633
|
);
|
|
18554
18634
|
return c.json({ error: "grant-misconfigured" }, 500);
|
|
18555
18635
|
}
|
|
@@ -18565,12 +18645,12 @@ app35.post("/", async (c) => {
|
|
|
18565
18645
|
await consumeMagicTokenAndActivate(grant.grantId);
|
|
18566
18646
|
} catch (err) {
|
|
18567
18647
|
console.error(
|
|
18568
|
-
`${
|
|
18648
|
+
`${TAG29} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
18569
18649
|
);
|
|
18570
18650
|
return c.json({ error: "verification-failed" }, 500);
|
|
18571
18651
|
}
|
|
18572
18652
|
clearAccessRateLimit(ip, agentSlug);
|
|
18573
|
-
console.log(`${
|
|
18653
|
+
console.log(`${TAG29} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
|
|
18574
18654
|
console.log(
|
|
18575
18655
|
`${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
|
|
18576
18656
|
);
|
|
@@ -18584,7 +18664,7 @@ app35.post("/", async (c) => {
|
|
|
18584
18664
|
displayName: grant.displayName
|
|
18585
18665
|
});
|
|
18586
18666
|
});
|
|
18587
|
-
var verify_token_default =
|
|
18667
|
+
var verify_token_default = app36;
|
|
18588
18668
|
|
|
18589
18669
|
// app/lib/access-email.ts
|
|
18590
18670
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -18646,10 +18726,10 @@ async function sendMagicLinkEmail(payload) {
|
|
|
18646
18726
|
}
|
|
18647
18727
|
|
|
18648
18728
|
// server/routes/access/request-magic-link.ts
|
|
18649
|
-
var
|
|
18650
|
-
var
|
|
18729
|
+
var TAG30 = "[access-request-link]";
|
|
18730
|
+
var app37 = new Hono();
|
|
18651
18731
|
var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
|
|
18652
|
-
|
|
18732
|
+
app37.post("/", async (c) => {
|
|
18653
18733
|
let body;
|
|
18654
18734
|
try {
|
|
18655
18735
|
body = await c.req.json();
|
|
@@ -18663,18 +18743,18 @@ app36.post("/", async (c) => {
|
|
|
18663
18743
|
}
|
|
18664
18744
|
const rateMsg = checkRequestLinkRateLimit(contactValue);
|
|
18665
18745
|
if (rateMsg) {
|
|
18666
|
-
console.error(`${
|
|
18746
|
+
console.error(`${TAG30} contactValue=${maskContact(contactValue)} result=rate-limited`);
|
|
18667
18747
|
return c.json({ error: rateMsg }, 429);
|
|
18668
18748
|
}
|
|
18669
18749
|
recordRequestLinkAttempt(contactValue);
|
|
18670
18750
|
const accountId = process.env.ACCOUNT_ID ?? "";
|
|
18671
18751
|
if (!accountId) {
|
|
18672
|
-
console.error(`${
|
|
18752
|
+
console.error(`${TAG30} contactValue=${maskContact(contactValue)} result=no-account-id`);
|
|
18673
18753
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
18674
18754
|
}
|
|
18675
18755
|
const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
|
|
18676
18756
|
if (!grant) {
|
|
18677
|
-
console.log(`${
|
|
18757
|
+
console.log(`${TAG30} contactValue=${maskContact(contactValue)} result=notfound`);
|
|
18678
18758
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
18679
18759
|
}
|
|
18680
18760
|
let token;
|
|
@@ -18682,7 +18762,7 @@ app36.post("/", async (c) => {
|
|
|
18682
18762
|
token = await generateNewMagicToken(grant.grantId);
|
|
18683
18763
|
} catch (err) {
|
|
18684
18764
|
console.error(
|
|
18685
|
-
`${
|
|
18765
|
+
`${TAG30} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
18686
18766
|
);
|
|
18687
18767
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
18688
18768
|
}
|
|
@@ -18714,22 +18794,22 @@ app36.post("/", async (c) => {
|
|
|
18714
18794
|
});
|
|
18715
18795
|
if (!sendResult.ok) {
|
|
18716
18796
|
console.error(
|
|
18717
|
-
`${
|
|
18797
|
+
`${TAG30} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
|
|
18718
18798
|
);
|
|
18719
18799
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
18720
18800
|
}
|
|
18721
18801
|
console.log(
|
|
18722
|
-
`${
|
|
18802
|
+
`${TAG30} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
|
|
18723
18803
|
);
|
|
18724
18804
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
18725
18805
|
});
|
|
18726
|
-
var request_magic_link_default =
|
|
18806
|
+
var request_magic_link_default = app37;
|
|
18727
18807
|
|
|
18728
18808
|
// server/routes/access/index.ts
|
|
18729
|
-
var
|
|
18730
|
-
|
|
18731
|
-
|
|
18732
|
-
var access_default =
|
|
18809
|
+
var app38 = new Hono();
|
|
18810
|
+
app38.route("/verify-token", verify_token_default);
|
|
18811
|
+
app38.route("/request-magic-link", request_magic_link_default);
|
|
18812
|
+
var access_default = app38;
|
|
18733
18813
|
|
|
18734
18814
|
// server/routes/sites.ts
|
|
18735
18815
|
import { existsSync as existsSync19, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
|
|
@@ -18764,8 +18844,8 @@ function getExt(p) {
|
|
|
18764
18844
|
if (idx < p.lastIndexOf("/")) return "";
|
|
18765
18845
|
return p.slice(idx).toLowerCase();
|
|
18766
18846
|
}
|
|
18767
|
-
var
|
|
18768
|
-
|
|
18847
|
+
var app39 = new Hono();
|
|
18848
|
+
app39.get("/:rel{.*}", (c) => {
|
|
18769
18849
|
const reqPath = c.req.path;
|
|
18770
18850
|
const rawRel = c.req.param("rel") ?? "";
|
|
18771
18851
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -18868,7 +18948,7 @@ app38.get("/:rel{.*}", (c) => {
|
|
|
18868
18948
|
"X-Content-Type-Options": "nosniff"
|
|
18869
18949
|
});
|
|
18870
18950
|
});
|
|
18871
|
-
var sites_default =
|
|
18951
|
+
var sites_default = app39;
|
|
18872
18952
|
|
|
18873
18953
|
// app/lib/visitor-token.ts
|
|
18874
18954
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
@@ -18968,7 +19048,7 @@ function readBrandConfig() {
|
|
|
18968
19048
|
}
|
|
18969
19049
|
|
|
18970
19050
|
// server/routes/visitor-consent.ts
|
|
18971
|
-
var
|
|
19051
|
+
var app40 = new Hono();
|
|
18972
19052
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
18973
19053
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
18974
19054
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -19013,17 +19093,17 @@ function siteSlugFromReferer(referer) {
|
|
|
19013
19093
|
return "";
|
|
19014
19094
|
}
|
|
19015
19095
|
}
|
|
19016
|
-
|
|
19096
|
+
app40.options("/consent", (c) => {
|
|
19017
19097
|
const origin = getOrigin(c);
|
|
19018
19098
|
setCorsHeaders(c, origin);
|
|
19019
19099
|
return c.body(null, 204);
|
|
19020
19100
|
});
|
|
19021
|
-
|
|
19101
|
+
app40.options("/brand-config", (c) => {
|
|
19022
19102
|
const origin = getOrigin(c);
|
|
19023
19103
|
setCorsHeaders(c, origin);
|
|
19024
19104
|
return c.body(null, 204);
|
|
19025
19105
|
});
|
|
19026
|
-
|
|
19106
|
+
app40.post("/consent", async (c) => {
|
|
19027
19107
|
const origin = getOrigin(c);
|
|
19028
19108
|
setCorsHeaders(c, origin);
|
|
19029
19109
|
let raw;
|
|
@@ -19063,7 +19143,7 @@ app39.post("/consent", async (c) => {
|
|
|
19063
19143
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
19064
19144
|
return c.body(null, 204);
|
|
19065
19145
|
});
|
|
19066
|
-
|
|
19146
|
+
app40.get("/brand-config", (c) => {
|
|
19067
19147
|
const origin = getOrigin(c);
|
|
19068
19148
|
setCorsHeaders(c, origin);
|
|
19069
19149
|
const brand = readBrandConfig();
|
|
@@ -19073,7 +19153,7 @@ app39.get("/brand-config", (c) => {
|
|
|
19073
19153
|
c.header("Cache-Control", "public, max-age=300");
|
|
19074
19154
|
return c.json({ consent: { copy, palette } });
|
|
19075
19155
|
});
|
|
19076
|
-
var visitor_consent_default =
|
|
19156
|
+
var visitor_consent_default = app40;
|
|
19077
19157
|
|
|
19078
19158
|
// server/routes/listings.ts
|
|
19079
19159
|
function getCookie(headerValue, name) {
|
|
@@ -19100,8 +19180,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
19100
19180
|
}
|
|
19101
19181
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
19102
19182
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
19103
|
-
var
|
|
19104
|
-
|
|
19183
|
+
var app41 = new Hono();
|
|
19184
|
+
app41.get("/:slug/click", async (c) => {
|
|
19105
19185
|
const slug = c.req.param("slug") ?? "";
|
|
19106
19186
|
const rawSession = c.req.query("session") ?? "";
|
|
19107
19187
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -19165,10 +19245,10 @@ app40.get("/:slug/click", async (c) => {
|
|
|
19165
19245
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
19166
19246
|
return c.redirect(redirectUrl, 302);
|
|
19167
19247
|
});
|
|
19168
|
-
var listings_default =
|
|
19248
|
+
var listings_default = app41;
|
|
19169
19249
|
|
|
19170
19250
|
// server/routes/visitor-event.ts
|
|
19171
|
-
var
|
|
19251
|
+
var app42 = new Hono();
|
|
19172
19252
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
19173
19253
|
var buckets = /* @__PURE__ */ new Map();
|
|
19174
19254
|
var RATE_LIMIT = 60;
|
|
@@ -19235,12 +19315,12 @@ function originAllowed(origin, allowlist) {
|
|
|
19235
19315
|
return false;
|
|
19236
19316
|
}
|
|
19237
19317
|
}
|
|
19238
|
-
|
|
19318
|
+
app42.options("/event", (c) => {
|
|
19239
19319
|
const origin = getOrigin2(c);
|
|
19240
19320
|
setCorsHeaders2(c, origin);
|
|
19241
19321
|
return c.body(null, 204);
|
|
19242
19322
|
});
|
|
19243
|
-
|
|
19323
|
+
app42.post("/event", async (c) => {
|
|
19244
19324
|
const origin = getOrigin2(c);
|
|
19245
19325
|
setCorsHeaders2(c, origin);
|
|
19246
19326
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -19445,7 +19525,7 @@ async function writeEvent(opts) {
|
|
|
19445
19525
|
);
|
|
19446
19526
|
}
|
|
19447
19527
|
}
|
|
19448
|
-
var visitor_event_default =
|
|
19528
|
+
var visitor_event_default = app42;
|
|
19449
19529
|
|
|
19450
19530
|
// server/routes/session.ts
|
|
19451
19531
|
import { resolve as resolve23 } from "path";
|
|
@@ -19482,8 +19562,8 @@ function withVisitorCookie(response, visitorId) {
|
|
|
19482
19562
|
headers
|
|
19483
19563
|
});
|
|
19484
19564
|
}
|
|
19485
|
-
var
|
|
19486
|
-
|
|
19565
|
+
var app43 = new Hono();
|
|
19566
|
+
app43.post("/", async (c) => {
|
|
19487
19567
|
let body;
|
|
19488
19568
|
try {
|
|
19489
19569
|
body = await c.req.json();
|
|
@@ -19687,7 +19767,7 @@ app42.post("/", async (c) => {
|
|
|
19687
19767
|
newVisitorId
|
|
19688
19768
|
);
|
|
19689
19769
|
});
|
|
19690
|
-
var session_default2 =
|
|
19770
|
+
var session_default2 = app43;
|
|
19691
19771
|
|
|
19692
19772
|
// app/lib/graph-health.ts
|
|
19693
19773
|
var import_dist5 = __toESM(require_dist4(), 1);
|
|
@@ -19910,7 +19990,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
19910
19990
|
}
|
|
19911
19991
|
|
|
19912
19992
|
// app/lib/whatsapp/inbound/claude-bridge.ts
|
|
19913
|
-
var
|
|
19993
|
+
var TAG31 = "[whatsapp-adaptor]";
|
|
19914
19994
|
function whatsappTurnTimeoutMs() {
|
|
19915
19995
|
return Number(process.env.WHATSAPP_PTY_TURN_TIMEOUT_MS ?? String(5 * 6e4));
|
|
19916
19996
|
}
|
|
@@ -19927,7 +20007,7 @@ ${note}` : note;
|
|
|
19927
20007
|
async function dispatchToClaude(input) {
|
|
19928
20008
|
const hasFileMedia = !!input.mediaPath && input.mediaType !== "audio";
|
|
19929
20009
|
const mediaField = hasFileMedia ? `media=${input.mediaType} mediaPath=${input.mediaPath}` : input.mediaType === "audio" ? "media=audio mediaPath=transcribed" : "media=none";
|
|
19930
|
-
console.error(`${
|
|
20010
|
+
console.error(`${TAG31} inbound-media ${mediaField} role=${input.role} senderId=${input.senderId}`);
|
|
19931
20011
|
const text = composeTurn(input);
|
|
19932
20012
|
if (!text.trim()) return;
|
|
19933
20013
|
const result = await dispatchOnce({
|
|
@@ -19940,13 +20020,19 @@ async function dispatchToClaude(input) {
|
|
|
19940
20020
|
timeoutMs: whatsappTurnTimeoutMs()
|
|
19941
20021
|
});
|
|
19942
20022
|
if ("error" in result) {
|
|
20023
|
+
if (result.error === "timeout" && result.cause === "no-turn") {
|
|
20024
|
+
recordInboundOutcome(input.senderId, "timeout-no-turn");
|
|
20025
|
+
} else if (result.error === "timeout" && result.cause === "relay-missed") {
|
|
20026
|
+
recordInboundOutcome(input.senderId, "timeout-relay-missed");
|
|
20027
|
+
}
|
|
19943
20028
|
return;
|
|
19944
20029
|
}
|
|
20030
|
+
recordInboundOutcome(input.senderId, "relay-ok");
|
|
19945
20031
|
try {
|
|
19946
20032
|
await input.reply(result.turnText);
|
|
19947
20033
|
} catch (err) {
|
|
19948
20034
|
const m = err instanceof Error ? err.message : String(err);
|
|
19949
|
-
console.error(`${
|
|
20035
|
+
console.error(`${TAG31} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
|
|
19950
20036
|
}
|
|
19951
20037
|
}
|
|
19952
20038
|
function startReaper2() {
|
|
@@ -20276,9 +20362,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
|
|
|
20276
20362
|
function isPublicHost(host) {
|
|
20277
20363
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
20278
20364
|
}
|
|
20279
|
-
var
|
|
20280
|
-
|
|
20281
|
-
|
|
20365
|
+
var app44 = new Hono();
|
|
20366
|
+
app44.use("*", clientIpMiddleware);
|
|
20367
|
+
app44.use("*", async (c, next) => {
|
|
20282
20368
|
await next();
|
|
20283
20369
|
c.header("X-Content-Type-Options", "nosniff");
|
|
20284
20370
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -20288,7 +20374,7 @@ app43.use("*", async (c, next) => {
|
|
|
20288
20374
|
);
|
|
20289
20375
|
});
|
|
20290
20376
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
20291
|
-
|
|
20377
|
+
app44.use("*", async (c, next) => {
|
|
20292
20378
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
20293
20379
|
await next();
|
|
20294
20380
|
return;
|
|
@@ -20306,7 +20392,7 @@ app43.use("*", async (c, next) => {
|
|
|
20306
20392
|
});
|
|
20307
20393
|
}
|
|
20308
20394
|
});
|
|
20309
|
-
|
|
20395
|
+
app44.use("*", async (c, next) => {
|
|
20310
20396
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20311
20397
|
if (!isPublicHost(host)) {
|
|
20312
20398
|
await next();
|
|
@@ -20337,7 +20423,7 @@ function resolveRemoteAuthOpts() {
|
|
|
20337
20423
|
return brandLoginOpts;
|
|
20338
20424
|
}
|
|
20339
20425
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
20340
|
-
|
|
20426
|
+
app44.post("/__remote-auth/login", async (c) => {
|
|
20341
20427
|
const client = clientFrom(c);
|
|
20342
20428
|
const clientIp = client.ip || "unknown";
|
|
20343
20429
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -20382,7 +20468,7 @@ app43.post("/__remote-auth/login", async (c) => {
|
|
|
20382
20468
|
}
|
|
20383
20469
|
});
|
|
20384
20470
|
});
|
|
20385
|
-
|
|
20471
|
+
app44.get("/__remote-auth/logout", (c) => {
|
|
20386
20472
|
const client = clientFrom(c);
|
|
20387
20473
|
const clientIp = client.ip || "unknown";
|
|
20388
20474
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -20395,7 +20481,7 @@ app43.get("/__remote-auth/logout", (c) => {
|
|
|
20395
20481
|
}
|
|
20396
20482
|
});
|
|
20397
20483
|
});
|
|
20398
|
-
|
|
20484
|
+
app44.post("/__remote-auth/change-password", async (c) => {
|
|
20399
20485
|
const client = clientFrom(c);
|
|
20400
20486
|
const clientIp = client.ip || "unknown";
|
|
20401
20487
|
const rateLimited = checkRateLimit(client);
|
|
@@ -20446,13 +20532,13 @@ app43.post("/__remote-auth/change-password", async (c) => {
|
|
|
20446
20532
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
20447
20533
|
}
|
|
20448
20534
|
});
|
|
20449
|
-
|
|
20535
|
+
app44.get("/__remote-auth/setup", (c) => {
|
|
20450
20536
|
if (isRemoteAuthConfigured()) {
|
|
20451
20537
|
return c.redirect("/");
|
|
20452
20538
|
}
|
|
20453
20539
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
20454
20540
|
});
|
|
20455
|
-
|
|
20541
|
+
app44.post("/__remote-auth/set-initial-password", async (c) => {
|
|
20456
20542
|
if (isRemoteAuthConfigured()) {
|
|
20457
20543
|
return c.redirect("/");
|
|
20458
20544
|
}
|
|
@@ -20490,10 +20576,10 @@ app43.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
20490
20576
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
20491
20577
|
}
|
|
20492
20578
|
});
|
|
20493
|
-
|
|
20579
|
+
app44.get("/api/remote-auth/status", (c) => {
|
|
20494
20580
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
20495
20581
|
});
|
|
20496
|
-
|
|
20582
|
+
app44.post("/api/remote-auth/set-password", async (c) => {
|
|
20497
20583
|
let body;
|
|
20498
20584
|
try {
|
|
20499
20585
|
body = await c.req.json();
|
|
@@ -20524,9 +20610,9 @@ app43.post("/api/remote-auth/set-password", async (c) => {
|
|
|
20524
20610
|
return c.json({ error: "Failed to save password" }, 500);
|
|
20525
20611
|
}
|
|
20526
20612
|
});
|
|
20527
|
-
|
|
20613
|
+
app44.route("/api/_client-error", client_error_default);
|
|
20528
20614
|
console.log("[client-error-route] mounted");
|
|
20529
|
-
|
|
20615
|
+
app44.use("*", async (c, next) => {
|
|
20530
20616
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20531
20617
|
const path2 = c.req.path;
|
|
20532
20618
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -20559,13 +20645,13 @@ app43.use("*", async (c, next) => {
|
|
|
20559
20645
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
20560
20646
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
20561
20647
|
});
|
|
20562
|
-
|
|
20563
|
-
|
|
20564
|
-
|
|
20565
|
-
|
|
20566
|
-
|
|
20567
|
-
|
|
20568
|
-
|
|
20648
|
+
app44.route("/api/health", health_default);
|
|
20649
|
+
app44.route("/api/chat", chat_default);
|
|
20650
|
+
app44.route("/api/whatsapp", whatsapp_default);
|
|
20651
|
+
app44.route("/api/onboarding", onboarding_default);
|
|
20652
|
+
app44.route("/api/admin", admin_default);
|
|
20653
|
+
app44.route("/api/access", access_default);
|
|
20654
|
+
app44.route("/api/session", session_default2);
|
|
20569
20655
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
20570
20656
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
20571
20657
|
var IMAGE_MIME = {
|
|
@@ -20577,7 +20663,7 @@ var IMAGE_MIME = {
|
|
|
20577
20663
|
".svg": "image/svg+xml",
|
|
20578
20664
|
".ico": "image/x-icon"
|
|
20579
20665
|
};
|
|
20580
|
-
|
|
20666
|
+
app44.get("/agent-assets/:slug/:filename", (c) => {
|
|
20581
20667
|
const slug = c.req.param("slug");
|
|
20582
20668
|
const filename = c.req.param("filename");
|
|
20583
20669
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -20612,7 +20698,7 @@ app43.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
20612
20698
|
"Cache-Control": "public, max-age=3600"
|
|
20613
20699
|
});
|
|
20614
20700
|
});
|
|
20615
|
-
|
|
20701
|
+
app44.get("/generated/:filename", (c) => {
|
|
20616
20702
|
const filename = c.req.param("filename");
|
|
20617
20703
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
20618
20704
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -20642,10 +20728,10 @@ app43.get("/generated/:filename", (c) => {
|
|
|
20642
20728
|
"Cache-Control": "public, max-age=86400"
|
|
20643
20729
|
});
|
|
20644
20730
|
});
|
|
20645
|
-
|
|
20646
|
-
|
|
20647
|
-
|
|
20648
|
-
|
|
20731
|
+
app44.route("/sites", sites_default);
|
|
20732
|
+
app44.route("/listings", listings_default);
|
|
20733
|
+
app44.route("/v", visitor_event_default);
|
|
20734
|
+
app44.route("/v", visitor_consent_default);
|
|
20649
20735
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
20650
20736
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
20651
20737
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -20776,7 +20862,7 @@ function escapeHtml(s) {
|
|
|
20776
20862
|
function agentUnavailableHtml() {
|
|
20777
20863
|
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
|
|
20778
20864
|
}
|
|
20779
|
-
|
|
20865
|
+
app44.get("/", (c) => {
|
|
20780
20866
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20781
20867
|
if (isPublicHost(host)) {
|
|
20782
20868
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -20792,12 +20878,12 @@ app43.get("/", (c) => {
|
|
|
20792
20878
|
}
|
|
20793
20879
|
return c.html(cachedHtml("index.html"));
|
|
20794
20880
|
});
|
|
20795
|
-
|
|
20881
|
+
app44.get("/public", (c) => {
|
|
20796
20882
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20797
20883
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20798
20884
|
return c.html(cachedHtml("public.html"));
|
|
20799
20885
|
});
|
|
20800
|
-
|
|
20886
|
+
app44.get("/chat", (c) => {
|
|
20801
20887
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20802
20888
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20803
20889
|
return c.html(cachedHtml("public.html"));
|
|
@@ -20816,9 +20902,9 @@ async function logViewerFetch(c, next) {
|
|
|
20816
20902
|
duration_ms: Date.now() - start
|
|
20817
20903
|
});
|
|
20818
20904
|
}
|
|
20819
|
-
|
|
20820
|
-
|
|
20821
|
-
|
|
20905
|
+
app44.use("/vnc-viewer.html", logViewerFetch);
|
|
20906
|
+
app44.use("/vnc-popout.html", logViewerFetch);
|
|
20907
|
+
app44.get("/vnc-popout.html", (c) => {
|
|
20822
20908
|
let html = htmlCache.get("vnc-popout.html");
|
|
20823
20909
|
if (!html) {
|
|
20824
20910
|
html = readFileSync22(resolve26(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -20831,7 +20917,7 @@ app43.get("/vnc-popout.html", (c) => {
|
|
|
20831
20917
|
}
|
|
20832
20918
|
return c.html(html);
|
|
20833
20919
|
});
|
|
20834
|
-
|
|
20920
|
+
app44.post("/api/vnc/client-event", async (c) => {
|
|
20835
20921
|
let body;
|
|
20836
20922
|
try {
|
|
20837
20923
|
body = await c.req.json();
|
|
@@ -20852,25 +20938,30 @@ app43.post("/api/vnc/client-event", async (c) => {
|
|
|
20852
20938
|
});
|
|
20853
20939
|
return c.json({ ok: true });
|
|
20854
20940
|
});
|
|
20855
|
-
|
|
20941
|
+
app44.get("/g/:slug", (c) => {
|
|
20856
20942
|
return c.html(brandedPublicHtml());
|
|
20857
20943
|
});
|
|
20858
|
-
|
|
20944
|
+
app44.get("/graph", (c) => {
|
|
20859
20945
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20860
20946
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20861
20947
|
return c.html(cachedHtml("graph.html"));
|
|
20862
20948
|
});
|
|
20863
|
-
|
|
20949
|
+
app44.get("/sessions", (c) => {
|
|
20864
20950
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20865
20951
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20866
20952
|
return c.html(cachedHtml("sessions.html"));
|
|
20867
20953
|
});
|
|
20868
|
-
|
|
20954
|
+
app44.get("/data", (c) => {
|
|
20869
20955
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20870
20956
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20871
20957
|
return c.html(cachedHtml("data.html"));
|
|
20872
20958
|
});
|
|
20873
|
-
|
|
20959
|
+
app44.get("/browser", (c) => {
|
|
20960
|
+
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20961
|
+
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20962
|
+
return c.html(cachedHtml("browser.html"));
|
|
20963
|
+
});
|
|
20964
|
+
app44.get("/:slug", async (c, next) => {
|
|
20874
20965
|
const slug = c.req.param("slug");
|
|
20875
20966
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
20876
20967
|
const account = resolveAccount();
|
|
@@ -20885,13 +20976,13 @@ app43.get("/:slug", async (c, next) => {
|
|
|
20885
20976
|
await next();
|
|
20886
20977
|
});
|
|
20887
20978
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
20888
|
-
|
|
20979
|
+
app44.get("/favicon.ico", (c) => {
|
|
20889
20980
|
c.header("Cache-Control", "public, max-age=300");
|
|
20890
20981
|
return c.redirect(brandFaviconPath, 302);
|
|
20891
20982
|
});
|
|
20892
20983
|
}
|
|
20893
|
-
|
|
20894
|
-
|
|
20984
|
+
app44.use("/*", serveStatic({ root: "./public" }));
|
|
20985
|
+
app44.all("*", (c) => {
|
|
20895
20986
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20896
20987
|
const path2 = c.req.path;
|
|
20897
20988
|
if (isPublicHost(host)) {
|
|
@@ -20905,7 +20996,7 @@ app43.all("*", (c) => {
|
|
|
20905
20996
|
});
|
|
20906
20997
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
20907
20998
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
20908
|
-
var httpServer = serve({ fetch:
|
|
20999
|
+
var httpServer = serve({ fetch: app44.fetch, port, hostname });
|
|
20909
21000
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
20910
21001
|
startAuthHealthHeartbeat();
|
|
20911
21002
|
{
|
|
@@ -20942,7 +21033,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
20942
21033
|
}
|
|
20943
21034
|
try {
|
|
20944
21035
|
const registered = [];
|
|
20945
|
-
for (const r of
|
|
21036
|
+
for (const r of app44.routes ?? []) {
|
|
20946
21037
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
20947
21038
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
20948
21039
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|