@rubytech/create-maxy 1.0.888 → 1.0.890
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +5 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +4 -2
- package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/time-resolve-description.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/time-resolve-description.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/time-resolve-description.test.js +16 -0
- package/payload/platform/plugins/scheduling/mcp/dist/__tests__/time-resolve-description.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/scripts/log-adherence-check.sh +28 -3
- package/payload/server/chunk-FBTNBSB4.js +2282 -0
- package/payload/server/chunk-O7DTMDJM.js +759 -0
- package/payload/server/chunk-OD4LSAB2.js +9770 -0
- package/payload/server/chunk-S65GGO53.js +11629 -0
- package/payload/server/chunk-TUCK5CI2.js +3566 -0
- package/payload/server/client-pool-E3OU5NYU.js +34 -0
- package/payload/server/cloudflare-task-tracker-KCIUQYB5.js +22 -0
- package/payload/server/maxy-edge.js +4 -4
- package/payload/server/public/assets/{Checkbox-CeujDRv0.js → Checkbox-ebZSKvw2.js} +1 -1
- package/payload/server/public/assets/{admin-BN_z-2Bm.js → admin-Ewxzru2U.js} +31 -31
- package/payload/server/public/assets/data-pOc8b2rA.js +1 -0
- package/payload/server/public/assets/graph-DeG4HsDI.js +1 -0
- package/payload/server/public/assets/{graph-labels-Co03qEv5.js → graph-labels-DHQuVOgO.js} +1 -1
- package/payload/server/public/assets/jsx-runtime-CqFGUuze.css +1 -0
- package/payload/server/public/assets/{page-DGLz4ozf.js → page-DJiTa_Y_.js} +1 -1
- package/payload/server/public/assets/{page-C4E0CWHe.js → page-DL8yJkUn.js} +1 -1
- package/payload/server/public/assets/{public-rILg7e8-.js → public-BS-tmbAu.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-D3Upd7Q3.js → useVoiceRecorder-COlUADaA.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +450 -314
- package/payload/server/public/assets/data-LYciLZK9.js +0 -1
- package/payload/server/public/assets/graph-C-SKAbGX.js +0 -1
- package/payload/server/public/assets/jsx-runtime-BcZkJOEw.css +0 -1
- /package/payload/server/public/assets/{jsx-runtime-BWYXu1CT.js → jsx-runtime-BCHoQyWP.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ACCOUNTS_DIR,
|
|
3
2
|
ATTACHMENTS_ROOT,
|
|
4
3
|
Hono,
|
|
5
4
|
MAX_FILES_PER_MESSAGE,
|
|
6
5
|
MAX_FILE_SIZE_BYTES,
|
|
7
|
-
PLATFORM_ROOT,
|
|
8
6
|
SUPPORTED_MIME_TYPES,
|
|
9
7
|
assertSupportedMime,
|
|
10
|
-
autoDeliverPremiumPlugins,
|
|
11
8
|
browserViewerLog,
|
|
12
9
|
buildX11Env,
|
|
13
10
|
callOauthLlm,
|
|
@@ -26,10 +23,6 @@ import {
|
|
|
26
23
|
ensureCdp,
|
|
27
24
|
ensureLogDir,
|
|
28
25
|
ensureVnc,
|
|
29
|
-
findMissingPlugins,
|
|
30
|
-
getBundleMtimeIso,
|
|
31
|
-
getDefaultAccountId,
|
|
32
|
-
hasStubAccountDir,
|
|
33
26
|
hashPassword,
|
|
34
27
|
httpLog,
|
|
35
28
|
invokeAgent,
|
|
@@ -42,17 +35,12 @@ import {
|
|
|
42
35
|
load,
|
|
43
36
|
logPath,
|
|
44
37
|
pickComponentBytes,
|
|
45
|
-
reconcileEnabledPlugins,
|
|
46
38
|
recordFailedAttempt,
|
|
47
39
|
render,
|
|
48
40
|
renderLoginPage,
|
|
49
41
|
requireAdminSession,
|
|
50
|
-
resolveAccount,
|
|
51
|
-
resolveAgentConfig,
|
|
52
42
|
resolveBrowserTransport,
|
|
53
43
|
resolveClientIp,
|
|
54
|
-
resolveDefaultAgentSlug,
|
|
55
|
-
resolveUserAccounts,
|
|
56
44
|
safeJson,
|
|
57
45
|
sanitizeClientCorrId,
|
|
58
46
|
serve,
|
|
@@ -62,10 +50,8 @@ import {
|
|
|
62
50
|
storeComponentArtefact,
|
|
63
51
|
storeGeneratedFile,
|
|
64
52
|
storePublicAttachment,
|
|
65
|
-
streamLogPathFor,
|
|
66
53
|
stripAttachmentMetaSuffix,
|
|
67
54
|
tryCookieBridgeForConversation,
|
|
68
|
-
validateAgentSlug,
|
|
69
55
|
validateFilePathInAccount,
|
|
70
56
|
validateKey,
|
|
71
57
|
validatePasswordStrength,
|
|
@@ -73,50 +59,66 @@ import {
|
|
|
73
59
|
verifyRemotePassword,
|
|
74
60
|
vncLog,
|
|
75
61
|
waitForExit,
|
|
76
|
-
walkPremiumBundles,
|
|
77
62
|
writeChromiumWrapper
|
|
78
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-OD4LSAB2.js";
|
|
79
64
|
import {
|
|
65
|
+
ACCOUNTS_DIR,
|
|
80
66
|
CDP_PORT,
|
|
81
67
|
COMMERCIAL_MODE,
|
|
82
68
|
LOG_DIR,
|
|
83
69
|
MAXY_DIR,
|
|
70
|
+
PLATFORM_ROOT,
|
|
84
71
|
TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
|
|
85
72
|
TELEGRAM_WEBHOOK_SECRET_FILE,
|
|
86
73
|
USERS_FILE,
|
|
87
74
|
WEBSOCKIFY_PORT,
|
|
88
75
|
agentLogStream,
|
|
76
|
+
appendStreamLogLine,
|
|
77
|
+
autoDeliverPremiumPlugins,
|
|
89
78
|
clearSessionHistory,
|
|
90
79
|
completeGrantSetup,
|
|
91
80
|
consumeWantsPriorConversation,
|
|
92
81
|
emitMissingOnResolve,
|
|
82
|
+
findMissingPlugins,
|
|
93
83
|
fingerprintSessionKey,
|
|
94
84
|
getAccountIdForSession,
|
|
95
85
|
getActiveClient,
|
|
96
86
|
getAgentNameForSession,
|
|
87
|
+
getBundleMtimeIso,
|
|
97
88
|
getConversationIdForSession,
|
|
89
|
+
getDefaultAccountId,
|
|
98
90
|
getGrantForSession,
|
|
99
91
|
getGroupSlugForSession,
|
|
100
92
|
getRoleForSession,
|
|
101
93
|
getSessionKeyByConversationId,
|
|
102
94
|
getSessionMessages,
|
|
95
|
+
getStreamLogHandle,
|
|
103
96
|
getUserIdForSession,
|
|
104
97
|
getUserNameForSession,
|
|
105
98
|
getVisitorIdForSession,
|
|
99
|
+
hasStubAccountDir,
|
|
106
100
|
interruptClient,
|
|
107
101
|
listAdminSessionsInProgress,
|
|
108
102
|
mintAdminSessionToken,
|
|
103
|
+
reconcileEnabledPlugins,
|
|
109
104
|
registerGrantSession,
|
|
110
105
|
registerResumedSession,
|
|
111
106
|
registerSession,
|
|
107
|
+
resolveAccount,
|
|
108
|
+
resolveAgentConfig,
|
|
109
|
+
resolveDefaultAgentSlug,
|
|
110
|
+
resolveUserAccounts,
|
|
112
111
|
setAgentSessionId,
|
|
113
112
|
setConversationIdForSession,
|
|
114
113
|
setGroupContextForSession,
|
|
115
114
|
setWantsPriorConversation,
|
|
116
115
|
sigtermFlushStreamLogs,
|
|
116
|
+
streamLogPathFor,
|
|
117
117
|
unregisterSession,
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
validateAgentSlug,
|
|
119
|
+
validateSession,
|
|
120
|
+
walkPremiumBundles
|
|
121
|
+
} from "./chunk-TUCK5CI2.js";
|
|
120
122
|
import {
|
|
121
123
|
CLOUDFLARE_TASK_DIAGNOSTICS,
|
|
122
124
|
appendCloudflareSteps,
|
|
@@ -125,7 +127,7 @@ import {
|
|
|
125
127
|
openCloudflareTask,
|
|
126
128
|
readTunnelState,
|
|
127
129
|
resolveUnitGoneVerdict
|
|
128
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-O7DTMDJM.js";
|
|
129
131
|
import {
|
|
130
132
|
GREETING_DIRECTIVE,
|
|
131
133
|
HAIKU_MODEL,
|
|
@@ -160,7 +162,7 @@ import {
|
|
|
160
162
|
verifyConversationOwnership,
|
|
161
163
|
writeAdminUserAndPerson,
|
|
162
164
|
writeTurnFailure
|
|
163
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-FBTNBSB4.js";
|
|
164
166
|
import {
|
|
165
167
|
__commonJS,
|
|
166
168
|
__toESM
|
|
@@ -664,7 +666,7 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
664
666
|
|
|
665
667
|
// server/index.ts
|
|
666
668
|
import { readFileSync as readFileSync19, existsSync as existsSync25, watchFile } from "fs";
|
|
667
|
-
import { resolve as
|
|
669
|
+
import { resolve as resolve21, join as join12, basename as basename4 } from "path";
|
|
668
670
|
import { homedir as homedir3 } from "os";
|
|
669
671
|
|
|
670
672
|
// app/lib/agent-slug-pattern.ts
|
|
@@ -1308,7 +1310,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
1308
1310
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
1309
1311
|
console.error(`${TAG3} draining credential save queue\u2026`);
|
|
1310
1312
|
const timer2 = new Promise(
|
|
1311
|
-
(
|
|
1313
|
+
(resolve22) => setTimeout(() => resolve22("timeout"), timeoutMs)
|
|
1312
1314
|
);
|
|
1313
1315
|
const result = await Promise.race([
|
|
1314
1316
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -1436,11 +1438,11 @@ async function createWaSocket(opts) {
|
|
|
1436
1438
|
return sock;
|
|
1437
1439
|
}
|
|
1438
1440
|
async function waitForConnection(sock) {
|
|
1439
|
-
return new Promise((
|
|
1441
|
+
return new Promise((resolve22, reject) => {
|
|
1440
1442
|
const handler = (update) => {
|
|
1441
1443
|
if (update.connection === "open") {
|
|
1442
1444
|
sock.ev.off("connection.update", handler);
|
|
1443
|
-
|
|
1445
|
+
resolve22();
|
|
1444
1446
|
}
|
|
1445
1447
|
if (update.connection === "close") {
|
|
1446
1448
|
sock.ev.off("connection.update", handler);
|
|
@@ -1554,14 +1556,14 @@ ${inspected}`;
|
|
|
1554
1556
|
return inspect2(err, INSPECT_OPTS2);
|
|
1555
1557
|
}
|
|
1556
1558
|
function withTimeout(label, promise, timeoutMs) {
|
|
1557
|
-
return new Promise((
|
|
1559
|
+
return new Promise((resolve22, reject) => {
|
|
1558
1560
|
const timer2 = setTimeout(() => {
|
|
1559
1561
|
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
1560
1562
|
}, timeoutMs);
|
|
1561
1563
|
promise.then(
|
|
1562
1564
|
(value) => {
|
|
1563
1565
|
clearTimeout(timer2);
|
|
1564
|
-
|
|
1566
|
+
resolve22(value);
|
|
1565
1567
|
},
|
|
1566
1568
|
(err) => {
|
|
1567
1569
|
clearTimeout(timer2);
|
|
@@ -2096,8 +2098,8 @@ async function persistWhatsAppMessage(input) {
|
|
|
2096
2098
|
const { givenName, familyName } = splitName(input.pushName);
|
|
2097
2099
|
const prev = sessionWriteLocks.get(input.cacheKey);
|
|
2098
2100
|
let release;
|
|
2099
|
-
const mine = new Promise((
|
|
2100
|
-
release =
|
|
2101
|
+
const mine = new Promise((resolve22) => {
|
|
2102
|
+
release = resolve22;
|
|
2101
2103
|
});
|
|
2102
2104
|
const chained = (prev ?? Promise.resolve()).then(() => mine);
|
|
2103
2105
|
sessionWriteLocks.set(input.cacheKey, chained);
|
|
@@ -3134,11 +3136,11 @@ async function connectWithReconnect(conn) {
|
|
|
3134
3136
|
console.error(
|
|
3135
3137
|
`${TAG13} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
3136
3138
|
);
|
|
3137
|
-
await new Promise((
|
|
3138
|
-
const timer2 = setTimeout(
|
|
3139
|
+
await new Promise((resolve22) => {
|
|
3140
|
+
const timer2 = setTimeout(resolve22, delay);
|
|
3139
3141
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
3140
3142
|
clearTimeout(timer2);
|
|
3141
|
-
|
|
3143
|
+
resolve22();
|
|
3142
3144
|
}, { once: true });
|
|
3143
3145
|
});
|
|
3144
3146
|
}
|
|
@@ -3146,16 +3148,16 @@ async function connectWithReconnect(conn) {
|
|
|
3146
3148
|
}
|
|
3147
3149
|
}
|
|
3148
3150
|
function waitForDisconnectEvent(conn) {
|
|
3149
|
-
return new Promise((
|
|
3151
|
+
return new Promise((resolve22) => {
|
|
3150
3152
|
if (!conn.sock) {
|
|
3151
|
-
|
|
3153
|
+
resolve22();
|
|
3152
3154
|
return;
|
|
3153
3155
|
}
|
|
3154
3156
|
const sock = conn.sock;
|
|
3155
3157
|
const handler = (update) => {
|
|
3156
3158
|
if (update.connection === "close") {
|
|
3157
3159
|
sock.ev.off("connection.update", handler);
|
|
3158
|
-
|
|
3160
|
+
resolve22();
|
|
3159
3161
|
}
|
|
3160
3162
|
};
|
|
3161
3163
|
sock.ev.on("connection.update", handler);
|
|
@@ -3417,8 +3419,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
3417
3419
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
3418
3420
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
3419
3421
|
let resolvePending;
|
|
3420
|
-
const sttPending = new Promise((
|
|
3421
|
-
resolvePending =
|
|
3422
|
+
const sttPending = new Promise((resolve22) => {
|
|
3423
|
+
resolvePending = resolve22;
|
|
3422
3424
|
});
|
|
3423
3425
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
3424
3426
|
try {
|
|
@@ -3539,20 +3541,20 @@ async function probeApiKey() {
|
|
|
3539
3541
|
return result.status;
|
|
3540
3542
|
}
|
|
3541
3543
|
function checkPort(port2, timeoutMs = 500) {
|
|
3542
|
-
return new Promise((
|
|
3544
|
+
return new Promise((resolve22) => {
|
|
3543
3545
|
const socket = createConnection(port2, "127.0.0.1");
|
|
3544
3546
|
socket.setTimeout(timeoutMs);
|
|
3545
3547
|
socket.once("connect", () => {
|
|
3546
3548
|
socket.destroy();
|
|
3547
|
-
|
|
3549
|
+
resolve22(true);
|
|
3548
3550
|
});
|
|
3549
3551
|
socket.once("error", () => {
|
|
3550
3552
|
socket.destroy();
|
|
3551
|
-
|
|
3553
|
+
resolve22(false);
|
|
3552
3554
|
});
|
|
3553
3555
|
socket.once("timeout", () => {
|
|
3554
3556
|
socket.destroy();
|
|
3555
|
-
|
|
3557
|
+
resolve22(false);
|
|
3556
3558
|
});
|
|
3557
3559
|
});
|
|
3558
3560
|
}
|
|
@@ -5643,8 +5645,8 @@ async function startLogin(opts) {
|
|
|
5643
5645
|
resetActiveLogin(accountId);
|
|
5644
5646
|
let resolveQr = null;
|
|
5645
5647
|
let rejectQr = null;
|
|
5646
|
-
const qrPromise = new Promise((
|
|
5647
|
-
resolveQr =
|
|
5648
|
+
const qrPromise = new Promise((resolve22, reject) => {
|
|
5649
|
+
resolveQr = resolve22;
|
|
5648
5650
|
rejectQr = reject;
|
|
5649
5651
|
});
|
|
5650
5652
|
const qrTimer = setTimeout(
|
|
@@ -6780,7 +6782,7 @@ app8.post("/skip", async (c) => {
|
|
|
6780
6782
|
var onboarding_default = app8;
|
|
6781
6783
|
|
|
6782
6784
|
// server/routes/client-error.ts
|
|
6783
|
-
import { appendFileSync, existsSync as existsSync10, renameSync as renameSync2, statSync as statSync3 } from "fs";
|
|
6785
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync10, renameSync as renameSync2, statSync as statSync3 } from "fs";
|
|
6784
6786
|
import { join as join7 } from "path";
|
|
6785
6787
|
var CLIENT_ERRORS_LOG = join7(LOG_DIR, "client-errors.log");
|
|
6786
6788
|
var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
@@ -6929,7 +6931,7 @@ app9.post("/", async (c) => {
|
|
|
6929
6931
|
tag: typeof body.tag === "string" ? truncate(body.tag, 32) : void 0,
|
|
6930
6932
|
status: typeof body.status === "number" ? body.status : void 0
|
|
6931
6933
|
};
|
|
6932
|
-
|
|
6934
|
+
appendFileSync2(CLIENT_ERRORS_LOG, JSON.stringify(payload) + "\n", "utf-8");
|
|
6933
6935
|
} catch (err) {
|
|
6934
6936
|
console.error(`[client-error] append failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6935
6937
|
}
|
|
@@ -7187,13 +7189,11 @@ app10.post("/", async (c) => {
|
|
|
7187
7189
|
var session_default2 = app10;
|
|
7188
7190
|
|
|
7189
7191
|
// server/routes/admin/chat.ts
|
|
7190
|
-
import { resolve as resolve8 } from "path";
|
|
7191
|
-
import { appendFileSync as appendFileSync3 } from "fs";
|
|
7192
7192
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
7193
7193
|
|
|
7194
7194
|
// app/lib/script-stream-tailer.ts
|
|
7195
7195
|
import * as childProcess from "child_process";
|
|
7196
|
-
import { appendFileSync as
|
|
7196
|
+
import { appendFileSync as appendFileSync3, createReadStream as createReadStream2, mkdirSync as mkdirSync5, statSync as statSync5 } from "fs";
|
|
7197
7197
|
import { dirname as dirname4 } from "path";
|
|
7198
7198
|
import { StringDecoder } from "string_decoder";
|
|
7199
7199
|
var SCRIPT_STREAM_RE = /^\[([^\]]+)\] \[script:([a-z][a-z0-9-]*)((?::[a-z0-9:_-]+)?)\] (.*)$/;
|
|
@@ -7304,7 +7304,7 @@ function writeRouteMilestone(streamLogPath, scope, line) {
|
|
|
7304
7304
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
7305
7305
|
try {
|
|
7306
7306
|
mkdirSync5(dirname4(streamLogPath), { recursive: true });
|
|
7307
|
-
|
|
7307
|
+
appendFileSync3(streamLogPath, `[${ts}] [script:${scope}] ${line}
|
|
7308
7308
|
`);
|
|
7309
7309
|
} catch (err) {
|
|
7310
7310
|
console.error(
|
|
@@ -7479,7 +7479,7 @@ var app11 = new Hono();
|
|
|
7479
7479
|
app11.post("/cancel", requireAdminSession, async (c) => {
|
|
7480
7480
|
const session_key = c.var.cacheKey;
|
|
7481
7481
|
try {
|
|
7482
|
-
const { interruptClient: interruptClient2 } = await import("./client-pool-
|
|
7482
|
+
const { interruptClient: interruptClient2 } = await import("./client-pool-E3OU5NYU.js");
|
|
7483
7483
|
await interruptClient2(session_key);
|
|
7484
7484
|
return c.json({ ok: true });
|
|
7485
7485
|
} catch (err) {
|
|
@@ -7673,14 +7673,14 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7673
7673
|
const encoder = new TextEncoder();
|
|
7674
7674
|
const sseLogStream = agentLogStream("sse-events", account.accountDir, session_key);
|
|
7675
7675
|
const sk = conversationId.slice(0, 8);
|
|
7676
|
-
const
|
|
7676
|
+
const streamLog = getStreamLogHandle(account.accountDir, session_key);
|
|
7677
7677
|
try {
|
|
7678
|
-
|
|
7678
|
+
streamLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [chat-route-version=task1013-one-writer-lazy-open] cacheKey=${session_key.slice(0, 12)}\u2026 conversationId=${conversationId}
|
|
7679
7679
|
`);
|
|
7680
7680
|
} catch {
|
|
7681
7681
|
}
|
|
7682
7682
|
try {
|
|
7683
|
-
|
|
7683
|
+
streamLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [client-acquire] cacheKey=${session_key.slice(0, 12)}\u2026 resume=${resumedAgentSessionId ? resumedAgentSessionId.slice(0, 8) + "\u2026" : "none"} reason=${acquireReason}
|
|
7684
7684
|
`);
|
|
7685
7685
|
} catch {
|
|
7686
7686
|
}
|
|
@@ -7689,7 +7689,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7689
7689
|
incoming.on("close", () => {
|
|
7690
7690
|
const tsClose = (/* @__PURE__ */ new Date()).toISOString();
|
|
7691
7691
|
try {
|
|
7692
|
-
|
|
7692
|
+
streamLog.write(`[${tsClose}] [incoming-close] cacheKey=${session_key.slice(0, 12)}\u2026 complete=${incoming.complete}
|
|
7693
7693
|
`);
|
|
7694
7694
|
} catch {
|
|
7695
7695
|
}
|
|
@@ -7697,7 +7697,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7697
7697
|
console.error(`[${tsClose}] [incoming-close] DISCONNECT cacheKey=${session_key.slice(0, 12)}\u2026`);
|
|
7698
7698
|
interruptClient(session_key).catch((err) => {
|
|
7699
7699
|
try {
|
|
7700
|
-
|
|
7700
|
+
streamLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [incoming-close] interrupt-failed: ${err instanceof Error ? err.message : String(err)}
|
|
7701
7701
|
`);
|
|
7702
7702
|
} catch {
|
|
7703
7703
|
}
|
|
@@ -7706,19 +7706,36 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7706
7706
|
});
|
|
7707
7707
|
} else {
|
|
7708
7708
|
try {
|
|
7709
|
-
|
|
7709
|
+
streamLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [incoming-close] UNAVAILABLE \u2014 c.env.incoming is not an EventEmitter
|
|
7710
7710
|
`);
|
|
7711
7711
|
} catch {
|
|
7712
7712
|
}
|
|
7713
7713
|
}
|
|
7714
7714
|
const sseLog = {
|
|
7715
|
+
// Pre-token marker write. Buffers via streamLog.write (handle buffer +
|
|
7716
|
+
// console.error backstop to server.log on zero-token sessions).
|
|
7715
7717
|
write(line) {
|
|
7716
7718
|
try {
|
|
7717
7719
|
sseLogStream.write(line);
|
|
7718
7720
|
} catch {
|
|
7719
7721
|
}
|
|
7720
7722
|
try {
|
|
7721
|
-
|
|
7723
|
+
streamLog.write(line);
|
|
7724
|
+
} catch {
|
|
7725
|
+
}
|
|
7726
|
+
return true;
|
|
7727
|
+
},
|
|
7728
|
+
// Task 1013 — SDK token-event write. Calls streamLog.writeToken which
|
|
7729
|
+
// opens the per-session file lazily on first call (flushing the
|
|
7730
|
+
// pre-token buffer alongside) and appends thereafter. Used by the
|
|
7731
|
+
// SDK event for-await loop so the file exists iff a token was emitted.
|
|
7732
|
+
writeToken(line) {
|
|
7733
|
+
try {
|
|
7734
|
+
sseLogStream.write(line);
|
|
7735
|
+
} catch {
|
|
7736
|
+
}
|
|
7737
|
+
try {
|
|
7738
|
+
streamLog.writeToken(line);
|
|
7722
7739
|
} catch {
|
|
7723
7740
|
}
|
|
7724
7741
|
return true;
|
|
@@ -7763,11 +7780,10 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7763
7780
|
const reqSignal = c.req.raw?.signal;
|
|
7764
7781
|
if (reqSignal) {
|
|
7765
7782
|
reqSignal.addEventListener("abort", () => {
|
|
7766
|
-
const abortStreamLog = agentLogStream("claude-agent-stream", account.accountDir, session_key);
|
|
7767
7783
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
7768
7784
|
sseLog.write(`[${ts}] [${sk}] admin: ABORT [operator-cancel] interrupting pool client
|
|
7769
7785
|
`);
|
|
7770
|
-
interruptClient(session_key
|
|
7786
|
+
interruptClient(session_key).catch((err) => {
|
|
7771
7787
|
sseLog.write(`[${ts}] [${sk}] admin: ABORT [interrupt-failed] ${err instanceof Error ? err.message : String(err)}
|
|
7772
7788
|
`);
|
|
7773
7789
|
});
|
|
@@ -7778,7 +7794,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7778
7794
|
try {
|
|
7779
7795
|
registerAdminSSE(sseEntry);
|
|
7780
7796
|
tailer = startScriptStreamTailer({
|
|
7781
|
-
path:
|
|
7797
|
+
path: streamLog.path,
|
|
7782
7798
|
onEvent: (event) => {
|
|
7783
7799
|
if (!controllerOpen) return;
|
|
7784
7800
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
@@ -7793,7 +7809,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7793
7809
|
}
|
|
7794
7810
|
},
|
|
7795
7811
|
onError: (err) => {
|
|
7796
|
-
console.error(`[script-stream-tailer] ${
|
|
7812
|
+
console.error(`[script-stream-tailer] ${streamLog.path}: ${err.message}`);
|
|
7797
7813
|
}
|
|
7798
7814
|
});
|
|
7799
7815
|
for await (const event of invokeAgent(
|
|
@@ -7806,7 +7822,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7806
7822
|
)) {
|
|
7807
7823
|
const data = JSON.stringify(event);
|
|
7808
7824
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
7809
|
-
sseLog.
|
|
7825
|
+
sseLog.writeToken(`[${ts}] [${sk}] admin: ${data}
|
|
7810
7826
|
`);
|
|
7811
7827
|
controller.enqueue(encoder.encode(`data: ${data}
|
|
7812
7828
|
|
|
@@ -7947,9 +7963,127 @@ app12.post("/", requireAdminSession, async (c) => {
|
|
|
7947
7963
|
});
|
|
7948
7964
|
var chat_failure_default = app12;
|
|
7949
7965
|
|
|
7950
|
-
// server/routes/admin/
|
|
7966
|
+
// server/routes/admin/failure-report.ts
|
|
7967
|
+
var SESSION_KEY_RE = /^sk_[0-9a-f]{16}$/i;
|
|
7968
|
+
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7969
|
+
var ISO_RE2 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
7970
|
+
var SAFE_TOKEN_RE = /^[\w.:-]{1,64}$/;
|
|
7971
|
+
function validate2(body) {
|
|
7972
|
+
const missing = [];
|
|
7973
|
+
if (typeof body.sessionKey !== "string" || !SESSION_KEY_RE.test(body.sessionKey)) missing.push("sessionKey");
|
|
7974
|
+
if (typeof body.conversationId !== "string" || !UUID_RE4.test(body.conversationId)) missing.push("conversationId");
|
|
7975
|
+
if (typeof body.lastUserMessageId !== "string" || !SAFE_TOKEN_RE.test(body.lastUserMessageId)) missing.push("lastUserMessageId");
|
|
7976
|
+
if (typeof body.clickTs !== "string" || !ISO_RE2.test(body.clickTs)) missing.push("clickTs");
|
|
7977
|
+
const snap = body.clientSnapshot;
|
|
7978
|
+
if (!snap || typeof snap !== "object") missing.push("clientSnapshot");
|
|
7979
|
+
if (missing.length > 0) return { ok: false, missing };
|
|
7980
|
+
const snapshot = snap;
|
|
7981
|
+
const lastAssistantMessageId = typeof body.lastAssistantMessageId === "string" && SAFE_TOKEN_RE.test(body.lastAssistantMessageId) ? body.lastAssistantMessageId : "-";
|
|
7982
|
+
const sseReadyState = typeof snapshot.sseReadyState === "string" && SAFE_TOKEN_RE.test(snapshot.sseReadyState) ? snapshot.sseReadyState : typeof snapshot.sseReadyState === "number" ? String(snapshot.sseReadyState) : "-";
|
|
7983
|
+
const lastEventType = typeof snapshot.lastEventType === "string" && SAFE_TOKEN_RE.test(snapshot.lastEventType) ? snapshot.lastEventType : "-";
|
|
7984
|
+
const lastAppliedMessageId = typeof snapshot.lastAppliedMessageId === "string" && SAFE_TOKEN_RE.test(snapshot.lastAppliedMessageId) ? snapshot.lastAppliedMessageId : "-";
|
|
7985
|
+
return {
|
|
7986
|
+
ok: true,
|
|
7987
|
+
value: {
|
|
7988
|
+
sessionKey: body.sessionKey,
|
|
7989
|
+
conversationId: body.conversationId,
|
|
7990
|
+
lastUserMessageId: body.lastUserMessageId,
|
|
7991
|
+
lastAssistantMessageId,
|
|
7992
|
+
clickTs: body.clickTs,
|
|
7993
|
+
sseReadyState,
|
|
7994
|
+
lastEventType,
|
|
7995
|
+
lastAppliedMessageId
|
|
7996
|
+
}
|
|
7997
|
+
};
|
|
7998
|
+
}
|
|
7951
7999
|
var app13 = new Hono();
|
|
7952
8000
|
app13.post("/", requireAdminSession, async (c) => {
|
|
8001
|
+
let body;
|
|
8002
|
+
try {
|
|
8003
|
+
body = await c.req.json();
|
|
8004
|
+
} catch {
|
|
8005
|
+
return c.json({ ok: false, error: "missing-turn-identifiers", missing: ["body-not-json"] }, 400);
|
|
8006
|
+
}
|
|
8007
|
+
const v = validate2(body);
|
|
8008
|
+
if (!v.ok) {
|
|
8009
|
+
return c.json({ ok: false, error: "missing-turn-identifiers", missing: v.missing }, 400);
|
|
8010
|
+
}
|
|
8011
|
+
const cacheKey = c.var.cacheKey;
|
|
8012
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
8013
|
+
if (!accountId) {
|
|
8014
|
+
return c.json({ ok: false, error: "no-account" }, 401);
|
|
8015
|
+
}
|
|
8016
|
+
const line = [
|
|
8017
|
+
`[failure-report] sessionKey=${v.value.sessionKey}`,
|
|
8018
|
+
`conversationId=${v.value.conversationId}`,
|
|
8019
|
+
`userMessageId=${v.value.lastUserMessageId}`,
|
|
8020
|
+
`assistantMessageId=${v.value.lastAssistantMessageId}`,
|
|
8021
|
+
`sseState=${v.value.sseReadyState}`,
|
|
8022
|
+
`lastEventType=${v.value.lastEventType}`,
|
|
8023
|
+
`lastAppliedMessageId=${v.value.lastAppliedMessageId}`,
|
|
8024
|
+
`ts=${v.value.clickTs}`
|
|
8025
|
+
].join(" ");
|
|
8026
|
+
appendStreamLogLine(accountId, v.value.sessionKey, line);
|
|
8027
|
+
return c.json({ ok: true });
|
|
8028
|
+
});
|
|
8029
|
+
var failure_report_default = app13;
|
|
8030
|
+
|
|
8031
|
+
// server/routes/admin/sse-telemetry.ts
|
|
8032
|
+
var SESSION_KEY_RE2 = /^sk_[0-9a-f]{16}$/i;
|
|
8033
|
+
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
8034
|
+
var ISO_RE3 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
8035
|
+
var PHASE_VALUES = /* @__PURE__ */ new Set(["connected", "event_received", "render_complete", "error", "close"]);
|
|
8036
|
+
var SAFE_TOKEN_RE2 = /^[\w.:-]{1,64}$/;
|
|
8037
|
+
function validate3(body) {
|
|
8038
|
+
const missing = [];
|
|
8039
|
+
if (typeof body.sessionKey !== "string" || !SESSION_KEY_RE2.test(body.sessionKey)) missing.push("sessionKey");
|
|
8040
|
+
if (typeof body.conversationId !== "string" || !UUID_RE5.test(body.conversationId)) missing.push("conversationId");
|
|
8041
|
+
if (typeof body.phase !== "string" || !PHASE_VALUES.has(body.phase)) missing.push("phase");
|
|
8042
|
+
if (typeof body.ts !== "string" || !ISO_RE3.test(body.ts)) missing.push("ts");
|
|
8043
|
+
if (missing.length > 0) return { ok: false, missing };
|
|
8044
|
+
const eventType = typeof body.eventType === "string" && SAFE_TOKEN_RE2.test(body.eventType) ? body.eventType : "-";
|
|
8045
|
+
const messageId = typeof body.messageId === "string" && SAFE_TOKEN_RE2.test(body.messageId) ? body.messageId : "-";
|
|
8046
|
+
return {
|
|
8047
|
+
ok: true,
|
|
8048
|
+
value: {
|
|
8049
|
+
sessionKey: body.sessionKey,
|
|
8050
|
+
conversationId: body.conversationId,
|
|
8051
|
+
phase: body.phase,
|
|
8052
|
+
eventType,
|
|
8053
|
+
messageId,
|
|
8054
|
+
ts: body.ts
|
|
8055
|
+
}
|
|
8056
|
+
};
|
|
8057
|
+
}
|
|
8058
|
+
var app14 = new Hono();
|
|
8059
|
+
app14.post("/", requireAdminSession, async (c) => {
|
|
8060
|
+
let body;
|
|
8061
|
+
try {
|
|
8062
|
+
body = await c.req.json();
|
|
8063
|
+
} catch {
|
|
8064
|
+
return c.json({ ok: false, error: "missing-turn-identifiers", missing: ["body-not-json"] }, 400);
|
|
8065
|
+
}
|
|
8066
|
+
const v = validate3(body);
|
|
8067
|
+
if (!v.ok) {
|
|
8068
|
+
return c.json({ ok: false, error: "missing-turn-identifiers", missing: v.missing }, 400);
|
|
8069
|
+
}
|
|
8070
|
+
const cacheKey = c.var.cacheKey;
|
|
8071
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
8072
|
+
if (!accountId) {
|
|
8073
|
+
return c.json({ ok: false, error: "no-account" }, 401);
|
|
8074
|
+
}
|
|
8075
|
+
appendStreamLogLine(
|
|
8076
|
+
accountId,
|
|
8077
|
+
v.value.sessionKey,
|
|
8078
|
+
`[sse-client] phase=${v.value.phase} sessionKey=${v.value.sessionKey} conversationId=${v.value.conversationId} messageId=${v.value.messageId} eventType=${v.value.eventType} ts=${v.value.ts}`
|
|
8079
|
+
);
|
|
8080
|
+
return c.json({ ok: true });
|
|
8081
|
+
});
|
|
8082
|
+
var sse_telemetry_default = app14;
|
|
8083
|
+
|
|
8084
|
+
// server/routes/admin/compact.ts
|
|
8085
|
+
var app15 = new Hono();
|
|
8086
|
+
app15.post("/", requireAdminSession, async (c) => {
|
|
7953
8087
|
const cacheKey = c.var.cacheKey;
|
|
7954
8088
|
const encoder = new TextEncoder();
|
|
7955
8089
|
const stream = new ReadableStream({
|
|
@@ -7976,11 +8110,11 @@ app13.post("/", requireAdminSession, async (c) => {
|
|
|
7976
8110
|
}
|
|
7977
8111
|
});
|
|
7978
8112
|
});
|
|
7979
|
-
var compact_default =
|
|
8113
|
+
var compact_default = app15;
|
|
7980
8114
|
|
|
7981
8115
|
// server/routes/admin/logs.ts
|
|
7982
8116
|
import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync6 } from "fs";
|
|
7983
|
-
import { resolve as
|
|
8117
|
+
import { resolve as resolve8, basename as basename2 } from "path";
|
|
7984
8118
|
|
|
7985
8119
|
// app/lib/logs-read-resolve.ts
|
|
7986
8120
|
import { existsSync as existsSync12 } from "fs";
|
|
@@ -7999,15 +8133,15 @@ function resolveSessionLogPaths(filename, logDirs) {
|
|
|
7999
8133
|
|
|
8000
8134
|
// server/routes/admin/logs.ts
|
|
8001
8135
|
var TAIL_BYTES = 8192;
|
|
8002
|
-
var
|
|
8003
|
-
|
|
8136
|
+
var app16 = new Hono();
|
|
8137
|
+
app16.get("/", async (c) => {
|
|
8004
8138
|
const fileParam = c.req.query("file");
|
|
8005
8139
|
const typeParam = c.req.query("type");
|
|
8006
8140
|
const conversationIdParam = c.req.query("conversationId");
|
|
8007
8141
|
const cacheKeyParam = c.req.query("cacheKey");
|
|
8008
8142
|
const download = c.req.query("download") === "1";
|
|
8009
8143
|
const account = resolveAccount();
|
|
8010
|
-
const accountLogDir = account ?
|
|
8144
|
+
const accountLogDir = account ? resolve8(account.accountDir, "logs") : null;
|
|
8011
8145
|
const logDirs = [];
|
|
8012
8146
|
if (accountLogDir) logDirs.push(accountLogDir);
|
|
8013
8147
|
logDirs.push(LOG_DIR);
|
|
@@ -8015,7 +8149,7 @@ app14.get("/", async (c) => {
|
|
|
8015
8149
|
const safe = basename2(fileParam);
|
|
8016
8150
|
const searched = [];
|
|
8017
8151
|
for (const dir of logDirs) {
|
|
8018
|
-
const filePath =
|
|
8152
|
+
const filePath = resolve8(dir, safe);
|
|
8019
8153
|
searched.push(filePath);
|
|
8020
8154
|
try {
|
|
8021
8155
|
const buffer = readFileSync11(filePath);
|
|
@@ -8127,10 +8261,10 @@ app14.get("/", async (c) => {
|
|
|
8127
8261
|
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
8128
8262
|
continue;
|
|
8129
8263
|
}
|
|
8130
|
-
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync6(
|
|
8264
|
+
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync6(resolve8(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
8131
8265
|
seen.add(name);
|
|
8132
8266
|
try {
|
|
8133
|
-
const content = readFileSync11(
|
|
8267
|
+
const content = readFileSync11(resolve8(dir, name));
|
|
8134
8268
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
8135
8269
|
logs[name] = tail.trim() || "(empty)";
|
|
8136
8270
|
} catch (err) {
|
|
@@ -8142,12 +8276,12 @@ app14.get("/", async (c) => {
|
|
|
8142
8276
|
}
|
|
8143
8277
|
return c.json({ logs });
|
|
8144
8278
|
});
|
|
8145
|
-
var logs_default =
|
|
8279
|
+
var logs_default = app16;
|
|
8146
8280
|
|
|
8147
8281
|
// server/routes/admin/claude-info.ts
|
|
8148
8282
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
8149
|
-
var
|
|
8150
|
-
|
|
8283
|
+
var app17 = new Hono();
|
|
8284
|
+
app17.get("/", (c) => {
|
|
8151
8285
|
let version = "unknown";
|
|
8152
8286
|
try {
|
|
8153
8287
|
const raw = execFileSync2("claude", ["--version"], { encoding: "utf-8", timeout: 5e3 });
|
|
@@ -8165,14 +8299,14 @@ app15.get("/", (c) => {
|
|
|
8165
8299
|
const thinkingView = resolvedAccount?.config.thinkingView ?? "default";
|
|
8166
8300
|
return c.json({ version, account, model, thinkingView });
|
|
8167
8301
|
});
|
|
8168
|
-
var claude_info_default =
|
|
8302
|
+
var claude_info_default = app17;
|
|
8169
8303
|
|
|
8170
8304
|
// server/routes/admin/attachment.ts
|
|
8171
8305
|
import { readFile as readFile2, readdir } from "fs/promises";
|
|
8172
8306
|
import { existsSync as existsSync14 } from "fs";
|
|
8173
|
-
import { resolve as
|
|
8174
|
-
var
|
|
8175
|
-
|
|
8307
|
+
import { resolve as resolve9 } from "path";
|
|
8308
|
+
var app18 = new Hono();
|
|
8309
|
+
app18.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
8176
8310
|
const attachmentId = c.req.param("attachmentId");
|
|
8177
8311
|
const cacheKey = c.var.cacheKey;
|
|
8178
8312
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -8182,11 +8316,11 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
8182
8316
|
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(attachmentId)) {
|
|
8183
8317
|
return new Response("Not found", { status: 404 });
|
|
8184
8318
|
}
|
|
8185
|
-
const dir =
|
|
8319
|
+
const dir = resolve9(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
8186
8320
|
if (!existsSync14(dir)) {
|
|
8187
8321
|
return new Response("Not found", { status: 404 });
|
|
8188
8322
|
}
|
|
8189
|
-
const metaPath =
|
|
8323
|
+
const metaPath = resolve9(dir, `${attachmentId}.meta.json`);
|
|
8190
8324
|
if (!existsSync14(metaPath)) {
|
|
8191
8325
|
return new Response("Not found", { status: 404 });
|
|
8192
8326
|
}
|
|
@@ -8201,7 +8335,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
8201
8335
|
if (!dataFile) {
|
|
8202
8336
|
return new Response("Not found", { status: 404 });
|
|
8203
8337
|
}
|
|
8204
|
-
const filePath =
|
|
8338
|
+
const filePath = resolve9(dir, dataFile);
|
|
8205
8339
|
const buffer = await readFile2(filePath);
|
|
8206
8340
|
return new Response(new Uint8Array(buffer), {
|
|
8207
8341
|
headers: {
|
|
@@ -8211,16 +8345,16 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
8211
8345
|
}
|
|
8212
8346
|
});
|
|
8213
8347
|
});
|
|
8214
|
-
var attachment_default =
|
|
8348
|
+
var attachment_default = app18;
|
|
8215
8349
|
|
|
8216
8350
|
// server/routes/admin/agents.ts
|
|
8217
|
-
import { resolve as
|
|
8351
|
+
import { resolve as resolve10 } from "path";
|
|
8218
8352
|
import { readdirSync as readdirSync6, readFileSync as readFileSync12, existsSync as existsSync15, rmSync } from "fs";
|
|
8219
|
-
var
|
|
8220
|
-
|
|
8353
|
+
var app19 = new Hono();
|
|
8354
|
+
app19.get("/", (c) => {
|
|
8221
8355
|
const account = resolveAccount();
|
|
8222
8356
|
if (!account) return c.json({ agents: [] });
|
|
8223
|
-
const agentsDir =
|
|
8357
|
+
const agentsDir = resolve10(account.accountDir, "agents");
|
|
8224
8358
|
if (!existsSync15(agentsDir)) return c.json({ agents: [] });
|
|
8225
8359
|
const agents = [];
|
|
8226
8360
|
try {
|
|
@@ -8228,7 +8362,7 @@ app17.get("/", (c) => {
|
|
|
8228
8362
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
8229
8363
|
if (!entry.isDirectory()) continue;
|
|
8230
8364
|
if (entry.name === "admin") continue;
|
|
8231
|
-
const configPath2 =
|
|
8365
|
+
const configPath2 = resolve10(agentsDir, entry.name, "config.json");
|
|
8232
8366
|
if (!existsSync15(configPath2)) continue;
|
|
8233
8367
|
try {
|
|
8234
8368
|
const config = JSON.parse(readFileSync12(configPath2, "utf-8"));
|
|
@@ -8247,7 +8381,7 @@ app17.get("/", (c) => {
|
|
|
8247
8381
|
}
|
|
8248
8382
|
return c.json({ agents });
|
|
8249
8383
|
});
|
|
8250
|
-
|
|
8384
|
+
app19.delete("/:slug", async (c) => {
|
|
8251
8385
|
const slug = c.req.param("slug");
|
|
8252
8386
|
const account = resolveAccount();
|
|
8253
8387
|
if (!account) return c.json({ error: "No account resolved" }, 400);
|
|
@@ -8257,7 +8391,7 @@ app17.delete("/:slug", async (c) => {
|
|
|
8257
8391
|
if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
|
|
8258
8392
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
8259
8393
|
}
|
|
8260
|
-
const agentDir =
|
|
8394
|
+
const agentDir = resolve10(account.accountDir, "agents", slug);
|
|
8261
8395
|
if (!existsSync15(agentDir)) {
|
|
8262
8396
|
return c.json({ error: "Agent not found" }, 404);
|
|
8263
8397
|
}
|
|
@@ -8277,7 +8411,7 @@ app17.delete("/:slug", async (c) => {
|
|
|
8277
8411
|
return c.json({ error: "Failed to delete agent" }, 500);
|
|
8278
8412
|
}
|
|
8279
8413
|
});
|
|
8280
|
-
|
|
8414
|
+
app19.post("/:slug/project", async (c) => {
|
|
8281
8415
|
const slug = c.req.param("slug");
|
|
8282
8416
|
const account = resolveAccount();
|
|
8283
8417
|
if (!account) return c.json({ error: "No account resolved" }, 400);
|
|
@@ -8287,7 +8421,7 @@ app17.post("/:slug/project", async (c) => {
|
|
|
8287
8421
|
if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
|
|
8288
8422
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
8289
8423
|
}
|
|
8290
|
-
const agentDir =
|
|
8424
|
+
const agentDir = resolve10(account.accountDir, "agents", slug);
|
|
8291
8425
|
if (!existsSync15(agentDir)) {
|
|
8292
8426
|
return c.json({ error: "Agent not found on disk" }, 404);
|
|
8293
8427
|
}
|
|
@@ -8299,12 +8433,12 @@ app17.post("/:slug/project", async (c) => {
|
|
|
8299
8433
|
return c.json({ error: `Projection failed: ${msg}` }, 500);
|
|
8300
8434
|
}
|
|
8301
8435
|
});
|
|
8302
|
-
var agents_default =
|
|
8436
|
+
var agents_default = app19;
|
|
8303
8437
|
|
|
8304
8438
|
// server/routes/admin/sessions.ts
|
|
8305
8439
|
import crypto2 from "crypto";
|
|
8306
8440
|
import { resolve as resolvePath } from "path";
|
|
8307
|
-
import {
|
|
8441
|
+
import { existsSync as existsSync17 } from "fs";
|
|
8308
8442
|
|
|
8309
8443
|
// app/lib/synthetic-marker.ts
|
|
8310
8444
|
var CLOUDFLARE_MARKER_PREFIX = "Cloudflare setup completed (actionId: ";
|
|
@@ -8487,7 +8621,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, conversationId
|
|
|
8487
8621
|
if (reason) {
|
|
8488
8622
|
invalid++;
|
|
8489
8623
|
try {
|
|
8490
|
-
|
|
8624
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [attachment-rehydrate-invalid] conversationId=${conversationId.slice(0, 8)} messageId=${messageId.slice(0, 8)} attachmentId=${(a.attachmentId || "").slice(0, 8)} reason=${reason}
|
|
8491
8625
|
`);
|
|
8492
8626
|
} catch {
|
|
8493
8627
|
}
|
|
@@ -8550,7 +8684,7 @@ function reconstructAssistantEvents(content, components, conversationId, message
|
|
|
8550
8684
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [component-rehydrate-invalid] conversationId=${conversationId.slice(0, 8)} messageId=${messageId.slice(0, 8)} name=${c.name || "<unnamed>"} reason=${invalidReason}
|
|
8551
8685
|
`;
|
|
8552
8686
|
try {
|
|
8553
|
-
|
|
8687
|
+
streamLogPath.write(line);
|
|
8554
8688
|
} catch {
|
|
8555
8689
|
}
|
|
8556
8690
|
continue;
|
|
@@ -8590,8 +8724,8 @@ function formatAge(updatedAtStr) {
|
|
|
8590
8724
|
return "unknown";
|
|
8591
8725
|
}
|
|
8592
8726
|
}
|
|
8593
|
-
var
|
|
8594
|
-
|
|
8727
|
+
var app20 = new Hono();
|
|
8728
|
+
app20.get("/", requireAdminSession, async (c) => {
|
|
8595
8729
|
const cacheKey = c.var.cacheKey;
|
|
8596
8730
|
const accountId = getAccountIdForSession(cacheKey);
|
|
8597
8731
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -8631,7 +8765,7 @@ app18.get("/", requireAdminSession, async (c) => {
|
|
|
8631
8765
|
return c.json({ error: "Failed to fetch sessions" }, 500);
|
|
8632
8766
|
}
|
|
8633
8767
|
});
|
|
8634
|
-
|
|
8768
|
+
app20.post("/new", requireAdminSession, async (c) => {
|
|
8635
8769
|
const oldCacheKey = c.var.cacheKey;
|
|
8636
8770
|
const accountId = getAccountIdForSession(oldCacheKey);
|
|
8637
8771
|
const userId = getUserIdForSession(oldCacheKey);
|
|
@@ -8647,7 +8781,7 @@ app18.post("/new", requireAdminSession, async (c) => {
|
|
|
8647
8781
|
console.log(`[session] ${(/* @__PURE__ */ new Date()).toISOString()} session reset for new conversation: oldCacheKey=${oldCacheKey.slice(0, 8)}\u2026 newCacheKey=${newCacheKey.slice(0, 8)}\u2026 previousConversationId=${previousConversationId?.slice(0, 8) ?? "none"}\u2026 newConversationId=deferred`);
|
|
8648
8782
|
return c.json({ session_key: newSignedSessionToken, conversationId: null });
|
|
8649
8783
|
});
|
|
8650
|
-
|
|
8784
|
+
app20.post("/switch", requireAdminSession, async (c) => {
|
|
8651
8785
|
const cacheKey = c.var.cacheKey;
|
|
8652
8786
|
const accountId = getAccountIdForSession(cacheKey);
|
|
8653
8787
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -8675,7 +8809,7 @@ app18.post("/switch", requireAdminSession, async (c) => {
|
|
|
8675
8809
|
console.log(`[session-switch] from=${cacheKey.slice(0, 8)} to=${targetCacheKey.slice(0, 8)} targetConvId=${targetConversationId?.slice(0, 8) ?? "none"} accountId=${accountId.slice(0, 8)}`);
|
|
8676
8810
|
return c.json({ session_key: targetSignedSessionToken, conversationId: targetConversationId });
|
|
8677
8811
|
});
|
|
8678
|
-
|
|
8812
|
+
app20.delete("/:id", requireAdminSession, async (c) => {
|
|
8679
8813
|
const conversationId = c.req.param("id");
|
|
8680
8814
|
const cacheKey = c.var.cacheKey;
|
|
8681
8815
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -8690,7 +8824,7 @@ app18.delete("/:id", requireAdminSession, async (c) => {
|
|
|
8690
8824
|
return c.json({ error: "Failed to delete session" }, 500);
|
|
8691
8825
|
}
|
|
8692
8826
|
});
|
|
8693
|
-
|
|
8827
|
+
app20.post("/:id/resume", async (c) => {
|
|
8694
8828
|
const conversationId = c.req.param("id");
|
|
8695
8829
|
const signedSessionToken = c.req.query("session_key") ?? "";
|
|
8696
8830
|
if (!signedSessionToken) {
|
|
@@ -8740,7 +8874,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8740
8874
|
if (persistedAgentSessionId) {
|
|
8741
8875
|
setAgentSessionId(cacheKey, persistedAgentSessionId);
|
|
8742
8876
|
}
|
|
8743
|
-
const streamLogPath = resolvePath(ACCOUNTS_DIR, accountId,
|
|
8877
|
+
const streamLogPath = getStreamLogHandle(resolvePath(ACCOUNTS_DIR, accountId), cacheKey);
|
|
8744
8878
|
const tag = persistedAgentSessionId ? `agentSessionId=${persistedAgentSessionId.slice(0, 8)}\u2026` : "agentSessionId=missing";
|
|
8745
8879
|
let messages = [];
|
|
8746
8880
|
let neo4jMessages = [];
|
|
@@ -8843,7 +8977,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8843
8977
|
const filename = bytesPick.mimeType === "text/html" ? `${c2.artefactTitle}.html` : `${c2.artefactTitle}.md`;
|
|
8844
8978
|
await storeComponentArtefact(accountId, c2.artefactAttachmentId, bytesPick.mimeType, bytesPick.content, filename);
|
|
8845
8979
|
clearHealPending(accountId, c2.artefactAttachmentId);
|
|
8846
|
-
|
|
8980
|
+
appendFileSync(
|
|
8847
8981
|
streamLogPath,
|
|
8848
8982
|
`[${(/* @__PURE__ */ new Date()).toISOString()}] [render-component-persist] heal componentName=${c2.name} attachmentId=${c2.artefactAttachmentId.slice(0, 8)} mimeType=${bytesPick.mimeType} bytes=${bytesPick.content.length} outcome=ok
|
|
8849
8983
|
`
|
|
@@ -8857,7 +8991,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8857
8991
|
} catch (writeErr) {
|
|
8858
8992
|
clearHealPending(accountId, c2.artefactAttachmentId);
|
|
8859
8993
|
const reason2 = writeErr instanceof Error ? writeErr.message : String(writeErr);
|
|
8860
|
-
|
|
8994
|
+
appendFileSync(
|
|
8861
8995
|
streamLogPath,
|
|
8862
8996
|
`[${(/* @__PURE__ */ new Date()).toISOString()}] [render-component-persist] heal componentName=${c2.name} attachmentId=${c2.artefactAttachmentId.slice(0, 8)} outcome=disk-fail reason=${JSON.stringify(reason2.slice(0, 200))}
|
|
8863
8997
|
`
|
|
@@ -8878,14 +9012,14 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8878
9012
|
);
|
|
8879
9013
|
jsonlHealOk += 1;
|
|
8880
9014
|
try {
|
|
8881
|
-
|
|
9015
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-persist-heal] convId=${conversationId.slice(0, 8)} turnIndex=${i} role=${q.role} outcome=ok messageId=${(messageId ?? "").slice(0, 8)}
|
|
8882
9016
|
`);
|
|
8883
9017
|
} catch {
|
|
8884
9018
|
}
|
|
8885
9019
|
} catch (err) {
|
|
8886
9020
|
jsonlHealFail += 1;
|
|
8887
9021
|
try {
|
|
8888
|
-
|
|
9022
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-persist-heal] convId=${conversationId.slice(0, 8)} turnIndex=${i} role=${q.role} outcome=fail reason=${JSON.stringify((err instanceof Error ? err.message : String(err)).slice(0, 200))}
|
|
8889
9023
|
`);
|
|
8890
9024
|
} catch {
|
|
8891
9025
|
}
|
|
@@ -8936,18 +9070,18 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8936
9070
|
const reason = bridged ? "post-restart" : "page-refresh";
|
|
8937
9071
|
try {
|
|
8938
9072
|
const source = jsonlMissing ? persistedAgentSessionId ? "jsonl-missing" : "neo4j-only" : "jsonl";
|
|
8939
|
-
|
|
9073
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-resume] reason=${reason} source=${source} cacheKey=${cacheKey.slice(0, 8)} conversationId=${conversationId.slice(0, 8)} ${tag} loadedMessages=${messages.length} jsonlReplayMessages=${jsonlReplayMessages.length} neo4jMessages=${neo4jMessages.length} jsonlMalformed=${jsonlMalformedLines} componentCount=${totalComponents} userAttachmentCount=${totalAttachments} syntheticHidden=${syntheticHidden}
|
|
8940
9074
|
`);
|
|
8941
9075
|
if (totalComponents > 0) {
|
|
8942
|
-
|
|
9076
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [component-rehydrate] conversationId=${conversationId.slice(0, 8)} count=${totalComponents} valid=${totalValid} invalid=${totalInvalid} textRuns=${textRuns}
|
|
8943
9077
|
`);
|
|
8944
9078
|
}
|
|
8945
9079
|
if (totalAttachments > 0 || totalAttachmentInvalid > 0) {
|
|
8946
|
-
|
|
9080
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [attachment-rehydrate] conversationId=${conversationId.slice(0, 8)} userMessages=${userMessageCount} attachments=${totalAttachments} invalid=${totalAttachmentInvalid}
|
|
8947
9081
|
`);
|
|
8948
9082
|
}
|
|
8949
9083
|
if (jsonlHealMissing > 0) {
|
|
8950
|
-
|
|
9084
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-resume-heal] conversationId=${conversationId.slice(0, 8)} missingTurns=${jsonlHealMissing} healOk=${jsonlHealOk} healFail=${jsonlHealFail} note=async-writes-may-still-be-in-flight
|
|
8951
9085
|
`);
|
|
8952
9086
|
}
|
|
8953
9087
|
} catch {
|
|
@@ -8966,7 +9100,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8966
9100
|
}
|
|
8967
9101
|
});
|
|
8968
9102
|
});
|
|
8969
|
-
|
|
9103
|
+
app20.post("/:id/label", requireAdminSession, async (c) => {
|
|
8970
9104
|
const conversationId = c.req.param("id");
|
|
8971
9105
|
const cacheKey = c.var.cacheKey;
|
|
8972
9106
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -8993,7 +9127,7 @@ app18.post("/:id/label", requireAdminSession, async (c) => {
|
|
|
8993
9127
|
return c.json({ label: null });
|
|
8994
9128
|
}
|
|
8995
9129
|
});
|
|
8996
|
-
|
|
9130
|
+
app20.put("/:id/label", requireAdminSession, async (c) => {
|
|
8997
9131
|
const conversationId = c.req.param("id");
|
|
8998
9132
|
const cacheKey = c.var.cacheKey;
|
|
8999
9133
|
let body;
|
|
@@ -9019,11 +9153,11 @@ app18.put("/:id/label", requireAdminSession, async (c) => {
|
|
|
9019
9153
|
return c.json({ error: "Failed to rename session" }, 500);
|
|
9020
9154
|
}
|
|
9021
9155
|
});
|
|
9022
|
-
var sessions_default =
|
|
9156
|
+
var sessions_default = app20;
|
|
9023
9157
|
|
|
9024
9158
|
// server/routes/admin/browser.ts
|
|
9025
|
-
var
|
|
9026
|
-
|
|
9159
|
+
var app21 = new Hono();
|
|
9160
|
+
app21.post("/launch", async (c) => {
|
|
9027
9161
|
try {
|
|
9028
9162
|
const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
|
|
9029
9163
|
if (transport === "vnc") {
|
|
@@ -9045,7 +9179,7 @@ app19.post("/launch", async (c) => {
|
|
|
9045
9179
|
);
|
|
9046
9180
|
}
|
|
9047
9181
|
});
|
|
9048
|
-
var browser_default =
|
|
9182
|
+
var browser_default = app21;
|
|
9049
9183
|
|
|
9050
9184
|
// server/routes/admin/browser-iframe.ts
|
|
9051
9185
|
var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
@@ -9062,8 +9196,8 @@ function asString(v, max = 500) {
|
|
|
9062
9196
|
function asNumber(v) {
|
|
9063
9197
|
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
9064
9198
|
}
|
|
9065
|
-
var
|
|
9066
|
-
|
|
9199
|
+
var app22 = new Hono();
|
|
9200
|
+
app22.post("/event", async (c) => {
|
|
9067
9201
|
let body = {};
|
|
9068
9202
|
try {
|
|
9069
9203
|
body = await c.req.json();
|
|
@@ -9084,7 +9218,7 @@ app20.post("/event", async (c) => {
|
|
|
9084
9218
|
});
|
|
9085
9219
|
return c.body(null, 204);
|
|
9086
9220
|
});
|
|
9087
|
-
var browser_iframe_default =
|
|
9221
|
+
var browser_iframe_default = app22;
|
|
9088
9222
|
|
|
9089
9223
|
// app/lib/cdp-client.ts
|
|
9090
9224
|
var CDP_HOST = "127.0.0.1";
|
|
@@ -9127,8 +9261,8 @@ async function cdpNavigateNewTab(url, opts = {}) {
|
|
|
9127
9261
|
}
|
|
9128
9262
|
|
|
9129
9263
|
// server/routes/admin/device-browser.ts
|
|
9130
|
-
var
|
|
9131
|
-
|
|
9264
|
+
var app23 = new Hono();
|
|
9265
|
+
app23.post("/navigate", async (c) => {
|
|
9132
9266
|
const TAG19 = "[device-url:click]";
|
|
9133
9267
|
let body;
|
|
9134
9268
|
try {
|
|
@@ -9215,7 +9349,7 @@ app21.post("/navigate", async (c) => {
|
|
|
9215
9349
|
targetId: outcome.targetId
|
|
9216
9350
|
});
|
|
9217
9351
|
});
|
|
9218
|
-
var device_browser_default =
|
|
9352
|
+
var device_browser_default = app23;
|
|
9219
9353
|
|
|
9220
9354
|
// server/routes/admin/events.ts
|
|
9221
9355
|
var ALLOWED_EVENTS2 = /* @__PURE__ */ new Set([
|
|
@@ -9224,8 +9358,8 @@ var ALLOWED_EVENTS2 = /* @__PURE__ */ new Set([
|
|
|
9224
9358
|
"device-url:vnc-surface-shown",
|
|
9225
9359
|
"device-url:malformed"
|
|
9226
9360
|
]);
|
|
9227
|
-
var
|
|
9228
|
-
|
|
9361
|
+
var app24 = new Hono();
|
|
9362
|
+
app24.post("/", async (c) => {
|
|
9229
9363
|
const TAG19 = "[admin:events]";
|
|
9230
9364
|
let body;
|
|
9231
9365
|
try {
|
|
@@ -9256,11 +9390,11 @@ app22.post("/", async (c) => {
|
|
|
9256
9390
|
console.error(`[${event}] ${formatted}`);
|
|
9257
9391
|
return c.json({ ok: true });
|
|
9258
9392
|
});
|
|
9259
|
-
var events_default =
|
|
9393
|
+
var events_default = app24;
|
|
9260
9394
|
|
|
9261
9395
|
// server/routes/admin/cloudflare.ts
|
|
9262
9396
|
import { homedir as homedir2 } from "os";
|
|
9263
|
-
import { resolve as
|
|
9397
|
+
import { resolve as resolve12 } from "path";
|
|
9264
9398
|
import { readFileSync as readFileSync15 } from "fs";
|
|
9265
9399
|
|
|
9266
9400
|
// app/lib/dns-label.ts
|
|
@@ -9279,8 +9413,8 @@ function isValidDomain(value) {
|
|
|
9279
9413
|
// app/lib/alias-domains.ts
|
|
9280
9414
|
import { existsSync as existsSync18, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "fs";
|
|
9281
9415
|
import { dirname as dirname5 } from "path";
|
|
9282
|
-
import { resolve as
|
|
9283
|
-
var ALIAS_DOMAINS_PATH =
|
|
9416
|
+
import { resolve as resolve11 } from "path";
|
|
9417
|
+
var ALIAS_DOMAINS_PATH = resolve11(MAXY_DIR, "alias-domains.json");
|
|
9284
9418
|
function readExisting() {
|
|
9285
9419
|
if (!existsSync18(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
|
|
9286
9420
|
try {
|
|
@@ -9333,8 +9467,8 @@ function readDiscoveryResults(accountId) {
|
|
|
9333
9467
|
return { tunnels: entry.tunnels, domains: entry.domains };
|
|
9334
9468
|
}
|
|
9335
9469
|
function loadBrandInfo() {
|
|
9336
|
-
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ??
|
|
9337
|
-
const brandPath =
|
|
9470
|
+
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve12(process.cwd(), "..");
|
|
9471
|
+
const brandPath = resolve12(platformRoot2, "config", "brand.json");
|
|
9338
9472
|
try {
|
|
9339
9473
|
const parsed = JSON.parse(readFileSync15(brandPath, "utf-8"));
|
|
9340
9474
|
const hostname2 = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
|
|
@@ -9399,7 +9533,7 @@ function validateBody(body) {
|
|
|
9399
9533
|
}
|
|
9400
9534
|
return null;
|
|
9401
9535
|
}
|
|
9402
|
-
var
|
|
9536
|
+
var app25 = new Hono();
|
|
9403
9537
|
function fieldFromReason(reason) {
|
|
9404
9538
|
switch (reason) {
|
|
9405
9539
|
case "not-signed-in":
|
|
@@ -9420,7 +9554,7 @@ function fieldFromReason(reason) {
|
|
|
9420
9554
|
return "script";
|
|
9421
9555
|
}
|
|
9422
9556
|
}
|
|
9423
|
-
|
|
9557
|
+
app25.get("/domains", requireAdminSession, async (c) => {
|
|
9424
9558
|
const started = Date.now();
|
|
9425
9559
|
const cacheKey = c.var.cacheKey;
|
|
9426
9560
|
let correlationId;
|
|
@@ -9464,7 +9598,7 @@ app23.get("/domains", requireAdminSession, async (c) => {
|
|
|
9464
9598
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
9465
9599
|
log(`phase=stream-log-resolved path=${streamLogPath}`);
|
|
9466
9600
|
const brand = loadBrandInfo();
|
|
9467
|
-
const scriptPath =
|
|
9601
|
+
const scriptPath = resolve12(homedir2(), "list-cf-domains.sh");
|
|
9468
9602
|
const result = await runFormSpawn({
|
|
9469
9603
|
scriptPath,
|
|
9470
9604
|
args: [brand.hostname],
|
|
@@ -9516,7 +9650,7 @@ ${result.stderr}` : ""}`;
|
|
|
9516
9650
|
return c.json(success, 200);
|
|
9517
9651
|
});
|
|
9518
9652
|
var TUNNELS_TIMEOUT_MS = 30 * 1e3;
|
|
9519
|
-
|
|
9653
|
+
app25.get("/tunnels", requireAdminSession, async (c) => {
|
|
9520
9654
|
const started = Date.now();
|
|
9521
9655
|
const cacheKey = c.var.cacheKey;
|
|
9522
9656
|
let correlationId;
|
|
@@ -9555,7 +9689,7 @@ app23.get("/tunnels", requireAdminSession, async (c) => {
|
|
|
9555
9689
|
if (!accountId) return err("session", "No account bound to session \u2014 refresh chat.");
|
|
9556
9690
|
if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
|
|
9557
9691
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
9558
|
-
const certPath =
|
|
9692
|
+
const certPath = resolve12(homedir2(), brand.configDir, "cloudflared", "cert.pem");
|
|
9559
9693
|
const { existsSync: existsSync26 } = await import("fs");
|
|
9560
9694
|
if (!existsSync26(certPath)) {
|
|
9561
9695
|
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.`);
|
|
@@ -9613,7 +9747,7 @@ ${result.stderr}` : ""}`;
|
|
|
9613
9747
|
const success = { ok: true, tunnels, defaultName, correlationId, streamLogPath };
|
|
9614
9748
|
return c.json(success, 200);
|
|
9615
9749
|
});
|
|
9616
|
-
|
|
9750
|
+
app25.post("/setup", requireAdminSession, async (c) => {
|
|
9617
9751
|
const started = Date.now();
|
|
9618
9752
|
const cacheKey = c.var.cacheKey;
|
|
9619
9753
|
let correlationId;
|
|
@@ -9875,23 +10009,23 @@ actionId: ${actionId}`,
|
|
|
9875
10009
|
};
|
|
9876
10010
|
return ok(success);
|
|
9877
10011
|
});
|
|
9878
|
-
var cloudflare_default =
|
|
10012
|
+
var cloudflare_default = app25;
|
|
9879
10013
|
|
|
9880
10014
|
// server/routes/admin/files.ts
|
|
9881
10015
|
import { createReadStream as createReadStream3 } from "fs";
|
|
9882
10016
|
import { readdir as readdir2, readFile as readFile3, stat as stat3, mkdir as mkdir2, writeFile as writeFile3, unlink as unlink2 } from "fs/promises";
|
|
9883
10017
|
import { realpathSync as realpathSync3 } from "fs";
|
|
9884
|
-
import { basename as basename3, dirname as dirname6, join as join10, resolve as
|
|
10018
|
+
import { basename as basename3, dirname as dirname6, join as join10, resolve as resolve14, sep as sep2 } from "path";
|
|
9885
10019
|
import { Readable as Readable2 } from "stream";
|
|
9886
10020
|
|
|
9887
10021
|
// app/lib/data-path.ts
|
|
9888
10022
|
import { realpathSync as realpathSync2 } from "fs";
|
|
9889
|
-
import { resolve as
|
|
9890
|
-
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ??
|
|
9891
|
-
var DATA_ROOT =
|
|
10023
|
+
import { resolve as resolve13, normalize, sep, relative } from "path";
|
|
10024
|
+
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve13(process.cwd(), "../platform");
|
|
10025
|
+
var DATA_ROOT = resolve13(PLATFORM_ROOT5, "..", "data");
|
|
9892
10026
|
function resolveDataPath(raw) {
|
|
9893
10027
|
const cleaned = normalize("/" + (raw ?? "").replace(/\\/g, "/")).replace(/^\/+/, "");
|
|
9894
|
-
const absolute =
|
|
10028
|
+
const absolute = resolve13(DATA_ROOT, cleaned);
|
|
9895
10029
|
let dataRootReal;
|
|
9896
10030
|
try {
|
|
9897
10031
|
dataRootReal = realpathSync2(DATA_ROOT);
|
|
@@ -10156,7 +10290,7 @@ async function restoreNode(params) {
|
|
|
10156
10290
|
}
|
|
10157
10291
|
|
|
10158
10292
|
// app/lib/file-delete-cascade.ts
|
|
10159
|
-
var
|
|
10293
|
+
var UUID_RE6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
10160
10294
|
function parseAttachmentPath(relPath2) {
|
|
10161
10295
|
const segments = relPath2.split("/").filter(Boolean);
|
|
10162
10296
|
if (segments.length !== 4) return null;
|
|
@@ -10164,7 +10298,7 @@ function parseAttachmentPath(relPath2) {
|
|
|
10164
10298
|
const accountId = segments[1];
|
|
10165
10299
|
const attachmentId = segments[2];
|
|
10166
10300
|
const filename = segments[3];
|
|
10167
|
-
if (!
|
|
10301
|
+
if (!UUID_RE6.test(accountId) || !UUID_RE6.test(attachmentId)) return null;
|
|
10168
10302
|
const dot = filename.lastIndexOf(".");
|
|
10169
10303
|
if (dot === -1) return null;
|
|
10170
10304
|
const stem = filename.slice(0, dot);
|
|
@@ -10236,7 +10370,7 @@ async function cascadeDeleteDocument(params) {
|
|
|
10236
10370
|
}
|
|
10237
10371
|
|
|
10238
10372
|
// server/routes/admin/files.ts
|
|
10239
|
-
var
|
|
10373
|
+
var UUID_RE7 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
10240
10374
|
async function readMeta(absDir, baseName) {
|
|
10241
10375
|
try {
|
|
10242
10376
|
const raw = await readFile3(join10(absDir, `${baseName}.meta.json`), "utf8");
|
|
@@ -10250,7 +10384,7 @@ async function readMeta(absDir, baseName) {
|
|
|
10250
10384
|
}
|
|
10251
10385
|
async function readAccountNames() {
|
|
10252
10386
|
const map = /* @__PURE__ */ new Map();
|
|
10253
|
-
const accountsDir =
|
|
10387
|
+
const accountsDir = resolve14(DATA_ROOT, "accounts");
|
|
10254
10388
|
let names;
|
|
10255
10389
|
try {
|
|
10256
10390
|
names = await readdir2(accountsDir);
|
|
@@ -10258,8 +10392,8 @@ async function readAccountNames() {
|
|
|
10258
10392
|
return map;
|
|
10259
10393
|
}
|
|
10260
10394
|
for (const name of names) {
|
|
10261
|
-
if (!
|
|
10262
|
-
const configPath2 =
|
|
10395
|
+
if (!UUID_RE7.test(name)) continue;
|
|
10396
|
+
const configPath2 = resolve14(accountsDir, name, "account.json");
|
|
10263
10397
|
try {
|
|
10264
10398
|
const raw = await readFile3(configPath2, "utf8");
|
|
10265
10399
|
const parsed = JSON.parse(raw);
|
|
@@ -10276,7 +10410,7 @@ async function readAccountNames() {
|
|
|
10276
10410
|
return map;
|
|
10277
10411
|
}
|
|
10278
10412
|
async function enrich(absolute, entry, accountNames) {
|
|
10279
|
-
if (entry.kind === "directory" &&
|
|
10413
|
+
if (entry.kind === "directory" && UUID_RE7.test(entry.name)) {
|
|
10280
10414
|
const meta = await readMeta(join10(absolute, entry.name), entry.name);
|
|
10281
10415
|
if (meta?.filename) {
|
|
10282
10416
|
entry.displayName = meta.filename;
|
|
@@ -10292,7 +10426,7 @@ async function enrich(absolute, entry, accountNames) {
|
|
|
10292
10426
|
if (entry.kind === "file") {
|
|
10293
10427
|
const dot = entry.name.lastIndexOf(".");
|
|
10294
10428
|
const base = dot === -1 ? entry.name : entry.name.slice(0, dot);
|
|
10295
|
-
if (
|
|
10429
|
+
if (UUID_RE7.test(base)) {
|
|
10296
10430
|
const meta = await readMeta(absolute, base);
|
|
10297
10431
|
if (meta?.filename) {
|
|
10298
10432
|
entry.displayName = meta.filename;
|
|
@@ -10304,12 +10438,12 @@ async function enrich(absolute, entry, accountNames) {
|
|
|
10304
10438
|
function buildDisplayPath(relPath2, accountNames) {
|
|
10305
10439
|
if (relPath2 === "." || relPath2 === "") return [];
|
|
10306
10440
|
return relPath2.split("/").filter(Boolean).map((seg) => {
|
|
10307
|
-
const dn =
|
|
10441
|
+
const dn = UUID_RE7.test(seg) ? accountNames.get(seg) : void 0;
|
|
10308
10442
|
return dn ? { name: seg, displayName: dn } : { name: seg };
|
|
10309
10443
|
});
|
|
10310
10444
|
}
|
|
10311
|
-
var
|
|
10312
|
-
|
|
10445
|
+
var app26 = new Hono();
|
|
10446
|
+
app26.get("/", requireAdminSession, async (c) => {
|
|
10313
10447
|
const cacheKey = c.var.cacheKey;
|
|
10314
10448
|
if (!getAccountIdForSession(cacheKey)) {
|
|
10315
10449
|
console.error(`[data] auth-rejected endpoint="/api/admin/files" reason="no account for session"`);
|
|
@@ -10332,7 +10466,7 @@ app24.get("/", requireAdminSession, async (c) => {
|
|
|
10332
10466
|
const names = await readdir2(absolute);
|
|
10333
10467
|
const entries = [];
|
|
10334
10468
|
for (const name of names) {
|
|
10335
|
-
if (
|
|
10469
|
+
if (UUID_RE7.test(name.replace(/\.meta\.json$/, "")) && name.endsWith(".meta.json")) {
|
|
10336
10470
|
continue;
|
|
10337
10471
|
}
|
|
10338
10472
|
try {
|
|
@@ -10370,7 +10504,7 @@ app24.get("/", requireAdminSession, async (c) => {
|
|
|
10370
10504
|
return c.json({ error: message }, 500);
|
|
10371
10505
|
}
|
|
10372
10506
|
});
|
|
10373
|
-
|
|
10507
|
+
app26.get("/download", requireAdminSession, async (c) => {
|
|
10374
10508
|
const cacheKey = c.var.cacheKey;
|
|
10375
10509
|
if (!getAccountIdForSession(cacheKey)) {
|
|
10376
10510
|
console.error(`[data] auth-rejected endpoint="/api/admin/files/download" reason="no account for session"`);
|
|
@@ -10418,7 +10552,7 @@ app24.get("/download", requireAdminSession, async (c) => {
|
|
|
10418
10552
|
return c.json({ error: message }, 500);
|
|
10419
10553
|
}
|
|
10420
10554
|
});
|
|
10421
|
-
|
|
10555
|
+
app26.post("/upload", requireAdminSession, async (c) => {
|
|
10422
10556
|
const cacheKey = c.var.cacheKey;
|
|
10423
10557
|
const accountId = getAccountIdForSession(cacheKey);
|
|
10424
10558
|
if (!accountId) {
|
|
@@ -10450,8 +10584,8 @@ app24.post("/upload", requireAdminSession, async (c) => {
|
|
|
10450
10584
|
}
|
|
10451
10585
|
const safeName = basename3(file.name).replace(/[\0/\\]/g, "_");
|
|
10452
10586
|
const finalName = `${Date.now()}-${safeName}`;
|
|
10453
|
-
const destDir =
|
|
10454
|
-
const destPath =
|
|
10587
|
+
const destDir = resolve14(DATA_ROOT, "uploads", accountId);
|
|
10588
|
+
const destPath = resolve14(destDir, finalName);
|
|
10455
10589
|
try {
|
|
10456
10590
|
await mkdir2(destDir, { recursive: true });
|
|
10457
10591
|
const dataRootReal = realpathSync3(DATA_ROOT);
|
|
@@ -10476,7 +10610,7 @@ app24.post("/upload", requireAdminSession, async (c) => {
|
|
|
10476
10610
|
mimeType: file.type
|
|
10477
10611
|
});
|
|
10478
10612
|
});
|
|
10479
|
-
|
|
10613
|
+
app26.delete("/", requireAdminSession, async (c) => {
|
|
10480
10614
|
const cacheKey = c.var.cacheKey;
|
|
10481
10615
|
const accountId = getAccountIdForSession(cacheKey);
|
|
10482
10616
|
if (!accountId) {
|
|
@@ -10509,7 +10643,7 @@ app24.delete("/", requireAdminSession, async (c) => {
|
|
|
10509
10643
|
}
|
|
10510
10644
|
const dot = base.lastIndexOf(".");
|
|
10511
10645
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
10512
|
-
const sidecarPath =
|
|
10646
|
+
const sidecarPath = UUID_RE7.test(stem) && base !== `${stem}.meta.json` ? join10(dirname6(absolute), `${stem}.meta.json`) : null;
|
|
10513
10647
|
await unlink2(absolute);
|
|
10514
10648
|
if (sidecarPath) {
|
|
10515
10649
|
try {
|
|
@@ -10543,7 +10677,7 @@ app24.delete("/", requireAdminSession, async (c) => {
|
|
|
10543
10677
|
return c.json({ error: message }, 500);
|
|
10544
10678
|
}
|
|
10545
10679
|
});
|
|
10546
|
-
var files_default =
|
|
10680
|
+
var files_default = app26;
|
|
10547
10681
|
|
|
10548
10682
|
// ../lib/graph-search/src/index.ts
|
|
10549
10683
|
var import_dist = __toESM(require_dist());
|
|
@@ -10923,8 +11057,8 @@ var MAX_LIMIT = 2e3;
|
|
|
10923
11057
|
var DEFAULT_VECTOR_THRESHOLD = 0.82;
|
|
10924
11058
|
var MESSAGE_FAMILY_LABELS = ["Message", "UserMessage", "AssistantMessage", "WhatsAppMessage"];
|
|
10925
11059
|
var CONVERSATION_PARENT_LABELS = /* @__PURE__ */ new Set(["AdminConversation", "PublicConversation"]);
|
|
10926
|
-
var
|
|
10927
|
-
|
|
11060
|
+
var app27 = new Hono();
|
|
11061
|
+
app27.get("/", requireAdminSession, async (c) => {
|
|
10928
11062
|
const cacheKey = c.var.cacheKey;
|
|
10929
11063
|
const q = (c.req.query("q") ?? "").trim();
|
|
10930
11064
|
const rawLimit = c.req.query("limit");
|
|
@@ -11055,7 +11189,7 @@ app25.get("/", requireAdminSession, async (c) => {
|
|
|
11055
11189
|
await session.close();
|
|
11056
11190
|
}
|
|
11057
11191
|
});
|
|
11058
|
-
var graph_search_default =
|
|
11192
|
+
var graph_search_default = app27;
|
|
11059
11193
|
|
|
11060
11194
|
// server/routes/admin/graph-subgraph.ts
|
|
11061
11195
|
import neo4j2 from "neo4j-driver";
|
|
@@ -11213,8 +11347,8 @@ var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
|
|
|
11213
11347
|
"otpCode",
|
|
11214
11348
|
"cacheKey"
|
|
11215
11349
|
]);
|
|
11216
|
-
var
|
|
11217
|
-
|
|
11350
|
+
var app28 = new Hono();
|
|
11351
|
+
app28.get("/", requireAdminSession, async (c) => {
|
|
11218
11352
|
const cacheKey = c.var.cacheKey;
|
|
11219
11353
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11220
11354
|
if (!accountId) {
|
|
@@ -11797,12 +11931,12 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
|
|
|
11797
11931
|
}
|
|
11798
11932
|
return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
|
|
11799
11933
|
}
|
|
11800
|
-
var graph_subgraph_default =
|
|
11934
|
+
var graph_subgraph_default = app28;
|
|
11801
11935
|
|
|
11802
11936
|
// server/routes/admin/graph-delete.ts
|
|
11803
11937
|
var ALLOWED_BY = ["graph-page", "graph-drag-trash"];
|
|
11804
|
-
var
|
|
11805
|
-
|
|
11938
|
+
var app29 = new Hono();
|
|
11939
|
+
app29.post("/", requireAdminSession, async (c) => {
|
|
11806
11940
|
const cacheKey = c.var.cacheKey;
|
|
11807
11941
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11808
11942
|
if (!accountId) {
|
|
@@ -11873,11 +12007,11 @@ app27.post("/", requireAdminSession, async (c) => {
|
|
|
11873
12007
|
}
|
|
11874
12008
|
}
|
|
11875
12009
|
});
|
|
11876
|
-
var graph_delete_default =
|
|
12010
|
+
var graph_delete_default = app29;
|
|
11877
12011
|
|
|
11878
12012
|
// server/routes/admin/graph-restore.ts
|
|
11879
|
-
var
|
|
11880
|
-
|
|
12013
|
+
var app30 = new Hono();
|
|
12014
|
+
app30.post("/", requireAdminSession, async (c) => {
|
|
11881
12015
|
const cacheKey = c.var.cacheKey;
|
|
11882
12016
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11883
12017
|
if (!accountId) {
|
|
@@ -11941,11 +12075,11 @@ app28.post("/", requireAdminSession, async (c) => {
|
|
|
11941
12075
|
}
|
|
11942
12076
|
}
|
|
11943
12077
|
});
|
|
11944
|
-
var graph_restore_default =
|
|
12078
|
+
var graph_restore_default = app30;
|
|
11945
12079
|
|
|
11946
12080
|
// server/routes/admin/graph-labels-in-graph.ts
|
|
11947
|
-
var
|
|
11948
|
-
|
|
12081
|
+
var app31 = new Hono();
|
|
12082
|
+
app31.get("/", requireAdminSession, async (c) => {
|
|
11949
12083
|
const cacheKey = c.var.cacheKey;
|
|
11950
12084
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11951
12085
|
if (!accountId) {
|
|
@@ -12011,11 +12145,11 @@ var LABELS_IN_GRAPH_CYPHER = `
|
|
|
12011
12145
|
sum(halfEdges) AS relDegree
|
|
12012
12146
|
RETURN label, nodeCount, relDegree
|
|
12013
12147
|
`;
|
|
12014
|
-
var graph_labels_in_graph_default =
|
|
12148
|
+
var graph_labels_in_graph_default = app31;
|
|
12015
12149
|
|
|
12016
12150
|
// server/routes/admin/graph-default-view.ts
|
|
12017
|
-
var
|
|
12018
|
-
|
|
12151
|
+
var app32 = new Hono();
|
|
12152
|
+
app32.get("/", requireAdminSession, async (c) => {
|
|
12019
12153
|
const cacheKey = c.var.cacheKey;
|
|
12020
12154
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12021
12155
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -12053,7 +12187,7 @@ app30.get("/", requireAdminSession, async (c) => {
|
|
|
12053
12187
|
}
|
|
12054
12188
|
}
|
|
12055
12189
|
});
|
|
12056
|
-
|
|
12190
|
+
app32.put("/", requireAdminSession, async (c) => {
|
|
12057
12191
|
const cacheKey = c.var.cacheKey;
|
|
12058
12192
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12059
12193
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -12142,11 +12276,11 @@ var WRITE_CYPHER = `
|
|
|
12142
12276
|
p.updatedAt = $updatedAt
|
|
12143
12277
|
RETURN p.labels AS labels
|
|
12144
12278
|
`;
|
|
12145
|
-
var graph_default_view_default =
|
|
12279
|
+
var graph_default_view_default = app32;
|
|
12146
12280
|
|
|
12147
12281
|
// server/routes/admin/file-attach.ts
|
|
12148
|
-
var
|
|
12149
|
-
|
|
12282
|
+
var app33 = new Hono();
|
|
12283
|
+
app33.post("/", async (c) => {
|
|
12150
12284
|
try {
|
|
12151
12285
|
const body = await c.req.json();
|
|
12152
12286
|
const { filePath, accountId } = body;
|
|
@@ -12169,11 +12303,11 @@ app31.post("/", async (c) => {
|
|
|
12169
12303
|
return c.json({ error: message }, 500);
|
|
12170
12304
|
}
|
|
12171
12305
|
});
|
|
12172
|
-
var file_attach_default =
|
|
12306
|
+
var file_attach_default = app33;
|
|
12173
12307
|
|
|
12174
12308
|
// server/routes/admin/adherence.ts
|
|
12175
|
-
var
|
|
12176
|
-
|
|
12309
|
+
var app34 = new Hono();
|
|
12310
|
+
app34.get("/", requireAdminSession, async (c) => {
|
|
12177
12311
|
const agent = c.req.query("agent") ?? "admin";
|
|
12178
12312
|
const includeBlock = c.req.query("block") === "1";
|
|
12179
12313
|
const account = resolveAccount();
|
|
@@ -12194,18 +12328,18 @@ app32.get("/", requireAdminSession, async (c) => {
|
|
|
12194
12328
|
return c.json({ error: "Failed to read adherence ledger", agent }, 500);
|
|
12195
12329
|
}
|
|
12196
12330
|
});
|
|
12197
|
-
var adherence_default =
|
|
12331
|
+
var adherence_default = app34;
|
|
12198
12332
|
|
|
12199
12333
|
// server/routes/admin/sidebar-artefacts.ts
|
|
12200
12334
|
import neo4j3 from "neo4j-driver";
|
|
12201
12335
|
import { readFile as readFile4, readdir as readdir3, stat as stat4 } from "fs/promises";
|
|
12202
|
-
import { resolve as
|
|
12336
|
+
import { resolve as resolve15, relative as relative2, isAbsolute } from "path";
|
|
12203
12337
|
import { existsSync as existsSync19 } from "fs";
|
|
12204
12338
|
var LIMIT = 50;
|
|
12205
12339
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
12206
12340
|
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
12207
|
-
var
|
|
12208
|
-
|
|
12341
|
+
var app35 = new Hono();
|
|
12342
|
+
app35.get("/", requireAdminSession, async (c) => {
|
|
12209
12343
|
const cacheKey = c.var.cacheKey;
|
|
12210
12344
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12211
12345
|
if (!accountId) {
|
|
@@ -12216,7 +12350,7 @@ app33.get("/", requireAdminSession, async (c) => {
|
|
|
12216
12350
|
if (docs === null) {
|
|
12217
12351
|
return c.json({ error: "Failed to load artefacts" }, 500);
|
|
12218
12352
|
}
|
|
12219
|
-
const accountDir =
|
|
12353
|
+
const accountDir = resolve15(ACCOUNTS_DIR, accountId);
|
|
12220
12354
|
const agents = await fetchAgentTemplateRows(accountDir);
|
|
12221
12355
|
const artefacts = [...docs, ...agents].sort(
|
|
12222
12356
|
(a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
|
|
@@ -12279,8 +12413,8 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
|
|
|
12279
12413
|
logSkip(displayName, "non-text-mime", mimeType);
|
|
12280
12414
|
return { content: "", skipReason: "non-text-mime" };
|
|
12281
12415
|
}
|
|
12282
|
-
const accountDir =
|
|
12283
|
-
const dir =
|
|
12416
|
+
const accountDir = resolve15(ATTACHMENTS_ROOT, accountId);
|
|
12417
|
+
const dir = resolve15(accountDir, attachmentId);
|
|
12284
12418
|
try {
|
|
12285
12419
|
validateFilePathInAccount(dir, accountDir);
|
|
12286
12420
|
} catch {
|
|
@@ -12294,7 +12428,7 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
|
|
|
12294
12428
|
logSkip(displayName, "missing-on-disk", mimeType);
|
|
12295
12429
|
return { content: "", skipReason: "missing-on-disk" };
|
|
12296
12430
|
}
|
|
12297
|
-
return { content: await readFile4(
|
|
12431
|
+
return { content: await readFile4(resolve15(dir, dataFile), "utf-8"), skipReason: null };
|
|
12298
12432
|
} catch (err) {
|
|
12299
12433
|
const message = err instanceof Error ? err.message : String(err);
|
|
12300
12434
|
console.error(`[admin/sidebar-artefacts] read-failed attachmentId=${attachmentId.slice(0, 8)} error="${message}"`);
|
|
@@ -12310,8 +12444,8 @@ function logSkip(name, reason, mimeType) {
|
|
|
12310
12444
|
async function fetchAgentTemplateRows(accountDir) {
|
|
12311
12445
|
const rows = [];
|
|
12312
12446
|
for (const filename of ADMIN_AGENT_FILES) {
|
|
12313
|
-
const overridePath =
|
|
12314
|
-
const bundledPath =
|
|
12447
|
+
const overridePath = resolve15(accountDir, "agents", "admin", filename);
|
|
12448
|
+
const bundledPath = resolve15(PLATFORM_ROOT, "templates", "agents", "admin", filename);
|
|
12315
12449
|
const labelStem = filename.replace(/\.md$/, "");
|
|
12316
12450
|
const row = await readAgentTemplateRow({
|
|
12317
12451
|
id: `agent-template:admin:${filename}`,
|
|
@@ -12325,12 +12459,12 @@ async function fetchAgentTemplateRows(accountDir) {
|
|
|
12325
12459
|
});
|
|
12326
12460
|
if (row) rows.push(row);
|
|
12327
12461
|
}
|
|
12328
|
-
const overrideDir =
|
|
12329
|
-
const bundledDir =
|
|
12462
|
+
const overrideDir = resolve15(accountDir, "specialists", "agents");
|
|
12463
|
+
const bundledDir = resolve15(PLATFORM_ROOT, "templates", "specialists", "agents");
|
|
12330
12464
|
const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
|
|
12331
12465
|
for (const filename of specialistNames) {
|
|
12332
|
-
const overridePath =
|
|
12333
|
-
const bundledPath =
|
|
12466
|
+
const overridePath = resolve15(overrideDir, filename);
|
|
12467
|
+
const bundledPath = resolve15(bundledDir, filename);
|
|
12334
12468
|
const row = await readAgentTemplateRow({
|
|
12335
12469
|
id: `agent-template:specialist:${filename}`,
|
|
12336
12470
|
displayName: filename.replace(/\.md$/, ""),
|
|
@@ -12411,16 +12545,16 @@ function isWithin(target, root) {
|
|
|
12411
12545
|
const rel = relative2(root, target);
|
|
12412
12546
|
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
12413
12547
|
}
|
|
12414
|
-
var sidebar_artefacts_default =
|
|
12548
|
+
var sidebar_artefacts_default = app35;
|
|
12415
12549
|
|
|
12416
12550
|
// server/routes/admin/sidebar-artefact-save.ts
|
|
12417
12551
|
import { mkdir as mkdir3, readdir as readdir4, stat as stat5, writeFile as writeFile4 } from "fs/promises";
|
|
12418
|
-
import { resolve as
|
|
12552
|
+
import { resolve as resolve16 } from "path";
|
|
12419
12553
|
import { existsSync as existsSync20 } from "fs";
|
|
12420
12554
|
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
12421
|
-
var
|
|
12422
|
-
var
|
|
12423
|
-
|
|
12555
|
+
var UUID_RE8 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
12556
|
+
var app36 = new Hono();
|
|
12557
|
+
app36.post("/", requireAdminSession, async (c) => {
|
|
12424
12558
|
const cacheKey = c.var.cacheKey;
|
|
12425
12559
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12426
12560
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -12428,7 +12562,7 @@ app34.post("/", requireAdminSession, async (c) => {
|
|
|
12428
12562
|
if (!body || typeof body.id !== "string" || typeof body.content !== "string") {
|
|
12429
12563
|
return c.json({ error: "id and content required" }, 400);
|
|
12430
12564
|
}
|
|
12431
|
-
const accountDir =
|
|
12565
|
+
const accountDir = resolve16(ACCOUNTS_DIR, accountId);
|
|
12432
12566
|
const resolved = await resolveSavePath(body.id, accountId, accountDir);
|
|
12433
12567
|
if (resolved.kind === "heal-race") {
|
|
12434
12568
|
c.header("Retry-After", "2");
|
|
@@ -12473,17 +12607,17 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
12473
12607
|
if (role !== "admin" || !ADMIN_AGENT_FILES2.has(filename)) {
|
|
12474
12608
|
return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
12475
12609
|
}
|
|
12476
|
-
const parent =
|
|
12610
|
+
const parent = resolve16(accountDir, "agents", "admin");
|
|
12477
12611
|
await mkdir3(parent, { recursive: true });
|
|
12478
12612
|
try {
|
|
12479
12613
|
validateFilePathInAccount(parent, accountDir);
|
|
12480
12614
|
} catch {
|
|
12481
12615
|
return { kind: "reject", status: 400, reason: "containment-rejected" };
|
|
12482
12616
|
}
|
|
12483
|
-
return { kind: "admin-template", path:
|
|
12617
|
+
return { kind: "admin-template", path: resolve16(parent, filename) };
|
|
12484
12618
|
}
|
|
12485
|
-
if (
|
|
12486
|
-
const dir =
|
|
12619
|
+
if (UUID_RE8.test(id)) {
|
|
12620
|
+
const dir = resolve16(ATTACHMENTS_ROOT, accountId, id);
|
|
12487
12621
|
if (!existsSync20(dir)) {
|
|
12488
12622
|
const attShort = id.slice(0, 8);
|
|
12489
12623
|
if (isHealPending(accountId, id)) {
|
|
@@ -12516,7 +12650,7 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
12516
12650
|
}
|
|
12517
12651
|
}
|
|
12518
12652
|
try {
|
|
12519
|
-
validateFilePathInAccount(dir,
|
|
12653
|
+
validateFilePathInAccount(dir, resolve16(ATTACHMENTS_ROOT, accountId));
|
|
12520
12654
|
} catch {
|
|
12521
12655
|
return { kind: "reject", status: 400, reason: "containment-rejected" };
|
|
12522
12656
|
}
|
|
@@ -12525,38 +12659,38 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
12525
12659
|
if (!dataFile) {
|
|
12526
12660
|
return { kind: "reject", status: 400, reason: "not-found" };
|
|
12527
12661
|
}
|
|
12528
|
-
return { kind: "knowledge-doc", path:
|
|
12662
|
+
return { kind: "knowledge-doc", path: resolve16(dir, dataFile) };
|
|
12529
12663
|
}
|
|
12530
12664
|
return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
12531
12665
|
}
|
|
12532
12666
|
function relPath(absPath, root) {
|
|
12533
12667
|
return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
|
|
12534
12668
|
}
|
|
12535
|
-
var sidebar_artefact_save_default =
|
|
12669
|
+
var sidebar_artefact_save_default = app36;
|
|
12536
12670
|
|
|
12537
12671
|
// server/routes/admin/sidebar-artefact-content.ts
|
|
12538
12672
|
import { readFile as readFile5, readdir as readdir5 } from "fs/promises";
|
|
12539
12673
|
import { existsSync as existsSync21 } from "fs";
|
|
12540
|
-
import { resolve as
|
|
12541
|
-
var
|
|
12542
|
-
var
|
|
12543
|
-
|
|
12674
|
+
import { resolve as resolve17 } from "path";
|
|
12675
|
+
var UUID_RE9 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
12676
|
+
var app37 = new Hono();
|
|
12677
|
+
app37.get("/", requireAdminSession, async (c) => {
|
|
12544
12678
|
const cacheKey = c.var.cacheKey;
|
|
12545
12679
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12546
12680
|
if (!accountId) return new Response("Unauthorized", { status: 401 });
|
|
12547
12681
|
const id = c.req.query("id") ?? "";
|
|
12548
|
-
if (!
|
|
12682
|
+
if (!UUID_RE9.test(id)) {
|
|
12549
12683
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12550
12684
|
return new Response("Not found", { status: 404 });
|
|
12551
12685
|
}
|
|
12552
|
-
const dir =
|
|
12686
|
+
const dir = resolve17(ATTACHMENTS_ROOT, accountId, id);
|
|
12553
12687
|
if (!existsSync21(dir)) {
|
|
12554
12688
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12555
12689
|
return new Response("Not found", { status: 404 });
|
|
12556
12690
|
}
|
|
12557
12691
|
let meta;
|
|
12558
12692
|
try {
|
|
12559
|
-
meta = JSON.parse(await readFile5(
|
|
12693
|
+
meta = JSON.parse(await readFile5(resolve17(dir, `${id}.meta.json`), "utf-8"));
|
|
12560
12694
|
} catch {
|
|
12561
12695
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12562
12696
|
return new Response("Not found", { status: 404 });
|
|
@@ -12568,7 +12702,7 @@ app35.get("/", requireAdminSession, async (c) => {
|
|
|
12568
12702
|
return new Response("Not found", { status: 404 });
|
|
12569
12703
|
}
|
|
12570
12704
|
const start = Date.now();
|
|
12571
|
-
const buffer = await readFile5(
|
|
12705
|
+
const buffer = await readFile5(resolve17(dir, dataFile));
|
|
12572
12706
|
const ms = Date.now() - start;
|
|
12573
12707
|
console.log(
|
|
12574
12708
|
`[admin/sidebar-artefact-content] account=${accountId} id=${id.slice(0, 8)} mime=${meta.mimeType} bytes=${buffer.length} ms=${ms}`
|
|
@@ -12581,12 +12715,12 @@ app35.get("/", requireAdminSession, async (c) => {
|
|
|
12581
12715
|
}
|
|
12582
12716
|
});
|
|
12583
12717
|
});
|
|
12584
|
-
var sidebar_artefact_content_default =
|
|
12718
|
+
var sidebar_artefact_content_default = app37;
|
|
12585
12719
|
|
|
12586
12720
|
// server/routes/admin/health.ts
|
|
12587
12721
|
import { existsSync as existsSync22, readFileSync as readFileSync16 } from "fs";
|
|
12588
|
-
import { resolve as
|
|
12589
|
-
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ??
|
|
12722
|
+
import { resolve as resolve18, join as join11 } from "path";
|
|
12723
|
+
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
|
|
12590
12724
|
var brandHostname = "maxy";
|
|
12591
12725
|
var brandJsonPath = join11(PLATFORM_ROOT6, "config", "brand.json");
|
|
12592
12726
|
if (existsSync22(brandJsonPath)) {
|
|
@@ -12596,7 +12730,7 @@ if (existsSync22(brandJsonPath)) {
|
|
|
12596
12730
|
} catch {
|
|
12597
12731
|
}
|
|
12598
12732
|
}
|
|
12599
|
-
var VERSION_FILE =
|
|
12733
|
+
var VERSION_FILE = resolve18(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
|
|
12600
12734
|
var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
12601
12735
|
var PROBE_TIMEOUT_MS = 1e3;
|
|
12602
12736
|
function readVersion() {
|
|
@@ -12626,8 +12760,8 @@ async function probeConversationDb() {
|
|
|
12626
12760
|
});
|
|
12627
12761
|
}
|
|
12628
12762
|
}
|
|
12629
|
-
var
|
|
12630
|
-
|
|
12763
|
+
var app38 = new Hono();
|
|
12764
|
+
app38.get("/", async (c) => {
|
|
12631
12765
|
const version = readVersion();
|
|
12632
12766
|
const probe = await probeConversationDb();
|
|
12633
12767
|
const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
|
|
@@ -12649,42 +12783,44 @@ app36.get("/", async (c) => {
|
|
|
12649
12783
|
uptimeMs
|
|
12650
12784
|
});
|
|
12651
12785
|
});
|
|
12652
|
-
var health_default2 =
|
|
12786
|
+
var health_default2 = app38;
|
|
12653
12787
|
|
|
12654
12788
|
// server/routes/admin/index.ts
|
|
12655
|
-
var
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12789
|
+
var app39 = new Hono();
|
|
12790
|
+
app39.route("/session", session_default2);
|
|
12791
|
+
app39.route("/chat", chat_default2);
|
|
12792
|
+
app39.route("/chat-failure", chat_failure_default);
|
|
12793
|
+
app39.route("/failure-report", failure_report_default);
|
|
12794
|
+
app39.route("/sse-telemetry", sse_telemetry_default);
|
|
12795
|
+
app39.route("/compact", compact_default);
|
|
12796
|
+
app39.route("/logs", logs_default);
|
|
12797
|
+
app39.route("/claude-info", claude_info_default);
|
|
12798
|
+
app39.route("/attachment", attachment_default);
|
|
12799
|
+
app39.route("/agents", agents_default);
|
|
12800
|
+
app39.route("/sessions", sessions_default);
|
|
12801
|
+
app39.route("/browser", browser_default);
|
|
12802
|
+
app39.route("/browser-iframe", browser_iframe_default);
|
|
12803
|
+
app39.route("/device-browser", device_browser_default);
|
|
12804
|
+
app39.route("/events", events_default);
|
|
12805
|
+
app39.route("/cloudflare", cloudflare_default);
|
|
12806
|
+
app39.route("/files", files_default);
|
|
12807
|
+
app39.route("/graph-search", graph_search_default);
|
|
12808
|
+
app39.route("/graph-subgraph", graph_subgraph_default);
|
|
12809
|
+
app39.route("/graph-delete", graph_delete_default);
|
|
12810
|
+
app39.route("/graph-restore", graph_restore_default);
|
|
12811
|
+
app39.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
12812
|
+
app39.route("/graph-default-view", graph_default_view_default);
|
|
12813
|
+
app39.route("/file-attach", file_attach_default);
|
|
12814
|
+
app39.route("/adherence", adherence_default);
|
|
12815
|
+
app39.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
12816
|
+
app39.route("/sidebar-artefact-save", sidebar_artefact_save_default);
|
|
12817
|
+
app39.route("/sidebar-artefact-content", sidebar_artefact_content_default);
|
|
12818
|
+
app39.route("/health-brand", health_default2);
|
|
12819
|
+
var admin_default = app39;
|
|
12684
12820
|
|
|
12685
12821
|
// server/routes/sites.ts
|
|
12686
12822
|
import { existsSync as existsSync23, readFileSync as readFileSync17, realpathSync as realpathSync4, statSync as statSync7 } from "fs";
|
|
12687
|
-
import { resolve as
|
|
12823
|
+
import { resolve as resolve19 } from "path";
|
|
12688
12824
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
12689
12825
|
var MIME = {
|
|
12690
12826
|
".html": "text/html; charset=utf-8",
|
|
@@ -12715,8 +12851,8 @@ function getExt(p) {
|
|
|
12715
12851
|
if (idx < p.lastIndexOf("/")) return "";
|
|
12716
12852
|
return p.slice(idx).toLowerCase();
|
|
12717
12853
|
}
|
|
12718
|
-
var
|
|
12719
|
-
|
|
12854
|
+
var app40 = new Hono();
|
|
12855
|
+
app40.get("/:rel{.*}", (c) => {
|
|
12720
12856
|
const reqPath = c.req.path;
|
|
12721
12857
|
const rawRel = c.req.param("rel") ?? "";
|
|
12722
12858
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -12741,8 +12877,8 @@ app38.get("/:rel{.*}", (c) => {
|
|
|
12741
12877
|
}
|
|
12742
12878
|
segments.push(seg);
|
|
12743
12879
|
}
|
|
12744
|
-
const rootDir =
|
|
12745
|
-
let filePath = segments.length === 0 ? rootDir :
|
|
12880
|
+
const rootDir = resolve19(account.accountDir, "sites");
|
|
12881
|
+
let filePath = segments.length === 0 ? rootDir : resolve19(rootDir, ...segments);
|
|
12746
12882
|
if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
|
|
12747
12883
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
12748
12884
|
return c.text("Forbidden", 403);
|
|
@@ -12762,7 +12898,7 @@ app38.get("/:rel{.*}", (c) => {
|
|
|
12762
12898
|
return c.redirect(target, 301);
|
|
12763
12899
|
}
|
|
12764
12900
|
if (stat6?.isDirectory()) {
|
|
12765
|
-
filePath =
|
|
12901
|
+
filePath = resolve19(filePath, "index.html");
|
|
12766
12902
|
}
|
|
12767
12903
|
if (!filePath.startsWith(rootDir + "/")) {
|
|
12768
12904
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
@@ -12819,7 +12955,7 @@ app38.get("/:rel{.*}", (c) => {
|
|
|
12819
12955
|
"X-Content-Type-Options": "nosniff"
|
|
12820
12956
|
});
|
|
12821
12957
|
});
|
|
12822
|
-
var sites_default =
|
|
12958
|
+
var sites_default = app40;
|
|
12823
12959
|
|
|
12824
12960
|
// app/lib/graph-health.ts
|
|
12825
12961
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -12937,7 +13073,7 @@ function startGraphHealthTimer() {
|
|
|
12937
13073
|
// ../lib/entitlement/src/index.ts
|
|
12938
13074
|
import { createPublicKey, createHash as createHash3, verify as cryptoVerify } from "crypto";
|
|
12939
13075
|
import { existsSync as existsSync24, readFileSync as readFileSync18, statSync as statSync8 } from "fs";
|
|
12940
|
-
import { resolve as
|
|
13076
|
+
import { resolve as resolve20 } from "path";
|
|
12941
13077
|
|
|
12942
13078
|
// ../lib/entitlement/src/canonicalize.ts
|
|
12943
13079
|
function canonicalize(value) {
|
|
@@ -12972,7 +13108,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
|
|
|
12972
13108
|
var GRACE_DAYS = 7;
|
|
12973
13109
|
var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
|
|
12974
13110
|
function pubkeyPath(brand) {
|
|
12975
|
-
return
|
|
13111
|
+
return resolve20(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
|
|
12976
13112
|
}
|
|
12977
13113
|
var memo = null;
|
|
12978
13114
|
function memoKey(mtimeMs, account) {
|
|
@@ -12984,7 +13120,7 @@ function resolveEntitlement(brand, account) {
|
|
|
12984
13120
|
if (brand.commercialMode !== true) {
|
|
12985
13121
|
return logResolved(implicitTrust(account), null);
|
|
12986
13122
|
}
|
|
12987
|
-
const entitlementPath =
|
|
13123
|
+
const entitlementPath = resolve20(brand.configDir, "entitlement.json");
|
|
12988
13124
|
if (!existsSync24(entitlementPath)) {
|
|
12989
13125
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
12990
13126
|
}
|
|
@@ -13229,9 +13365,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
13229
13365
|
function isPublicHost(host) {
|
|
13230
13366
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
13231
13367
|
}
|
|
13232
|
-
var
|
|
13233
|
-
|
|
13234
|
-
|
|
13368
|
+
var app41 = new Hono();
|
|
13369
|
+
app41.use("*", clientIpMiddleware);
|
|
13370
|
+
app41.use("*", async (c, next) => {
|
|
13235
13371
|
await next();
|
|
13236
13372
|
c.header("X-Content-Type-Options", "nosniff");
|
|
13237
13373
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -13241,7 +13377,7 @@ app39.use("*", async (c, next) => {
|
|
|
13241
13377
|
);
|
|
13242
13378
|
});
|
|
13243
13379
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
13244
|
-
|
|
13380
|
+
app41.use("*", async (c, next) => {
|
|
13245
13381
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
13246
13382
|
await next();
|
|
13247
13383
|
return;
|
|
@@ -13274,7 +13410,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
13274
13410
|
"/sites/"
|
|
13275
13411
|
];
|
|
13276
13412
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
13277
|
-
|
|
13413
|
+
app41.use("*", async (c, next) => {
|
|
13278
13414
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13279
13415
|
if (!isPublicHost(host)) {
|
|
13280
13416
|
await next();
|
|
@@ -13314,7 +13450,7 @@ function resolveRemoteAuthOpts() {
|
|
|
13314
13450
|
return brandLoginOpts;
|
|
13315
13451
|
}
|
|
13316
13452
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
13317
|
-
|
|
13453
|
+
app41.post("/__remote-auth/login", async (c) => {
|
|
13318
13454
|
const client = clientFrom(c);
|
|
13319
13455
|
const clientIp = client.ip || "unknown";
|
|
13320
13456
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -13359,7 +13495,7 @@ app39.post("/__remote-auth/login", async (c) => {
|
|
|
13359
13495
|
}
|
|
13360
13496
|
});
|
|
13361
13497
|
});
|
|
13362
|
-
|
|
13498
|
+
app41.get("/__remote-auth/logout", (c) => {
|
|
13363
13499
|
const client = clientFrom(c);
|
|
13364
13500
|
const clientIp = client.ip || "unknown";
|
|
13365
13501
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -13372,7 +13508,7 @@ app39.get("/__remote-auth/logout", (c) => {
|
|
|
13372
13508
|
}
|
|
13373
13509
|
});
|
|
13374
13510
|
});
|
|
13375
|
-
|
|
13511
|
+
app41.post("/__remote-auth/change-password", async (c) => {
|
|
13376
13512
|
const client = clientFrom(c);
|
|
13377
13513
|
const clientIp = client.ip || "unknown";
|
|
13378
13514
|
const rateLimited = checkRateLimit(client);
|
|
@@ -13423,13 +13559,13 @@ app39.post("/__remote-auth/change-password", async (c) => {
|
|
|
13423
13559
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
13424
13560
|
}
|
|
13425
13561
|
});
|
|
13426
|
-
|
|
13562
|
+
app41.get("/__remote-auth/setup", (c) => {
|
|
13427
13563
|
if (isRemoteAuthConfigured()) {
|
|
13428
13564
|
return c.redirect("/");
|
|
13429
13565
|
}
|
|
13430
13566
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
13431
13567
|
});
|
|
13432
|
-
|
|
13568
|
+
app41.post("/__remote-auth/set-initial-password", async (c) => {
|
|
13433
13569
|
if (isRemoteAuthConfigured()) {
|
|
13434
13570
|
return c.redirect("/");
|
|
13435
13571
|
}
|
|
@@ -13467,10 +13603,10 @@ app39.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
13467
13603
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
13468
13604
|
}
|
|
13469
13605
|
});
|
|
13470
|
-
|
|
13606
|
+
app41.get("/api/remote-auth/status", (c) => {
|
|
13471
13607
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
13472
13608
|
});
|
|
13473
|
-
|
|
13609
|
+
app41.post("/api/remote-auth/set-password", async (c) => {
|
|
13474
13610
|
let body;
|
|
13475
13611
|
try {
|
|
13476
13612
|
body = await c.req.json();
|
|
@@ -13501,9 +13637,9 @@ app39.post("/api/remote-auth/set-password", async (c) => {
|
|
|
13501
13637
|
return c.json({ error: "Failed to save password" }, 500);
|
|
13502
13638
|
}
|
|
13503
13639
|
});
|
|
13504
|
-
|
|
13640
|
+
app41.route("/api/_client-error", client_error_default);
|
|
13505
13641
|
console.log("[client-error-route] mounted");
|
|
13506
|
-
|
|
13642
|
+
app41.use("*", async (c, next) => {
|
|
13507
13643
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13508
13644
|
const path2 = c.req.path;
|
|
13509
13645
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -13543,15 +13679,15 @@ app39.use("*", async (c, next) => {
|
|
|
13543
13679
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
13544
13680
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
13545
13681
|
});
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13682
|
+
app41.route("/api/health", health_default);
|
|
13683
|
+
app41.route("/api/session", session_default);
|
|
13684
|
+
app41.route("/api/chat", chat_default);
|
|
13685
|
+
app41.route("/api/group", group_default);
|
|
13686
|
+
app41.route("/api/access", access_default);
|
|
13687
|
+
app41.route("/api/telegram", telegram_default);
|
|
13688
|
+
app41.route("/api/whatsapp", whatsapp_default);
|
|
13689
|
+
app41.route("/api/onboarding", onboarding_default);
|
|
13690
|
+
app41.route("/api/admin", admin_default);
|
|
13555
13691
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
13556
13692
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
13557
13693
|
var IMAGE_MIME = {
|
|
@@ -13563,7 +13699,7 @@ var IMAGE_MIME = {
|
|
|
13563
13699
|
".svg": "image/svg+xml",
|
|
13564
13700
|
".ico": "image/x-icon"
|
|
13565
13701
|
};
|
|
13566
|
-
|
|
13702
|
+
app41.get("/agent-assets/:slug/:filename", (c) => {
|
|
13567
13703
|
const slug = c.req.param("slug");
|
|
13568
13704
|
const filename = c.req.param("filename");
|
|
13569
13705
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -13579,8 +13715,8 @@ app39.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
13579
13715
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
13580
13716
|
return c.text("Not found", 404);
|
|
13581
13717
|
}
|
|
13582
|
-
const filePath =
|
|
13583
|
-
const expectedDir =
|
|
13718
|
+
const filePath = resolve21(account.accountDir, "agents", slug, "assets", filename);
|
|
13719
|
+
const expectedDir = resolve21(account.accountDir, "agents", slug, "assets");
|
|
13584
13720
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
13585
13721
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
13586
13722
|
return c.text("Forbidden", 403);
|
|
@@ -13598,7 +13734,7 @@ app39.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
13598
13734
|
"Cache-Control": "public, max-age=3600"
|
|
13599
13735
|
});
|
|
13600
13736
|
});
|
|
13601
|
-
|
|
13737
|
+
app41.get("/generated/:filename", (c) => {
|
|
13602
13738
|
const filename = c.req.param("filename");
|
|
13603
13739
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
13604
13740
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -13609,8 +13745,8 @@ app39.get("/generated/:filename", (c) => {
|
|
|
13609
13745
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
13610
13746
|
return c.text("Not found", 404);
|
|
13611
13747
|
}
|
|
13612
|
-
const filePath =
|
|
13613
|
-
const expectedDir =
|
|
13748
|
+
const filePath = resolve21(account.accountDir, "generated", filename);
|
|
13749
|
+
const expectedDir = resolve21(account.accountDir, "generated");
|
|
13614
13750
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
13615
13751
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
13616
13752
|
return c.text("Forbidden", 403);
|
|
@@ -13628,7 +13764,7 @@ app39.get("/generated/:filename", (c) => {
|
|
|
13628
13764
|
"Cache-Control": "public, max-age=86400"
|
|
13629
13765
|
});
|
|
13630
13766
|
});
|
|
13631
|
-
|
|
13767
|
+
app41.route("/sites", sites_default);
|
|
13632
13768
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
13633
13769
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
13634
13770
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -13694,7 +13830,7 @@ var clientErrorReporterScript = `<script>
|
|
|
13694
13830
|
function cachedHtml(file) {
|
|
13695
13831
|
let html = htmlCache.get(file);
|
|
13696
13832
|
if (!html) {
|
|
13697
|
-
html = readFileSync19(
|
|
13833
|
+
html = readFileSync19(resolve21(process.cwd(), "public", file), "utf-8");
|
|
13698
13834
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
13699
13835
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
13700
13836
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -13765,7 +13901,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
13765
13901
|
function escapeHtml(s) {
|
|
13766
13902
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
13767
13903
|
}
|
|
13768
|
-
|
|
13904
|
+
app41.get("/", (c) => {
|
|
13769
13905
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13770
13906
|
if (isPublicHost(host)) {
|
|
13771
13907
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -13773,12 +13909,12 @@ app39.get("/", (c) => {
|
|
|
13773
13909
|
}
|
|
13774
13910
|
return c.html(cachedHtml("index.html"));
|
|
13775
13911
|
});
|
|
13776
|
-
|
|
13912
|
+
app41.get("/public", (c) => {
|
|
13777
13913
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13778
13914
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13779
13915
|
return c.html(cachedHtml("public.html"));
|
|
13780
13916
|
});
|
|
13781
|
-
|
|
13917
|
+
app41.get("/chat", (c) => {
|
|
13782
13918
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13783
13919
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13784
13920
|
return c.html(cachedHtml("public.html"));
|
|
@@ -13797,12 +13933,12 @@ async function logViewerFetch(c, next) {
|
|
|
13797
13933
|
duration_ms: Date.now() - start
|
|
13798
13934
|
});
|
|
13799
13935
|
}
|
|
13800
|
-
|
|
13801
|
-
|
|
13802
|
-
|
|
13936
|
+
app41.use("/vnc-viewer.html", logViewerFetch);
|
|
13937
|
+
app41.use("/vnc-popout.html", logViewerFetch);
|
|
13938
|
+
app41.get("/vnc-popout.html", (c) => {
|
|
13803
13939
|
let html = htmlCache.get("vnc-popout.html");
|
|
13804
13940
|
if (!html) {
|
|
13805
|
-
html = readFileSync19(
|
|
13941
|
+
html = readFileSync19(resolve21(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
13806
13942
|
const name = escapeHtml(BRAND.productName);
|
|
13807
13943
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
13808
13944
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -13812,7 +13948,7 @@ app39.get("/vnc-popout.html", (c) => {
|
|
|
13812
13948
|
}
|
|
13813
13949
|
return c.html(html);
|
|
13814
13950
|
});
|
|
13815
|
-
|
|
13951
|
+
app41.post("/api/vnc/client-event", async (c) => {
|
|
13816
13952
|
let body;
|
|
13817
13953
|
try {
|
|
13818
13954
|
body = await c.req.json();
|
|
@@ -13833,20 +13969,20 @@ app39.post("/api/vnc/client-event", async (c) => {
|
|
|
13833
13969
|
});
|
|
13834
13970
|
return c.json({ ok: true });
|
|
13835
13971
|
});
|
|
13836
|
-
|
|
13972
|
+
app41.get("/g/:slug", (c) => {
|
|
13837
13973
|
return c.html(brandedPublicHtml());
|
|
13838
13974
|
});
|
|
13839
|
-
|
|
13975
|
+
app41.get("/graph", (c) => {
|
|
13840
13976
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13841
13977
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13842
13978
|
return c.html(cachedHtml("graph.html"));
|
|
13843
13979
|
});
|
|
13844
|
-
|
|
13980
|
+
app41.get("/data", (c) => {
|
|
13845
13981
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13846
13982
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13847
13983
|
return c.html(cachedHtml("data.html"));
|
|
13848
13984
|
});
|
|
13849
|
-
|
|
13985
|
+
app41.get("/:slug", async (c, next) => {
|
|
13850
13986
|
const slug = c.req.param("slug");
|
|
13851
13987
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
13852
13988
|
const branding = loadBrandingCache(slug);
|
|
@@ -13856,15 +13992,15 @@ app39.get("/:slug", async (c, next) => {
|
|
|
13856
13992
|
await next();
|
|
13857
13993
|
});
|
|
13858
13994
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
13859
|
-
|
|
13995
|
+
app41.get("/favicon.ico", (c) => {
|
|
13860
13996
|
c.header("Cache-Control", "public, max-age=300");
|
|
13861
13997
|
return c.redirect(brandFaviconPath, 302);
|
|
13862
13998
|
});
|
|
13863
13999
|
}
|
|
13864
|
-
|
|
14000
|
+
app41.use("/*", serveStatic({ root: "./public" }));
|
|
13865
14001
|
var port = parseInt(process.env.MAXY_UI_INTERNAL_PORT ?? process.env.PORT ?? "19199", 10);
|
|
13866
14002
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
13867
|
-
var httpServer = serve({ fetch:
|
|
14003
|
+
var httpServer = serve({ fetch: app41.fetch, port, hostname });
|
|
13868
14004
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
13869
14005
|
console.log("[boot] auth-mode summary: oauth=8 api-key=1 (api-key consumer: invokePublicAgent only)");
|
|
13870
14006
|
var SUBAPP_MANIFEST = [
|
|
@@ -13885,7 +14021,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
13885
14021
|
}
|
|
13886
14022
|
try {
|
|
13887
14023
|
const registered = [];
|
|
13888
|
-
for (const r of
|
|
14024
|
+
for (const r of app41.routes ?? []) {
|
|
13889
14025
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
13890
14026
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
13891
14027
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -13993,7 +14129,7 @@ reconcileEnabledPlugins(bootAccount?.accountDir, bootAccount?.config);
|
|
|
13993
14129
|
(async () => {
|
|
13994
14130
|
if (!bootAccount) return;
|
|
13995
14131
|
try {
|
|
13996
|
-
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-
|
|
14132
|
+
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-KCIUQYB5.js");
|
|
13997
14133
|
const result = await recoverRunningCloudflareTasks(
|
|
13998
14134
|
bootAccount.accountId,
|
|
13999
14135
|
configDirForWhatsApp,
|
|
@@ -14053,7 +14189,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
14053
14189
|
}
|
|
14054
14190
|
init({
|
|
14055
14191
|
configDir: configDirForWhatsApp,
|
|
14056
|
-
platformRoot:
|
|
14192
|
+
platformRoot: resolve21(process.env.MAXY_PLATFORM_ROOT ?? join12(__dirname, "..")),
|
|
14057
14193
|
accountConfig: bootAccountConfig,
|
|
14058
14194
|
onMessage: async (msg) => {
|
|
14059
14195
|
try {
|