@rubytech/create-maxy 1.0.888 → 1.0.890

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