@rubytech/create-realagent 1.0.826 → 1.0.829
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/neo4j/schema.cypher +35 -2
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/hooks/__tests__/archive-ingest-surface-gate.test.sh +39 -54
- package/payload/platform/plugins/admin/hooks/archive-ingest-surface-gate.sh +26 -52
- package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +7 -7
- package/payload/platform/plugins/docs/references/cloudflare.md +1 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +1 -0
- package/payload/platform/plugins/memory/PLUGIN.md +5 -5
- package/payload/platform/plugins/memory/mcp/dist/index.js +18 -253
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js +51 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-validator.test.js +103 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-validator.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts +19 -4
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js +149 -56
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/schema-validator.d.ts +16 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/schema-validator.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/schema-validator.js +12 -3
- package/payload/platform/plugins/memory/mcp/dist/lib/schema-validator.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write.test.js +2 -138
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js +66 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-open.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-open.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-open.test.js +148 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-open.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts +1 -64
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +6 -336
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +30 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +231 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts +21 -17
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +77 -37
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
- package/payload/platform/plugins/memory/references/schema-base.md +7 -2
- package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +54 -4
- package/payload/platform/plugins/whatsapp/PLUGIN.md +1 -1
- package/payload/platform/plugins/whatsapp-import/lib/dist/delta-cursor.d.ts +18 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/delta-cursor.d.ts.map +1 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/delta-cursor.js +31 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/delta-cursor.js.map +1 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/derive-keys.d.ts +27 -12
- package/payload/platform/plugins/whatsapp-import/lib/dist/derive-keys.d.ts.map +1 -1
- package/payload/platform/plugins/whatsapp-import/lib/dist/derive-keys.js +40 -20
- package/payload/platform/plugins/whatsapp-import/lib/dist/derive-keys.js.map +1 -1
- package/payload/platform/plugins/whatsapp-import/lib/dist/index.d.ts +7 -4
- package/payload/platform/plugins/whatsapp-import/lib/dist/index.d.ts.map +1 -1
- package/payload/platform/plugins/whatsapp-import/lib/dist/index.js +9 -6
- package/payload/platform/plugins/whatsapp-import/lib/dist/index.js.map +1 -1
- package/payload/platform/plugins/whatsapp-import/lib/dist/sessionize.d.ts +25 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/sessionize.d.ts.map +1 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/sessionize.js +48 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/sessionize.js.map +1 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/to-classifier-input.d.ts +3 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/to-classifier-input.d.ts.map +1 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/to-classifier-input.js +47 -0
- package/payload/platform/plugins/whatsapp-import/lib/dist/to-classifier-input.js.map +1 -0
- package/payload/platform/scripts/seed-neo4j.sh +15 -14
- package/payload/platform/templates/specialists/agents/database-operator.md +10 -17
- package/payload/server/chunk-CUSH3UXP.js +2305 -0
- package/payload/server/chunk-IWNDVGKT.js +10077 -0
- package/payload/server/chunk-KC7NUABI.js +654 -0
- package/payload/server/chunk-T2OPNP3L.js +654 -0
- package/payload/server/chunk-WUVXPZIV.js +1116 -0
- package/payload/server/client-pool-3TM3SRIA.js +32 -0
- package/payload/server/cloudflare-task-tracker-4NIODMGL.js +19 -0
- package/payload/server/cloudflare-task-tracker-CR6TL4VL.js +19 -0
- package/payload/server/maxy-edge.js +3 -3
- package/payload/server/neo4j-migrations-XTQ4WEV6.js +428 -0
- package/payload/server/public/assets/{admin-DOkUspG1.js → admin-BNwPsMhJ.js} +2 -2
- package/payload/server/public/assets/{graph-LLMJa4Ch.js → graph-N_Bw-8oT.js} +1 -1
- package/payload/server/public/assets/{page-DoaF3DB0.js → page-BKLGP-th.js} +1 -1
- package/payload/server/public/graph.html +2 -2
- package/payload/server/public/index.html +2 -2
- package/payload/server/server.js +281 -168
- package/payload/platform/plugins/whatsapp-import/PLUGIN.md +0 -46
- package/payload/platform/plugins/whatsapp-import/bin/ingest.mjs +0 -670
- package/payload/platform/plugins/whatsapp-import/bin/whatsapp-ingest.sh +0 -131
- package/payload/platform/plugins/whatsapp-import/lib/src/__tests__/filter-gate.test.ts +0 -172
- package/payload/platform/plugins/whatsapp-import/lib/src/__tests__/ingest-idempotence.test.ts +0 -141
- package/payload/platform/plugins/whatsapp-import/lib/src/__tests__/parse-export-lrm.test.ts +0 -83
- package/payload/platform/plugins/whatsapp-import/lib/src/__tests__/parse-export.test.ts +0 -678
- package/payload/platform/plugins/whatsapp-import/lib/src/derive-keys.ts +0 -59
- package/payload/platform/plugins/whatsapp-import/lib/src/filter.ts +0 -136
- package/payload/platform/plugins/whatsapp-import/lib/src/index.ts +0 -19
- package/payload/platform/plugins/whatsapp-import/lib/src/parse-export.ts +0 -471
- package/payload/platform/plugins/whatsapp-import/lib/tsconfig.json +0 -9
- package/payload/platform/plugins/whatsapp-import/lib/vitest.config.ts +0 -9
- package/payload/platform/plugins/whatsapp-import/skills/whatsapp-import/SKILL.md +0 -131
- package/payload/platform/plugins/whatsapp-import/skills/whatsapp-import/references/export-parse.md +0 -109
- package/payload/platform/plugins/whatsapp-import/skills/whatsapp-import-enrich/SKILL.md +0 -333
package/payload/server/server.js
CHANGED
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
vncLog,
|
|
52
52
|
waitForExit,
|
|
53
53
|
writeChromiumWrapper
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-IWNDVGKT.js";
|
|
55
55
|
import {
|
|
56
56
|
agentLogStream,
|
|
57
57
|
clearSessionHistory,
|
|
@@ -79,7 +79,7 @@ import {
|
|
|
79
79
|
sigtermFlushStreamLogs,
|
|
80
80
|
unregisterSession,
|
|
81
81
|
validateSession
|
|
82
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-WUVXPZIV.js";
|
|
83
83
|
import {
|
|
84
84
|
ACCOUNTS_DIR,
|
|
85
85
|
PLATFORM_ROOT,
|
|
@@ -95,8 +95,9 @@ import {
|
|
|
95
95
|
appendCloudflareSteps,
|
|
96
96
|
completeCloudflareTask,
|
|
97
97
|
openCloudflareTask,
|
|
98
|
-
readTunnelState
|
|
99
|
-
|
|
98
|
+
readTunnelState,
|
|
99
|
+
resolveUnitGoneVerdict
|
|
100
|
+
} from "./chunk-KC7NUABI.js";
|
|
100
101
|
import {
|
|
101
102
|
GREETING_DIRECTIVE,
|
|
102
103
|
HAIKU_MODEL,
|
|
@@ -128,7 +129,7 @@ import {
|
|
|
128
129
|
verifyAndGetConversationUpdatedAt,
|
|
129
130
|
verifyConversationOwnership,
|
|
130
131
|
writeAdminUserAndPerson
|
|
131
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-CUSH3UXP.js";
|
|
132
133
|
|
|
133
134
|
// ../lib/graph-trash/dist/index.js
|
|
134
135
|
var require_dist = __commonJS({
|
|
@@ -627,8 +628,8 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
627
628
|
};
|
|
628
629
|
|
|
629
630
|
// server/index.ts
|
|
630
|
-
import { readFileSync as
|
|
631
|
-
import { resolve as
|
|
631
|
+
import { readFileSync as readFileSync16, existsSync as existsSync22, watchFile } from "fs";
|
|
632
|
+
import { resolve as resolve22, join as join10, basename as basename5 } from "path";
|
|
632
633
|
import { homedir as homedir2 } from "os";
|
|
633
634
|
|
|
634
635
|
// app/lib/agent-slug-pattern.ts
|
|
@@ -1272,7 +1273,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
1272
1273
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
1273
1274
|
console.error(`${TAG3} draining credential save queue\u2026`);
|
|
1274
1275
|
const timer2 = new Promise(
|
|
1275
|
-
(
|
|
1276
|
+
(resolve23) => setTimeout(() => resolve23("timeout"), timeoutMs)
|
|
1276
1277
|
);
|
|
1277
1278
|
const result = await Promise.race([
|
|
1278
1279
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -1400,11 +1401,11 @@ async function createWaSocket(opts) {
|
|
|
1400
1401
|
return sock;
|
|
1401
1402
|
}
|
|
1402
1403
|
async function waitForConnection(sock) {
|
|
1403
|
-
return new Promise((
|
|
1404
|
+
return new Promise((resolve23, reject) => {
|
|
1404
1405
|
const handler = (update) => {
|
|
1405
1406
|
if (update.connection === "open") {
|
|
1406
1407
|
sock.ev.off("connection.update", handler);
|
|
1407
|
-
|
|
1408
|
+
resolve23();
|
|
1408
1409
|
}
|
|
1409
1410
|
if (update.connection === "close") {
|
|
1410
1411
|
sock.ev.off("connection.update", handler);
|
|
@@ -1518,14 +1519,14 @@ ${inspected}`;
|
|
|
1518
1519
|
return inspect2(err, INSPECT_OPTS2);
|
|
1519
1520
|
}
|
|
1520
1521
|
function withTimeout(label, promise, timeoutMs) {
|
|
1521
|
-
return new Promise((
|
|
1522
|
+
return new Promise((resolve23, reject) => {
|
|
1522
1523
|
const timer2 = setTimeout(() => {
|
|
1523
1524
|
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
1524
1525
|
}, timeoutMs);
|
|
1525
1526
|
promise.then(
|
|
1526
1527
|
(value) => {
|
|
1527
1528
|
clearTimeout(timer2);
|
|
1528
|
-
|
|
1529
|
+
resolve23(value);
|
|
1529
1530
|
},
|
|
1530
1531
|
(err) => {
|
|
1531
1532
|
clearTimeout(timer2);
|
|
@@ -2060,8 +2061,8 @@ async function persistWhatsAppMessage(input) {
|
|
|
2060
2061
|
const { givenName, familyName } = splitName(input.pushName);
|
|
2061
2062
|
const prev = sessionWriteLocks.get(input.sessionKey);
|
|
2062
2063
|
let release;
|
|
2063
|
-
const mine = new Promise((
|
|
2064
|
-
release =
|
|
2064
|
+
const mine = new Promise((resolve23) => {
|
|
2065
|
+
release = resolve23;
|
|
2065
2066
|
});
|
|
2066
2067
|
const chained = (prev ?? Promise.resolve()).then(() => mine);
|
|
2067
2068
|
sessionWriteLocks.set(input.sessionKey, chained);
|
|
@@ -3068,11 +3069,11 @@ async function connectWithReconnect(conn) {
|
|
|
3068
3069
|
console.error(
|
|
3069
3070
|
`${TAG13} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
3070
3071
|
);
|
|
3071
|
-
await new Promise((
|
|
3072
|
-
const timer2 = setTimeout(
|
|
3072
|
+
await new Promise((resolve23) => {
|
|
3073
|
+
const timer2 = setTimeout(resolve23, delay);
|
|
3073
3074
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
3074
3075
|
clearTimeout(timer2);
|
|
3075
|
-
|
|
3076
|
+
resolve23();
|
|
3076
3077
|
}, { once: true });
|
|
3077
3078
|
});
|
|
3078
3079
|
}
|
|
@@ -3080,16 +3081,16 @@ async function connectWithReconnect(conn) {
|
|
|
3080
3081
|
}
|
|
3081
3082
|
}
|
|
3082
3083
|
function waitForDisconnectEvent(conn) {
|
|
3083
|
-
return new Promise((
|
|
3084
|
+
return new Promise((resolve23) => {
|
|
3084
3085
|
if (!conn.sock) {
|
|
3085
|
-
|
|
3086
|
+
resolve23();
|
|
3086
3087
|
return;
|
|
3087
3088
|
}
|
|
3088
3089
|
const sock = conn.sock;
|
|
3089
3090
|
const handler = (update) => {
|
|
3090
3091
|
if (update.connection === "close") {
|
|
3091
3092
|
sock.ev.off("connection.update", handler);
|
|
3092
|
-
|
|
3093
|
+
resolve23();
|
|
3093
3094
|
}
|
|
3094
3095
|
};
|
|
3095
3096
|
sock.ev.on("connection.update", handler);
|
|
@@ -3350,8 +3351,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
3350
3351
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
3351
3352
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
3352
3353
|
let resolvePending;
|
|
3353
|
-
const sttPending = new Promise((
|
|
3354
|
-
resolvePending =
|
|
3354
|
+
const sttPending = new Promise((resolve23) => {
|
|
3355
|
+
resolvePending = resolve23;
|
|
3355
3356
|
});
|
|
3356
3357
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
3357
3358
|
try {
|
|
@@ -3472,20 +3473,20 @@ async function probeApiKey() {
|
|
|
3472
3473
|
return result.status;
|
|
3473
3474
|
}
|
|
3474
3475
|
function checkPort(port2, timeoutMs = 500) {
|
|
3475
|
-
return new Promise((
|
|
3476
|
+
return new Promise((resolve23) => {
|
|
3476
3477
|
const socket = createConnection(port2, "127.0.0.1");
|
|
3477
3478
|
socket.setTimeout(timeoutMs);
|
|
3478
3479
|
socket.once("connect", () => {
|
|
3479
3480
|
socket.destroy();
|
|
3480
|
-
|
|
3481
|
+
resolve23(true);
|
|
3481
3482
|
});
|
|
3482
3483
|
socket.once("error", () => {
|
|
3483
3484
|
socket.destroy();
|
|
3484
|
-
|
|
3485
|
+
resolve23(false);
|
|
3485
3486
|
});
|
|
3486
3487
|
socket.once("timeout", () => {
|
|
3487
3488
|
socket.destroy();
|
|
3488
|
-
|
|
3489
|
+
resolve23(false);
|
|
3489
3490
|
});
|
|
3490
3491
|
});
|
|
3491
3492
|
}
|
|
@@ -5686,8 +5687,8 @@ async function startLogin(opts) {
|
|
|
5686
5687
|
resetActiveLogin(accountId);
|
|
5687
5688
|
let resolveQr = null;
|
|
5688
5689
|
let rejectQr = null;
|
|
5689
|
-
const qrPromise = new Promise((
|
|
5690
|
-
resolveQr =
|
|
5690
|
+
const qrPromise = new Promise((resolve23, reject) => {
|
|
5691
|
+
resolveQr = resolve23;
|
|
5691
5692
|
rejectQr = reject;
|
|
5692
5693
|
});
|
|
5693
5694
|
const qrTimer = setTimeout(
|
|
@@ -7284,7 +7285,7 @@ var app11 = new Hono();
|
|
|
7284
7285
|
app11.post("/cancel", requireAdminSession, async (c) => {
|
|
7285
7286
|
const session_key = c.var.sessionKey;
|
|
7286
7287
|
try {
|
|
7287
|
-
const { interruptClient: interruptClient2 } = await import("./client-pool-
|
|
7288
|
+
const { interruptClient: interruptClient2 } = await import("./client-pool-3TM3SRIA.js");
|
|
7288
7289
|
await interruptClient2(session_key);
|
|
7289
7290
|
return c.json({ ok: true });
|
|
7290
7291
|
} catch (err) {
|
|
@@ -8039,6 +8040,17 @@ var agents_default = app16;
|
|
|
8039
8040
|
import crypto2 from "crypto";
|
|
8040
8041
|
import { resolve as resolvePath } from "path";
|
|
8041
8042
|
import { appendFileSync as appendFileSync4, existsSync as existsSync15 } from "fs";
|
|
8043
|
+
|
|
8044
|
+
// app/lib/synthetic-marker.ts
|
|
8045
|
+
var CLOUDFLARE_MARKER_PREFIX = "Cloudflare setup completed (actionId: ";
|
|
8046
|
+
var COMPONENT_DONE_PREFIX = '{"_componentDone"';
|
|
8047
|
+
var LIFECYCLE_PREFIX = '{"_lifecycle"';
|
|
8048
|
+
function isSyntheticUserMarker(content) {
|
|
8049
|
+
if (typeof content !== "string" || content.length === 0) return false;
|
|
8050
|
+
return content.startsWith(COMPONENT_DONE_PREFIX) || content.startsWith(LIFECYCLE_PREFIX) || content.startsWith(CLOUDFLARE_MARKER_PREFIX);
|
|
8051
|
+
}
|
|
8052
|
+
|
|
8053
|
+
// server/routes/admin/sessions.ts
|
|
8042
8054
|
function validateAndShapeAttachments(raws, conversationAccountId, conversationId, messageId, streamLogPath) {
|
|
8043
8055
|
const chips = [];
|
|
8044
8056
|
let valid = 0;
|
|
@@ -8310,6 +8322,7 @@ app17.post("/:id/resume", async (c) => {
|
|
|
8310
8322
|
let totalComponents = 0;
|
|
8311
8323
|
let totalAttachments = 0;
|
|
8312
8324
|
let totalAttachmentInvalid = 0;
|
|
8325
|
+
let syntheticHidden = 0;
|
|
8313
8326
|
const rehydrated = messages.map((m) => {
|
|
8314
8327
|
const components = m.components ?? [];
|
|
8315
8328
|
const rawAttachments = m.attachments ?? [];
|
|
@@ -8318,6 +8331,7 @@ app17.post("/:id/resume", async (c) => {
|
|
|
8318
8331
|
totalAttachments += valid2;
|
|
8319
8332
|
totalAttachmentInvalid += invalid2;
|
|
8320
8333
|
const cleanedContent = chips.length > 0 ? stripAttachmentMetaSuffix(m.content) : m.content;
|
|
8334
|
+
if (m.role === "user" && isSyntheticUserMarker(cleanedContent)) syntheticHidden += 1;
|
|
8321
8335
|
return {
|
|
8322
8336
|
messageId: m.messageId,
|
|
8323
8337
|
role: m.role,
|
|
@@ -8344,7 +8358,7 @@ app17.post("/:id/resume", async (c) => {
|
|
|
8344
8358
|
const userMessageCount = rehydrated.filter((m) => m.role !== "assistant").length;
|
|
8345
8359
|
const reason = bridged ? "post-restart" : "page-refresh";
|
|
8346
8360
|
try {
|
|
8347
|
-
appendFileSync4(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-resume] reason=${reason} sessionKey=${sessionKey.slice(0, 8)} conversationId=${conversationId.slice(0, 8)} ${tag} loadedMessages=${messages.length} componentCount=${totalComponents} userAttachmentCount=${totalAttachments}
|
|
8361
|
+
appendFileSync4(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-resume] reason=${reason} sessionKey=${sessionKey.slice(0, 8)} conversationId=${conversationId.slice(0, 8)} ${tag} loadedMessages=${messages.length} componentCount=${totalComponents} userAttachmentCount=${totalAttachments} syntheticHidden=${syntheticHidden}
|
|
8348
8362
|
`);
|
|
8349
8363
|
if (totalComponents > 0) {
|
|
8350
8364
|
appendFileSync4(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [component-rehydrate] conversationId=${conversationId.slice(0, 8)} count=${totalComponents} valid=${totalValid} invalid=${totalInvalid} textRuns=${textRuns}
|
|
@@ -8357,7 +8371,7 @@ app17.post("/:id/resume", async (c) => {
|
|
|
8357
8371
|
} catch {
|
|
8358
8372
|
}
|
|
8359
8373
|
const age = formatAge(updatedAt);
|
|
8360
|
-
console.log(`[admin-resume] ${(/* @__PURE__ */ new Date()).toISOString()} reason=${reason} conversationId=${conversationId.slice(0, 8)}\u2026 age=${age} loaded=${messages.length} messages ${tag} components=${totalComponents} attachments=${totalAttachments} sessionKey=${sessionKey.slice(0, 8)}\u2026`);
|
|
8374
|
+
console.log(`[admin-resume] ${(/* @__PURE__ */ new Date()).toISOString()} reason=${reason} conversationId=${conversationId.slice(0, 8)}\u2026 age=${age} loaded=${messages.length} messages ${tag} components=${totalComponents} attachments=${totalAttachments} syntheticHidden=${syntheticHidden} sessionKey=${sessionKey.slice(0, 8)}\u2026`);
|
|
8361
8375
|
return c.json({ conversationId, messages: rehydrated });
|
|
8362
8376
|
});
|
|
8363
8377
|
app17.post("/:id/label", requireAdminSession, async (c) => {
|
|
@@ -8880,8 +8894,8 @@ app21.get("/tunnels", requireAdminSession, async (c) => {
|
|
|
8880
8894
|
if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
|
|
8881
8895
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
8882
8896
|
const certPath = resolve14(homedir(), brand.configDir, "cloudflared", "cert.pem");
|
|
8883
|
-
const { existsSync:
|
|
8884
|
-
if (!
|
|
8897
|
+
const { existsSync: existsSync23 } = await import("fs");
|
|
8898
|
+
if (!existsSync23(certPath)) {
|
|
8885
8899
|
return err("cert", `Cloudflare origin certificate is not on disk yet (${certPath}). Complete the Cloudflare login first by submitting the form once \u2014 the OAuth flow writes cert.pem.`);
|
|
8886
8900
|
}
|
|
8887
8901
|
const result = await runFormSpawn({
|
|
@@ -9061,38 +9075,63 @@ app21.post("/setup", requireAdminSession, async (c) => {
|
|
|
9061
9075
|
} catch (e) {
|
|
9062
9076
|
logErr(`phase=task-steps-append-failed reason="${e instanceof Error ? e.message : String(e)}"`);
|
|
9063
9077
|
}
|
|
9064
|
-
|
|
9065
|
-
|
|
9078
|
+
let unitGoneWithDiskProof = false;
|
|
9079
|
+
if (status === null) {
|
|
9080
|
+
const verdict = resolveUnitGoneVerdict({
|
|
9081
|
+
tunnelState: readTunnelState(brand.configDir),
|
|
9082
|
+
expected: { tunnelName: body.tunnelName, tunnelId: body.tunnelId }
|
|
9083
|
+
});
|
|
9084
|
+
const resolution = verdict.kind === "close-completed" ? "close-completed" : "close-failed-diagnostic";
|
|
9085
|
+
log(`phase=post-exit-disk-check tunnel-state-found=${verdict.tunnelStateFound} identity-match=${verdict.identityMatch} resolution=${resolution}`);
|
|
9086
|
+
if (verdict.kind === "close-failed") {
|
|
9087
|
+
try {
|
|
9088
|
+
await completeCloudflareTask({
|
|
9089
|
+
taskId: cloudflareTask.taskId,
|
|
9090
|
+
taskElementId: cloudflareTask.taskElementId,
|
|
9091
|
+
accountId,
|
|
9092
|
+
conversationKey: sessionKey,
|
|
9093
|
+
status: "failed",
|
|
9094
|
+
errorMessage: CLOUDFLARE_TASK_DIAGNOSTICS.endpointDiedPreReconcile
|
|
9095
|
+
});
|
|
9096
|
+
} catch (e) {
|
|
9097
|
+
logErr(`phase=task-close-failed status=failed reason="${e instanceof Error ? e.message : String(e)}"`);
|
|
9098
|
+
}
|
|
9099
|
+
return;
|
|
9100
|
+
}
|
|
9101
|
+
unitGoneWithDiskProof = true;
|
|
9102
|
+
} else if (status.execMainStatus !== 0) {
|
|
9103
|
+
logErr(`phase=post-exit-skipped reason=exit=${status.execMainStatus} id=${actionId}`);
|
|
9066
9104
|
try {
|
|
9067
|
-
const diagnostic = status ? `${CLOUDFLARE_TASK_DIAGNOSTICS.scriptExitedNonzero} exit=${status.execMainStatus}` : CLOUDFLARE_TASK_DIAGNOSTICS.endpointDiedPreReconcile;
|
|
9068
9105
|
await completeCloudflareTask({
|
|
9069
9106
|
taskId: cloudflareTask.taskId,
|
|
9070
9107
|
taskElementId: cloudflareTask.taskElementId,
|
|
9071
9108
|
accountId,
|
|
9072
9109
|
conversationKey: sessionKey,
|
|
9073
9110
|
status: "failed",
|
|
9074
|
-
errorMessage:
|
|
9111
|
+
errorMessage: `${CLOUDFLARE_TASK_DIAGNOSTICS.scriptExitedNonzero} exit=${status.execMainStatus}`
|
|
9075
9112
|
});
|
|
9076
9113
|
} catch (e) {
|
|
9077
9114
|
logErr(`phase=task-close-failed status=failed reason="${e instanceof Error ? e.message : String(e)}"`);
|
|
9078
9115
|
}
|
|
9079
9116
|
return;
|
|
9080
9117
|
}
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9118
|
+
if (!unitGoneWithDiskProof) {
|
|
9119
|
+
const candidates = [publicFqdn, apex].filter((h) => typeof h === "string" && h.length > 0);
|
|
9120
|
+
for (const host of candidates) {
|
|
9121
|
+
if (host === adminFqdn) {
|
|
9122
|
+
log(`phase=alias-domain-write host=${host} result=skipped-admin`);
|
|
9123
|
+
continue;
|
|
9124
|
+
}
|
|
9125
|
+
if (host.startsWith("public.")) {
|
|
9126
|
+
log(`phase=alias-domain-write host=${host} result=skipped-public-prefix`);
|
|
9127
|
+
continue;
|
|
9128
|
+
}
|
|
9129
|
+
try {
|
|
9130
|
+
addAliasDomain(host);
|
|
9131
|
+
log(`phase=alias-domain-write host=${host} result=written`);
|
|
9132
|
+
} catch (e) {
|
|
9133
|
+
logErr(`phase=alias-domain-write host=${host} result=error reason="${e instanceof Error ? e.message : String(e)}"`);
|
|
9134
|
+
}
|
|
9096
9135
|
}
|
|
9097
9136
|
}
|
|
9098
9137
|
try {
|
|
@@ -10276,6 +10315,11 @@ var GRAPH_LABEL_COLOURS = {
|
|
|
10276
10315
|
AccessGrant: "#66381F",
|
|
10277
10316
|
// Knowledge — moss family (organic)
|
|
10278
10317
|
KnowledgeDocument: "#6E8A5A",
|
|
10318
|
+
// Task 891 — chunked WhatsApp/messaging archive parent. Sits in the
|
|
10319
|
+
// knowledge moss family because it's structurally a document parent
|
|
10320
|
+
// (HAS_SECTION → :Section:Conversation chunks); the conversational
|
|
10321
|
+
// plum family is reserved for the live Conversation/Message labels.
|
|
10322
|
+
ConversationArchive: "#82A06A",
|
|
10279
10323
|
Section: "#8AA876",
|
|
10280
10324
|
Chunk: "#A6C194",
|
|
10281
10325
|
DigitalDocument: "#5A7548",
|
|
@@ -11742,37 +11786,106 @@ app33.get("/", requireAdminSession, async (c) => {
|
|
|
11742
11786
|
});
|
|
11743
11787
|
var sidebar_artefact_content_default = app33;
|
|
11744
11788
|
|
|
11745
|
-
// server/routes/admin/
|
|
11789
|
+
// server/routes/admin/health.ts
|
|
11790
|
+
import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
|
|
11791
|
+
import { resolve as resolve20, join as join9 } from "path";
|
|
11792
|
+
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
|
|
11793
|
+
var brandHostname = "maxy";
|
|
11794
|
+
var brandJsonPath = join9(PLATFORM_ROOT7, "config", "brand.json");
|
|
11795
|
+
if (existsSync20(brandJsonPath)) {
|
|
11796
|
+
try {
|
|
11797
|
+
const brand = JSON.parse(readFileSync14(brandJsonPath, "utf-8"));
|
|
11798
|
+
if (brand.hostname) brandHostname = brand.hostname;
|
|
11799
|
+
} catch {
|
|
11800
|
+
}
|
|
11801
|
+
}
|
|
11802
|
+
var VERSION_FILE = resolve20(PLATFORM_ROOT7, `config/.${brandHostname}-version`);
|
|
11803
|
+
var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
11804
|
+
var PROBE_TIMEOUT_MS = 1e3;
|
|
11805
|
+
function readVersion() {
|
|
11806
|
+
if (!existsSync20(VERSION_FILE)) return "unknown";
|
|
11807
|
+
return readFileSync14(VERSION_FILE, "utf-8").trim() || "unknown";
|
|
11808
|
+
}
|
|
11809
|
+
async function probeConversationDb() {
|
|
11810
|
+
let session;
|
|
11811
|
+
try {
|
|
11812
|
+
session = getSession();
|
|
11813
|
+
} catch (err) {
|
|
11814
|
+
return { state: "error", reason: err instanceof Error ? err.message : String(err) };
|
|
11815
|
+
}
|
|
11816
|
+
let timer2;
|
|
11817
|
+
try {
|
|
11818
|
+
const probe = session.run("RETURN 1");
|
|
11819
|
+
const timeout = new Promise((_, reject) => {
|
|
11820
|
+
timer2 = setTimeout(() => reject(new Error("timeout")), PROBE_TIMEOUT_MS);
|
|
11821
|
+
});
|
|
11822
|
+
await Promise.race([probe, timeout]);
|
|
11823
|
+
return { state: "ok" };
|
|
11824
|
+
} catch (err) {
|
|
11825
|
+
return { state: "error", reason: err instanceof Error ? err.message : String(err) };
|
|
11826
|
+
} finally {
|
|
11827
|
+
if (timer2) clearTimeout(timer2);
|
|
11828
|
+
session.close().catch(() => {
|
|
11829
|
+
});
|
|
11830
|
+
}
|
|
11831
|
+
}
|
|
11746
11832
|
var app34 = new Hono();
|
|
11747
|
-
app34.
|
|
11748
|
-
|
|
11749
|
-
|
|
11750
|
-
|
|
11751
|
-
|
|
11752
|
-
|
|
11753
|
-
|
|
11754
|
-
|
|
11755
|
-
|
|
11756
|
-
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
|
|
11761
|
-
|
|
11762
|
-
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
11766
|
-
|
|
11767
|
-
|
|
11768
|
-
|
|
11769
|
-
app34
|
|
11770
|
-
|
|
11771
|
-
|
|
11833
|
+
app34.get("/", async (c) => {
|
|
11834
|
+
const version = readVersion();
|
|
11835
|
+
const probe = await probeConversationDb();
|
|
11836
|
+
const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
|
|
11837
|
+
if (probe.state === "error") {
|
|
11838
|
+
const reason = (probe.reason ?? "").replace(/\s+/g, " ").trim() || "unknown";
|
|
11839
|
+
console.log(
|
|
11840
|
+
`[admin/health-brand] processStartedAt=${PROCESS_STARTED_AT} uptimeMs=${uptimeMs} version=${version} conversationDb=error errorReason=${reason}`
|
|
11841
|
+
);
|
|
11842
|
+
} else {
|
|
11843
|
+
console.log(
|
|
11844
|
+
`[admin/health-brand] processStartedAt=${PROCESS_STARTED_AT} uptimeMs=${uptimeMs} version=${version} conversationDb=ok`
|
|
11845
|
+
);
|
|
11846
|
+
}
|
|
11847
|
+
return c.json({
|
|
11848
|
+
ok: true,
|
|
11849
|
+
processStartedAt: PROCESS_STARTED_AT,
|
|
11850
|
+
version,
|
|
11851
|
+
conversationDb: probe.state,
|
|
11852
|
+
uptimeMs
|
|
11853
|
+
});
|
|
11854
|
+
});
|
|
11855
|
+
var health_default2 = app34;
|
|
11856
|
+
|
|
11857
|
+
// server/routes/admin/index.ts
|
|
11858
|
+
var app35 = new Hono();
|
|
11859
|
+
app35.route("/session", session_default2);
|
|
11860
|
+
app35.route("/chat", chat_default2);
|
|
11861
|
+
app35.route("/compact", compact_default);
|
|
11862
|
+
app35.route("/logs", logs_default);
|
|
11863
|
+
app35.route("/claude-info", claude_info_default);
|
|
11864
|
+
app35.route("/attachment", attachment_default);
|
|
11865
|
+
app35.route("/agents", agents_default);
|
|
11866
|
+
app35.route("/sessions", sessions_default);
|
|
11867
|
+
app35.route("/browser", browser_default);
|
|
11868
|
+
app35.route("/device-browser", device_browser_default);
|
|
11869
|
+
app35.route("/events", events_default);
|
|
11870
|
+
app35.route("/cloudflare", cloudflare_default);
|
|
11871
|
+
app35.route("/files", files_default);
|
|
11872
|
+
app35.route("/graph-search", graph_search_default);
|
|
11873
|
+
app35.route("/graph-subgraph", graph_subgraph_default);
|
|
11874
|
+
app35.route("/graph-delete", graph_delete_default);
|
|
11875
|
+
app35.route("/graph-restore", graph_restore_default);
|
|
11876
|
+
app35.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
11877
|
+
app35.route("/graph-default-view", graph_default_view_default);
|
|
11878
|
+
app35.route("/file-attach", file_attach_default);
|
|
11879
|
+
app35.route("/adherence", adherence_default);
|
|
11880
|
+
app35.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
11881
|
+
app35.route("/sidebar-artefact-save", sidebar_artefact_save_default);
|
|
11882
|
+
app35.route("/sidebar-artefact-content", sidebar_artefact_content_default);
|
|
11883
|
+
app35.route("/health-brand", health_default2);
|
|
11884
|
+
var admin_default = app35;
|
|
11772
11885
|
|
|
11773
11886
|
// server/routes/sites.ts
|
|
11774
|
-
import { existsSync as
|
|
11775
|
-
import { resolve as
|
|
11887
|
+
import { existsSync as existsSync21, readFileSync as readFileSync15, realpathSync as realpathSync5, statSync as statSync5 } from "fs";
|
|
11888
|
+
import { resolve as resolve21 } from "path";
|
|
11776
11889
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
11777
11890
|
var MIME = {
|
|
11778
11891
|
".html": "text/html; charset=utf-8",
|
|
@@ -11803,8 +11916,8 @@ function getExt(p) {
|
|
|
11803
11916
|
if (idx < p.lastIndexOf("/")) return "";
|
|
11804
11917
|
return p.slice(idx).toLowerCase();
|
|
11805
11918
|
}
|
|
11806
|
-
var
|
|
11807
|
-
|
|
11919
|
+
var app36 = new Hono();
|
|
11920
|
+
app36.get("/:rel{.*}", (c) => {
|
|
11808
11921
|
const reqPath = c.req.path;
|
|
11809
11922
|
const rawRel = c.req.param("rel") ?? "";
|
|
11810
11923
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -11830,28 +11943,28 @@ app35.get("/:rel{.*}", (c) => {
|
|
|
11830
11943
|
}
|
|
11831
11944
|
segments.push(seg);
|
|
11832
11945
|
}
|
|
11833
|
-
const rootDir =
|
|
11834
|
-
let filePath = segments.length === 0 ? rootDir :
|
|
11946
|
+
const rootDir = resolve21(account.accountDir, "sites");
|
|
11947
|
+
let filePath = segments.length === 0 ? rootDir : resolve21(rootDir, ...segments);
|
|
11835
11948
|
if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
|
|
11836
11949
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
11837
11950
|
return c.text("Forbidden", 403);
|
|
11838
11951
|
}
|
|
11839
11952
|
let stat7;
|
|
11840
11953
|
try {
|
|
11841
|
-
stat7 =
|
|
11954
|
+
stat7 = existsSync21(filePath) ? statSync5(filePath) : null;
|
|
11842
11955
|
} catch {
|
|
11843
11956
|
stat7 = null;
|
|
11844
11957
|
}
|
|
11845
11958
|
if (stat7?.isDirectory()) {
|
|
11846
|
-
filePath =
|
|
11959
|
+
filePath = resolve21(filePath, "index.html");
|
|
11847
11960
|
} else if (stat7 === null && isDirRequest) {
|
|
11848
|
-
filePath =
|
|
11961
|
+
filePath = resolve21(filePath, "index.html");
|
|
11849
11962
|
}
|
|
11850
11963
|
if (!filePath.startsWith(rootDir + "/")) {
|
|
11851
11964
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
11852
11965
|
return c.text("Forbidden", 403);
|
|
11853
11966
|
}
|
|
11854
|
-
if (!
|
|
11967
|
+
if (!existsSync21(filePath)) {
|
|
11855
11968
|
console.error(`[sites] not-found path=${reqPath} status=404`);
|
|
11856
11969
|
return c.text("Not found", 404);
|
|
11857
11970
|
}
|
|
@@ -11870,7 +11983,7 @@ app35.get("/:rel{.*}", (c) => {
|
|
|
11870
11983
|
}
|
|
11871
11984
|
let body;
|
|
11872
11985
|
try {
|
|
11873
|
-
body =
|
|
11986
|
+
body = readFileSync15(realPath);
|
|
11874
11987
|
} catch (err) {
|
|
11875
11988
|
const code = err?.code;
|
|
11876
11989
|
if (code === "EISDIR") {
|
|
@@ -11902,7 +12015,7 @@ app35.get("/:rel{.*}", (c) => {
|
|
|
11902
12015
|
"X-Content-Type-Options": "nosniff"
|
|
11903
12016
|
});
|
|
11904
12017
|
});
|
|
11905
|
-
var sites_default =
|
|
12018
|
+
var sites_default = app36;
|
|
11906
12019
|
|
|
11907
12020
|
// app/lib/graph-health.ts
|
|
11908
12021
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -12001,15 +12114,15 @@ function clientFrom(c) {
|
|
|
12001
12114
|
c.req.header("x-forwarded-for")
|
|
12002
12115
|
);
|
|
12003
12116
|
}
|
|
12004
|
-
var
|
|
12005
|
-
var BRAND_JSON_PATH =
|
|
12117
|
+
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
12118
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join10(PLATFORM_ROOT8, "config", "brand.json") : "";
|
|
12006
12119
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
12007
|
-
if (BRAND_JSON_PATH && !
|
|
12120
|
+
if (BRAND_JSON_PATH && !existsSync22(BRAND_JSON_PATH)) {
|
|
12008
12121
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
12009
12122
|
}
|
|
12010
|
-
if (BRAND_JSON_PATH &&
|
|
12123
|
+
if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
|
|
12011
12124
|
try {
|
|
12012
|
-
const parsed = JSON.parse(
|
|
12125
|
+
const parsed = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
|
|
12013
12126
|
BRAND = { ...BRAND, ...parsed };
|
|
12014
12127
|
} catch (err) {
|
|
12015
12128
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -12028,11 +12141,11 @@ var brandLoginOpts = {
|
|
|
12028
12141
|
bodyFont: BRAND.defaultFonts?.body,
|
|
12029
12142
|
logoContainsName: !!BRAND.logoContainsName
|
|
12030
12143
|
};
|
|
12031
|
-
var ALIAS_DOMAINS_PATH2 =
|
|
12144
|
+
var ALIAS_DOMAINS_PATH2 = join10(homedir2(), BRAND.configDir, "alias-domains.json");
|
|
12032
12145
|
function loadAliasDomains() {
|
|
12033
12146
|
try {
|
|
12034
|
-
if (!
|
|
12035
|
-
const parsed = JSON.parse(
|
|
12147
|
+
if (!existsSync22(ALIAS_DOMAINS_PATH2)) return null;
|
|
12148
|
+
const parsed = JSON.parse(readFileSync16(ALIAS_DOMAINS_PATH2, "utf-8"));
|
|
12036
12149
|
if (!Array.isArray(parsed)) {
|
|
12037
12150
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
12038
12151
|
return null;
|
|
@@ -12056,9 +12169,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
12056
12169
|
function isPublicHost(host) {
|
|
12057
12170
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
12058
12171
|
}
|
|
12059
|
-
var
|
|
12060
|
-
|
|
12061
|
-
|
|
12172
|
+
var app37 = new Hono();
|
|
12173
|
+
app37.use("*", clientIpMiddleware);
|
|
12174
|
+
app37.use("*", async (c, next) => {
|
|
12062
12175
|
await next();
|
|
12063
12176
|
c.header("X-Content-Type-Options", "nosniff");
|
|
12064
12177
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -12082,7 +12195,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
12082
12195
|
"/sites/"
|
|
12083
12196
|
];
|
|
12084
12197
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
12085
|
-
|
|
12198
|
+
app37.use("*", async (c, next) => {
|
|
12086
12199
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12087
12200
|
if (!isPublicHost(host)) {
|
|
12088
12201
|
await next();
|
|
@@ -12122,7 +12235,7 @@ function resolveRemoteAuthOpts() {
|
|
|
12122
12235
|
return brandLoginOpts;
|
|
12123
12236
|
}
|
|
12124
12237
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
12125
|
-
|
|
12238
|
+
app37.post("/__remote-auth/login", async (c) => {
|
|
12126
12239
|
const client = clientFrom(c);
|
|
12127
12240
|
const clientIp = client.ip || "unknown";
|
|
12128
12241
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -12166,7 +12279,7 @@ app36.post("/__remote-auth/login", async (c) => {
|
|
|
12166
12279
|
}
|
|
12167
12280
|
});
|
|
12168
12281
|
});
|
|
12169
|
-
|
|
12282
|
+
app37.get("/__remote-auth/logout", (c) => {
|
|
12170
12283
|
return new Response(null, {
|
|
12171
12284
|
status: 302,
|
|
12172
12285
|
headers: {
|
|
@@ -12176,7 +12289,7 @@ app36.get("/__remote-auth/logout", (c) => {
|
|
|
12176
12289
|
}
|
|
12177
12290
|
});
|
|
12178
12291
|
});
|
|
12179
|
-
|
|
12292
|
+
app37.post("/__remote-auth/change-password", async (c) => {
|
|
12180
12293
|
const client = clientFrom(c);
|
|
12181
12294
|
const clientIp = client.ip || "unknown";
|
|
12182
12295
|
const rateLimited = checkRateLimit(client);
|
|
@@ -12226,13 +12339,13 @@ app36.post("/__remote-auth/change-password", async (c) => {
|
|
|
12226
12339
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
12227
12340
|
}
|
|
12228
12341
|
});
|
|
12229
|
-
|
|
12342
|
+
app37.get("/__remote-auth/setup", (c) => {
|
|
12230
12343
|
if (isRemoteAuthConfigured()) {
|
|
12231
12344
|
return c.redirect("/");
|
|
12232
12345
|
}
|
|
12233
12346
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
12234
12347
|
});
|
|
12235
|
-
|
|
12348
|
+
app37.post("/__remote-auth/set-initial-password", async (c) => {
|
|
12236
12349
|
if (isRemoteAuthConfigured()) {
|
|
12237
12350
|
return c.redirect("/");
|
|
12238
12351
|
}
|
|
@@ -12268,10 +12381,10 @@ app36.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
12268
12381
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
12269
12382
|
}
|
|
12270
12383
|
});
|
|
12271
|
-
|
|
12384
|
+
app37.get("/api/remote-auth/status", (c) => {
|
|
12272
12385
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
12273
12386
|
});
|
|
12274
|
-
|
|
12387
|
+
app37.post("/api/remote-auth/set-password", async (c) => {
|
|
12275
12388
|
let body;
|
|
12276
12389
|
try {
|
|
12277
12390
|
body = await c.req.json();
|
|
@@ -12301,9 +12414,9 @@ app36.post("/api/remote-auth/set-password", async (c) => {
|
|
|
12301
12414
|
return c.json({ error: "Failed to save password" }, 500);
|
|
12302
12415
|
}
|
|
12303
12416
|
});
|
|
12304
|
-
|
|
12417
|
+
app37.route("/api/_client-error", client_error_default);
|
|
12305
12418
|
console.log("[client-error-route] mounted");
|
|
12306
|
-
|
|
12419
|
+
app37.use("*", async (c, next) => {
|
|
12307
12420
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12308
12421
|
const path2 = c.req.path;
|
|
12309
12422
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -12336,15 +12449,15 @@ app36.use("*", async (c, next) => {
|
|
|
12336
12449
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
12337
12450
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
12338
12451
|
});
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12452
|
+
app37.route("/api/health", health_default);
|
|
12453
|
+
app37.route("/api/session", session_default);
|
|
12454
|
+
app37.route("/api/chat", chat_default);
|
|
12455
|
+
app37.route("/api/group", group_default);
|
|
12456
|
+
app37.route("/api/access", access_default);
|
|
12457
|
+
app37.route("/api/telegram", telegram_default);
|
|
12458
|
+
app37.route("/api/whatsapp", whatsapp_default);
|
|
12459
|
+
app37.route("/api/onboarding", onboarding_default);
|
|
12460
|
+
app37.route("/api/admin", admin_default);
|
|
12348
12461
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
12349
12462
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
12350
12463
|
var IMAGE_MIME = {
|
|
@@ -12356,7 +12469,7 @@ var IMAGE_MIME = {
|
|
|
12356
12469
|
".svg": "image/svg+xml",
|
|
12357
12470
|
".ico": "image/x-icon"
|
|
12358
12471
|
};
|
|
12359
|
-
|
|
12472
|
+
app37.get("/agent-assets/:slug/:filename", (c) => {
|
|
12360
12473
|
const slug = c.req.param("slug");
|
|
12361
12474
|
const filename = c.req.param("filename");
|
|
12362
12475
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -12372,26 +12485,26 @@ app36.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
12372
12485
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
12373
12486
|
return c.text("Not found", 404);
|
|
12374
12487
|
}
|
|
12375
|
-
const filePath =
|
|
12376
|
-
const expectedDir =
|
|
12488
|
+
const filePath = resolve22(account.accountDir, "agents", slug, "assets", filename);
|
|
12489
|
+
const expectedDir = resolve22(account.accountDir, "agents", slug, "assets");
|
|
12377
12490
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
12378
12491
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
12379
12492
|
return c.text("Forbidden", 403);
|
|
12380
12493
|
}
|
|
12381
|
-
if (!
|
|
12494
|
+
if (!existsSync22(filePath)) {
|
|
12382
12495
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
12383
12496
|
return c.text("Not found", 404);
|
|
12384
12497
|
}
|
|
12385
12498
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
12386
12499
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
12387
12500
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
12388
|
-
const body =
|
|
12501
|
+
const body = readFileSync16(filePath);
|
|
12389
12502
|
return c.body(body, 200, {
|
|
12390
12503
|
"Content-Type": contentType,
|
|
12391
12504
|
"Cache-Control": "public, max-age=3600"
|
|
12392
12505
|
});
|
|
12393
12506
|
});
|
|
12394
|
-
|
|
12507
|
+
app37.get("/generated/:filename", (c) => {
|
|
12395
12508
|
const filename = c.req.param("filename");
|
|
12396
12509
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
12397
12510
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -12402,32 +12515,32 @@ app36.get("/generated/:filename", (c) => {
|
|
|
12402
12515
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
12403
12516
|
return c.text("Not found", 404);
|
|
12404
12517
|
}
|
|
12405
|
-
const filePath =
|
|
12406
|
-
const expectedDir =
|
|
12518
|
+
const filePath = resolve22(account.accountDir, "generated", filename);
|
|
12519
|
+
const expectedDir = resolve22(account.accountDir, "generated");
|
|
12407
12520
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
12408
12521
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
12409
12522
|
return c.text("Forbidden", 403);
|
|
12410
12523
|
}
|
|
12411
|
-
if (!
|
|
12524
|
+
if (!existsSync22(filePath)) {
|
|
12412
12525
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
12413
12526
|
return c.text("Not found", 404);
|
|
12414
12527
|
}
|
|
12415
12528
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
12416
12529
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
12417
12530
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
12418
|
-
const body =
|
|
12531
|
+
const body = readFileSync16(filePath);
|
|
12419
12532
|
return c.body(body, 200, {
|
|
12420
12533
|
"Content-Type": contentType,
|
|
12421
12534
|
"Cache-Control": "public, max-age=86400"
|
|
12422
12535
|
});
|
|
12423
12536
|
});
|
|
12424
|
-
|
|
12537
|
+
app37.route("/sites", sites_default);
|
|
12425
12538
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
12426
12539
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
12427
12540
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
12428
|
-
if (BRAND_JSON_PATH &&
|
|
12541
|
+
if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
|
|
12429
12542
|
try {
|
|
12430
|
-
const fullBrand = JSON.parse(
|
|
12543
|
+
const fullBrand = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
|
|
12431
12544
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
12432
12545
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
12433
12546
|
} catch {
|
|
@@ -12443,10 +12556,10 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
12443
12556
|
})}</script>`;
|
|
12444
12557
|
function readInstalledVersion() {
|
|
12445
12558
|
try {
|
|
12446
|
-
if (!
|
|
12447
|
-
const versionFile =
|
|
12448
|
-
if (!
|
|
12449
|
-
const content =
|
|
12559
|
+
if (!PLATFORM_ROOT8) return "unknown";
|
|
12560
|
+
const versionFile = join10(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
|
|
12561
|
+
if (!existsSync22(versionFile)) return "unknown";
|
|
12562
|
+
const content = readFileSync16(versionFile, "utf-8").trim();
|
|
12450
12563
|
return content || "unknown";
|
|
12451
12564
|
} catch {
|
|
12452
12565
|
return "unknown";
|
|
@@ -12487,7 +12600,7 @@ var clientErrorReporterScript = `<script>
|
|
|
12487
12600
|
function cachedHtml(file) {
|
|
12488
12601
|
let html = htmlCache.get(file);
|
|
12489
12602
|
if (!html) {
|
|
12490
|
-
html =
|
|
12603
|
+
html = readFileSync16(resolve22(process.cwd(), "public", file), "utf-8");
|
|
12491
12604
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
12492
12605
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
12493
12606
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -12503,26 +12616,26 @@ ${clientErrorReporterScript}
|
|
|
12503
12616
|
}
|
|
12504
12617
|
var brandedHtmlCache = /* @__PURE__ */ new Map();
|
|
12505
12618
|
function loadBrandingCache(agentSlug) {
|
|
12506
|
-
const configDir2 =
|
|
12619
|
+
const configDir2 = join10(homedir2(), BRAND.configDir);
|
|
12507
12620
|
try {
|
|
12508
|
-
const accountJsonPath =
|
|
12509
|
-
if (!
|
|
12510
|
-
const account = JSON.parse(
|
|
12621
|
+
const accountJsonPath = join10(configDir2, "account.json");
|
|
12622
|
+
if (!existsSync22(accountJsonPath)) return null;
|
|
12623
|
+
const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
|
|
12511
12624
|
const accountId = account.accountId;
|
|
12512
12625
|
if (!accountId) return null;
|
|
12513
|
-
const cachePath =
|
|
12514
|
-
if (!
|
|
12515
|
-
return JSON.parse(
|
|
12626
|
+
const cachePath = join10(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
12627
|
+
if (!existsSync22(cachePath)) return null;
|
|
12628
|
+
return JSON.parse(readFileSync16(cachePath, "utf-8"));
|
|
12516
12629
|
} catch {
|
|
12517
12630
|
return null;
|
|
12518
12631
|
}
|
|
12519
12632
|
}
|
|
12520
12633
|
function resolveDefaultSlug() {
|
|
12521
12634
|
try {
|
|
12522
|
-
const configDir2 =
|
|
12523
|
-
const accountJsonPath =
|
|
12524
|
-
if (!
|
|
12525
|
-
const account = JSON.parse(
|
|
12635
|
+
const configDir2 = join10(homedir2(), BRAND.configDir);
|
|
12636
|
+
const accountJsonPath = join10(configDir2, "account.json");
|
|
12637
|
+
if (!existsSync22(accountJsonPath)) return null;
|
|
12638
|
+
const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
|
|
12526
12639
|
return account.defaultAgent || null;
|
|
12527
12640
|
} catch {
|
|
12528
12641
|
return null;
|
|
@@ -12558,7 +12671,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
12558
12671
|
function escapeHtml(s) {
|
|
12559
12672
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
12560
12673
|
}
|
|
12561
|
-
|
|
12674
|
+
app37.get("/", (c) => {
|
|
12562
12675
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12563
12676
|
if (isPublicHost(host)) {
|
|
12564
12677
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -12566,12 +12679,12 @@ app36.get("/", (c) => {
|
|
|
12566
12679
|
}
|
|
12567
12680
|
return c.html(cachedHtml("index.html"));
|
|
12568
12681
|
});
|
|
12569
|
-
|
|
12682
|
+
app37.get("/public", (c) => {
|
|
12570
12683
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12571
12684
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
12572
12685
|
return c.html(cachedHtml("public.html"));
|
|
12573
12686
|
});
|
|
12574
|
-
|
|
12687
|
+
app37.get("/chat", (c) => {
|
|
12575
12688
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12576
12689
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
12577
12690
|
return c.html(cachedHtml("public.html"));
|
|
@@ -12590,12 +12703,12 @@ async function logViewerFetch(c, next) {
|
|
|
12590
12703
|
duration_ms: Date.now() - start
|
|
12591
12704
|
});
|
|
12592
12705
|
}
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12706
|
+
app37.use("/vnc-viewer.html", logViewerFetch);
|
|
12707
|
+
app37.use("/vnc-popout.html", logViewerFetch);
|
|
12708
|
+
app37.get("/vnc-popout.html", (c) => {
|
|
12596
12709
|
let html = htmlCache.get("vnc-popout.html");
|
|
12597
12710
|
if (!html) {
|
|
12598
|
-
html =
|
|
12711
|
+
html = readFileSync16(resolve22(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
12599
12712
|
const name = escapeHtml(BRAND.productName);
|
|
12600
12713
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
12601
12714
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -12605,7 +12718,7 @@ app36.get("/vnc-popout.html", (c) => {
|
|
|
12605
12718
|
}
|
|
12606
12719
|
return c.html(html);
|
|
12607
12720
|
});
|
|
12608
|
-
|
|
12721
|
+
app37.post("/api/vnc/client-event", async (c) => {
|
|
12609
12722
|
let body;
|
|
12610
12723
|
try {
|
|
12611
12724
|
body = await c.req.json();
|
|
@@ -12626,20 +12739,20 @@ app36.post("/api/vnc/client-event", async (c) => {
|
|
|
12626
12739
|
});
|
|
12627
12740
|
return c.json({ ok: true });
|
|
12628
12741
|
});
|
|
12629
|
-
|
|
12742
|
+
app37.get("/g/:slug", (c) => {
|
|
12630
12743
|
return c.html(brandedPublicHtml());
|
|
12631
12744
|
});
|
|
12632
|
-
|
|
12745
|
+
app37.get("/graph", (c) => {
|
|
12633
12746
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12634
12747
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
12635
12748
|
return c.html(cachedHtml("graph.html"));
|
|
12636
12749
|
});
|
|
12637
|
-
|
|
12750
|
+
app37.get("/data", (c) => {
|
|
12638
12751
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12639
12752
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
12640
12753
|
return c.html(cachedHtml("data.html"));
|
|
12641
12754
|
});
|
|
12642
|
-
|
|
12755
|
+
app37.get("/:slug", async (c, next) => {
|
|
12643
12756
|
const slug = c.req.param("slug");
|
|
12644
12757
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
12645
12758
|
const branding = loadBrandingCache(slug);
|
|
@@ -12648,10 +12761,10 @@ app36.get("/:slug", async (c, next) => {
|
|
|
12648
12761
|
}
|
|
12649
12762
|
await next();
|
|
12650
12763
|
});
|
|
12651
|
-
|
|
12764
|
+
app37.use("/*", serveStatic({ root: "./public" }));
|
|
12652
12765
|
var port = parseInt(process.env.MAXY_UI_INTERNAL_PORT ?? process.env.PORT ?? "19199", 10);
|
|
12653
12766
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
12654
|
-
var httpServer = serve({ fetch:
|
|
12767
|
+
var httpServer = serve({ fetch: app37.fetch, port, hostname });
|
|
12655
12768
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
12656
12769
|
var SUBAPP_MANIFEST = [
|
|
12657
12770
|
{ prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
|
|
@@ -12671,7 +12784,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
12671
12784
|
}
|
|
12672
12785
|
try {
|
|
12673
12786
|
const registered = [];
|
|
12674
|
-
for (const r of
|
|
12787
|
+
for (const r of app37.routes ?? []) {
|
|
12675
12788
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
12676
12789
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
12677
12790
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -12685,8 +12798,8 @@ try {
|
|
|
12685
12798
|
(async () => {
|
|
12686
12799
|
try {
|
|
12687
12800
|
let userId = "";
|
|
12688
|
-
if (
|
|
12689
|
-
const users = JSON.parse(
|
|
12801
|
+
if (existsSync22(USERS_FILE)) {
|
|
12802
|
+
const users = JSON.parse(readFileSync16(USERS_FILE, "utf-8").trim() || "[]");
|
|
12690
12803
|
userId = users[0]?.userId ?? "";
|
|
12691
12804
|
}
|
|
12692
12805
|
await backfillNullUserIdConversations(userId);
|
|
@@ -12719,7 +12832,7 @@ autoDeliverPremiumPlugins(bootEntitlement?.purchasedPlugins ?? void 0);
|
|
|
12719
12832
|
(async () => {
|
|
12720
12833
|
if (!bootAccount) return;
|
|
12721
12834
|
try {
|
|
12722
|
-
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-
|
|
12835
|
+
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-4NIODMGL.js");
|
|
12723
12836
|
const result = await recoverRunningCloudflareTasks(
|
|
12724
12837
|
bootAccount.accountId,
|
|
12725
12838
|
configDirForWhatsApp,
|
|
@@ -12769,7 +12882,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
12769
12882
|
}
|
|
12770
12883
|
init({
|
|
12771
12884
|
configDir: configDirForWhatsApp,
|
|
12772
|
-
platformRoot:
|
|
12885
|
+
platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ?? join10(__dirname, "..")),
|
|
12773
12886
|
accountConfig: bootAccountConfig,
|
|
12774
12887
|
onMessage: async (msg) => {
|
|
12775
12888
|
try {
|