@rubytech/create-maxy 1.0.889 → 1.0.891

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