@rubytech/create-maxy-code 0.1.377 → 0.1.379
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/plugins/admin/skills/platform-architecture/SKILL.md +27 -6
- package/payload/platform/plugins/docs/references/admin-ui.md +26 -5
- package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +13 -0
- package/payload/platform/scripts/lib/read-brand-json.sh +19 -0
- package/payload/platform/scripts/seed-neo4j.sh +44 -3
- 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 +100 -13
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/server/{chunk-Y4SHSFGK.js → chunk-ZYS5V5QG.js} +22 -21
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/{AdminLoginScreens-DVjwrcZa.js → AdminLoginScreens-BHo8w_9J.js} +1 -1
- package/payload/server/public/assets/AdminShell-DbTijFVA.js +1 -0
- package/payload/server/public/assets/{Checkbox-B8dm2kDD.js → Checkbox-LmjNFccS.js} +1 -1
- package/payload/server/public/assets/admin-BBWILfl8.js +1 -0
- package/payload/server/public/assets/{arc-Crkz45LN.js → arc-JgkiMDpu.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-Dh5BzVzk.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-C9JThHgP.js → architectureDiagram-Q4EWVU46-CyIbl1bD.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DpsV_HXT.js → blockDiagram-DXYQGD6D-CkcZVblf.js} +1 -1
- package/payload/server/public/assets/{browser-BMyQHWKS.js → browser-DtLvD_ES.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CTm_6aKi.js → c4Diagram-AHTNJAMY-VByNuobb.js} +1 -1
- package/payload/server/public/assets/calendar-D3i4IqOV.js +1 -0
- package/payload/server/public/assets/channel-CFHc3PQ7.js +1 -0
- package/payload/server/public/assets/chat-DU-T6blN.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-1KSJW1q6.js → chunk-2KRD3SAO-BFwiGcqo.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-C3t08Ip-.js → chunk-336JU56O-BMCBU-vf.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-De9_O1hi.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-kl1ze33n.js → chunk-4BX2VUAB-RfOeo8_F.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-DxpoDoHg.js → chunk-4TB4RGXK-B5xbgonc.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-WM9VJzha.js → chunk-55IACEB6-K8U55ikJ.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-CLH63ZH3.js → chunk-5FUZZQ4R-DgmmsrAc.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-DCTb8IAT.js → chunk-5PVQY5BW-DQ6rtehF.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-BSYzyaoH.js → chunk-67CJDMHE-CC2kfpmQ.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-CarJ7O2P.js → chunk-7N4EOEYR-BClZ5bzw.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-DTNLyBpH.js → chunk-AA7GKIK3-adtwAFKX.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-BFmHflHY.js → chunk-BSJP7CBP-fKY1UWEd.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-BpjG0IzU.js → chunk-CIAEETIT-knPAMmjG.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-2fSowhlW.js → chunk-EDXVE4YY-C7FRKZ5e.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-ClcranGV.js → chunk-ENJZ2VHE-0cgFfv3z.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-DLq4BItQ.js → chunk-FMBD7UC4-Dm_Hcblb.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-B9QI3Guz.js → chunk-FOC6F5B3-CfCJNXmK.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-BAr-Mv1Z.js → chunk-ICPOFSXX-xeu6qrZj.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-8PvAHasY.js → chunk-K5T4RW27-BQDCSuTh.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC--aGaDRH5.js → chunk-KGLVRYIC-D6fFAgbM.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-BrWj7mw2.js → chunk-LIHQZDEY-Dskwlc-K.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-kYQmkMTi.js → chunk-ORNJ4GCN-CnHIrJeA.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-CIsryCWH.js → chunk-OYMX7WX6-B4bnsPkv.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-COwe7oXR.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-68X653e3.js → chunk-U2HBQHQK-BeEXzOqV.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-v3v9soX3.js → chunk-X2U36JSP-D2rpgOqd.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-CW5DPpop.js → chunk-XPW4576I-D-yT82Xf.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-B1VP7Rl2.js → chunk-YZCP3GAM-DqxlLBm1.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-DiJrujNY.js → chunk-ZZ45TVLE-CA_Ep0OM.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-wjL65qaU.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-D_EIplVd.js +1 -0
- package/payload/server/public/assets/clone-CEczy_Ef.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-BscXxLMc.js → cose-bilkent-S5V4N54A-DWb9mxTa.js} +1 -1
- package/payload/server/public/assets/{dagre-MBv6WlCS.js → dagre-B3K7jxOZ.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-DVgGlTQ1.js → dagre-KV5264BT-BhiTISRq.js} +1 -1
- package/payload/server/public/assets/data-B_vDxQrO.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-BmhCaO0a.js → diagram-5BDNPKRD-D5yBIDpm.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-ChU9L8vz.js → diagram-G4DWMVQ6-CSTE1S4d.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-Oy409Zc_.js → diagram-MMDJMWI5-D8llv4XY.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-Cn1YByqk.js → diagram-TYMM5635-CITQ7aDM.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-e17yfLvr.js → erDiagram-SMLLAGMA-BjR5nlmv.js} +1 -1
- package/payload/server/public/assets/{flatten-Cl1Bc3dR.js → flatten-DhYYI_lo.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-Dqt7sCVZ.js → flowDiagram-DWJPFMVM-Dl6e-E0f.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-B4IhwS2r.js → ganttDiagram-T4ZO3ILL-CppkrFAl.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-KHAc7IxG.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-BDw-PKcI.js → gitGraphDiagram-UUTBAWPF-clV_tnwa.js} +1 -1
- package/payload/server/public/assets/{graph-DF_nLsTp.js → graph-ClQeGEH4.js} +3 -3
- package/payload/server/public/assets/{graph-labels-HWQ5J7S-.js → graph-labels-OaIKHgMg.js} +1 -1
- package/payload/server/public/assets/{graphlib-DPIYk_sg.js → graphlib-Cnk6WL-8.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-C6nm3sYf.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-DhwCejsr.js +2 -0
- package/payload/server/public/assets/{isEmpty-D1pGOD1J.js → isEmpty-DGhq_DBP.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-BRIHsB3G.js → ishikawaDiagram-UXIWVN3A-DUqusmP1.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-aKNgmoHd.js → journeyDiagram-VCZTEJTY-RMEvGtDJ.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-cwBwT-nm.js → kanban-definition-6JOO6SKY-BxkwQPCP.js} +1 -1
- package/payload/server/public/assets/{line-DVtVRzUA.js → line-CiOuSBlJ.js} +1 -1
- package/payload/server/public/assets/{linear-DtoOFPO2.js → linear-D22sItNm.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-G7YD_zO3.js → mermaid-parser.core-kvN8ajT-.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-DpFyndHm.js → mermaid.core-DKHTTwbg.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CYXK_Pvz.js → mindmap-definition-QFDTVHPH-CKUJxwdG.js} +1 -1
- package/payload/server/public/assets/operator-Dxqfta5U.js +1 -0
- package/payload/server/public/assets/{ordinal-CBZeH4Yp.js → ordinal-CibZU3PM.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-z-APhyNH.js +1 -0
- package/payload/server/public/assets/page-BkIb7CHh.js +32 -0
- package/payload/server/public/assets/page-Dv_YEOUW.js +1 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-D_HVZjir.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-DFo4N6WH.js → pieDiagram-DEJITSTG-CRMabeJN.js} +1 -1
- package/payload/server/public/assets/{public-NNHS6mWb.js → public-C_mM8sSZ.js} +1 -1
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BlH5iIhl.js → quadrantDiagram-34T5L4WZ-DcrlhDuj.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-DtKBIb3o.js +1 -0
- package/payload/server/public/assets/{reduce-PuPlFPRX.js → reduce-Da0RBva0.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-D5WLty8A.js → requirementDiagram-MS252O5E-DP231rM_.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-CKSJX39F.js → rotate-ccw-VF0b6NTt.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-vB85IxHG.js → sankeyDiagram-XADWPNL6--HM5_dC8.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-Cxraa0Ee.js → sequenceDiagram-FGHM5R23-BsiVmDR9.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-BBPssYBx.js → stateDiagram-FHFEXIEX-Cjdhqdjh.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-6v4alr7n.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Bgk6PT62.js → timeline-definition-GMOUNBTQ-Cf5xPmSA.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-DbXWs029.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-DUGgqAs9.js +1 -0
- package/payload/server/public/assets/useSubAccountSwitcher-CQbgG-FH.js +9 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-Ca1GJeBC.css → useSubAccountSwitcher-VzvzZC7h.css} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-B-APTs3L.js → vennDiagram-DHZGUBPP-PCor55Sw.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-Cjn85RON.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CkXJSs_i.js → wardleyDiagram-NUSXRM2D-bokCHsim.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BkyshPMV.js → xychartDiagram-5P7HB3ND-B2YnsUoQ.js} +1 -1
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +4 -4
- package/payload/server/public/chat.html +7 -7
- package/payload/server/public/data.html +5 -4
- package/payload/server/public/graph.html +7 -7
- package/payload/server/public/index.html +8 -6
- package/payload/server/public/operator.html +9 -9
- package/payload/server/public/public.html +7 -7
- package/payload/server/server.js +289 -103
- package/payload/server/public/assets/AdminShell-CNQxSO9B.js +0 -1
- package/payload/server/public/assets/admin-Dfv2e8fn.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-Dma4Bgha.js +0 -1
- package/payload/server/public/assets/calendar-CG-2rQ4m.js +0 -1
- package/payload/server/public/assets/channel-B_-5bau1.js +0 -1
- package/payload/server/public/assets/chat-CRPVhDCc.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-Dirxdwjh.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-Duipo1kI.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-B3kX5SuB.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-D761c7Lr.js +0 -1
- package/payload/server/public/assets/clone-BrhFv6Tb.js +0 -1
- package/payload/server/public/assets/data-Bodds4fv.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-BCQAqtLy.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-qU7hK50T.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-KGdcJeTs.js +0 -2
- package/payload/server/public/assets/operator-DH9OAMpe.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-DiU2yS9m.js +0 -1
- package/payload/server/public/assets/page--Uj3qG5S.js +0 -32
- package/payload/server/public/assets/pie-ZZUOXDRM-zHUKKlVv.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-BUnVoaPg.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BWmmUwDt.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-C3Y-Q52h.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-Dk0qZpAg.js +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-DRITc7qp.js +0 -9
- package/payload/server/public/assets/wardley-RL74JXVD-BAWI02OA.js +0 -1
- /package/payload/server/public/assets/{_baseFor-brRjpUOX.js → _baseFor-BFYpZGkN.js} +0 -0
- /package/payload/server/public/assets/{array-BGFCBI0e.js → array-CYkMkqnU.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-TvRJ2tGX.js → cytoscape.esm-DqlHsaog.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-CRZydyG6.js → defaultLocale-Beh6XjaL.js} +0 -0
- /package/payload/server/public/assets/{dist-B0CkUodR.js → dist-BMqkacmt.js} +0 -0
- /package/payload/server/public/assets/{init-B8gtcn7T.js → init-Rr1s_RiX.js} +0 -0
- /package/payload/server/public/assets/{katex-RxgSu_dy.js → katex-pVJiI_rc.js} +0 -0
- /package/payload/server/public/assets/{path-DZF-JdEe.js → path-BAQ3hXlG.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-CQ36nxok.js → preload-helper-B_l5jfgx.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-6CnTHTkH.js → rough.esm-nHaDi0Kw.js} +0 -0
- /package/payload/server/public/assets/{src-CR_MU8uy.js → src-CsEKjNXD.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
embed,
|
|
42
42
|
emitMissingOnResolve,
|
|
43
43
|
ensureConversation,
|
|
44
|
+
fetchAccountName,
|
|
44
45
|
fetchBranding,
|
|
45
46
|
findMissingPlugins,
|
|
46
47
|
findRecentConversation,
|
|
@@ -71,7 +72,6 @@ import {
|
|
|
71
72
|
loadAdminUserName,
|
|
72
73
|
loadPersonNameByElementId,
|
|
73
74
|
loadUserProfile,
|
|
74
|
-
loadWhatsappSenderName,
|
|
75
75
|
migrateLegacyRemotePassword,
|
|
76
76
|
persistMessage,
|
|
77
77
|
projectAgent,
|
|
@@ -109,7 +109,7 @@ import {
|
|
|
109
109
|
vncLog,
|
|
110
110
|
walkPremiumBundles,
|
|
111
111
|
writeAdminUserAndPerson
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-ZYS5V5QG.js";
|
|
113
113
|
import {
|
|
114
114
|
__commonJS,
|
|
115
115
|
__toESM
|
|
@@ -1868,6 +1868,24 @@ function readSelfId(authDir) {
|
|
|
1868
1868
|
return { e164: null, jid: null, lid: null };
|
|
1869
1869
|
}
|
|
1870
1870
|
}
|
|
1871
|
+
function credsCensus(authDir) {
|
|
1872
|
+
const raw = readCredsJsonRaw(resolveCredsPath(authDir));
|
|
1873
|
+
if (!raw) return { credsPresent: false, registered: false, hasAccountSignature: false, e164: null };
|
|
1874
|
+
try {
|
|
1875
|
+
const parsed = JSON.parse(raw);
|
|
1876
|
+
const registered = parsed?.registered === true;
|
|
1877
|
+
const hasAccountSignature = parsed?.account != null;
|
|
1878
|
+
let e164 = null;
|
|
1879
|
+
const jid = parsed?.me?.id;
|
|
1880
|
+
if (jid) {
|
|
1881
|
+
const match = jid.match(/^(\d+)(?::\d+)?@s\.whatsapp\.net$/i);
|
|
1882
|
+
if (match) e164 = match[1];
|
|
1883
|
+
}
|
|
1884
|
+
return { credsPresent: true, registered, hasAccountSignature, e164 };
|
|
1885
|
+
} catch {
|
|
1886
|
+
return { credsPresent: true, registered: false, hasAccountSignature: false, e164: null };
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1871
1889
|
async function clearAuth(authDir) {
|
|
1872
1890
|
try {
|
|
1873
1891
|
await fs.access(authDir);
|
|
@@ -2026,13 +2044,22 @@ function enqueueSaveCreds(authDir, saveCreds) {
|
|
|
2026
2044
|
});
|
|
2027
2045
|
}
|
|
2028
2046
|
async function createWaSocket(opts) {
|
|
2029
|
-
const { authDir, onQr, onConnectionUpdate, silent } = opts;
|
|
2047
|
+
const { authDir, onQr, onConnectionUpdate, silent, correlationId, account, getCodeIssuedTs } = opts;
|
|
2048
|
+
const cid = correlationId ?? "none";
|
|
2049
|
+
const acct = account ?? "unknown";
|
|
2030
2050
|
await fs2.mkdir(authDir, { recursive: true });
|
|
2031
2051
|
maybeRestoreCredsFromBackup(authDir);
|
|
2032
2052
|
const { state, saveCreds } = await useMultiFileAuthState(authDir);
|
|
2033
2053
|
const { version } = await fetchLatestBaileysVersion();
|
|
2054
|
+
if (!silent) {
|
|
2055
|
+
const preCensus = credsCensus(authDir);
|
|
2056
|
+
console.error(
|
|
2057
|
+
`${TAG2} op=creds-pre cid=${cid} account=${acct} credsPresent=${preCensus.credsPresent} registered=${preCensus.registered} hasAccount=${preCensus.hasAccountSignature}`
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
const openTs = Date.now();
|
|
2034
2061
|
console.error(
|
|
2035
|
-
`${TAG2}
|
|
2062
|
+
`${TAG2} op=socket-open cid=${cid} account=${acct} baileysVersion=${baileysPkgVersion} waProtocolVersion=${version.join(".")} openTs=${openTs}`
|
|
2036
2063
|
);
|
|
2037
2064
|
const baileysLogger = createBaileysLogger();
|
|
2038
2065
|
const sock = makeWASocket({
|
|
@@ -2053,6 +2080,9 @@ async function createWaSocket(opts) {
|
|
|
2053
2080
|
enqueueSaveCreds(authDir, saveCreds);
|
|
2054
2081
|
});
|
|
2055
2082
|
let qrSequence = 0;
|
|
2083
|
+
let everOpen = false;
|
|
2084
|
+
let lastQrTs = 0;
|
|
2085
|
+
let pairSuccessLogged = false;
|
|
2056
2086
|
sock.ev.on("connection.update", (update) => {
|
|
2057
2087
|
try {
|
|
2058
2088
|
const parts = [];
|
|
@@ -2068,17 +2098,40 @@ async function createWaSocket(opts) {
|
|
|
2068
2098
|
if (!silent && parts.length > 0) {
|
|
2069
2099
|
console.error(`${TAG2} connection.update ${parts.join(" ")}`);
|
|
2070
2100
|
}
|
|
2101
|
+
if (update.qr && !silent) {
|
|
2102
|
+
const now = Date.now();
|
|
2103
|
+
const sinceLastRefMs = lastQrTs ? now - lastQrTs : null;
|
|
2104
|
+
lastQrTs = now;
|
|
2105
|
+
console.error(
|
|
2106
|
+
`${TAG2} op=qr cid=${cid} qr=#${qrSequence} sinceOpenMs=${now - openTs} sinceLastRefMs=${sinceLastRefMs ?? "n/a"}`
|
|
2107
|
+
);
|
|
2108
|
+
}
|
|
2109
|
+
if (update.isNewLogin === true && !pairSuccessLogged && !silent) {
|
|
2110
|
+
pairSuccessLogged = true;
|
|
2111
|
+
const codeIssuedTs = getCodeIssuedTs?.();
|
|
2112
|
+
const sinceCodeIssuedMs = codeIssuedTs ? Date.now() - codeIssuedTs : null;
|
|
2113
|
+
const afterCensus = credsCensus(authDir);
|
|
2114
|
+
console.error(
|
|
2115
|
+
`${TAG2} op=pair-success cid=${cid} account=${acct} sinceCodeIssuedMs=${sinceCodeIssuedMs ?? "n/a"} hasAccountAfter=${afterCensus.hasAccountSignature}`
|
|
2116
|
+
);
|
|
2117
|
+
}
|
|
2071
2118
|
if (update.qr && onQr) {
|
|
2072
2119
|
onQr(update.qr);
|
|
2073
2120
|
}
|
|
2074
2121
|
if (update.connection === "close") {
|
|
2075
2122
|
const status = getStatusCode(update.lastDisconnect?.error);
|
|
2123
|
+
if (!silent) {
|
|
2124
|
+
console.error(
|
|
2125
|
+
`${TAG2} op=close cid=${cid} account=${acct} status=${status ?? "unknown"} reason="${formatError(update.lastDisconnect?.error)}" socketLifeMs=${Date.now() - openTs} kind=${closeKind(status, everOpen)}`
|
|
2126
|
+
);
|
|
2127
|
+
}
|
|
2076
2128
|
if (status === DisconnectReason.loggedOut && !silent) {
|
|
2077
2129
|
console.error(`${TAG2} session logged out (401) \u2014 re-link required`);
|
|
2078
2130
|
}
|
|
2079
2131
|
}
|
|
2080
|
-
if (update.connection === "open"
|
|
2081
|
-
|
|
2132
|
+
if (update.connection === "open") {
|
|
2133
|
+
everOpen = true;
|
|
2134
|
+
if (!silent) console.error(`${TAG2} connected`);
|
|
2082
2135
|
}
|
|
2083
2136
|
onConnectionUpdate?.(update);
|
|
2084
2137
|
} catch (err) {
|
|
@@ -2142,6 +2195,12 @@ function extractBoomDetails(err) {
|
|
|
2142
2195
|
if (!statusCode && !error && !message) return null;
|
|
2143
2196
|
return { statusCode, error, message };
|
|
2144
2197
|
}
|
|
2198
|
+
function closeKind(status, everOpen) {
|
|
2199
|
+
if (status === DisconnectReason.restartRequired) return "restart-required-515";
|
|
2200
|
+
if (status === DisconnectReason.loggedOut) return "logged-out-401";
|
|
2201
|
+
if (status === 408) return everOpen ? "conn-lost-408" : "qr-refs-ended-408";
|
|
2202
|
+
return "other";
|
|
2203
|
+
}
|
|
2145
2204
|
|
|
2146
2205
|
// app/lib/whatsapp/reconnect.ts
|
|
2147
2206
|
import { DisconnectReason as DisconnectReason2 } from "@whiskeysockets/baileys";
|
|
@@ -3101,6 +3160,9 @@ var STORE_ROOT = () => join3(process.env.MAXY_DIR_OVERRIDE ?? MAXY_DIR, "data",
|
|
|
3101
3160
|
function conversationFile(platformAccountId, remoteJid) {
|
|
3102
3161
|
return join3(STORE_ROOT(), platformAccountId, `${remoteJid}.jsonl`);
|
|
3103
3162
|
}
|
|
3163
|
+
function conversationFilePath(platformAccountId, remoteJid) {
|
|
3164
|
+
return conversationFile(platformAccountId, remoteJid);
|
|
3165
|
+
}
|
|
3104
3166
|
function parseLines(raw) {
|
|
3105
3167
|
const out = [];
|
|
3106
3168
|
for (const line of raw.split("\n")) {
|
|
@@ -6054,6 +6116,13 @@ async function runPostPairing(login) {
|
|
|
6054
6116
|
}
|
|
6055
6117
|
async function loginConnectionLoop(accountId, login) {
|
|
6056
6118
|
let attempt = 0;
|
|
6119
|
+
const cidShort = login.id.slice(0, 8);
|
|
6120
|
+
const logTerminal = (outcome, errMsg) => {
|
|
6121
|
+
const fc = credsCensus(login.authDir);
|
|
6122
|
+
console.error(
|
|
6123
|
+
`${TAG17} op=terminal cid=${cidShort} outcome=${outcome} credsFinal={registered=${fc.registered},account=${fc.hasAccountSignature},me=${fc.e164 ?? "null"}}` + (errMsg ? ` error="${errMsg}"` : "")
|
|
6124
|
+
);
|
|
6125
|
+
};
|
|
6057
6126
|
while (true) {
|
|
6058
6127
|
try {
|
|
6059
6128
|
await waitForConnection(login.sock);
|
|
@@ -6062,6 +6131,7 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
6062
6131
|
await runPostPairing(current);
|
|
6063
6132
|
current.connected = true;
|
|
6064
6133
|
console.error(`${TAG17} loginConnectionLoop: connected account=${accountId} attempt=${attempt} configPersisted=${current.configPersisted}`);
|
|
6134
|
+
logTerminal("connected");
|
|
6065
6135
|
}
|
|
6066
6136
|
return;
|
|
6067
6137
|
} catch (err) {
|
|
@@ -6078,6 +6148,7 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
6078
6148
|
current.error = formatError(err);
|
|
6079
6149
|
}
|
|
6080
6150
|
current.errorStatus = getStatusCode(err);
|
|
6151
|
+
logTerminal("error", current.error);
|
|
6081
6152
|
return;
|
|
6082
6153
|
}
|
|
6083
6154
|
attempt++;
|
|
@@ -6089,14 +6160,19 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
6089
6160
|
await new Promise((r) => setTimeout(r, delay));
|
|
6090
6161
|
const afterDelay = activeLogins.get(accountId);
|
|
6091
6162
|
if (afterDelay?.id !== login.id) return;
|
|
6163
|
+
const rc = credsCensus(login.authDir);
|
|
6164
|
+
console.error(
|
|
6165
|
+
`${TAG17} op=reconnect cid=${cidShort} attempt=${attempt}/${LOGIN_MAX_RECONNECTS} withRegistered=${rc.registered} withAccount=${rc.hasAccountSignature}`
|
|
6166
|
+
);
|
|
6092
6167
|
try {
|
|
6093
|
-
const newSock = await createWaSocket({ authDir: login.authDir });
|
|
6168
|
+
const newSock = await createWaSocket({ authDir: login.authDir, correlationId: cidShort, account: accountId });
|
|
6094
6169
|
current.sock = newSock;
|
|
6095
6170
|
} catch (sockErr) {
|
|
6096
6171
|
console.error(
|
|
6097
6172
|
`${TAG17} reconnect socket creation failed (attempt ${attempt}/${LOGIN_MAX_RECONNECTS}): ${String(sockErr)}`
|
|
6098
6173
|
);
|
|
6099
6174
|
current.error = `Reconnection failed: ${String(sockErr)}`;
|
|
6175
|
+
logTerminal("error", current.error);
|
|
6100
6176
|
return;
|
|
6101
6177
|
}
|
|
6102
6178
|
}
|
|
@@ -6104,11 +6180,13 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
6104
6180
|
}
|
|
6105
6181
|
async function startLogin(opts) {
|
|
6106
6182
|
const { accountId, authDir, phone, accountDir = null, force, timeoutMs = 3e4 } = opts;
|
|
6183
|
+
const loginId = randomUUID6();
|
|
6184
|
+
const cid = loginId.slice(0, 8);
|
|
6107
6185
|
const existing0 = activeLogins.get(accountId);
|
|
6108
6186
|
const hasAuth = await authExists(authDir);
|
|
6109
6187
|
const selfId = readSelfId(authDir);
|
|
6110
6188
|
console.error(
|
|
6111
|
-
`${TAG17}
|
|
6189
|
+
`${TAG17} op=start cid=${cid} account=${accountId} force=${!!force} hasAuth=${hasAuth}` + (existing0 ? ` activeLogin={id=${existing0.id.slice(0, 8)},age=${Math.round((Date.now() - existing0.startedAt) / 1e3)}s,hasCode=${!!existing0.pairingCode}}` : " activeLogin=none")
|
|
6112
6190
|
);
|
|
6113
6191
|
if (hasAuth && !force) {
|
|
6114
6192
|
const who = selfId.e164 ?? selfId.jid ?? "unknown";
|
|
@@ -6147,21 +6225,32 @@ async function startLogin(opts) {
|
|
|
6147
6225
|
);
|
|
6148
6226
|
let requested = false;
|
|
6149
6227
|
let sock;
|
|
6228
|
+
let socketOpenTs = 0;
|
|
6229
|
+
let codeIssuedTs;
|
|
6150
6230
|
try {
|
|
6151
6231
|
sock = await createWaSocket({
|
|
6152
6232
|
authDir,
|
|
6233
|
+
correlationId: cid,
|
|
6234
|
+
account: accountId,
|
|
6235
|
+
getCodeIssuedTs: () => codeIssuedTs,
|
|
6153
6236
|
// The first QR event means the noise handshake is complete and the
|
|
6154
6237
|
// socket can send the pairing IQ — the safe moment to request the code.
|
|
6155
6238
|
// We never render the QR; it is only a readiness signal.
|
|
6156
6239
|
onQr: () => {
|
|
6157
6240
|
if (requested) return;
|
|
6158
6241
|
requested = true;
|
|
6242
|
+
console.error(
|
|
6243
|
+
`${TAG17} op=pairing-request cid=${cid} account=${accountId} qrRef=#1 sinceOpenMs=${socketOpenTs ? Date.now() - socketOpenTs : 0}`
|
|
6244
|
+
);
|
|
6159
6245
|
void sock.requestPairingCode(digits).then((code) => {
|
|
6160
6246
|
clearTimeout(codeTimer);
|
|
6247
|
+
codeIssuedTs = Date.now();
|
|
6161
6248
|
const current = activeLogins.get(accountId);
|
|
6162
6249
|
if (current?.id !== login.id) return;
|
|
6163
6250
|
if (!current.pairingCode) current.pairingCode = code;
|
|
6164
|
-
console.error(
|
|
6251
|
+
console.error(
|
|
6252
|
+
`${TAG17} op=code-issued cid=${cid} account=${accountId} phone=${maskPhone(digits)} codeLen=${code.length} sinceOpenMs=${socketOpenTs ? codeIssuedTs - socketOpenTs : 0}`
|
|
6253
|
+
);
|
|
6165
6254
|
resolveCode?.(code);
|
|
6166
6255
|
}).catch((err) => {
|
|
6167
6256
|
clearTimeout(codeTimer);
|
|
@@ -6169,6 +6258,7 @@ async function startLogin(opts) {
|
|
|
6169
6258
|
});
|
|
6170
6259
|
}
|
|
6171
6260
|
});
|
|
6261
|
+
socketOpenTs = Date.now();
|
|
6172
6262
|
} catch (err) {
|
|
6173
6263
|
clearTimeout(codeTimer);
|
|
6174
6264
|
resetActiveLogin(accountId);
|
|
@@ -6178,7 +6268,7 @@ async function startLogin(opts) {
|
|
|
6178
6268
|
accountId,
|
|
6179
6269
|
authDir,
|
|
6180
6270
|
accountDir,
|
|
6181
|
-
id:
|
|
6271
|
+
id: loginId,
|
|
6182
6272
|
sock,
|
|
6183
6273
|
startedAt: Date.now(),
|
|
6184
6274
|
phone: digits,
|
|
@@ -6473,6 +6563,10 @@ function reconcileCredsOnDisk(opts) {
|
|
|
6473
6563
|
for (const accountId of listCredsAccountIds(credsRoot)) {
|
|
6474
6564
|
if (liveAccountIds.has(accountId)) continue;
|
|
6475
6565
|
const authDir = join9(credsRoot, accountId);
|
|
6566
|
+
const census = credsCensus(authDir);
|
|
6567
|
+
if (census.registered && !census.hasAccountSignature) {
|
|
6568
|
+
console.error(`${TAG19} op=half-registered account=${accountId} registered=true hasAccount=false`);
|
|
6569
|
+
}
|
|
6476
6570
|
const selfPhone = readSelfId(authDir).e164 ?? void 0;
|
|
6477
6571
|
const configured = accountDir ? isAccountConfigured(accountDir, accountId) : false;
|
|
6478
6572
|
console.error(
|
|
@@ -6946,9 +7040,39 @@ function selectReaderChannelSessions(rows) {
|
|
|
6946
7040
|
lastMessageAt: r.lastMessageAt,
|
|
6947
7041
|
modelGated: r.modelGated,
|
|
6948
7042
|
model: r.model,
|
|
6949
|
-
|
|
7043
|
+
source: "session"
|
|
6950
7044
|
}));
|
|
6951
7045
|
}
|
|
7046
|
+
function buildStoreConversationRows(accountId, convos) {
|
|
7047
|
+
const rows = [];
|
|
7048
|
+
for (const [remoteJid, messages] of convos) {
|
|
7049
|
+
if (messages.length === 0) continue;
|
|
7050
|
+
const last = messages[messages.length - 1];
|
|
7051
|
+
const scope = last.scope;
|
|
7052
|
+
const isGroup = remoteJid.endsWith("@g.us");
|
|
7053
|
+
const senderTelephone = isGroup ? null : messages[0].senderTelephone;
|
|
7054
|
+
const senderName = messages.find((m) => m.senderName)?.senderName ?? null;
|
|
7055
|
+
rows.push({
|
|
7056
|
+
sessionId: "",
|
|
7057
|
+
projectDir: "",
|
|
7058
|
+
title: remoteJid,
|
|
7059
|
+
senderId: senderTelephone,
|
|
7060
|
+
startedAt: messages[0].dateSent,
|
|
7061
|
+
channel: "whatsapp",
|
|
7062
|
+
role: scope === "admin" ? "admin" : "public",
|
|
7063
|
+
operatorName: null,
|
|
7064
|
+
whatsappName: senderName,
|
|
7065
|
+
lastMessageAt: last.dateSent,
|
|
7066
|
+
modelGated: false,
|
|
7067
|
+
model: null,
|
|
7068
|
+
source: "store",
|
|
7069
|
+
accountId,
|
|
7070
|
+
remoteJid,
|
|
7071
|
+
scope
|
|
7072
|
+
});
|
|
7073
|
+
}
|
|
7074
|
+
return rows.sort((a, b) => (b.lastMessageAt ?? "").localeCompare(a.lastMessageAt ?? ""));
|
|
7075
|
+
}
|
|
6952
7076
|
|
|
6953
7077
|
// server/routes/admin/sidebar-sessions.ts
|
|
6954
7078
|
var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/i;
|
|
@@ -7743,7 +7867,7 @@ app4.get("/conversations", requireAdminSession, async (c) => {
|
|
|
7743
7867
|
model: lastAssistantModel(body)
|
|
7744
7868
|
});
|
|
7745
7869
|
}
|
|
7746
|
-
const
|
|
7870
|
+
const sessionRows = selectReaderChannelSessions(rows).filter((r) => r.channel !== "whatsapp");
|
|
7747
7871
|
const account = resolveAccount();
|
|
7748
7872
|
let users = [];
|
|
7749
7873
|
if (account) {
|
|
@@ -7756,13 +7880,11 @@ app4.get("/conversations", requireAdminSession, async (c) => {
|
|
|
7756
7880
|
}
|
|
7757
7881
|
const admins = account?.config.admins ?? [];
|
|
7758
7882
|
const nameBySender = /* @__PURE__ */ new Map();
|
|
7759
|
-
const
|
|
7760
|
-
const distinct = [...new Set(selected.map((r) => r.senderId).filter((s) => !!s))];
|
|
7883
|
+
const distinct = [...new Set(sessionRows.map((r) => r.senderId).filter((s) => !!s))];
|
|
7761
7884
|
await Promise.all(
|
|
7762
7885
|
distinct.map(async (senderId) => {
|
|
7763
7886
|
if (!account) {
|
|
7764
7887
|
nameBySender.set(senderId, null);
|
|
7765
|
-
whatsappNameBySender.set(senderId, null);
|
|
7766
7888
|
return;
|
|
7767
7889
|
}
|
|
7768
7890
|
const idRes = classifyAdminUserId(users, admins, senderId);
|
|
@@ -7770,57 +7892,19 @@ app4.get("/conversations", requireAdminSession, async (c) => {
|
|
|
7770
7892
|
const { name, reason } = resolveOperatorDisplay(idRes, nameRes);
|
|
7771
7893
|
if (reason) console.error(`[wa-reader] op=operator-unresolved senderId=${senderId} reason=${reason}`);
|
|
7772
7894
|
nameBySender.set(senderId, name);
|
|
7773
|
-
if (!name) {
|
|
7774
|
-
const waName = await loadWhatsappSenderName(account.accountId, senderId);
|
|
7775
|
-
if (waName) console.error(`[wa-reader] op=operator-name-fallback senderId=${senderId} source=whatsapp-pushname`);
|
|
7776
|
-
whatsappNameBySender.set(senderId, waName);
|
|
7777
|
-
} else {
|
|
7778
|
-
whatsappNameBySender.set(senderId, null);
|
|
7779
|
-
}
|
|
7780
7895
|
})
|
|
7781
7896
|
);
|
|
7782
|
-
const
|
|
7897
|
+
const sessionConversations = sessionRows.map((r) => ({
|
|
7783
7898
|
...r,
|
|
7784
|
-
operatorName: r.senderId ? nameBySender.get(r.senderId) ?? null : null
|
|
7785
|
-
whatsappName: r.senderId ? whatsappNameBySender.get(r.senderId) ?? null : null,
|
|
7786
|
-
rowType: "session"
|
|
7899
|
+
operatorName: r.senderId ? nameBySender.get(r.senderId) ?? null : null
|
|
7787
7900
|
}));
|
|
7788
|
-
const
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
for (const [remoteJid, messages] of allConvos) {
|
|
7796
|
-
if (messages.length === 0) continue;
|
|
7797
|
-
const isGroup = remoteJid.endsWith("@g.us");
|
|
7798
|
-
const senderTelephone = isGroup ? null : messages[0].senderTelephone;
|
|
7799
|
-
if (!isGroup && senderTelephone && coveredSenderIds.has(senderTelephone)) continue;
|
|
7800
|
-
const last = messages[messages.length - 1];
|
|
7801
|
-
const resolvedName = isGroup ? null : messages.find((m) => m.senderName)?.senderName ?? null;
|
|
7802
|
-
persistedOnlyRows.push({
|
|
7803
|
-
sessionId: `persisted:${account.accountId}:${remoteJid}`,
|
|
7804
|
-
projectDir: "",
|
|
7805
|
-
title: remoteJid,
|
|
7806
|
-
senderId: senderTelephone,
|
|
7807
|
-
startedAt: messages[0].dateSent,
|
|
7808
|
-
channel: "whatsapp",
|
|
7809
|
-
role: "public",
|
|
7810
|
-
operatorName: null,
|
|
7811
|
-
whatsappName: resolvedName,
|
|
7812
|
-
lastMessageAt: last.dateSent,
|
|
7813
|
-
modelGated: false,
|
|
7814
|
-
model: null,
|
|
7815
|
-
rowType: "persisted-only",
|
|
7816
|
-
accountId: account.accountId,
|
|
7817
|
-
remoteJid
|
|
7818
|
-
});
|
|
7819
|
-
}
|
|
7820
|
-
}
|
|
7821
|
-
const allRows = [...conversations, ...persistedOnlyRows];
|
|
7822
|
-
console.log(`[wa-reader] op=full-list accountId=${account?.accountId ?? "null"} sessionRows=${conversations.length} persistedOnlyRows=${persistedOnlyRows.length}`);
|
|
7823
|
-
return c.json({ conversations: allRows });
|
|
7901
|
+
const storeRows = account ? buildStoreConversationRows(account.accountId, readAllConversations(account.accountId)) : [];
|
|
7902
|
+
const adminScope = storeRows.filter((r) => r.scope === "admin").length;
|
|
7903
|
+
const publicScope = storeRows.length - adminScope;
|
|
7904
|
+
console.log(
|
|
7905
|
+
`[wa-reader] op=list accountId=${account?.accountId ?? "null"} conversations=${storeRows.length} adminScope=${adminScope} publicScope=${publicScope}`
|
|
7906
|
+
);
|
|
7907
|
+
return c.json({ conversations: [...sessionConversations, ...storeRows] });
|
|
7824
7908
|
});
|
|
7825
7909
|
function readFrom(path2, from) {
|
|
7826
7910
|
const end = statSync4(path2).size;
|
|
@@ -8160,7 +8244,7 @@ app4.get("/directive", requireAdminSession, (c) => {
|
|
|
8160
8244
|
}
|
|
8161
8245
|
return c.text(body);
|
|
8162
8246
|
});
|
|
8163
|
-
app4.get("/
|
|
8247
|
+
app4.get("/store-stream", requireAdminSession, (c) => {
|
|
8164
8248
|
const accountIdRaw = c.req.query("accountId");
|
|
8165
8249
|
const remoteJid = c.req.query("remoteJid");
|
|
8166
8250
|
if (!accountIdRaw || !remoteJid) {
|
|
@@ -8175,16 +8259,108 @@ app4.get("/persisted-messages", requireAdminSession, async (c) => {
|
|
|
8175
8259
|
if (!isUserJid(remoteJid) && !isGroupJid(remoteJid)) {
|
|
8176
8260
|
return c.json({ error: "invalid remoteJid" }, 400);
|
|
8177
8261
|
}
|
|
8178
|
-
const
|
|
8179
|
-
const
|
|
8262
|
+
const file = conversationFilePath(accountId, remoteJid);
|
|
8263
|
+
const encoder = new TextEncoder();
|
|
8264
|
+
const connId = `${remoteJid.slice(0, 12)}-${process.hrtime.bigint().toString(36).slice(-6)}`;
|
|
8265
|
+
const startedAt = Date.now();
|
|
8266
|
+
const lastEventId = c.req.header("Last-Event-ID");
|
|
8267
|
+
const toTurn = (r) => ({
|
|
8180
8268
|
kind: "whatsapp-persisted",
|
|
8181
|
-
text:
|
|
8182
|
-
ts:
|
|
8183
|
-
fromMe:
|
|
8184
|
-
senderName:
|
|
8185
|
-
})
|
|
8186
|
-
|
|
8187
|
-
|
|
8269
|
+
text: r.body,
|
|
8270
|
+
ts: r.dateSent,
|
|
8271
|
+
fromMe: r.fromMe,
|
|
8272
|
+
senderName: r.senderName
|
|
8273
|
+
});
|
|
8274
|
+
const readable = new ReadableStream({
|
|
8275
|
+
start(controller) {
|
|
8276
|
+
const send = (turn, id) => {
|
|
8277
|
+
try {
|
|
8278
|
+
controller.enqueue(encoder.encode(`id: ${id}
|
|
8279
|
+
data: ${JSON.stringify(turn)}
|
|
8280
|
+
|
|
8281
|
+
`));
|
|
8282
|
+
} catch {
|
|
8283
|
+
}
|
|
8284
|
+
};
|
|
8285
|
+
const fileEnd0 = (() => {
|
|
8286
|
+
try {
|
|
8287
|
+
return statSync4(file).size;
|
|
8288
|
+
} catch {
|
|
8289
|
+
return 0;
|
|
8290
|
+
}
|
|
8291
|
+
})();
|
|
8292
|
+
let offset = resumeOffset(lastEventId, fileEnd0);
|
|
8293
|
+
if (offset === 0) {
|
|
8294
|
+
const records = [];
|
|
8295
|
+
try {
|
|
8296
|
+
const { buf, end } = readFrom(file, 0);
|
|
8297
|
+
offset = end;
|
|
8298
|
+
for (const line of buf.toString("utf8").split("\n")) {
|
|
8299
|
+
if (!line.trim()) continue;
|
|
8300
|
+
try {
|
|
8301
|
+
records.push(JSON.parse(line));
|
|
8302
|
+
} catch {
|
|
8303
|
+
}
|
|
8304
|
+
}
|
|
8305
|
+
} catch {
|
|
8306
|
+
offset = fileEnd0;
|
|
8307
|
+
}
|
|
8308
|
+
records.sort((a, b) => a.dateSent.localeCompare(b.dateSent));
|
|
8309
|
+
const scope = records.length ? records[records.length - 1].scope : "none";
|
|
8310
|
+
for (const m of records) send(toTurn(m), offset);
|
|
8311
|
+
console.log(
|
|
8312
|
+
`[wa-reader] op=open remoteJid=${remoteJid} scope=${scope} messages=${records.length} source=store`
|
|
8313
|
+
);
|
|
8314
|
+
}
|
|
8315
|
+
const drain = () => {
|
|
8316
|
+
try {
|
|
8317
|
+
const { buf, end } = readFrom(file, offset);
|
|
8318
|
+
if (end <= offset) return;
|
|
8319
|
+
const { lines, nextOffset } = splitNewLines(buf, offset);
|
|
8320
|
+
offset = nextOffset;
|
|
8321
|
+
let n = 0;
|
|
8322
|
+
for (const line of lines) {
|
|
8323
|
+
if (!line.trim()) continue;
|
|
8324
|
+
let rec;
|
|
8325
|
+
try {
|
|
8326
|
+
rec = JSON.parse(line);
|
|
8327
|
+
} catch {
|
|
8328
|
+
continue;
|
|
8329
|
+
}
|
|
8330
|
+
send(toTurn(rec), offset);
|
|
8331
|
+
n++;
|
|
8332
|
+
}
|
|
8333
|
+
if (n > 0) console.log(`[wa-reader] op=store-drain conn=${connId} turns=${n}`);
|
|
8334
|
+
} catch {
|
|
8335
|
+
}
|
|
8336
|
+
};
|
|
8337
|
+
let watcher = null;
|
|
8338
|
+
try {
|
|
8339
|
+
watcher = watch(file, drain);
|
|
8340
|
+
} catch {
|
|
8341
|
+
}
|
|
8342
|
+
const poll = setInterval(drain, 1e3);
|
|
8343
|
+
const heartbeat = setInterval(() => {
|
|
8344
|
+
try {
|
|
8345
|
+
controller.enqueue(encoder.encode(": ping\n\n"));
|
|
8346
|
+
} catch {
|
|
8347
|
+
}
|
|
8348
|
+
}, 2e4);
|
|
8349
|
+
c.req.raw.signal.addEventListener("abort", () => {
|
|
8350
|
+
watcher?.close();
|
|
8351
|
+
clearInterval(poll);
|
|
8352
|
+
clearInterval(heartbeat);
|
|
8353
|
+
console.log(`[wa-reader] op=store-close conn=${connId} ranMs=${Date.now() - startedAt}`);
|
|
8354
|
+
try {
|
|
8355
|
+
controller.close();
|
|
8356
|
+
} catch {
|
|
8357
|
+
}
|
|
8358
|
+
});
|
|
8359
|
+
}
|
|
8360
|
+
});
|
|
8361
|
+
return new Response(readable, {
|
|
8362
|
+
headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" }
|
|
8363
|
+
});
|
|
8188
8364
|
});
|
|
8189
8365
|
var whatsapp_reader_default = app4;
|
|
8190
8366
|
|
|
@@ -8714,9 +8890,9 @@ var WEBCHAT_ADMIN_KEY = "webchat-admin";
|
|
|
8714
8890
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
8715
8891
|
function locateSession(sessionId) {
|
|
8716
8892
|
const dir = findSessionProjectDir(sessionId);
|
|
8717
|
-
if (!dir) return { projectDir: null, channel: null };
|
|
8893
|
+
if (!dir) return { projectDir: null, channel: null, accountId: null };
|
|
8718
8894
|
const meta = readSidecarMeta(join18(dir, `${sessionId}.meta.json`));
|
|
8719
|
-
return { projectDir: dir, channel: meta.channel };
|
|
8895
|
+
return { projectDir: dir, channel: meta.channel, accountId: meta.accountId };
|
|
8720
8896
|
}
|
|
8721
8897
|
function locateSidecar(sessionId) {
|
|
8722
8898
|
const cfg = claudeConfigDir();
|
|
@@ -8732,7 +8908,7 @@ function locateSidecar(sessionId) {
|
|
|
8732
8908
|
const metaPath = join18(projectsRoot, slug, `${sessionId}.meta.json`);
|
|
8733
8909
|
if (existsSync10(metaPath)) {
|
|
8734
8910
|
const meta = readSidecarMeta(metaPath);
|
|
8735
|
-
return { channel: meta.channel, adminUserId: meta.adminUserId };
|
|
8911
|
+
return { channel: meta.channel, adminUserId: meta.adminUserId, accountId: meta.accountId };
|
|
8736
8912
|
}
|
|
8737
8913
|
}
|
|
8738
8914
|
return null;
|
|
@@ -9010,6 +9186,7 @@ function createWebchatRoutes(deps) {
|
|
|
9010
9186
|
}
|
|
9011
9187
|
let deliveryKey = WEBCHAT_ADMIN_KEY;
|
|
9012
9188
|
let deliverySessionId;
|
|
9189
|
+
let deliveryAccountId = accountId;
|
|
9013
9190
|
const explicitTarget = target !== void 0;
|
|
9014
9191
|
if (target === void 0) {
|
|
9015
9192
|
const latest = latestAdminWebchatSessionId(requesterUserId, primaryUserId, scopeAccountId, multiAccount);
|
|
@@ -9022,7 +9199,7 @@ function createWebchatRoutes(deps) {
|
|
|
9022
9199
|
}
|
|
9023
9200
|
}
|
|
9024
9201
|
if (target !== void 0) {
|
|
9025
|
-
let { projectDir, channel } = locateSession(target);
|
|
9202
|
+
let { projectDir, channel, accountId: sessionAccountId } = locateSession(target);
|
|
9026
9203
|
if (projectDir === null) {
|
|
9027
9204
|
const sidecar = locateSidecar(target);
|
|
9028
9205
|
if (sidecar === null) {
|
|
@@ -9030,6 +9207,7 @@ function createWebchatRoutes(deps) {
|
|
|
9030
9207
|
return c.json({ error: "session not found" }, 404);
|
|
9031
9208
|
}
|
|
9032
9209
|
channel = sidecar.channel;
|
|
9210
|
+
sessionAccountId = sidecar.accountId;
|
|
9033
9211
|
}
|
|
9034
9212
|
const binding = conflictingBinding(channel);
|
|
9035
9213
|
if (binding !== null) {
|
|
@@ -9038,6 +9216,7 @@ function createWebchatRoutes(deps) {
|
|
|
9038
9216
|
}
|
|
9039
9217
|
deliveryKey = `session:${target}`;
|
|
9040
9218
|
deliverySessionId = target;
|
|
9219
|
+
deliveryAccountId = sessionAccountId ?? accountId;
|
|
9041
9220
|
}
|
|
9042
9221
|
if (isMultipart) {
|
|
9043
9222
|
const kind = files.some((f) => isAudioMime(f.type)) ? "voice" : "files";
|
|
@@ -9114,7 +9293,7 @@ ${note}` : note;
|
|
|
9114
9293
|
}
|
|
9115
9294
|
const adminUserId = requesterUserId ?? void 0;
|
|
9116
9295
|
if (deliverySessionId !== void 0) {
|
|
9117
|
-
await deps.handleInbound({ role: "admin", accountId, key: deliveryKey, text, sessionId: deliverySessionId, adminUserId });
|
|
9296
|
+
await deps.handleInbound({ role: "admin", accountId: deliveryAccountId, key: deliveryKey, text, sessionId: deliverySessionId, adminUserId });
|
|
9118
9297
|
} else {
|
|
9119
9298
|
await deps.handleInbound({ role: "admin", accountId: bootstrapAccountId, key: deliveryKey, text, adminUserId });
|
|
9120
9299
|
}
|
|
@@ -10443,12 +10622,7 @@ async function createAdminSession(accountId, thinkingView, userId, userName, rol
|
|
|
10443
10622
|
const cacheKey = fingerprintSessionKey(signedSessionToken);
|
|
10444
10623
|
registerSession(cacheKey, "admin", accountId, void 0, userId, userName, role);
|
|
10445
10624
|
if (userId) setWantsPriorConversation(cacheKey);
|
|
10446
|
-
|
|
10447
|
-
try {
|
|
10448
|
-
const branding = await fetchBranding(accountId);
|
|
10449
|
-
businessName = branding?.name || void 0;
|
|
10450
|
-
} catch {
|
|
10451
|
-
}
|
|
10625
|
+
const businessName = await fetchAccountName(accountId) || void 0;
|
|
10452
10626
|
let initialSessionId = null;
|
|
10453
10627
|
try {
|
|
10454
10628
|
const ensured = await ensureConversation(
|
|
@@ -10486,12 +10660,7 @@ function operatorRoleFor(config, userId) {
|
|
|
10486
10660
|
async function buildAccountOptionList(accounts, userId) {
|
|
10487
10661
|
return Promise.all(
|
|
10488
10662
|
accounts.map(async (a) => {
|
|
10489
|
-
|
|
10490
|
-
try {
|
|
10491
|
-
const branding = await fetchBranding(a.accountId);
|
|
10492
|
-
businessName = branding?.name || void 0;
|
|
10493
|
-
} catch {
|
|
10494
|
-
}
|
|
10663
|
+
const businessName = await fetchAccountName(a.accountId) || void 0;
|
|
10495
10664
|
return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId) };
|
|
10496
10665
|
})
|
|
10497
10666
|
);
|
|
@@ -10512,12 +10681,7 @@ app11.get("/", async (c) => {
|
|
|
10512
10681
|
}
|
|
10513
10682
|
const account = resolveAccount();
|
|
10514
10683
|
const thinkingView = account?.config.thinkingView ?? "default";
|
|
10515
|
-
|
|
10516
|
-
try {
|
|
10517
|
-
const branding = await fetchBranding(accountId);
|
|
10518
|
-
businessName = branding?.name || void 0;
|
|
10519
|
-
} catch {
|
|
10520
|
-
}
|
|
10684
|
+
const businessName = await fetchAccountName(accountId) || void 0;
|
|
10521
10685
|
const role = getRoleForSession(cacheKey);
|
|
10522
10686
|
console.log(`[admin-session] role=${role ?? "null"} cacheKey=${cacheKey.slice(0, 8)} phase=restore`);
|
|
10523
10687
|
const restoredUserId = getUserIdForSession(cacheKey);
|
|
@@ -16292,8 +16456,10 @@ app29.post("/", requireAdminSession, async (c) => {
|
|
|
16292
16456
|
return c.json({ error: "sessionId must be a v4 UUID" }, 400);
|
|
16293
16457
|
}
|
|
16294
16458
|
const base = managerBase("session-delete:wrapper");
|
|
16459
|
+
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
16460
|
+
const acctQuery = accountId ? `?accountId=${encodeURIComponent(accountId)}` : "";
|
|
16295
16461
|
try {
|
|
16296
|
-
const stop = await fetch(`${base}/${sessionId}/stop`, { method: "POST" });
|
|
16462
|
+
const stop = await fetch(`${base}/${sessionId}/stop${acctQuery}`, { method: "POST" });
|
|
16297
16463
|
if (stop.status !== 204 && stop.status !== 200 && stop.status !== 404) {
|
|
16298
16464
|
console.error(`[session-delete] sessionId=${sessionId} stop-status=${stop.status}`);
|
|
16299
16465
|
return c.json({ error: `stop-failed-${stop.status}` }, 502);
|
|
@@ -16304,7 +16470,7 @@ app29.post("/", requireAdminSession, async (c) => {
|
|
|
16304
16470
|
}
|
|
16305
16471
|
let del;
|
|
16306
16472
|
try {
|
|
16307
|
-
del = await fetch(`${base}/${sessionId}`, { method: "DELETE" });
|
|
16473
|
+
del = await fetch(`${base}/${sessionId}${acctQuery}`, { method: "DELETE" });
|
|
16308
16474
|
} catch (err) {
|
|
16309
16475
|
console.error(`[session-delete] sessionId=${sessionId} delete-unreachable err=${err instanceof Error ? err.message : String(err)}`);
|
|
16310
16476
|
return c.json({ error: "manager-unreachable" }, 502);
|
|
@@ -16333,9 +16499,11 @@ app30.post("/", requireAdminSession, async (c) => {
|
|
|
16333
16499
|
if (!SESSION_ID_RE2.test(sessionId)) {
|
|
16334
16500
|
return c.json({ error: "sessionId must be a v4 UUID" }, 400);
|
|
16335
16501
|
}
|
|
16502
|
+
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
16503
|
+
const acctQuery = accountId ? `?accountId=${encodeURIComponent(accountId)}` : "";
|
|
16336
16504
|
let res;
|
|
16337
16505
|
try {
|
|
16338
|
-
res = await fetch(`${managerBase("session-stop:wrapper")}/${sessionId}/stop`, { method: "POST" });
|
|
16506
|
+
res = await fetch(`${managerBase("session-stop:wrapper")}/${sessionId}/stop${acctQuery}`, { method: "POST" });
|
|
16339
16507
|
} catch (err) {
|
|
16340
16508
|
console.error(`[session-stop] sessionId=${sessionId} manager-unreachable err=${err instanceof Error ? err.message : String(err)}`);
|
|
16341
16509
|
return c.json({ error: "manager-unreachable" }, 502);
|
|
@@ -20416,6 +20584,12 @@ function buildWaSpawnRequest(input) {
|
|
|
20416
20584
|
role: input.role,
|
|
20417
20585
|
channel: "whatsapp",
|
|
20418
20586
|
personId,
|
|
20587
|
+
// Task 1325 — the account whose WhatsApp received this inbound is the
|
|
20588
|
+
// session's own account (the sessionId hashes it). Threading it as
|
|
20589
|
+
// targetAccountId makes a message-triggered resume of a client-account
|
|
20590
|
+
// session resolve under that account, not the manager's boot-time house
|
|
20591
|
+
// default (which fired for every non-webchat resume before this).
|
|
20592
|
+
targetAccountId: input.accountId,
|
|
20419
20593
|
waChannel: { senderId: input.senderId, gatewayUrl: input.gatewayUrl, serverPath: input.serverPath },
|
|
20420
20594
|
logContext: `channel=whatsapp-native role=${input.role} senderId=${input.senderId}`
|
|
20421
20595
|
};
|
|
@@ -21725,6 +21899,12 @@ function buildTelegramSpawnRequest(input) {
|
|
|
21725
21899
|
role: input.role,
|
|
21726
21900
|
channel: "telegram",
|
|
21727
21901
|
personId,
|
|
21902
|
+
// Task 1325 — the account whose Telegram bot received this inbound is the
|
|
21903
|
+
// session's own account (the sessionId hashes it). Threading it as
|
|
21904
|
+
// targetAccountId makes a message-triggered resume of a client-account
|
|
21905
|
+
// session resolve under that account, not the manager's boot-time house
|
|
21906
|
+
// default. Mirror of the WhatsApp builder.
|
|
21907
|
+
targetAccountId: input.accountId,
|
|
21728
21908
|
telegramChannel: { senderId: input.senderId, gatewayUrl: input.gatewayUrl, serverPath: input.serverPath },
|
|
21729
21909
|
logContext: `channel=telegram-native role=${input.role} senderId=${input.senderId}`
|
|
21730
21910
|
};
|
|
@@ -22503,12 +22683,14 @@ var webchatGateway = new WebchatGateway({
|
|
|
22503
22683
|
senderId: key,
|
|
22504
22684
|
adminUserId,
|
|
22505
22685
|
webchatChannel: { key, gatewayUrl, serverPath },
|
|
22506
|
-
// Task 1318 — the manager tags the spawned session's sidecar
|
|
22686
|
+
// Task 1318 / 1325 — the manager tags the spawned session's sidecar
|
|
22507
22687
|
// (meta.accountId) and scopes its ACCOUNT_DIR from this. `accountId`
|
|
22508
|
-
// here is exactly what POST /send resolved for this inbound:
|
|
22509
|
-
// an existing-session delivery
|
|
22510
|
-
//
|
|
22511
|
-
//
|
|
22688
|
+
// here is exactly what POST /send resolved for this inbound: the target
|
|
22689
|
+
// session's OWN account for an existing-session delivery (Task 1325 —
|
|
22690
|
+
// read from its sidecar, so a client-account session resumes under its
|
|
22691
|
+
// own account, never house), the viewer's scoped sub-account for a fresh
|
|
22692
|
+
// bootstrap — the same value the sessionId hash above already used, so
|
|
22693
|
+
// the two never disagree.
|
|
22512
22694
|
targetAccountId: accountId,
|
|
22513
22695
|
logContext: `channel=webchat key=${key} role=${role}`
|
|
22514
22696
|
});
|
|
@@ -23272,6 +23454,10 @@ app55.get("/graph", (c) => {
|
|
|
23272
23454
|
});
|
|
23273
23455
|
app55.get("/chat", (c) => {
|
|
23274
23456
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
23457
|
+
if (isOperatorHost(host, getOperatorDomains())) {
|
|
23458
|
+
console.log(`[host-class] host=${host} class=operator served=operator.html`);
|
|
23459
|
+
return c.html(cachedHtml("operator.html"));
|
|
23460
|
+
}
|
|
23275
23461
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
23276
23462
|
return c.html(cachedHtml("chat.html"));
|
|
23277
23463
|
});
|