@rubytech/create-maxy 1.0.765 → 1.0.766

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.
@@ -606,8 +606,8 @@ var serveStatic = (options = { root: "" }) => {
606
606
  };
607
607
 
608
608
  // server/index.ts
609
- import { readFileSync as readFileSync16, existsSync as existsSync20, watchFile } from "fs";
610
- import { resolve as resolve21, join as join10, basename as basename7 } from "path";
609
+ import { readFileSync as readFileSync16, existsSync as existsSync22, watchFile } from "fs";
610
+ import { resolve as resolve23, join as join10, basename as basename7 } from "path";
611
611
  import { homedir as homedir2 } from "os";
612
612
 
613
613
  // app/lib/agent-slug-pattern.ts
@@ -1351,9 +1351,9 @@ function discoverAllSources(configDir2, accountLogDir2) {
1351
1351
  }
1352
1352
  function readNewLines(filepath, prev) {
1353
1353
  if (!existsSync3(filepath)) return null;
1354
- const stat6 = statSync3(filepath);
1355
- const size = stat6.size;
1356
- const inode = stat6.ino;
1354
+ const stat7 = statSync3(filepath);
1355
+ const size = stat7.size;
1356
+ const inode = stat7.ino;
1357
1357
  let startOffset = 0;
1358
1358
  let rotated = false;
1359
1359
  let truncated = false;
@@ -2692,7 +2692,7 @@ var credsSaveQueue = Promise.resolve();
2692
2692
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
2693
2693
  console.error(`${TAG3} draining credential save queue\u2026`);
2694
2694
  const timer2 = new Promise(
2695
- (resolve22) => setTimeout(() => resolve22("timeout"), timeoutMs)
2695
+ (resolve24) => setTimeout(() => resolve24("timeout"), timeoutMs)
2696
2696
  );
2697
2697
  const result = await Promise.race([
2698
2698
  credsSaveQueue.then(() => "drained"),
@@ -2820,11 +2820,11 @@ async function createWaSocket(opts) {
2820
2820
  return sock;
2821
2821
  }
2822
2822
  async function waitForConnection(sock) {
2823
- return new Promise((resolve22, reject) => {
2823
+ return new Promise((resolve24, reject) => {
2824
2824
  const handler = (update) => {
2825
2825
  if (update.connection === "open") {
2826
2826
  sock.ev.off("connection.update", handler);
2827
- resolve22();
2827
+ resolve24();
2828
2828
  }
2829
2829
  if (update.connection === "close") {
2830
2830
  sock.ev.off("connection.update", handler);
@@ -2938,14 +2938,14 @@ ${inspected}`;
2938
2938
  return inspect2(err, INSPECT_OPTS2);
2939
2939
  }
2940
2940
  function withTimeout(label, promise, timeoutMs) {
2941
- return new Promise((resolve22, reject) => {
2941
+ return new Promise((resolve24, reject) => {
2942
2942
  const timer2 = setTimeout(() => {
2943
2943
  reject(new Error(`${label} timed out after ${timeoutMs}ms`));
2944
2944
  }, timeoutMs);
2945
2945
  promise.then(
2946
2946
  (value) => {
2947
2947
  clearTimeout(timer2);
2948
- resolve22(value);
2948
+ resolve24(value);
2949
2949
  },
2950
2950
  (err) => {
2951
2951
  clearTimeout(timer2);
@@ -4159,11 +4159,11 @@ async function connectWithReconnect(conn) {
4159
4159
  console.error(
4160
4160
  `${TAG11} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
4161
4161
  );
4162
- await new Promise((resolve22) => {
4163
- const timer2 = setTimeout(resolve22, delay);
4162
+ await new Promise((resolve24) => {
4163
+ const timer2 = setTimeout(resolve24, delay);
4164
4164
  conn.abortController.signal.addEventListener("abort", () => {
4165
4165
  clearTimeout(timer2);
4166
- resolve22();
4166
+ resolve24();
4167
4167
  }, { once: true });
4168
4168
  });
4169
4169
  }
@@ -4171,16 +4171,16 @@ async function connectWithReconnect(conn) {
4171
4171
  }
4172
4172
  }
4173
4173
  function waitForDisconnectEvent(conn) {
4174
- return new Promise((resolve22) => {
4174
+ return new Promise((resolve24) => {
4175
4175
  if (!conn.sock) {
4176
- resolve22();
4176
+ resolve24();
4177
4177
  return;
4178
4178
  }
4179
4179
  const sock = conn.sock;
4180
4180
  const handler = (update) => {
4181
4181
  if (update.connection === "close") {
4182
4182
  sock.ev.off("connection.update", handler);
4183
- resolve22();
4183
+ resolve24();
4184
4184
  }
4185
4185
  };
4186
4186
  sock.ev.on("connection.update", handler);
@@ -4397,8 +4397,8 @@ async function handleInboundMessage(conn, msg) {
4397
4397
  const conversationKey = isGroup ? remoteJid : senderPhone;
4398
4398
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
4399
4399
  let resolvePending;
4400
- const sttPending = new Promise((resolve22) => {
4401
- resolvePending = resolve22;
4400
+ const sttPending = new Promise((resolve24) => {
4401
+ resolvePending = resolve24;
4402
4402
  });
4403
4403
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
4404
4404
  try {
@@ -4511,20 +4511,20 @@ async function probeApiKey() {
4511
4511
  return result.status;
4512
4512
  }
4513
4513
  function checkPort(port2, timeoutMs = 500) {
4514
- return new Promise((resolve22) => {
4514
+ return new Promise((resolve24) => {
4515
4515
  const socket = createConnection(port2, "127.0.0.1");
4516
4516
  socket.setTimeout(timeoutMs);
4517
4517
  socket.once("connect", () => {
4518
4518
  socket.destroy();
4519
- resolve22(true);
4519
+ resolve24(true);
4520
4520
  });
4521
4521
  socket.once("error", () => {
4522
4522
  socket.destroy();
4523
- resolve22(false);
4523
+ resolve24(false);
4524
4524
  });
4525
4525
  socket.once("timeout", () => {
4526
4526
  socket.destroy();
4527
- resolve22(false);
4527
+ resolve24(false);
4528
4528
  });
4529
4529
  });
4530
4530
  }
@@ -6734,8 +6734,8 @@ async function startLogin(opts) {
6734
6734
  resetActiveLogin(accountId);
6735
6735
  let resolveQr = null;
6736
6736
  let rejectQr = null;
6737
- const qrPromise = new Promise((resolve22, reject) => {
6738
- resolveQr = resolve22;
6737
+ const qrPromise = new Promise((resolve24, reject) => {
6738
+ resolveQr = resolve24;
6739
6739
  rejectQr = reject;
6740
6740
  });
6741
6741
  const qrTimer = setTimeout(
@@ -9697,8 +9697,8 @@ function resolveDataPath(raw) {
9697
9697
  if (resolvedReal !== dataRootReal && !resolvedReal.startsWith(dataRootReal + sep)) {
9698
9698
  return { ok: false, status: 403, error: "Path escapes DATA_ROOT", resolved: resolvedReal };
9699
9699
  }
9700
- const relPath = relative(dataRootReal, resolvedReal) || ".";
9701
- return { ok: true, absolute: resolvedReal, dataRootReal, relative: relPath };
9700
+ const relPath2 = relative(dataRootReal, resolvedReal) || ".";
9701
+ return { ok: true, absolute: resolvedReal, dataRootReal, relative: relPath2 };
9702
9702
  }
9703
9703
 
9704
9704
  // ../lib/graph-trash/src/index.ts
@@ -9932,8 +9932,8 @@ async function restoreNode(params) {
9932
9932
 
9933
9933
  // app/lib/file-delete-cascade.ts
9934
9934
  var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9935
- function parseAttachmentPath(relPath) {
9936
- const segments = relPath.split("/").filter(Boolean);
9935
+ function parseAttachmentPath(relPath2) {
9936
+ const segments = relPath2.split("/").filter(Boolean);
9937
9937
  if (segments.length !== 4) return null;
9938
9938
  if (segments[0] !== "uploads") return null;
9939
9939
  const accountId = segments[1];
@@ -10076,9 +10076,9 @@ async function enrich(absolute, entry, accountNames) {
10076
10076
  }
10077
10077
  }
10078
10078
  }
10079
- function buildDisplayPath(relPath, accountNames) {
10080
- if (relPath === "." || relPath === "") return [];
10081
- return relPath.split("/").filter(Boolean).map((seg) => {
10079
+ function buildDisplayPath(relPath2, accountNames) {
10080
+ if (relPath2 === "." || relPath2 === "") return [];
10081
+ return relPath2.split("/").filter(Boolean).map((seg) => {
10082
10082
  const dn = UUID_RE3.test(seg) ? accountNames.get(seg) : void 0;
10083
10083
  return dn ? { name: seg, displayName: dn } : { name: seg };
10084
10084
  });
@@ -10098,7 +10098,7 @@ app22.get("/", requireAdminSession, async (c) => {
10098
10098
  }
10099
10099
  return c.json({ error: resolution.error }, resolution.status);
10100
10100
  }
10101
- const { absolute, relative: relPath } = resolution;
10101
+ const { absolute, relative: relPath2 } = resolution;
10102
10102
  try {
10103
10103
  const info = await stat4(absolute);
10104
10104
  if (!info.isDirectory()) {
@@ -10131,17 +10131,17 @@ app22.get("/", requireAdminSession, async (c) => {
10131
10131
  const bKey = b.displayName ?? b.name;
10132
10132
  return aKey.localeCompare(bKey);
10133
10133
  });
10134
- const displayPath = buildDisplayPath(relPath, accountNames);
10135
- console.error(`[data] file-list path="${relPath}" entries=${entries.length}`);
10136
- return c.json({ path: relPath, displayPath, entries });
10134
+ const displayPath = buildDisplayPath(relPath2, accountNames);
10135
+ console.error(`[data] file-list path="${relPath2}" entries=${entries.length}`);
10136
+ return c.json({ path: relPath2, displayPath, entries });
10137
10137
  } catch (err) {
10138
10138
  const code = err.code;
10139
10139
  if (code === "ENOENT") {
10140
- console.error(`[data] file-list not-found path="${relPath}"`);
10140
+ console.error(`[data] file-list not-found path="${relPath2}"`);
10141
10141
  return c.json({ error: "Not found" }, 404);
10142
10142
  }
10143
10143
  const message = err instanceof Error ? err.message : String(err);
10144
- console.error(`[data] file-list error path="${relPath}" err="${message}"`);
10144
+ console.error(`[data] file-list error path="${relPath2}" err="${message}"`);
10145
10145
  return c.json({ error: message }, 500);
10146
10146
  }
10147
10147
  });
@@ -10160,7 +10160,7 @@ app22.get("/download", requireAdminSession, async (c) => {
10160
10160
  }
10161
10161
  return c.json({ error: resolution.error }, resolution.status);
10162
10162
  }
10163
- const { absolute, relative: relPath } = resolution;
10163
+ const { absolute, relative: relPath2 } = resolution;
10164
10164
  try {
10165
10165
  const info = await stat4(absolute);
10166
10166
  if (!info.isFile()) {
@@ -10170,7 +10170,7 @@ app22.get("/download", requireAdminSession, async (c) => {
10170
10170
  const mimeType = detectMimeType(absolute);
10171
10171
  const nodeStream = createReadStream3(absolute);
10172
10172
  const webStream = Readable2.toWeb(nodeStream);
10173
- console.error(`[data] file-download path="${relPath}" size=${info.size}`);
10173
+ console.error(`[data] file-download path="${relPath2}" size=${info.size}`);
10174
10174
  const safeQuotedName = filename.replace(/[\r\n"\\]/g, "_");
10175
10175
  const encodedName = encodeURIComponent(filename);
10176
10176
  return new Response(webStream, {
@@ -10185,11 +10185,11 @@ app22.get("/download", requireAdminSession, async (c) => {
10185
10185
  } catch (err) {
10186
10186
  const code = err.code;
10187
10187
  if (code === "ENOENT") {
10188
- console.error(`[data] file-download not-found path="${relPath}"`);
10188
+ console.error(`[data] file-download not-found path="${relPath2}"`);
10189
10189
  return c.json({ error: "Not found" }, 404);
10190
10190
  }
10191
10191
  const message = err instanceof Error ? err.message : String(err);
10192
- console.error(`[data] file-download error path="${relPath}" err="${message}"`);
10192
+ console.error(`[data] file-download error path="${relPath2}" err="${message}"`);
10193
10193
  return c.json({ error: message }, 500);
10194
10194
  }
10195
10195
  });
@@ -10267,11 +10267,11 @@ app22.delete("/", requireAdminSession, async (c) => {
10267
10267
  }
10268
10268
  return c.json({ error: resolution.error }, resolution.status);
10269
10269
  }
10270
- const { absolute, relative: relPath } = resolution;
10270
+ const { absolute, relative: relPath2 } = resolution;
10271
10271
  const base = basename6(absolute);
10272
- const segments = relPath.split("/").filter(Boolean);
10272
+ const segments = relPath2.split("/").filter(Boolean);
10273
10273
  if (base === "account.json" || segments.includes(".git")) {
10274
- console.error(`[data] file-delete blocked path="${relPath}" reason="protected"`);
10274
+ console.error(`[data] file-delete blocked path="${relPath2}" reason="protected"`);
10275
10275
  return c.json({ error: "Protected file \u2014 refusing to delete" }, 403);
10276
10276
  }
10277
10277
  try {
@@ -10292,29 +10292,29 @@ app22.delete("/", requireAdminSession, async (c) => {
10292
10292
  } catch {
10293
10293
  }
10294
10294
  }
10295
- console.error(`[data] file-delete path="${relPath}" bytes=${info.size}`);
10296
- const parsed = parseAttachmentPath(relPath);
10295
+ console.error(`[data] file-delete path="${relPath2}" bytes=${info.size}`);
10296
+ const parsed = parseAttachmentPath(relPath2);
10297
10297
  if (parsed) {
10298
10298
  try {
10299
10299
  const { nodes } = await cascadeDeleteDocument({
10300
10300
  accountId,
10301
10301
  attachmentId: parsed.attachmentId
10302
10302
  });
10303
- console.error(`[data] file-delete graph-cascade path="${relPath}" nodes=${nodes}`);
10303
+ console.error(`[data] file-delete graph-cascade path="${relPath2}" nodes=${nodes}`);
10304
10304
  } catch (err) {
10305
10305
  const message = err instanceof Error ? err.message : String(err);
10306
- console.error(`[data] file-delete graph-cascade-failed path="${relPath}" err="${message}"`);
10306
+ console.error(`[data] file-delete graph-cascade-failed path="${relPath2}" err="${message}"`);
10307
10307
  }
10308
10308
  }
10309
10309
  return c.json({ ok: true });
10310
10310
  } catch (err) {
10311
10311
  const code = err.code;
10312
10312
  if (code === "ENOENT") {
10313
- console.error(`[data] file-delete not-found path="${relPath}"`);
10313
+ console.error(`[data] file-delete not-found path="${relPath2}"`);
10314
10314
  return c.json({ error: "Not found" }, 404);
10315
10315
  }
10316
10316
  const message = err instanceof Error ? err.message : String(err);
10317
- console.error(`[data] file-delete error path="${relPath}" err="${message}"`);
10317
+ console.error(`[data] file-delete error path="${relPath2}" err="${message}"`);
10318
10318
  return c.json({ error: message }, 500);
10319
10319
  }
10320
10320
  });
@@ -11769,32 +11769,57 @@ async function fetchKnowledgeDocs(accountId) {
11769
11769
  await session.close();
11770
11770
  }
11771
11771
  return Promise.all(metas.map(async (m) => {
11772
- const content = await readArtefactContent(accountId, m.attachmentId, m.mimeType);
11773
- return { id: m.id, name: m.name, kind: "knowledge-doc", updatedAt: m.updatedAt, content };
11772
+ const { content, skipReason } = await readArtefactContent(accountId, m.attachmentId, m.mimeType, m.name);
11773
+ return {
11774
+ id: m.id,
11775
+ name: m.name,
11776
+ kind: "knowledge-doc",
11777
+ updatedAt: m.updatedAt,
11778
+ content,
11779
+ editable: skipReason === null,
11780
+ mimeType: m.mimeType,
11781
+ skipReason
11782
+ };
11774
11783
  }));
11775
11784
  }
11776
- async function readArtefactContent(accountId, attachmentId, mimeType) {
11777
- if (!attachmentId) return "";
11785
+ async function readArtefactContent(accountId, attachmentId, mimeType, displayName) {
11786
+ if (!attachmentId) {
11787
+ logSkip(displayName, "null-attachmentId", mimeType);
11788
+ return { content: "", skipReason: "null-attachmentId" };
11789
+ }
11778
11790
  const isText = TEXT_MIME_PREFIXES.some((p) => mimeType.startsWith(p));
11779
- if (!isText) return "";
11791
+ if (!isText) {
11792
+ logSkip(displayName, "non-text-mime", mimeType);
11793
+ return { content: "", skipReason: "non-text-mime" };
11794
+ }
11780
11795
  const accountDir = resolve20(ATTACHMENTS_ROOT, accountId);
11781
11796
  const dir = resolve20(accountDir, attachmentId);
11782
11797
  try {
11783
11798
  validateFilePathInAccount(dir, accountDir);
11784
11799
  } catch {
11785
- return "";
11800
+ logSkip(displayName, "containment-rejected", mimeType);
11801
+ return { content: "", skipReason: "containment-rejected" };
11786
11802
  }
11787
11803
  try {
11788
11804
  const entries = await readdir3(dir);
11789
11805
  const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
11790
- if (!dataFile) return "";
11791
- return await readFile5(resolve20(dir, dataFile), "utf-8");
11806
+ if (!dataFile) {
11807
+ logSkip(displayName, "missing-on-disk", mimeType);
11808
+ return { content: "", skipReason: "missing-on-disk" };
11809
+ }
11810
+ return { content: await readFile5(resolve20(dir, dataFile), "utf-8"), skipReason: null };
11792
11811
  } catch (err) {
11793
11812
  const message = err instanceof Error ? err.message : String(err);
11794
11813
  console.error(`[admin/sidebar-artefacts] read-failed attachmentId=${attachmentId.slice(0, 8)} error="${message}"`);
11795
- return "";
11814
+ logSkip(displayName, "missing-on-disk", mimeType);
11815
+ return { content: "", skipReason: "missing-on-disk" };
11796
11816
  }
11797
11817
  }
11818
+ function logSkip(name, reason, mimeType) {
11819
+ console.log(
11820
+ `[admin/sidebar-artefacts] content-skipped name="${name}" reason=${reason} mimeType=${mimeType || "none"}`
11821
+ );
11822
+ }
11798
11823
  async function fetchAgentTemplateRows(accountDir) {
11799
11824
  const rows = [];
11800
11825
  for (const filename of ADMIN_AGENT_FILES) {
@@ -11808,7 +11833,8 @@ async function fetchAgentTemplateRows(accountDir) {
11808
11833
  overridePath,
11809
11834
  overrideRoot: accountDir,
11810
11835
  bundledPath,
11811
- bundledRoot: PLATFORM_ROOT
11836
+ bundledRoot: PLATFORM_ROOT,
11837
+ editable: true
11812
11838
  });
11813
11839
  if (row) rows.push(row);
11814
11840
  }
@@ -11825,7 +11851,8 @@ async function fetchAgentTemplateRows(accountDir) {
11825
11851
  overridePath,
11826
11852
  overrideRoot: accountDir,
11827
11853
  bundledPath,
11828
- bundledRoot: PLATFORM_ROOT
11854
+ bundledRoot: PLATFORM_ROOT,
11855
+ editable: false
11829
11856
  });
11830
11857
  if (row) rows.push(row);
11831
11858
  }
@@ -11880,7 +11907,10 @@ async function readAgentTemplateRow(inp) {
11880
11907
  name: inp.displayName,
11881
11908
  kind: "agent-template",
11882
11909
  updatedAt: st.mtime.toISOString(),
11883
- content
11910
+ content,
11911
+ editable: inp.editable,
11912
+ mimeType: "text/markdown",
11913
+ skipReason: null
11884
11914
  };
11885
11915
  } catch (err) {
11886
11916
  const message = err instanceof Error ? err.message : String(err);
@@ -11896,32 +11926,172 @@ function isWithin(target, root) {
11896
11926
  }
11897
11927
  var sidebar_artefacts_default = app32;
11898
11928
 
11899
- // server/routes/admin/index.ts
11929
+ // server/routes/admin/sidebar-artefact-save.ts
11930
+ import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
11931
+ import { resolve as resolve21 } from "path";
11932
+ import { existsSync as existsSync20 } from "fs";
11933
+ var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
11934
+ var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
11900
11935
  var app33 = new Hono();
11901
- app33.route("/session", session_default2);
11902
- app33.route("/chat", chat_default2);
11903
- app33.route("/compact", compact_default);
11904
- app33.route("/logs", logs_default);
11905
- app33.route("/claude-info", claude_info_default);
11906
- app33.route("/attachment", attachment_default);
11907
- app33.route("/agents", agents_default);
11908
- app33.route("/sessions", sessions_default);
11909
- app33.route("/browser", browser_default);
11910
- app33.route("/device-browser", device_browser_default);
11911
- app33.route("/events", events_default);
11912
- app33.route("/cloudflare", cloudflare_default);
11913
- app33.route("/files", files_default);
11914
- app33.route("/graph-search", graph_search_default);
11915
- app33.route("/graph-subgraph", graph_subgraph_default);
11916
- app33.route("/graph-delete", graph_delete_default);
11917
- app33.route("/graph-restore", graph_restore_default);
11918
- app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
11919
- app33.route("/graph-default-view", graph_default_view_default);
11920
- app33.route("/file-attach", file_attach_default);
11921
- app33.route("/adherence", adherence_default);
11922
- app33.route("/sidebar-projects", sidebar_projects_default);
11923
- app33.route("/sidebar-artefacts", sidebar_artefacts_default);
11924
- var admin_default = app33;
11936
+ app33.post("/", requireAdminSession, async (c) => {
11937
+ const sessionKey = c.var.sessionKey;
11938
+ const accountId = getAccountIdForSession(sessionKey);
11939
+ if (!accountId) return c.json({ error: "Account not found for session" }, 401);
11940
+ const body = await safeJson(c);
11941
+ if (!body || typeof body.id !== "string" || typeof body.content !== "string") {
11942
+ return c.json({ error: "id and content required" }, 400);
11943
+ }
11944
+ const accountDir = resolve21(ACCOUNTS_DIR, accountId);
11945
+ const resolved = await resolveSavePath(body.id, accountId, accountDir);
11946
+ if (resolved.kind === "reject") {
11947
+ console.error(
11948
+ `[admin/sidebar-artefact-save] auth-rejected reason=${resolved.reason} path=${body.id}`
11949
+ );
11950
+ return c.json({ error: resolved.reason }, resolved.status);
11951
+ }
11952
+ const start = Date.now();
11953
+ try {
11954
+ await writeFile5(resolved.path, body.content, "utf-8");
11955
+ } catch (err) {
11956
+ const message = err instanceof Error ? err.message : String(err);
11957
+ console.error(
11958
+ `[admin/sidebar-artefact-save] write-failed path=${relPath(resolved.path, accountDir)} error="${message}"`
11959
+ );
11960
+ return c.json({ error: "Write failed" }, 500);
11961
+ }
11962
+ let updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11963
+ try {
11964
+ const st = await stat6(resolved.path);
11965
+ updatedAt = st.mtime.toISOString();
11966
+ } catch {
11967
+ }
11968
+ const ms = Date.now() - start;
11969
+ console.log(
11970
+ `[admin/sidebar-artefact-save] account=${accountId} path=${relPath(resolved.path, accountDir)} bytes=${body.content.length} ms=${ms}`
11971
+ );
11972
+ return c.json({ updatedAt });
11973
+ });
11974
+ async function resolveSavePath(id, accountId, accountDir) {
11975
+ if (id.startsWith("agent-template:")) {
11976
+ const parts = id.split(":");
11977
+ if (parts.length !== 3) return { kind: "reject", status: 400, reason: "invalid-id" };
11978
+ const [, role, filename] = parts;
11979
+ if (role === "specialist") {
11980
+ return { kind: "reject", status: 403, reason: "specialist-write-blocked" };
11981
+ }
11982
+ if (role !== "admin" || !ADMIN_AGENT_FILES2.has(filename)) {
11983
+ return { kind: "reject", status: 400, reason: "invalid-id" };
11984
+ }
11985
+ const parent = resolve21(accountDir, "agents", "admin");
11986
+ await mkdir4(parent, { recursive: true });
11987
+ try {
11988
+ validateFilePathInAccount(parent, accountDir);
11989
+ } catch {
11990
+ return { kind: "reject", status: 400, reason: "containment-rejected" };
11991
+ }
11992
+ return { kind: "admin-template", path: resolve21(parent, filename) };
11993
+ }
11994
+ if (UUID_RE4.test(id)) {
11995
+ const dir = resolve21(ATTACHMENTS_ROOT, accountId, id);
11996
+ if (!existsSync20(dir)) {
11997
+ return { kind: "reject", status: 400, reason: "not-found" };
11998
+ }
11999
+ try {
12000
+ validateFilePathInAccount(dir, resolve21(ATTACHMENTS_ROOT, accountId));
12001
+ } catch {
12002
+ return { kind: "reject", status: 400, reason: "containment-rejected" };
12003
+ }
12004
+ const entries = await readdir4(dir);
12005
+ const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
12006
+ if (!dataFile) {
12007
+ return { kind: "reject", status: 400, reason: "not-found" };
12008
+ }
12009
+ return { kind: "knowledge-doc", path: resolve21(dir, dataFile) };
12010
+ }
12011
+ return { kind: "reject", status: 400, reason: "invalid-id" };
12012
+ }
12013
+ function relPath(absPath, root) {
12014
+ return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
12015
+ }
12016
+ var sidebar_artefact_save_default = app33;
12017
+
12018
+ // server/routes/admin/sidebar-artefact-content.ts
12019
+ import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
12020
+ import { existsSync as existsSync21 } from "fs";
12021
+ import { resolve as resolve22 } from "path";
12022
+ var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
12023
+ var app34 = new Hono();
12024
+ app34.get("/", requireAdminSession, async (c) => {
12025
+ const sessionKey = c.var.sessionKey;
12026
+ const accountId = getAccountIdForSession(sessionKey);
12027
+ if (!accountId) return new Response("Unauthorized", { status: 401 });
12028
+ const id = c.req.query("id") ?? "";
12029
+ if (!UUID_RE5.test(id)) {
12030
+ console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
12031
+ return new Response("Not found", { status: 404 });
12032
+ }
12033
+ const dir = resolve22(ATTACHMENTS_ROOT, accountId, id);
12034
+ if (!existsSync21(dir)) {
12035
+ console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
12036
+ return new Response("Not found", { status: 404 });
12037
+ }
12038
+ let meta;
12039
+ try {
12040
+ meta = JSON.parse(await readFile6(resolve22(dir, `${id}.meta.json`), "utf-8"));
12041
+ } catch {
12042
+ console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
12043
+ return new Response("Not found", { status: 404 });
12044
+ }
12045
+ const entries = await readdir5(dir);
12046
+ const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
12047
+ if (!dataFile) {
12048
+ console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
12049
+ return new Response("Not found", { status: 404 });
12050
+ }
12051
+ const start = Date.now();
12052
+ const buffer = await readFile6(resolve22(dir, dataFile));
12053
+ const ms = Date.now() - start;
12054
+ console.log(
12055
+ `[admin/sidebar-artefact-content] account=${accountId} id=${id.slice(0, 8)} mime=${meta.mimeType} bytes=${buffer.length} ms=${ms}`
12056
+ );
12057
+ return new Response(new Uint8Array(buffer), {
12058
+ headers: {
12059
+ "Content-Type": meta.mimeType,
12060
+ "Content-Disposition": `inline; filename="${meta.filename}"`,
12061
+ "Cache-Control": "private, max-age=3600"
12062
+ }
12063
+ });
12064
+ });
12065
+ var sidebar_artefact_content_default = app34;
12066
+
12067
+ // server/routes/admin/index.ts
12068
+ var app35 = new Hono();
12069
+ app35.route("/session", session_default2);
12070
+ app35.route("/chat", chat_default2);
12071
+ app35.route("/compact", compact_default);
12072
+ app35.route("/logs", logs_default);
12073
+ app35.route("/claude-info", claude_info_default);
12074
+ app35.route("/attachment", attachment_default);
12075
+ app35.route("/agents", agents_default);
12076
+ app35.route("/sessions", sessions_default);
12077
+ app35.route("/browser", browser_default);
12078
+ app35.route("/device-browser", device_browser_default);
12079
+ app35.route("/events", events_default);
12080
+ app35.route("/cloudflare", cloudflare_default);
12081
+ app35.route("/files", files_default);
12082
+ app35.route("/graph-search", graph_search_default);
12083
+ app35.route("/graph-subgraph", graph_subgraph_default);
12084
+ app35.route("/graph-delete", graph_delete_default);
12085
+ app35.route("/graph-restore", graph_restore_default);
12086
+ app35.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12087
+ app35.route("/graph-default-view", graph_default_view_default);
12088
+ app35.route("/file-attach", file_attach_default);
12089
+ app35.route("/adherence", adherence_default);
12090
+ app35.route("/sidebar-projects", sidebar_projects_default);
12091
+ app35.route("/sidebar-artefacts", sidebar_artefacts_default);
12092
+ app35.route("/sidebar-artefact-save", sidebar_artefact_save_default);
12093
+ app35.route("/sidebar-artefact-content", sidebar_artefact_content_default);
12094
+ var admin_default = app35;
11925
12095
 
11926
12096
  // app/lib/graph-health.ts
11927
12097
  var HOUR_MS = 60 * 60 * 1e3;
@@ -12023,10 +12193,10 @@ function clientFrom(c) {
12023
12193
  var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT || "";
12024
12194
  var BRAND_JSON_PATH = PLATFORM_ROOT7 ? join10(PLATFORM_ROOT7, "config", "brand.json") : "";
12025
12195
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
12026
- if (BRAND_JSON_PATH && !existsSync20(BRAND_JSON_PATH)) {
12196
+ if (BRAND_JSON_PATH && !existsSync22(BRAND_JSON_PATH)) {
12027
12197
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
12028
12198
  }
12029
- if (BRAND_JSON_PATH && existsSync20(BRAND_JSON_PATH)) {
12199
+ if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
12030
12200
  try {
12031
12201
  const parsed = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
12032
12202
  BRAND = { ...BRAND, ...parsed };
@@ -12050,7 +12220,7 @@ var brandLoginOpts = {
12050
12220
  var ALIAS_DOMAINS_PATH2 = join10(homedir2(), BRAND.configDir, "alias-domains.json");
12051
12221
  function loadAliasDomains() {
12052
12222
  try {
12053
- if (!existsSync20(ALIAS_DOMAINS_PATH2)) return null;
12223
+ if (!existsSync22(ALIAS_DOMAINS_PATH2)) return null;
12054
12224
  const parsed = JSON.parse(readFileSync16(ALIAS_DOMAINS_PATH2, "utf-8"));
12055
12225
  if (!Array.isArray(parsed)) {
12056
12226
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
@@ -12075,9 +12245,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
12075
12245
  function isPublicHost(host) {
12076
12246
  return host.startsWith("public.") || aliasDomains.has(host);
12077
12247
  }
12078
- var app34 = new Hono();
12079
- app34.use("*", clientIpMiddleware);
12080
- app34.use("*", async (c, next) => {
12248
+ var app36 = new Hono();
12249
+ app36.use("*", clientIpMiddleware);
12250
+ app36.use("*", async (c, next) => {
12081
12251
  await next();
12082
12252
  c.header("X-Content-Type-Options", "nosniff");
12083
12253
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -12100,7 +12270,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
12100
12270
  "/g/"
12101
12271
  ];
12102
12272
  var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
12103
- app34.use("*", async (c, next) => {
12273
+ app36.use("*", async (c, next) => {
12104
12274
  const host = (c.req.header("host") ?? "").split(":")[0];
12105
12275
  if (!isPublicHost(host)) {
12106
12276
  await next();
@@ -12140,7 +12310,7 @@ function resolveRemoteAuthOpts() {
12140
12310
  return brandLoginOpts;
12141
12311
  }
12142
12312
  var MAX_LOGIN_BODY = 8 * 1024;
12143
- app34.post("/__remote-auth/login", async (c) => {
12313
+ app36.post("/__remote-auth/login", async (c) => {
12144
12314
  const client = clientFrom(c);
12145
12315
  const clientIp = client.ip || "unknown";
12146
12316
  if (!requestIsTlsTerminated(c)) {
@@ -12184,7 +12354,7 @@ app34.post("/__remote-auth/login", async (c) => {
12184
12354
  }
12185
12355
  });
12186
12356
  });
12187
- app34.get("/__remote-auth/logout", (c) => {
12357
+ app36.get("/__remote-auth/logout", (c) => {
12188
12358
  return new Response(null, {
12189
12359
  status: 302,
12190
12360
  headers: {
@@ -12194,7 +12364,7 @@ app34.get("/__remote-auth/logout", (c) => {
12194
12364
  }
12195
12365
  });
12196
12366
  });
12197
- app34.post("/__remote-auth/change-password", async (c) => {
12367
+ app36.post("/__remote-auth/change-password", async (c) => {
12198
12368
  const client = clientFrom(c);
12199
12369
  const clientIp = client.ip || "unknown";
12200
12370
  const rateLimited = checkRateLimit(client);
@@ -12244,13 +12414,13 @@ app34.post("/__remote-auth/change-password", async (c) => {
12244
12414
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
12245
12415
  }
12246
12416
  });
12247
- app34.get("/__remote-auth/setup", (c) => {
12417
+ app36.get("/__remote-auth/setup", (c) => {
12248
12418
  if (isRemoteAuthConfigured()) {
12249
12419
  return c.redirect("/");
12250
12420
  }
12251
12421
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
12252
12422
  });
12253
- app34.post("/__remote-auth/set-initial-password", async (c) => {
12423
+ app36.post("/__remote-auth/set-initial-password", async (c) => {
12254
12424
  if (isRemoteAuthConfigured()) {
12255
12425
  return c.redirect("/");
12256
12426
  }
@@ -12286,10 +12456,10 @@ app34.post("/__remote-auth/set-initial-password", async (c) => {
12286
12456
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
12287
12457
  }
12288
12458
  });
12289
- app34.get("/api/remote-auth/status", (c) => {
12459
+ app36.get("/api/remote-auth/status", (c) => {
12290
12460
  return c.json({ configured: isRemoteAuthConfigured() });
12291
12461
  });
12292
- app34.post("/api/remote-auth/set-password", async (c) => {
12462
+ app36.post("/api/remote-auth/set-password", async (c) => {
12293
12463
  let body;
12294
12464
  try {
12295
12465
  body = await c.req.json();
@@ -12319,9 +12489,9 @@ app34.post("/api/remote-auth/set-password", async (c) => {
12319
12489
  return c.json({ error: "Failed to save password" }, 500);
12320
12490
  }
12321
12491
  });
12322
- app34.route("/api/_client-error", client_error_default);
12492
+ app36.route("/api/_client-error", client_error_default);
12323
12493
  console.log("[client-error-route] mounted");
12324
- app34.use("*", async (c, next) => {
12494
+ app36.use("*", async (c, next) => {
12325
12495
  const host = (c.req.header("host") ?? "").split(":")[0];
12326
12496
  const path2 = c.req.path;
12327
12497
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -12354,15 +12524,15 @@ app34.use("*", async (c, next) => {
12354
12524
  console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
12355
12525
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
12356
12526
  });
12357
- app34.route("/api/health", health_default);
12358
- app34.route("/api/session", session_default);
12359
- app34.route("/api/chat", chat_default);
12360
- app34.route("/api/group", group_default);
12361
- app34.route("/api/access", access_default);
12362
- app34.route("/api/telegram", telegram_default);
12363
- app34.route("/api/whatsapp", whatsapp_default);
12364
- app34.route("/api/onboarding", onboarding_default);
12365
- app34.route("/api/admin", admin_default);
12527
+ app36.route("/api/health", health_default);
12528
+ app36.route("/api/session", session_default);
12529
+ app36.route("/api/chat", chat_default);
12530
+ app36.route("/api/group", group_default);
12531
+ app36.route("/api/access", access_default);
12532
+ app36.route("/api/telegram", telegram_default);
12533
+ app36.route("/api/whatsapp", whatsapp_default);
12534
+ app36.route("/api/onboarding", onboarding_default);
12535
+ app36.route("/api/admin", admin_default);
12366
12536
  var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
12367
12537
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
12368
12538
  var IMAGE_MIME = {
@@ -12374,7 +12544,7 @@ var IMAGE_MIME = {
12374
12544
  ".svg": "image/svg+xml",
12375
12545
  ".ico": "image/x-icon"
12376
12546
  };
12377
- app34.get("/agent-assets/:slug/:filename", (c) => {
12547
+ app36.get("/agent-assets/:slug/:filename", (c) => {
12378
12548
  const slug = c.req.param("slug");
12379
12549
  const filename = c.req.param("filename");
12380
12550
  if (!SAFE_SLUG_RE.test(slug)) {
@@ -12390,13 +12560,13 @@ app34.get("/agent-assets/:slug/:filename", (c) => {
12390
12560
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
12391
12561
  return c.text("Not found", 404);
12392
12562
  }
12393
- const filePath = resolve21(account.accountDir, "agents", slug, "assets", filename);
12394
- const expectedDir = resolve21(account.accountDir, "agents", slug, "assets");
12563
+ const filePath = resolve23(account.accountDir, "agents", slug, "assets", filename);
12564
+ const expectedDir = resolve23(account.accountDir, "agents", slug, "assets");
12395
12565
  if (!filePath.startsWith(expectedDir + "/")) {
12396
12566
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
12397
12567
  return c.text("Forbidden", 403);
12398
12568
  }
12399
- if (!existsSync20(filePath)) {
12569
+ if (!existsSync22(filePath)) {
12400
12570
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
12401
12571
  return c.text("Not found", 404);
12402
12572
  }
@@ -12409,7 +12579,7 @@ app34.get("/agent-assets/:slug/:filename", (c) => {
12409
12579
  "Cache-Control": "public, max-age=3600"
12410
12580
  });
12411
12581
  });
12412
- app34.get("/generated/:filename", (c) => {
12582
+ app36.get("/generated/:filename", (c) => {
12413
12583
  const filename = c.req.param("filename");
12414
12584
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
12415
12585
  console.error(`[generated] serve file=${filename} status=403`);
@@ -12420,13 +12590,13 @@ app34.get("/generated/:filename", (c) => {
12420
12590
  console.error(`[generated] serve file=${filename} status=404`);
12421
12591
  return c.text("Not found", 404);
12422
12592
  }
12423
- const filePath = resolve21(account.accountDir, "generated", filename);
12424
- const expectedDir = resolve21(account.accountDir, "generated");
12593
+ const filePath = resolve23(account.accountDir, "generated", filename);
12594
+ const expectedDir = resolve23(account.accountDir, "generated");
12425
12595
  if (!filePath.startsWith(expectedDir + "/")) {
12426
12596
  console.error(`[generated] serve file=${filename} status=403`);
12427
12597
  return c.text("Forbidden", 403);
12428
12598
  }
12429
- if (!existsSync20(filePath)) {
12599
+ if (!existsSync22(filePath)) {
12430
12600
  console.error(`[generated] serve file=${filename} status=404`);
12431
12601
  return c.text("Not found", 404);
12432
12602
  }
@@ -12442,7 +12612,7 @@ app34.get("/generated/:filename", (c) => {
12442
12612
  var htmlCache = /* @__PURE__ */ new Map();
12443
12613
  var brandLogoPath = "/brand/maxy-monochrome.png";
12444
12614
  var brandIconPath = "/brand/maxy-monochrome.png";
12445
- if (BRAND_JSON_PATH && existsSync20(BRAND_JSON_PATH)) {
12615
+ if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
12446
12616
  try {
12447
12617
  const fullBrand = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
12448
12618
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
@@ -12462,7 +12632,7 @@ function readInstalledVersion() {
12462
12632
  try {
12463
12633
  if (!PLATFORM_ROOT7) return "unknown";
12464
12634
  const versionFile = join10(PLATFORM_ROOT7, "config", `.${BRAND.hostname}-version`);
12465
- if (!existsSync20(versionFile)) return "unknown";
12635
+ if (!existsSync22(versionFile)) return "unknown";
12466
12636
  const content = readFileSync16(versionFile, "utf-8").trim();
12467
12637
  return content || "unknown";
12468
12638
  } catch {
@@ -12504,7 +12674,7 @@ var clientErrorReporterScript = `<script>
12504
12674
  function cachedHtml(file) {
12505
12675
  let html = htmlCache.get(file);
12506
12676
  if (!html) {
12507
- html = readFileSync16(resolve21(process.cwd(), "public", file), "utf-8");
12677
+ html = readFileSync16(resolve23(process.cwd(), "public", file), "utf-8");
12508
12678
  const productNameEsc = escapeHtml(BRAND.productName);
12509
12679
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
12510
12680
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -12523,12 +12693,12 @@ function loadBrandingCache(agentSlug) {
12523
12693
  const configDir2 = join10(homedir2(), BRAND.configDir);
12524
12694
  try {
12525
12695
  const accountJsonPath = join10(configDir2, "account.json");
12526
- if (!existsSync20(accountJsonPath)) return null;
12696
+ if (!existsSync22(accountJsonPath)) return null;
12527
12697
  const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
12528
12698
  const accountId = account.accountId;
12529
12699
  if (!accountId) return null;
12530
12700
  const cachePath = join10(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
12531
- if (!existsSync20(cachePath)) return null;
12701
+ if (!existsSync22(cachePath)) return null;
12532
12702
  return JSON.parse(readFileSync16(cachePath, "utf-8"));
12533
12703
  } catch {
12534
12704
  return null;
@@ -12538,7 +12708,7 @@ function resolveDefaultSlug() {
12538
12708
  try {
12539
12709
  const configDir2 = join10(homedir2(), BRAND.configDir);
12540
12710
  const accountJsonPath = join10(configDir2, "account.json");
12541
- if (!existsSync20(accountJsonPath)) return null;
12711
+ if (!existsSync22(accountJsonPath)) return null;
12542
12712
  const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
12543
12713
  return account.defaultAgent || null;
12544
12714
  } catch {
@@ -12575,7 +12745,7 @@ function brandedPublicHtml(agentSlug) {
12575
12745
  function escapeHtml(s) {
12576
12746
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
12577
12747
  }
12578
- app34.get("/", (c) => {
12748
+ app36.get("/", (c) => {
12579
12749
  const host = (c.req.header("host") ?? "").split(":")[0];
12580
12750
  if (isPublicHost(host)) {
12581
12751
  const defaultSlug = resolveDefaultSlug();
@@ -12583,12 +12753,12 @@ app34.get("/", (c) => {
12583
12753
  }
12584
12754
  return c.html(cachedHtml("index.html"));
12585
12755
  });
12586
- app34.get("/public", (c) => {
12756
+ app36.get("/public", (c) => {
12587
12757
  const host = (c.req.header("host") ?? "").split(":")[0];
12588
12758
  if (isPublicHost(host)) return c.text("Not found", 404);
12589
12759
  return c.html(cachedHtml("public.html"));
12590
12760
  });
12591
- app34.get("/chat", (c) => {
12761
+ app36.get("/chat", (c) => {
12592
12762
  const host = (c.req.header("host") ?? "").split(":")[0];
12593
12763
  if (isPublicHost(host)) return c.text("Not found", 404);
12594
12764
  return c.html(cachedHtml("public.html"));
@@ -12607,12 +12777,12 @@ async function logViewerFetch(c, next) {
12607
12777
  duration_ms: Date.now() - start
12608
12778
  });
12609
12779
  }
12610
- app34.use("/vnc-viewer.html", logViewerFetch);
12611
- app34.use("/vnc-popout.html", logViewerFetch);
12612
- app34.get("/vnc-popout.html", (c) => {
12780
+ app36.use("/vnc-viewer.html", logViewerFetch);
12781
+ app36.use("/vnc-popout.html", logViewerFetch);
12782
+ app36.get("/vnc-popout.html", (c) => {
12613
12783
  let html = htmlCache.get("vnc-popout.html");
12614
12784
  if (!html) {
12615
- html = readFileSync16(resolve21(process.cwd(), "public", "vnc-popout.html"), "utf-8");
12785
+ html = readFileSync16(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
12616
12786
  const name = escapeHtml(BRAND.productName);
12617
12787
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
12618
12788
  html = html.replace("</head>", ` ${brandScript}
@@ -12622,7 +12792,7 @@ app34.get("/vnc-popout.html", (c) => {
12622
12792
  }
12623
12793
  return c.html(html);
12624
12794
  });
12625
- app34.post("/api/vnc/client-event", async (c) => {
12795
+ app36.post("/api/vnc/client-event", async (c) => {
12626
12796
  let body;
12627
12797
  try {
12628
12798
  body = await c.req.json();
@@ -12643,20 +12813,20 @@ app34.post("/api/vnc/client-event", async (c) => {
12643
12813
  });
12644
12814
  return c.json({ ok: true });
12645
12815
  });
12646
- app34.get("/g/:slug", (c) => {
12816
+ app36.get("/g/:slug", (c) => {
12647
12817
  return c.html(brandedPublicHtml());
12648
12818
  });
12649
- app34.get("/graph", (c) => {
12819
+ app36.get("/graph", (c) => {
12650
12820
  const host = (c.req.header("host") ?? "").split(":")[0];
12651
12821
  if (isPublicHost(host)) return c.text("Not found", 404);
12652
12822
  return c.html(cachedHtml("graph.html"));
12653
12823
  });
12654
- app34.get("/data", (c) => {
12824
+ app36.get("/data", (c) => {
12655
12825
  const host = (c.req.header("host") ?? "").split(":")[0];
12656
12826
  if (isPublicHost(host)) return c.text("Not found", 404);
12657
12827
  return c.html(cachedHtml("data.html"));
12658
12828
  });
12659
- app34.get("/:slug", async (c, next) => {
12829
+ app36.get("/:slug", async (c, next) => {
12660
12830
  const slug = c.req.param("slug");
12661
12831
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
12662
12832
  const branding = loadBrandingCache(slug);
@@ -12665,10 +12835,10 @@ app34.get("/:slug", async (c, next) => {
12665
12835
  }
12666
12836
  await next();
12667
12837
  });
12668
- app34.use("/*", serveStatic({ root: "./public" }));
12838
+ app36.use("/*", serveStatic({ root: "./public" }));
12669
12839
  var port = parseInt(process.env.MAXY_UI_INTERNAL_PORT ?? process.env.PORT ?? "19199", 10);
12670
12840
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
12671
- var httpServer = serve({ fetch: app34.fetch, port, hostname });
12841
+ var httpServer = serve({ fetch: app36.fetch, port, hostname });
12672
12842
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
12673
12843
  var SUBAPP_MANIFEST = [
12674
12844
  { prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
@@ -12688,7 +12858,7 @@ for (const m of SUBAPP_MANIFEST) {
12688
12858
  }
12689
12859
  try {
12690
12860
  const registered = [];
12691
- for (const r of app34.routes ?? []) {
12861
+ for (const r of app36.routes ?? []) {
12692
12862
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
12693
12863
  if (AGENT_SLUG_PATTERN.test(r.path)) {
12694
12864
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -12702,7 +12872,7 @@ try {
12702
12872
  (async () => {
12703
12873
  try {
12704
12874
  let userId = "";
12705
- if (existsSync20(USERS_FILE)) {
12875
+ if (existsSync22(USERS_FILE)) {
12706
12876
  const users = JSON.parse(readFileSync16(USERS_FILE, "utf-8").trim() || "[]");
12707
12877
  userId = users[0]?.userId ?? "";
12708
12878
  }
@@ -12755,7 +12925,7 @@ if (bootAccountConfig?.whatsapp) {
12755
12925
  }
12756
12926
  init({
12757
12927
  configDir: configDirForWhatsApp,
12758
- platformRoot: resolve21(process.env.MAXY_PLATFORM_ROOT ?? join10(__dirname, "..")),
12928
+ platformRoot: resolve23(process.env.MAXY_PLATFORM_ROOT ?? join10(__dirname, "..")),
12759
12929
  accountConfig: bootAccountConfig,
12760
12930
  onMessage: async (msg) => {
12761
12931
  try {