@rubytech/create-maxy 1.0.889 → 1.0.891
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 +2 -2
- package/payload/platform/plugins/admin/PLUGIN.md +8 -3
- package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-load.test.d.ts +2 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-load.test.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-load.test.js +88 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-load.test.js.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +62 -5
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts +13 -0
- package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js +14 -0
- package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js.map +1 -1
- package/payload/platform/plugins/admin/skills/plugin-management/SKILL.md +1 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +6 -2
- package/payload/platform/plugins/memory/PLUGIN.md +1 -1
- package/payload/platform/scripts/check-skill-load-coverage.mjs +100 -0
- package/payload/platform/scripts/log-adherence-check.sh +28 -3
- package/payload/platform/scripts/logs-read.sh +108 -5
- package/payload/platform/templates/agents/admin/IDENTITY.md +10 -10
- package/payload/platform/templates/agents/public/IDENTITY.md +1 -1
- package/payload/platform/templates/specialists/agents/content-producer.md +2 -2
- package/payload/platform/templates/specialists/agents/database-operator.md +3 -3
- package/payload/platform/templates/specialists/agents/personal-assistant.md +2 -2
- package/payload/platform/templates/specialists/agents/project-manager.md +1 -1
- package/payload/platform/templates/specialists/agents/research-assistant.md +1 -1
- package/payload/server/chunk-FBTNBSB4.js +2282 -0
- package/payload/server/chunk-NZ6D7QJM.js +3571 -0
- package/payload/server/chunk-O7DTMDJM.js +759 -0
- package/payload/server/chunk-OD4LSAB2.js +9770 -0
- package/payload/server/chunk-RICR2PXW.js +9771 -0
- package/payload/server/chunk-TUCK5CI2.js +3566 -0
- package/payload/server/client-pool-E3OU5NYU.js +34 -0
- package/payload/server/client-pool-PG23WNFG.js +34 -0
- package/payload/server/cloudflare-task-tracker-KCIUQYB5.js +22 -0
- package/payload/server/maxy-edge.js +29 -5
- package/payload/server/public/assets/{admin-BN_z-2Bm.js → admin-BM3orGyK.js} +31 -31
- package/payload/server/public/index.html +1 -1
- package/payload/server/server.js +452 -314
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-RICR2PXW.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-NZ6D7QJM.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
|
}
|
|
@@ -4291,6 +4293,7 @@ function isLocalHost(host) {
|
|
|
4291
4293
|
}
|
|
4292
4294
|
var app3 = new Hono();
|
|
4293
4295
|
app3.post("/", async (c) => {
|
|
4296
|
+
console.log(`[chat-route] entered route=public method=POST`);
|
|
4294
4297
|
const contentType = c.req.header("content-type") ?? "";
|
|
4295
4298
|
const local = isLocalHost(c.req.header("host") ?? "");
|
|
4296
4299
|
let message;
|
|
@@ -5643,8 +5646,8 @@ async function startLogin(opts) {
|
|
|
5643
5646
|
resetActiveLogin(accountId);
|
|
5644
5647
|
let resolveQr = null;
|
|
5645
5648
|
let rejectQr = null;
|
|
5646
|
-
const qrPromise = new Promise((
|
|
5647
|
-
resolveQr =
|
|
5649
|
+
const qrPromise = new Promise((resolve22, reject) => {
|
|
5650
|
+
resolveQr = resolve22;
|
|
5648
5651
|
rejectQr = reject;
|
|
5649
5652
|
});
|
|
5650
5653
|
const qrTimer = setTimeout(
|
|
@@ -6780,7 +6783,7 @@ app8.post("/skip", async (c) => {
|
|
|
6780
6783
|
var onboarding_default = app8;
|
|
6781
6784
|
|
|
6782
6785
|
// server/routes/client-error.ts
|
|
6783
|
-
import { appendFileSync, existsSync as existsSync10, renameSync as renameSync2, statSync as statSync3 } from "fs";
|
|
6786
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync10, renameSync as renameSync2, statSync as statSync3 } from "fs";
|
|
6784
6787
|
import { join as join7 } from "path";
|
|
6785
6788
|
var CLIENT_ERRORS_LOG = join7(LOG_DIR, "client-errors.log");
|
|
6786
6789
|
var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
@@ -6929,7 +6932,7 @@ app9.post("/", async (c) => {
|
|
|
6929
6932
|
tag: typeof body.tag === "string" ? truncate(body.tag, 32) : void 0,
|
|
6930
6933
|
status: typeof body.status === "number" ? body.status : void 0
|
|
6931
6934
|
};
|
|
6932
|
-
|
|
6935
|
+
appendFileSync2(CLIENT_ERRORS_LOG, JSON.stringify(payload) + "\n", "utf-8");
|
|
6933
6936
|
} catch (err) {
|
|
6934
6937
|
console.error(`[client-error] append failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6935
6938
|
}
|
|
@@ -7187,13 +7190,11 @@ app10.post("/", async (c) => {
|
|
|
7187
7190
|
var session_default2 = app10;
|
|
7188
7191
|
|
|
7189
7192
|
// server/routes/admin/chat.ts
|
|
7190
|
-
import { resolve as resolve8 } from "path";
|
|
7191
|
-
import { appendFileSync as appendFileSync3 } from "fs";
|
|
7192
7193
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
7193
7194
|
|
|
7194
7195
|
// app/lib/script-stream-tailer.ts
|
|
7195
7196
|
import * as childProcess from "child_process";
|
|
7196
|
-
import { appendFileSync as
|
|
7197
|
+
import { appendFileSync as appendFileSync3, createReadStream as createReadStream2, mkdirSync as mkdirSync5, statSync as statSync5 } from "fs";
|
|
7197
7198
|
import { dirname as dirname4 } from "path";
|
|
7198
7199
|
import { StringDecoder } from "string_decoder";
|
|
7199
7200
|
var SCRIPT_STREAM_RE = /^\[([^\]]+)\] \[script:([a-z][a-z0-9-]*)((?::[a-z0-9:_-]+)?)\] (.*)$/;
|
|
@@ -7304,7 +7305,7 @@ function writeRouteMilestone(streamLogPath, scope, line) {
|
|
|
7304
7305
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
7305
7306
|
try {
|
|
7306
7307
|
mkdirSync5(dirname4(streamLogPath), { recursive: true });
|
|
7307
|
-
|
|
7308
|
+
appendFileSync3(streamLogPath, `[${ts}] [script:${scope}] ${line}
|
|
7308
7309
|
`);
|
|
7309
7310
|
} catch (err) {
|
|
7310
7311
|
console.error(
|
|
@@ -7479,7 +7480,7 @@ var app11 = new Hono();
|
|
|
7479
7480
|
app11.post("/cancel", requireAdminSession, async (c) => {
|
|
7480
7481
|
const session_key = c.var.cacheKey;
|
|
7481
7482
|
try {
|
|
7482
|
-
const { interruptClient: interruptClient2 } = await import("./client-pool-
|
|
7483
|
+
const { interruptClient: interruptClient2 } = await import("./client-pool-PG23WNFG.js");
|
|
7483
7484
|
await interruptClient2(session_key);
|
|
7484
7485
|
return c.json({ ok: true });
|
|
7485
7486
|
} catch (err) {
|
|
@@ -7488,6 +7489,7 @@ app11.post("/cancel", requireAdminSession, async (c) => {
|
|
|
7488
7489
|
});
|
|
7489
7490
|
app11.post("/", requireAdminSession, async (c) => {
|
|
7490
7491
|
const session_key = c.var.cacheKey;
|
|
7492
|
+
console.log(`[chat-route] entered route=admin method=POST cacheKey=${session_key.slice(0, 8)}\u2026`);
|
|
7491
7493
|
const contentType = c.req.header("content-type") ?? "";
|
|
7492
7494
|
let message;
|
|
7493
7495
|
let userTimestamp;
|
|
@@ -7673,14 +7675,14 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7673
7675
|
const encoder = new TextEncoder();
|
|
7674
7676
|
const sseLogStream = agentLogStream("sse-events", account.accountDir, session_key);
|
|
7675
7677
|
const sk = conversationId.slice(0, 8);
|
|
7676
|
-
const
|
|
7678
|
+
const streamLog = getStreamLogHandle(account.accountDir, session_key);
|
|
7677
7679
|
try {
|
|
7678
|
-
|
|
7680
|
+
streamLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [chat-route-version=task1013-one-writer-lazy-open] cacheKey=${session_key.slice(0, 12)}\u2026 conversationId=${conversationId}
|
|
7679
7681
|
`);
|
|
7680
7682
|
} catch {
|
|
7681
7683
|
}
|
|
7682
7684
|
try {
|
|
7683
|
-
|
|
7685
|
+
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
7686
|
`);
|
|
7685
7687
|
} catch {
|
|
7686
7688
|
}
|
|
@@ -7689,7 +7691,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7689
7691
|
incoming.on("close", () => {
|
|
7690
7692
|
const tsClose = (/* @__PURE__ */ new Date()).toISOString();
|
|
7691
7693
|
try {
|
|
7692
|
-
|
|
7694
|
+
streamLog.write(`[${tsClose}] [incoming-close] cacheKey=${session_key.slice(0, 12)}\u2026 complete=${incoming.complete}
|
|
7693
7695
|
`);
|
|
7694
7696
|
} catch {
|
|
7695
7697
|
}
|
|
@@ -7697,7 +7699,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7697
7699
|
console.error(`[${tsClose}] [incoming-close] DISCONNECT cacheKey=${session_key.slice(0, 12)}\u2026`);
|
|
7698
7700
|
interruptClient(session_key).catch((err) => {
|
|
7699
7701
|
try {
|
|
7700
|
-
|
|
7702
|
+
streamLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [incoming-close] interrupt-failed: ${err instanceof Error ? err.message : String(err)}
|
|
7701
7703
|
`);
|
|
7702
7704
|
} catch {
|
|
7703
7705
|
}
|
|
@@ -7706,19 +7708,36 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7706
7708
|
});
|
|
7707
7709
|
} else {
|
|
7708
7710
|
try {
|
|
7709
|
-
|
|
7711
|
+
streamLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [incoming-close] UNAVAILABLE \u2014 c.env.incoming is not an EventEmitter
|
|
7710
7712
|
`);
|
|
7711
7713
|
} catch {
|
|
7712
7714
|
}
|
|
7713
7715
|
}
|
|
7714
7716
|
const sseLog = {
|
|
7717
|
+
// Pre-token marker write. Buffers via streamLog.write (handle buffer +
|
|
7718
|
+
// console.error backstop to server.log on zero-token sessions).
|
|
7715
7719
|
write(line) {
|
|
7716
7720
|
try {
|
|
7717
7721
|
sseLogStream.write(line);
|
|
7718
7722
|
} catch {
|
|
7719
7723
|
}
|
|
7720
7724
|
try {
|
|
7721
|
-
|
|
7725
|
+
streamLog.write(line);
|
|
7726
|
+
} catch {
|
|
7727
|
+
}
|
|
7728
|
+
return true;
|
|
7729
|
+
},
|
|
7730
|
+
// Task 1013 — SDK token-event write. Calls streamLog.writeToken which
|
|
7731
|
+
// opens the per-session file lazily on first call (flushing the
|
|
7732
|
+
// pre-token buffer alongside) and appends thereafter. Used by the
|
|
7733
|
+
// SDK event for-await loop so the file exists iff a token was emitted.
|
|
7734
|
+
writeToken(line) {
|
|
7735
|
+
try {
|
|
7736
|
+
sseLogStream.write(line);
|
|
7737
|
+
} catch {
|
|
7738
|
+
}
|
|
7739
|
+
try {
|
|
7740
|
+
streamLog.writeToken(line);
|
|
7722
7741
|
} catch {
|
|
7723
7742
|
}
|
|
7724
7743
|
return true;
|
|
@@ -7763,11 +7782,10 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7763
7782
|
const reqSignal = c.req.raw?.signal;
|
|
7764
7783
|
if (reqSignal) {
|
|
7765
7784
|
reqSignal.addEventListener("abort", () => {
|
|
7766
|
-
const abortStreamLog = agentLogStream("claude-agent-stream", account.accountDir, session_key);
|
|
7767
7785
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
7768
7786
|
sseLog.write(`[${ts}] [${sk}] admin: ABORT [operator-cancel] interrupting pool client
|
|
7769
7787
|
`);
|
|
7770
|
-
interruptClient(session_key
|
|
7788
|
+
interruptClient(session_key).catch((err) => {
|
|
7771
7789
|
sseLog.write(`[${ts}] [${sk}] admin: ABORT [interrupt-failed] ${err instanceof Error ? err.message : String(err)}
|
|
7772
7790
|
`);
|
|
7773
7791
|
});
|
|
@@ -7778,7 +7796,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7778
7796
|
try {
|
|
7779
7797
|
registerAdminSSE(sseEntry);
|
|
7780
7798
|
tailer = startScriptStreamTailer({
|
|
7781
|
-
path:
|
|
7799
|
+
path: streamLog.path,
|
|
7782
7800
|
onEvent: (event) => {
|
|
7783
7801
|
if (!controllerOpen) return;
|
|
7784
7802
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
@@ -7793,7 +7811,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7793
7811
|
}
|
|
7794
7812
|
},
|
|
7795
7813
|
onError: (err) => {
|
|
7796
|
-
console.error(`[script-stream-tailer] ${
|
|
7814
|
+
console.error(`[script-stream-tailer] ${streamLog.path}: ${err.message}`);
|
|
7797
7815
|
}
|
|
7798
7816
|
});
|
|
7799
7817
|
for await (const event of invokeAgent(
|
|
@@ -7806,7 +7824,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7806
7824
|
)) {
|
|
7807
7825
|
const data = JSON.stringify(event);
|
|
7808
7826
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
7809
|
-
sseLog.
|
|
7827
|
+
sseLog.writeToken(`[${ts}] [${sk}] admin: ${data}
|
|
7810
7828
|
`);
|
|
7811
7829
|
controller.enqueue(encoder.encode(`data: ${data}
|
|
7812
7830
|
|
|
@@ -7947,9 +7965,127 @@ app12.post("/", requireAdminSession, async (c) => {
|
|
|
7947
7965
|
});
|
|
7948
7966
|
var chat_failure_default = app12;
|
|
7949
7967
|
|
|
7950
|
-
// server/routes/admin/
|
|
7968
|
+
// server/routes/admin/failure-report.ts
|
|
7969
|
+
var SESSION_KEY_RE = /^sk_[0-9a-f]{16}$/i;
|
|
7970
|
+
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7971
|
+
var ISO_RE2 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
7972
|
+
var SAFE_TOKEN_RE = /^[\w.:-]{1,64}$/;
|
|
7973
|
+
function validate2(body) {
|
|
7974
|
+
const missing = [];
|
|
7975
|
+
if (typeof body.sessionKey !== "string" || !SESSION_KEY_RE.test(body.sessionKey)) missing.push("sessionKey");
|
|
7976
|
+
if (typeof body.conversationId !== "string" || !UUID_RE4.test(body.conversationId)) missing.push("conversationId");
|
|
7977
|
+
if (typeof body.lastUserMessageId !== "string" || !SAFE_TOKEN_RE.test(body.lastUserMessageId)) missing.push("lastUserMessageId");
|
|
7978
|
+
if (typeof body.clickTs !== "string" || !ISO_RE2.test(body.clickTs)) missing.push("clickTs");
|
|
7979
|
+
const snap = body.clientSnapshot;
|
|
7980
|
+
if (!snap || typeof snap !== "object") missing.push("clientSnapshot");
|
|
7981
|
+
if (missing.length > 0) return { ok: false, missing };
|
|
7982
|
+
const snapshot = snap;
|
|
7983
|
+
const lastAssistantMessageId = typeof body.lastAssistantMessageId === "string" && SAFE_TOKEN_RE.test(body.lastAssistantMessageId) ? body.lastAssistantMessageId : "-";
|
|
7984
|
+
const sseReadyState = typeof snapshot.sseReadyState === "string" && SAFE_TOKEN_RE.test(snapshot.sseReadyState) ? snapshot.sseReadyState : typeof snapshot.sseReadyState === "number" ? String(snapshot.sseReadyState) : "-";
|
|
7985
|
+
const lastEventType = typeof snapshot.lastEventType === "string" && SAFE_TOKEN_RE.test(snapshot.lastEventType) ? snapshot.lastEventType : "-";
|
|
7986
|
+
const lastAppliedMessageId = typeof snapshot.lastAppliedMessageId === "string" && SAFE_TOKEN_RE.test(snapshot.lastAppliedMessageId) ? snapshot.lastAppliedMessageId : "-";
|
|
7987
|
+
return {
|
|
7988
|
+
ok: true,
|
|
7989
|
+
value: {
|
|
7990
|
+
sessionKey: body.sessionKey,
|
|
7991
|
+
conversationId: body.conversationId,
|
|
7992
|
+
lastUserMessageId: body.lastUserMessageId,
|
|
7993
|
+
lastAssistantMessageId,
|
|
7994
|
+
clickTs: body.clickTs,
|
|
7995
|
+
sseReadyState,
|
|
7996
|
+
lastEventType,
|
|
7997
|
+
lastAppliedMessageId
|
|
7998
|
+
}
|
|
7999
|
+
};
|
|
8000
|
+
}
|
|
7951
8001
|
var app13 = new Hono();
|
|
7952
8002
|
app13.post("/", requireAdminSession, async (c) => {
|
|
8003
|
+
let body;
|
|
8004
|
+
try {
|
|
8005
|
+
body = await c.req.json();
|
|
8006
|
+
} catch {
|
|
8007
|
+
return c.json({ ok: false, error: "missing-turn-identifiers", missing: ["body-not-json"] }, 400);
|
|
8008
|
+
}
|
|
8009
|
+
const v = validate2(body);
|
|
8010
|
+
if (!v.ok) {
|
|
8011
|
+
return c.json({ ok: false, error: "missing-turn-identifiers", missing: v.missing }, 400);
|
|
8012
|
+
}
|
|
8013
|
+
const cacheKey = c.var.cacheKey;
|
|
8014
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
8015
|
+
if (!accountId) {
|
|
8016
|
+
return c.json({ ok: false, error: "no-account" }, 401);
|
|
8017
|
+
}
|
|
8018
|
+
const line = [
|
|
8019
|
+
`[failure-report] sessionKey=${v.value.sessionKey}`,
|
|
8020
|
+
`conversationId=${v.value.conversationId}`,
|
|
8021
|
+
`userMessageId=${v.value.lastUserMessageId}`,
|
|
8022
|
+
`assistantMessageId=${v.value.lastAssistantMessageId}`,
|
|
8023
|
+
`sseState=${v.value.sseReadyState}`,
|
|
8024
|
+
`lastEventType=${v.value.lastEventType}`,
|
|
8025
|
+
`lastAppliedMessageId=${v.value.lastAppliedMessageId}`,
|
|
8026
|
+
`ts=${v.value.clickTs}`
|
|
8027
|
+
].join(" ");
|
|
8028
|
+
appendStreamLogLine(accountId, v.value.sessionKey, line);
|
|
8029
|
+
return c.json({ ok: true });
|
|
8030
|
+
});
|
|
8031
|
+
var failure_report_default = app13;
|
|
8032
|
+
|
|
8033
|
+
// server/routes/admin/sse-telemetry.ts
|
|
8034
|
+
var SESSION_KEY_RE2 = /^sk_[0-9a-f]{16}$/i;
|
|
8035
|
+
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
8036
|
+
var ISO_RE3 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
8037
|
+
var PHASE_VALUES = /* @__PURE__ */ new Set(["connected", "event_received", "render_complete", "error", "close"]);
|
|
8038
|
+
var SAFE_TOKEN_RE2 = /^[\w.:-]{1,64}$/;
|
|
8039
|
+
function validate3(body) {
|
|
8040
|
+
const missing = [];
|
|
8041
|
+
if (typeof body.sessionKey !== "string" || !SESSION_KEY_RE2.test(body.sessionKey)) missing.push("sessionKey");
|
|
8042
|
+
if (typeof body.conversationId !== "string" || !UUID_RE5.test(body.conversationId)) missing.push("conversationId");
|
|
8043
|
+
if (typeof body.phase !== "string" || !PHASE_VALUES.has(body.phase)) missing.push("phase");
|
|
8044
|
+
if (typeof body.ts !== "string" || !ISO_RE3.test(body.ts)) missing.push("ts");
|
|
8045
|
+
if (missing.length > 0) return { ok: false, missing };
|
|
8046
|
+
const eventType = typeof body.eventType === "string" && SAFE_TOKEN_RE2.test(body.eventType) ? body.eventType : "-";
|
|
8047
|
+
const messageId = typeof body.messageId === "string" && SAFE_TOKEN_RE2.test(body.messageId) ? body.messageId : "-";
|
|
8048
|
+
return {
|
|
8049
|
+
ok: true,
|
|
8050
|
+
value: {
|
|
8051
|
+
sessionKey: body.sessionKey,
|
|
8052
|
+
conversationId: body.conversationId,
|
|
8053
|
+
phase: body.phase,
|
|
8054
|
+
eventType,
|
|
8055
|
+
messageId,
|
|
8056
|
+
ts: body.ts
|
|
8057
|
+
}
|
|
8058
|
+
};
|
|
8059
|
+
}
|
|
8060
|
+
var app14 = new Hono();
|
|
8061
|
+
app14.post("/", requireAdminSession, async (c) => {
|
|
8062
|
+
let body;
|
|
8063
|
+
try {
|
|
8064
|
+
body = await c.req.json();
|
|
8065
|
+
} catch {
|
|
8066
|
+
return c.json({ ok: false, error: "missing-turn-identifiers", missing: ["body-not-json"] }, 400);
|
|
8067
|
+
}
|
|
8068
|
+
const v = validate3(body);
|
|
8069
|
+
if (!v.ok) {
|
|
8070
|
+
return c.json({ ok: false, error: "missing-turn-identifiers", missing: v.missing }, 400);
|
|
8071
|
+
}
|
|
8072
|
+
const cacheKey = c.var.cacheKey;
|
|
8073
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
8074
|
+
if (!accountId) {
|
|
8075
|
+
return c.json({ ok: false, error: "no-account" }, 401);
|
|
8076
|
+
}
|
|
8077
|
+
appendStreamLogLine(
|
|
8078
|
+
accountId,
|
|
8079
|
+
v.value.sessionKey,
|
|
8080
|
+
`[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}`
|
|
8081
|
+
);
|
|
8082
|
+
return c.json({ ok: true });
|
|
8083
|
+
});
|
|
8084
|
+
var sse_telemetry_default = app14;
|
|
8085
|
+
|
|
8086
|
+
// server/routes/admin/compact.ts
|
|
8087
|
+
var app15 = new Hono();
|
|
8088
|
+
app15.post("/", requireAdminSession, async (c) => {
|
|
7953
8089
|
const cacheKey = c.var.cacheKey;
|
|
7954
8090
|
const encoder = new TextEncoder();
|
|
7955
8091
|
const stream = new ReadableStream({
|
|
@@ -7976,11 +8112,11 @@ app13.post("/", requireAdminSession, async (c) => {
|
|
|
7976
8112
|
}
|
|
7977
8113
|
});
|
|
7978
8114
|
});
|
|
7979
|
-
var compact_default =
|
|
8115
|
+
var compact_default = app15;
|
|
7980
8116
|
|
|
7981
8117
|
// server/routes/admin/logs.ts
|
|
7982
8118
|
import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync6 } from "fs";
|
|
7983
|
-
import { resolve as
|
|
8119
|
+
import { resolve as resolve8, basename as basename2 } from "path";
|
|
7984
8120
|
|
|
7985
8121
|
// app/lib/logs-read-resolve.ts
|
|
7986
8122
|
import { existsSync as existsSync12 } from "fs";
|
|
@@ -7999,15 +8135,15 @@ function resolveSessionLogPaths(filename, logDirs) {
|
|
|
7999
8135
|
|
|
8000
8136
|
// server/routes/admin/logs.ts
|
|
8001
8137
|
var TAIL_BYTES = 8192;
|
|
8002
|
-
var
|
|
8003
|
-
|
|
8138
|
+
var app16 = new Hono();
|
|
8139
|
+
app16.get("/", async (c) => {
|
|
8004
8140
|
const fileParam = c.req.query("file");
|
|
8005
8141
|
const typeParam = c.req.query("type");
|
|
8006
8142
|
const conversationIdParam = c.req.query("conversationId");
|
|
8007
8143
|
const cacheKeyParam = c.req.query("cacheKey");
|
|
8008
8144
|
const download = c.req.query("download") === "1";
|
|
8009
8145
|
const account = resolveAccount();
|
|
8010
|
-
const accountLogDir = account ?
|
|
8146
|
+
const accountLogDir = account ? resolve8(account.accountDir, "logs") : null;
|
|
8011
8147
|
const logDirs = [];
|
|
8012
8148
|
if (accountLogDir) logDirs.push(accountLogDir);
|
|
8013
8149
|
logDirs.push(LOG_DIR);
|
|
@@ -8015,7 +8151,7 @@ app14.get("/", async (c) => {
|
|
|
8015
8151
|
const safe = basename2(fileParam);
|
|
8016
8152
|
const searched = [];
|
|
8017
8153
|
for (const dir of logDirs) {
|
|
8018
|
-
const filePath =
|
|
8154
|
+
const filePath = resolve8(dir, safe);
|
|
8019
8155
|
searched.push(filePath);
|
|
8020
8156
|
try {
|
|
8021
8157
|
const buffer = readFileSync11(filePath);
|
|
@@ -8127,10 +8263,10 @@ app14.get("/", async (c) => {
|
|
|
8127
8263
|
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
8128
8264
|
continue;
|
|
8129
8265
|
}
|
|
8130
|
-
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync6(
|
|
8266
|
+
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
8267
|
seen.add(name);
|
|
8132
8268
|
try {
|
|
8133
|
-
const content = readFileSync11(
|
|
8269
|
+
const content = readFileSync11(resolve8(dir, name));
|
|
8134
8270
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
8135
8271
|
logs[name] = tail.trim() || "(empty)";
|
|
8136
8272
|
} catch (err) {
|
|
@@ -8142,12 +8278,12 @@ app14.get("/", async (c) => {
|
|
|
8142
8278
|
}
|
|
8143
8279
|
return c.json({ logs });
|
|
8144
8280
|
});
|
|
8145
|
-
var logs_default =
|
|
8281
|
+
var logs_default = app16;
|
|
8146
8282
|
|
|
8147
8283
|
// server/routes/admin/claude-info.ts
|
|
8148
8284
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
8149
|
-
var
|
|
8150
|
-
|
|
8285
|
+
var app17 = new Hono();
|
|
8286
|
+
app17.get("/", (c) => {
|
|
8151
8287
|
let version = "unknown";
|
|
8152
8288
|
try {
|
|
8153
8289
|
const raw = execFileSync2("claude", ["--version"], { encoding: "utf-8", timeout: 5e3 });
|
|
@@ -8165,14 +8301,14 @@ app15.get("/", (c) => {
|
|
|
8165
8301
|
const thinkingView = resolvedAccount?.config.thinkingView ?? "default";
|
|
8166
8302
|
return c.json({ version, account, model, thinkingView });
|
|
8167
8303
|
});
|
|
8168
|
-
var claude_info_default =
|
|
8304
|
+
var claude_info_default = app17;
|
|
8169
8305
|
|
|
8170
8306
|
// server/routes/admin/attachment.ts
|
|
8171
8307
|
import { readFile as readFile2, readdir } from "fs/promises";
|
|
8172
8308
|
import { existsSync as existsSync14 } from "fs";
|
|
8173
|
-
import { resolve as
|
|
8174
|
-
var
|
|
8175
|
-
|
|
8309
|
+
import { resolve as resolve9 } from "path";
|
|
8310
|
+
var app18 = new Hono();
|
|
8311
|
+
app18.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
8176
8312
|
const attachmentId = c.req.param("attachmentId");
|
|
8177
8313
|
const cacheKey = c.var.cacheKey;
|
|
8178
8314
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -8182,11 +8318,11 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
8182
8318
|
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(attachmentId)) {
|
|
8183
8319
|
return new Response("Not found", { status: 404 });
|
|
8184
8320
|
}
|
|
8185
|
-
const dir =
|
|
8321
|
+
const dir = resolve9(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
8186
8322
|
if (!existsSync14(dir)) {
|
|
8187
8323
|
return new Response("Not found", { status: 404 });
|
|
8188
8324
|
}
|
|
8189
|
-
const metaPath =
|
|
8325
|
+
const metaPath = resolve9(dir, `${attachmentId}.meta.json`);
|
|
8190
8326
|
if (!existsSync14(metaPath)) {
|
|
8191
8327
|
return new Response("Not found", { status: 404 });
|
|
8192
8328
|
}
|
|
@@ -8201,7 +8337,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
8201
8337
|
if (!dataFile) {
|
|
8202
8338
|
return new Response("Not found", { status: 404 });
|
|
8203
8339
|
}
|
|
8204
|
-
const filePath =
|
|
8340
|
+
const filePath = resolve9(dir, dataFile);
|
|
8205
8341
|
const buffer = await readFile2(filePath);
|
|
8206
8342
|
return new Response(new Uint8Array(buffer), {
|
|
8207
8343
|
headers: {
|
|
@@ -8211,16 +8347,16 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
8211
8347
|
}
|
|
8212
8348
|
});
|
|
8213
8349
|
});
|
|
8214
|
-
var attachment_default =
|
|
8350
|
+
var attachment_default = app18;
|
|
8215
8351
|
|
|
8216
8352
|
// server/routes/admin/agents.ts
|
|
8217
|
-
import { resolve as
|
|
8353
|
+
import { resolve as resolve10 } from "path";
|
|
8218
8354
|
import { readdirSync as readdirSync6, readFileSync as readFileSync12, existsSync as existsSync15, rmSync } from "fs";
|
|
8219
|
-
var
|
|
8220
|
-
|
|
8355
|
+
var app19 = new Hono();
|
|
8356
|
+
app19.get("/", (c) => {
|
|
8221
8357
|
const account = resolveAccount();
|
|
8222
8358
|
if (!account) return c.json({ agents: [] });
|
|
8223
|
-
const agentsDir =
|
|
8359
|
+
const agentsDir = resolve10(account.accountDir, "agents");
|
|
8224
8360
|
if (!existsSync15(agentsDir)) return c.json({ agents: [] });
|
|
8225
8361
|
const agents = [];
|
|
8226
8362
|
try {
|
|
@@ -8228,7 +8364,7 @@ app17.get("/", (c) => {
|
|
|
8228
8364
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
8229
8365
|
if (!entry.isDirectory()) continue;
|
|
8230
8366
|
if (entry.name === "admin") continue;
|
|
8231
|
-
const configPath2 =
|
|
8367
|
+
const configPath2 = resolve10(agentsDir, entry.name, "config.json");
|
|
8232
8368
|
if (!existsSync15(configPath2)) continue;
|
|
8233
8369
|
try {
|
|
8234
8370
|
const config = JSON.parse(readFileSync12(configPath2, "utf-8"));
|
|
@@ -8247,7 +8383,7 @@ app17.get("/", (c) => {
|
|
|
8247
8383
|
}
|
|
8248
8384
|
return c.json({ agents });
|
|
8249
8385
|
});
|
|
8250
|
-
|
|
8386
|
+
app19.delete("/:slug", async (c) => {
|
|
8251
8387
|
const slug = c.req.param("slug");
|
|
8252
8388
|
const account = resolveAccount();
|
|
8253
8389
|
if (!account) return c.json({ error: "No account resolved" }, 400);
|
|
@@ -8257,7 +8393,7 @@ app17.delete("/:slug", async (c) => {
|
|
|
8257
8393
|
if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
|
|
8258
8394
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
8259
8395
|
}
|
|
8260
|
-
const agentDir =
|
|
8396
|
+
const agentDir = resolve10(account.accountDir, "agents", slug);
|
|
8261
8397
|
if (!existsSync15(agentDir)) {
|
|
8262
8398
|
return c.json({ error: "Agent not found" }, 404);
|
|
8263
8399
|
}
|
|
@@ -8277,7 +8413,7 @@ app17.delete("/:slug", async (c) => {
|
|
|
8277
8413
|
return c.json({ error: "Failed to delete agent" }, 500);
|
|
8278
8414
|
}
|
|
8279
8415
|
});
|
|
8280
|
-
|
|
8416
|
+
app19.post("/:slug/project", async (c) => {
|
|
8281
8417
|
const slug = c.req.param("slug");
|
|
8282
8418
|
const account = resolveAccount();
|
|
8283
8419
|
if (!account) return c.json({ error: "No account resolved" }, 400);
|
|
@@ -8287,7 +8423,7 @@ app17.post("/:slug/project", async (c) => {
|
|
|
8287
8423
|
if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
|
|
8288
8424
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
8289
8425
|
}
|
|
8290
|
-
const agentDir =
|
|
8426
|
+
const agentDir = resolve10(account.accountDir, "agents", slug);
|
|
8291
8427
|
if (!existsSync15(agentDir)) {
|
|
8292
8428
|
return c.json({ error: "Agent not found on disk" }, 404);
|
|
8293
8429
|
}
|
|
@@ -8299,12 +8435,12 @@ app17.post("/:slug/project", async (c) => {
|
|
|
8299
8435
|
return c.json({ error: `Projection failed: ${msg}` }, 500);
|
|
8300
8436
|
}
|
|
8301
8437
|
});
|
|
8302
|
-
var agents_default =
|
|
8438
|
+
var agents_default = app19;
|
|
8303
8439
|
|
|
8304
8440
|
// server/routes/admin/sessions.ts
|
|
8305
8441
|
import crypto2 from "crypto";
|
|
8306
8442
|
import { resolve as resolvePath } from "path";
|
|
8307
|
-
import {
|
|
8443
|
+
import { existsSync as existsSync17 } from "fs";
|
|
8308
8444
|
|
|
8309
8445
|
// app/lib/synthetic-marker.ts
|
|
8310
8446
|
var CLOUDFLARE_MARKER_PREFIX = "Cloudflare setup completed (actionId: ";
|
|
@@ -8487,7 +8623,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, conversationId
|
|
|
8487
8623
|
if (reason) {
|
|
8488
8624
|
invalid++;
|
|
8489
8625
|
try {
|
|
8490
|
-
|
|
8626
|
+
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
8627
|
`);
|
|
8492
8628
|
} catch {
|
|
8493
8629
|
}
|
|
@@ -8550,7 +8686,7 @@ function reconstructAssistantEvents(content, components, conversationId, message
|
|
|
8550
8686
|
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
8687
|
`;
|
|
8552
8688
|
try {
|
|
8553
|
-
|
|
8689
|
+
streamLogPath.write(line);
|
|
8554
8690
|
} catch {
|
|
8555
8691
|
}
|
|
8556
8692
|
continue;
|
|
@@ -8590,8 +8726,8 @@ function formatAge(updatedAtStr) {
|
|
|
8590
8726
|
return "unknown";
|
|
8591
8727
|
}
|
|
8592
8728
|
}
|
|
8593
|
-
var
|
|
8594
|
-
|
|
8729
|
+
var app20 = new Hono();
|
|
8730
|
+
app20.get("/", requireAdminSession, async (c) => {
|
|
8595
8731
|
const cacheKey = c.var.cacheKey;
|
|
8596
8732
|
const accountId = getAccountIdForSession(cacheKey);
|
|
8597
8733
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -8631,7 +8767,7 @@ app18.get("/", requireAdminSession, async (c) => {
|
|
|
8631
8767
|
return c.json({ error: "Failed to fetch sessions" }, 500);
|
|
8632
8768
|
}
|
|
8633
8769
|
});
|
|
8634
|
-
|
|
8770
|
+
app20.post("/new", requireAdminSession, async (c) => {
|
|
8635
8771
|
const oldCacheKey = c.var.cacheKey;
|
|
8636
8772
|
const accountId = getAccountIdForSession(oldCacheKey);
|
|
8637
8773
|
const userId = getUserIdForSession(oldCacheKey);
|
|
@@ -8647,7 +8783,7 @@ app18.post("/new", requireAdminSession, async (c) => {
|
|
|
8647
8783
|
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
8784
|
return c.json({ session_key: newSignedSessionToken, conversationId: null });
|
|
8649
8785
|
});
|
|
8650
|
-
|
|
8786
|
+
app20.post("/switch", requireAdminSession, async (c) => {
|
|
8651
8787
|
const cacheKey = c.var.cacheKey;
|
|
8652
8788
|
const accountId = getAccountIdForSession(cacheKey);
|
|
8653
8789
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -8675,7 +8811,7 @@ app18.post("/switch", requireAdminSession, async (c) => {
|
|
|
8675
8811
|
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
8812
|
return c.json({ session_key: targetSignedSessionToken, conversationId: targetConversationId });
|
|
8677
8813
|
});
|
|
8678
|
-
|
|
8814
|
+
app20.delete("/:id", requireAdminSession, async (c) => {
|
|
8679
8815
|
const conversationId = c.req.param("id");
|
|
8680
8816
|
const cacheKey = c.var.cacheKey;
|
|
8681
8817
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -8690,7 +8826,7 @@ app18.delete("/:id", requireAdminSession, async (c) => {
|
|
|
8690
8826
|
return c.json({ error: "Failed to delete session" }, 500);
|
|
8691
8827
|
}
|
|
8692
8828
|
});
|
|
8693
|
-
|
|
8829
|
+
app20.post("/:id/resume", async (c) => {
|
|
8694
8830
|
const conversationId = c.req.param("id");
|
|
8695
8831
|
const signedSessionToken = c.req.query("session_key") ?? "";
|
|
8696
8832
|
if (!signedSessionToken) {
|
|
@@ -8740,7 +8876,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8740
8876
|
if (persistedAgentSessionId) {
|
|
8741
8877
|
setAgentSessionId(cacheKey, persistedAgentSessionId);
|
|
8742
8878
|
}
|
|
8743
|
-
const streamLogPath = resolvePath(ACCOUNTS_DIR, accountId,
|
|
8879
|
+
const streamLogPath = getStreamLogHandle(resolvePath(ACCOUNTS_DIR, accountId), cacheKey);
|
|
8744
8880
|
const tag = persistedAgentSessionId ? `agentSessionId=${persistedAgentSessionId.slice(0, 8)}\u2026` : "agentSessionId=missing";
|
|
8745
8881
|
let messages = [];
|
|
8746
8882
|
let neo4jMessages = [];
|
|
@@ -8843,7 +8979,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8843
8979
|
const filename = bytesPick.mimeType === "text/html" ? `${c2.artefactTitle}.html` : `${c2.artefactTitle}.md`;
|
|
8844
8980
|
await storeComponentArtefact(accountId, c2.artefactAttachmentId, bytesPick.mimeType, bytesPick.content, filename);
|
|
8845
8981
|
clearHealPending(accountId, c2.artefactAttachmentId);
|
|
8846
|
-
|
|
8982
|
+
appendFileSync(
|
|
8847
8983
|
streamLogPath,
|
|
8848
8984
|
`[${(/* @__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
8985
|
`
|
|
@@ -8857,7 +8993,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8857
8993
|
} catch (writeErr) {
|
|
8858
8994
|
clearHealPending(accountId, c2.artefactAttachmentId);
|
|
8859
8995
|
const reason2 = writeErr instanceof Error ? writeErr.message : String(writeErr);
|
|
8860
|
-
|
|
8996
|
+
appendFileSync(
|
|
8861
8997
|
streamLogPath,
|
|
8862
8998
|
`[${(/* @__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
8999
|
`
|
|
@@ -8878,14 +9014,14 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8878
9014
|
);
|
|
8879
9015
|
jsonlHealOk += 1;
|
|
8880
9016
|
try {
|
|
8881
|
-
|
|
9017
|
+
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
9018
|
`);
|
|
8883
9019
|
} catch {
|
|
8884
9020
|
}
|
|
8885
9021
|
} catch (err) {
|
|
8886
9022
|
jsonlHealFail += 1;
|
|
8887
9023
|
try {
|
|
8888
|
-
|
|
9024
|
+
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
9025
|
`);
|
|
8890
9026
|
} catch {
|
|
8891
9027
|
}
|
|
@@ -8936,18 +9072,18 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8936
9072
|
const reason = bridged ? "post-restart" : "page-refresh";
|
|
8937
9073
|
try {
|
|
8938
9074
|
const source = jsonlMissing ? persistedAgentSessionId ? "jsonl-missing" : "neo4j-only" : "jsonl";
|
|
8939
|
-
|
|
9075
|
+
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
9076
|
`);
|
|
8941
9077
|
if (totalComponents > 0) {
|
|
8942
|
-
|
|
9078
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [component-rehydrate] conversationId=${conversationId.slice(0, 8)} count=${totalComponents} valid=${totalValid} invalid=${totalInvalid} textRuns=${textRuns}
|
|
8943
9079
|
`);
|
|
8944
9080
|
}
|
|
8945
9081
|
if (totalAttachments > 0 || totalAttachmentInvalid > 0) {
|
|
8946
|
-
|
|
9082
|
+
streamLogPath.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [attachment-rehydrate] conversationId=${conversationId.slice(0, 8)} userMessages=${userMessageCount} attachments=${totalAttachments} invalid=${totalAttachmentInvalid}
|
|
8947
9083
|
`);
|
|
8948
9084
|
}
|
|
8949
9085
|
if (jsonlHealMissing > 0) {
|
|
8950
|
-
|
|
9086
|
+
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
9087
|
`);
|
|
8952
9088
|
}
|
|
8953
9089
|
} catch {
|
|
@@ -8966,7 +9102,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8966
9102
|
}
|
|
8967
9103
|
});
|
|
8968
9104
|
});
|
|
8969
|
-
|
|
9105
|
+
app20.post("/:id/label", requireAdminSession, async (c) => {
|
|
8970
9106
|
const conversationId = c.req.param("id");
|
|
8971
9107
|
const cacheKey = c.var.cacheKey;
|
|
8972
9108
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -8993,7 +9129,7 @@ app18.post("/:id/label", requireAdminSession, async (c) => {
|
|
|
8993
9129
|
return c.json({ label: null });
|
|
8994
9130
|
}
|
|
8995
9131
|
});
|
|
8996
|
-
|
|
9132
|
+
app20.put("/:id/label", requireAdminSession, async (c) => {
|
|
8997
9133
|
const conversationId = c.req.param("id");
|
|
8998
9134
|
const cacheKey = c.var.cacheKey;
|
|
8999
9135
|
let body;
|
|
@@ -9019,11 +9155,11 @@ app18.put("/:id/label", requireAdminSession, async (c) => {
|
|
|
9019
9155
|
return c.json({ error: "Failed to rename session" }, 500);
|
|
9020
9156
|
}
|
|
9021
9157
|
});
|
|
9022
|
-
var sessions_default =
|
|
9158
|
+
var sessions_default = app20;
|
|
9023
9159
|
|
|
9024
9160
|
// server/routes/admin/browser.ts
|
|
9025
|
-
var
|
|
9026
|
-
|
|
9161
|
+
var app21 = new Hono();
|
|
9162
|
+
app21.post("/launch", async (c) => {
|
|
9027
9163
|
try {
|
|
9028
9164
|
const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
|
|
9029
9165
|
if (transport === "vnc") {
|
|
@@ -9045,7 +9181,7 @@ app19.post("/launch", async (c) => {
|
|
|
9045
9181
|
);
|
|
9046
9182
|
}
|
|
9047
9183
|
});
|
|
9048
|
-
var browser_default =
|
|
9184
|
+
var browser_default = app21;
|
|
9049
9185
|
|
|
9050
9186
|
// server/routes/admin/browser-iframe.ts
|
|
9051
9187
|
var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
@@ -9062,8 +9198,8 @@ function asString(v, max = 500) {
|
|
|
9062
9198
|
function asNumber(v) {
|
|
9063
9199
|
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
9064
9200
|
}
|
|
9065
|
-
var
|
|
9066
|
-
|
|
9201
|
+
var app22 = new Hono();
|
|
9202
|
+
app22.post("/event", async (c) => {
|
|
9067
9203
|
let body = {};
|
|
9068
9204
|
try {
|
|
9069
9205
|
body = await c.req.json();
|
|
@@ -9084,7 +9220,7 @@ app20.post("/event", async (c) => {
|
|
|
9084
9220
|
});
|
|
9085
9221
|
return c.body(null, 204);
|
|
9086
9222
|
});
|
|
9087
|
-
var browser_iframe_default =
|
|
9223
|
+
var browser_iframe_default = app22;
|
|
9088
9224
|
|
|
9089
9225
|
// app/lib/cdp-client.ts
|
|
9090
9226
|
var CDP_HOST = "127.0.0.1";
|
|
@@ -9127,8 +9263,8 @@ async function cdpNavigateNewTab(url, opts = {}) {
|
|
|
9127
9263
|
}
|
|
9128
9264
|
|
|
9129
9265
|
// server/routes/admin/device-browser.ts
|
|
9130
|
-
var
|
|
9131
|
-
|
|
9266
|
+
var app23 = new Hono();
|
|
9267
|
+
app23.post("/navigate", async (c) => {
|
|
9132
9268
|
const TAG19 = "[device-url:click]";
|
|
9133
9269
|
let body;
|
|
9134
9270
|
try {
|
|
@@ -9215,7 +9351,7 @@ app21.post("/navigate", async (c) => {
|
|
|
9215
9351
|
targetId: outcome.targetId
|
|
9216
9352
|
});
|
|
9217
9353
|
});
|
|
9218
|
-
var device_browser_default =
|
|
9354
|
+
var device_browser_default = app23;
|
|
9219
9355
|
|
|
9220
9356
|
// server/routes/admin/events.ts
|
|
9221
9357
|
var ALLOWED_EVENTS2 = /* @__PURE__ */ new Set([
|
|
@@ -9224,8 +9360,8 @@ var ALLOWED_EVENTS2 = /* @__PURE__ */ new Set([
|
|
|
9224
9360
|
"device-url:vnc-surface-shown",
|
|
9225
9361
|
"device-url:malformed"
|
|
9226
9362
|
]);
|
|
9227
|
-
var
|
|
9228
|
-
|
|
9363
|
+
var app24 = new Hono();
|
|
9364
|
+
app24.post("/", async (c) => {
|
|
9229
9365
|
const TAG19 = "[admin:events]";
|
|
9230
9366
|
let body;
|
|
9231
9367
|
try {
|
|
@@ -9256,11 +9392,11 @@ app22.post("/", async (c) => {
|
|
|
9256
9392
|
console.error(`[${event}] ${formatted}`);
|
|
9257
9393
|
return c.json({ ok: true });
|
|
9258
9394
|
});
|
|
9259
|
-
var events_default =
|
|
9395
|
+
var events_default = app24;
|
|
9260
9396
|
|
|
9261
9397
|
// server/routes/admin/cloudflare.ts
|
|
9262
9398
|
import { homedir as homedir2 } from "os";
|
|
9263
|
-
import { resolve as
|
|
9399
|
+
import { resolve as resolve12 } from "path";
|
|
9264
9400
|
import { readFileSync as readFileSync15 } from "fs";
|
|
9265
9401
|
|
|
9266
9402
|
// app/lib/dns-label.ts
|
|
@@ -9279,8 +9415,8 @@ function isValidDomain(value) {
|
|
|
9279
9415
|
// app/lib/alias-domains.ts
|
|
9280
9416
|
import { existsSync as existsSync18, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "fs";
|
|
9281
9417
|
import { dirname as dirname5 } from "path";
|
|
9282
|
-
import { resolve as
|
|
9283
|
-
var ALIAS_DOMAINS_PATH =
|
|
9418
|
+
import { resolve as resolve11 } from "path";
|
|
9419
|
+
var ALIAS_DOMAINS_PATH = resolve11(MAXY_DIR, "alias-domains.json");
|
|
9284
9420
|
function readExisting() {
|
|
9285
9421
|
if (!existsSync18(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
|
|
9286
9422
|
try {
|
|
@@ -9333,8 +9469,8 @@ function readDiscoveryResults(accountId) {
|
|
|
9333
9469
|
return { tunnels: entry.tunnels, domains: entry.domains };
|
|
9334
9470
|
}
|
|
9335
9471
|
function loadBrandInfo() {
|
|
9336
|
-
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ??
|
|
9337
|
-
const brandPath =
|
|
9472
|
+
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve12(process.cwd(), "..");
|
|
9473
|
+
const brandPath = resolve12(platformRoot2, "config", "brand.json");
|
|
9338
9474
|
try {
|
|
9339
9475
|
const parsed = JSON.parse(readFileSync15(brandPath, "utf-8"));
|
|
9340
9476
|
const hostname2 = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
|
|
@@ -9399,7 +9535,7 @@ function validateBody(body) {
|
|
|
9399
9535
|
}
|
|
9400
9536
|
return null;
|
|
9401
9537
|
}
|
|
9402
|
-
var
|
|
9538
|
+
var app25 = new Hono();
|
|
9403
9539
|
function fieldFromReason(reason) {
|
|
9404
9540
|
switch (reason) {
|
|
9405
9541
|
case "not-signed-in":
|
|
@@ -9420,7 +9556,7 @@ function fieldFromReason(reason) {
|
|
|
9420
9556
|
return "script";
|
|
9421
9557
|
}
|
|
9422
9558
|
}
|
|
9423
|
-
|
|
9559
|
+
app25.get("/domains", requireAdminSession, async (c) => {
|
|
9424
9560
|
const started = Date.now();
|
|
9425
9561
|
const cacheKey = c.var.cacheKey;
|
|
9426
9562
|
let correlationId;
|
|
@@ -9464,7 +9600,7 @@ app23.get("/domains", requireAdminSession, async (c) => {
|
|
|
9464
9600
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
9465
9601
|
log(`phase=stream-log-resolved path=${streamLogPath}`);
|
|
9466
9602
|
const brand = loadBrandInfo();
|
|
9467
|
-
const scriptPath =
|
|
9603
|
+
const scriptPath = resolve12(homedir2(), "list-cf-domains.sh");
|
|
9468
9604
|
const result = await runFormSpawn({
|
|
9469
9605
|
scriptPath,
|
|
9470
9606
|
args: [brand.hostname],
|
|
@@ -9516,7 +9652,7 @@ ${result.stderr}` : ""}`;
|
|
|
9516
9652
|
return c.json(success, 200);
|
|
9517
9653
|
});
|
|
9518
9654
|
var TUNNELS_TIMEOUT_MS = 30 * 1e3;
|
|
9519
|
-
|
|
9655
|
+
app25.get("/tunnels", requireAdminSession, async (c) => {
|
|
9520
9656
|
const started = Date.now();
|
|
9521
9657
|
const cacheKey = c.var.cacheKey;
|
|
9522
9658
|
let correlationId;
|
|
@@ -9555,7 +9691,7 @@ app23.get("/tunnels", requireAdminSession, async (c) => {
|
|
|
9555
9691
|
if (!accountId) return err("session", "No account bound to session \u2014 refresh chat.");
|
|
9556
9692
|
if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
|
|
9557
9693
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
9558
|
-
const certPath =
|
|
9694
|
+
const certPath = resolve12(homedir2(), brand.configDir, "cloudflared", "cert.pem");
|
|
9559
9695
|
const { existsSync: existsSync26 } = await import("fs");
|
|
9560
9696
|
if (!existsSync26(certPath)) {
|
|
9561
9697
|
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 +9749,7 @@ ${result.stderr}` : ""}`;
|
|
|
9613
9749
|
const success = { ok: true, tunnels, defaultName, correlationId, streamLogPath };
|
|
9614
9750
|
return c.json(success, 200);
|
|
9615
9751
|
});
|
|
9616
|
-
|
|
9752
|
+
app25.post("/setup", requireAdminSession, async (c) => {
|
|
9617
9753
|
const started = Date.now();
|
|
9618
9754
|
const cacheKey = c.var.cacheKey;
|
|
9619
9755
|
let correlationId;
|
|
@@ -9875,23 +10011,23 @@ actionId: ${actionId}`,
|
|
|
9875
10011
|
};
|
|
9876
10012
|
return ok(success);
|
|
9877
10013
|
});
|
|
9878
|
-
var cloudflare_default =
|
|
10014
|
+
var cloudflare_default = app25;
|
|
9879
10015
|
|
|
9880
10016
|
// server/routes/admin/files.ts
|
|
9881
10017
|
import { createReadStream as createReadStream3 } from "fs";
|
|
9882
10018
|
import { readdir as readdir2, readFile as readFile3, stat as stat3, mkdir as mkdir2, writeFile as writeFile3, unlink as unlink2 } from "fs/promises";
|
|
9883
10019
|
import { realpathSync as realpathSync3 } from "fs";
|
|
9884
|
-
import { basename as basename3, dirname as dirname6, join as join10, resolve as
|
|
10020
|
+
import { basename as basename3, dirname as dirname6, join as join10, resolve as resolve14, sep as sep2 } from "path";
|
|
9885
10021
|
import { Readable as Readable2 } from "stream";
|
|
9886
10022
|
|
|
9887
10023
|
// app/lib/data-path.ts
|
|
9888
10024
|
import { realpathSync as realpathSync2 } from "fs";
|
|
9889
|
-
import { resolve as
|
|
9890
|
-
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ??
|
|
9891
|
-
var DATA_ROOT =
|
|
10025
|
+
import { resolve as resolve13, normalize, sep, relative } from "path";
|
|
10026
|
+
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve13(process.cwd(), "../platform");
|
|
10027
|
+
var DATA_ROOT = resolve13(PLATFORM_ROOT5, "..", "data");
|
|
9892
10028
|
function resolveDataPath(raw) {
|
|
9893
10029
|
const cleaned = normalize("/" + (raw ?? "").replace(/\\/g, "/")).replace(/^\/+/, "");
|
|
9894
|
-
const absolute =
|
|
10030
|
+
const absolute = resolve13(DATA_ROOT, cleaned);
|
|
9895
10031
|
let dataRootReal;
|
|
9896
10032
|
try {
|
|
9897
10033
|
dataRootReal = realpathSync2(DATA_ROOT);
|
|
@@ -10156,7 +10292,7 @@ async function restoreNode(params) {
|
|
|
10156
10292
|
}
|
|
10157
10293
|
|
|
10158
10294
|
// app/lib/file-delete-cascade.ts
|
|
10159
|
-
var
|
|
10295
|
+
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
10296
|
function parseAttachmentPath(relPath2) {
|
|
10161
10297
|
const segments = relPath2.split("/").filter(Boolean);
|
|
10162
10298
|
if (segments.length !== 4) return null;
|
|
@@ -10164,7 +10300,7 @@ function parseAttachmentPath(relPath2) {
|
|
|
10164
10300
|
const accountId = segments[1];
|
|
10165
10301
|
const attachmentId = segments[2];
|
|
10166
10302
|
const filename = segments[3];
|
|
10167
|
-
if (!
|
|
10303
|
+
if (!UUID_RE6.test(accountId) || !UUID_RE6.test(attachmentId)) return null;
|
|
10168
10304
|
const dot = filename.lastIndexOf(".");
|
|
10169
10305
|
if (dot === -1) return null;
|
|
10170
10306
|
const stem = filename.slice(0, dot);
|
|
@@ -10236,7 +10372,7 @@ async function cascadeDeleteDocument(params) {
|
|
|
10236
10372
|
}
|
|
10237
10373
|
|
|
10238
10374
|
// server/routes/admin/files.ts
|
|
10239
|
-
var
|
|
10375
|
+
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
10376
|
async function readMeta(absDir, baseName) {
|
|
10241
10377
|
try {
|
|
10242
10378
|
const raw = await readFile3(join10(absDir, `${baseName}.meta.json`), "utf8");
|
|
@@ -10250,7 +10386,7 @@ async function readMeta(absDir, baseName) {
|
|
|
10250
10386
|
}
|
|
10251
10387
|
async function readAccountNames() {
|
|
10252
10388
|
const map = /* @__PURE__ */ new Map();
|
|
10253
|
-
const accountsDir =
|
|
10389
|
+
const accountsDir = resolve14(DATA_ROOT, "accounts");
|
|
10254
10390
|
let names;
|
|
10255
10391
|
try {
|
|
10256
10392
|
names = await readdir2(accountsDir);
|
|
@@ -10258,8 +10394,8 @@ async function readAccountNames() {
|
|
|
10258
10394
|
return map;
|
|
10259
10395
|
}
|
|
10260
10396
|
for (const name of names) {
|
|
10261
|
-
if (!
|
|
10262
|
-
const configPath2 =
|
|
10397
|
+
if (!UUID_RE7.test(name)) continue;
|
|
10398
|
+
const configPath2 = resolve14(accountsDir, name, "account.json");
|
|
10263
10399
|
try {
|
|
10264
10400
|
const raw = await readFile3(configPath2, "utf8");
|
|
10265
10401
|
const parsed = JSON.parse(raw);
|
|
@@ -10276,7 +10412,7 @@ async function readAccountNames() {
|
|
|
10276
10412
|
return map;
|
|
10277
10413
|
}
|
|
10278
10414
|
async function enrich(absolute, entry, accountNames) {
|
|
10279
|
-
if (entry.kind === "directory" &&
|
|
10415
|
+
if (entry.kind === "directory" && UUID_RE7.test(entry.name)) {
|
|
10280
10416
|
const meta = await readMeta(join10(absolute, entry.name), entry.name);
|
|
10281
10417
|
if (meta?.filename) {
|
|
10282
10418
|
entry.displayName = meta.filename;
|
|
@@ -10292,7 +10428,7 @@ async function enrich(absolute, entry, accountNames) {
|
|
|
10292
10428
|
if (entry.kind === "file") {
|
|
10293
10429
|
const dot = entry.name.lastIndexOf(".");
|
|
10294
10430
|
const base = dot === -1 ? entry.name : entry.name.slice(0, dot);
|
|
10295
|
-
if (
|
|
10431
|
+
if (UUID_RE7.test(base)) {
|
|
10296
10432
|
const meta = await readMeta(absolute, base);
|
|
10297
10433
|
if (meta?.filename) {
|
|
10298
10434
|
entry.displayName = meta.filename;
|
|
@@ -10304,12 +10440,12 @@ async function enrich(absolute, entry, accountNames) {
|
|
|
10304
10440
|
function buildDisplayPath(relPath2, accountNames) {
|
|
10305
10441
|
if (relPath2 === "." || relPath2 === "") return [];
|
|
10306
10442
|
return relPath2.split("/").filter(Boolean).map((seg) => {
|
|
10307
|
-
const dn =
|
|
10443
|
+
const dn = UUID_RE7.test(seg) ? accountNames.get(seg) : void 0;
|
|
10308
10444
|
return dn ? { name: seg, displayName: dn } : { name: seg };
|
|
10309
10445
|
});
|
|
10310
10446
|
}
|
|
10311
|
-
var
|
|
10312
|
-
|
|
10447
|
+
var app26 = new Hono();
|
|
10448
|
+
app26.get("/", requireAdminSession, async (c) => {
|
|
10313
10449
|
const cacheKey = c.var.cacheKey;
|
|
10314
10450
|
if (!getAccountIdForSession(cacheKey)) {
|
|
10315
10451
|
console.error(`[data] auth-rejected endpoint="/api/admin/files" reason="no account for session"`);
|
|
@@ -10332,7 +10468,7 @@ app24.get("/", requireAdminSession, async (c) => {
|
|
|
10332
10468
|
const names = await readdir2(absolute);
|
|
10333
10469
|
const entries = [];
|
|
10334
10470
|
for (const name of names) {
|
|
10335
|
-
if (
|
|
10471
|
+
if (UUID_RE7.test(name.replace(/\.meta\.json$/, "")) && name.endsWith(".meta.json")) {
|
|
10336
10472
|
continue;
|
|
10337
10473
|
}
|
|
10338
10474
|
try {
|
|
@@ -10370,7 +10506,7 @@ app24.get("/", requireAdminSession, async (c) => {
|
|
|
10370
10506
|
return c.json({ error: message }, 500);
|
|
10371
10507
|
}
|
|
10372
10508
|
});
|
|
10373
|
-
|
|
10509
|
+
app26.get("/download", requireAdminSession, async (c) => {
|
|
10374
10510
|
const cacheKey = c.var.cacheKey;
|
|
10375
10511
|
if (!getAccountIdForSession(cacheKey)) {
|
|
10376
10512
|
console.error(`[data] auth-rejected endpoint="/api/admin/files/download" reason="no account for session"`);
|
|
@@ -10418,7 +10554,7 @@ app24.get("/download", requireAdminSession, async (c) => {
|
|
|
10418
10554
|
return c.json({ error: message }, 500);
|
|
10419
10555
|
}
|
|
10420
10556
|
});
|
|
10421
|
-
|
|
10557
|
+
app26.post("/upload", requireAdminSession, async (c) => {
|
|
10422
10558
|
const cacheKey = c.var.cacheKey;
|
|
10423
10559
|
const accountId = getAccountIdForSession(cacheKey);
|
|
10424
10560
|
if (!accountId) {
|
|
@@ -10450,8 +10586,8 @@ app24.post("/upload", requireAdminSession, async (c) => {
|
|
|
10450
10586
|
}
|
|
10451
10587
|
const safeName = basename3(file.name).replace(/[\0/\\]/g, "_");
|
|
10452
10588
|
const finalName = `${Date.now()}-${safeName}`;
|
|
10453
|
-
const destDir =
|
|
10454
|
-
const destPath =
|
|
10589
|
+
const destDir = resolve14(DATA_ROOT, "uploads", accountId);
|
|
10590
|
+
const destPath = resolve14(destDir, finalName);
|
|
10455
10591
|
try {
|
|
10456
10592
|
await mkdir2(destDir, { recursive: true });
|
|
10457
10593
|
const dataRootReal = realpathSync3(DATA_ROOT);
|
|
@@ -10476,7 +10612,7 @@ app24.post("/upload", requireAdminSession, async (c) => {
|
|
|
10476
10612
|
mimeType: file.type
|
|
10477
10613
|
});
|
|
10478
10614
|
});
|
|
10479
|
-
|
|
10615
|
+
app26.delete("/", requireAdminSession, async (c) => {
|
|
10480
10616
|
const cacheKey = c.var.cacheKey;
|
|
10481
10617
|
const accountId = getAccountIdForSession(cacheKey);
|
|
10482
10618
|
if (!accountId) {
|
|
@@ -10509,7 +10645,7 @@ app24.delete("/", requireAdminSession, async (c) => {
|
|
|
10509
10645
|
}
|
|
10510
10646
|
const dot = base.lastIndexOf(".");
|
|
10511
10647
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
10512
|
-
const sidecarPath =
|
|
10648
|
+
const sidecarPath = UUID_RE7.test(stem) && base !== `${stem}.meta.json` ? join10(dirname6(absolute), `${stem}.meta.json`) : null;
|
|
10513
10649
|
await unlink2(absolute);
|
|
10514
10650
|
if (sidecarPath) {
|
|
10515
10651
|
try {
|
|
@@ -10543,7 +10679,7 @@ app24.delete("/", requireAdminSession, async (c) => {
|
|
|
10543
10679
|
return c.json({ error: message }, 500);
|
|
10544
10680
|
}
|
|
10545
10681
|
});
|
|
10546
|
-
var files_default =
|
|
10682
|
+
var files_default = app26;
|
|
10547
10683
|
|
|
10548
10684
|
// ../lib/graph-search/src/index.ts
|
|
10549
10685
|
var import_dist = __toESM(require_dist());
|
|
@@ -10923,8 +11059,8 @@ var MAX_LIMIT = 2e3;
|
|
|
10923
11059
|
var DEFAULT_VECTOR_THRESHOLD = 0.82;
|
|
10924
11060
|
var MESSAGE_FAMILY_LABELS = ["Message", "UserMessage", "AssistantMessage", "WhatsAppMessage"];
|
|
10925
11061
|
var CONVERSATION_PARENT_LABELS = /* @__PURE__ */ new Set(["AdminConversation", "PublicConversation"]);
|
|
10926
|
-
var
|
|
10927
|
-
|
|
11062
|
+
var app27 = new Hono();
|
|
11063
|
+
app27.get("/", requireAdminSession, async (c) => {
|
|
10928
11064
|
const cacheKey = c.var.cacheKey;
|
|
10929
11065
|
const q = (c.req.query("q") ?? "").trim();
|
|
10930
11066
|
const rawLimit = c.req.query("limit");
|
|
@@ -11055,7 +11191,7 @@ app25.get("/", requireAdminSession, async (c) => {
|
|
|
11055
11191
|
await session.close();
|
|
11056
11192
|
}
|
|
11057
11193
|
});
|
|
11058
|
-
var graph_search_default =
|
|
11194
|
+
var graph_search_default = app27;
|
|
11059
11195
|
|
|
11060
11196
|
// server/routes/admin/graph-subgraph.ts
|
|
11061
11197
|
import neo4j2 from "neo4j-driver";
|
|
@@ -11213,8 +11349,8 @@ var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
|
|
|
11213
11349
|
"otpCode",
|
|
11214
11350
|
"cacheKey"
|
|
11215
11351
|
]);
|
|
11216
|
-
var
|
|
11217
|
-
|
|
11352
|
+
var app28 = new Hono();
|
|
11353
|
+
app28.get("/", requireAdminSession, async (c) => {
|
|
11218
11354
|
const cacheKey = c.var.cacheKey;
|
|
11219
11355
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11220
11356
|
if (!accountId) {
|
|
@@ -11797,12 +11933,12 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
|
|
|
11797
11933
|
}
|
|
11798
11934
|
return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
|
|
11799
11935
|
}
|
|
11800
|
-
var graph_subgraph_default =
|
|
11936
|
+
var graph_subgraph_default = app28;
|
|
11801
11937
|
|
|
11802
11938
|
// server/routes/admin/graph-delete.ts
|
|
11803
11939
|
var ALLOWED_BY = ["graph-page", "graph-drag-trash"];
|
|
11804
|
-
var
|
|
11805
|
-
|
|
11940
|
+
var app29 = new Hono();
|
|
11941
|
+
app29.post("/", requireAdminSession, async (c) => {
|
|
11806
11942
|
const cacheKey = c.var.cacheKey;
|
|
11807
11943
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11808
11944
|
if (!accountId) {
|
|
@@ -11873,11 +12009,11 @@ app27.post("/", requireAdminSession, async (c) => {
|
|
|
11873
12009
|
}
|
|
11874
12010
|
}
|
|
11875
12011
|
});
|
|
11876
|
-
var graph_delete_default =
|
|
12012
|
+
var graph_delete_default = app29;
|
|
11877
12013
|
|
|
11878
12014
|
// server/routes/admin/graph-restore.ts
|
|
11879
|
-
var
|
|
11880
|
-
|
|
12015
|
+
var app30 = new Hono();
|
|
12016
|
+
app30.post("/", requireAdminSession, async (c) => {
|
|
11881
12017
|
const cacheKey = c.var.cacheKey;
|
|
11882
12018
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11883
12019
|
if (!accountId) {
|
|
@@ -11941,11 +12077,11 @@ app28.post("/", requireAdminSession, async (c) => {
|
|
|
11941
12077
|
}
|
|
11942
12078
|
}
|
|
11943
12079
|
});
|
|
11944
|
-
var graph_restore_default =
|
|
12080
|
+
var graph_restore_default = app30;
|
|
11945
12081
|
|
|
11946
12082
|
// server/routes/admin/graph-labels-in-graph.ts
|
|
11947
|
-
var
|
|
11948
|
-
|
|
12083
|
+
var app31 = new Hono();
|
|
12084
|
+
app31.get("/", requireAdminSession, async (c) => {
|
|
11949
12085
|
const cacheKey = c.var.cacheKey;
|
|
11950
12086
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11951
12087
|
if (!accountId) {
|
|
@@ -12011,11 +12147,11 @@ var LABELS_IN_GRAPH_CYPHER = `
|
|
|
12011
12147
|
sum(halfEdges) AS relDegree
|
|
12012
12148
|
RETURN label, nodeCount, relDegree
|
|
12013
12149
|
`;
|
|
12014
|
-
var graph_labels_in_graph_default =
|
|
12150
|
+
var graph_labels_in_graph_default = app31;
|
|
12015
12151
|
|
|
12016
12152
|
// server/routes/admin/graph-default-view.ts
|
|
12017
|
-
var
|
|
12018
|
-
|
|
12153
|
+
var app32 = new Hono();
|
|
12154
|
+
app32.get("/", requireAdminSession, async (c) => {
|
|
12019
12155
|
const cacheKey = c.var.cacheKey;
|
|
12020
12156
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12021
12157
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -12053,7 +12189,7 @@ app30.get("/", requireAdminSession, async (c) => {
|
|
|
12053
12189
|
}
|
|
12054
12190
|
}
|
|
12055
12191
|
});
|
|
12056
|
-
|
|
12192
|
+
app32.put("/", requireAdminSession, async (c) => {
|
|
12057
12193
|
const cacheKey = c.var.cacheKey;
|
|
12058
12194
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12059
12195
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -12142,11 +12278,11 @@ var WRITE_CYPHER = `
|
|
|
12142
12278
|
p.updatedAt = $updatedAt
|
|
12143
12279
|
RETURN p.labels AS labels
|
|
12144
12280
|
`;
|
|
12145
|
-
var graph_default_view_default =
|
|
12281
|
+
var graph_default_view_default = app32;
|
|
12146
12282
|
|
|
12147
12283
|
// server/routes/admin/file-attach.ts
|
|
12148
|
-
var
|
|
12149
|
-
|
|
12284
|
+
var app33 = new Hono();
|
|
12285
|
+
app33.post("/", async (c) => {
|
|
12150
12286
|
try {
|
|
12151
12287
|
const body = await c.req.json();
|
|
12152
12288
|
const { filePath, accountId } = body;
|
|
@@ -12169,11 +12305,11 @@ app31.post("/", async (c) => {
|
|
|
12169
12305
|
return c.json({ error: message }, 500);
|
|
12170
12306
|
}
|
|
12171
12307
|
});
|
|
12172
|
-
var file_attach_default =
|
|
12308
|
+
var file_attach_default = app33;
|
|
12173
12309
|
|
|
12174
12310
|
// server/routes/admin/adherence.ts
|
|
12175
|
-
var
|
|
12176
|
-
|
|
12311
|
+
var app34 = new Hono();
|
|
12312
|
+
app34.get("/", requireAdminSession, async (c) => {
|
|
12177
12313
|
const agent = c.req.query("agent") ?? "admin";
|
|
12178
12314
|
const includeBlock = c.req.query("block") === "1";
|
|
12179
12315
|
const account = resolveAccount();
|
|
@@ -12194,18 +12330,18 @@ app32.get("/", requireAdminSession, async (c) => {
|
|
|
12194
12330
|
return c.json({ error: "Failed to read adherence ledger", agent }, 500);
|
|
12195
12331
|
}
|
|
12196
12332
|
});
|
|
12197
|
-
var adherence_default =
|
|
12333
|
+
var adherence_default = app34;
|
|
12198
12334
|
|
|
12199
12335
|
// server/routes/admin/sidebar-artefacts.ts
|
|
12200
12336
|
import neo4j3 from "neo4j-driver";
|
|
12201
12337
|
import { readFile as readFile4, readdir as readdir3, stat as stat4 } from "fs/promises";
|
|
12202
|
-
import { resolve as
|
|
12338
|
+
import { resolve as resolve15, relative as relative2, isAbsolute } from "path";
|
|
12203
12339
|
import { existsSync as existsSync19 } from "fs";
|
|
12204
12340
|
var LIMIT = 50;
|
|
12205
12341
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
12206
12342
|
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
12207
|
-
var
|
|
12208
|
-
|
|
12343
|
+
var app35 = new Hono();
|
|
12344
|
+
app35.get("/", requireAdminSession, async (c) => {
|
|
12209
12345
|
const cacheKey = c.var.cacheKey;
|
|
12210
12346
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12211
12347
|
if (!accountId) {
|
|
@@ -12216,7 +12352,7 @@ app33.get("/", requireAdminSession, async (c) => {
|
|
|
12216
12352
|
if (docs === null) {
|
|
12217
12353
|
return c.json({ error: "Failed to load artefacts" }, 500);
|
|
12218
12354
|
}
|
|
12219
|
-
const accountDir =
|
|
12355
|
+
const accountDir = resolve15(ACCOUNTS_DIR, accountId);
|
|
12220
12356
|
const agents = await fetchAgentTemplateRows(accountDir);
|
|
12221
12357
|
const artefacts = [...docs, ...agents].sort(
|
|
12222
12358
|
(a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
|
|
@@ -12279,8 +12415,8 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
|
|
|
12279
12415
|
logSkip(displayName, "non-text-mime", mimeType);
|
|
12280
12416
|
return { content: "", skipReason: "non-text-mime" };
|
|
12281
12417
|
}
|
|
12282
|
-
const accountDir =
|
|
12283
|
-
const dir =
|
|
12418
|
+
const accountDir = resolve15(ATTACHMENTS_ROOT, accountId);
|
|
12419
|
+
const dir = resolve15(accountDir, attachmentId);
|
|
12284
12420
|
try {
|
|
12285
12421
|
validateFilePathInAccount(dir, accountDir);
|
|
12286
12422
|
} catch {
|
|
@@ -12294,7 +12430,7 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
|
|
|
12294
12430
|
logSkip(displayName, "missing-on-disk", mimeType);
|
|
12295
12431
|
return { content: "", skipReason: "missing-on-disk" };
|
|
12296
12432
|
}
|
|
12297
|
-
return { content: await readFile4(
|
|
12433
|
+
return { content: await readFile4(resolve15(dir, dataFile), "utf-8"), skipReason: null };
|
|
12298
12434
|
} catch (err) {
|
|
12299
12435
|
const message = err instanceof Error ? err.message : String(err);
|
|
12300
12436
|
console.error(`[admin/sidebar-artefacts] read-failed attachmentId=${attachmentId.slice(0, 8)} error="${message}"`);
|
|
@@ -12310,8 +12446,8 @@ function logSkip(name, reason, mimeType) {
|
|
|
12310
12446
|
async function fetchAgentTemplateRows(accountDir) {
|
|
12311
12447
|
const rows = [];
|
|
12312
12448
|
for (const filename of ADMIN_AGENT_FILES) {
|
|
12313
|
-
const overridePath =
|
|
12314
|
-
const bundledPath =
|
|
12449
|
+
const overridePath = resolve15(accountDir, "agents", "admin", filename);
|
|
12450
|
+
const bundledPath = resolve15(PLATFORM_ROOT, "templates", "agents", "admin", filename);
|
|
12315
12451
|
const labelStem = filename.replace(/\.md$/, "");
|
|
12316
12452
|
const row = await readAgentTemplateRow({
|
|
12317
12453
|
id: `agent-template:admin:${filename}`,
|
|
@@ -12325,12 +12461,12 @@ async function fetchAgentTemplateRows(accountDir) {
|
|
|
12325
12461
|
});
|
|
12326
12462
|
if (row) rows.push(row);
|
|
12327
12463
|
}
|
|
12328
|
-
const overrideDir =
|
|
12329
|
-
const bundledDir =
|
|
12464
|
+
const overrideDir = resolve15(accountDir, "specialists", "agents");
|
|
12465
|
+
const bundledDir = resolve15(PLATFORM_ROOT, "templates", "specialists", "agents");
|
|
12330
12466
|
const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
|
|
12331
12467
|
for (const filename of specialistNames) {
|
|
12332
|
-
const overridePath =
|
|
12333
|
-
const bundledPath =
|
|
12468
|
+
const overridePath = resolve15(overrideDir, filename);
|
|
12469
|
+
const bundledPath = resolve15(bundledDir, filename);
|
|
12334
12470
|
const row = await readAgentTemplateRow({
|
|
12335
12471
|
id: `agent-template:specialist:${filename}`,
|
|
12336
12472
|
displayName: filename.replace(/\.md$/, ""),
|
|
@@ -12411,16 +12547,16 @@ function isWithin(target, root) {
|
|
|
12411
12547
|
const rel = relative2(root, target);
|
|
12412
12548
|
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
12413
12549
|
}
|
|
12414
|
-
var sidebar_artefacts_default =
|
|
12550
|
+
var sidebar_artefacts_default = app35;
|
|
12415
12551
|
|
|
12416
12552
|
// server/routes/admin/sidebar-artefact-save.ts
|
|
12417
12553
|
import { mkdir as mkdir3, readdir as readdir4, stat as stat5, writeFile as writeFile4 } from "fs/promises";
|
|
12418
|
-
import { resolve as
|
|
12554
|
+
import { resolve as resolve16 } from "path";
|
|
12419
12555
|
import { existsSync as existsSync20 } from "fs";
|
|
12420
12556
|
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
12421
|
-
var
|
|
12422
|
-
var
|
|
12423
|
-
|
|
12557
|
+
var UUID_RE8 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
12558
|
+
var app36 = new Hono();
|
|
12559
|
+
app36.post("/", requireAdminSession, async (c) => {
|
|
12424
12560
|
const cacheKey = c.var.cacheKey;
|
|
12425
12561
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12426
12562
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -12428,7 +12564,7 @@ app34.post("/", requireAdminSession, async (c) => {
|
|
|
12428
12564
|
if (!body || typeof body.id !== "string" || typeof body.content !== "string") {
|
|
12429
12565
|
return c.json({ error: "id and content required" }, 400);
|
|
12430
12566
|
}
|
|
12431
|
-
const accountDir =
|
|
12567
|
+
const accountDir = resolve16(ACCOUNTS_DIR, accountId);
|
|
12432
12568
|
const resolved = await resolveSavePath(body.id, accountId, accountDir);
|
|
12433
12569
|
if (resolved.kind === "heal-race") {
|
|
12434
12570
|
c.header("Retry-After", "2");
|
|
@@ -12473,17 +12609,17 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
12473
12609
|
if (role !== "admin" || !ADMIN_AGENT_FILES2.has(filename)) {
|
|
12474
12610
|
return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
12475
12611
|
}
|
|
12476
|
-
const parent =
|
|
12612
|
+
const parent = resolve16(accountDir, "agents", "admin");
|
|
12477
12613
|
await mkdir3(parent, { recursive: true });
|
|
12478
12614
|
try {
|
|
12479
12615
|
validateFilePathInAccount(parent, accountDir);
|
|
12480
12616
|
} catch {
|
|
12481
12617
|
return { kind: "reject", status: 400, reason: "containment-rejected" };
|
|
12482
12618
|
}
|
|
12483
|
-
return { kind: "admin-template", path:
|
|
12619
|
+
return { kind: "admin-template", path: resolve16(parent, filename) };
|
|
12484
12620
|
}
|
|
12485
|
-
if (
|
|
12486
|
-
const dir =
|
|
12621
|
+
if (UUID_RE8.test(id)) {
|
|
12622
|
+
const dir = resolve16(ATTACHMENTS_ROOT, accountId, id);
|
|
12487
12623
|
if (!existsSync20(dir)) {
|
|
12488
12624
|
const attShort = id.slice(0, 8);
|
|
12489
12625
|
if (isHealPending(accountId, id)) {
|
|
@@ -12516,7 +12652,7 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
12516
12652
|
}
|
|
12517
12653
|
}
|
|
12518
12654
|
try {
|
|
12519
|
-
validateFilePathInAccount(dir,
|
|
12655
|
+
validateFilePathInAccount(dir, resolve16(ATTACHMENTS_ROOT, accountId));
|
|
12520
12656
|
} catch {
|
|
12521
12657
|
return { kind: "reject", status: 400, reason: "containment-rejected" };
|
|
12522
12658
|
}
|
|
@@ -12525,38 +12661,38 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
12525
12661
|
if (!dataFile) {
|
|
12526
12662
|
return { kind: "reject", status: 400, reason: "not-found" };
|
|
12527
12663
|
}
|
|
12528
|
-
return { kind: "knowledge-doc", path:
|
|
12664
|
+
return { kind: "knowledge-doc", path: resolve16(dir, dataFile) };
|
|
12529
12665
|
}
|
|
12530
12666
|
return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
12531
12667
|
}
|
|
12532
12668
|
function relPath(absPath, root) {
|
|
12533
12669
|
return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
|
|
12534
12670
|
}
|
|
12535
|
-
var sidebar_artefact_save_default =
|
|
12671
|
+
var sidebar_artefact_save_default = app36;
|
|
12536
12672
|
|
|
12537
12673
|
// server/routes/admin/sidebar-artefact-content.ts
|
|
12538
12674
|
import { readFile as readFile5, readdir as readdir5 } from "fs/promises";
|
|
12539
12675
|
import { existsSync as existsSync21 } from "fs";
|
|
12540
|
-
import { resolve as
|
|
12541
|
-
var
|
|
12542
|
-
var
|
|
12543
|
-
|
|
12676
|
+
import { resolve as resolve17 } from "path";
|
|
12677
|
+
var UUID_RE9 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
12678
|
+
var app37 = new Hono();
|
|
12679
|
+
app37.get("/", requireAdminSession, async (c) => {
|
|
12544
12680
|
const cacheKey = c.var.cacheKey;
|
|
12545
12681
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12546
12682
|
if (!accountId) return new Response("Unauthorized", { status: 401 });
|
|
12547
12683
|
const id = c.req.query("id") ?? "";
|
|
12548
|
-
if (!
|
|
12684
|
+
if (!UUID_RE9.test(id)) {
|
|
12549
12685
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12550
12686
|
return new Response("Not found", { status: 404 });
|
|
12551
12687
|
}
|
|
12552
|
-
const dir =
|
|
12688
|
+
const dir = resolve17(ATTACHMENTS_ROOT, accountId, id);
|
|
12553
12689
|
if (!existsSync21(dir)) {
|
|
12554
12690
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12555
12691
|
return new Response("Not found", { status: 404 });
|
|
12556
12692
|
}
|
|
12557
12693
|
let meta;
|
|
12558
12694
|
try {
|
|
12559
|
-
meta = JSON.parse(await readFile5(
|
|
12695
|
+
meta = JSON.parse(await readFile5(resolve17(dir, `${id}.meta.json`), "utf-8"));
|
|
12560
12696
|
} catch {
|
|
12561
12697
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12562
12698
|
return new Response("Not found", { status: 404 });
|
|
@@ -12568,7 +12704,7 @@ app35.get("/", requireAdminSession, async (c) => {
|
|
|
12568
12704
|
return new Response("Not found", { status: 404 });
|
|
12569
12705
|
}
|
|
12570
12706
|
const start = Date.now();
|
|
12571
|
-
const buffer = await readFile5(
|
|
12707
|
+
const buffer = await readFile5(resolve17(dir, dataFile));
|
|
12572
12708
|
const ms = Date.now() - start;
|
|
12573
12709
|
console.log(
|
|
12574
12710
|
`[admin/sidebar-artefact-content] account=${accountId} id=${id.slice(0, 8)} mime=${meta.mimeType} bytes=${buffer.length} ms=${ms}`
|
|
@@ -12581,12 +12717,12 @@ app35.get("/", requireAdminSession, async (c) => {
|
|
|
12581
12717
|
}
|
|
12582
12718
|
});
|
|
12583
12719
|
});
|
|
12584
|
-
var sidebar_artefact_content_default =
|
|
12720
|
+
var sidebar_artefact_content_default = app37;
|
|
12585
12721
|
|
|
12586
12722
|
// server/routes/admin/health.ts
|
|
12587
12723
|
import { existsSync as existsSync22, readFileSync as readFileSync16 } from "fs";
|
|
12588
|
-
import { resolve as
|
|
12589
|
-
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ??
|
|
12724
|
+
import { resolve as resolve18, join as join11 } from "path";
|
|
12725
|
+
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
|
|
12590
12726
|
var brandHostname = "maxy";
|
|
12591
12727
|
var brandJsonPath = join11(PLATFORM_ROOT6, "config", "brand.json");
|
|
12592
12728
|
if (existsSync22(brandJsonPath)) {
|
|
@@ -12596,7 +12732,7 @@ if (existsSync22(brandJsonPath)) {
|
|
|
12596
12732
|
} catch {
|
|
12597
12733
|
}
|
|
12598
12734
|
}
|
|
12599
|
-
var VERSION_FILE =
|
|
12735
|
+
var VERSION_FILE = resolve18(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
|
|
12600
12736
|
var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
12601
12737
|
var PROBE_TIMEOUT_MS = 1e3;
|
|
12602
12738
|
function readVersion() {
|
|
@@ -12626,8 +12762,8 @@ async function probeConversationDb() {
|
|
|
12626
12762
|
});
|
|
12627
12763
|
}
|
|
12628
12764
|
}
|
|
12629
|
-
var
|
|
12630
|
-
|
|
12765
|
+
var app38 = new Hono();
|
|
12766
|
+
app38.get("/", async (c) => {
|
|
12631
12767
|
const version = readVersion();
|
|
12632
12768
|
const probe = await probeConversationDb();
|
|
12633
12769
|
const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
|
|
@@ -12649,42 +12785,44 @@ app36.get("/", async (c) => {
|
|
|
12649
12785
|
uptimeMs
|
|
12650
12786
|
});
|
|
12651
12787
|
});
|
|
12652
|
-
var health_default2 =
|
|
12788
|
+
var health_default2 = app38;
|
|
12653
12789
|
|
|
12654
12790
|
// 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
|
-
|
|
12791
|
+
var app39 = new Hono();
|
|
12792
|
+
app39.route("/session", session_default2);
|
|
12793
|
+
app39.route("/chat", chat_default2);
|
|
12794
|
+
app39.route("/chat-failure", chat_failure_default);
|
|
12795
|
+
app39.route("/failure-report", failure_report_default);
|
|
12796
|
+
app39.route("/sse-telemetry", sse_telemetry_default);
|
|
12797
|
+
app39.route("/compact", compact_default);
|
|
12798
|
+
app39.route("/logs", logs_default);
|
|
12799
|
+
app39.route("/claude-info", claude_info_default);
|
|
12800
|
+
app39.route("/attachment", attachment_default);
|
|
12801
|
+
app39.route("/agents", agents_default);
|
|
12802
|
+
app39.route("/sessions", sessions_default);
|
|
12803
|
+
app39.route("/browser", browser_default);
|
|
12804
|
+
app39.route("/browser-iframe", browser_iframe_default);
|
|
12805
|
+
app39.route("/device-browser", device_browser_default);
|
|
12806
|
+
app39.route("/events", events_default);
|
|
12807
|
+
app39.route("/cloudflare", cloudflare_default);
|
|
12808
|
+
app39.route("/files", files_default);
|
|
12809
|
+
app39.route("/graph-search", graph_search_default);
|
|
12810
|
+
app39.route("/graph-subgraph", graph_subgraph_default);
|
|
12811
|
+
app39.route("/graph-delete", graph_delete_default);
|
|
12812
|
+
app39.route("/graph-restore", graph_restore_default);
|
|
12813
|
+
app39.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
12814
|
+
app39.route("/graph-default-view", graph_default_view_default);
|
|
12815
|
+
app39.route("/file-attach", file_attach_default);
|
|
12816
|
+
app39.route("/adherence", adherence_default);
|
|
12817
|
+
app39.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
12818
|
+
app39.route("/sidebar-artefact-save", sidebar_artefact_save_default);
|
|
12819
|
+
app39.route("/sidebar-artefact-content", sidebar_artefact_content_default);
|
|
12820
|
+
app39.route("/health-brand", health_default2);
|
|
12821
|
+
var admin_default = app39;
|
|
12684
12822
|
|
|
12685
12823
|
// server/routes/sites.ts
|
|
12686
12824
|
import { existsSync as existsSync23, readFileSync as readFileSync17, realpathSync as realpathSync4, statSync as statSync7 } from "fs";
|
|
12687
|
-
import { resolve as
|
|
12825
|
+
import { resolve as resolve19 } from "path";
|
|
12688
12826
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
12689
12827
|
var MIME = {
|
|
12690
12828
|
".html": "text/html; charset=utf-8",
|
|
@@ -12715,8 +12853,8 @@ function getExt(p) {
|
|
|
12715
12853
|
if (idx < p.lastIndexOf("/")) return "";
|
|
12716
12854
|
return p.slice(idx).toLowerCase();
|
|
12717
12855
|
}
|
|
12718
|
-
var
|
|
12719
|
-
|
|
12856
|
+
var app40 = new Hono();
|
|
12857
|
+
app40.get("/:rel{.*}", (c) => {
|
|
12720
12858
|
const reqPath = c.req.path;
|
|
12721
12859
|
const rawRel = c.req.param("rel") ?? "";
|
|
12722
12860
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -12741,8 +12879,8 @@ app38.get("/:rel{.*}", (c) => {
|
|
|
12741
12879
|
}
|
|
12742
12880
|
segments.push(seg);
|
|
12743
12881
|
}
|
|
12744
|
-
const rootDir =
|
|
12745
|
-
let filePath = segments.length === 0 ? rootDir :
|
|
12882
|
+
const rootDir = resolve19(account.accountDir, "sites");
|
|
12883
|
+
let filePath = segments.length === 0 ? rootDir : resolve19(rootDir, ...segments);
|
|
12746
12884
|
if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
|
|
12747
12885
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
12748
12886
|
return c.text("Forbidden", 403);
|
|
@@ -12762,7 +12900,7 @@ app38.get("/:rel{.*}", (c) => {
|
|
|
12762
12900
|
return c.redirect(target, 301);
|
|
12763
12901
|
}
|
|
12764
12902
|
if (stat6?.isDirectory()) {
|
|
12765
|
-
filePath =
|
|
12903
|
+
filePath = resolve19(filePath, "index.html");
|
|
12766
12904
|
}
|
|
12767
12905
|
if (!filePath.startsWith(rootDir + "/")) {
|
|
12768
12906
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
@@ -12819,7 +12957,7 @@ app38.get("/:rel{.*}", (c) => {
|
|
|
12819
12957
|
"X-Content-Type-Options": "nosniff"
|
|
12820
12958
|
});
|
|
12821
12959
|
});
|
|
12822
|
-
var sites_default =
|
|
12960
|
+
var sites_default = app40;
|
|
12823
12961
|
|
|
12824
12962
|
// app/lib/graph-health.ts
|
|
12825
12963
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -12937,7 +13075,7 @@ function startGraphHealthTimer() {
|
|
|
12937
13075
|
// ../lib/entitlement/src/index.ts
|
|
12938
13076
|
import { createPublicKey, createHash as createHash3, verify as cryptoVerify } from "crypto";
|
|
12939
13077
|
import { existsSync as existsSync24, readFileSync as readFileSync18, statSync as statSync8 } from "fs";
|
|
12940
|
-
import { resolve as
|
|
13078
|
+
import { resolve as resolve20 } from "path";
|
|
12941
13079
|
|
|
12942
13080
|
// ../lib/entitlement/src/canonicalize.ts
|
|
12943
13081
|
function canonicalize(value) {
|
|
@@ -12972,7 +13110,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
|
|
|
12972
13110
|
var GRACE_DAYS = 7;
|
|
12973
13111
|
var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
|
|
12974
13112
|
function pubkeyPath(brand) {
|
|
12975
|
-
return
|
|
13113
|
+
return resolve20(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
|
|
12976
13114
|
}
|
|
12977
13115
|
var memo = null;
|
|
12978
13116
|
function memoKey(mtimeMs, account) {
|
|
@@ -12984,7 +13122,7 @@ function resolveEntitlement(brand, account) {
|
|
|
12984
13122
|
if (brand.commercialMode !== true) {
|
|
12985
13123
|
return logResolved(implicitTrust(account), null);
|
|
12986
13124
|
}
|
|
12987
|
-
const entitlementPath =
|
|
13125
|
+
const entitlementPath = resolve20(brand.configDir, "entitlement.json");
|
|
12988
13126
|
if (!existsSync24(entitlementPath)) {
|
|
12989
13127
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
12990
13128
|
}
|
|
@@ -13229,9 +13367,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
13229
13367
|
function isPublicHost(host) {
|
|
13230
13368
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
13231
13369
|
}
|
|
13232
|
-
var
|
|
13233
|
-
|
|
13234
|
-
|
|
13370
|
+
var app41 = new Hono();
|
|
13371
|
+
app41.use("*", clientIpMiddleware);
|
|
13372
|
+
app41.use("*", async (c, next) => {
|
|
13235
13373
|
await next();
|
|
13236
13374
|
c.header("X-Content-Type-Options", "nosniff");
|
|
13237
13375
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -13241,7 +13379,7 @@ app39.use("*", async (c, next) => {
|
|
|
13241
13379
|
);
|
|
13242
13380
|
});
|
|
13243
13381
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
13244
|
-
|
|
13382
|
+
app41.use("*", async (c, next) => {
|
|
13245
13383
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
13246
13384
|
await next();
|
|
13247
13385
|
return;
|
|
@@ -13274,7 +13412,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
13274
13412
|
"/sites/"
|
|
13275
13413
|
];
|
|
13276
13414
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
13277
|
-
|
|
13415
|
+
app41.use("*", async (c, next) => {
|
|
13278
13416
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13279
13417
|
if (!isPublicHost(host)) {
|
|
13280
13418
|
await next();
|
|
@@ -13314,7 +13452,7 @@ function resolveRemoteAuthOpts() {
|
|
|
13314
13452
|
return brandLoginOpts;
|
|
13315
13453
|
}
|
|
13316
13454
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
13317
|
-
|
|
13455
|
+
app41.post("/__remote-auth/login", async (c) => {
|
|
13318
13456
|
const client = clientFrom(c);
|
|
13319
13457
|
const clientIp = client.ip || "unknown";
|
|
13320
13458
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -13359,7 +13497,7 @@ app39.post("/__remote-auth/login", async (c) => {
|
|
|
13359
13497
|
}
|
|
13360
13498
|
});
|
|
13361
13499
|
});
|
|
13362
|
-
|
|
13500
|
+
app41.get("/__remote-auth/logout", (c) => {
|
|
13363
13501
|
const client = clientFrom(c);
|
|
13364
13502
|
const clientIp = client.ip || "unknown";
|
|
13365
13503
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -13372,7 +13510,7 @@ app39.get("/__remote-auth/logout", (c) => {
|
|
|
13372
13510
|
}
|
|
13373
13511
|
});
|
|
13374
13512
|
});
|
|
13375
|
-
|
|
13513
|
+
app41.post("/__remote-auth/change-password", async (c) => {
|
|
13376
13514
|
const client = clientFrom(c);
|
|
13377
13515
|
const clientIp = client.ip || "unknown";
|
|
13378
13516
|
const rateLimited = checkRateLimit(client);
|
|
@@ -13423,13 +13561,13 @@ app39.post("/__remote-auth/change-password", async (c) => {
|
|
|
13423
13561
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
13424
13562
|
}
|
|
13425
13563
|
});
|
|
13426
|
-
|
|
13564
|
+
app41.get("/__remote-auth/setup", (c) => {
|
|
13427
13565
|
if (isRemoteAuthConfigured()) {
|
|
13428
13566
|
return c.redirect("/");
|
|
13429
13567
|
}
|
|
13430
13568
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
13431
13569
|
});
|
|
13432
|
-
|
|
13570
|
+
app41.post("/__remote-auth/set-initial-password", async (c) => {
|
|
13433
13571
|
if (isRemoteAuthConfigured()) {
|
|
13434
13572
|
return c.redirect("/");
|
|
13435
13573
|
}
|
|
@@ -13467,10 +13605,10 @@ app39.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
13467
13605
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
13468
13606
|
}
|
|
13469
13607
|
});
|
|
13470
|
-
|
|
13608
|
+
app41.get("/api/remote-auth/status", (c) => {
|
|
13471
13609
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
13472
13610
|
});
|
|
13473
|
-
|
|
13611
|
+
app41.post("/api/remote-auth/set-password", async (c) => {
|
|
13474
13612
|
let body;
|
|
13475
13613
|
try {
|
|
13476
13614
|
body = await c.req.json();
|
|
@@ -13501,9 +13639,9 @@ app39.post("/api/remote-auth/set-password", async (c) => {
|
|
|
13501
13639
|
return c.json({ error: "Failed to save password" }, 500);
|
|
13502
13640
|
}
|
|
13503
13641
|
});
|
|
13504
|
-
|
|
13642
|
+
app41.route("/api/_client-error", client_error_default);
|
|
13505
13643
|
console.log("[client-error-route] mounted");
|
|
13506
|
-
|
|
13644
|
+
app41.use("*", async (c, next) => {
|
|
13507
13645
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13508
13646
|
const path2 = c.req.path;
|
|
13509
13647
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -13543,15 +13681,15 @@ app39.use("*", async (c, next) => {
|
|
|
13543
13681
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
13544
13682
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
13545
13683
|
});
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13684
|
+
app41.route("/api/health", health_default);
|
|
13685
|
+
app41.route("/api/session", session_default);
|
|
13686
|
+
app41.route("/api/chat", chat_default);
|
|
13687
|
+
app41.route("/api/group", group_default);
|
|
13688
|
+
app41.route("/api/access", access_default);
|
|
13689
|
+
app41.route("/api/telegram", telegram_default);
|
|
13690
|
+
app41.route("/api/whatsapp", whatsapp_default);
|
|
13691
|
+
app41.route("/api/onboarding", onboarding_default);
|
|
13692
|
+
app41.route("/api/admin", admin_default);
|
|
13555
13693
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
13556
13694
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
13557
13695
|
var IMAGE_MIME = {
|
|
@@ -13563,7 +13701,7 @@ var IMAGE_MIME = {
|
|
|
13563
13701
|
".svg": "image/svg+xml",
|
|
13564
13702
|
".ico": "image/x-icon"
|
|
13565
13703
|
};
|
|
13566
|
-
|
|
13704
|
+
app41.get("/agent-assets/:slug/:filename", (c) => {
|
|
13567
13705
|
const slug = c.req.param("slug");
|
|
13568
13706
|
const filename = c.req.param("filename");
|
|
13569
13707
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -13579,8 +13717,8 @@ app39.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
13579
13717
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
13580
13718
|
return c.text("Not found", 404);
|
|
13581
13719
|
}
|
|
13582
|
-
const filePath =
|
|
13583
|
-
const expectedDir =
|
|
13720
|
+
const filePath = resolve21(account.accountDir, "agents", slug, "assets", filename);
|
|
13721
|
+
const expectedDir = resolve21(account.accountDir, "agents", slug, "assets");
|
|
13584
13722
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
13585
13723
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
13586
13724
|
return c.text("Forbidden", 403);
|
|
@@ -13598,7 +13736,7 @@ app39.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
13598
13736
|
"Cache-Control": "public, max-age=3600"
|
|
13599
13737
|
});
|
|
13600
13738
|
});
|
|
13601
|
-
|
|
13739
|
+
app41.get("/generated/:filename", (c) => {
|
|
13602
13740
|
const filename = c.req.param("filename");
|
|
13603
13741
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
13604
13742
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -13609,8 +13747,8 @@ app39.get("/generated/:filename", (c) => {
|
|
|
13609
13747
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
13610
13748
|
return c.text("Not found", 404);
|
|
13611
13749
|
}
|
|
13612
|
-
const filePath =
|
|
13613
|
-
const expectedDir =
|
|
13750
|
+
const filePath = resolve21(account.accountDir, "generated", filename);
|
|
13751
|
+
const expectedDir = resolve21(account.accountDir, "generated");
|
|
13614
13752
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
13615
13753
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
13616
13754
|
return c.text("Forbidden", 403);
|
|
@@ -13628,7 +13766,7 @@ app39.get("/generated/:filename", (c) => {
|
|
|
13628
13766
|
"Cache-Control": "public, max-age=86400"
|
|
13629
13767
|
});
|
|
13630
13768
|
});
|
|
13631
|
-
|
|
13769
|
+
app41.route("/sites", sites_default);
|
|
13632
13770
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
13633
13771
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
13634
13772
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -13694,7 +13832,7 @@ var clientErrorReporterScript = `<script>
|
|
|
13694
13832
|
function cachedHtml(file) {
|
|
13695
13833
|
let html = htmlCache.get(file);
|
|
13696
13834
|
if (!html) {
|
|
13697
|
-
html = readFileSync19(
|
|
13835
|
+
html = readFileSync19(resolve21(process.cwd(), "public", file), "utf-8");
|
|
13698
13836
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
13699
13837
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
13700
13838
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -13765,7 +13903,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
13765
13903
|
function escapeHtml(s) {
|
|
13766
13904
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
13767
13905
|
}
|
|
13768
|
-
|
|
13906
|
+
app41.get("/", (c) => {
|
|
13769
13907
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13770
13908
|
if (isPublicHost(host)) {
|
|
13771
13909
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -13773,12 +13911,12 @@ app39.get("/", (c) => {
|
|
|
13773
13911
|
}
|
|
13774
13912
|
return c.html(cachedHtml("index.html"));
|
|
13775
13913
|
});
|
|
13776
|
-
|
|
13914
|
+
app41.get("/public", (c) => {
|
|
13777
13915
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13778
13916
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13779
13917
|
return c.html(cachedHtml("public.html"));
|
|
13780
13918
|
});
|
|
13781
|
-
|
|
13919
|
+
app41.get("/chat", (c) => {
|
|
13782
13920
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13783
13921
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13784
13922
|
return c.html(cachedHtml("public.html"));
|
|
@@ -13797,12 +13935,12 @@ async function logViewerFetch(c, next) {
|
|
|
13797
13935
|
duration_ms: Date.now() - start
|
|
13798
13936
|
});
|
|
13799
13937
|
}
|
|
13800
|
-
|
|
13801
|
-
|
|
13802
|
-
|
|
13938
|
+
app41.use("/vnc-viewer.html", logViewerFetch);
|
|
13939
|
+
app41.use("/vnc-popout.html", logViewerFetch);
|
|
13940
|
+
app41.get("/vnc-popout.html", (c) => {
|
|
13803
13941
|
let html = htmlCache.get("vnc-popout.html");
|
|
13804
13942
|
if (!html) {
|
|
13805
|
-
html = readFileSync19(
|
|
13943
|
+
html = readFileSync19(resolve21(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
13806
13944
|
const name = escapeHtml(BRAND.productName);
|
|
13807
13945
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
13808
13946
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -13812,7 +13950,7 @@ app39.get("/vnc-popout.html", (c) => {
|
|
|
13812
13950
|
}
|
|
13813
13951
|
return c.html(html);
|
|
13814
13952
|
});
|
|
13815
|
-
|
|
13953
|
+
app41.post("/api/vnc/client-event", async (c) => {
|
|
13816
13954
|
let body;
|
|
13817
13955
|
try {
|
|
13818
13956
|
body = await c.req.json();
|
|
@@ -13833,20 +13971,20 @@ app39.post("/api/vnc/client-event", async (c) => {
|
|
|
13833
13971
|
});
|
|
13834
13972
|
return c.json({ ok: true });
|
|
13835
13973
|
});
|
|
13836
|
-
|
|
13974
|
+
app41.get("/g/:slug", (c) => {
|
|
13837
13975
|
return c.html(brandedPublicHtml());
|
|
13838
13976
|
});
|
|
13839
|
-
|
|
13977
|
+
app41.get("/graph", (c) => {
|
|
13840
13978
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13841
13979
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13842
13980
|
return c.html(cachedHtml("graph.html"));
|
|
13843
13981
|
});
|
|
13844
|
-
|
|
13982
|
+
app41.get("/data", (c) => {
|
|
13845
13983
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13846
13984
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13847
13985
|
return c.html(cachedHtml("data.html"));
|
|
13848
13986
|
});
|
|
13849
|
-
|
|
13987
|
+
app41.get("/:slug", async (c, next) => {
|
|
13850
13988
|
const slug = c.req.param("slug");
|
|
13851
13989
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
13852
13990
|
const branding = loadBrandingCache(slug);
|
|
@@ -13856,15 +13994,15 @@ app39.get("/:slug", async (c, next) => {
|
|
|
13856
13994
|
await next();
|
|
13857
13995
|
});
|
|
13858
13996
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
13859
|
-
|
|
13997
|
+
app41.get("/favicon.ico", (c) => {
|
|
13860
13998
|
c.header("Cache-Control", "public, max-age=300");
|
|
13861
13999
|
return c.redirect(brandFaviconPath, 302);
|
|
13862
14000
|
});
|
|
13863
14001
|
}
|
|
13864
|
-
|
|
14002
|
+
app41.use("/*", serveStatic({ root: "./public" }));
|
|
13865
14003
|
var port = parseInt(process.env.MAXY_UI_INTERNAL_PORT ?? process.env.PORT ?? "19199", 10);
|
|
13866
14004
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
13867
|
-
var httpServer = serve({ fetch:
|
|
14005
|
+
var httpServer = serve({ fetch: app41.fetch, port, hostname });
|
|
13868
14006
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
13869
14007
|
console.log("[boot] auth-mode summary: oauth=8 api-key=1 (api-key consumer: invokePublicAgent only)");
|
|
13870
14008
|
var SUBAPP_MANIFEST = [
|
|
@@ -13885,7 +14023,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
13885
14023
|
}
|
|
13886
14024
|
try {
|
|
13887
14025
|
const registered = [];
|
|
13888
|
-
for (const r of
|
|
14026
|
+
for (const r of app41.routes ?? []) {
|
|
13889
14027
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
13890
14028
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
13891
14029
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -13993,7 +14131,7 @@ reconcileEnabledPlugins(bootAccount?.accountDir, bootAccount?.config);
|
|
|
13993
14131
|
(async () => {
|
|
13994
14132
|
if (!bootAccount) return;
|
|
13995
14133
|
try {
|
|
13996
|
-
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-
|
|
14134
|
+
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-KCIUQYB5.js");
|
|
13997
14135
|
const result = await recoverRunningCloudflareTasks(
|
|
13998
14136
|
bootAccount.accountId,
|
|
13999
14137
|
configDirForWhatsApp,
|
|
@@ -14053,7 +14191,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
14053
14191
|
}
|
|
14054
14192
|
init({
|
|
14055
14193
|
configDir: configDirForWhatsApp,
|
|
14056
|
-
platformRoot:
|
|
14194
|
+
platformRoot: resolve21(process.env.MAXY_PLATFORM_ROOT ?? join12(__dirname, "..")),
|
|
14057
14195
|
accountConfig: bootAccountConfig,
|
|
14058
14196
|
onMessage: async (msg) => {
|
|
14059
14197
|
try {
|