@rubytech/create-realagent 1.0.643 → 1.0.646
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/lib/graph-mcp/dist/index.js +7 -1
- package/payload/platform/lib/graph-mcp/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-mcp/src/index.ts +9 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +12 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/neo4j.js +7 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/lib/neo4j.js +7 -1
- package/payload/platform/plugins/contacts/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/neo4j.js +7 -1
- package/payload/platform/plugins/email/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js +8 -1
- package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.js +7 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js +7 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +8 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/tasks/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/tasks/mcp/dist/lib/neo4j.js +7 -1
- package/payload/platform/plugins/tasks/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/lib/neo4j.js +7 -1
- package/payload/platform/plugins/waitlist/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js +4 -7
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/neo4j.js +7 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.js +7 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/src/lib/neo4j.ts +9 -1
- package/payload/server/public/assets/admin-Cahp6spj.js +352 -0
- package/payload/server/public/assets/data-B4mICUUf.js +1 -0
- package/payload/server/public/assets/{jsx-runtime-SjVUZj3J.js → jsx-runtime-BYz1l0sM.js} +3 -3
- package/payload/server/public/assets/jsx-runtime-DzyKTi89.css +1 -0
- package/payload/server/public/assets/public-DUzYc3_6.js +5 -0
- package/payload/server/public/assets/share-2-Dl0LQGkm.js +1 -0
- package/payload/server/public/assets/useVoiceRecorder-0mmp40A4.js +36 -0
- package/payload/server/public/data.html +4 -4
- package/payload/server/public/index.html +5 -5
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +774 -644
- package/payload/server/public/assets/admin-BTfeGAIg.js +0 -352
- package/payload/server/public/assets/data-DHhDRGaC.js +0 -1
- package/payload/server/public/assets/jsx-runtime-BNLXzSN4.css +0 -1
- package/payload/server/public/assets/public-C-nsHZgC.js +0 -5
- package/payload/server/public/assets/search-BzKUsdMm.js +0 -1
- package/payload/server/public/assets/useVoiceRecorder-t2l8eU6m.js +0 -36
package/payload/server/server.js
CHANGED
|
@@ -67,13 +67,13 @@ var compose = (middleware, onError, onNotFound) => {
|
|
|
67
67
|
if (handler) {
|
|
68
68
|
try {
|
|
69
69
|
res = await handler(context, () => dispatch(i + 1));
|
|
70
|
-
} catch (
|
|
71
|
-
if (
|
|
72
|
-
context.error =
|
|
73
|
-
res = await onError(
|
|
70
|
+
} catch (err) {
|
|
71
|
+
if (err instanceof Error && onError) {
|
|
72
|
+
context.error = err;
|
|
73
|
+
res = await onError(err, context);
|
|
74
74
|
isError = true;
|
|
75
75
|
} else {
|
|
76
|
-
throw
|
|
76
|
+
throw err;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
} else {
|
|
@@ -1100,12 +1100,12 @@ var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
|
|
|
1100
1100
|
var notFoundHandler = (c) => {
|
|
1101
1101
|
return c.text("404 Not Found", 404);
|
|
1102
1102
|
};
|
|
1103
|
-
var errorHandler = (
|
|
1104
|
-
if ("getResponse" in
|
|
1105
|
-
const res =
|
|
1103
|
+
var errorHandler = (err, c) => {
|
|
1104
|
+
if ("getResponse" in err) {
|
|
1105
|
+
const res = err.getResponse();
|
|
1106
1106
|
return c.newResponse(res.body, res);
|
|
1107
1107
|
}
|
|
1108
|
-
console.error(
|
|
1108
|
+
console.error(err);
|
|
1109
1109
|
return c.text("Internal Server Error", 500);
|
|
1110
1110
|
};
|
|
1111
1111
|
var Hono = class _Hono {
|
|
@@ -1356,11 +1356,11 @@ var Hono = class _Hono {
|
|
|
1356
1356
|
this.router.add(method, path2, [handler, r]);
|
|
1357
1357
|
this.routes.push(r);
|
|
1358
1358
|
}
|
|
1359
|
-
#handleError(
|
|
1360
|
-
if (
|
|
1361
|
-
return this.errorHandler(
|
|
1359
|
+
#handleError(err, c) {
|
|
1360
|
+
if (err instanceof Error) {
|
|
1361
|
+
return this.errorHandler(err, c);
|
|
1362
1362
|
}
|
|
1363
|
-
throw
|
|
1363
|
+
throw err;
|
|
1364
1364
|
}
|
|
1365
1365
|
#dispatch(request, executionCtx, env, method) {
|
|
1366
1366
|
if (method === "HEAD") {
|
|
@@ -1381,12 +1381,12 @@ var Hono = class _Hono {
|
|
|
1381
1381
|
res = matchResult[0][0][0][0](c, async () => {
|
|
1382
1382
|
c.res = await this.#notFoundHandler(c);
|
|
1383
1383
|
});
|
|
1384
|
-
} catch (
|
|
1385
|
-
return this.#handleError(
|
|
1384
|
+
} catch (err) {
|
|
1385
|
+
return this.#handleError(err, c);
|
|
1386
1386
|
}
|
|
1387
1387
|
return res instanceof Promise ? res.then(
|
|
1388
1388
|
(resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))
|
|
1389
|
-
).catch((
|
|
1389
|
+
).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);
|
|
1390
1390
|
}
|
|
1391
1391
|
const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
|
|
1392
1392
|
return (async () => {
|
|
@@ -1398,8 +1398,8 @@ var Hono = class _Hono {
|
|
|
1398
1398
|
);
|
|
1399
1399
|
}
|
|
1400
1400
|
return context.res;
|
|
1401
|
-
} catch (
|
|
1402
|
-
return this.#handleError(
|
|
1401
|
+
} catch (err) {
|
|
1402
|
+
return this.#handleError(err, c);
|
|
1403
1403
|
}
|
|
1404
1404
|
})();
|
|
1405
1405
|
}
|
|
@@ -2430,16 +2430,16 @@ var handleFetchError = (e) => new Response(null, {
|
|
|
2430
2430
|
status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500
|
|
2431
2431
|
});
|
|
2432
2432
|
var handleResponseError = (e, outgoing) => {
|
|
2433
|
-
const
|
|
2434
|
-
if (
|
|
2433
|
+
const err = e instanceof Error ? e : new Error("unknown error", { cause: e });
|
|
2434
|
+
if (err.code === "ERR_STREAM_PREMATURE_CLOSE") {
|
|
2435
2435
|
console.info("The user aborted a request.");
|
|
2436
2436
|
} else {
|
|
2437
2437
|
console.error(e);
|
|
2438
2438
|
if (!outgoing.headersSent) {
|
|
2439
2439
|
outgoing.writeHead(500, { "Content-Type": "text/plain" });
|
|
2440
2440
|
}
|
|
2441
|
-
outgoing.end(`Error: ${
|
|
2442
|
-
outgoing.destroy(
|
|
2441
|
+
outgoing.end(`Error: ${err.message}`);
|
|
2442
|
+
outgoing.destroy(err);
|
|
2443
2443
|
}
|
|
2444
2444
|
};
|
|
2445
2445
|
var flushHeaders = (outgoing) => {
|
|
@@ -2496,8 +2496,8 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
2496
2496
|
if (options.errorHandler) {
|
|
2497
2497
|
try {
|
|
2498
2498
|
res = await res;
|
|
2499
|
-
} catch (
|
|
2500
|
-
const errRes = await options.errorHandler(
|
|
2499
|
+
} catch (err) {
|
|
2500
|
+
const errRes = await options.errorHandler(err);
|
|
2501
2501
|
if (!errRes) {
|
|
2502
2502
|
return;
|
|
2503
2503
|
}
|
|
@@ -2768,8 +2768,8 @@ var createStreamBody = (stream) => {
|
|
|
2768
2768
|
stream.on("data", (chunk) => {
|
|
2769
2769
|
controller.enqueue(chunk);
|
|
2770
2770
|
});
|
|
2771
|
-
stream.on("error", (
|
|
2772
|
-
controller.error(
|
|
2771
|
+
stream.on("error", (err) => {
|
|
2772
|
+
controller.error(err);
|
|
2773
2773
|
});
|
|
2774
2774
|
stream.on("end", () => {
|
|
2775
2775
|
controller.close();
|
|
@@ -2930,8 +2930,8 @@ var CLAUDE_CREDENTIALS_FILE = resolve(homedir(), ".claude", ".credentials.json")
|
|
|
2930
2930
|
var VNC_LOG_FILE = resolve2(LOG_DIR, "vnc-boot.log");
|
|
2931
2931
|
try {
|
|
2932
2932
|
mkdirSync(LOG_DIR, { recursive: true });
|
|
2933
|
-
} catch (
|
|
2934
|
-
console.error(`[vnc-log-fail] mkdir ${LOG_DIR} failed: ${
|
|
2933
|
+
} catch (err) {
|
|
2934
|
+
console.error(`[vnc-log-fail] mkdir ${LOG_DIR} failed: ${err.message}`);
|
|
2935
2935
|
}
|
|
2936
2936
|
function vncLog(phase, fields = {}) {
|
|
2937
2937
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -2941,8 +2941,8 @@ function vncLog(phase, fields = {}) {
|
|
|
2941
2941
|
`;
|
|
2942
2942
|
try {
|
|
2943
2943
|
appendFileSync(VNC_LOG_FILE, line);
|
|
2944
|
-
} catch (
|
|
2945
|
-
console.error(`[vnc-log-fail] ${
|
|
2944
|
+
} catch (err) {
|
|
2945
|
+
console.error(`[vnc-log-fail] ${err.message} \u2014 dropped: ${line.slice(0, 300).trim()}`);
|
|
2946
2946
|
}
|
|
2947
2947
|
}
|
|
2948
2948
|
var corrCounter = 0;
|
|
@@ -2983,8 +2983,8 @@ var SCRYPT_P = 1;
|
|
|
2983
2983
|
var SCRYPT_KEYLEN = 64;
|
|
2984
2984
|
function scryptAsync(password, salt) {
|
|
2985
2985
|
return new Promise((resolve33, reject) => {
|
|
2986
|
-
scrypt(password, salt, SCRYPT_KEYLEN, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P }, (
|
|
2987
|
-
if (
|
|
2986
|
+
scrypt(password, salt, SCRYPT_KEYLEN, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P }, (err, key) => {
|
|
2987
|
+
if (err) reject(err);
|
|
2988
2988
|
else resolve33(key);
|
|
2989
2989
|
});
|
|
2990
2990
|
});
|
|
@@ -3595,11 +3595,11 @@ function attachVncWsProxy(server, opts) {
|
|
|
3595
3595
|
upstreamHost,
|
|
3596
3596
|
upstreamPort
|
|
3597
3597
|
});
|
|
3598
|
-
} catch (
|
|
3598
|
+
} catch (err) {
|
|
3599
3599
|
vncLog("ws-upgrade", {
|
|
3600
3600
|
decision: "rejected",
|
|
3601
3601
|
reason: "handler-exception",
|
|
3602
|
-
err:
|
|
3602
|
+
err: err.message
|
|
3603
3603
|
});
|
|
3604
3604
|
clientSocket.destroy();
|
|
3605
3605
|
}
|
|
@@ -3754,12 +3754,12 @@ function handleUpgrade(req, clientSocket, head, opts) {
|
|
|
3754
3754
|
upstream.once("close", (hadError) => {
|
|
3755
3755
|
finish("upstream", hadError ? "error" : "normal");
|
|
3756
3756
|
});
|
|
3757
|
-
clientSocket.once("error", (
|
|
3758
|
-
vncLog("proxy-error", { corrId, side: "client", err:
|
|
3757
|
+
clientSocket.once("error", (err) => {
|
|
3758
|
+
vncLog("proxy-error", { corrId, side: "client", err: err.message });
|
|
3759
3759
|
finish("client", "error");
|
|
3760
3760
|
});
|
|
3761
|
-
upstream.once("error", (
|
|
3762
|
-
vncLog("proxy-error", { corrId, side: "upstream", err:
|
|
3761
|
+
upstream.once("error", (err) => {
|
|
3762
|
+
vncLog("proxy-error", { corrId, side: "upstream", err: err.message });
|
|
3763
3763
|
finish("upstream", "error");
|
|
3764
3764
|
});
|
|
3765
3765
|
});
|
|
@@ -3774,12 +3774,12 @@ function handleUpgrade(req, clientSocket, head, opts) {
|
|
|
3774
3774
|
writeStatusAndDestroy(clientSocket, 504, "Gateway Timeout");
|
|
3775
3775
|
upstream.destroy();
|
|
3776
3776
|
});
|
|
3777
|
-
upstream.once("error", (
|
|
3777
|
+
upstream.once("error", (err) => {
|
|
3778
3778
|
if (proxyOpened) return;
|
|
3779
3779
|
vncLog("proxy-error", {
|
|
3780
3780
|
corrId,
|
|
3781
3781
|
side: "upstream-connect",
|
|
3782
|
-
err:
|
|
3782
|
+
err: err.message
|
|
3783
3783
|
});
|
|
3784
3784
|
writeStatusAndDestroy(clientSocket, 502, "Bad Gateway");
|
|
3785
3785
|
upstream.destroy();
|
|
@@ -3840,23 +3840,32 @@ var HOP_BY_HOP2 = /* @__PURE__ */ new Set([
|
|
|
3840
3840
|
"transfer-encoding",
|
|
3841
3841
|
"upgrade"
|
|
3842
3842
|
]);
|
|
3843
|
+
var cachedUpstreamPort = null;
|
|
3843
3844
|
function resolveUpstreamPort() {
|
|
3844
|
-
|
|
3845
|
+
if (cachedUpstreamPort !== null) return cachedUpstreamPort;
|
|
3846
|
+
const uri = process.env.NEO4J_URI;
|
|
3847
|
+
if (!uri) {
|
|
3848
|
+
throw new Error(
|
|
3849
|
+
"[ui/graph-proxy] NEO4J_URI unset \u2014 refusing to default to bolt://localhost:7687 (Task 580)"
|
|
3850
|
+
);
|
|
3851
|
+
}
|
|
3845
3852
|
const m = uri.match(/:(\d+)$/);
|
|
3846
3853
|
const boltPort = m ? parseInt(m[1], 10) : 7687;
|
|
3847
|
-
|
|
3854
|
+
cachedUpstreamPort = boltPort - 213;
|
|
3855
|
+
console.error(`[ui/graph-proxy] resolved neo4j_uri=${uri} http_port=${cachedUpstreamPort}`);
|
|
3856
|
+
return cachedUpstreamPort;
|
|
3848
3857
|
}
|
|
3849
3858
|
var UPSTREAM_HOST = "127.0.0.1";
|
|
3850
|
-
var UPSTREAM_PORT = resolveUpstreamPort();
|
|
3851
3859
|
function attachGraphHttpRoutes(app2) {
|
|
3852
3860
|
const handler = async (c) => {
|
|
3853
3861
|
const raw2 = c.req.raw;
|
|
3854
3862
|
const url = new URL(raw2.url);
|
|
3863
|
+
const upstreamPort = resolveUpstreamPort();
|
|
3855
3864
|
const pathAfterPrefix = url.pathname.slice(GRAPH_PREFIX.length) || "/";
|
|
3856
|
-
const upstreamUrl = `http://${UPSTREAM_HOST}:${
|
|
3865
|
+
const upstreamUrl = `http://${UPSTREAM_HOST}:${upstreamPort}${pathAfterPrefix}${url.search}`;
|
|
3857
3866
|
const upstreamHeaders = new Headers(raw2.headers);
|
|
3858
3867
|
for (const h of HOP_BY_HOP2) upstreamHeaders.delete(h);
|
|
3859
|
-
upstreamHeaders.set("host", `${UPSTREAM_HOST}:${
|
|
3868
|
+
upstreamHeaders.set("host", `${UPSTREAM_HOST}:${upstreamPort}`);
|
|
3860
3869
|
try {
|
|
3861
3870
|
const upstream = await fetch(upstreamUrl, {
|
|
3862
3871
|
method: raw2.method,
|
|
@@ -3869,13 +3878,18 @@ function attachGraphHttpRoutes(app2) {
|
|
|
3869
3878
|
});
|
|
3870
3879
|
const resHeaders = new Headers(upstream.headers);
|
|
3871
3880
|
for (const h of HOP_BY_HOP2) resHeaders.delete(h);
|
|
3881
|
+
const loc = resHeaders.get("location");
|
|
3882
|
+
if (loc) {
|
|
3883
|
+
const rewritten = rewriteLocation(loc);
|
|
3884
|
+
if (rewritten !== loc) resHeaders.set("location", rewritten);
|
|
3885
|
+
}
|
|
3872
3886
|
return new Response(upstream.body, {
|
|
3873
3887
|
status: upstream.status,
|
|
3874
3888
|
statusText: upstream.statusText,
|
|
3875
3889
|
headers: resHeaders
|
|
3876
3890
|
});
|
|
3877
|
-
} catch (
|
|
3878
|
-
const msg =
|
|
3891
|
+
} catch (err) {
|
|
3892
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3879
3893
|
console.error(`[graph-proxy] upstream fetch failed for ${upstreamUrl}: ${msg}`);
|
|
3880
3894
|
return c.text(`Graph proxy upstream unreachable: ${msg}`, 502);
|
|
3881
3895
|
}
|
|
@@ -3920,13 +3934,14 @@ function attachGraphWsProxy(server, opts) {
|
|
|
3920
3934
|
}
|
|
3921
3935
|
const rewrittenPath = pathname === GRAPH_PREFIX ? "/" : pathname.slice(GRAPH_PREFIX.length);
|
|
3922
3936
|
const rewrittenUrl = qsIndex === -1 ? rewrittenPath : rewrittenPath + url.slice(qsIndex);
|
|
3923
|
-
const
|
|
3937
|
+
const upstreamPort = resolveUpstreamPort();
|
|
3938
|
+
const upstream = createConnection2({ host: UPSTREAM_HOST, port: upstreamPort });
|
|
3924
3939
|
upstream.setTimeout(UPSTREAM_TIMEOUT_MS2);
|
|
3925
3940
|
upstream.once("connect", () => {
|
|
3926
3941
|
upstream.setTimeout(0);
|
|
3927
3942
|
const lines = [];
|
|
3928
3943
|
lines.push(`${req.method ?? "GET"} ${rewrittenUrl} HTTP/${req.httpVersion}`);
|
|
3929
|
-
lines.push(`host: ${UPSTREAM_HOST}:${
|
|
3944
|
+
lines.push(`host: ${UPSTREAM_HOST}:${upstreamPort}`);
|
|
3930
3945
|
for (const [name, value] of Object.entries(req.headers)) {
|
|
3931
3946
|
if (name === "host") continue;
|
|
3932
3947
|
if (HOP_BY_HOP2.has(name)) continue;
|
|
@@ -3958,13 +3973,13 @@ function attachGraphWsProxy(server, opts) {
|
|
|
3958
3973
|
writeStatusAndDestroy2(clientSocket, 504, "Gateway Timeout");
|
|
3959
3974
|
upstream.destroy();
|
|
3960
3975
|
});
|
|
3961
|
-
upstream.once("error", (
|
|
3962
|
-
console.error(`[graph-proxy] ws upstream error: ${
|
|
3976
|
+
upstream.once("error", (err) => {
|
|
3977
|
+
console.error(`[graph-proxy] ws upstream error: ${err.message}`);
|
|
3963
3978
|
writeStatusAndDestroy2(clientSocket, 502, "Bad Gateway");
|
|
3964
3979
|
upstream.destroy();
|
|
3965
3980
|
});
|
|
3966
|
-
} catch (
|
|
3967
|
-
console.error(`[graph-proxy] upgrade handler exception: ${
|
|
3981
|
+
} catch (err) {
|
|
3982
|
+
console.error(`[graph-proxy] upgrade handler exception: ${err.message}`);
|
|
3968
3983
|
clientSocket.destroy();
|
|
3969
3984
|
}
|
|
3970
3985
|
});
|
|
@@ -3998,6 +4013,21 @@ function headerString2(value) {
|
|
|
3998
4013
|
if (value == null) return void 0;
|
|
3999
4014
|
return Array.isArray(value) ? value[0] : value;
|
|
4000
4015
|
}
|
|
4016
|
+
function rewriteLocation(location) {
|
|
4017
|
+
try {
|
|
4018
|
+
const parsed = new URL(location);
|
|
4019
|
+
if (parsed.hostname === UPSTREAM_HOST && parsed.port === String(resolveUpstreamPort())) {
|
|
4020
|
+
const pathWithQuery = parsed.pathname + parsed.search + parsed.hash;
|
|
4021
|
+
return pathWithQuery.startsWith(GRAPH_PREFIX) ? pathWithQuery : `${GRAPH_PREFIX}${pathWithQuery}`;
|
|
4022
|
+
}
|
|
4023
|
+
return location;
|
|
4024
|
+
} catch {
|
|
4025
|
+
if (location.startsWith("/") && !location.startsWith(`${GRAPH_PREFIX}/`) && location !== GRAPH_PREFIX) {
|
|
4026
|
+
return `${GRAPH_PREFIX}${location}`;
|
|
4027
|
+
}
|
|
4028
|
+
return location;
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4001
4031
|
function parseOriginHost2(origin) {
|
|
4002
4032
|
if (!origin) return null;
|
|
4003
4033
|
try {
|
|
@@ -4073,8 +4103,8 @@ function writeOAuthCredentials(tokens) {
|
|
|
4073
4103
|
};
|
|
4074
4104
|
writeFileSync2(CLAUDE_CREDENTIALS_FILE, JSON.stringify(fileData, null, 2), "utf-8");
|
|
4075
4105
|
return newExpiresAt;
|
|
4076
|
-
} catch (
|
|
4077
|
-
console.error(`[claude-auth] credential write failed: ${
|
|
4106
|
+
} catch (err) {
|
|
4107
|
+
console.error(`[claude-auth] credential write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4078
4108
|
return null;
|
|
4079
4109
|
}
|
|
4080
4110
|
}
|
|
@@ -4123,8 +4153,8 @@ async function doRefresh() {
|
|
|
4123
4153
|
client_id: CLIENT_ID
|
|
4124
4154
|
})
|
|
4125
4155
|
});
|
|
4126
|
-
} catch (
|
|
4127
|
-
console.error(`[auth-refresh] network error: ${
|
|
4156
|
+
} catch (err) {
|
|
4157
|
+
console.error(`[auth-refresh] network error: ${err instanceof Error ? err.message : String(err)}`);
|
|
4128
4158
|
return { status: "expired", expiresAt: creds.expiresAt };
|
|
4129
4159
|
}
|
|
4130
4160
|
if (res.status === 429) {
|
|
@@ -4222,13 +4252,13 @@ function resolveKeyFilePath() {
|
|
|
4222
4252
|
);
|
|
4223
4253
|
}
|
|
4224
4254
|
configDirName2 = brand.configDir;
|
|
4225
|
-
} catch (
|
|
4226
|
-
if (
|
|
4255
|
+
} catch (err) {
|
|
4256
|
+
if (err instanceof SyntaxError) {
|
|
4227
4257
|
throw new Error(
|
|
4228
|
-
`brand.json at ${brandPath3} is not valid JSON: ${
|
|
4258
|
+
`brand.json at ${brandPath3} is not valid JSON: ${err.message}`
|
|
4229
4259
|
);
|
|
4230
4260
|
}
|
|
4231
|
-
throw
|
|
4261
|
+
throw err;
|
|
4232
4262
|
}
|
|
4233
4263
|
}
|
|
4234
4264
|
cachedKeyFilePath = resolve3(homedir2(), configDirName2, ".anthropic-api-key");
|
|
@@ -4242,8 +4272,8 @@ function readKey() {
|
|
|
4242
4272
|
let keyFilePath2;
|
|
4243
4273
|
try {
|
|
4244
4274
|
keyFilePath2 = resolveKeyFilePath();
|
|
4245
|
-
} catch (
|
|
4246
|
-
const msg =
|
|
4275
|
+
} catch (err) {
|
|
4276
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4247
4277
|
console.error(`[anthropic-key] path resolution failed: ${msg}`);
|
|
4248
4278
|
return null;
|
|
4249
4279
|
}
|
|
@@ -4261,14 +4291,14 @@ function readKey() {
|
|
|
4261
4291
|
return null;
|
|
4262
4292
|
}
|
|
4263
4293
|
return raw2;
|
|
4264
|
-
} catch (
|
|
4265
|
-
const code =
|
|
4294
|
+
} catch (err) {
|
|
4295
|
+
const code = err instanceof Error && "code" in err ? err.code : void 0;
|
|
4266
4296
|
if (code === "ENOENT") {
|
|
4267
4297
|
console.error(
|
|
4268
4298
|
`[anthropic-key] no key available (env var unset, file not found: ${keyFilePath2})`
|
|
4269
4299
|
);
|
|
4270
4300
|
} else {
|
|
4271
|
-
const msg =
|
|
4301
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4272
4302
|
console.error(
|
|
4273
4303
|
`[anthropic-key] failed to read key file ${keyFilePath2}: ${msg}`
|
|
4274
4304
|
);
|
|
@@ -4337,9 +4367,9 @@ async function validateKey(key) {
|
|
|
4337
4367
|
status: "error",
|
|
4338
4368
|
message: `Could not verify API key. Anthropic returned ${res.status}. This may be a temporary outage \u2014 try again later.`
|
|
4339
4369
|
};
|
|
4340
|
-
} catch (
|
|
4370
|
+
} catch (err) {
|
|
4341
4371
|
const latency = Date.now() - start;
|
|
4342
|
-
const msg =
|
|
4372
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4343
4373
|
console.error(
|
|
4344
4374
|
`[anthropic-key] validate: error (network failure, ${latency}ms): ${msg}`
|
|
4345
4375
|
);
|
|
@@ -4462,8 +4492,8 @@ function discoverNativeDisplay() {
|
|
|
4462
4492
|
display: sessionDisplay
|
|
4463
4493
|
});
|
|
4464
4494
|
return info;
|
|
4465
|
-
} catch (
|
|
4466
|
-
vncLog("native-display-discovery", { action: "fallback", reason: "error", err:
|
|
4495
|
+
} catch (err) {
|
|
4496
|
+
vncLog("native-display-discovery", { action: "fallback", reason: "error", err: err.message });
|
|
4467
4497
|
return fallback;
|
|
4468
4498
|
}
|
|
4469
4499
|
}
|
|
@@ -4506,13 +4536,13 @@ async function ensureVnc() {
|
|
|
4506
4536
|
vncLog("ensure-vnc", { action: "restart", reason: "x-down" });
|
|
4507
4537
|
try {
|
|
4508
4538
|
execFileSync("bash", [VNC_SCRIPT, "start"], { timeout: 2e4 });
|
|
4509
|
-
} catch (
|
|
4510
|
-
vncLog("ensure-vnc", { action: "restart-failed", err:
|
|
4539
|
+
} catch (err) {
|
|
4540
|
+
vncLog("ensure-vnc", { action: "restart-failed", err: err.message });
|
|
4511
4541
|
return false;
|
|
4512
4542
|
}
|
|
4513
|
-
const
|
|
4514
|
-
vncLog("ensure-vnc", { action: "restart-complete", x_port_5900:
|
|
4515
|
-
return
|
|
4543
|
+
const ok = await waitForPort(5900, 12e3);
|
|
4544
|
+
vncLog("ensure-vnc", { action: "restart-complete", x_port_5900: ok });
|
|
4545
|
+
return ok;
|
|
4516
4546
|
}
|
|
4517
4547
|
async function ensureCdp(transport = "vnc") {
|
|
4518
4548
|
const targetSentinel = transport === "native" ? "native" : ":99";
|
|
@@ -4563,8 +4593,8 @@ async function ensureCdp(transport = "vnc") {
|
|
|
4563
4593
|
vncLog("ensure-cdp", { action: `restart-${vncCommand}`, reason: "cdp-dead", transport });
|
|
4564
4594
|
try {
|
|
4565
4595
|
execFileSync("bash", [VNC_SCRIPT, vncCommand], { timeout: 2e4 });
|
|
4566
|
-
} catch (
|
|
4567
|
-
vncLog("ensure-cdp", { action: "restart-chrome-failed", transport, err:
|
|
4596
|
+
} catch (err) {
|
|
4597
|
+
vncLog("ensure-cdp", { action: "restart-chrome-failed", transport, err: err.message });
|
|
4568
4598
|
return false;
|
|
4569
4599
|
}
|
|
4570
4600
|
const cdpOk = await waitForPort(9222, 12e3);
|
|
@@ -4679,9 +4709,15 @@ function readPassword() {
|
|
|
4679
4709
|
}
|
|
4680
4710
|
function getDriver() {
|
|
4681
4711
|
if (!driver) {
|
|
4682
|
-
const uri = process.env.NEO4J_URI
|
|
4712
|
+
const uri = process.env.NEO4J_URI;
|
|
4713
|
+
if (!uri) {
|
|
4714
|
+
throw new Error(
|
|
4715
|
+
"[ui/neo4j-store] NEO4J_URI unset \u2014 refusing to default to bolt://localhost:7687 (Task 580)"
|
|
4716
|
+
);
|
|
4717
|
+
}
|
|
4683
4718
|
const user = process.env.NEO4J_USER ?? "neo4j";
|
|
4684
4719
|
const password = readPassword();
|
|
4720
|
+
console.error(`[ui/neo4j-store] resolved neo4j_uri=${uri}`);
|
|
4685
4721
|
driver = neo4j.driver(uri, neo4j.auth.basic(user, password), {
|
|
4686
4722
|
maxConnectionPoolSize: 5
|
|
4687
4723
|
});
|
|
@@ -4771,8 +4807,8 @@ async function ensureConversation(accountId, agentType, sessionKey, visitorId, a
|
|
|
4771
4807
|
console.error(`[session] ${(/* @__PURE__ */ new Date()).toISOString()} conversation attributed: conversationId=${id.slice(0, 8)}\u2026 userId=${userId ?? "none"} ${agentType}/${accountId.slice(0, 8)}\u2026`);
|
|
4772
4808
|
}
|
|
4773
4809
|
return id ?? null;
|
|
4774
|
-
} catch (
|
|
4775
|
-
console.error(`[persist] ensureConversation failed: ${
|
|
4810
|
+
} catch (err) {
|
|
4811
|
+
console.error(`[persist] ensureConversation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4776
4812
|
return null;
|
|
4777
4813
|
} finally {
|
|
4778
4814
|
await session.close();
|
|
@@ -4798,8 +4834,8 @@ async function findRecentConversation(visitorId, accountId, agentSlug, maxAgeHou
|
|
|
4798
4834
|
if (!conversationId) return null;
|
|
4799
4835
|
console.log(`[persist] found recent conversation ${conversationId.slice(0, 8)}\u2026 for visitor ${visitorId.slice(0, 8)}\u2026`);
|
|
4800
4836
|
return { conversationId, sessionKey };
|
|
4801
|
-
} catch (
|
|
4802
|
-
console.error(`[persist] findRecentConversation failed: ${
|
|
4837
|
+
} catch (err) {
|
|
4838
|
+
console.error(`[persist] findRecentConversation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4803
4839
|
return null;
|
|
4804
4840
|
} finally {
|
|
4805
4841
|
await session.close();
|
|
@@ -4821,8 +4857,8 @@ async function findGroupBySlug(groupSlug, accountId) {
|
|
|
4821
4857
|
groupName: record.get("groupName"),
|
|
4822
4858
|
agentSlug: record.get("agentSlug")
|
|
4823
4859
|
};
|
|
4824
|
-
} catch (
|
|
4825
|
-
console.error(`[group] findGroupBySlug failed: ${
|
|
4860
|
+
} catch (err) {
|
|
4861
|
+
console.error(`[group] findGroupBySlug failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4826
4862
|
return null;
|
|
4827
4863
|
} finally {
|
|
4828
4864
|
await session.close();
|
|
@@ -4844,8 +4880,8 @@ async function getGroupParticipants(conversationId) {
|
|
|
4844
4880
|
joinedAt: String(r.get("joinedAt")),
|
|
4845
4881
|
visitorId: r.get("visitorId")
|
|
4846
4882
|
}));
|
|
4847
|
-
} catch (
|
|
4848
|
-
console.error(`[group] getGroupParticipants failed: ${
|
|
4883
|
+
} catch (err) {
|
|
4884
|
+
console.error(`[group] getGroupParticipants failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4849
4885
|
return [];
|
|
4850
4886
|
} finally {
|
|
4851
4887
|
await session.close();
|
|
@@ -4862,8 +4898,8 @@ async function checkGroupMembership(conversationId, visitorId) {
|
|
|
4862
4898
|
{ conversationId, visitorId }
|
|
4863
4899
|
);
|
|
4864
4900
|
return result.records[0]?.get("displayName") ?? null;
|
|
4865
|
-
} catch (
|
|
4866
|
-
console.error(`[group] checkGroupMembership failed: ${
|
|
4901
|
+
} catch (err) {
|
|
4902
|
+
console.error(`[group] checkGroupMembership failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4867
4903
|
return null;
|
|
4868
4904
|
} finally {
|
|
4869
4905
|
await session.close();
|
|
@@ -4893,8 +4929,8 @@ async function bindVisitorToGroup(conversationId, visitorId, personEmail, person
|
|
|
4893
4929
|
console.error(`[group] auth-denied id=${conversationId.slice(0, 8)}\u2026 visitor=${visitorId.slice(0, 8)}\u2026`);
|
|
4894
4930
|
}
|
|
4895
4931
|
return name ? { displayName: name } : null;
|
|
4896
|
-
} catch (
|
|
4897
|
-
console.error(`[group] bindVisitorToGroup failed: ${
|
|
4932
|
+
} catch (err) {
|
|
4933
|
+
console.error(`[group] bindVisitorToGroup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4898
4934
|
return null;
|
|
4899
4935
|
} finally {
|
|
4900
4936
|
await session.close();
|
|
@@ -4922,8 +4958,8 @@ async function getMessagesSince(conversationId, since, limit = 100) {
|
|
|
4922
4958
|
senderVisitorId: r.get("senderVisitorId"),
|
|
4923
4959
|
createdAt: String(r.get("createdAt"))
|
|
4924
4960
|
}));
|
|
4925
|
-
} catch (
|
|
4926
|
-
console.error(`[group] getMessagesSince failed: ${
|
|
4961
|
+
} catch (err) {
|
|
4962
|
+
console.error(`[group] getMessagesSince failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4927
4963
|
return [];
|
|
4928
4964
|
} finally {
|
|
4929
4965
|
await session.close();
|
|
@@ -4944,8 +4980,8 @@ async function getGroupMessagesForContext(conversationId, limit = 50) {
|
|
|
4944
4980
|
content: r.get("content"),
|
|
4945
4981
|
senderName: r.get("senderName")
|
|
4946
4982
|
}));
|
|
4947
|
-
} catch (
|
|
4948
|
-
console.error(`[group] getGroupMessagesForContext failed: ${
|
|
4983
|
+
} catch (err) {
|
|
4984
|
+
console.error(`[group] getGroupMessagesForContext failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4949
4985
|
return [];
|
|
4950
4986
|
} finally {
|
|
4951
4987
|
await session.close();
|
|
@@ -4972,8 +5008,8 @@ async function backfillNullUserIdConversations(userId) {
|
|
|
4972
5008
|
console.log(`[session] ${(/* @__PURE__ */ new Date()).toISOString()} backfill: no orphaned admin conversations found`);
|
|
4973
5009
|
}
|
|
4974
5010
|
return typeof updated === "number" ? updated : 0;
|
|
4975
|
-
} catch (
|
|
4976
|
-
console.error(`[session] backfillNullUserIdConversations failed: ${
|
|
5011
|
+
} catch (err) {
|
|
5012
|
+
console.error(`[session] backfillNullUserIdConversations failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4977
5013
|
return 0;
|
|
4978
5014
|
} finally {
|
|
4979
5015
|
await session.close();
|
|
@@ -5003,8 +5039,8 @@ async function createNewAdminConversation(userId, accountId, sessionKey) {
|
|
|
5003
5039
|
cacheConversationId(sessionKey, conversationId);
|
|
5004
5040
|
console.log(`[session] ${(/* @__PURE__ */ new Date()).toISOString()} conversation created: conversationId=${conversationId.slice(0, 8)}\u2026 userId=${userId} accountId=${accountId.slice(0, 8)}\u2026`);
|
|
5005
5041
|
return conversationId;
|
|
5006
|
-
} catch (
|
|
5007
|
-
console.error(`[session] createNewAdminConversation failed: ${
|
|
5042
|
+
} catch (err) {
|
|
5043
|
+
console.error(`[session] createNewAdminConversation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5008
5044
|
return null;
|
|
5009
5045
|
} finally {
|
|
5010
5046
|
await session.close();
|
|
@@ -5049,8 +5085,8 @@ async function fetchBranding(accountId) {
|
|
|
5049
5085
|
if (faviconUrl) branding.faviconUrl = faviconUrl;
|
|
5050
5086
|
console.error(`[branding] resolved for accountId=${accountId.slice(0, 8)}\u2026: primary=${branding.primaryColor ?? "\u2013"} logo=${branding.logoUrl ? "yes" : "no"}`);
|
|
5051
5087
|
return branding;
|
|
5052
|
-
} catch (
|
|
5053
|
-
console.error(`[branding] fetchBranding failed for accountId=${accountId.slice(0, 8)}\u2026: ${
|
|
5088
|
+
} catch (err) {
|
|
5089
|
+
console.error(`[branding] fetchBranding failed for accountId=${accountId.slice(0, 8)}\u2026: ${err instanceof Error ? err.message : String(err)}`);
|
|
5054
5090
|
return null;
|
|
5055
5091
|
} finally {
|
|
5056
5092
|
await session.close();
|
|
@@ -5104,8 +5140,8 @@ async function persistToolCall(record) {
|
|
|
5104
5140
|
}
|
|
5105
5141
|
);
|
|
5106
5142
|
console.error(`[persist] tool-call persisted: name=${record.toolName} conversation=${record.conversationId.slice(0, 8)}\u2026${record.approvalState ? ` approval=${record.approvalState}` : ""}`);
|
|
5107
|
-
} catch (
|
|
5108
|
-
console.error(`[persist] tool-call write failed: name=${record.toolName} error=${
|
|
5143
|
+
} catch (err) {
|
|
5144
|
+
console.error(`[persist] tool-call write failed: name=${record.toolName} error=${err instanceof Error ? err.message : String(err)}`);
|
|
5109
5145
|
} finally {
|
|
5110
5146
|
await session.close();
|
|
5111
5147
|
}
|
|
@@ -5116,8 +5152,8 @@ async function persistMessage(conversationId, role, content, accountId, tokens,
|
|
|
5116
5152
|
let embedding = null;
|
|
5117
5153
|
try {
|
|
5118
5154
|
embedding = await embed(content);
|
|
5119
|
-
} catch (
|
|
5120
|
-
console.error(`[persist] Embedding failed, storing without: ${
|
|
5155
|
+
} catch (err) {
|
|
5156
|
+
console.error(`[persist] Embedding failed, storing without: ${err instanceof Error ? err.message : String(err)}`);
|
|
5121
5157
|
}
|
|
5122
5158
|
const session = getSession();
|
|
5123
5159
|
try {
|
|
@@ -5157,8 +5193,8 @@ async function persistMessage(conversationId, role, content, accountId, tokens,
|
|
|
5157
5193
|
);
|
|
5158
5194
|
console.error(`[persist] ${(/* @__PURE__ */ new Date()).toISOString()} conversationId=${conversationId.slice(0, 8)}\u2026 role=${role} len=${content.length}${sender ? ` sender=${sender.displayName}` : ""}`);
|
|
5159
5195
|
return messageId;
|
|
5160
|
-
} catch (
|
|
5161
|
-
console.error(`[persist] Neo4j write failed: ${
|
|
5196
|
+
} catch (err) {
|
|
5197
|
+
console.error(`[persist] Neo4j write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5162
5198
|
return null;
|
|
5163
5199
|
} finally {
|
|
5164
5200
|
await session.close();
|
|
@@ -5180,8 +5216,8 @@ async function getRecentMessages(conversationId, limit = 50) {
|
|
|
5180
5216
|
content: r.get("content"),
|
|
5181
5217
|
createdAt: String(r.get("createdAt"))
|
|
5182
5218
|
}));
|
|
5183
|
-
} catch (
|
|
5184
|
-
console.error(`[persist] getRecentMessages failed: ${
|
|
5219
|
+
} catch (err) {
|
|
5220
|
+
console.error(`[persist] getRecentMessages failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5185
5221
|
return [];
|
|
5186
5222
|
} finally {
|
|
5187
5223
|
await session.close();
|
|
@@ -5196,8 +5232,8 @@ async function verifyConversationOwnership(conversationId, accountId) {
|
|
|
5196
5232
|
{ conversationId, accountId }
|
|
5197
5233
|
);
|
|
5198
5234
|
return result.records.length > 0;
|
|
5199
|
-
} catch (
|
|
5200
|
-
console.error(`[persist] verifyConversationOwnership failed: ${
|
|
5235
|
+
} catch (err) {
|
|
5236
|
+
console.error(`[persist] verifyConversationOwnership failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5201
5237
|
return false;
|
|
5202
5238
|
} finally {
|
|
5203
5239
|
await session.close();
|
|
@@ -5213,8 +5249,8 @@ async function verifyAndGetConversationUpdatedAt(conversationId, accountId) {
|
|
|
5213
5249
|
);
|
|
5214
5250
|
const record = result.records[0];
|
|
5215
5251
|
return record ? record.get("updatedAt") : null;
|
|
5216
|
-
} catch (
|
|
5217
|
-
console.error(`[persist] verifyAndGetConversationUpdatedAt failed: ${
|
|
5252
|
+
} catch (err) {
|
|
5253
|
+
console.error(`[persist] verifyAndGetConversationUpdatedAt failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5218
5254
|
return null;
|
|
5219
5255
|
} finally {
|
|
5220
5256
|
await session.close();
|
|
@@ -5245,8 +5281,8 @@ async function searchMessages(accountId, queryEmbedding, limit = 10) {
|
|
|
5245
5281
|
createdAt: String(r.get("createdAt")),
|
|
5246
5282
|
score: typeof r.get("score") === "number" ? r.get("score") : Number(r.get("score"))
|
|
5247
5283
|
}));
|
|
5248
|
-
} catch (
|
|
5249
|
-
console.error(`[persist] searchMessages failed: ${
|
|
5284
|
+
} catch (err) {
|
|
5285
|
+
console.error(`[persist] searchMessages failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5250
5286
|
return [];
|
|
5251
5287
|
} finally {
|
|
5252
5288
|
await session.close();
|
|
@@ -5269,8 +5305,8 @@ async function listAdminSessions(accountId, userId, limit = 20) {
|
|
|
5269
5305
|
name: r.get("name"),
|
|
5270
5306
|
updatedAt: String(r.get("updatedAt"))
|
|
5271
5307
|
}));
|
|
5272
|
-
} catch (
|
|
5273
|
-
console.error(`[persist] listAdminSessions failed: ${
|
|
5308
|
+
} catch (err) {
|
|
5309
|
+
console.error(`[persist] listAdminSessions failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5274
5310
|
return [];
|
|
5275
5311
|
} finally {
|
|
5276
5312
|
await session.close();
|
|
@@ -5290,8 +5326,8 @@ async function deleteConversation(conversationId) {
|
|
|
5290
5326
|
const count = typeof deleted === "object" && deleted !== null ? Number(deleted) : Number(deleted ?? 0);
|
|
5291
5327
|
console.error(`[persist] deleteConversation ${conversationId.slice(0, 8)}\u2026: ${count > 0 ? "deleted" : "not found"}`);
|
|
5292
5328
|
return count > 0;
|
|
5293
|
-
} catch (
|
|
5294
|
-
console.error(`[persist] deleteConversation failed: ${
|
|
5329
|
+
} catch (err) {
|
|
5330
|
+
console.error(`[persist] deleteConversation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5295
5331
|
return false;
|
|
5296
5332
|
} finally {
|
|
5297
5333
|
await session.close();
|
|
@@ -5358,9 +5394,9 @@ ${userContent}`;
|
|
|
5358
5394
|
console.error("[persist] autoLabel: haiku subprocess timed out");
|
|
5359
5395
|
resolve33(null);
|
|
5360
5396
|
}, SESSION_LABEL_TIMEOUT_MS);
|
|
5361
|
-
proc.on("error", (
|
|
5397
|
+
proc.on("error", (err) => {
|
|
5362
5398
|
clearTimeout(timer);
|
|
5363
|
-
console.error(`[persist] autoLabel: subprocess error \u2014 ${
|
|
5399
|
+
console.error(`[persist] autoLabel: subprocess error \u2014 ${err.message}`);
|
|
5364
5400
|
resolve33(null);
|
|
5365
5401
|
});
|
|
5366
5402
|
proc.on("close", (code) => {
|
|
@@ -5423,8 +5459,8 @@ async function autoLabelSession(conversationId, userMessage) {
|
|
|
5423
5459
|
let embedding = null;
|
|
5424
5460
|
try {
|
|
5425
5461
|
embedding = await embed(fullLabel);
|
|
5426
|
-
} catch (
|
|
5427
|
-
console.error(`[persist] Conversation embedding failed, labelling without: ${
|
|
5462
|
+
} catch (err) {
|
|
5463
|
+
console.error(`[persist] Conversation embedding failed, labelling without: ${err instanceof Error ? err.message : String(err)}`);
|
|
5428
5464
|
}
|
|
5429
5465
|
const session = getSession();
|
|
5430
5466
|
try {
|
|
@@ -5445,13 +5481,13 @@ async function autoLabelSession(conversationId, userMessage) {
|
|
|
5445
5481
|
console.error(`[persist] Auto-labeled session ${conversationId.slice(0, 8)}\u2026: "${fullLabel}"${embedding ? " (embedded)" : ""}`);
|
|
5446
5482
|
labelAccumulator.delete(conversationId);
|
|
5447
5483
|
}
|
|
5448
|
-
} catch (
|
|
5449
|
-
console.error(`[persist] autoLabelSession failed: ${
|
|
5484
|
+
} catch (err) {
|
|
5485
|
+
console.error(`[persist] autoLabelSession failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5450
5486
|
} finally {
|
|
5451
5487
|
await session.close();
|
|
5452
5488
|
}
|
|
5453
|
-
} catch (
|
|
5454
|
-
console.error(`[persist] autoLabel: unexpected error \u2014 ${
|
|
5489
|
+
} catch (err) {
|
|
5490
|
+
console.error(`[persist] autoLabel: unexpected error \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
5455
5491
|
} finally {
|
|
5456
5492
|
const currentEntry = labelAccumulator.get(conversationId);
|
|
5457
5493
|
if (currentEntry) currentEntry.pending = false;
|
|
@@ -5461,8 +5497,8 @@ async function renameConversation(conversationId, label) {
|
|
|
5461
5497
|
let embedding = null;
|
|
5462
5498
|
try {
|
|
5463
5499
|
embedding = await embed(label);
|
|
5464
|
-
} catch (
|
|
5465
|
-
console.error(`[persist] manual-label: embedding failed, persisting without: ${
|
|
5500
|
+
} catch (err) {
|
|
5501
|
+
console.error(`[persist] manual-label: embedding failed, persisting without: ${err instanceof Error ? err.message : String(err)}`);
|
|
5466
5502
|
}
|
|
5467
5503
|
const session = getSession();
|
|
5468
5504
|
try {
|
|
@@ -5501,8 +5537,8 @@ async function getUserTimezone(accountId, userId) {
|
|
|
5501
5537
|
if (result.records.length === 0) return null;
|
|
5502
5538
|
const tz = result.records[0].get("timezone");
|
|
5503
5539
|
return tz && tz.trim().length > 0 ? tz : null;
|
|
5504
|
-
} catch (
|
|
5505
|
-
console.error(`[datetime] getUserTimezone failed: ${
|
|
5540
|
+
} catch (err) {
|
|
5541
|
+
console.error(`[datetime] getUserTimezone failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5506
5542
|
return null;
|
|
5507
5543
|
} finally {
|
|
5508
5544
|
await session.close();
|
|
@@ -5598,8 +5634,8 @@ async function loadUserProfile(accountId, userId) {
|
|
|
5598
5634
|
`[profile] loaded for userId=${userId} accountId=${accountId.slice(0, 8)}\u2026 preferences=${preferences.length} (decay: ${decayCount} updated)`
|
|
5599
5635
|
);
|
|
5600
5636
|
return summary;
|
|
5601
|
-
} catch (
|
|
5602
|
-
console.error(`[profile] loadUserProfile failed: ${
|
|
5637
|
+
} catch (err) {
|
|
5638
|
+
console.error(`[profile] loadUserProfile failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5603
5639
|
return null;
|
|
5604
5640
|
} finally {
|
|
5605
5641
|
await session.close();
|
|
@@ -5684,9 +5720,9 @@ function readRecentToolFailures(accountId, conversationId) {
|
|
|
5684
5720
|
} finally {
|
|
5685
5721
|
closeSync(fd);
|
|
5686
5722
|
}
|
|
5687
|
-
} catch (
|
|
5723
|
+
} catch (err) {
|
|
5688
5724
|
console.error(
|
|
5689
|
-
`[session-context] recent-tool-failures read failed: ${
|
|
5725
|
+
`[session-context] recent-tool-failures read failed: ${err instanceof Error ? err.message : String(err)}`
|
|
5690
5726
|
);
|
|
5691
5727
|
return [];
|
|
5692
5728
|
}
|
|
@@ -5880,8 +5916,8 @@ ${failureLines.map((l) => `- ${l.trim()}`).join("\n")}`);
|
|
|
5880
5916
|
return `<previous-context>
|
|
5881
5917
|
${sections.join("\n\n")}
|
|
5882
5918
|
</previous-context>`;
|
|
5883
|
-
} catch (
|
|
5884
|
-
console.error(`[session-context] loadSessionContext failed: ${
|
|
5919
|
+
} catch (err) {
|
|
5920
|
+
console.error(`[session-context] loadSessionContext failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5885
5921
|
return null;
|
|
5886
5922
|
} finally {
|
|
5887
5923
|
await session.close();
|
|
@@ -5923,9 +5959,9 @@ async function consumeStep7FlagUI(session, accountId) {
|
|
|
5923
5959
|
);
|
|
5924
5960
|
try {
|
|
5925
5961
|
rmSync(flagPath);
|
|
5926
|
-
} catch (
|
|
5962
|
+
} catch (err) {
|
|
5927
5963
|
console.error(
|
|
5928
|
-
`[onboarding-flag-consumed] warn: failed to delete ${flagPath}: ${
|
|
5964
|
+
`[onboarding-flag-consumed] warn: failed to delete ${flagPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
5929
5965
|
);
|
|
5930
5966
|
}
|
|
5931
5967
|
return true;
|
|
@@ -5948,8 +5984,8 @@ async function loadOnboardingStep(accountId) {
|
|
|
5948
5984
|
return raw2.toNumber();
|
|
5949
5985
|
}
|
|
5950
5986
|
return 0;
|
|
5951
|
-
} catch (
|
|
5952
|
-
console.error(`[onboarding-inject] loadOnboardingStep failed: ${
|
|
5987
|
+
} catch (err) {
|
|
5988
|
+
console.error(`[onboarding-inject] loadOnboardingStep failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5953
5989
|
return null;
|
|
5954
5990
|
} finally {
|
|
5955
5991
|
await session.close();
|
|
@@ -6119,8 +6155,8 @@ async function writeReflectionPreferences(accountId, userId, conversationId, upd
|
|
|
6119
6155
|
}
|
|
6120
6156
|
console.error(`[profile-reflection] Wrote ${written}/${updates.length} preference updates for userId=${userId} accountId=${accountId.slice(0, 8)}\u2026`);
|
|
6121
6157
|
return written;
|
|
6122
|
-
} catch (
|
|
6123
|
-
console.error(`[profile-reflection] writeReflectionPreferences failed: ${
|
|
6158
|
+
} catch (err) {
|
|
6159
|
+
console.error(`[profile-reflection] writeReflectionPreferences failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6124
6160
|
return written;
|
|
6125
6161
|
} finally {
|
|
6126
6162
|
await session.close();
|
|
@@ -6156,12 +6192,12 @@ async function searchKnowledgeFulltext(accountId, query, limit) {
|
|
|
6156
6192
|
score
|
|
6157
6193
|
};
|
|
6158
6194
|
});
|
|
6159
|
-
} catch (
|
|
6160
|
-
const msg =
|
|
6195
|
+
} catch (err) {
|
|
6196
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6161
6197
|
if (msg.includes("index") || msg.includes("fulltext") || msg.includes("not found")) {
|
|
6162
6198
|
return [];
|
|
6163
6199
|
}
|
|
6164
|
-
throw
|
|
6200
|
+
throw err;
|
|
6165
6201
|
} finally {
|
|
6166
6202
|
await session.close();
|
|
6167
6203
|
}
|
|
@@ -6300,12 +6336,12 @@ ${message.slice(0, CLASSIFIER_MSG_CAP)}`
|
|
|
6300
6336
|
`${TAG} done duration_ms=${durationMs} input_tokens=${inputTokens} output_tokens=${outputTokens} commitments=${commitments.length} confidences=[${commitments.map((c) => c.confidence.toFixed(2)).join(",")}]`
|
|
6301
6337
|
);
|
|
6302
6338
|
return commitments;
|
|
6303
|
-
} catch (
|
|
6339
|
+
} catch (err) {
|
|
6304
6340
|
const durationMs = Date.now() - startMs;
|
|
6305
|
-
if (
|
|
6341
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
6306
6342
|
console.error(`${TAG} failed error=timeout duration_ms=${durationMs}`);
|
|
6307
6343
|
} else {
|
|
6308
|
-
const reason =
|
|
6344
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
6309
6345
|
console.error(`${TAG} failed error=${reason} duration_ms=${durationMs}`);
|
|
6310
6346
|
}
|
|
6311
6347
|
return [];
|
|
@@ -6378,10 +6414,10 @@ async function probeDns(host, family) {
|
|
|
6378
6414
|
if (timer) clearTimeout(timer);
|
|
6379
6415
|
const ms = Date.now() - start;
|
|
6380
6416
|
return `${label}=${result.address} ${label}_ms=${ms}`;
|
|
6381
|
-
} catch (
|
|
6417
|
+
} catch (err) {
|
|
6382
6418
|
if (timer) clearTimeout(timer);
|
|
6383
6419
|
const ms = Date.now() - start;
|
|
6384
|
-
const msg =
|
|
6420
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6385
6421
|
return `${label}=err ${label}_err=${quoteDiag(msg.slice(0, 60))} ${label}_ms=${ms}`;
|
|
6386
6422
|
}
|
|
6387
6423
|
}
|
|
@@ -6404,9 +6440,9 @@ async function probeTcp(host, port2) {
|
|
|
6404
6440
|
clearTimeout(timer);
|
|
6405
6441
|
finish(`tcp=ok tcp_ms=${Date.now() - start}`);
|
|
6406
6442
|
});
|
|
6407
|
-
sock.once("error", (
|
|
6443
|
+
sock.once("error", (err) => {
|
|
6408
6444
|
clearTimeout(timer);
|
|
6409
|
-
const msg =
|
|
6445
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6410
6446
|
finish(`tcp=err tcp_err=${quoteDiag(msg.slice(0, 60))} tcp_ms=${Date.now() - start}`);
|
|
6411
6447
|
});
|
|
6412
6448
|
});
|
|
@@ -6419,9 +6455,9 @@ async function probeHttp(url) {
|
|
|
6419
6455
|
const res = await fetch(url, { method: "HEAD", redirect: "manual", signal: controller.signal });
|
|
6420
6456
|
clearTimeout(timer);
|
|
6421
6457
|
return `http_status=${res.status} http_ms=${Date.now() - start}`;
|
|
6422
|
-
} catch (
|
|
6458
|
+
} catch (err) {
|
|
6423
6459
|
clearTimeout(timer);
|
|
6424
|
-
const msg =
|
|
6460
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6425
6461
|
return `http_status=err http_err=${quoteDiag(msg.slice(0, 60))} http_ms=${Date.now() - start}`;
|
|
6426
6462
|
}
|
|
6427
6463
|
}
|
|
@@ -6503,8 +6539,8 @@ function sigtermFlushStreamLogs(reason, source) {
|
|
|
6503
6539
|
`;
|
|
6504
6540
|
try {
|
|
6505
6541
|
appendFileSync2(entry.path, line);
|
|
6506
|
-
} catch (
|
|
6507
|
-
const msg =
|
|
6542
|
+
} catch (err) {
|
|
6543
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6508
6544
|
console.error(`[server-sigterm-flush-err] path=${entry.path} reason=${msg}`);
|
|
6509
6545
|
}
|
|
6510
6546
|
}
|
|
@@ -6514,8 +6550,8 @@ function purgeOldLogs(logDir, prefix) {
|
|
|
6514
6550
|
let entries;
|
|
6515
6551
|
try {
|
|
6516
6552
|
entries = readdirSync2(logDir);
|
|
6517
|
-
} catch (
|
|
6518
|
-
const msg =
|
|
6553
|
+
} catch (err) {
|
|
6554
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6519
6555
|
console.error(`[log-purge-err] readdir dir=${logDir} prefix=${prefix} reason=${msg}`);
|
|
6520
6556
|
return;
|
|
6521
6557
|
}
|
|
@@ -6524,8 +6560,8 @@ function purgeOldLogs(logDir, prefix) {
|
|
|
6524
6560
|
const filePath = resolve6(logDir, file);
|
|
6525
6561
|
try {
|
|
6526
6562
|
if (statSync3(filePath).mtimeMs < cutoff) unlinkSync2(filePath);
|
|
6527
|
-
} catch (
|
|
6528
|
-
const msg =
|
|
6563
|
+
} catch (err) {
|
|
6564
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6529
6565
|
console.error(`[log-purge-err] file=${file} reason=${msg}`);
|
|
6530
6566
|
}
|
|
6531
6567
|
}
|
|
@@ -6581,8 +6617,8 @@ function sampleProcState(pid) {
|
|
|
6581
6617
|
let openFds2 = 0;
|
|
6582
6618
|
try {
|
|
6583
6619
|
openFds2 = readdirSync2(fdDir).length;
|
|
6584
|
-
} catch (
|
|
6585
|
-
const msg =
|
|
6620
|
+
} catch (err) {
|
|
6621
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6586
6622
|
return `proc_err=${JSON.stringify(msg.slice(0, 60))}`;
|
|
6587
6623
|
}
|
|
6588
6624
|
let established2 = 0;
|
|
@@ -6634,8 +6670,8 @@ function sampleProcState(pid) {
|
|
|
6634
6670
|
}
|
|
6635
6671
|
}
|
|
6636
6672
|
return `open_fds=${openFds} socket_count=${sockets} tcp_established=${established} tcp_connecting=${connecting} rss_mb=unknown`;
|
|
6637
|
-
} catch (
|
|
6638
|
-
const msg =
|
|
6673
|
+
} catch (err) {
|
|
6674
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6639
6675
|
return `proc_err=${JSON.stringify(msg.slice(0, 60))}`;
|
|
6640
6676
|
}
|
|
6641
6677
|
}
|
|
@@ -6728,8 +6764,8 @@ function resolveDefaultAgentSlug(accountDir) {
|
|
|
6728
6764
|
let config;
|
|
6729
6765
|
try {
|
|
6730
6766
|
config = JSON.parse(readFileSync7(configPath2, "utf-8"));
|
|
6731
|
-
} catch (
|
|
6732
|
-
console.error("[agent-resolve] failed to read account.json:",
|
|
6767
|
+
} catch (err) {
|
|
6768
|
+
console.error("[agent-resolve] failed to read account.json:", err);
|
|
6733
6769
|
return null;
|
|
6734
6770
|
}
|
|
6735
6771
|
if (!config.defaultAgent) {
|
|
@@ -6928,8 +6964,8 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6928
6964
|
let bundleRaw;
|
|
6929
6965
|
try {
|
|
6930
6966
|
bundleRaw = readFileSync7(bundlePath, "utf-8");
|
|
6931
|
-
} catch (
|
|
6932
|
-
console.log(`${TAG18} ${pluginName}: cannot read BUNDLE.md \u2014 ${
|
|
6967
|
+
} catch (err) {
|
|
6968
|
+
console.log(`${TAG18} ${pluginName}: cannot read BUNDLE.md \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
6933
6969
|
continue;
|
|
6934
6970
|
}
|
|
6935
6971
|
const fmMatch = bundleRaw.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -6971,8 +7007,8 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6971
7007
|
try {
|
|
6972
7008
|
cpSync(source, target, { recursive: true });
|
|
6973
7009
|
delivered++;
|
|
6974
|
-
} catch (
|
|
6975
|
-
console.log(`${TAG18} ${pluginName}/${sub}: copy failed \u2014 ${
|
|
7010
|
+
} catch (err) {
|
|
7011
|
+
console.log(`${TAG18} ${pluginName}/${sub}: copy failed \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
6976
7012
|
}
|
|
6977
7013
|
}
|
|
6978
7014
|
console.log(`${TAG18} ${pluginName} (bundle): ${delivered} delivered, ${skipped} already present`);
|
|
@@ -6985,8 +7021,8 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6985
7021
|
try {
|
|
6986
7022
|
cpSync(stagingDir, target, { recursive: true });
|
|
6987
7023
|
console.log(`${TAG18} ${pluginName} (standalone): delivered`);
|
|
6988
|
-
} catch (
|
|
6989
|
-
console.log(`${TAG18} ${pluginName}: copy failed \u2014 ${
|
|
7024
|
+
} catch (err) {
|
|
7025
|
+
console.log(`${TAG18} ${pluginName}: copy failed \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
6990
7026
|
}
|
|
6991
7027
|
}
|
|
6992
7028
|
}
|
|
@@ -7026,8 +7062,8 @@ function migratePluginRenames(accountDir, config) {
|
|
|
7026
7062
|
writeFileSync5(configPath2, JSON.stringify(parsed, null, 2) + "\n");
|
|
7027
7063
|
config.enabledPlugins = migrated;
|
|
7028
7064
|
console.log(`${TAG18} account.json updated (${migrated.length} plugins)`);
|
|
7029
|
-
} catch (
|
|
7030
|
-
console.error(`${TAG18} failed to update account.json \u2014 ${
|
|
7065
|
+
} catch (err) {
|
|
7066
|
+
console.error(`${TAG18} failed to update account.json \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
7031
7067
|
}
|
|
7032
7068
|
const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
|
|
7033
7069
|
for (const oldName of Object.keys(PLUGIN_RENAMES)) {
|
|
@@ -7036,8 +7072,8 @@ function migratePluginRenames(accountDir, config) {
|
|
|
7036
7072
|
try {
|
|
7037
7073
|
rmSync2(orphan, { recursive: true });
|
|
7038
7074
|
console.log(`${TAG18} removed orphan: ${oldName}`);
|
|
7039
|
-
} catch (
|
|
7040
|
-
console.log(`${TAG18} orphan removal failed: ${oldName} \u2014 ${
|
|
7075
|
+
} catch (err) {
|
|
7076
|
+
console.log(`${TAG18} orphan removal failed: ${oldName} \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
7041
7077
|
}
|
|
7042
7078
|
}
|
|
7043
7079
|
}
|
|
@@ -7073,8 +7109,8 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
|
|
|
7073
7109
|
const source = resolve6(bundleAgentsDir, filename);
|
|
7074
7110
|
try {
|
|
7075
7111
|
cpSync(source, target);
|
|
7076
|
-
} catch (
|
|
7077
|
-
console.log(`${TAG18} copy failed: ${filename} \u2014 ${
|
|
7112
|
+
} catch (err) {
|
|
7113
|
+
console.log(`${TAG18} copy failed: ${filename} \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
7078
7114
|
continue;
|
|
7079
7115
|
}
|
|
7080
7116
|
try {
|
|
@@ -7104,8 +7140,8 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
|
|
|
7104
7140
|
try {
|
|
7105
7141
|
writeFileSync5(agentsmdPath, agentsmd);
|
|
7106
7142
|
console.log(`${TAG18} AGENTS.md updated (${delivered} agents added)`);
|
|
7107
|
-
} catch (
|
|
7108
|
-
console.error(`${TAG18} AGENTS.md update failed \u2014 ${
|
|
7143
|
+
} catch (err) {
|
|
7144
|
+
console.error(`${TAG18} AGENTS.md update failed \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
7109
7145
|
}
|
|
7110
7146
|
}
|
|
7111
7147
|
}
|
|
@@ -7261,8 +7297,8 @@ function loadEmbeddedPlugins(agentType, selectedPlugins, enabledPlugins) {
|
|
|
7261
7297
|
let raw2;
|
|
7262
7298
|
try {
|
|
7263
7299
|
raw2 = readFileSync7(pluginPath, "utf-8");
|
|
7264
|
-
} catch (
|
|
7265
|
-
console.warn(`[plugins] ${dir}: failed to read PLUGIN.md for ${agentType} embed: ${String(
|
|
7300
|
+
} catch (err) {
|
|
7301
|
+
console.warn(`[plugins] ${dir}: failed to read PLUGIN.md for ${agentType} embed: ${String(err)}`);
|
|
7266
7302
|
continue;
|
|
7267
7303
|
}
|
|
7268
7304
|
const body = raw2.replace(/^---\n[\s\S]*?\n---\n*/, "").trim();
|
|
@@ -7355,7 +7391,7 @@ function fetchMcpToolsList(pluginDir) {
|
|
|
7355
7391
|
proc.stderr.on("data", (chunk) => {
|
|
7356
7392
|
stderrBuf += chunk.toString();
|
|
7357
7393
|
});
|
|
7358
|
-
proc.on("error", (
|
|
7394
|
+
proc.on("error", (err) => settle([], `spawn error: ${err.message}`));
|
|
7359
7395
|
proc.on("close", (code) => {
|
|
7360
7396
|
if (!settled) settle([], `process exited with code ${code}`);
|
|
7361
7397
|
});
|
|
@@ -7862,12 +7898,33 @@ function readBrandHostname() {
|
|
|
7862
7898
|
}
|
|
7863
7899
|
return cachedBrandHostname;
|
|
7864
7900
|
}
|
|
7901
|
+
function requireNeo4jUri() {
|
|
7902
|
+
const uri = process.env.NEO4J_URI;
|
|
7903
|
+
if (!uri) {
|
|
7904
|
+
throw new Error(
|
|
7905
|
+
"NEO4J_URI unset \u2014 refusing to default to bolt://localhost:7687. Set NEO4J_URI in the gateway's env (systemd EnvironmentFile or shell .env). (Task 580)"
|
|
7906
|
+
);
|
|
7907
|
+
}
|
|
7908
|
+
const brand = readBrandHostname();
|
|
7909
|
+
if (brand === "realagent" && /:7687([/?]|$)/.test(uri)) {
|
|
7910
|
+
throw new Error(
|
|
7911
|
+
`NEO4J_URI=${uri} points at :7687 on a realagent install \u2014 realagent owns :7688. This would silently write into Maxy's DB (Task 577 vector). (Task 580)`
|
|
7912
|
+
);
|
|
7913
|
+
}
|
|
7914
|
+
return uri;
|
|
7915
|
+
}
|
|
7865
7916
|
function getMcpServers(accountId, conversationId, userId, enabledPlugins) {
|
|
7866
7917
|
if (!conversationId) {
|
|
7867
7918
|
throw new Error(`getMcpServers: conversationId is required (accountId=${accountId.slice(0, 8)})`);
|
|
7868
7919
|
}
|
|
7869
7920
|
const { logDir: LOG_DIR2, streamLogPath: STREAM_LOG_PATH } = streamLogPathFor(accountId, conversationId);
|
|
7870
|
-
const baseEnv = {
|
|
7921
|
+
const baseEnv = {
|
|
7922
|
+
ACCOUNT_ID: accountId,
|
|
7923
|
+
PLATFORM_ROOT: PLATFORM_ROOT4,
|
|
7924
|
+
LOG_DIR: LOG_DIR2,
|
|
7925
|
+
STREAM_LOG_PATH,
|
|
7926
|
+
NEO4J_URI: requireNeo4jUri()
|
|
7927
|
+
};
|
|
7871
7928
|
const servers = {
|
|
7872
7929
|
"memory": {
|
|
7873
7930
|
command: "node",
|
|
@@ -7938,7 +7995,6 @@ function getMcpServers(accountId, conversationId, userId, enabledPlugins) {
|
|
|
7938
7995
|
env: {
|
|
7939
7996
|
...baseEnv,
|
|
7940
7997
|
BRAND: readBrandHostname(),
|
|
7941
|
-
NEO4J_URI: process.env.NEO4J_URI ?? "bolt://localhost:7687",
|
|
7942
7998
|
NEO4J_USERNAME: process.env.NEO4J_USERNAME ?? process.env.NEO4J_USER ?? "neo4j",
|
|
7943
7999
|
NEO4J_NAMESPACE: "maxy-graph",
|
|
7944
8000
|
NEO4J_READ_ONLY: "true",
|
|
@@ -8306,7 +8362,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
|
8306
8362
|
proc.stderr.on("data", (chunk) => {
|
|
8307
8363
|
stderrBuf += chunk.toString();
|
|
8308
8364
|
});
|
|
8309
|
-
proc.on("error", (
|
|
8365
|
+
proc.on("error", (err) => settle(null, `spawn error: ${err.message}`));
|
|
8310
8366
|
proc.on("close", (code) => {
|
|
8311
8367
|
if (!settled) settle(null, `process exited with code ${code}`);
|
|
8312
8368
|
});
|
|
@@ -8470,11 +8526,11 @@ ${truncatedResponse}` : "No response text was generated.",
|
|
|
8470
8526
|
streamLog.write(`[${isoTs()}] [context-overflow-recovery] summary=fallback reason=haiku-empty
|
|
8471
8527
|
`);
|
|
8472
8528
|
return basicTemplate;
|
|
8473
|
-
} catch (
|
|
8474
|
-
const reason =
|
|
8529
|
+
} catch (err) {
|
|
8530
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
8475
8531
|
streamLog.write(`[${isoTs()}] [context-overflow-recovery] summary=fallback reason=${reason}
|
|
8476
8532
|
`);
|
|
8477
|
-
if (!(
|
|
8533
|
+
if (!(err instanceof Error && (err.name === "AbortError" || reason.includes("ECONNREFUSED") || reason.includes("ENOTFOUND")))) {
|
|
8478
8534
|
console.error(`[context-overflow-recovery] Haiku summary failed: ${reason}`);
|
|
8479
8535
|
}
|
|
8480
8536
|
return basicTemplate;
|
|
@@ -8584,9 +8640,9 @@ Extract preference updates as JSON array.`
|
|
|
8584
8640
|
console.error(`[profile-reflection] Extracted ${sanitized.length} preference updates via Haiku (${updates.length - sanitized.length} filtered)`);
|
|
8585
8641
|
const convId = sessionStore.get(sessionKey)?.conversationId;
|
|
8586
8642
|
return await writeReflectionPreferences(accountId, userId, convId, sanitized);
|
|
8587
|
-
} catch (
|
|
8588
|
-
const reason =
|
|
8589
|
-
if (
|
|
8643
|
+
} catch (err) {
|
|
8644
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
8645
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
8590
8646
|
console.error(`[profile-reflection] Haiku call timed out after ${REFLECTION_TIMEOUT_MS}ms`);
|
|
8591
8647
|
} else {
|
|
8592
8648
|
console.error(`[profile-reflection] Haiku call failed: ${reason}`);
|
|
@@ -8694,8 +8750,8 @@ async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSes
|
|
|
8694
8750
|
`);
|
|
8695
8751
|
streamLog.write(`[${isoTs()}] [compaction-start] resumeSessionId=${resumeSessionId}
|
|
8696
8752
|
`);
|
|
8697
|
-
proc.on("error", (
|
|
8698
|
-
if (!streamLog.destroyed && !streamLog.writableEnded) streamLog.write(`[${isoTs()}] [compaction-spawn-error] ${
|
|
8753
|
+
proc.on("error", (err) => {
|
|
8754
|
+
if (!streamLog.destroyed && !streamLog.writableEnded) streamLog.write(`[${isoTs()}] [compaction-spawn-error] ${err.message}
|
|
8699
8755
|
`);
|
|
8700
8756
|
});
|
|
8701
8757
|
yield "Summarising session...";
|
|
@@ -8828,8 +8884,8 @@ async function* parseClaudeStream(proc, streamLog, adminModel, conversationId, a
|
|
|
8828
8884
|
streamLog.write(`[${isoTs()}] [tool-wait-diag]${convIdTag} name=${info.name} tool_use_id=${toolUseId} elapsed=${elapsedSec}s ${diag}
|
|
8829
8885
|
`);
|
|
8830
8886
|
}
|
|
8831
|
-
}).catch((
|
|
8832
|
-
const msg =
|
|
8887
|
+
}).catch((err) => {
|
|
8888
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
8833
8889
|
if (!streamLog.destroyed && !streamLog.writableEnded) {
|
|
8834
8890
|
streamLog.write(`[${isoTs()}] [tool-wait-diag]${convIdTag} name=${info.name} tool_use_id=${toolUseId} elapsed=${elapsedSec}s diag_err=${JSON.stringify(msg.slice(0, 80))}
|
|
8835
8891
|
`);
|
|
@@ -9131,9 +9187,9 @@ async function* parseClaudeStream(proc, streamLog, adminModel, conversationId, a
|
|
|
9131
9187
|
streamLog.write(`[${isoTs()}] [tool-failure-diag]${convIdTag} name=${name} ${diag}
|
|
9132
9188
|
`);
|
|
9133
9189
|
}
|
|
9134
|
-
} catch (
|
|
9190
|
+
} catch (err) {
|
|
9135
9191
|
if (!streamLog.destroyed) {
|
|
9136
|
-
const msg2 =
|
|
9192
|
+
const msg2 = err instanceof Error ? err.message : String(err);
|
|
9137
9193
|
streamLog.write(`[${isoTs()}] [tool-failure-diag]${convIdTag} name=${name} diag_err=${JSON.stringify(msg2.slice(0, 80))}
|
|
9138
9194
|
`);
|
|
9139
9195
|
}
|
|
@@ -9625,8 +9681,8 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9625
9681
|
`);
|
|
9626
9682
|
if (sessionKey) activeProcesses.delete(sessionKey);
|
|
9627
9683
|
});
|
|
9628
|
-
proc.on("error", (
|
|
9629
|
-
if (!streamLog.destroyed && !streamLog.writableEnded) streamLog.write(`[${isoTs()}] [spawn-error] ${
|
|
9684
|
+
proc.on("error", (err) => {
|
|
9685
|
+
if (!streamLog.destroyed && !streamLog.writableEnded) streamLog.write(`[${isoTs()}] [spawn-error] ${err.message}
|
|
9630
9686
|
`);
|
|
9631
9687
|
});
|
|
9632
9688
|
let currentAgentSessionId;
|
|
@@ -9700,8 +9756,8 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9700
9756
|
const reflectionUserId = getUserIdForSession(sessionKey);
|
|
9701
9757
|
if (reflectionUserId) {
|
|
9702
9758
|
const profileForReflection = await loadUserProfile(accountId, reflectionUserId);
|
|
9703
|
-
reflectOnSessionProfile(accountId, reflectionUserId, sessionKey, profileForReflection).catch((
|
|
9704
|
-
console.error(`[profile-reflection] Unhandled error: ${
|
|
9759
|
+
reflectOnSessionProfile(accountId, reflectionUserId, sessionKey, profileForReflection).catch((err) => {
|
|
9760
|
+
console.error(`[profile-reflection] Unhandled error: ${err instanceof Error ? err.message : String(err)}`);
|
|
9705
9761
|
});
|
|
9706
9762
|
}
|
|
9707
9763
|
clearAgentSessionId(sessionKey, "compaction-complete");
|
|
@@ -9730,8 +9786,8 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9730
9786
|
(step.value.summary ? step.value.summary + "\n\n" : "") + "Recovered conversation context:\n" + contextPairs
|
|
9731
9787
|
);
|
|
9732
9788
|
}
|
|
9733
|
-
} catch (
|
|
9734
|
-
console.error(`[persist] Context re-seeding failed: ${
|
|
9789
|
+
} catch (err) {
|
|
9790
|
+
console.error(`[persist] Context re-seeding failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
9735
9791
|
}
|
|
9736
9792
|
}
|
|
9737
9793
|
}
|
|
@@ -9743,8 +9799,8 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9743
9799
|
yield { type: "status", message: step.value };
|
|
9744
9800
|
step = await compactionIter.next();
|
|
9745
9801
|
}
|
|
9746
|
-
} catch (
|
|
9747
|
-
const msg =
|
|
9802
|
+
} catch (err) {
|
|
9803
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
9748
9804
|
streamLog.write(`[${isoTs()}] [session-reset] compaction failed: ${msg}
|
|
9749
9805
|
`);
|
|
9750
9806
|
yield { type: "status", message: "Compaction failed \u2014 resetting anyway." };
|
|
@@ -9865,8 +9921,8 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9865
9921
|
}
|
|
9866
9922
|
const pendingTrimmed = consumePendingTrimmedMessages(sessionKey);
|
|
9867
9923
|
if (pendingTrimmed && pendingTrimmed.length > 0) {
|
|
9868
|
-
const
|
|
9869
|
-
if (!
|
|
9924
|
+
const ok = await compactTrimmedMessages(accountId, pendingTrimmed);
|
|
9925
|
+
if (!ok) {
|
|
9870
9926
|
storePendingTrimmedMessages(sessionKey, pendingTrimmed);
|
|
9871
9927
|
}
|
|
9872
9928
|
}
|
|
@@ -9890,8 +9946,8 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9890
9946
|
const trimmed = trimHistory(sessionKey, historyBudget);
|
|
9891
9947
|
if (trimmed.length > 0) {
|
|
9892
9948
|
yield { type: "status", message: "Archiving older messages..." };
|
|
9893
|
-
const
|
|
9894
|
-
if (!
|
|
9949
|
+
const ok = await compactTrimmedMessages(accountId, trimmed);
|
|
9950
|
+
if (!ok) {
|
|
9895
9951
|
storePendingTrimmedMessages(sessionKey, trimmed);
|
|
9896
9952
|
}
|
|
9897
9953
|
}
|
|
@@ -9961,8 +10017,8 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9961
10017
|
`);
|
|
9962
10018
|
if (sessionKey) activeProcesses.delete(sessionKey);
|
|
9963
10019
|
});
|
|
9964
|
-
proc.on("error", (
|
|
9965
|
-
if (!streamLog.destroyed && !streamLog.writableEnded) streamLog.write(`[${isoTs()}] [spawn-error] ${
|
|
10020
|
+
proc.on("error", (err) => {
|
|
10021
|
+
if (!streamLog.destroyed && !streamLog.writableEnded) streamLog.write(`[${isoTs()}] [spawn-error] ${err.message}
|
|
9966
10022
|
`);
|
|
9967
10023
|
});
|
|
9968
10024
|
let responseText = "";
|
|
@@ -10032,8 +10088,8 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
10032
10088
|
yield { type: "status", message: step.value };
|
|
10033
10089
|
step = await compactionIter.next();
|
|
10034
10090
|
}
|
|
10035
|
-
} catch (
|
|
10036
|
-
const msg =
|
|
10091
|
+
} catch (err) {
|
|
10092
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
10037
10093
|
streamLog.write(`[${isoTs()}] [session-reset] compaction failed: ${msg}
|
|
10038
10094
|
`);
|
|
10039
10095
|
yield { type: "status", message: "Compaction failed \u2014 resetting anyway." };
|
|
@@ -10188,8 +10244,8 @@ async function* invokePublicAgent(message, systemPrompt, accountId, accountDir,
|
|
|
10188
10244
|
if (sessionKey) {
|
|
10189
10245
|
const pendingTrimmed = consumePendingTrimmedMessages(sessionKey);
|
|
10190
10246
|
if (pendingTrimmed && pendingTrimmed.length > 0) {
|
|
10191
|
-
const
|
|
10192
|
-
if (!
|
|
10247
|
+
const ok = await compactTrimmedMessages(accountId, pendingTrimmed);
|
|
10248
|
+
if (!ok) {
|
|
10193
10249
|
storePendingTrimmedMessages(sessionKey, pendingTrimmed);
|
|
10194
10250
|
}
|
|
10195
10251
|
}
|
|
@@ -10200,8 +10256,8 @@ async function* invokePublicAgent(message, systemPrompt, accountId, accountDir,
|
|
|
10200
10256
|
const trimmed = trimHistory(sessionKey, historyBudget);
|
|
10201
10257
|
if (trimmed.length > 0) {
|
|
10202
10258
|
yield { type: "status", message: "Archiving older messages..." };
|
|
10203
|
-
const
|
|
10204
|
-
if (!
|
|
10259
|
+
const ok = await compactTrimmedMessages(accountId, trimmed);
|
|
10260
|
+
if (!ok) {
|
|
10205
10261
|
storePendingTrimmedMessages(sessionKey, trimmed);
|
|
10206
10262
|
}
|
|
10207
10263
|
}
|
|
@@ -10446,12 +10502,12 @@ async function* compactSession(sessionKey) {
|
|
|
10446
10502
|
const history = getMessageHistory(sessionKey);
|
|
10447
10503
|
if (history.length === 0) return { ok: true };
|
|
10448
10504
|
yield "Saving to memory...";
|
|
10449
|
-
const
|
|
10450
|
-
if (
|
|
10505
|
+
const ok = await compactTrimmedMessages(account.accountId, history);
|
|
10506
|
+
if (ok) {
|
|
10451
10507
|
if (session) session.messageHistory = [];
|
|
10452
10508
|
}
|
|
10453
10509
|
yield "Closing session...";
|
|
10454
|
-
return { ok
|
|
10510
|
+
return { ok };
|
|
10455
10511
|
}
|
|
10456
10512
|
const currentSessionId = getAgentSessionId(sessionKey);
|
|
10457
10513
|
if (!currentSessionId) return { ok: false, reason: "no-session" };
|
|
@@ -10477,8 +10533,8 @@ ${EXPLANATORY_STYLE_INSTRUCTIONS}` : baseSystemPrompt;
|
|
|
10477
10533
|
const compactUserId = getUserIdForSession(sessionKey);
|
|
10478
10534
|
if (compactAgentType === "admin" && compactUserId) {
|
|
10479
10535
|
const currentProfile = await loadUserProfile(account.accountId, compactUserId);
|
|
10480
|
-
reflectOnSessionProfile(account.accountId, compactUserId, sessionKey, currentProfile).catch((
|
|
10481
|
-
console.error(`[profile-reflection] Unhandled error: ${
|
|
10536
|
+
reflectOnSessionProfile(account.accountId, compactUserId, sessionKey, currentProfile).catch((err) => {
|
|
10537
|
+
console.error(`[profile-reflection] Unhandled error: ${err instanceof Error ? err.message : String(err)}`);
|
|
10482
10538
|
});
|
|
10483
10539
|
}
|
|
10484
10540
|
clearAgentSessionId(sessionKey, "session-compact-complete");
|
|
@@ -10569,8 +10625,8 @@ ${sessionContext}`;
|
|
|
10569
10625
|
let skillContent = "";
|
|
10570
10626
|
try {
|
|
10571
10627
|
skillContent = readFileSync7(skillPath, "utf-8");
|
|
10572
|
-
} catch (
|
|
10573
|
-
console.error(`[onboarding-inject] accountId=${accountId.slice(0, 8)}\u2026 error=skill-read-failed path=${skillPath} reason=${
|
|
10628
|
+
} catch (err) {
|
|
10629
|
+
console.error(`[onboarding-inject] accountId=${accountId.slice(0, 8)}\u2026 error=skill-read-failed path=${skillPath} reason=${err instanceof Error ? err.message : String(err)}`);
|
|
10574
10630
|
}
|
|
10575
10631
|
const skillBytes = Buffer.byteLength(skillContent, "utf-8");
|
|
10576
10632
|
if (skillContent.length > 0) {
|
|
@@ -10624,8 +10680,8 @@ ${manifest}`;
|
|
|
10624
10680
|
baseSystemPrompt += `
|
|
10625
10681
|
|
|
10626
10682
|
${graphRef}`;
|
|
10627
|
-
} catch (
|
|
10628
|
-
console.error(`[graph-primitives] reference missing at ${graphRefPath} \u2014 admin session will have no Cypher cookbook: ${
|
|
10683
|
+
} catch (err) {
|
|
10684
|
+
console.error(`[graph-primitives] reference missing at ${graphRefPath} \u2014 admin session will have no Cypher cookbook: ${err instanceof Error ? err.message : String(err)}`);
|
|
10629
10685
|
}
|
|
10630
10686
|
}
|
|
10631
10687
|
if (agentConfig?.budget) {
|
|
@@ -10709,8 +10765,8 @@ ${gwParts.join("\n")}`;
|
|
|
10709
10765
|
if (sessionKey) {
|
|
10710
10766
|
try {
|
|
10711
10767
|
await ensureConversation(accountId, agentType, sessionKey, void 0, void 0, sessionUserId);
|
|
10712
|
-
} catch (
|
|
10713
|
-
console.error(`[persist] ensureConversation failed in invokeAgent: ${
|
|
10768
|
+
} catch (err) {
|
|
10769
|
+
console.error(`[persist] ensureConversation failed in invokeAgent: ${err instanceof Error ? err.message : String(err)}`);
|
|
10714
10770
|
}
|
|
10715
10771
|
}
|
|
10716
10772
|
if (agentType !== "public") {
|
|
@@ -10724,8 +10780,8 @@ ${gwParts.join("\n")}`;
|
|
|
10724
10780
|
const classifyStartMs = Date.now();
|
|
10725
10781
|
const [adminClassification, commitments] = await Promise.all([
|
|
10726
10782
|
needsTopicCheck ? classifyMemoryQuery(message, history) : Promise.resolve(QUERY_CLASSIFIER_FALLBACK),
|
|
10727
|
-
classifyCommitments(message, history).catch((
|
|
10728
|
-
console.error(`[commitment-classifier] unexpected error: ${
|
|
10783
|
+
classifyCommitments(message, history).catch((err) => {
|
|
10784
|
+
console.error(`[commitment-classifier] unexpected error: ${err instanceof Error ? err.message : String(err)}`);
|
|
10729
10785
|
return [];
|
|
10730
10786
|
})
|
|
10731
10787
|
]);
|
|
@@ -10755,8 +10811,8 @@ ${block}`;
|
|
|
10755
10811
|
}
|
|
10756
10812
|
console.log(`[commitment-offer] sessionKey=${sk}\u2026 count=${commitments.filter((c) => c.confidence >= COMMITMENT_CONFIDENCE_THRESHOLD).length} summaries=${commitments.filter((c) => c.confidence >= COMMITMENT_CONFIDENCE_THRESHOLD).map((c) => JSON.stringify(c.what)).join(",")}`);
|
|
10757
10813
|
}
|
|
10758
|
-
} catch (
|
|
10759
|
-
console.error(`[commitment-classifier] block error: ${
|
|
10814
|
+
} catch (err) {
|
|
10815
|
+
console.error(`[commitment-classifier] block error: ${err instanceof Error ? err.message : String(err)}`);
|
|
10760
10816
|
}
|
|
10761
10817
|
}
|
|
10762
10818
|
if (agentType === "public") {
|
|
@@ -11229,8 +11285,8 @@ function loadRules(configDir2) {
|
|
|
11229
11285
|
let parsed;
|
|
11230
11286
|
try {
|
|
11231
11287
|
parsed = JSON.parse(raw2);
|
|
11232
|
-
} catch (
|
|
11233
|
-
throw new Error(`rules file ${path2} is not valid JSON: ${
|
|
11288
|
+
} catch (err) {
|
|
11289
|
+
throw new Error(`rules file ${path2} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
11234
11290
|
}
|
|
11235
11291
|
return validateRulesFile(parsed, path2);
|
|
11236
11292
|
}
|
|
@@ -11319,8 +11375,8 @@ function validateRule(input, label, seenIds) {
|
|
|
11319
11375
|
if (pattern.length > 0) {
|
|
11320
11376
|
try {
|
|
11321
11377
|
new RegExp(pattern);
|
|
11322
|
-
} catch (
|
|
11323
|
-
throw new Error(`${label}: pattern is not a valid regex: ${
|
|
11378
|
+
} catch (err) {
|
|
11379
|
+
throw new Error(`${label}: pattern is not a valid regex: ${err instanceof Error ? err.message : String(err)}`);
|
|
11324
11380
|
}
|
|
11325
11381
|
}
|
|
11326
11382
|
const thresholdCount = r.thresholdCount;
|
|
@@ -11351,8 +11407,8 @@ function validateRule(input, label, seenIds) {
|
|
|
11351
11407
|
if (r.followupPattern.length > 0) {
|
|
11352
11408
|
try {
|
|
11353
11409
|
new RegExp(r.followupPattern);
|
|
11354
|
-
} catch (
|
|
11355
|
-
throw new Error(`${label}: followupPattern is not a valid regex: ${
|
|
11410
|
+
} catch (err) {
|
|
11411
|
+
throw new Error(`${label}: followupPattern is not a valid regex: ${err instanceof Error ? err.message : String(err)}`);
|
|
11356
11412
|
}
|
|
11357
11413
|
}
|
|
11358
11414
|
rule.followupPattern = r.followupPattern;
|
|
@@ -11410,8 +11466,8 @@ function loadTailState(configDir2) {
|
|
|
11410
11466
|
}
|
|
11411
11467
|
}
|
|
11412
11468
|
return clean;
|
|
11413
|
-
} catch (
|
|
11414
|
-
console.error(`[review] tail state corrupt at ${path2}, starting fresh: ${
|
|
11469
|
+
} catch (err) {
|
|
11470
|
+
console.error(`[review] tail state corrupt at ${path2}, starting fresh: ${err instanceof Error ? err.message : String(err)}`);
|
|
11415
11471
|
return {};
|
|
11416
11472
|
}
|
|
11417
11473
|
}
|
|
@@ -11587,8 +11643,8 @@ function reviewLog(configDir2, event) {
|
|
|
11587
11643
|
).toISOString()} [review] ${JSON.stringify(event)}
|
|
11588
11644
|
`;
|
|
11589
11645
|
appendFileSync3(path2, line, "utf-8");
|
|
11590
|
-
} catch (
|
|
11591
|
-
console.error(`[review] failed to write review log at ${path2}: ${
|
|
11646
|
+
} catch (err) {
|
|
11647
|
+
console.error(`[review] failed to write review log at ${path2}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11592
11648
|
}
|
|
11593
11649
|
}
|
|
11594
11650
|
async function ensureReviewAlertIndex() {
|
|
@@ -11701,8 +11757,8 @@ function queueAlert(configDir2, accountId, match2) {
|
|
|
11701
11757
|
mkdirSync7(dirname4(path2), { recursive: true });
|
|
11702
11758
|
const line = JSON.stringify({ accountId, match: match2 }) + "\n";
|
|
11703
11759
|
appendFileSync3(path2, line, "utf-8");
|
|
11704
|
-
} catch (
|
|
11705
|
-
console.error(`[review] failed to queue alert at ${path2}: ${
|
|
11760
|
+
} catch (err) {
|
|
11761
|
+
console.error(`[review] failed to queue alert at ${path2}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11706
11762
|
}
|
|
11707
11763
|
}
|
|
11708
11764
|
async function drainPendingAlerts(configDir2) {
|
|
@@ -11754,13 +11810,13 @@ async function bootDetector() {
|
|
|
11754
11810
|
let rulesFile;
|
|
11755
11811
|
try {
|
|
11756
11812
|
rulesFile = loadRules(configDir2);
|
|
11757
|
-
} catch (
|
|
11813
|
+
} catch (err) {
|
|
11758
11814
|
reviewLog(configDir2, {
|
|
11759
11815
|
event: "boot-failed",
|
|
11760
11816
|
reason: "rules-invalid",
|
|
11761
|
-
error:
|
|
11817
|
+
error: err instanceof Error ? err.message : String(err)
|
|
11762
11818
|
});
|
|
11763
|
-
console.error(`[review] boot: rules file invalid \u2014 ${
|
|
11819
|
+
console.error(`[review] boot: rules file invalid \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
11764
11820
|
return null;
|
|
11765
11821
|
}
|
|
11766
11822
|
if (addMissingDefaultRules(rulesFile)) {
|
|
@@ -11776,22 +11832,22 @@ async function bootDetector() {
|
|
|
11776
11832
|
try {
|
|
11777
11833
|
await ensureReviewAlertIndex();
|
|
11778
11834
|
reviewLog(configDir2, { event: "neo4j-index-ensured" });
|
|
11779
|
-
} catch (
|
|
11835
|
+
} catch (err) {
|
|
11780
11836
|
reviewLog(configDir2, {
|
|
11781
11837
|
event: "neo4j-index-failed",
|
|
11782
|
-
error:
|
|
11838
|
+
error: err instanceof Error ? err.message : String(err)
|
|
11783
11839
|
});
|
|
11784
|
-
console.error(`[review] boot: ensureReviewAlertIndex failed (continuing): ${
|
|
11840
|
+
console.error(`[review] boot: ensureReviewAlertIndex failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
11785
11841
|
}
|
|
11786
11842
|
try {
|
|
11787
11843
|
await ensureReviewDigestSchedule(accountId);
|
|
11788
11844
|
reviewLog(configDir2, { event: "digest-schedule-ensured" });
|
|
11789
|
-
} catch (
|
|
11845
|
+
} catch (err) {
|
|
11790
11846
|
reviewLog(configDir2, {
|
|
11791
11847
|
event: "digest-schedule-failed",
|
|
11792
|
-
error:
|
|
11848
|
+
error: err instanceof Error ? err.message : String(err)
|
|
11793
11849
|
});
|
|
11794
|
-
console.error(`[review] boot: ensureReviewDigestSchedule failed (continuing): ${
|
|
11850
|
+
console.error(`[review] boot: ensureReviewDigestSchedule failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
11795
11851
|
}
|
|
11796
11852
|
const tailState = loadTailState(configDir2);
|
|
11797
11853
|
const logDir = accountLogDir(accountDir);
|
|
@@ -12048,13 +12104,13 @@ async function runScanCycle(runtime) {
|
|
|
12048
12104
|
rulesLoaded: runtime.rulesFile.rules.length,
|
|
12049
12105
|
mtime: new Date(currentMtime).toISOString()
|
|
12050
12106
|
});
|
|
12051
|
-
} catch (
|
|
12107
|
+
} catch (err) {
|
|
12052
12108
|
reviewLog(runtime.configDir, {
|
|
12053
12109
|
event: "rules-reload-failed",
|
|
12054
|
-
error:
|
|
12110
|
+
error: err instanceof Error ? err.message : String(err)
|
|
12055
12111
|
});
|
|
12056
12112
|
runtime.snapshot.state = "degraded";
|
|
12057
|
-
runtime.snapshot.lastError =
|
|
12113
|
+
runtime.snapshot.lastError = err instanceof Error ? err.message : String(err);
|
|
12058
12114
|
}
|
|
12059
12115
|
}
|
|
12060
12116
|
const logDir = accountLogDir(runtime.accountDir);
|
|
@@ -12181,12 +12237,12 @@ async function runScanCycle(runtime) {
|
|
|
12181
12237
|
try {
|
|
12182
12238
|
await upsertReviewAlert(runtime.accountId, match2);
|
|
12183
12239
|
reviewLog(runtime.configDir, { event: "alert-persisted", ruleId: match2.ruleId });
|
|
12184
|
-
} catch (
|
|
12240
|
+
} catch (err) {
|
|
12185
12241
|
queueAlert(runtime.configDir, runtime.accountId, match2);
|
|
12186
12242
|
reviewLog(runtime.configDir, {
|
|
12187
12243
|
event: "alert-queued",
|
|
12188
12244
|
ruleId: match2.ruleId,
|
|
12189
|
-
error:
|
|
12245
|
+
error: err instanceof Error ? err.message : String(err)
|
|
12190
12246
|
});
|
|
12191
12247
|
}
|
|
12192
12248
|
}
|
|
@@ -12199,18 +12255,18 @@ async function runScanCycle(runtime) {
|
|
|
12199
12255
|
remaining: drain.remaining
|
|
12200
12256
|
});
|
|
12201
12257
|
}
|
|
12202
|
-
} catch (
|
|
12258
|
+
} catch (err) {
|
|
12203
12259
|
reviewLog(runtime.configDir, {
|
|
12204
12260
|
event: "queue-drain-failed",
|
|
12205
|
-
error:
|
|
12261
|
+
error: err instanceof Error ? err.message : String(err)
|
|
12206
12262
|
});
|
|
12207
12263
|
}
|
|
12208
12264
|
try {
|
|
12209
12265
|
runtime.snapshot.activeAlerts = await countActiveReviewAlerts(runtime.accountId);
|
|
12210
|
-
} catch (
|
|
12266
|
+
} catch (err) {
|
|
12211
12267
|
reviewLog(runtime.configDir, {
|
|
12212
12268
|
event: "active-alerts-count-failed",
|
|
12213
|
-
error:
|
|
12269
|
+
error: err instanceof Error ? err.message : String(err)
|
|
12214
12270
|
});
|
|
12215
12271
|
}
|
|
12216
12272
|
saveTailState(runtime.configDir, runtime.tailState);
|
|
@@ -12229,12 +12285,12 @@ async function runScanCycle(runtime) {
|
|
|
12229
12285
|
matches: matches.length,
|
|
12230
12286
|
durationMs: cycleDuration
|
|
12231
12287
|
});
|
|
12232
|
-
} catch (
|
|
12288
|
+
} catch (err) {
|
|
12233
12289
|
runtime.snapshot.state = "degraded";
|
|
12234
|
-
runtime.snapshot.lastError =
|
|
12290
|
+
runtime.snapshot.lastError = err instanceof Error ? err.message : String(err);
|
|
12235
12291
|
reviewLog(runtime.configDir, {
|
|
12236
12292
|
event: "cycle-failed",
|
|
12237
|
-
error:
|
|
12293
|
+
error: err instanceof Error ? err.message : String(err)
|
|
12238
12294
|
});
|
|
12239
12295
|
}
|
|
12240
12296
|
}
|
|
@@ -12277,16 +12333,16 @@ async function startReviewDetector() {
|
|
|
12277
12333
|
activeRuntime = await bootDetector();
|
|
12278
12334
|
if (!activeRuntime) return;
|
|
12279
12335
|
stopFn = startScanLoop(activeRuntime);
|
|
12280
|
-
} catch (
|
|
12281
|
-
console.error(`[review] detector start failed: ${
|
|
12336
|
+
} catch (err) {
|
|
12337
|
+
console.error(`[review] detector start failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
12282
12338
|
}
|
|
12283
12339
|
}
|
|
12284
12340
|
async function shutdownReviewDetector() {
|
|
12285
12341
|
if (!stopFn) return;
|
|
12286
12342
|
try {
|
|
12287
12343
|
await stopFn();
|
|
12288
|
-
} catch (
|
|
12289
|
-
console.error(`[review] detector shutdown error: ${
|
|
12344
|
+
} catch (err) {
|
|
12345
|
+
console.error(`[review] detector shutdown error: ${err instanceof Error ? err.message : String(err)}`);
|
|
12290
12346
|
}
|
|
12291
12347
|
stopFn = null;
|
|
12292
12348
|
activeRuntime = null;
|
|
@@ -12391,8 +12447,8 @@ function reloadManagerConfig(accountDir) {
|
|
|
12391
12447
|
const config = readConfig(accountDir);
|
|
12392
12448
|
reloadConfig(config);
|
|
12393
12449
|
console.error(`${TAG2} reloaded manager config`);
|
|
12394
|
-
} catch (
|
|
12395
|
-
console.error(`${TAG2} manager config reload failed: ${String(
|
|
12450
|
+
} catch (err) {
|
|
12451
|
+
console.error(`${TAG2} manager config reload failed: ${String(err)}`);
|
|
12396
12452
|
}
|
|
12397
12453
|
}
|
|
12398
12454
|
var E164_PATTERN = /^\+\d{7,15}$/;
|
|
@@ -12453,8 +12509,8 @@ function persistAfterPairing(accountDir, accountId, selfPhone) {
|
|
|
12453
12509
|
console.error(`${TAG2} persisted after pairing account=${accountId} phone=${selfPhone ?? "null"}`);
|
|
12454
12510
|
reloadManagerConfig(accountDir);
|
|
12455
12511
|
return { ok: true };
|
|
12456
|
-
} catch (
|
|
12457
|
-
const msg =
|
|
12512
|
+
} catch (err) {
|
|
12513
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12458
12514
|
console.error(`${TAG2} persist failed account=${accountId}: ${msg}`);
|
|
12459
12515
|
return { ok: false, error: msg };
|
|
12460
12516
|
}
|
|
@@ -12489,8 +12545,8 @@ function addAdminPhone(accountDir, phone) {
|
|
|
12489
12545
|
console.error(`${TAG2} added admin phone=${normalized}`);
|
|
12490
12546
|
reloadManagerConfig(accountDir);
|
|
12491
12547
|
return { ok: true, message: `Added ${normalized} as admin phone. Messages from this number will route to the admin agent.` };
|
|
12492
|
-
} catch (
|
|
12493
|
-
const msg =
|
|
12548
|
+
} catch (err) {
|
|
12549
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12494
12550
|
console.error(`${TAG2} addAdminPhone failed: ${msg}`);
|
|
12495
12551
|
return { ok: false, error: msg };
|
|
12496
12552
|
}
|
|
@@ -12523,8 +12579,8 @@ function removeAdminPhone(accountDir, phone) {
|
|
|
12523
12579
|
console.error(`${TAG2} removed admin phone=${normalized}`);
|
|
12524
12580
|
reloadManagerConfig(accountDir);
|
|
12525
12581
|
return { ok: true, message: `Removed ${normalized} from admin phones. Messages from this number will now route to the public agent.` };
|
|
12526
|
-
} catch (
|
|
12527
|
-
const msg =
|
|
12582
|
+
} catch (err) {
|
|
12583
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12528
12584
|
console.error(`${TAG2} removeAdminPhone failed: ${msg}`);
|
|
12529
12585
|
return { ok: false, error: msg };
|
|
12530
12586
|
}
|
|
@@ -12575,8 +12631,8 @@ function setPublicAgent(accountDir, slug) {
|
|
|
12575
12631
|
console.error(`${TAG2} publicAgent set to ${trimmed}`);
|
|
12576
12632
|
reloadManagerConfig(accountDir);
|
|
12577
12633
|
return { ok: true, message: `Public agent set to "${trimmed}". WhatsApp messages from non-admin phones will be handled by this agent.` };
|
|
12578
|
-
} catch (
|
|
12579
|
-
const msg =
|
|
12634
|
+
} catch (err) {
|
|
12635
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12580
12636
|
console.error(`${TAG2} setPublicAgent failed: ${msg}`);
|
|
12581
12637
|
return { ok: false, error: msg };
|
|
12582
12638
|
}
|
|
@@ -12621,8 +12677,8 @@ function updateConfig(accountDir, fields) {
|
|
|
12621
12677
|
console.error(`${TAG2} updated fields=[${fieldNames.join(",")}]`);
|
|
12622
12678
|
reloadManagerConfig(accountDir);
|
|
12623
12679
|
return { ok: true, message: `Updated WhatsApp config: ${fieldNames.join(", ")}.` };
|
|
12624
|
-
} catch (
|
|
12625
|
-
const msg =
|
|
12680
|
+
} catch (err) {
|
|
12681
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12626
12682
|
console.error(`${TAG2} updateConfig failed: ${msg}`);
|
|
12627
12683
|
return { ok: false, error: msg };
|
|
12628
12684
|
}
|
|
@@ -12682,8 +12738,8 @@ async function authExists(authDir) {
|
|
|
12682
12738
|
const raw2 = await fs.readFile(credsPath, "utf-8");
|
|
12683
12739
|
JSON.parse(raw2);
|
|
12684
12740
|
return true;
|
|
12685
|
-
} catch (
|
|
12686
|
-
console.warn(`${TAG3} credential validation failed path=${credsPath}: ${String(
|
|
12741
|
+
} catch (err) {
|
|
12742
|
+
console.warn(`${TAG3} credential validation failed path=${credsPath}: ${String(err)}`);
|
|
12687
12743
|
return false;
|
|
12688
12744
|
}
|
|
12689
12745
|
}
|
|
@@ -12711,8 +12767,8 @@ function maybeRestoreCredsFromBackup(authDir) {
|
|
|
12711
12767
|
JSON.parse(backupRaw);
|
|
12712
12768
|
fsSync.copyFileSync(backupPath, credsPath);
|
|
12713
12769
|
console.error(`${TAG3} restored corrupted creds.json from backup in ${authDir}`);
|
|
12714
|
-
} catch (
|
|
12715
|
-
console.warn(`${TAG3} credential restore failed authDir=${authDir}: ${String(
|
|
12770
|
+
} catch (err) {
|
|
12771
|
+
console.warn(`${TAG3} credential restore failed authDir=${authDir}: ${String(err)}`);
|
|
12716
12772
|
}
|
|
12717
12773
|
}
|
|
12718
12774
|
function readSelfId(authDir) {
|
|
@@ -12728,8 +12784,8 @@ function readSelfId(authDir) {
|
|
|
12728
12784
|
if (match2) e164 = match2[1];
|
|
12729
12785
|
}
|
|
12730
12786
|
return { e164, jid };
|
|
12731
|
-
} catch (
|
|
12732
|
-
console.warn(`${TAG3} readSelfId failed authDir=${authDir}: ${String(
|
|
12787
|
+
} catch (err) {
|
|
12788
|
+
console.warn(`${TAG3} readSelfId failed authDir=${authDir}: ${String(err)}`);
|
|
12733
12789
|
return { e164: null, jid: null };
|
|
12734
12790
|
}
|
|
12735
12791
|
}
|
|
@@ -12790,8 +12846,8 @@ function serializeArg(arg) {
|
|
|
12790
12846
|
if (typeof arg === "string") return arg;
|
|
12791
12847
|
try {
|
|
12792
12848
|
return inspect(arg, INSPECT_OPTS);
|
|
12793
|
-
} catch (
|
|
12794
|
-
return `[inspect-failed: ${String(
|
|
12849
|
+
} catch (err) {
|
|
12850
|
+
return `[inspect-failed: ${String(err)}]`;
|
|
12795
12851
|
}
|
|
12796
12852
|
}
|
|
12797
12853
|
function bindingsToPrefix(bindings) {
|
|
@@ -12861,12 +12917,12 @@ async function safeSaveCreds(authDir, saveCreds) {
|
|
|
12861
12917
|
try {
|
|
12862
12918
|
JSON.parse(raw2);
|
|
12863
12919
|
fsSync2.copyFileSync(credsPath, backupPath);
|
|
12864
|
-
} catch (
|
|
12865
|
-
console.warn(`${TAG4} backup pre-copy failed (parse or write) authDir=${authDir}: ${String(
|
|
12920
|
+
} catch (err) {
|
|
12921
|
+
console.warn(`${TAG4} backup pre-copy failed (parse or write) authDir=${authDir}: ${String(err)}`);
|
|
12866
12922
|
}
|
|
12867
12923
|
}
|
|
12868
|
-
} catch (
|
|
12869
|
-
console.warn(`${TAG4} backup preparation failed authDir=${authDir}: ${String(
|
|
12924
|
+
} catch (err) {
|
|
12925
|
+
console.warn(`${TAG4} backup preparation failed authDir=${authDir}: ${String(err)}`);
|
|
12870
12926
|
}
|
|
12871
12927
|
try {
|
|
12872
12928
|
await Promise.resolve(saveCreds());
|
|
@@ -12881,13 +12937,13 @@ async function safeSaveCreds(authDir, saveCreds) {
|
|
|
12881
12937
|
} catch (statErr) {
|
|
12882
12938
|
console.error(`${TAG4} creds NOT found on disk after save path=${credsPath}: ${String(statErr)}`);
|
|
12883
12939
|
}
|
|
12884
|
-
} catch (
|
|
12885
|
-
console.error(`${TAG4} failed saving creds to ${authDir}: ${String(
|
|
12940
|
+
} catch (err) {
|
|
12941
|
+
console.error(`${TAG4} failed saving creds to ${authDir}: ${String(err)}`);
|
|
12886
12942
|
}
|
|
12887
12943
|
}
|
|
12888
12944
|
function enqueueSaveCreds(authDir, saveCreds) {
|
|
12889
|
-
credsSaveQueue = credsSaveQueue.then(() => safeSaveCreds(authDir, saveCreds)).catch((
|
|
12890
|
-
console.error(`${TAG4} creds save queue error: ${String(
|
|
12945
|
+
credsSaveQueue = credsSaveQueue.then(() => safeSaveCreds(authDir, saveCreds)).catch((err) => {
|
|
12946
|
+
console.error(`${TAG4} creds save queue error: ${String(err)}`);
|
|
12891
12947
|
});
|
|
12892
12948
|
}
|
|
12893
12949
|
async function createWaSocket(opts) {
|
|
@@ -12946,13 +13002,13 @@ async function createWaSocket(opts) {
|
|
|
12946
13002
|
console.error(`${TAG4} connected`);
|
|
12947
13003
|
}
|
|
12948
13004
|
onConnectionUpdate?.(update);
|
|
12949
|
-
} catch (
|
|
12950
|
-
console.error(`${TAG4} connection.update handler error: ${String(
|
|
13005
|
+
} catch (err) {
|
|
13006
|
+
console.error(`${TAG4} connection.update handler error: ${String(err)}`);
|
|
12951
13007
|
}
|
|
12952
13008
|
});
|
|
12953
13009
|
if (sock.ws && typeof sock.ws.on === "function") {
|
|
12954
|
-
sock.ws.on("error", (
|
|
12955
|
-
console.error(`${TAG4} WebSocket error: ${String(
|
|
13010
|
+
sock.ws.on("error", (err) => {
|
|
13011
|
+
console.error(`${TAG4} WebSocket error: ${String(err)}`);
|
|
12956
13012
|
});
|
|
12957
13013
|
}
|
|
12958
13014
|
return sock;
|
|
@@ -12972,21 +13028,21 @@ async function waitForConnection(sock) {
|
|
|
12972
13028
|
sock.ev.on("connection.update", handler);
|
|
12973
13029
|
});
|
|
12974
13030
|
}
|
|
12975
|
-
function getStatusCode(
|
|
12976
|
-
return
|
|
13031
|
+
function getStatusCode(err) {
|
|
13032
|
+
return err?.error?.output?.statusCode ?? err?.output?.statusCode ?? err?.status;
|
|
12977
13033
|
}
|
|
12978
|
-
function formatError(
|
|
12979
|
-
if (
|
|
12980
|
-
if (typeof
|
|
12981
|
-
if (!
|
|
12982
|
-
const boom = extractBoomDetails(
|
|
12983
|
-
const status = boom?.statusCode ?? getStatusCode(
|
|
12984
|
-
const code =
|
|
13034
|
+
function formatError(err) {
|
|
13035
|
+
if (err instanceof Error) return err.message;
|
|
13036
|
+
if (typeof err === "string") return err;
|
|
13037
|
+
if (!err || typeof err !== "object") return String(err);
|
|
13038
|
+
const boom = extractBoomDetails(err) ?? extractBoomDetails(err?.error) ?? extractBoomDetails(err?.lastDisconnect?.error);
|
|
13039
|
+
const status = boom?.statusCode ?? getStatusCode(err);
|
|
13040
|
+
const code = err?.code;
|
|
12985
13041
|
const codeText = typeof code === "string" || typeof code === "number" ? String(code) : void 0;
|
|
12986
13042
|
const messageCandidates = [
|
|
12987
13043
|
boom?.message,
|
|
12988
|
-
typeof
|
|
12989
|
-
typeof
|
|
13044
|
+
typeof err?.message === "string" ? err.message : void 0,
|
|
13045
|
+
typeof err?.error?.message === "string" ? err.error.message : void 0
|
|
12990
13046
|
].filter((v) => Boolean(v?.trim()));
|
|
12991
13047
|
const message = messageCandidates[0];
|
|
12992
13048
|
const pieces = [];
|
|
@@ -12994,11 +13050,11 @@ function formatError(err2) {
|
|
|
12994
13050
|
if (boom?.error) pieces.push(boom.error);
|
|
12995
13051
|
if (message) pieces.push(message);
|
|
12996
13052
|
if (codeText) pieces.push(`code=${codeText}`);
|
|
12997
|
-
return pieces.length > 0 ? pieces.join(" ") : String(
|
|
13053
|
+
return pieces.length > 0 ? pieces.join(" ") : String(err);
|
|
12998
13054
|
}
|
|
12999
|
-
function extractBoomDetails(
|
|
13000
|
-
if (!
|
|
13001
|
-
const output =
|
|
13055
|
+
function extractBoomDetails(err) {
|
|
13056
|
+
if (!err || typeof err !== "object") return null;
|
|
13057
|
+
const output = err?.output;
|
|
13002
13058
|
if (!output || typeof output !== "object") return null;
|
|
13003
13059
|
const payload = output.payload;
|
|
13004
13060
|
const statusCode = typeof output.statusCode === "number" ? output.statusCode : typeof payload?.statusCode === "number" ? payload.statusCode : void 0;
|
|
@@ -13022,9 +13078,9 @@ function computeReconnectNextState(input) {
|
|
|
13022
13078
|
}
|
|
13023
13079
|
return { action: "retry", nextAttempts, reason: "short-lived" };
|
|
13024
13080
|
}
|
|
13025
|
-
function classifyDisconnect(
|
|
13026
|
-
const statusCode = getStatusCode(
|
|
13027
|
-
const message = formatError(
|
|
13081
|
+
function classifyDisconnect(err) {
|
|
13082
|
+
const statusCode = getStatusCode(err);
|
|
13083
|
+
const message = formatError(err);
|
|
13028
13084
|
if (statusCode === DisconnectReason2.loggedOut) {
|
|
13029
13085
|
return {
|
|
13030
13086
|
kind: "loggedOut",
|
|
@@ -13066,14 +13122,14 @@ var INSPECT_OPTS2 = {
|
|
|
13066
13122
|
compact: true,
|
|
13067
13123
|
maxArrayLength: 50
|
|
13068
13124
|
};
|
|
13069
|
-
function formatErr(
|
|
13070
|
-
if (
|
|
13071
|
-
const base = `${
|
|
13072
|
-
const inspected = inspect2(
|
|
13125
|
+
function formatErr(err) {
|
|
13126
|
+
if (err instanceof Error) {
|
|
13127
|
+
const base = `${err.name}: ${err.message}`;
|
|
13128
|
+
const inspected = inspect2(err, INSPECT_OPTS2);
|
|
13073
13129
|
return `${base}
|
|
13074
13130
|
${inspected}`;
|
|
13075
13131
|
}
|
|
13076
|
-
return inspect2(
|
|
13132
|
+
return inspect2(err, INSPECT_OPTS2);
|
|
13077
13133
|
}
|
|
13078
13134
|
function withTimeout(label, promise, timeoutMs) {
|
|
13079
13135
|
return new Promise((resolve33, reject) => {
|
|
@@ -13085,9 +13141,9 @@ function withTimeout(label, promise, timeoutMs) {
|
|
|
13085
13141
|
clearTimeout(timer);
|
|
13086
13142
|
resolve33(value);
|
|
13087
13143
|
},
|
|
13088
|
-
(
|
|
13144
|
+
(err) => {
|
|
13089
13145
|
clearTimeout(timer);
|
|
13090
|
-
reject(
|
|
13146
|
+
reject(err);
|
|
13091
13147
|
}
|
|
13092
13148
|
);
|
|
13093
13149
|
});
|
|
@@ -13128,8 +13184,8 @@ async function runInitQueries(sock, ctx) {
|
|
|
13128
13184
|
console.error(
|
|
13129
13185
|
`${TAG5} fetchBlocklist ok account=${ctx.accountId} count=${count}`
|
|
13130
13186
|
);
|
|
13131
|
-
} catch (
|
|
13132
|
-
const formatted = formatErr(
|
|
13187
|
+
} catch (err) {
|
|
13188
|
+
const formatted = formatErr(err);
|
|
13133
13189
|
result.errors.blocklist = formatted;
|
|
13134
13190
|
console.error(
|
|
13135
13191
|
`${TAG5} fetchBlocklist FAILED account=${ctx.accountId}: ${formatted}`
|
|
@@ -13155,8 +13211,8 @@ async function runInitQueries(sock, ctx) {
|
|
|
13155
13211
|
console.error(
|
|
13156
13212
|
`${TAG5} fetchPrivacySettings ok account=${ctx.accountId} keys=${settings ? Object.keys(settings).join(",") : ""}`
|
|
13157
13213
|
);
|
|
13158
|
-
} catch (
|
|
13159
|
-
const formatted = formatErr(
|
|
13214
|
+
} catch (err) {
|
|
13215
|
+
const formatted = formatErr(err);
|
|
13160
13216
|
result.errors.privacySettings = formatted;
|
|
13161
13217
|
console.error(
|
|
13162
13218
|
`${TAG5} fetchPrivacySettings FAILED account=${ctx.accountId}: ${formatted}`
|
|
@@ -13230,8 +13286,8 @@ async function resolveJidToE164(jid, lidMapping) {
|
|
|
13230
13286
|
return phone;
|
|
13231
13287
|
}
|
|
13232
13288
|
}
|
|
13233
|
-
} catch (
|
|
13234
|
-
console.error(`[whatsapp:normalize] LID mapping failed jid=${jid}: ${String(
|
|
13289
|
+
} catch (err) {
|
|
13290
|
+
console.error(`[whatsapp:normalize] LID mapping failed jid=${jid}: ${String(err)}`);
|
|
13235
13291
|
}
|
|
13236
13292
|
}
|
|
13237
13293
|
const lidMatch = jid.match(WHATSAPP_LID_RE);
|
|
@@ -13484,8 +13540,8 @@ function recordActivity(event) {
|
|
|
13484
13540
|
console.error(
|
|
13485
13541
|
`${TAG6} channel-activity: direction=${direction} account=${accountId} jid=${jid}` + (messageType ? ` type=${messageType}` : "")
|
|
13486
13542
|
);
|
|
13487
|
-
} catch (
|
|
13488
|
-
console.error(`${TAG6} recording failed: ${String(
|
|
13543
|
+
} catch (err) {
|
|
13544
|
+
console.error(`${TAG6} recording failed: ${String(err)}`);
|
|
13489
13545
|
}
|
|
13490
13546
|
}
|
|
13491
13547
|
function getChannelActivity(accountId) {
|
|
@@ -13524,9 +13580,9 @@ async function sendTextMessage(sock, to, text, opts) {
|
|
|
13524
13580
|
recordActivity({ accountId: opts.accountId, direction: "outbound", jid, messageType: "text" });
|
|
13525
13581
|
}
|
|
13526
13582
|
return { success: true, messageId: messageId ?? void 0 };
|
|
13527
|
-
} catch (
|
|
13528
|
-
console.error(`${TAG7} send failed to=${to}: ${String(
|
|
13529
|
-
return { success: false, error: String(
|
|
13583
|
+
} catch (err) {
|
|
13584
|
+
console.error(`${TAG7} send failed to=${to}: ${String(err)}`);
|
|
13585
|
+
return { success: false, error: String(err) };
|
|
13530
13586
|
}
|
|
13531
13587
|
}
|
|
13532
13588
|
async function sendReadReceipt(sock, chatJid, messageIds, participant) {
|
|
@@ -13586,9 +13642,9 @@ async function sendMediaMessage(sock, to, media, opts) {
|
|
|
13586
13642
|
recordActivity({ accountId: opts.accountId, direction: "outbound", jid, messageType: media.type });
|
|
13587
13643
|
}
|
|
13588
13644
|
return { success: true, messageId: messageId ?? void 0 };
|
|
13589
|
-
} catch (
|
|
13590
|
-
console.error(`${TAG7} send media failed to=${to}: ${String(
|
|
13591
|
-
return { success: false, error: String(
|
|
13645
|
+
} catch (err) {
|
|
13646
|
+
console.error(`${TAG7} send media failed to=${to}: ${String(err)}`);
|
|
13647
|
+
return { success: false, error: String(err) };
|
|
13592
13648
|
}
|
|
13593
13649
|
}
|
|
13594
13650
|
|
|
@@ -13690,8 +13746,8 @@ async function downloadInboundMedia(msg, sock, opts) {
|
|
|
13690
13746
|
mimetype: mimetype ?? "application/octet-stream",
|
|
13691
13747
|
size: buffer.length
|
|
13692
13748
|
};
|
|
13693
|
-
} catch (
|
|
13694
|
-
console.error(`${TAG8} media download failed type=${mimetype ?? "unknown"} error=${String(
|
|
13749
|
+
} catch (err) {
|
|
13750
|
+
console.error(`${TAG8} media download failed type=${mimetype ?? "unknown"} error=${String(err)}`);
|
|
13695
13751
|
return void 0;
|
|
13696
13752
|
}
|
|
13697
13753
|
}
|
|
@@ -13733,8 +13789,8 @@ function createInboundDebouncer(opts) {
|
|
|
13733
13789
|
if (result && typeof result.catch === "function") {
|
|
13734
13790
|
result.catch(onError);
|
|
13735
13791
|
}
|
|
13736
|
-
} catch (
|
|
13737
|
-
onError(
|
|
13792
|
+
} catch (err) {
|
|
13793
|
+
onError(err);
|
|
13738
13794
|
}
|
|
13739
13795
|
}
|
|
13740
13796
|
async function flush() {
|
|
@@ -13749,8 +13805,8 @@ function createInboundDebouncer(opts) {
|
|
|
13749
13805
|
if (result && typeof result.catch === "function") {
|
|
13750
13806
|
result.catch(onError);
|
|
13751
13807
|
}
|
|
13752
|
-
} catch (
|
|
13753
|
-
onError(
|
|
13808
|
+
} catch (err) {
|
|
13809
|
+
onError(err);
|
|
13754
13810
|
}
|
|
13755
13811
|
return;
|
|
13756
13812
|
}
|
|
@@ -13761,8 +13817,8 @@ function createInboundDebouncer(opts) {
|
|
|
13761
13817
|
if (result && typeof result.catch === "function") {
|
|
13762
13818
|
result.catch(onError);
|
|
13763
13819
|
}
|
|
13764
|
-
} catch (
|
|
13765
|
-
onError(
|
|
13820
|
+
} catch (err) {
|
|
13821
|
+
onError(err);
|
|
13766
13822
|
}
|
|
13767
13823
|
return;
|
|
13768
13824
|
}
|
|
@@ -13876,9 +13932,9 @@ async function isBusinessOpen(accountId) {
|
|
|
13876
13932
|
} finally {
|
|
13877
13933
|
await session.close();
|
|
13878
13934
|
}
|
|
13879
|
-
} catch (
|
|
13935
|
+
} catch (err) {
|
|
13880
13936
|
console.error(
|
|
13881
|
-
`${TAG10} [${accountId}] business hours check failed, treating as open: ${
|
|
13937
|
+
`${TAG10} [${accountId}] business hours check failed, treating as open: ${err instanceof Error ? err.message : String(err)}`
|
|
13882
13938
|
);
|
|
13883
13939
|
return { open: true, reason: "hours check failed (treating as open)" };
|
|
13884
13940
|
}
|
|
@@ -13956,8 +14012,8 @@ async function transcribe(audioPath, mimetype) {
|
|
|
13956
14012
|
// overwrite without prompting
|
|
13957
14013
|
wavPath
|
|
13958
14014
|
], { timeout: 3e4 });
|
|
13959
|
-
} catch (
|
|
13960
|
-
const reason =
|
|
14015
|
+
} catch (err) {
|
|
14016
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
13961
14017
|
console.error(`${TAG11} failed: ffmpeg conversion error=${reason}`);
|
|
13962
14018
|
return void 0;
|
|
13963
14019
|
}
|
|
@@ -13986,9 +14042,9 @@ async function transcribe(audioPath, mimetype) {
|
|
|
13986
14042
|
`${TAG11} done provider=whisper-local duration_ms=${durationMs} words=${words} lang=${language}`
|
|
13987
14043
|
);
|
|
13988
14044
|
return { text, language, durationMs };
|
|
13989
|
-
} catch (
|
|
14045
|
+
} catch (err) {
|
|
13990
14046
|
const durationMs = Date.now() - startMs;
|
|
13991
|
-
const reason =
|
|
14047
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
13992
14048
|
console.error(`${TAG11} failed provider=whisper-local duration_ms=${durationMs} error=${reason}`);
|
|
13993
14049
|
return void 0;
|
|
13994
14050
|
} finally {
|
|
@@ -14043,8 +14099,8 @@ async function init(opts) {
|
|
|
14043
14099
|
console.error(`${TAG12} skipping disabled account=${accountId}`);
|
|
14044
14100
|
continue;
|
|
14045
14101
|
}
|
|
14046
|
-
startConnection(accountId).catch((
|
|
14047
|
-
console.error(`${TAG12} failed to auto-start account=${accountId}: ${formatError(
|
|
14102
|
+
startConnection(accountId).catch((err) => {
|
|
14103
|
+
console.error(`${TAG12} failed to auto-start account=${accountId}: ${formatError(err)}`);
|
|
14048
14104
|
});
|
|
14049
14105
|
}
|
|
14050
14106
|
}
|
|
@@ -14088,8 +14144,8 @@ async function stopConnection(accountId) {
|
|
|
14088
14144
|
conn.sock.ev.removeAllListeners("connection.update");
|
|
14089
14145
|
conn.sock.ev.removeAllListeners("creds.update");
|
|
14090
14146
|
conn.sock.ws?.close?.();
|
|
14091
|
-
} catch (
|
|
14092
|
-
console.warn(`${TAG12} socket cleanup error during stop account=${accountId}: ${String(
|
|
14147
|
+
} catch (err) {
|
|
14148
|
+
console.warn(`${TAG12} socket cleanup error during stop account=${accountId}: ${String(err)}`);
|
|
14093
14149
|
}
|
|
14094
14150
|
}
|
|
14095
14151
|
connections.delete(accountId);
|
|
@@ -14135,8 +14191,8 @@ async function registerLoginSocket(accountId, sock, authDir) {
|
|
|
14135
14191
|
try {
|
|
14136
14192
|
await sock.sendPresenceUpdate("available");
|
|
14137
14193
|
console.error(`${TAG12} presence set to available account=${accountId}`);
|
|
14138
|
-
} catch (
|
|
14139
|
-
console.error(`${TAG12} presence update failed account=${accountId}: ${String(
|
|
14194
|
+
} catch (err) {
|
|
14195
|
+
console.error(`${TAG12} presence update failed account=${accountId}: ${String(err)}`);
|
|
14140
14196
|
}
|
|
14141
14197
|
await runInitQueries(sock, {
|
|
14142
14198
|
accountId,
|
|
@@ -14187,8 +14243,8 @@ function loadConfig(accountConfig) {
|
|
|
14187
14243
|
whatsAppConfig = {};
|
|
14188
14244
|
}
|
|
14189
14245
|
}
|
|
14190
|
-
} catch (
|
|
14191
|
-
console.error(`${TAG12} config load error: ${String(
|
|
14246
|
+
} catch (err) {
|
|
14247
|
+
console.error(`${TAG12} config load error: ${String(err)}`);
|
|
14192
14248
|
whatsAppConfig = {};
|
|
14193
14249
|
}
|
|
14194
14250
|
}
|
|
@@ -14219,8 +14275,8 @@ async function connectWithReconnect(conn) {
|
|
|
14219
14275
|
try {
|
|
14220
14276
|
await sock.sendPresenceUpdate("available");
|
|
14221
14277
|
console.error(`${TAG12} presence set to available account=${conn.accountId}`);
|
|
14222
|
-
} catch (
|
|
14223
|
-
console.error(`${TAG12} presence update failed account=${conn.accountId}: ${String(
|
|
14278
|
+
} catch (err) {
|
|
14279
|
+
console.error(`${TAG12} presence update failed account=${conn.accountId}: ${String(err)}`);
|
|
14224
14280
|
}
|
|
14225
14281
|
await runInitQueries(sock, {
|
|
14226
14282
|
accountId: conn.accountId,
|
|
@@ -14238,14 +14294,14 @@ async function connectWithReconnect(conn) {
|
|
|
14238
14294
|
uptimeMs = Date.now() - connectedAt;
|
|
14239
14295
|
conn.connected = false;
|
|
14240
14296
|
conn.sock = null;
|
|
14241
|
-
} catch (
|
|
14297
|
+
} catch (err) {
|
|
14242
14298
|
conn.connected = false;
|
|
14243
14299
|
conn.sock = null;
|
|
14244
|
-
cycleError =
|
|
14300
|
+
cycleError = err;
|
|
14245
14301
|
if (connectedAt) {
|
|
14246
14302
|
uptimeMs = Date.now() - connectedAt;
|
|
14247
14303
|
}
|
|
14248
|
-
const classification = classifyDisconnect(
|
|
14304
|
+
const classification = classifyDisconnect(err);
|
|
14249
14305
|
conn.lastError = classification.message;
|
|
14250
14306
|
console.error(`${TAG12} disconnect account=${conn.accountId}: ${classification.kind} \u2014 ${classification.message}`);
|
|
14251
14307
|
if (!classification.shouldRetry) {
|
|
@@ -14318,8 +14374,8 @@ function watchForDisconnect(conn) {
|
|
|
14318
14374
|
console.error(`${TAG12} socket disconnected for account=${conn.accountId}`);
|
|
14319
14375
|
conn.connected = false;
|
|
14320
14376
|
conn.sock = null;
|
|
14321
|
-
connectWithReconnect(conn).catch((
|
|
14322
|
-
console.error(`${TAG12} reconnection failed for account=${conn.accountId}: ${formatError(
|
|
14377
|
+
connectWithReconnect(conn).catch((err) => {
|
|
14378
|
+
console.error(`${TAG12} reconnection failed for account=${conn.accountId}: ${formatError(err)}`);
|
|
14323
14379
|
});
|
|
14324
14380
|
}
|
|
14325
14381
|
});
|
|
@@ -14346,9 +14402,9 @@ async function getGroupMeta(conn, jid) {
|
|
|
14346
14402
|
`${TAG12} group metadata cached for ${jid}: "${meta.subject}", ${participants.length} participants, expires in ${GROUP_META_TTL}ms account=${conn.accountId}`
|
|
14347
14403
|
);
|
|
14348
14404
|
return entry;
|
|
14349
|
-
} catch (
|
|
14405
|
+
} catch (err) {
|
|
14350
14406
|
console.error(
|
|
14351
|
-
`${TAG12} group metadata fetch failed for ${jid}: ${
|
|
14407
|
+
`${TAG12} group metadata fetch failed for ${jid}: ${err instanceof Error ? err.message : String(err)}, caching empty entry for ${GROUP_META_TTL}ms account=${conn.accountId}`
|
|
14352
14408
|
);
|
|
14353
14409
|
const emptyEntry = { expires: Date.now() + GROUP_META_TTL };
|
|
14354
14410
|
conn.groupMetaCache.set(jid, emptyEntry);
|
|
@@ -14384,8 +14440,8 @@ function monitorInbound(conn) {
|
|
|
14384
14440
|
mediaType: mediaEntry?.mediaType ?? last.mediaType
|
|
14385
14441
|
});
|
|
14386
14442
|
},
|
|
14387
|
-
onError: (
|
|
14388
|
-
console.error(`${TAG12} debounce flush error account=${conn.accountId}: ${String(
|
|
14443
|
+
onError: (err) => {
|
|
14444
|
+
console.error(`${TAG12} debounce flush error account=${conn.accountId}: ${String(err)}`);
|
|
14389
14445
|
}
|
|
14390
14446
|
});
|
|
14391
14447
|
sock.ev.on("messages.upsert", async (upsert) => {
|
|
@@ -14437,8 +14493,8 @@ function monitorInbound(conn) {
|
|
|
14437
14493
|
continue;
|
|
14438
14494
|
}
|
|
14439
14495
|
await handleInboundMessage(conn, msg);
|
|
14440
|
-
} catch (
|
|
14441
|
-
console.error(`${TAG12} inbound handler error account=${conn.accountId}: ${String(
|
|
14496
|
+
} catch (err) {
|
|
14497
|
+
console.error(`${TAG12} inbound handler error account=${conn.accountId}: ${String(err)}`);
|
|
14442
14498
|
}
|
|
14443
14499
|
}
|
|
14444
14500
|
});
|
|
@@ -14591,9 +14647,9 @@ async function handleInboundMessage(conn, msg) {
|
|
|
14591
14647
|
try {
|
|
14592
14648
|
await reply(afterHoursMessage);
|
|
14593
14649
|
console.error(`${TAG12} [${conn.accountId}] after-hours auto-reply sent to ${remoteJid}`);
|
|
14594
|
-
} catch (
|
|
14650
|
+
} catch (err) {
|
|
14595
14651
|
console.error(
|
|
14596
|
-
`${TAG12} [${conn.accountId}] after-hours auto-reply failed: ${
|
|
14652
|
+
`${TAG12} [${conn.accountId}] after-hours auto-reply failed: ${err instanceof Error ? err.message : String(err)}`
|
|
14597
14653
|
);
|
|
14598
14654
|
}
|
|
14599
14655
|
}
|
|
@@ -14650,8 +14706,8 @@ async function GET(req, remoteAddress) {
|
|
|
14650
14706
|
pinConfigured = Array.isArray(users) && users.length > 0;
|
|
14651
14707
|
}
|
|
14652
14708
|
}
|
|
14653
|
-
} catch (
|
|
14654
|
-
console.error(`[health] users.json corrupt \u2014 reporting pin_configured=false: ${
|
|
14709
|
+
} catch (err) {
|
|
14710
|
+
console.error(`[health] users.json corrupt \u2014 reporting pin_configured=false: ${err instanceof Error ? err.message : String(err)}`);
|
|
14655
14711
|
}
|
|
14656
14712
|
let authHealth;
|
|
14657
14713
|
try {
|
|
@@ -14685,8 +14741,8 @@ async function GET(req, remoteAddress) {
|
|
|
14685
14741
|
lastError: a.lastError ?? null,
|
|
14686
14742
|
sessionStuckReason: a.sessionStuckReason ?? null
|
|
14687
14743
|
}));
|
|
14688
|
-
} catch (
|
|
14689
|
-
console.error(`[health] failed to read WhatsApp status: ${
|
|
14744
|
+
} catch (err) {
|
|
14745
|
+
console.error(`[health] failed to read WhatsApp status: ${err instanceof Error ? err.message : String(err)}`);
|
|
14690
14746
|
}
|
|
14691
14747
|
const whatsappAnyConnected = whatsappAccounts.some((a) => a.connected);
|
|
14692
14748
|
const whatsappAnyStuck = whatsappAccounts.some((a) => Boolean(a.sessionStuckReason));
|
|
@@ -14737,8 +14793,8 @@ async function POST(req) {
|
|
|
14737
14793
|
let body;
|
|
14738
14794
|
try {
|
|
14739
14795
|
body = await req.json();
|
|
14740
|
-
} catch (
|
|
14741
|
-
console.error("[session] failed to parse request body:",
|
|
14796
|
+
} catch (err) {
|
|
14797
|
+
console.error("[session] failed to parse request body:", err);
|
|
14742
14798
|
return Response.json({ error: "Invalid request" }, { status: 400 });
|
|
14743
14799
|
}
|
|
14744
14800
|
if (!body.session_id || typeof body.session_id !== "string") {
|
|
@@ -14990,8 +15046,8 @@ function writeBrandingCache(accountId, agentSlug, branding) {
|
|
|
14990
15046
|
const cacheDir = resolve12(MAXY_DIR, "branding-cache", accountId);
|
|
14991
15047
|
mkdirSync8(cacheDir, { recursive: true });
|
|
14992
15048
|
writeFileSync10(resolve12(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
|
|
14993
|
-
} catch (
|
|
14994
|
-
console.error(`[branding] cache write failed: ${
|
|
15049
|
+
} catch (err) {
|
|
15050
|
+
console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
14995
15051
|
}
|
|
14996
15052
|
}
|
|
14997
15053
|
function parseVisitorCookie(cookieHeader) {
|
|
@@ -15027,20 +15083,20 @@ var VISITOR_ERROR_MESSAGES = {
|
|
|
15027
15083
|
claude_overloaded: "I'm not available right now. Please try again shortly.",
|
|
15028
15084
|
agent_error: "I'm not available right now. Please try again later."
|
|
15029
15085
|
};
|
|
15030
|
-
function classifyAgentError(
|
|
15031
|
-
const msg =
|
|
15086
|
+
function classifyAgentError(err) {
|
|
15087
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
15032
15088
|
if (/\b(401|authentication_error|OAuth token has expired)\b/i.test(msg)) return "auth_expired";
|
|
15033
15089
|
if (/credit balance|billing|purchase credits/i.test(msg)) return "billing";
|
|
15034
15090
|
if (/\b(500|api_error|internal server error)\b/i.test(msg)) return "claude_down";
|
|
15035
15091
|
if (/\b(529|overloaded)\b/i.test(msg)) return "claude_overloaded";
|
|
15036
15092
|
return "agent_error";
|
|
15037
15093
|
}
|
|
15038
|
-
function friendlyAgentError(
|
|
15039
|
-
const code = classifyAgentError(
|
|
15094
|
+
function friendlyAgentError(err, agentType = "admin") {
|
|
15095
|
+
const code = classifyAgentError(err);
|
|
15040
15096
|
if (agentType === "public") return VISITOR_ERROR_MESSAGES[code];
|
|
15041
15097
|
const base = ADMIN_ERROR_MESSAGES[code];
|
|
15042
15098
|
if (code === "agent_error") {
|
|
15043
|
-
const raw2 =
|
|
15099
|
+
const raw2 = err instanceof Error ? err.message : String(err);
|
|
15044
15100
|
return `${base}
|
|
15045
15101
|
|
|
15046
15102
|
${raw2}`;
|
|
@@ -15200,8 +15256,8 @@ async function transcribeVoiceNote(file, source) {
|
|
|
15200
15256
|
tempPath = join8(tempDir, `recording${ext}`);
|
|
15201
15257
|
const buffer = Buffer.from(await file.arrayBuffer());
|
|
15202
15258
|
await writeFile3(tempPath, buffer);
|
|
15203
|
-
} catch (
|
|
15204
|
-
const reason =
|
|
15259
|
+
} catch (err) {
|
|
15260
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
15205
15261
|
console.error(`${TAG13} failed source=${source} error=temp-file-write: ${reason}`);
|
|
15206
15262
|
return { ok: false, error: "Could not process voice note" };
|
|
15207
15263
|
}
|
|
@@ -15224,9 +15280,9 @@ async function transcribeVoiceNote(file, source) {
|
|
|
15224
15280
|
ok: true,
|
|
15225
15281
|
result: { text: rawText, durationMs: elapsed, words }
|
|
15226
15282
|
};
|
|
15227
|
-
} catch (
|
|
15283
|
+
} catch (err) {
|
|
15228
15284
|
const elapsed = Date.now() - startMs;
|
|
15229
|
-
const reason =
|
|
15285
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
15230
15286
|
console.error(
|
|
15231
15287
|
`${TAG13} failed source=${source} error=${reason} duration_ms=${elapsed}`
|
|
15232
15288
|
);
|
|
@@ -15474,10 +15530,10 @@ async function processInbound(rawText, channel) {
|
|
|
15474
15530
|
);
|
|
15475
15531
|
}
|
|
15476
15532
|
return result;
|
|
15477
|
-
} catch (
|
|
15533
|
+
} catch (err) {
|
|
15478
15534
|
const latencyMs = Date.now() - startMs;
|
|
15479
|
-
const reason =
|
|
15480
|
-
const errorType =
|
|
15535
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
15536
|
+
const errorType = err instanceof Error && err.name === "AbortError" ? "timeout" : "api-error";
|
|
15481
15537
|
console.warn(
|
|
15482
15538
|
`${TAG14} fallthrough channel=${channel} reason=${errorType}: ${reason} latency_ms=${latencyMs}`
|
|
15483
15539
|
);
|
|
@@ -15562,9 +15618,9 @@ async function POST2(req) {
|
|
|
15562
15618
|
`File "${file.name}" exceeds the 20 MB limit (${(file.size / 1024 / 1024).toFixed(1)} MB).`
|
|
15563
15619
|
);
|
|
15564
15620
|
}
|
|
15565
|
-
} catch (
|
|
15621
|
+
} catch (err) {
|
|
15566
15622
|
return new Response(
|
|
15567
|
-
JSON.stringify({ error:
|
|
15623
|
+
JSON.stringify({ error: err instanceof Error ? err.message : "Invalid file" }),
|
|
15568
15624
|
{ status: 422, headers: { "Content-Type": "application/json" } }
|
|
15569
15625
|
);
|
|
15570
15626
|
}
|
|
@@ -15703,22 +15759,22 @@ async function POST2(req) {
|
|
|
15703
15759
|
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
15704
15760
|
}
|
|
15705
15761
|
}
|
|
15706
|
-
} catch (
|
|
15707
|
-
const rawMessage =
|
|
15762
|
+
} catch (err) {
|
|
15763
|
+
const rawMessage = err instanceof Error ? err.message : String(err);
|
|
15708
15764
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
15709
|
-
const controllerClosed =
|
|
15765
|
+
const controllerClosed = err instanceof TypeError && /Controller is already closed/i.test(rawMessage);
|
|
15710
15766
|
if (controllerClosed) {
|
|
15711
15767
|
sseLog.write(`[${ts}] [${sk}] ${agentName}: DISCONNECT [client_disconnect] ${rawMessage}
|
|
15712
15768
|
`);
|
|
15713
15769
|
} else {
|
|
15714
|
-
const category = classifyAgentError(
|
|
15770
|
+
const category = classifyAgentError(err);
|
|
15715
15771
|
sseLog.write(`[${ts}] [${sk}] ${agentName}: ERROR [${category}] ${rawMessage}
|
|
15716
15772
|
`);
|
|
15717
15773
|
sseLog.write(`[${ts}] [${sk}] ${agentName}: ${JSON.stringify({ type: "done", subtype: "error", error: rawMessage, error_category: category })}
|
|
15718
15774
|
`);
|
|
15719
15775
|
try {
|
|
15720
15776
|
controller.enqueue(
|
|
15721
|
-
encoder.encode(`data: ${JSON.stringify({ error: friendlyAgentError(
|
|
15777
|
+
encoder.encode(`data: ${JSON.stringify({ error: friendlyAgentError(err, local ? "admin" : "public") })}
|
|
15722
15778
|
|
|
15723
15779
|
`)
|
|
15724
15780
|
);
|
|
@@ -15766,9 +15822,15 @@ function readPassword2() {
|
|
|
15766
15822
|
}
|
|
15767
15823
|
function getDriver2() {
|
|
15768
15824
|
if (!driver2) {
|
|
15769
|
-
const uri = process.env.NEO4J_URI
|
|
15825
|
+
const uri = process.env.NEO4J_URI;
|
|
15826
|
+
if (!uri) {
|
|
15827
|
+
throw new Error(
|
|
15828
|
+
"[ui/access-gate] NEO4J_URI unset \u2014 refusing to default to bolt://localhost:7687 (Task 580)"
|
|
15829
|
+
);
|
|
15830
|
+
}
|
|
15770
15831
|
const user = process.env.NEO4J_USER ?? "neo4j";
|
|
15771
15832
|
const password = readPassword2();
|
|
15833
|
+
console.error(`[ui/access-gate] resolved neo4j_uri=${uri}`);
|
|
15772
15834
|
driver2 = neo4j2.driver(uri, neo4j2.auth.basic(user, password), {
|
|
15773
15835
|
maxConnectionPoolSize: 5
|
|
15774
15836
|
});
|
|
@@ -16124,8 +16186,8 @@ async function POST3(req) {
|
|
|
16124
16186
|
status: result.status
|
|
16125
16187
|
}
|
|
16126
16188
|
});
|
|
16127
|
-
} catch (
|
|
16128
|
-
console.error(`[access-gate] verify-token ip=${clientIp} agent=${agentSlug} error=${
|
|
16189
|
+
} catch (err) {
|
|
16190
|
+
console.error(`[access-gate] verify-token ip=${clientIp} agent=${agentSlug} error=${err instanceof Error ? err.message : String(err)}`);
|
|
16129
16191
|
return Response.json({ error: "Internal server error" }, { status: 500 });
|
|
16130
16192
|
}
|
|
16131
16193
|
}
|
|
@@ -16218,8 +16280,8 @@ async function POST4(req) {
|
|
|
16218
16280
|
status: grant.status
|
|
16219
16281
|
}
|
|
16220
16282
|
});
|
|
16221
|
-
} catch (
|
|
16222
|
-
console.error(`[access-gate] verify-otp ip=${clientIp} agent=${agentSlug} error=${
|
|
16283
|
+
} catch (err) {
|
|
16284
|
+
console.error(`[access-gate] verify-otp ip=${clientIp} agent=${agentSlug} error=${err instanceof Error ? err.message : String(err)}`);
|
|
16223
16285
|
return Response.json({ error: "Internal server error" }, { status: 500 });
|
|
16224
16286
|
}
|
|
16225
16287
|
}
|
|
@@ -16262,8 +16324,8 @@ async function POST5(req) {
|
|
|
16262
16324
|
completeGrantSetup(session_key);
|
|
16263
16325
|
console.error(`[access-gate] create-credentials agent=${grant.grantContactValue ? "redacted" : "unknown"} result=success`);
|
|
16264
16326
|
return Response.json({ session_key });
|
|
16265
|
-
} catch (
|
|
16266
|
-
console.error(`[access-gate] create-credentials error=${
|
|
16327
|
+
} catch (err) {
|
|
16328
|
+
console.error(`[access-gate] create-credentials error=${err instanceof Error ? err.message : String(err)}`);
|
|
16267
16329
|
return Response.json({ error: "Internal server error" }, { status: 500 });
|
|
16268
16330
|
}
|
|
16269
16331
|
}
|
|
@@ -16348,8 +16410,8 @@ async function POST6(req) {
|
|
|
16348
16410
|
session_key: sessionKey,
|
|
16349
16411
|
agent_id: agentSlug
|
|
16350
16412
|
});
|
|
16351
|
-
} catch (
|
|
16352
|
-
console.error(`[access-gate] login ip=${clientIp} agent=${agentSlug} error=${
|
|
16413
|
+
} catch (err) {
|
|
16414
|
+
console.error(`[access-gate] login ip=${clientIp} agent=${agentSlug} error=${err instanceof Error ? err.message : String(err)}`);
|
|
16353
16415
|
return Response.json({ error: "Internal server error" }, { status: 500 });
|
|
16354
16416
|
}
|
|
16355
16417
|
}
|
|
@@ -16380,13 +16442,13 @@ function readBrevoApiKey() {
|
|
|
16380
16442
|
throw new Error(`Brevo API key file is empty: ${BREVO_API_KEY_FILE}`);
|
|
16381
16443
|
}
|
|
16382
16444
|
return key;
|
|
16383
|
-
} catch (
|
|
16384
|
-
if (
|
|
16445
|
+
} catch (err) {
|
|
16446
|
+
if (err.code === "ENOENT") {
|
|
16385
16447
|
throw new Error(
|
|
16386
16448
|
`Brevo API key not configured. Expected at ${BREVO_API_KEY_FILE}. Set up SMS via the admin agent: "set up SMS" \u2192 provide your Brevo API key.`
|
|
16387
16449
|
);
|
|
16388
16450
|
}
|
|
16389
|
-
throw
|
|
16451
|
+
throw err;
|
|
16390
16452
|
}
|
|
16391
16453
|
}
|
|
16392
16454
|
function hasBrevoApiKey() {
|
|
@@ -16396,10 +16458,10 @@ async function sendSms(recipient, content, opts) {
|
|
|
16396
16458
|
let apiKey;
|
|
16397
16459
|
try {
|
|
16398
16460
|
apiKey = readBrevoApiKey();
|
|
16399
|
-
} catch (
|
|
16461
|
+
} catch (err) {
|
|
16400
16462
|
return {
|
|
16401
16463
|
success: false,
|
|
16402
|
-
error:
|
|
16464
|
+
error: err instanceof Error ? err.message : "Failed to read Brevo API key"
|
|
16403
16465
|
};
|
|
16404
16466
|
}
|
|
16405
16467
|
const finalContent = opts?.aiGenerated ? `${content} [AI-generated]` : content;
|
|
@@ -16443,13 +16505,13 @@ async function sendSms(recipient, content, opts) {
|
|
|
16443
16505
|
error = `Brevo API error (HTTP ${statusCode})`;
|
|
16444
16506
|
}
|
|
16445
16507
|
return { success: false, error, statusCode };
|
|
16446
|
-
} catch (
|
|
16447
|
-
if (
|
|
16508
|
+
} catch (err) {
|
|
16509
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
16448
16510
|
return { success: false, error: "Brevo API request timed out (10s)" };
|
|
16449
16511
|
}
|
|
16450
16512
|
return {
|
|
16451
16513
|
success: false,
|
|
16452
|
-
error: `SMS delivery failed: ${
|
|
16514
|
+
error: `SMS delivery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
16453
16515
|
};
|
|
16454
16516
|
} finally {
|
|
16455
16517
|
clearTimeout(timeout);
|
|
@@ -16520,8 +16582,8 @@ async function POST7(req) {
|
|
|
16520
16582
|
console.error(`[access-gate] forgot-password ip=${clientIp} agent=${agentSlug} contact=${maskContact(contact)} result=token_generated`);
|
|
16521
16583
|
}
|
|
16522
16584
|
return Response.json(GENERIC_RESPONSE);
|
|
16523
|
-
} catch (
|
|
16524
|
-
console.error(`[access-gate] forgot-password ip=${clientIp} agent=${agentSlug} error=${
|
|
16585
|
+
} catch (err) {
|
|
16586
|
+
console.error(`[access-gate] forgot-password ip=${clientIp} agent=${agentSlug} error=${err instanceof Error ? err.message : String(err)}`);
|
|
16525
16587
|
return Response.json(GENERIC_RESPONSE);
|
|
16526
16588
|
}
|
|
16527
16589
|
}
|
|
@@ -16578,8 +16640,8 @@ async function POST8(req, remoteAddress) {
|
|
|
16578
16640
|
messageId: smsResult.messageId,
|
|
16579
16641
|
grantId: grant.grantId
|
|
16580
16642
|
});
|
|
16581
|
-
} catch (
|
|
16582
|
-
console.error(`[access-gate] send-otp agent=${agentSlug} phone=${maskContact(phone)} error=${
|
|
16643
|
+
} catch (err) {
|
|
16644
|
+
console.error(`[access-gate] send-otp agent=${agentSlug} phone=${maskContact(phone)} error=${err instanceof Error ? err.message : String(err)}`);
|
|
16583
16645
|
return Response.json({ error: "Internal server error" }, { status: 500 });
|
|
16584
16646
|
}
|
|
16585
16647
|
}
|
|
@@ -16665,9 +16727,9 @@ async function handleInbound(params) {
|
|
|
16665
16727
|
if (agentType === "public" && responseText) {
|
|
16666
16728
|
responseText += "\n\n\u2014 This message was generated by AI";
|
|
16667
16729
|
}
|
|
16668
|
-
} catch (
|
|
16730
|
+
} catch (err) {
|
|
16669
16731
|
console.error(
|
|
16670
|
-
`${TAG15} agent-error: chatId=${chatId} senderId=${senderId} error=${
|
|
16732
|
+
`${TAG15} agent-error: chatId=${chatId} senderId=${senderId} error=${err instanceof Error ? err.message : String(err)}`
|
|
16671
16733
|
);
|
|
16672
16734
|
responseText = "I'm having trouble right now. Please try again in a moment.";
|
|
16673
16735
|
}
|
|
@@ -16688,9 +16750,9 @@ async function handleInbound(params) {
|
|
|
16688
16750
|
`${TAG15} send-error: chatId=${chatId} error=${data.description ?? "unknown"}`
|
|
16689
16751
|
);
|
|
16690
16752
|
}
|
|
16691
|
-
} catch (
|
|
16753
|
+
} catch (err) {
|
|
16692
16754
|
console.error(
|
|
16693
|
-
`${TAG15} send-error: chatId=${chatId} error=${
|
|
16755
|
+
`${TAG15} send-error: chatId=${chatId} error=${err instanceof Error ? err.message : String(err)}`
|
|
16694
16756
|
);
|
|
16695
16757
|
}
|
|
16696
16758
|
}
|
|
@@ -16757,8 +16819,8 @@ async function POST9(req) {
|
|
|
16757
16819
|
method: "POST",
|
|
16758
16820
|
headers: { "Content-Type": "application/json" },
|
|
16759
16821
|
body: JSON.stringify({ callback_query_id: callbackId })
|
|
16760
|
-
}).catch((
|
|
16761
|
-
console.error(`${TAG15} callback-ack-error: ${
|
|
16822
|
+
}).catch((err) => {
|
|
16823
|
+
console.error(`${TAG15} callback-ack-error: ${err instanceof Error ? err.message : String(err)}`);
|
|
16762
16824
|
});
|
|
16763
16825
|
}
|
|
16764
16826
|
handleInbound({
|
|
@@ -16769,9 +16831,9 @@ async function POST9(req) {
|
|
|
16769
16831
|
botToken,
|
|
16770
16832
|
accountId: account.accountId,
|
|
16771
16833
|
agentType: accessResult.agentType
|
|
16772
|
-
}).catch((
|
|
16834
|
+
}).catch((err) => {
|
|
16773
16835
|
console.error(
|
|
16774
|
-
`${TAG15} unhandled-error: chatId=${chatId} senderId=${senderId} error=${
|
|
16836
|
+
`${TAG15} unhandled-error: chatId=${chatId} senderId=${senderId} error=${err instanceof Error ? err.message : String(err)}`
|
|
16775
16837
|
);
|
|
16776
16838
|
});
|
|
16777
16839
|
return Response.json({ ok: true });
|
|
@@ -16788,8 +16850,8 @@ var activeLogins = /* @__PURE__ */ new Map();
|
|
|
16788
16850
|
function closeSocket(sock) {
|
|
16789
16851
|
try {
|
|
16790
16852
|
sock.ws?.close?.();
|
|
16791
|
-
} catch (
|
|
16792
|
-
console.warn(`${TAG16} socket close error during cleanup: ${String(
|
|
16853
|
+
} catch (err) {
|
|
16854
|
+
console.warn(`${TAG16} socket close error during cleanup: ${String(err)}`);
|
|
16793
16855
|
}
|
|
16794
16856
|
}
|
|
16795
16857
|
function resetActiveLogin(accountId) {
|
|
@@ -16815,20 +16877,20 @@ async function loginConnectionLoop(accountId, login) {
|
|
|
16815
16877
|
console.error(`${TAG16} loginConnectionLoop: connected account=${accountId} attempt=${attempt}`);
|
|
16816
16878
|
}
|
|
16817
16879
|
return;
|
|
16818
|
-
} catch (
|
|
16880
|
+
} catch (err) {
|
|
16819
16881
|
const current = activeLogins.get(accountId);
|
|
16820
16882
|
if (current?.id !== login.id) return;
|
|
16821
|
-
const classification = classifyDisconnect(
|
|
16883
|
+
const classification = classifyDisconnect(err);
|
|
16822
16884
|
if (!classification.shouldRetry || attempt >= LOGIN_MAX_RECONNECTS) {
|
|
16823
16885
|
if (attempt >= LOGIN_MAX_RECONNECTS) {
|
|
16824
16886
|
console.error(
|
|
16825
16887
|
`${TAG16} login reconnect attempts exhausted (${attempt}/${LOGIN_MAX_RECONNECTS}) \u2014 surfacing error to agent`
|
|
16826
16888
|
);
|
|
16827
|
-
current.error = `Login failed after ${attempt} reconnect attempts: ${formatError(
|
|
16889
|
+
current.error = `Login failed after ${attempt} reconnect attempts: ${formatError(err)}`;
|
|
16828
16890
|
} else {
|
|
16829
|
-
current.error = formatError(
|
|
16891
|
+
current.error = formatError(err);
|
|
16830
16892
|
}
|
|
16831
|
-
current.errorStatus = getStatusCode(
|
|
16893
|
+
current.errorStatus = getStatusCode(err);
|
|
16832
16894
|
return;
|
|
16833
16895
|
}
|
|
16834
16896
|
attempt++;
|
|
@@ -16912,10 +16974,10 @@ async function startLogin(opts) {
|
|
|
16912
16974
|
resolveQr?.(qr2);
|
|
16913
16975
|
}
|
|
16914
16976
|
});
|
|
16915
|
-
} catch (
|
|
16977
|
+
} catch (err) {
|
|
16916
16978
|
clearTimeout(qrTimer);
|
|
16917
16979
|
resetActiveLogin(accountId);
|
|
16918
|
-
return { message: `Failed to start WhatsApp login: ${String(
|
|
16980
|
+
return { message: `Failed to start WhatsApp login: ${String(err)}` };
|
|
16919
16981
|
}
|
|
16920
16982
|
const login = {
|
|
16921
16983
|
accountId,
|
|
@@ -16927,20 +16989,20 @@ async function startLogin(opts) {
|
|
|
16927
16989
|
};
|
|
16928
16990
|
activeLogins.set(accountId, login);
|
|
16929
16991
|
if (pendingQr && !login.qr) login.qr = pendingQr;
|
|
16930
|
-
loginConnectionLoop(accountId, login).catch((
|
|
16931
|
-
console.error(`${TAG16} loginConnectionLoop unexpected error: ${String(
|
|
16992
|
+
loginConnectionLoop(accountId, login).catch((err) => {
|
|
16993
|
+
console.error(`${TAG16} loginConnectionLoop unexpected error: ${String(err)}`);
|
|
16932
16994
|
const current = activeLogins.get(accountId);
|
|
16933
16995
|
if (current?.id === login.id) {
|
|
16934
|
-
current.error = `Unexpected login error: ${String(
|
|
16996
|
+
current.error = `Unexpected login error: ${String(err)}`;
|
|
16935
16997
|
}
|
|
16936
16998
|
});
|
|
16937
16999
|
let qr;
|
|
16938
17000
|
try {
|
|
16939
17001
|
qr = await qrPromise;
|
|
16940
|
-
} catch (
|
|
17002
|
+
} catch (err) {
|
|
16941
17003
|
clearTimeout(qrTimer);
|
|
16942
17004
|
resetActiveLogin(accountId);
|
|
16943
|
-
return { message: `Failed to get QR: ${String(
|
|
17005
|
+
return { message: `Failed to get QR: ${String(err)}` };
|
|
16944
17006
|
}
|
|
16945
17007
|
login.qrDataUrl = `qr:${qr}`;
|
|
16946
17008
|
return {
|
|
@@ -17012,9 +17074,9 @@ async function POST10(req) {
|
|
|
17012
17074
|
const result = await startLogin({ accountId, authDir, force });
|
|
17013
17075
|
console.error(`[whatsapp:api] login/start result account=${accountId} hasQr=${!!result.qrRaw}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
|
|
17014
17076
|
return Response.json(result);
|
|
17015
|
-
} catch (
|
|
17016
|
-
console.error(`[whatsapp:api] login/start error: ${String(
|
|
17017
|
-
return Response.json({ error: String(
|
|
17077
|
+
} catch (err) {
|
|
17078
|
+
console.error(`[whatsapp:api] login/start error: ${String(err)}`);
|
|
17079
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17018
17080
|
}
|
|
17019
17081
|
}
|
|
17020
17082
|
|
|
@@ -17054,9 +17116,9 @@ async function POST11(req) {
|
|
|
17054
17116
|
selfPhone: result.selfPhone,
|
|
17055
17117
|
configPersisted
|
|
17056
17118
|
});
|
|
17057
|
-
} catch (
|
|
17058
|
-
console.error(`[whatsapp:api] login/wait error: ${String(
|
|
17059
|
-
return Response.json({ error: String(
|
|
17119
|
+
} catch (err) {
|
|
17120
|
+
console.error(`[whatsapp:api] login/wait error: ${String(err)}`);
|
|
17121
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17060
17122
|
}
|
|
17061
17123
|
}
|
|
17062
17124
|
|
|
@@ -17067,9 +17129,9 @@ async function GET2(_req) {
|
|
|
17067
17129
|
const summary = status.map((a) => `${a.accountId}:${a.connected ? "up" : "down"}`).join(", ");
|
|
17068
17130
|
console.error(`[whatsapp:api] status accounts=${status.length} [${summary}]`);
|
|
17069
17131
|
return Response.json({ accounts: status });
|
|
17070
|
-
} catch (
|
|
17071
|
-
console.error(`[whatsapp:api] status error: ${String(
|
|
17072
|
-
return Response.json({ error: String(
|
|
17132
|
+
} catch (err) {
|
|
17133
|
+
console.error(`[whatsapp:api] status error: ${String(err)}`);
|
|
17134
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17073
17135
|
}
|
|
17074
17136
|
}
|
|
17075
17137
|
|
|
@@ -17080,9 +17142,9 @@ async function POST12(req) {
|
|
|
17080
17142
|
const accountId = validateAccountId(body.accountId);
|
|
17081
17143
|
await stopConnection(accountId);
|
|
17082
17144
|
return Response.json({ disconnected: true, accountId });
|
|
17083
|
-
} catch (
|
|
17084
|
-
console.error(`[whatsapp:api] disconnect error: ${String(
|
|
17085
|
-
return Response.json({ error: String(
|
|
17145
|
+
} catch (err) {
|
|
17146
|
+
console.error(`[whatsapp:api] disconnect error: ${String(err)}`);
|
|
17147
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17086
17148
|
}
|
|
17087
17149
|
}
|
|
17088
17150
|
|
|
@@ -17093,9 +17155,9 @@ async function POST13(req) {
|
|
|
17093
17155
|
const accountId = validateAccountId(body.accountId);
|
|
17094
17156
|
await startConnection(accountId);
|
|
17095
17157
|
return Response.json({ reconnecting: true, accountId });
|
|
17096
|
-
} catch (
|
|
17097
|
-
console.error(`[whatsapp:api] reconnect error: ${String(
|
|
17098
|
-
return Response.json({ error: String(
|
|
17158
|
+
} catch (err) {
|
|
17159
|
+
console.error(`[whatsapp:api] reconnect error: ${String(err)}`);
|
|
17160
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17099
17161
|
}
|
|
17100
17162
|
}
|
|
17101
17163
|
|
|
@@ -17117,9 +17179,9 @@ async function POST14(req) {
|
|
|
17117
17179
|
}
|
|
17118
17180
|
const result = await sendTextMessage(sock, to, text, { accountId });
|
|
17119
17181
|
return Response.json(result);
|
|
17120
|
-
} catch (
|
|
17121
|
-
console.error(`[whatsapp:api] send error: ${String(
|
|
17122
|
-
return Response.json({ error: String(
|
|
17182
|
+
} catch (err) {
|
|
17183
|
+
console.error(`[whatsapp:api] send error: ${String(err)}`);
|
|
17184
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17123
17185
|
}
|
|
17124
17186
|
}
|
|
17125
17187
|
|
|
@@ -17286,8 +17348,8 @@ async function POST15(req) {
|
|
|
17286
17348
|
console.error(`[whatsapp:api] config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
|
|
17287
17349
|
}
|
|
17288
17350
|
}
|
|
17289
|
-
} catch (
|
|
17290
|
-
console.error(`[whatsapp:api] config action=list-public-agents error="failed to scan agents directory: ${String(
|
|
17351
|
+
} catch (err) {
|
|
17352
|
+
console.error(`[whatsapp:api] config action=list-public-agents error="failed to scan agents directory: ${String(err)}"`);
|
|
17291
17353
|
}
|
|
17292
17354
|
}
|
|
17293
17355
|
console.error(`[whatsapp:api] config action=list-public-agents count=${agents.length}`);
|
|
@@ -17314,9 +17376,9 @@ async function POST15(req) {
|
|
|
17314
17376
|
}));
|
|
17315
17377
|
console.error(`[whatsapp:api] config action=list-groups count=${groups.length} accountId=${groupAccountId}`);
|
|
17316
17378
|
return Response.json({ ok: true, groups });
|
|
17317
|
-
} catch (
|
|
17318
|
-
console.error(`[whatsapp:api] config action=list-groups error="${String(
|
|
17319
|
-
return Response.json({ ok: false, error: `Failed to fetch groups: ${String(
|
|
17379
|
+
} catch (err) {
|
|
17380
|
+
console.error(`[whatsapp:api] config action=list-groups error="${String(err)}" accountId=${groupAccountId}`);
|
|
17381
|
+
return Response.json({ ok: false, error: `Failed to fetch groups: ${String(err)}` });
|
|
17320
17382
|
}
|
|
17321
17383
|
}
|
|
17322
17384
|
case "update-config": {
|
|
@@ -17339,9 +17401,9 @@ async function POST15(req) {
|
|
|
17339
17401
|
{ status: 400 }
|
|
17340
17402
|
);
|
|
17341
17403
|
}
|
|
17342
|
-
} catch (
|
|
17343
|
-
console.error(`[whatsapp:api] config error: ${String(
|
|
17344
|
-
return Response.json({ ok: false, error: String(
|
|
17404
|
+
} catch (err) {
|
|
17405
|
+
console.error(`[whatsapp:api] config error: ${String(err)}`);
|
|
17406
|
+
return Response.json({ ok: false, error: String(err) }, { status: 500 });
|
|
17345
17407
|
}
|
|
17346
17408
|
}
|
|
17347
17409
|
|
|
@@ -17375,14 +17437,14 @@ async function POST16(req) {
|
|
|
17375
17437
|
console.error(`${TAG17} send-document REJECTED path=${sanitised} reason=outside_account_directory`);
|
|
17376
17438
|
return Response.json({ error: "Access denied: file is outside the account directory" }, { status: 403 });
|
|
17377
17439
|
}
|
|
17378
|
-
} catch (
|
|
17379
|
-
const code =
|
|
17440
|
+
} catch (err) {
|
|
17441
|
+
const code = err.code;
|
|
17380
17442
|
if (code === "ENOENT") {
|
|
17381
17443
|
console.error(`${TAG17} send-document ENOENT path=${filePath}`);
|
|
17382
17444
|
return Response.json({ error: `File not found: ${filePath}` }, { status: 404 });
|
|
17383
17445
|
}
|
|
17384
|
-
console.error(`${TAG17} send-document path error: ${String(
|
|
17385
|
-
return Response.json({ error: String(
|
|
17446
|
+
console.error(`${TAG17} send-document path error: ${String(err)}`);
|
|
17447
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17386
17448
|
}
|
|
17387
17449
|
const fileStat = await stat3(resolvedPath);
|
|
17388
17450
|
if (fileStat.size > MAX_FILE_SIZE_BYTES) {
|
|
@@ -17412,9 +17474,9 @@ async function POST16(req) {
|
|
|
17412
17474
|
`${TAG17} send-document to=${to} size=${fileStat.size} mime=${mimetype} ok=${result.success}` + (result.messageId ? ` id=${result.messageId}` : "")
|
|
17413
17475
|
);
|
|
17414
17476
|
return Response.json(result);
|
|
17415
|
-
} catch (
|
|
17416
|
-
console.error(`${TAG17} send-document error: ${String(
|
|
17417
|
-
return Response.json({ error: String(
|
|
17477
|
+
} catch (err) {
|
|
17478
|
+
console.error(`${TAG17} send-document error: ${String(err)}`);
|
|
17479
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17418
17480
|
}
|
|
17419
17481
|
}
|
|
17420
17482
|
|
|
@@ -17429,9 +17491,9 @@ async function GET3(req) {
|
|
|
17429
17491
|
`[whatsapp:api] activity accounts=${result.accounts.length} total=${total} recentEvents=${result.recentEvents.length}` + (accountId ? ` filter=${accountId}` : "")
|
|
17430
17492
|
);
|
|
17431
17493
|
return Response.json(result);
|
|
17432
|
-
} catch (
|
|
17433
|
-
console.error(`[whatsapp:api] activity error: ${String(
|
|
17434
|
-
return Response.json({ error: String(
|
|
17494
|
+
} catch (err) {
|
|
17495
|
+
console.error(`[whatsapp:api] activity error: ${String(err)}`);
|
|
17496
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17435
17497
|
}
|
|
17436
17498
|
}
|
|
17437
17499
|
|
|
@@ -17456,9 +17518,9 @@ async function GET4(req) {
|
|
|
17456
17518
|
`[whatsapp:api] conversations account=${accountId} count=${conversations.length}`
|
|
17457
17519
|
);
|
|
17458
17520
|
return Response.json({ conversations });
|
|
17459
|
-
} catch (
|
|
17460
|
-
console.error(`[whatsapp:api] conversations error: ${String(
|
|
17461
|
-
return Response.json({ error: String(
|
|
17521
|
+
} catch (err) {
|
|
17522
|
+
console.error(`[whatsapp:api] conversations error: ${String(err)}`);
|
|
17523
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17462
17524
|
}
|
|
17463
17525
|
}
|
|
17464
17526
|
|
|
@@ -17479,9 +17541,9 @@ async function GET5(req) {
|
|
|
17479
17541
|
`[whatsapp:api] messages account=${accountId} jid=${jid} limit=${effectiveLimit ?? "all"} returned=${messages.length}`
|
|
17480
17542
|
);
|
|
17481
17543
|
return Response.json({ messages });
|
|
17482
|
-
} catch (
|
|
17483
|
-
console.error(`[whatsapp:api] messages error: ${String(
|
|
17484
|
-
return Response.json({ error: String(
|
|
17544
|
+
} catch (err) {
|
|
17545
|
+
console.error(`[whatsapp:api] messages error: ${String(err)}`);
|
|
17546
|
+
return Response.json({ error: String(err) }, { status: 500 });
|
|
17485
17547
|
}
|
|
17486
17548
|
}
|
|
17487
17549
|
|
|
@@ -17526,9 +17588,9 @@ async function GET6(req) {
|
|
|
17526
17588
|
`[whatsapp:api] group-info jid=${jid} subject="${meta.subject}" participants=${meta.participants.length} account=${accountId}`
|
|
17527
17589
|
);
|
|
17528
17590
|
return Response.json(result);
|
|
17529
|
-
} catch (
|
|
17530
|
-
console.error(`[whatsapp:api] group-info error="${String(
|
|
17531
|
-
return Response.json({ error: `Failed to fetch group info: ${String(
|
|
17591
|
+
} catch (err) {
|
|
17592
|
+
console.error(`[whatsapp:api] group-info error="${String(err)}" jid=${jid} account=${accountId}`);
|
|
17593
|
+
return Response.json({ error: `Failed to fetch group info: ${String(err)}` }, { status: 500 });
|
|
17532
17594
|
}
|
|
17533
17595
|
}
|
|
17534
17596
|
|
|
@@ -17574,8 +17636,8 @@ async function GET7(req) {
|
|
|
17574
17636
|
})),
|
|
17575
17637
|
hasMore: messages.length >= POLL_LIMIT
|
|
17576
17638
|
});
|
|
17577
|
-
} catch (
|
|
17578
|
-
console.error(`[group] poll failed: ${
|
|
17639
|
+
} catch (err) {
|
|
17640
|
+
console.error(`[group] poll failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
17579
17641
|
return Response.json({ error: "Failed to fetch messages" }, { status: 503 });
|
|
17580
17642
|
}
|
|
17581
17643
|
}
|
|
@@ -17601,8 +17663,8 @@ async function POST17(req) {
|
|
|
17601
17663
|
sizeBytes: attachment.sizeBytes,
|
|
17602
17664
|
mimeType: attachment.mimeType
|
|
17603
17665
|
});
|
|
17604
|
-
} catch (
|
|
17605
|
-
const message =
|
|
17666
|
+
} catch (err) {
|
|
17667
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
17606
17668
|
console.error(`[admin:file-attach] error: ${message}`);
|
|
17607
17669
|
return Response.json({ error: message }, { status: 500 });
|
|
17608
17670
|
}
|
|
@@ -17712,8 +17774,8 @@ async function POST19(req) {
|
|
|
17712
17774
|
let existingUsers = null;
|
|
17713
17775
|
try {
|
|
17714
17776
|
existingUsers = readUsersFile();
|
|
17715
|
-
} catch (
|
|
17716
|
-
console.error(`[set-pin] users.json corrupt: ${
|
|
17777
|
+
} catch (err) {
|
|
17778
|
+
console.error(`[set-pin] users.json corrupt: ${err instanceof Error ? err.message : String(err)}`);
|
|
17717
17779
|
return Response.json({ error: "User configuration is corrupt." }, { status: 400 });
|
|
17718
17780
|
}
|
|
17719
17781
|
if (existingUsers !== null && existingUsers.length > 0) {
|
|
@@ -17749,8 +17811,8 @@ async function POST19(req) {
|
|
|
17749
17811
|
writeFileSync13(`${account.accountDir}/account.json`, JSON.stringify(config, null, 2) + "\n");
|
|
17750
17812
|
console.log(`[set-pin] added userId=${userId.slice(0, 8)}\u2026 to account.json admins`);
|
|
17751
17813
|
}
|
|
17752
|
-
} catch (
|
|
17753
|
-
console.error(`[set-pin] failed to update account.json admins: ${
|
|
17814
|
+
} catch (err) {
|
|
17815
|
+
console.error(`[set-pin] failed to update account.json admins: ${err instanceof Error ? err.message : String(err)}`);
|
|
17754
17816
|
}
|
|
17755
17817
|
}
|
|
17756
17818
|
return Response.json({ ok: true });
|
|
@@ -17759,8 +17821,8 @@ async function DELETE(req) {
|
|
|
17759
17821
|
let users = null;
|
|
17760
17822
|
try {
|
|
17761
17823
|
users = readUsersFile();
|
|
17762
|
-
} catch (
|
|
17763
|
-
console.error(`[set-pin] users.json corrupt on DELETE: ${
|
|
17824
|
+
} catch (err) {
|
|
17825
|
+
console.error(`[set-pin] users.json corrupt on DELETE: ${err instanceof Error ? err.message : String(err)}`);
|
|
17764
17826
|
return Response.json({ error: "User configuration is corrupt." }, { status: 400 });
|
|
17765
17827
|
}
|
|
17766
17828
|
if (users === null || users.length === 0) {
|
|
@@ -17809,8 +17871,8 @@ async function POST20() {
|
|
|
17809
17871
|
try {
|
|
17810
17872
|
const brand = JSON.parse(readFileSync18(brandPath3, "utf-8"));
|
|
17811
17873
|
if (brand.productName) agentName = brand.productName;
|
|
17812
|
-
} catch (
|
|
17813
|
-
console.error(`[onboarding-skip] brand.json read failed: ${
|
|
17874
|
+
} catch (err) {
|
|
17875
|
+
console.error(`[onboarding-skip] brand.json read failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
17814
17876
|
}
|
|
17815
17877
|
}
|
|
17816
17878
|
const soulPath = resolve18(accountDir, "agents", "admin", "SOUL.md");
|
|
@@ -17819,8 +17881,8 @@ async function POST20() {
|
|
|
17819
17881
|
writeFileSync14(soulPath, `You are ${agentName}, an AI operations manager.
|
|
17820
17882
|
`);
|
|
17821
17883
|
console.log(`[onboarding-skip] wrote SOUL.md: ${soulPath}`);
|
|
17822
|
-
} catch (
|
|
17823
|
-
console.error(`[onboarding-skip] SOUL.md write failed: ${
|
|
17884
|
+
} catch (err) {
|
|
17885
|
+
console.error(`[onboarding-skip] SOUL.md write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
17824
17886
|
return Response.json({ error: "Failed to write default personality." }, { status: 500 });
|
|
17825
17887
|
}
|
|
17826
17888
|
const session = getSession();
|
|
@@ -17843,8 +17905,8 @@ async function POST20() {
|
|
|
17843
17905
|
{ accountId, now }
|
|
17844
17906
|
);
|
|
17845
17907
|
console.log(`[onboarding-skip] accountId=${accountId.slice(0, 8)}\u2026 currentStep=6 skipped=true`);
|
|
17846
|
-
} catch (
|
|
17847
|
-
console.error(`[onboarding-skip] Neo4j update failed: ${
|
|
17908
|
+
} catch (err) {
|
|
17909
|
+
console.error(`[onboarding-skip] Neo4j update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
17848
17910
|
return Response.json({ error: "Failed to update onboarding state." }, { status: 500 });
|
|
17849
17911
|
} finally {
|
|
17850
17912
|
await session.close();
|
|
@@ -17878,8 +17940,8 @@ async function POST21(req) {
|
|
|
17878
17940
|
let users = null;
|
|
17879
17941
|
try {
|
|
17880
17942
|
users = readUsersFile2();
|
|
17881
|
-
} catch (
|
|
17882
|
-
console.error(`[session] users.json corrupt: ${
|
|
17943
|
+
} catch (err) {
|
|
17944
|
+
console.error(`[session] users.json corrupt: ${err instanceof Error ? err.message : String(err)}`);
|
|
17883
17945
|
return Response.json(
|
|
17884
17946
|
{ error: "User configuration is corrupt. Re-run the seed script." },
|
|
17885
17947
|
{ status: 503 }
|
|
@@ -17936,8 +17998,8 @@ async function createAdminSession(accountId, thinkingView, userId, userName) {
|
|
|
17936
17998
|
try {
|
|
17937
17999
|
const step = await loadOnboardingStep(accountId);
|
|
17938
18000
|
onboardingComplete = step === null || step >= 8;
|
|
17939
|
-
} catch (
|
|
17940
|
-
console.error(`[session] onboarding query failed: ${
|
|
18001
|
+
} catch (err) {
|
|
18002
|
+
console.error(`[session] onboarding query failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
17941
18003
|
}
|
|
17942
18004
|
let businessName;
|
|
17943
18005
|
try {
|
|
@@ -18029,8 +18091,8 @@ function startScriptStreamTailer(opts) {
|
|
|
18029
18091
|
});
|
|
18030
18092
|
stream.on("error", rej);
|
|
18031
18093
|
});
|
|
18032
|
-
} catch (
|
|
18033
|
-
if (onError) onError(
|
|
18094
|
+
} catch (err) {
|
|
18095
|
+
if (onError) onError(err instanceof Error ? err : new Error(String(err)));
|
|
18034
18096
|
} finally {
|
|
18035
18097
|
pendingRead = false;
|
|
18036
18098
|
}
|
|
@@ -18177,8 +18239,8 @@ async function POST22(req) {
|
|
|
18177
18239
|
`File "${file.name}" exceeds the 20 MB limit (${(file.size / 1024 / 1024).toFixed(1)} MB).`
|
|
18178
18240
|
);
|
|
18179
18241
|
}
|
|
18180
|
-
} catch (
|
|
18181
|
-
return chatReject(422,
|
|
18242
|
+
} catch (err) {
|
|
18243
|
+
return chatReject(422, err instanceof Error ? err.message : "Invalid file", session_key);
|
|
18182
18244
|
}
|
|
18183
18245
|
}
|
|
18184
18246
|
const accountId = getAccountIdForSession(session_key);
|
|
@@ -18189,8 +18251,8 @@ async function POST22(req) {
|
|
|
18189
18251
|
try {
|
|
18190
18252
|
const stored = await storeAttachment(accountId, file);
|
|
18191
18253
|
storedAttachments.push(stored);
|
|
18192
|
-
} catch (
|
|
18193
|
-
return chatReject(422,
|
|
18254
|
+
} catch (err) {
|
|
18255
|
+
return chatReject(422, err instanceof Error ? err.message : "File storage failed", session_key);
|
|
18194
18256
|
}
|
|
18195
18257
|
}
|
|
18196
18258
|
} else {
|
|
@@ -18311,8 +18373,8 @@ async function POST22(req) {
|
|
|
18311
18373
|
controllerOpen = false;
|
|
18312
18374
|
}
|
|
18313
18375
|
},
|
|
18314
|
-
onError: (
|
|
18315
|
-
console.error(`[script-stream-tailer] ${streamLogPath}: ${
|
|
18376
|
+
onError: (err) => {
|
|
18377
|
+
console.error(`[script-stream-tailer] ${streamLogPath}: ${err.message}`);
|
|
18316
18378
|
}
|
|
18317
18379
|
});
|
|
18318
18380
|
}
|
|
@@ -18332,16 +18394,16 @@ async function POST22(req) {
|
|
|
18332
18394
|
|
|
18333
18395
|
`));
|
|
18334
18396
|
}
|
|
18335
|
-
} catch (
|
|
18336
|
-
const rawMessage =
|
|
18397
|
+
} catch (err) {
|
|
18398
|
+
const rawMessage = err instanceof Error ? err.message : String(err);
|
|
18337
18399
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
18338
|
-
const controllerClosed =
|
|
18400
|
+
const controllerClosed = err instanceof TypeError && /Controller is already closed/i.test(rawMessage);
|
|
18339
18401
|
if (controllerClosed) {
|
|
18340
18402
|
sseLog.write(`[${ts}] [${sk}] admin: DISCONNECT [client_disconnect] ${rawMessage}
|
|
18341
18403
|
`);
|
|
18342
18404
|
} else {
|
|
18343
|
-
const category = classifyAgentError(
|
|
18344
|
-
const errEvent = JSON.stringify({ type: "text", content: friendlyAgentError(
|
|
18405
|
+
const category = classifyAgentError(err);
|
|
18406
|
+
const errEvent = JSON.stringify({ type: "text", content: friendlyAgentError(err) });
|
|
18345
18407
|
const doneEvent = JSON.stringify({ type: "done", subtype: "error", error: rawMessage, error_category: category });
|
|
18346
18408
|
sseLog.write(`[${ts}] [${sk}] admin: ERROR [${category}] ${rawMessage}
|
|
18347
18409
|
`);
|
|
@@ -18452,8 +18514,8 @@ async function GET9(request) {
|
|
|
18452
18514
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
18453
18515
|
if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
|
|
18454
18516
|
return new Response(content, { headers });
|
|
18455
|
-
} catch (
|
|
18456
|
-
const reason =
|
|
18517
|
+
} catch (err) {
|
|
18518
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
18457
18519
|
console.debug(`[admin/logs] miss dir=${dir} name=${safe} reason=${reason}`);
|
|
18458
18520
|
}
|
|
18459
18521
|
}
|
|
@@ -18494,8 +18556,8 @@ async function GET9(request) {
|
|
|
18494
18556
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
18495
18557
|
if (download) headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
18496
18558
|
return new Response(content, { headers });
|
|
18497
|
-
} catch (
|
|
18498
|
-
const reason =
|
|
18559
|
+
} catch (err) {
|
|
18560
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
18499
18561
|
console.debug(`[admin/logs] miss dir=${dir} name=${fileName} reason=${reason}`);
|
|
18500
18562
|
}
|
|
18501
18563
|
}
|
|
@@ -18509,8 +18571,8 @@ async function GET9(request) {
|
|
|
18509
18571
|
let files;
|
|
18510
18572
|
try {
|
|
18511
18573
|
files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
|
|
18512
|
-
} catch (
|
|
18513
|
-
const reason =
|
|
18574
|
+
} catch (err) {
|
|
18575
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
18514
18576
|
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
18515
18577
|
continue;
|
|
18516
18578
|
}
|
|
@@ -18520,8 +18582,8 @@ async function GET9(request) {
|
|
|
18520
18582
|
const content = readFileSync20(resolve20(dir, name));
|
|
18521
18583
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
18522
18584
|
logs[name] = tail.trim() || "(empty)";
|
|
18523
|
-
} catch (
|
|
18524
|
-
const reason =
|
|
18585
|
+
} catch (err) {
|
|
18586
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
18525
18587
|
console.debug(`[admin/logs] read-fail name=${name} reason=${reason}`);
|
|
18526
18588
|
logs[name] = `(unreadable: ${reason})`;
|
|
18527
18589
|
}
|
|
@@ -18631,8 +18693,8 @@ async function PATCH(req) {
|
|
|
18631
18693
|
writeFileSync15(configPath2, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
18632
18694
|
console.error(`[account-update] contextMode=${contextMode}`);
|
|
18633
18695
|
return Response.json({ ok: true, contextMode });
|
|
18634
|
-
} catch (
|
|
18635
|
-
console.error(`[account-update] failed: ${
|
|
18696
|
+
} catch (err) {
|
|
18697
|
+
console.error(`[account-update] failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
18636
18698
|
return Response.json({ error: "Failed to update account" }, { status: 500 });
|
|
18637
18699
|
}
|
|
18638
18700
|
}
|
|
@@ -18668,8 +18730,8 @@ async function GET12() {
|
|
|
18668
18730
|
console.error(`[admin/agents] failed to parse config.json for agent "${entry.name}" \u2014 skipping`);
|
|
18669
18731
|
}
|
|
18670
18732
|
}
|
|
18671
|
-
} catch (
|
|
18672
|
-
console.error(`[admin/agents] failed to scan agents directory: ${
|
|
18733
|
+
} catch (err) {
|
|
18734
|
+
console.error(`[admin/agents] failed to scan agents directory: ${err}`);
|
|
18673
18735
|
return Response.json({ agents: [] });
|
|
18674
18736
|
}
|
|
18675
18737
|
return Response.json({ agents });
|
|
@@ -18698,8 +18760,8 @@ async function DELETE2(_req, { params }) {
|
|
|
18698
18760
|
rmSync3(agentDir, { recursive: true, force: true });
|
|
18699
18761
|
console.log(`[admin/agents] deleted agent "${slug}"`);
|
|
18700
18762
|
return Response.json({ ok: true });
|
|
18701
|
-
} catch (
|
|
18702
|
-
console.error(`[admin/agents] failed to delete agent "${slug}": ${
|
|
18763
|
+
} catch (err) {
|
|
18764
|
+
console.error(`[admin/agents] failed to delete agent "${slug}": ${err}`);
|
|
18703
18765
|
return Response.json({ error: "Failed to delete agent" }, { status: 500 });
|
|
18704
18766
|
}
|
|
18705
18767
|
}
|
|
@@ -18767,8 +18829,8 @@ function rotateIfNeeded() {
|
|
|
18767
18829
|
const stats = statSync9(CLIENT_ERRORS_LOG);
|
|
18768
18830
|
if (stats.size < MAX_LOG_SIZE) return;
|
|
18769
18831
|
renameSync4(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
|
|
18770
|
-
} catch (
|
|
18771
|
-
console.error(`[client-error] log rotation failed: ${
|
|
18832
|
+
} catch (err) {
|
|
18833
|
+
console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
18772
18834
|
}
|
|
18773
18835
|
}
|
|
18774
18836
|
async function POST24(req, remoteAddress) {
|
|
@@ -18834,8 +18896,8 @@ async function POST24(req, remoteAddress) {
|
|
|
18834
18896
|
status: typeof body.status === "number" ? body.status : void 0
|
|
18835
18897
|
};
|
|
18836
18898
|
appendFileSync4(CLIENT_ERRORS_LOG, JSON.stringify(payload) + "\n", "utf-8");
|
|
18837
|
-
} catch (
|
|
18838
|
-
console.error(`[client-error] append failed: ${
|
|
18899
|
+
} catch (err) {
|
|
18900
|
+
console.error(`[client-error] append failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
18839
18901
|
}
|
|
18840
18902
|
errorTimestamps.push(Date.now());
|
|
18841
18903
|
return Response.json({ ok: true });
|
|
@@ -18880,8 +18942,8 @@ async function fetchLatest() {
|
|
|
18880
18942
|
return null;
|
|
18881
18943
|
}
|
|
18882
18944
|
return version;
|
|
18883
|
-
} catch (
|
|
18884
|
-
console.error(`[admin/version] npm registry fetch failed: ${
|
|
18945
|
+
} catch (err) {
|
|
18946
|
+
console.error(`[admin/version] npm registry fetch failed: ${err}`);
|
|
18885
18947
|
return null;
|
|
18886
18948
|
}
|
|
18887
18949
|
}
|
|
@@ -18966,15 +19028,15 @@ async function POST25(req) {
|
|
|
18966
19028
|
const installerScope = `upgrade-${upgradeHostname}`;
|
|
18967
19029
|
try {
|
|
18968
19030
|
writeFileSync16(LOCK_FILE, String(Date.now()));
|
|
18969
|
-
} catch (
|
|
18970
|
-
console.error("[admin/version/upgrade] failed to write lock file:",
|
|
19031
|
+
} catch (err) {
|
|
19032
|
+
console.error("[admin/version/upgrade] failed to write lock file:", err);
|
|
18971
19033
|
}
|
|
18972
19034
|
try {
|
|
18973
19035
|
writeFileSync16(LOG_FILE, "");
|
|
18974
|
-
} catch (
|
|
18975
|
-
console.error("[admin/version/upgrade] failed to truncate upgrade log:",
|
|
19036
|
+
} catch (err) {
|
|
19037
|
+
console.error("[admin/version/upgrade] failed to truncate upgrade log:", err);
|
|
18976
19038
|
return Response.json(
|
|
18977
|
-
{ ok: false, error:
|
|
19039
|
+
{ ok: false, error: err instanceof Error ? err.message : "failed to prepare upgrade log" },
|
|
18978
19040
|
{ status: 500 }
|
|
18979
19041
|
);
|
|
18980
19042
|
}
|
|
@@ -18998,10 +19060,10 @@ async function POST25(req) {
|
|
|
18998
19060
|
closeSync5(logFd);
|
|
18999
19061
|
console.log(`[admin/version/upgrade] spawned upgrade process (pid ${child.pid} scope ${installerScope})`);
|
|
19000
19062
|
return Response.json({ ok: true, started: true });
|
|
19001
|
-
} catch (
|
|
19002
|
-
console.error("[admin/version/upgrade] failed to spawn upgrade process:",
|
|
19063
|
+
} catch (err) {
|
|
19064
|
+
console.error("[admin/version/upgrade] failed to spawn upgrade process:", err);
|
|
19003
19065
|
return Response.json(
|
|
19004
|
-
{ ok: false, error:
|
|
19066
|
+
{ ok: false, error: err instanceof Error ? err.message : "failed to start upgrade" },
|
|
19005
19067
|
{ status: 500 }
|
|
19006
19068
|
);
|
|
19007
19069
|
}
|
|
@@ -19089,8 +19151,8 @@ async function GET15(req) {
|
|
|
19089
19151
|
try {
|
|
19090
19152
|
const sessions = await listAdminSessions(accountId, userId, 20);
|
|
19091
19153
|
return Response.json({ sessions });
|
|
19092
|
-
} catch (
|
|
19093
|
-
console.error(`[sessions-list] Failed: ${
|
|
19154
|
+
} catch (err) {
|
|
19155
|
+
console.error(`[sessions-list] Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
19094
19156
|
return Response.json({ error: "Failed to fetch sessions" }, { status: 500 });
|
|
19095
19157
|
}
|
|
19096
19158
|
}
|
|
@@ -19148,8 +19210,8 @@ async function DELETE3(req, { params }) {
|
|
|
19148
19210
|
try {
|
|
19149
19211
|
await deleteConversation(conversationId);
|
|
19150
19212
|
return Response.json({ ok: true });
|
|
19151
|
-
} catch (
|
|
19152
|
-
console.error(`[sessions-delete] Failed: ${
|
|
19213
|
+
} catch (err) {
|
|
19214
|
+
console.error(`[sessions-delete] Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
19153
19215
|
return Response.json({ error: "Failed to delete session" }, { status: 500 });
|
|
19154
19216
|
}
|
|
19155
19217
|
}
|
|
@@ -19176,8 +19238,8 @@ async function GET16(req, { params }) {
|
|
|
19176
19238
|
try {
|
|
19177
19239
|
const messages = await getRecentMessages(conversationId, 50);
|
|
19178
19240
|
return Response.json({ messages });
|
|
19179
|
-
} catch (
|
|
19180
|
-
console.error(`[sessions-messages] Failed: ${
|
|
19241
|
+
} catch (err) {
|
|
19242
|
+
console.error(`[sessions-messages] Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
19181
19243
|
return Response.json({ error: "Failed to fetch messages" }, { status: 500 });
|
|
19182
19244
|
}
|
|
19183
19245
|
}
|
|
@@ -19212,8 +19274,8 @@ async function POST27(req, { params }) {
|
|
|
19212
19274
|
seedSessionHistory(sessionKey, messages);
|
|
19213
19275
|
estimatedTokens = messages.reduce((sum, m) => sum + Math.ceil(m.content.length / 4), 0);
|
|
19214
19276
|
}
|
|
19215
|
-
} catch (
|
|
19216
|
-
console.error(`[session-resume] ${(/* @__PURE__ */ new Date()).toISOString()} getRecentMessages failed: conversationId=${conversationId.slice(0, 8)}\u2026 error=${
|
|
19277
|
+
} catch (err) {
|
|
19278
|
+
console.error(`[session-resume] ${(/* @__PURE__ */ new Date()).toISOString()} getRecentMessages failed: conversationId=${conversationId.slice(0, 8)}\u2026 error=${err instanceof Error ? err.message : String(err)}`);
|
|
19217
19279
|
return Response.json({ error: "Failed to load conversation messages" }, { status: 500 });
|
|
19218
19280
|
}
|
|
19219
19281
|
const age = formatAge(updatedAt);
|
|
@@ -19273,8 +19335,8 @@ async function POST28(req, { params }) {
|
|
|
19273
19335
|
console.error(`[admin] manual-label: haiku failed for ${conversationId} \u2014 null response`);
|
|
19274
19336
|
}
|
|
19275
19337
|
return Response.json({ label });
|
|
19276
|
-
} catch (
|
|
19277
|
-
console.error(`[admin] manual-label: haiku failed for ${conversationId} \u2014 ${
|
|
19338
|
+
} catch (err) {
|
|
19339
|
+
console.error(`[admin] manual-label: haiku failed for ${conversationId} \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
19278
19340
|
return Response.json({ label: null });
|
|
19279
19341
|
}
|
|
19280
19342
|
}
|
|
@@ -19311,8 +19373,8 @@ async function PUT(req, { params }) {
|
|
|
19311
19373
|
try {
|
|
19312
19374
|
await renameConversation(conversationId, label);
|
|
19313
19375
|
return Response.json({ ok: true });
|
|
19314
|
-
} catch (
|
|
19315
|
-
console.error(`[persist] manual-label: failed to rename ${conversationId} \u2014 ${
|
|
19376
|
+
} catch (err) {
|
|
19377
|
+
console.error(`[persist] manual-label: failed to rename ${conversationId} \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
19316
19378
|
return Response.json({ error: "Failed to rename session" }, { status: 500 });
|
|
19317
19379
|
}
|
|
19318
19380
|
}
|
|
@@ -19332,10 +19394,10 @@ async function POST29(req, remoteAddress) {
|
|
|
19332
19394
|
return Response.json({ ok: false, error: "Chrome failed to start" }, { status: 502 });
|
|
19333
19395
|
}
|
|
19334
19396
|
return Response.json({ ok: true, transport });
|
|
19335
|
-
} catch (
|
|
19336
|
-
console.error("[admin/browser/launch] Failed to start browser:",
|
|
19397
|
+
} catch (err) {
|
|
19398
|
+
console.error("[admin/browser/launch] Failed to start browser:", err);
|
|
19337
19399
|
return Response.json(
|
|
19338
|
-
{ ok: false, error:
|
|
19400
|
+
{ ok: false, error: err instanceof Error ? err.message : "Unknown error" },
|
|
19339
19401
|
{ status: 500 }
|
|
19340
19402
|
);
|
|
19341
19403
|
}
|
|
@@ -19354,12 +19416,12 @@ async function cdpNavigateNewTab(url, opts = {}) {
|
|
|
19354
19416
|
method: "PUT",
|
|
19355
19417
|
signal: AbortSignal.timeout(timeoutMs)
|
|
19356
19418
|
});
|
|
19357
|
-
} catch (
|
|
19358
|
-
const msg =
|
|
19419
|
+
} catch (err) {
|
|
19420
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
19359
19421
|
if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed") || msg.includes("ENOTFOUND")) {
|
|
19360
19422
|
return { result: "cdp-unreachable", detail: msg };
|
|
19361
19423
|
}
|
|
19362
|
-
if (
|
|
19424
|
+
if (err instanceof Error && err.name === "TimeoutError") {
|
|
19363
19425
|
return { result: "timeout", detail: msg };
|
|
19364
19426
|
}
|
|
19365
19427
|
return { result: "error", detail: msg };
|
|
@@ -19374,8 +19436,8 @@ async function cdpNavigateNewTab(url, opts = {}) {
|
|
|
19374
19436
|
let target;
|
|
19375
19437
|
try {
|
|
19376
19438
|
target = await res.json();
|
|
19377
|
-
} catch (
|
|
19378
|
-
const msg =
|
|
19439
|
+
} catch (err) {
|
|
19440
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
19379
19441
|
return { result: "error", detail: `CDP /json/new response not JSON: ${msg}` };
|
|
19380
19442
|
}
|
|
19381
19443
|
return { result: "ok", targetId: target?.id };
|
|
@@ -19387,8 +19449,8 @@ async function POST30(req, remoteAddress) {
|
|
|
19387
19449
|
let body;
|
|
19388
19450
|
try {
|
|
19389
19451
|
body = await req.json();
|
|
19390
|
-
} catch (
|
|
19391
|
-
const detail =
|
|
19452
|
+
} catch (err) {
|
|
19453
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
19392
19454
|
console.error(`${TAG18} reject reason=body-not-json detail=${detail} browser=fallback navigateResult=error`);
|
|
19393
19455
|
return Response.json(
|
|
19394
19456
|
{ ok: false, navigateResult: "error", browser: "fallback", detail: "Request body was not valid JSON" },
|
|
@@ -19482,8 +19544,8 @@ async function POST31(req) {
|
|
|
19482
19544
|
let body;
|
|
19483
19545
|
try {
|
|
19484
19546
|
body = await req.json();
|
|
19485
|
-
} catch (
|
|
19486
|
-
const detail =
|
|
19547
|
+
} catch (err) {
|
|
19548
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
19487
19549
|
console.error(`${TAG18} reject reason=body-not-json detail=${detail}`);
|
|
19488
19550
|
return Response.json({ ok: false, detail: "Request body was not valid JSON" }, { status: 400 });
|
|
19489
19551
|
}
|
|
@@ -19553,20 +19615,6 @@ function addAliasDomain(hostname2) {
|
|
|
19553
19615
|
|
|
19554
19616
|
// app/api/admin/cloudflare/setup/route.ts
|
|
19555
19617
|
var SCRIPT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
19556
|
-
function log(line) {
|
|
19557
|
-
console.log(`[cloudflare-setup] ${line}`);
|
|
19558
|
-
}
|
|
19559
|
-
function logErr(line) {
|
|
19560
|
-
console.error(`[cloudflare-setup] ${line}`);
|
|
19561
|
-
}
|
|
19562
|
-
function err(field, message, output) {
|
|
19563
|
-
logErr(`phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`);
|
|
19564
|
-
const body = { ok: false, field, message, output };
|
|
19565
|
-
return Response.json(body, { status: 200 });
|
|
19566
|
-
}
|
|
19567
|
-
function ok(result) {
|
|
19568
|
-
return Response.json(result, { status: 200 });
|
|
19569
|
-
}
|
|
19570
19618
|
function loadBrandInfo() {
|
|
19571
19619
|
const platformRoot3 = process.env.MAXY_PLATFORM_ROOT ?? resolve29(process.cwd(), "..");
|
|
19572
19620
|
const brandPath3 = resolve29(platformRoot3, "config", "brand.json");
|
|
@@ -19622,10 +19670,14 @@ function validateBody(body) {
|
|
|
19622
19670
|
}
|
|
19623
19671
|
return null;
|
|
19624
19672
|
}
|
|
19625
|
-
function runScript(scriptPath, args) {
|
|
19673
|
+
function runScript(scriptPath, args, streamLogPath, log) {
|
|
19626
19674
|
return new Promise((resolveP) => {
|
|
19627
19675
|
const child = childProcess.spawn(scriptPath, args, {
|
|
19628
|
-
|
|
19676
|
+
// STREAM_LOG_PATH (Task 581) enables setup-tunnel.sh's shared
|
|
19677
|
+
// _stream-log.sh helpers to tee phase lines + subprocess output into
|
|
19678
|
+
// the per-conversation stream log — same file the admin chat tailer
|
|
19679
|
+
// already reads for live in-turn rendering of agent events.
|
|
19680
|
+
env: { ...process.env, STREAM_LOG_PATH: streamLogPath },
|
|
19629
19681
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19630
19682
|
});
|
|
19631
19683
|
log(`phase=script-spawn pid=${child.pid ?? "unknown"} args="${args.join(" ")}"`);
|
|
@@ -19659,11 +19711,48 @@ ${e.message}`, timedOut: false });
|
|
|
19659
19711
|
}
|
|
19660
19712
|
async function POST32(req) {
|
|
19661
19713
|
const started = Date.now();
|
|
19714
|
+
let correlationId;
|
|
19715
|
+
let sessionKeyTail;
|
|
19716
|
+
let streamLogPath;
|
|
19717
|
+
function tag() {
|
|
19718
|
+
if (!correlationId) return "";
|
|
19719
|
+
return ` conversationId=${correlationId} session_key=${sessionKeyTail ?? "unknown"}`;
|
|
19720
|
+
}
|
|
19721
|
+
function log(line) {
|
|
19722
|
+
console.log(`[cloudflare-setup] ${line}${tag()}`);
|
|
19723
|
+
}
|
|
19724
|
+
function logErr(line) {
|
|
19725
|
+
console.error(`[cloudflare-setup] ${line}${tag()}`);
|
|
19726
|
+
}
|
|
19727
|
+
function err(field, message, output) {
|
|
19728
|
+
logErr(`phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`);
|
|
19729
|
+
const body2 = {
|
|
19730
|
+
ok: false,
|
|
19731
|
+
field,
|
|
19732
|
+
message,
|
|
19733
|
+
output,
|
|
19734
|
+
correlationId,
|
|
19735
|
+
streamLogPath
|
|
19736
|
+
};
|
|
19737
|
+
return Response.json(body2, { status: 200 });
|
|
19738
|
+
}
|
|
19739
|
+
function ok(result2) {
|
|
19740
|
+
return Response.json(result2, { status: 200 });
|
|
19741
|
+
}
|
|
19662
19742
|
const body = await parseBody2(req);
|
|
19663
19743
|
if (!body) return err("request", "Invalid JSON body");
|
|
19664
19744
|
if (!validateSession(body.session_key, "admin")) {
|
|
19665
19745
|
return err("request", "Invalid or expired admin session");
|
|
19666
19746
|
}
|
|
19747
|
+
const accountId = getAccountIdForSession(body.session_key);
|
|
19748
|
+
correlationId = getConversationIdForSession(body.session_key);
|
|
19749
|
+
sessionKeyTail = body.session_key.slice(-8);
|
|
19750
|
+
if (!accountId) {
|
|
19751
|
+
return err("request", "No account bound to session \u2014 refresh chat.");
|
|
19752
|
+
}
|
|
19753
|
+
if (!correlationId) {
|
|
19754
|
+
return err("request", "No active conversation for session \u2014 refresh chat.");
|
|
19755
|
+
}
|
|
19667
19756
|
const invalid = validateBody(body);
|
|
19668
19757
|
if (invalid) return err(invalid.field, invalid.message);
|
|
19669
19758
|
const adminFqdn = `${body.adminLabel}.${body.adminDomain}`;
|
|
@@ -19684,11 +19773,13 @@ async function POST32(req) {
|
|
|
19684
19773
|
} catch (e) {
|
|
19685
19774
|
return err("script", `Server misconfigured: ${e instanceof Error ? e.message : String(e)}`);
|
|
19686
19775
|
}
|
|
19776
|
+
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
19777
|
+
log(`phase=stream-log-resolved path=${streamLogPath}`);
|
|
19687
19778
|
const scriptPath = resolve29(homedir4(), "setup-tunnel.sh");
|
|
19688
19779
|
const args = [brand.hostname, String(port2), adminFqdn];
|
|
19689
19780
|
if (publicFqdn) args.push(publicFqdn);
|
|
19690
19781
|
if (apex) args.push(apex);
|
|
19691
|
-
const result = await runScript(scriptPath, args);
|
|
19782
|
+
const result = await runScript(scriptPath, args, streamLogPath, log);
|
|
19692
19783
|
const combined = `${result.stdout}${result.stderr ? `
|
|
19693
19784
|
---
|
|
19694
19785
|
${result.stderr}` : ""}`;
|
|
@@ -19742,15 +19833,15 @@ async function POST33(req) {
|
|
|
19742
19833
|
const body = await req.json();
|
|
19743
19834
|
if (typeof body?.installed === "string") installed = body.installed;
|
|
19744
19835
|
if (typeof body?.latest === "string") latest = body.latest;
|
|
19745
|
-
} catch (
|
|
19746
|
-
console.error(`[admin/version] alert-surfaced body parse failed: ${
|
|
19836
|
+
} catch (err) {
|
|
19837
|
+
console.error(`[admin/version] alert-surfaced body parse failed: ${err}`);
|
|
19747
19838
|
}
|
|
19748
19839
|
console.log(`[admin/version] alert-surfaced installed=${installed} latest=${latest ?? "null"}`);
|
|
19749
19840
|
return Response.json({ ok: true });
|
|
19750
19841
|
}
|
|
19751
19842
|
|
|
19752
19843
|
// app/api/admin/files/route.ts
|
|
19753
|
-
import { readdir as readdir2, stat as stat4 } from "fs/promises";
|
|
19844
|
+
import { readdir as readdir2, readFile as readFile4, stat as stat4 } from "fs/promises";
|
|
19754
19845
|
import { join as join14 } from "path";
|
|
19755
19846
|
|
|
19756
19847
|
// app/lib/data-path.ts
|
|
@@ -19764,18 +19855,18 @@ function resolveDataPath(raw2) {
|
|
|
19764
19855
|
let dataRootReal;
|
|
19765
19856
|
try {
|
|
19766
19857
|
dataRootReal = realpathSync3(DATA_ROOT);
|
|
19767
|
-
} catch (
|
|
19858
|
+
} catch (err) {
|
|
19768
19859
|
return {
|
|
19769
19860
|
ok: false,
|
|
19770
19861
|
status: 500,
|
|
19771
|
-
error: `DATA_ROOT not accessible: ${
|
|
19862
|
+
error: `DATA_ROOT not accessible: ${err instanceof Error ? err.message : String(err)}`
|
|
19772
19863
|
};
|
|
19773
19864
|
}
|
|
19774
19865
|
let resolvedReal;
|
|
19775
19866
|
try {
|
|
19776
19867
|
resolvedReal = realpathSync3(absolute);
|
|
19777
|
-
} catch (
|
|
19778
|
-
const code =
|
|
19868
|
+
} catch (err) {
|
|
19869
|
+
const code = err.code;
|
|
19779
19870
|
if (code === "ENOENT") {
|
|
19780
19871
|
if (absolute !== dataRootReal && !absolute.startsWith(dataRootReal + sep)) {
|
|
19781
19872
|
return { ok: false, status: 403, error: "Path escapes DATA_ROOT", resolved: absolute };
|
|
@@ -19785,7 +19876,7 @@ function resolveDataPath(raw2) {
|
|
|
19785
19876
|
return {
|
|
19786
19877
|
ok: false,
|
|
19787
19878
|
status: 500,
|
|
19788
|
-
error:
|
|
19879
|
+
error: err instanceof Error ? err.message : String(err)
|
|
19789
19880
|
};
|
|
19790
19881
|
}
|
|
19791
19882
|
if (resolvedReal !== dataRootReal && !resolvedReal.startsWith(dataRootReal + sep)) {
|
|
@@ -19796,6 +19887,39 @@ function resolveDataPath(raw2) {
|
|
|
19796
19887
|
}
|
|
19797
19888
|
|
|
19798
19889
|
// app/api/admin/files/route.ts
|
|
19890
|
+
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
19891
|
+
async function readMeta(absDir, baseName) {
|
|
19892
|
+
try {
|
|
19893
|
+
const raw2 = await readFile4(join14(absDir, `${baseName}.meta.json`), "utf8");
|
|
19894
|
+
const parsed = JSON.parse(raw2);
|
|
19895
|
+
if (typeof parsed?.filename === "string") {
|
|
19896
|
+
return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
|
|
19897
|
+
}
|
|
19898
|
+
} catch {
|
|
19899
|
+
}
|
|
19900
|
+
return null;
|
|
19901
|
+
}
|
|
19902
|
+
async function enrich(absolute, entry) {
|
|
19903
|
+
if (entry.kind === "directory" && UUID_RE2.test(entry.name)) {
|
|
19904
|
+
const meta = await readMeta(join14(absolute, entry.name), entry.name);
|
|
19905
|
+
if (meta?.filename) {
|
|
19906
|
+
entry.displayName = meta.filename;
|
|
19907
|
+
entry.mimeType = meta.mimeType;
|
|
19908
|
+
}
|
|
19909
|
+
return;
|
|
19910
|
+
}
|
|
19911
|
+
if (entry.kind === "file") {
|
|
19912
|
+
const dot = entry.name.lastIndexOf(".");
|
|
19913
|
+
const base = dot === -1 ? entry.name : entry.name.slice(0, dot);
|
|
19914
|
+
if (UUID_RE2.test(base)) {
|
|
19915
|
+
const meta = await readMeta(absolute, base);
|
|
19916
|
+
if (meta?.filename) {
|
|
19917
|
+
entry.displayName = meta.filename;
|
|
19918
|
+
entry.mimeType = meta.mimeType;
|
|
19919
|
+
}
|
|
19920
|
+
}
|
|
19921
|
+
}
|
|
19922
|
+
}
|
|
19799
19923
|
async function GET17(req) {
|
|
19800
19924
|
const url = new URL(req.url);
|
|
19801
19925
|
const sessionKey = url.searchParams.get("session_key");
|
|
@@ -19828,6 +19952,9 @@ async function GET17(req) {
|
|
|
19828
19952
|
const names = await readdir2(absolute);
|
|
19829
19953
|
const entries = [];
|
|
19830
19954
|
for (const name of names) {
|
|
19955
|
+
if (UUID_RE2.test(name.replace(/\.meta\.json$/, "")) && name.endsWith(".meta.json")) {
|
|
19956
|
+
continue;
|
|
19957
|
+
}
|
|
19831
19958
|
try {
|
|
19832
19959
|
const entryPath = join14(absolute, name);
|
|
19833
19960
|
const s = await stat4(entryPath);
|
|
@@ -19841,19 +19968,22 @@ async function GET17(req) {
|
|
|
19841
19968
|
entries.push({ name, kind: "other", sizeBytes: null, modifiedAt: (/* @__PURE__ */ new Date(0)).toISOString() });
|
|
19842
19969
|
}
|
|
19843
19970
|
}
|
|
19971
|
+
await Promise.all(entries.map((e) => enrich(absolute, e)));
|
|
19844
19972
|
entries.sort((a, b) => {
|
|
19845
19973
|
if (a.kind !== b.kind) return a.kind === "directory" ? -1 : 1;
|
|
19846
|
-
|
|
19974
|
+
const aKey = a.displayName ?? a.name;
|
|
19975
|
+
const bKey = b.displayName ?? b.name;
|
|
19976
|
+
return aKey.localeCompare(bKey);
|
|
19847
19977
|
});
|
|
19848
19978
|
console.error(`[data] file-list path="${relPath}" entries=${entries.length}`);
|
|
19849
19979
|
return Response.json({ path: relPath, entries });
|
|
19850
|
-
} catch (
|
|
19851
|
-
const code =
|
|
19980
|
+
} catch (err) {
|
|
19981
|
+
const code = err.code;
|
|
19852
19982
|
if (code === "ENOENT") {
|
|
19853
19983
|
console.error(`[data] file-list not-found path="${relPath}"`);
|
|
19854
19984
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
19855
19985
|
}
|
|
19856
|
-
const message =
|
|
19986
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
19857
19987
|
console.error(`[data] file-list error path="${relPath}" err="${message}"`);
|
|
19858
19988
|
return Response.json({ error: message }, { status: 500 });
|
|
19859
19989
|
}
|
|
@@ -19912,13 +20042,13 @@ async function GET18(req) {
|
|
|
19912
20042
|
"Cache-Control": "no-store"
|
|
19913
20043
|
}
|
|
19914
20044
|
});
|
|
19915
|
-
} catch (
|
|
19916
|
-
const code =
|
|
20045
|
+
} catch (err) {
|
|
20046
|
+
const code = err.code;
|
|
19917
20047
|
if (code === "ENOENT") {
|
|
19918
20048
|
console.error(`[data] file-download not-found path="${relPath}"`);
|
|
19919
20049
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
19920
20050
|
}
|
|
19921
|
-
const message =
|
|
20051
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
19922
20052
|
console.error(`[data] file-download error path="${relPath}" err="${message}"`);
|
|
19923
20053
|
return Response.json({ error: message }, { status: 500 });
|
|
19924
20054
|
}
|
|
@@ -19932,8 +20062,8 @@ async function POST34(req) {
|
|
|
19932
20062
|
let formData;
|
|
19933
20063
|
try {
|
|
19934
20064
|
formData = await req.formData();
|
|
19935
|
-
} catch (
|
|
19936
|
-
const message =
|
|
20065
|
+
} catch (err) {
|
|
20066
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
19937
20067
|
return Response.json({ error: `Invalid multipart body: ${message}` }, { status: 400 });
|
|
19938
20068
|
}
|
|
19939
20069
|
const sessionKey = formData.get("session_key") ?? "";
|
|
@@ -19980,8 +20110,8 @@ async function POST34(req) {
|
|
|
19980
20110
|
}
|
|
19981
20111
|
const buffer = Buffer.from(await file.arrayBuffer());
|
|
19982
20112
|
await writeFile4(destPath, buffer);
|
|
19983
|
-
} catch (
|
|
19984
|
-
const message =
|
|
20113
|
+
} catch (err) {
|
|
20114
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
19985
20115
|
console.error(`[data] file-upload error filename="${safeName}" err="${message}"`);
|
|
19986
20116
|
return Response.json({ error: message }, { status: 500 });
|
|
19987
20117
|
}
|
|
@@ -20027,9 +20157,9 @@ async function GET19(req) {
|
|
|
20027
20157
|
const elapsed = Date.now() - started;
|
|
20028
20158
|
console.error(`[data] graph-search query="${q}" results=${results.length} ms=${elapsed}`);
|
|
20029
20159
|
return Response.json({ results, elapsedMs: elapsed });
|
|
20030
|
-
} catch (
|
|
20160
|
+
} catch (err) {
|
|
20031
20161
|
const elapsed = Date.now() - started;
|
|
20032
|
-
const message =
|
|
20162
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
20033
20163
|
console.error(`[data] graph-search neo4j-unreachable query="${q}" ms=${elapsed} err="${message}"`);
|
|
20034
20164
|
return Response.json({ error: `Graph search unavailable: ${message}` }, { status: 503 });
|
|
20035
20165
|
}
|
|
@@ -20049,8 +20179,8 @@ if (BRAND_JSON_PATH && existsSync29(BRAND_JSON_PATH)) {
|
|
|
20049
20179
|
try {
|
|
20050
20180
|
const parsed = JSON.parse(readFileSync29(BRAND_JSON_PATH, "utf-8"));
|
|
20051
20181
|
BRAND = { ...BRAND, ...parsed };
|
|
20052
|
-
} catch (
|
|
20053
|
-
console.error(`[brand] Failed to parse brand.json: ${
|
|
20182
|
+
} catch (err) {
|
|
20183
|
+
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
20054
20184
|
process.exit(1);
|
|
20055
20185
|
}
|
|
20056
20186
|
}
|
|
@@ -20076,8 +20206,8 @@ function loadAliasDomains() {
|
|
|
20076
20206
|
return null;
|
|
20077
20207
|
}
|
|
20078
20208
|
return new Set(parsed.filter((h) => typeof h === "string"));
|
|
20079
|
-
} catch (
|
|
20080
|
-
console.error(`[alias-domains] failed to read alias-domains.json: ${
|
|
20209
|
+
} catch (err) {
|
|
20210
|
+
console.error(`[alias-domains] failed to read alias-domains.json: ${err}`);
|
|
20081
20211
|
return null;
|
|
20082
20212
|
}
|
|
20083
20213
|
}
|
|
@@ -20257,8 +20387,8 @@ app.post("/__remote-auth/change-password", async (c) => {
|
|
|
20257
20387
|
clearRateLimit(clientIp);
|
|
20258
20388
|
console.error(`[remote-auth] password changed ip=${clientIp}`);
|
|
20259
20389
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), success: "Password changed successfully. Sign in with your new password.", redirect }), 200);
|
|
20260
|
-
} catch (
|
|
20261
|
-
console.error(`[remote-auth] change-password save failed: ${
|
|
20390
|
+
} catch (err) {
|
|
20391
|
+
console.error(`[remote-auth] change-password save failed: ${err}`);
|
|
20262
20392
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
20263
20393
|
}
|
|
20264
20394
|
});
|
|
@@ -20302,8 +20432,8 @@ app.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
20302
20432
|
) ?? "unknown";
|
|
20303
20433
|
console.error(`[remote-auth] initial password set ip=${clientIp}`);
|
|
20304
20434
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "success" }), 200);
|
|
20305
|
-
} catch (
|
|
20306
|
-
console.error(`[remote-auth] initial password save failed: ${
|
|
20435
|
+
} catch (err) {
|
|
20436
|
+
console.error(`[remote-auth] initial password save failed: ${err}`);
|
|
20307
20437
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
20308
20438
|
}
|
|
20309
20439
|
});
|
|
@@ -20335,8 +20465,8 @@ app.post("/api/remote-auth/set-password", async (c) => {
|
|
|
20335
20465
|
await setRemotePassword(body.password);
|
|
20336
20466
|
console.error("[remote-auth] password set");
|
|
20337
20467
|
return Response.json({ ok: true });
|
|
20338
|
-
} catch (
|
|
20339
|
-
console.error(`[remote-auth] set-password failed: ${
|
|
20468
|
+
} catch (err) {
|
|
20469
|
+
console.error(`[remote-auth] set-password failed: ${err}`);
|
|
20340
20470
|
return Response.json({ error: "Failed to save password" }, { status: 500 });
|
|
20341
20471
|
}
|
|
20342
20472
|
});
|
|
@@ -20789,8 +20919,8 @@ try {
|
|
|
20789
20919
|
}
|
|
20790
20920
|
const summary = registered.map((r) => `${r.method} ${r.path}`).join(", ") || "(none)";
|
|
20791
20921
|
console.log(`[route-shadow] static-paths-matching-slug-pattern count=${registered.length} routes=${summary}`);
|
|
20792
|
-
} catch (
|
|
20793
|
-
console.error(`[route-shadow] introspection unavailable: ${
|
|
20922
|
+
} catch (err) {
|
|
20923
|
+
console.error(`[route-shadow] introspection unavailable: ${err instanceof Error ? err.message : String(err)}`);
|
|
20794
20924
|
}
|
|
20795
20925
|
(async () => {
|
|
20796
20926
|
try {
|
|
@@ -20800,15 +20930,15 @@ try {
|
|
|
20800
20930
|
userId = users[0]?.userId ?? "";
|
|
20801
20931
|
}
|
|
20802
20932
|
await backfillNullUserIdConversations(userId);
|
|
20803
|
-
} catch (
|
|
20804
|
-
console.error(`[session] backfill startup failed: ${
|
|
20933
|
+
} catch (err) {
|
|
20934
|
+
console.error(`[session] backfill startup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
20805
20935
|
}
|
|
20806
20936
|
})();
|
|
20807
20937
|
(async () => {
|
|
20808
20938
|
try {
|
|
20809
20939
|
await startReviewDetector();
|
|
20810
|
-
} catch (
|
|
20811
|
-
console.error(`[review] startReviewDetector rejected: ${
|
|
20940
|
+
} catch (err) {
|
|
20941
|
+
console.error(`[review] startReviewDetector rejected: ${err instanceof Error ? err.message : String(err)}`);
|
|
20812
20942
|
}
|
|
20813
20943
|
})();
|
|
20814
20944
|
var configDirForWhatsApp = basename8(MAXY_DIR) || ".maxy";
|
|
@@ -20914,8 +21044,8 @@ init({
|
|
|
20914
21044
|
}
|
|
20915
21045
|
await msg.reply(responseText);
|
|
20916
21046
|
}
|
|
20917
|
-
} catch (
|
|
20918
|
-
console.error(`[whatsapp:route] agent invocation failed: ${String(
|
|
21047
|
+
} catch (err) {
|
|
21048
|
+
console.error(`[whatsapp:route] agent invocation failed: ${String(err)}`);
|
|
20919
21049
|
try {
|
|
20920
21050
|
if (!msg.isOwnerMirror) {
|
|
20921
21051
|
await msg.reply("I'm having trouble right now. Please try again in a moment.");
|
|
@@ -20924,8 +21054,8 @@ init({
|
|
|
20924
21054
|
}
|
|
20925
21055
|
}
|
|
20926
21056
|
}
|
|
20927
|
-
}).catch((
|
|
20928
|
-
console.error(`[whatsapp] init failed: ${String(
|
|
21057
|
+
}).catch((err) => {
|
|
21058
|
+
console.error(`[whatsapp] init failed: ${String(err)}`);
|
|
20929
21059
|
});
|
|
20930
21060
|
var shuttingDown = false;
|
|
20931
21061
|
process.on("SIGTERM", async () => {
|
|
@@ -20937,24 +21067,24 @@ process.on("SIGTERM", async () => {
|
|
|
20937
21067
|
console.error("[server] SIGTERM received \u2014 starting graceful shutdown");
|
|
20938
21068
|
try {
|
|
20939
21069
|
sigtermFlushStreamLogs("systemd-stop", "server-index");
|
|
20940
|
-
} catch (
|
|
20941
|
-
console.error(`[server] sigterm flush error: ${String(
|
|
21070
|
+
} catch (err) {
|
|
21071
|
+
console.error(`[server] sigterm flush error: ${String(err)}`);
|
|
20942
21072
|
}
|
|
20943
21073
|
try {
|
|
20944
21074
|
broadcastAdminShutdown("systemd-stop");
|
|
20945
|
-
} catch (
|
|
20946
|
-
console.error(`[server] sigterm broadcast error: ${String(
|
|
21075
|
+
} catch (err) {
|
|
21076
|
+
console.error(`[server] sigterm broadcast error: ${String(err)}`);
|
|
20947
21077
|
}
|
|
20948
21078
|
await new Promise((res) => setImmediate(res));
|
|
20949
21079
|
try {
|
|
20950
21080
|
await shutdown();
|
|
20951
|
-
} catch (
|
|
20952
|
-
console.error(`[server] shutdown error: ${String(
|
|
21081
|
+
} catch (err) {
|
|
21082
|
+
console.error(`[server] shutdown error: ${String(err)}`);
|
|
20953
21083
|
}
|
|
20954
21084
|
try {
|
|
20955
21085
|
await shutdownReviewDetector();
|
|
20956
|
-
} catch (
|
|
20957
|
-
console.error(`[server] review detector shutdown error: ${String(
|
|
21086
|
+
} catch (err) {
|
|
21087
|
+
console.error(`[server] review detector shutdown error: ${String(err)}`);
|
|
20958
21088
|
}
|
|
20959
21089
|
console.error("[server] graceful shutdown complete \u2014 exiting");
|
|
20960
21090
|
process.exit(0);
|