@rubytech/create-realagent 1.0.832 → 1.0.834

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 (97) hide show
  1. package/dist/index.js +131 -9
  2. package/package.json +1 -1
  3. package/payload/platform/lib/admins-write/dist/index.d.ts +87 -0
  4. package/payload/platform/lib/admins-write/dist/index.d.ts.map +1 -0
  5. package/payload/platform/lib/admins-write/dist/index.js +248 -0
  6. package/payload/platform/lib/admins-write/dist/index.js.map +1 -0
  7. package/payload/platform/lib/admins-write/src/index.ts +311 -0
  8. package/payload/platform/lib/admins-write/tsconfig.json +8 -0
  9. package/payload/platform/neo4j/migrations/009-conversation-archive-title.ts +197 -0
  10. package/payload/platform/neo4j/schema.cypher +1 -1
  11. package/payload/platform/package.json +2 -2
  12. package/payload/platform/plugins/admin/PLUGIN.md +1 -1
  13. package/payload/platform/plugins/admin/mcp/dist/index.js +37 -44
  14. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  15. package/payload/platform/plugins/docs/references/internals.md +4 -3
  16. package/payload/platform/plugins/memory/bin/conversation-archive-ingest.mjs +215 -43
  17. package/payload/platform/plugins/memory/bin/conversation-archive-ingest.sh +7 -2
  18. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js +75 -0
  19. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js.map +1 -1
  20. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts +16 -10
  21. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts.map +1 -1
  22. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js +155 -100
  23. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js.map +1 -1
  24. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.d.ts +13 -5
  25. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.d.ts.map +1 -1
  26. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js +53 -59
  27. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js.map +1 -1
  28. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js +9 -0
  29. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js.map +1 -1
  30. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +24 -7
  31. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
  32. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +47 -11
  33. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
  34. package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +45 -8
  35. package/payload/platform/scripts/lib/resolve-account-dir.sh +3 -1
  36. package/payload/platform/scripts/migrate-import.sh +3 -1
  37. package/payload/platform/scripts/seed-neo4j.sh +13 -3
  38. package/payload/server/chunk-CRAIGEXY.js +654 -0
  39. package/payload/server/chunk-GK4WHM3H.js +9961 -0
  40. package/payload/server/chunk-I2NOLBQA.js +2123 -0
  41. package/payload/server/chunk-IVTESKFR.js +9961 -0
  42. package/payload/server/chunk-KD3XP4IK.js +1116 -0
  43. package/payload/server/chunk-KKGGT5RH.js +654 -0
  44. package/payload/server/chunk-MRJGG6CS.js +2124 -0
  45. package/payload/server/chunk-OJZPS4BL.js +367 -0
  46. package/payload/server/chunk-ZVW5XKPU.js +1116 -0
  47. package/payload/server/client-pool-FM3YJWV5.js +32 -0
  48. package/payload/server/client-pool-J5BCVVI2.js +32 -0
  49. package/payload/server/cloudflare-task-tracker-FSPEJOTH.js +19 -0
  50. package/payload/server/cloudflare-task-tracker-XCUO4N74.js +19 -0
  51. package/payload/server/maxy-edge.js +6 -5
  52. package/payload/server/neo4j-migrations-5AN2U3YO.js +664 -0
  53. package/payload/server/neo4j-migrations-XP7XDVPX.js +664 -0
  54. package/payload/server/public/assets/{Checkbox-CTGhpDKq.js → Checkbox-Bq6ORjz2.js} +1 -1
  55. package/payload/server/public/assets/admin-CstEkw-G.js +352 -0
  56. package/payload/server/public/assets/data-DwZZ7qbH.js +1 -0
  57. package/payload/server/public/assets/graph-DceEv42K.js +1 -0
  58. package/payload/server/public/assets/{jsx-runtime-D4WovFYk.css → jsx-runtime-DidQeNoZ.css} +1 -1
  59. package/payload/server/public/assets/page-Bpi_jPw6.js +50 -0
  60. package/payload/server/public/assets/{page-DkBfWy4C.js → page-CFWoVkgV.js} +1 -1
  61. package/payload/server/public/assets/{public-BdVIVpv8.js → public-BWMwq5Jj.js} +1 -1
  62. package/payload/server/public/assets/{useAdminFetch-DmHu0oCx.js → useAdminFetch-B93ig7ef.js} +1 -1
  63. package/payload/server/public/assets/{useVoiceRecorder-CSc_hxjV.js → useVoiceRecorder-Cb0nAtOo.js} +1 -1
  64. package/payload/server/public/data.html +5 -5
  65. package/payload/server/public/graph.html +6 -6
  66. package/payload/server/public/index.html +8 -8
  67. package/payload/server/public/public.html +5 -5
  68. package/payload/server/server.js +376 -167
  69. package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.d.ts +0 -31
  70. package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.d.ts.map +0 -1
  71. package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.js +0 -666
  72. package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.js.map +0 -1
  73. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.d.ts +0 -61
  74. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.d.ts.map +0 -1
  75. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js +0 -266
  76. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js.map +0 -1
  77. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.d.ts +0 -27
  78. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.d.ts.map +0 -1
  79. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.js +0 -477
  80. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.js.map +0 -1
  81. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.d.ts +0 -27
  82. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.d.ts.map +0 -1
  83. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.js +0 -160
  84. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.js.map +0 -1
  85. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.d.ts +0 -10
  86. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.d.ts.map +0 -1
  87. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.js +0 -29
  88. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.js.map +0 -1
  89. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.d.ts +0 -28
  90. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.d.ts.map +0 -1
  91. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.js +0 -34
  92. package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.js.map +0 -1
  93. package/payload/server/public/assets/admin-BNwPsMhJ.js +0 -352
  94. package/payload/server/public/assets/data-Y77FLKjs.js +0 -1
  95. package/payload/server/public/assets/graph-N_Bw-8oT.js +0 -1
  96. package/payload/server/public/assets/page-BKLGP-th.js +0 -50
  97. /package/payload/server/public/assets/{jsx-runtime-DkaAusaX.js → jsx-runtime-DH5S-MwB.js} +0 -0
@@ -1,11 +1,5 @@
1
1
  import {
2
- COMMERCIAL_MODE,
3
2
  Hono,
4
- LOG_DIR,
5
- MAXY_DIR,
6
- TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
7
- TELEGRAM_WEBHOOK_SECRET_FILE,
8
- USERS_FILE,
9
3
  autoDeliverPremiumPlugins,
10
4
  buildX11Env,
11
5
  callOauthLlm,
@@ -51,7 +45,7 @@ import {
51
45
  vncLog,
52
46
  waitForExit,
53
47
  writeChromiumWrapper
54
- } from "./chunk-ZKGAYLAK.js";
48
+ } from "./chunk-GK4WHM3H.js";
55
49
  import {
56
50
  agentLogStream,
57
51
  clearSessionHistory,
@@ -79,10 +73,16 @@ import {
79
73
  sigtermFlushStreamLogs,
80
74
  unregisterSession,
81
75
  validateSession
82
- } from "./chunk-25QDCOE5.js";
76
+ } from "./chunk-ZVW5XKPU.js";
83
77
  import {
84
78
  ACCOUNTS_DIR,
79
+ COMMERCIAL_MODE,
80
+ LOG_DIR,
81
+ MAXY_DIR,
85
82
  PLATFORM_ROOT,
83
+ TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
84
+ TELEGRAM_WEBHOOK_SECRET_FILE,
85
+ USERS_FILE,
86
86
  getDefaultAccountId,
87
87
  hasStubAccountDir,
88
88
  resolveAccount,
@@ -90,7 +90,7 @@ import {
90
90
  resolveDefaultAgentSlug,
91
91
  resolveUserAccounts,
92
92
  validateAgentSlug
93
- } from "./chunk-35YZS3KL.js";
93
+ } from "./chunk-OJZPS4BL.js";
94
94
  import {
95
95
  CLOUDFLARE_TASK_DIAGNOSTICS,
96
96
  appendCloudflareSteps,
@@ -98,7 +98,7 @@ import {
98
98
  openCloudflareTask,
99
99
  readTunnelState,
100
100
  resolveUnitGoneVerdict
101
- } from "./chunk-7CBRZKZS.js";
101
+ } from "./chunk-KKGGT5RH.js";
102
102
  import {
103
103
  GREETING_DIRECTIVE,
104
104
  HAIKU_MODEL,
@@ -130,7 +130,7 @@ import {
130
130
  verifyAndGetConversationUpdatedAt,
131
131
  verifyConversationOwnership,
132
132
  writeAdminUserAndPerson
133
- } from "./chunk-IXOPV36P.js";
133
+ } from "./chunk-MRJGG6CS.js";
134
134
 
135
135
  // ../lib/graph-trash/dist/index.js
136
136
  var require_dist = __commonJS({
@@ -629,8 +629,8 @@ var serveStatic = (options = { root: "" }) => {
629
629
  };
630
630
 
631
631
  // server/index.ts
632
- import { readFileSync as readFileSync16, existsSync as existsSync22, watchFile } from "fs";
633
- import { resolve as resolve22, join as join10, basename as basename5 } from "path";
632
+ import { readFileSync as readFileSync17, existsSync as existsSync23, watchFile } from "fs";
633
+ import { resolve as resolve22, join as join12, basename as basename5 } from "path";
634
634
  import { homedir as homedir2 } from "os";
635
635
 
636
636
  // app/lib/agent-slug-pattern.ts
@@ -6392,16 +6392,164 @@ var whatsapp_default = app7;
6392
6392
 
6393
6393
  // server/routes/onboarding.ts
6394
6394
  import { spawn, execFileSync } from "child_process";
6395
- import { openSync, closeSync, writeFileSync as writeFileSync4, writeSync, existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync8, unlinkSync } from "fs";
6396
- import { resolve as resolve8, dirname as dirname2 } from "path";
6395
+ import { openSync, closeSync, writeFileSync as writeFileSync5, writeSync, existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync9, unlinkSync } from "fs";
6396
+ import { resolve as resolve8, dirname as dirname3 } from "path";
6397
6397
  import { createHash, randomUUID as randomUUID6 } from "crypto";
6398
+
6399
+ // ../lib/admins-write/src/index.ts
6400
+ import { existsSync as existsSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync4, renameSync, mkdirSync as mkdirSync3, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
6401
+ import { dirname as dirname2, join as join6 } from "path";
6402
+ function logLine(input, result) {
6403
+ const userIdShort = input.userId.slice(0, 8);
6404
+ console.error(
6405
+ `[admins-write] caller=${input.caller} userId=${userIdShort} usersJsonResult=${result.usersJsonResult} accountJsonResult=${result.accountJsonResult}` + (result.usersError ? ` usersError=${result.usersError}` : "") + (result.accountError ? ` accountError=${result.accountError}` : "")
6406
+ );
6407
+ }
6408
+ function writeFileAtomic(filePath, contents, mode) {
6409
+ mkdirSync3(dirname2(filePath), { recursive: true });
6410
+ const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
6411
+ writeFileSync4(tempPath, contents, mode !== void 0 ? { mode } : void 0);
6412
+ renameSync(tempPath, filePath);
6413
+ }
6414
+ function writeAdminEntry(input) {
6415
+ const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
6416
+ try {
6417
+ let users = [];
6418
+ if (existsSync8(input.usersFile)) {
6419
+ const raw = readFileSync8(input.usersFile, "utf-8").trim();
6420
+ if (raw) {
6421
+ const parsed = JSON.parse(raw);
6422
+ if (!Array.isArray(parsed)) {
6423
+ throw new Error("users.json is not an array");
6424
+ }
6425
+ users = parsed;
6426
+ }
6427
+ }
6428
+ const existing = users.findIndex((u) => u.userId === input.userId);
6429
+ if (existing === -1) {
6430
+ users.push({ userId: input.userId, pin: input.pin });
6431
+ } else {
6432
+ const merged = { ...users[existing], pin: input.pin };
6433
+ delete merged.name;
6434
+ users[existing] = merged;
6435
+ }
6436
+ writeFileAtomic(input.usersFile, JSON.stringify(users, null, 2) + "\n", 384);
6437
+ result.usersJsonResult = "ok";
6438
+ } catch (err) {
6439
+ result.usersJsonResult = "fail";
6440
+ result.usersError = err instanceof Error ? err.message : String(err);
6441
+ logLine(input, result);
6442
+ return result;
6443
+ }
6444
+ try {
6445
+ const accountJsonPath = join6(input.accountDir, "account.json");
6446
+ if (!existsSync8(accountJsonPath)) {
6447
+ throw new Error(`account.json not found at ${accountJsonPath}`);
6448
+ }
6449
+ const config = JSON.parse(readFileSync8(accountJsonPath, "utf-8"));
6450
+ const admins = config.admins ?? [];
6451
+ if (admins.some((a) => a.userId === input.userId)) {
6452
+ result.accountJsonResult = "noop";
6453
+ } else {
6454
+ admins.push({ userId: input.userId, role: input.role });
6455
+ config.admins = admins;
6456
+ writeFileAtomic(accountJsonPath, JSON.stringify(config, null, 2) + "\n");
6457
+ result.accountJsonResult = "ok";
6458
+ }
6459
+ } catch (err) {
6460
+ result.accountJsonResult = "fail";
6461
+ result.accountError = err instanceof Error ? err.message : String(err);
6462
+ }
6463
+ logLine(input, result);
6464
+ return result;
6465
+ }
6466
+ function checkAdminAuthInvariant(input) {
6467
+ const result = {
6468
+ divergences: 0,
6469
+ accountWithoutUsers: [],
6470
+ usersWithoutAccount: []
6471
+ };
6472
+ const usersUserIds = /* @__PURE__ */ new Set();
6473
+ if (existsSync8(input.usersFile)) {
6474
+ try {
6475
+ const raw = readFileSync8(input.usersFile, "utf-8").trim();
6476
+ if (raw) {
6477
+ const users = JSON.parse(raw);
6478
+ for (const u of users) {
6479
+ if (typeof u.userId === "string") usersUserIds.add(u.userId);
6480
+ }
6481
+ }
6482
+ } catch (err) {
6483
+ const msg = err instanceof Error ? err.message : String(err);
6484
+ console.error(`[${input.tag}] users.json unreadable usersFile=${input.usersFile} error=${msg}`);
6485
+ }
6486
+ }
6487
+ const accountUserIds = /* @__PURE__ */ new Set();
6488
+ if (existsSync8(input.accountsDir)) {
6489
+ let entries;
6490
+ try {
6491
+ entries = readdirSync3(input.accountsDir);
6492
+ } catch (err) {
6493
+ const msg = err instanceof Error ? err.message : String(err);
6494
+ console.error(`[${input.tag}] accounts-dir unreadable accountsDir=${input.accountsDir} error=${msg}`);
6495
+ console.error(`[${input.tag}] check complete divergences=0 (accounts-dir unreadable)`);
6496
+ return result;
6497
+ }
6498
+ for (const entry of entries) {
6499
+ if (entry.startsWith(".")) continue;
6500
+ const accountDir = join6(input.accountsDir, entry);
6501
+ try {
6502
+ if (!statSync2(accountDir).isDirectory()) continue;
6503
+ } catch {
6504
+ continue;
6505
+ }
6506
+ const accountJsonPath = join6(accountDir, "account.json");
6507
+ if (!existsSync8(accountJsonPath)) continue;
6508
+ let admins = [];
6509
+ try {
6510
+ const config = JSON.parse(readFileSync8(accountJsonPath, "utf-8"));
6511
+ admins = config.admins ?? [];
6512
+ } catch (err) {
6513
+ const msg = err instanceof Error ? err.message : String(err);
6514
+ console.error(`[${input.tag}] account.json unreadable source=${accountJsonPath} error=${msg}`);
6515
+ continue;
6516
+ }
6517
+ for (const a of admins) {
6518
+ if (typeof a.userId !== "string") continue;
6519
+ accountUserIds.add(a.userId);
6520
+ if (!usersUserIds.has(a.userId)) {
6521
+ const userIdShort = a.userId.slice(0, 8);
6522
+ console.error(
6523
+ `[${input.tag}] direction=account-without-users userId=${userIdShort} source=${accountJsonPath}`
6524
+ );
6525
+ result.accountWithoutUsers.push({ userId: a.userId, source: accountJsonPath });
6526
+ result.divergences += 1;
6527
+ }
6528
+ }
6529
+ }
6530
+ }
6531
+ for (const uid of usersUserIds) {
6532
+ if (!accountUserIds.has(uid)) {
6533
+ const userIdShort = uid.slice(0, 8);
6534
+ console.error(
6535
+ `[${input.tag}] direction=users-without-account userId=${userIdShort} source=${input.usersFile}`
6536
+ );
6537
+ result.usersWithoutAccount.push({ userId: uid });
6538
+ result.divergences += 1;
6539
+ }
6540
+ }
6541
+ console.error(`[${input.tag}] check complete divergences=${result.divergences}`);
6542
+ return result;
6543
+ }
6544
+
6545
+ // server/routes/onboarding.ts
6398
6546
  var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT || "";
6399
6547
  function hashPin(pin) {
6400
6548
  return createHash("sha256").update(pin).digest("hex");
6401
6549
  }
6402
6550
  function readUsersFile() {
6403
- if (!existsSync8(USERS_FILE)) return null;
6404
- const raw = readFileSync8(USERS_FILE, "utf-8").trim();
6551
+ if (!existsSync9(USERS_FILE)) return null;
6552
+ const raw = readFileSync9(USERS_FILE, "utf-8").trim();
6405
6553
  if (!raw) return [];
6406
6554
  return JSON.parse(raw);
6407
6555
  }
@@ -6467,7 +6615,7 @@ app8.post("/claude-auth", async (c) => {
6467
6615
  if (!vncReady) return c.json({ error: "VNC display failed to start" }, 500);
6468
6616
  }
6469
6617
  await ensureCdp(transport);
6470
- writeFileSync4(logPath("claude-auth"), "");
6618
+ writeFileSync5(logPath("claude-auth"), "");
6471
6619
  const chromiumWrapper = writeChromiumWrapper();
6472
6620
  const x11Env = buildX11Env(chromiumWrapper, transport);
6473
6621
  vncLog("claude-auth", { action: "start", transport });
@@ -6528,36 +6676,41 @@ app8.post("/set-pin", async (c) => {
6528
6676
  } else {
6529
6677
  console.log(`[set-pin] minted new userId=${userId.slice(0, 8)}\u2026 (first-time install)`);
6530
6678
  }
6531
- mkdirSync3(dirname2(USERS_FILE), { recursive: true });
6532
- writeFileSync4(USERS_FILE, JSON.stringify([{ userId, pin: hash }]), { mode: 384 });
6533
- console.log(`[set-pin] wrote users.json: userId=${userId.slice(0, 8)}\u2026 hash=${hash.slice(0, 8)}\u2026`);
6534
- if (account) {
6535
- try {
6536
- const config = JSON.parse(readFileSync8(`${account.accountDir}/account.json`, "utf-8"));
6537
- if (!config.admins) config.admins = [];
6538
- if (!config.admins.some((a) => a.userId === userId)) {
6539
- config.admins.push({ userId, role: "owner" });
6540
- writeFileSync4(`${account.accountDir}/account.json`, JSON.stringify(config, null, 2) + "\n");
6541
- console.log(`[set-pin] added userId=${userId.slice(0, 8)}\u2026 to account.json admins`);
6542
- }
6543
- } catch (err) {
6544
- console.error(`[set-pin] failed to update account.json admins: ${err instanceof Error ? err.message : String(err)}`);
6545
- }
6546
- try {
6547
- const result = await writeAdminUserAndPerson({
6548
- userId,
6549
- fullName,
6550
- accountId: account.accountId
6551
- });
6552
- console.log(
6553
- `[admin-identity] adminuser-bound userId=${userId.slice(0, 8)} givenName=${result.givenName} familyName=${result.familyName ?? "null"} personReused=${result.personReused}`
6554
- );
6555
- } catch (err) {
6556
- console.error(
6557
- `[admin-identity] adminuser-bind-failed userId=${userId.slice(0, 8)} accountId=${account.accountId.slice(0, 8)} error=${err instanceof Error ? err.message : String(err)}`
6558
- );
6559
- return c.json({ error: "Failed to write admin identity to graph. Check Neo4j connectivity and retry." }, 500);
6560
- }
6679
+ if (!account) {
6680
+ console.error(`[set-pin] no account resolvable at set-pin time \u2014 refusing to write users.json without account binding`);
6681
+ return c.json({ error: "No account is configured on this device. Re-run the installer." }, 503);
6682
+ }
6683
+ const result = writeAdminEntry({
6684
+ userId,
6685
+ pin: hash,
6686
+ role: "owner",
6687
+ usersFile: USERS_FILE,
6688
+ accountDir: account.accountDir,
6689
+ caller: "set-pin"
6690
+ });
6691
+ if (result.usersJsonResult !== "ok") {
6692
+ console.error(`[set-pin] users.json write failed: ${result.usersError ?? "unknown"}`);
6693
+ return c.json({ error: "Failed to write user configuration. See server log." }, 500);
6694
+ }
6695
+ if (result.accountJsonResult === "fail") {
6696
+ console.error(`[set-pin] account.json write failed after users.json succeeded: ${result.accountError ?? "unknown"}`);
6697
+ return c.json({ error: "PIN saved but admin role could not be recorded. See server log." }, 500);
6698
+ }
6699
+ console.log(`[set-pin] wrote users.json + account.json admins: userId=${userId.slice(0, 8)}\u2026 role=owner`);
6700
+ try {
6701
+ const adminBind = await writeAdminUserAndPerson({
6702
+ userId,
6703
+ fullName,
6704
+ accountId: account.accountId
6705
+ });
6706
+ console.log(
6707
+ `[admin-identity] adminuser-bound userId=${userId.slice(0, 8)} givenName=${adminBind.givenName} familyName=${adminBind.familyName ?? "null"} personReused=${adminBind.personReused}`
6708
+ );
6709
+ } catch (err) {
6710
+ console.error(
6711
+ `[admin-identity] adminuser-bind-failed userId=${userId.slice(0, 8)} accountId=${account.accountId.slice(0, 8)} error=${err instanceof Error ? err.message : String(err)}`
6712
+ );
6713
+ return c.json({ error: "Failed to write admin identity to graph. Check Neo4j connectivity and retry." }, 500);
6561
6714
  }
6562
6715
  return c.json({ ok: true });
6563
6716
  });
@@ -6590,7 +6743,7 @@ app8.delete("/set-pin", async (c) => {
6590
6743
  unlinkSync(USERS_FILE);
6591
6744
  console.log(`[set-pin] cleared users.json (last entry removed): userId=${matchedUser.userId.slice(0, 8)}\u2026`);
6592
6745
  } else {
6593
- writeFileSync4(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
6746
+ writeFileSync5(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
6594
6747
  console.log(`[set-pin] removed entry from users.json: userId=${matchedUser.userId.slice(0, 8)}\u2026 remaining=${remaining.length}`);
6595
6748
  }
6596
6749
  return c.json({ ok: true });
@@ -6610,9 +6763,9 @@ app8.post("/skip", async (c) => {
6610
6763
  const { accountId, accountDir } = account;
6611
6764
  let agentName = "Maxy";
6612
6765
  const brandPath = PLATFORM_ROOT5 ? resolve8(PLATFORM_ROOT5, "config", "brand.json") : "";
6613
- if (brandPath && existsSync8(brandPath)) {
6766
+ if (brandPath && existsSync9(brandPath)) {
6614
6767
  try {
6615
- const brand = JSON.parse(readFileSync8(brandPath, "utf-8"));
6768
+ const brand = JSON.parse(readFileSync9(brandPath, "utf-8"));
6616
6769
  if (brand.productName) agentName = brand.productName;
6617
6770
  } catch (err) {
6618
6771
  console.error(`[onboarding-skip] brand.json read failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -6620,8 +6773,8 @@ app8.post("/skip", async (c) => {
6620
6773
  }
6621
6774
  const soulPath = resolve8(accountDir, "agents", "admin", "SOUL.md");
6622
6775
  try {
6623
- mkdirSync3(dirname2(soulPath), { recursive: true });
6624
- writeFileSync4(soulPath, `You are ${agentName}, an AI operations manager.
6776
+ mkdirSync4(dirname3(soulPath), { recursive: true });
6777
+ writeFileSync5(soulPath, `You are ${agentName}, an AI operations manager.
6625
6778
  `);
6626
6779
  console.log(`[onboarding-skip] wrote SOUL.md: ${soulPath}`);
6627
6780
  } catch (err) {
@@ -6665,9 +6818,9 @@ app8.post("/skip", async (c) => {
6665
6818
  var onboarding_default = app8;
6666
6819
 
6667
6820
  // server/routes/client-error.ts
6668
- import { appendFileSync, existsSync as existsSync9, renameSync, statSync as statSync2 } from "fs";
6669
- import { join as join6 } from "path";
6670
- var CLIENT_ERRORS_LOG = join6(LOG_DIR, "client-errors.log");
6821
+ import { appendFileSync, existsSync as existsSync10, renameSync as renameSync2, statSync as statSync3 } from "fs";
6822
+ import { join as join7 } from "path";
6823
+ var CLIENT_ERRORS_LOG = join7(LOG_DIR, "client-errors.log");
6671
6824
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
6672
6825
  var MAX_BODY_SIZE = 8 * 1024;
6673
6826
  var MAX_STACK_LEN = 2e3;
@@ -6710,10 +6863,10 @@ function stackHead(stack) {
6710
6863
  }
6711
6864
  function rotateIfNeeded() {
6712
6865
  try {
6713
- if (!existsSync9(CLIENT_ERRORS_LOG)) return;
6714
- const stats = statSync2(CLIENT_ERRORS_LOG);
6866
+ if (!existsSync10(CLIENT_ERRORS_LOG)) return;
6867
+ const stats = statSync3(CLIENT_ERRORS_LOG);
6715
6868
  if (stats.size < MAX_LOG_SIZE) return;
6716
- renameSync(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
6869
+ renameSync2(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
6717
6870
  } catch (err) {
6718
6871
  console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
6719
6872
  }
@@ -6824,18 +6977,53 @@ app9.post("/", async (c) => {
6824
6977
  var client_error_default = app9;
6825
6978
 
6826
6979
  // server/routes/admin/session.ts
6827
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, existsSync as existsSync10 } from "fs";
6980
+ import { readFileSync as readFileSync10, readdirSync as readdirSync4, statSync as statSync4, writeFileSync as writeFileSync6, existsSync as existsSync11 } from "fs";
6981
+ import { join as join8 } from "path";
6828
6982
  import { createHash as createHash2 } from "crypto";
6829
6983
  var deprecationLogged = /* @__PURE__ */ new Set();
6830
6984
  function hashPin2(pin) {
6831
6985
  return createHash2("sha256").update(pin).digest("hex");
6832
6986
  }
6833
6987
  function readUsersFile2() {
6834
- if (!existsSync10(USERS_FILE)) return null;
6835
- const raw = readFileSync9(USERS_FILE, "utf-8").trim();
6988
+ if (!existsSync11(USERS_FILE)) return null;
6989
+ const raw = readFileSync10(USERS_FILE, "utf-8").trim();
6836
6990
  if (!raw) return [];
6837
6991
  return JSON.parse(raw);
6838
6992
  }
6993
+ function scanForOrphanedAccountAdmins(users) {
6994
+ const usersUserIds = new Set(users.map((u) => u.userId));
6995
+ const orphans = [];
6996
+ if (!existsSync11(ACCOUNTS_DIR)) return orphans;
6997
+ let entries;
6998
+ try {
6999
+ entries = readdirSync4(ACCOUNTS_DIR);
7000
+ } catch {
7001
+ return orphans;
7002
+ }
7003
+ for (const entry of entries) {
7004
+ if (entry.startsWith(".")) continue;
7005
+ const accountDir = join8(ACCOUNTS_DIR, entry);
7006
+ try {
7007
+ if (!statSync4(accountDir).isDirectory()) continue;
7008
+ } catch {
7009
+ continue;
7010
+ }
7011
+ const accountJsonPath = join8(accountDir, "account.json");
7012
+ if (!existsSync11(accountJsonPath)) continue;
7013
+ try {
7014
+ const config = JSON.parse(readFileSync10(accountJsonPath, "utf-8"));
7015
+ const admins = config.admins ?? [];
7016
+ for (const a of admins) {
7017
+ if (typeof a.userId === "string" && !usersUserIds.has(a.userId)) {
7018
+ orphans.push(a.userId);
7019
+ }
7020
+ }
7021
+ } catch {
7022
+ continue;
7023
+ }
7024
+ }
7025
+ return orphans;
7026
+ }
6839
7027
  function stripLegacyNameField(users) {
6840
7028
  const dirty = users.some((u) => "name" in u && u.name !== void 0);
6841
7029
  if (!dirty) return;
@@ -6849,7 +7037,7 @@ function stripLegacyNameField(users) {
6849
7037
  }
6850
7038
  }
6851
7039
  try {
6852
- writeFileSync5(USERS_FILE, JSON.stringify(users), { mode: 384 });
7040
+ writeFileSync6(USERS_FILE, JSON.stringify(users), { mode: 384 });
6853
7041
  } catch (err) {
6854
7042
  console.error(`[admin-identity] users-json strip failed: ${err instanceof Error ? err.message : String(err)}`);
6855
7043
  }
@@ -6969,7 +7157,15 @@ app10.post("/", async (c) => {
6969
7157
  }
6970
7158
  const matchedUser = users.find((u) => u.pin === inputHash);
6971
7159
  if (!matchedUser) {
6972
- console.log(`[session] PIN auth failed: no matching user`);
7160
+ const orphanUserIds = scanForOrphanedAccountAdmins(users);
7161
+ if (orphanUserIds.length > 0) {
7162
+ const prefix = orphanUserIds[0].slice(0, 8);
7163
+ console.log(
7164
+ `[session] PIN auth failed: no matching user; account.json admins[] contains userId=${prefix} with no users.json row \u2014 three-store divergence`
7165
+ );
7166
+ } else {
7167
+ console.log(`[session] PIN auth failed: no matching user`);
7168
+ }
6973
7169
  return c.json({ error: "Invalid PIN" }, 401);
6974
7170
  }
6975
7171
  stripLegacyNameField(users);
@@ -7011,8 +7207,8 @@ import { appendFileSync as appendFileSync3 } from "fs";
7011
7207
 
7012
7208
  // app/lib/script-stream-tailer.ts
7013
7209
  import * as childProcess from "child_process";
7014
- import { appendFileSync as appendFileSync2, createReadStream as createReadStream2, mkdirSync as mkdirSync4, statSync as statSync3 } from "fs";
7015
- import { dirname as dirname3 } from "path";
7210
+ import { appendFileSync as appendFileSync2, createReadStream as createReadStream2, mkdirSync as mkdirSync5, statSync as statSync5 } from "fs";
7211
+ import { dirname as dirname4 } from "path";
7016
7212
  import { StringDecoder } from "string_decoder";
7017
7213
  var SCRIPT_STREAM_RE = /^\[([^\]]+)\] \[script:([a-z][a-z0-9-]*)((?::[a-z0-9:_-]+)?)\] (.*)$/;
7018
7214
  function parseLine(line) {
@@ -7030,7 +7226,7 @@ function startScriptStreamTailer(opts) {
7030
7226
  const { path: path2, onEvent, onError } = opts;
7031
7227
  let offset;
7032
7228
  try {
7033
- offset = statSync3(path2).size;
7229
+ offset = statSync5(path2).size;
7034
7230
  } catch {
7035
7231
  offset = 0;
7036
7232
  }
@@ -7049,7 +7245,7 @@ function startScriptStreamTailer(opts) {
7049
7245
  try {
7050
7246
  let size;
7051
7247
  try {
7052
- size = statSync3(path2).size;
7248
+ size = statSync5(path2).size;
7053
7249
  } catch {
7054
7250
  return;
7055
7251
  }
@@ -7121,7 +7317,7 @@ function writeRouteMilestone(streamLogPath, scope, line) {
7121
7317
  }
7122
7318
  const ts = (/* @__PURE__ */ new Date()).toISOString();
7123
7319
  try {
7124
- mkdirSync4(dirname3(streamLogPath), { recursive: true });
7320
+ mkdirSync5(dirname4(streamLogPath), { recursive: true });
7125
7321
  appendFileSync2(streamLogPath, `[${ts}] [script:${scope}] ${line}
7126
7322
  `);
7127
7323
  } catch (err) {
@@ -7297,7 +7493,7 @@ var app11 = new Hono();
7297
7493
  app11.post("/cancel", requireAdminSession, async (c) => {
7298
7494
  const session_key = c.var.sessionKey;
7299
7495
  try {
7300
- const { interruptClient: interruptClient2 } = await import("./client-pool-NBVGONQL.js");
7496
+ const { interruptClient: interruptClient2 } = await import("./client-pool-FM3YJWV5.js");
7301
7497
  await interruptClient2(session_key);
7302
7498
  return c.json({ ok: true });
7303
7499
  } catch (err) {
@@ -7692,22 +7888,22 @@ app12.post("/", requireAdminSession, async (c) => {
7692
7888
  var compact_default = app12;
7693
7889
 
7694
7890
  // server/routes/admin/logs.ts
7695
- import { existsSync as existsSync12, readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync4 } from "fs";
7891
+ import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync6 } from "fs";
7696
7892
  import { resolve as resolve10, basename as basename3 } from "path";
7697
7893
 
7698
7894
  // app/lib/logs-read-resolve.ts
7699
- import { existsSync as existsSync11 } from "fs";
7700
- import { join as join7 } from "path";
7895
+ import { existsSync as existsSync12 } from "fs";
7896
+ import { join as join9 } from "path";
7701
7897
  function resolveConversationLogPaths(fullFilename, preflushFilename, logDirs) {
7702
7898
  const tried = [fullFilename, preflushFilename];
7703
7899
  const hits = [];
7704
7900
  const stalePreflushPaths = [];
7705
7901
  for (const dir of logDirs) {
7706
- const fullPath = join7(dir, fullFilename);
7707
- if (existsSync11(fullPath)) {
7902
+ const fullPath = join9(dir, fullFilename);
7903
+ if (existsSync12(fullPath)) {
7708
7904
  hits.push({ path: fullPath, shape: "full", dir });
7709
- const preflushSibling = join7(dir, preflushFilename);
7710
- if (existsSync11(preflushSibling)) {
7905
+ const preflushSibling = join9(dir, preflushFilename);
7906
+ if (existsSync12(preflushSibling)) {
7711
7907
  stalePreflushPaths.push(preflushSibling);
7712
7908
  }
7713
7909
  }
@@ -7716,8 +7912,8 @@ function resolveConversationLogPaths(fullFilename, preflushFilename, logDirs) {
7716
7912
  return { hits, stalePreflushPaths, tried };
7717
7913
  }
7718
7914
  for (const dir of logDirs) {
7719
- const preflushPath = join7(dir, preflushFilename);
7720
- if (existsSync11(preflushPath)) {
7915
+ const preflushPath = join9(dir, preflushFilename);
7916
+ if (existsSync12(preflushPath)) {
7721
7917
  hits.push({ path: preflushPath, shape: "preflush", dir });
7722
7918
  }
7723
7919
  }
@@ -7748,8 +7944,8 @@ app13.get("/", async (c) => {
7748
7944
  const filePath = resolve10(dir, safe);
7749
7945
  searched.push(filePath);
7750
7946
  try {
7751
- const buffer = readFileSync10(filePath);
7752
- const onDiskBytes = statSync4(filePath).size;
7947
+ const buffer = readFileSync11(filePath);
7948
+ const onDiskBytes = statSync6(filePath).size;
7753
7949
  const headers = {
7754
7950
  "Content-Type": "text/plain; charset=utf-8",
7755
7951
  "Content-Length": String(buffer.byteLength)
@@ -7834,7 +8030,7 @@ app13.get("/", async (c) => {
7834
8030
  try {
7835
8031
  const filename = basename3(hit.path);
7836
8032
  if (stalePreflushCount > 0 && !download) {
7837
- const content = readFileSync10(hit.path, "utf-8");
8033
+ const content = readFileSync11(hit.path, "utf-8");
7838
8034
  return c.json({
7839
8035
  log: content,
7840
8036
  filename,
@@ -7842,8 +8038,8 @@ app13.get("/", async (c) => {
7842
8038
  warnings: stalePreflushPaths.map((path2) => ({ kind: "stale-preflush", path: path2 }))
7843
8039
  });
7844
8040
  }
7845
- const buffer = readFileSync10(hit.path);
7846
- const onDiskBytes = statSync4(hit.path).size;
8041
+ const buffer = readFileSync11(hit.path);
8042
+ const onDiskBytes = statSync6(hit.path).size;
7847
8043
  const headers = {
7848
8044
  "Content-Type": "text/plain; charset=utf-8",
7849
8045
  "Content-Length": String(buffer.byteLength)
@@ -7876,19 +8072,19 @@ app13.get("/", async (c) => {
7876
8072
  const seen = /* @__PURE__ */ new Set();
7877
8073
  const logs = {};
7878
8074
  for (const dir of logDirs) {
7879
- if (!existsSync12(dir)) continue;
8075
+ if (!existsSync13(dir)) continue;
7880
8076
  let files;
7881
8077
  try {
7882
- files = readdirSync3(dir).filter((f) => f.endsWith(".log"));
8078
+ files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
7883
8079
  } catch (err) {
7884
8080
  const reason = err instanceof Error ? err.message : String(err);
7885
8081
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
7886
8082
  continue;
7887
8083
  }
7888
- files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync4(resolve10(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
8084
+ files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync6(resolve10(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
7889
8085
  seen.add(name);
7890
8086
  try {
7891
- const content = readFileSync10(resolve10(dir, name));
8087
+ const content = readFileSync11(resolve10(dir, name));
7892
8088
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
7893
8089
  logs[name] = tail.trim() || "(empty)";
7894
8090
  } catch (err) {
@@ -7927,7 +8123,7 @@ var claude_info_default = app14;
7927
8123
 
7928
8124
  // server/routes/admin/attachment.ts
7929
8125
  import { readFile as readFile3, readdir } from "fs/promises";
7930
- import { existsSync as existsSync13 } from "fs";
8126
+ import { existsSync as existsSync14 } from "fs";
7931
8127
  import { resolve as resolve11 } from "path";
7932
8128
  var app15 = new Hono();
7933
8129
  app15.get("/:attachmentId", requireAdminSession, async (c) => {
@@ -7941,11 +8137,11 @@ app15.get("/:attachmentId", requireAdminSession, async (c) => {
7941
8137
  return new Response("Not found", { status: 404 });
7942
8138
  }
7943
8139
  const dir = resolve11(ATTACHMENTS_ROOT, accountId, attachmentId);
7944
- if (!existsSync13(dir)) {
8140
+ if (!existsSync14(dir)) {
7945
8141
  return new Response("Not found", { status: 404 });
7946
8142
  }
7947
8143
  const metaPath = resolve11(dir, `${attachmentId}.meta.json`);
7948
- if (!existsSync13(metaPath)) {
8144
+ if (!existsSync14(metaPath)) {
7949
8145
  return new Response("Not found", { status: 404 });
7950
8146
  }
7951
8147
  let meta;
@@ -7973,23 +8169,23 @@ var attachment_default = app15;
7973
8169
 
7974
8170
  // server/routes/admin/agents.ts
7975
8171
  import { resolve as resolve12 } from "path";
7976
- import { readdirSync as readdirSync4, readFileSync as readFileSync11, existsSync as existsSync14, rmSync } from "fs";
8172
+ import { readdirSync as readdirSync6, readFileSync as readFileSync12, existsSync as existsSync15, rmSync } from "fs";
7977
8173
  var app16 = new Hono();
7978
8174
  app16.get("/", (c) => {
7979
8175
  const account = resolveAccount();
7980
8176
  if (!account) return c.json({ agents: [] });
7981
8177
  const agentsDir = resolve12(account.accountDir, "agents");
7982
- if (!existsSync14(agentsDir)) return c.json({ agents: [] });
8178
+ if (!existsSync15(agentsDir)) return c.json({ agents: [] });
7983
8179
  const agents = [];
7984
8180
  try {
7985
- const entries = readdirSync4(agentsDir, { withFileTypes: true });
8181
+ const entries = readdirSync6(agentsDir, { withFileTypes: true });
7986
8182
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
7987
8183
  if (!entry.isDirectory()) continue;
7988
8184
  if (entry.name === "admin") continue;
7989
8185
  const configPath2 = resolve12(agentsDir, entry.name, "config.json");
7990
- if (!existsSync14(configPath2)) continue;
8186
+ if (!existsSync15(configPath2)) continue;
7991
8187
  try {
7992
- const config = JSON.parse(readFileSync11(configPath2, "utf-8"));
8188
+ const config = JSON.parse(readFileSync12(configPath2, "utf-8"));
7993
8189
  agents.push({
7994
8190
  slug: entry.name,
7995
8191
  displayName: config.displayName ?? entry.name,
@@ -8016,7 +8212,7 @@ app16.delete("/:slug", async (c) => {
8016
8212
  return c.json({ error: "Invalid agent slug" }, 400);
8017
8213
  }
8018
8214
  const agentDir = resolve12(account.accountDir, "agents", slug);
8019
- if (!existsSync14(agentDir)) {
8215
+ if (!existsSync15(agentDir)) {
8020
8216
  return c.json({ error: "Agent not found" }, 404);
8021
8217
  }
8022
8218
  try {
@@ -8046,7 +8242,7 @@ app16.post("/:slug/project", async (c) => {
8046
8242
  return c.json({ error: "Invalid agent slug" }, 400);
8047
8243
  }
8048
8244
  const agentDir = resolve12(account.accountDir, "agents", slug);
8049
- if (!existsSync14(agentDir)) {
8245
+ if (!existsSync15(agentDir)) {
8050
8246
  return c.json({ error: "Agent not found on disk" }, 404);
8051
8247
  }
8052
8248
  try {
@@ -8062,7 +8258,7 @@ var agents_default = app16;
8062
8258
  // server/routes/admin/sessions.ts
8063
8259
  import crypto2 from "crypto";
8064
8260
  import { resolve as resolvePath } from "path";
8065
- import { appendFileSync as appendFileSync4, existsSync as existsSync15 } from "fs";
8261
+ import { appendFileSync as appendFileSync4, existsSync as existsSync16 } from "fs";
8066
8262
 
8067
8263
  // app/lib/synthetic-marker.ts
8068
8264
  var CLOUDFLARE_MARKER_PREFIX = "Cloudflare setup completed (actionId: ";
@@ -8082,7 +8278,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, conversationId
8082
8278
  let reason = null;
8083
8279
  if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
8084
8280
  else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
8085
- else if (!existsSync15(a.storagePath)) reason = "missing-file";
8281
+ else if (!existsSync16(a.storagePath)) reason = "missing-file";
8086
8282
  if (reason) {
8087
8283
  invalid++;
8088
8284
  try {
@@ -8653,7 +8849,7 @@ var events_default = app20;
8653
8849
  // server/routes/admin/cloudflare.ts
8654
8850
  import { homedir } from "os";
8655
8851
  import { resolve as resolve14 } from "path";
8656
- import { readFileSync as readFileSync13 } from "fs";
8852
+ import { readFileSync as readFileSync14 } from "fs";
8657
8853
 
8658
8854
  // app/lib/dns-label.ts
8659
8855
  var VALID_LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
@@ -8669,14 +8865,14 @@ function isValidDomain(value) {
8669
8865
  }
8670
8866
 
8671
8867
  // app/lib/alias-domains.ts
8672
- import { existsSync as existsSync16, mkdirSync as mkdirSync5, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "fs";
8673
- import { dirname as dirname4 } from "path";
8868
+ import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "fs";
8869
+ import { dirname as dirname5 } from "path";
8674
8870
  import { resolve as resolve13 } from "path";
8675
8871
  var ALIAS_DOMAINS_PATH = resolve13(MAXY_DIR, "alias-domains.json");
8676
8872
  function readExisting() {
8677
- if (!existsSync16(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
8873
+ if (!existsSync17(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
8678
8874
  try {
8679
- const parsed = JSON.parse(readFileSync12(ALIAS_DOMAINS_PATH, "utf-8"));
8875
+ const parsed = JSON.parse(readFileSync13(ALIAS_DOMAINS_PATH, "utf-8"));
8680
8876
  if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
8681
8877
  return new Set(parsed.filter((h) => typeof h === "string"));
8682
8878
  } catch {
@@ -8687,8 +8883,8 @@ function addAliasDomain(hostname2) {
8687
8883
  const existing = readExisting();
8688
8884
  if (existing.has(hostname2)) return;
8689
8885
  existing.add(hostname2);
8690
- mkdirSync5(dirname4(ALIAS_DOMAINS_PATH), { recursive: true });
8691
- writeFileSync6(ALIAS_DOMAINS_PATH, JSON.stringify([...existing], null, 2) + "\n", "utf-8");
8886
+ mkdirSync6(dirname5(ALIAS_DOMAINS_PATH), { recursive: true });
8887
+ writeFileSync7(ALIAS_DOMAINS_PATH, JSON.stringify([...existing], null, 2) + "\n", "utf-8");
8692
8888
  }
8693
8889
 
8694
8890
  // app/lib/cloudflare-setup-types.ts
@@ -8703,7 +8899,7 @@ function loadBrandInfo() {
8703
8899
  const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
8704
8900
  const brandPath = resolve14(platformRoot2, "config", "brand.json");
8705
8901
  try {
8706
- const parsed = JSON.parse(readFileSync13(brandPath, "utf-8"));
8902
+ const parsed = JSON.parse(readFileSync14(brandPath, "utf-8"));
8707
8903
  const hostname2 = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
8708
8904
  const configDir2 = typeof parsed.configDir === "string" && parsed.configDir ? parsed.configDir : ".maxy";
8709
8905
  return { hostname: hostname2, configDir: configDir2 };
@@ -8917,8 +9113,8 @@ app21.get("/tunnels", requireAdminSession, async (c) => {
8917
9113
  if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
8918
9114
  streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
8919
9115
  const certPath = resolve14(homedir(), brand.configDir, "cloudflared", "cert.pem");
8920
- const { existsSync: existsSync23 } = await import("fs");
8921
- if (!existsSync23(certPath)) {
9116
+ const { existsSync: existsSync24 } = await import("fs");
9117
+ if (!existsSync24(certPath)) {
8922
9118
  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.`);
8923
9119
  }
8924
9120
  const result = await runFormSpawn({
@@ -9208,7 +9404,7 @@ var cloudflare_default = app21;
9208
9404
  import { createReadStream as createReadStream3 } from "fs";
9209
9405
  import { readdir as readdir2, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
9210
9406
  import { realpathSync as realpathSync4 } from "fs";
9211
- import { basename as basename4, dirname as dirname5, join as join8, resolve as resolve16, sep as sep2 } from "path";
9407
+ import { basename as basename4, dirname as dirname6, join as join10, resolve as resolve16, sep as sep2 } from "path";
9212
9408
  import { Readable as Readable2 } from "stream";
9213
9409
 
9214
9410
  // app/lib/data-path.ts
@@ -9566,7 +9762,7 @@ async function cascadeDeleteDocument(params) {
9566
9762
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9567
9763
  async function readMeta(absDir, baseName) {
9568
9764
  try {
9569
- const raw = await readFile4(join8(absDir, `${baseName}.meta.json`), "utf8");
9765
+ const raw = await readFile4(join10(absDir, `${baseName}.meta.json`), "utf8");
9570
9766
  const parsed = JSON.parse(raw);
9571
9767
  if (typeof parsed?.filename === "string") {
9572
9768
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -9604,7 +9800,7 @@ async function readAccountNames() {
9604
9800
  }
9605
9801
  async function enrich(absolute, entry, accountNames) {
9606
9802
  if (entry.kind === "directory" && UUID_RE4.test(entry.name)) {
9607
- const meta = await readMeta(join8(absolute, entry.name), entry.name);
9803
+ const meta = await readMeta(join10(absolute, entry.name), entry.name);
9608
9804
  if (meta?.filename) {
9609
9805
  entry.displayName = meta.filename;
9610
9806
  entry.mimeType = meta.mimeType;
@@ -9663,7 +9859,7 @@ app22.get("/", requireAdminSession, async (c) => {
9663
9859
  continue;
9664
9860
  }
9665
9861
  try {
9666
- const entryPath = join8(absolute, name);
9862
+ const entryPath = join10(absolute, name);
9667
9863
  const s = await stat4(entryPath);
9668
9864
  entries.push({
9669
9865
  name,
@@ -9836,7 +10032,7 @@ app22.delete("/", requireAdminSession, async (c) => {
9836
10032
  }
9837
10033
  const dot = base.lastIndexOf(".");
9838
10034
  const stem = dot === -1 ? base : base.slice(0, dot);
9839
- const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join8(dirname5(absolute), `${stem}.meta.json`) : null;
10035
+ const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join10(dirname6(absolute), `${stem}.meta.json`) : null;
9840
10036
  await unlink2(absolute);
9841
10037
  if (sidecarPath) {
9842
10038
  try {
@@ -11458,7 +11654,7 @@ var adherence_default = app30;
11458
11654
  import neo4j3 from "neo4j-driver";
11459
11655
  import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
11460
11656
  import { resolve as resolve17, relative as relative2, isAbsolute } from "path";
11461
- import { existsSync as existsSync17 } from "fs";
11657
+ import { existsSync as existsSync18 } from "fs";
11462
11658
  var LIMIT = 50;
11463
11659
  var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
11464
11660
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
@@ -11606,7 +11802,7 @@ async function fetchAgentTemplateRows(accountDir) {
11606
11802
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
11607
11803
  const names = /* @__PURE__ */ new Set();
11608
11804
  for (const dir of [overrideDir, bundledDir]) {
11609
- if (!existsSync17(dir)) continue;
11805
+ if (!existsSync18(dir)) continue;
11610
11806
  try {
11611
11807
  const entries = await readdir3(dir);
11612
11808
  for (const entry of entries) {
@@ -11621,7 +11817,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
11621
11817
  }
11622
11818
  async function readAgentTemplateRow(inp) {
11623
11819
  let chosenPath = null;
11624
- if (existsSync17(inp.overridePath)) {
11820
+ if (existsSync18(inp.overridePath)) {
11625
11821
  try {
11626
11822
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
11627
11823
  chosenPath = inp.overridePath;
@@ -11632,7 +11828,7 @@ async function readAgentTemplateRow(inp) {
11632
11828
  );
11633
11829
  return null;
11634
11830
  }
11635
- } else if (existsSync17(inp.bundledPath)) {
11831
+ } else if (existsSync18(inp.bundledPath)) {
11636
11832
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
11637
11833
  console.error(
11638
11834
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -11674,7 +11870,7 @@ var sidebar_artefacts_default = app31;
11674
11870
  // server/routes/admin/sidebar-artefact-save.ts
11675
11871
  import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
11676
11872
  import { resolve as resolve18 } from "path";
11677
- import { existsSync as existsSync18 } from "fs";
11873
+ import { existsSync as existsSync19 } from "fs";
11678
11874
  var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
11679
11875
  var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
11680
11876
  var app32 = new Hono();
@@ -11738,7 +11934,7 @@ async function resolveSavePath(id, accountId, accountDir) {
11738
11934
  }
11739
11935
  if (UUID_RE5.test(id)) {
11740
11936
  const dir = resolve18(ATTACHMENTS_ROOT, accountId, id);
11741
- if (!existsSync18(dir)) {
11937
+ if (!existsSync19(dir)) {
11742
11938
  return { kind: "reject", status: 400, reason: "not-found" };
11743
11939
  }
11744
11940
  try {
@@ -11762,7 +11958,7 @@ var sidebar_artefact_save_default = app32;
11762
11958
 
11763
11959
  // server/routes/admin/sidebar-artefact-content.ts
11764
11960
  import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
11765
- import { existsSync as existsSync19 } from "fs";
11961
+ import { existsSync as existsSync20 } from "fs";
11766
11962
  import { resolve as resolve19 } from "path";
11767
11963
  var UUID_RE6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
11768
11964
  var app33 = new Hono();
@@ -11776,7 +11972,7 @@ app33.get("/", requireAdminSession, async (c) => {
11776
11972
  return new Response("Not found", { status: 404 });
11777
11973
  }
11778
11974
  const dir = resolve19(ATTACHMENTS_ROOT, accountId, id);
11779
- if (!existsSync19(dir)) {
11975
+ if (!existsSync20(dir)) {
11780
11976
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
11781
11977
  return new Response("Not found", { status: 404 });
11782
11978
  }
@@ -11810,14 +12006,14 @@ app33.get("/", requireAdminSession, async (c) => {
11810
12006
  var sidebar_artefact_content_default = app33;
11811
12007
 
11812
12008
  // server/routes/admin/health.ts
11813
- import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
11814
- import { resolve as resolve20, join as join9 } from "path";
12009
+ import { existsSync as existsSync21, readFileSync as readFileSync15 } from "fs";
12010
+ import { resolve as resolve20, join as join11 } from "path";
11815
12011
  var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
11816
12012
  var brandHostname = "maxy";
11817
- var brandJsonPath = join9(PLATFORM_ROOT7, "config", "brand.json");
11818
- if (existsSync20(brandJsonPath)) {
12013
+ var brandJsonPath = join11(PLATFORM_ROOT7, "config", "brand.json");
12014
+ if (existsSync21(brandJsonPath)) {
11819
12015
  try {
11820
- const brand = JSON.parse(readFileSync14(brandJsonPath, "utf-8"));
12016
+ const brand = JSON.parse(readFileSync15(brandJsonPath, "utf-8"));
11821
12017
  if (brand.hostname) brandHostname = brand.hostname;
11822
12018
  } catch {
11823
12019
  }
@@ -11826,8 +12022,8 @@ var VERSION_FILE = resolve20(PLATFORM_ROOT7, `config/.${brandHostname}-version`)
11826
12022
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
11827
12023
  var PROBE_TIMEOUT_MS = 1e3;
11828
12024
  function readVersion() {
11829
- if (!existsSync20(VERSION_FILE)) return "unknown";
11830
- return readFileSync14(VERSION_FILE, "utf-8").trim() || "unknown";
12025
+ if (!existsSync21(VERSION_FILE)) return "unknown";
12026
+ return readFileSync15(VERSION_FILE, "utf-8").trim() || "unknown";
11831
12027
  }
11832
12028
  async function probeConversationDb() {
11833
12029
  let session;
@@ -11907,7 +12103,7 @@ app35.route("/health-brand", health_default2);
11907
12103
  var admin_default = app35;
11908
12104
 
11909
12105
  // server/routes/sites.ts
11910
- import { existsSync as existsSync21, readFileSync as readFileSync15, realpathSync as realpathSync5, statSync as statSync5 } from "fs";
12106
+ import { existsSync as existsSync22, readFileSync as readFileSync16, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
11911
12107
  import { resolve as resolve21 } from "path";
11912
12108
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
11913
12109
  var MIME = {
@@ -11974,7 +12170,7 @@ app36.get("/:rel{.*}", (c) => {
11974
12170
  }
11975
12171
  let stat7;
11976
12172
  try {
11977
- stat7 = existsSync21(filePath) ? statSync5(filePath) : null;
12173
+ stat7 = existsSync22(filePath) ? statSync7(filePath) : null;
11978
12174
  } catch {
11979
12175
  stat7 = null;
11980
12176
  }
@@ -11987,7 +12183,7 @@ app36.get("/:rel{.*}", (c) => {
11987
12183
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
11988
12184
  return c.text("Forbidden", 403);
11989
12185
  }
11990
- if (!existsSync21(filePath)) {
12186
+ if (!existsSync22(filePath)) {
11991
12187
  console.error(`[sites] not-found path=${reqPath} status=404`);
11992
12188
  return c.text("Not found", 404);
11993
12189
  }
@@ -12006,7 +12202,7 @@ app36.get("/:rel{.*}", (c) => {
12006
12202
  }
12007
12203
  let body;
12008
12204
  try {
12009
- body = readFileSync15(realPath);
12205
+ body = readFileSync16(realPath);
12010
12206
  } catch (err) {
12011
12207
  const code = err?.code;
12012
12208
  if (code === "EISDIR") {
@@ -12138,14 +12334,14 @@ function clientFrom(c) {
12138
12334
  );
12139
12335
  }
12140
12336
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
12141
- var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join10(PLATFORM_ROOT8, "config", "brand.json") : "";
12337
+ var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join12(PLATFORM_ROOT8, "config", "brand.json") : "";
12142
12338
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
12143
- if (BRAND_JSON_PATH && !existsSync22(BRAND_JSON_PATH)) {
12339
+ if (BRAND_JSON_PATH && !existsSync23(BRAND_JSON_PATH)) {
12144
12340
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
12145
12341
  }
12146
- if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
12342
+ if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
12147
12343
  try {
12148
- const parsed = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
12344
+ const parsed = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
12149
12345
  BRAND = { ...BRAND, ...parsed };
12150
12346
  } catch (err) {
12151
12347
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -12164,11 +12360,11 @@ var brandLoginOpts = {
12164
12360
  bodyFont: BRAND.defaultFonts?.body,
12165
12361
  logoContainsName: !!BRAND.logoContainsName
12166
12362
  };
12167
- var ALIAS_DOMAINS_PATH2 = join10(homedir2(), BRAND.configDir, "alias-domains.json");
12363
+ var ALIAS_DOMAINS_PATH2 = join12(homedir2(), BRAND.configDir, "alias-domains.json");
12168
12364
  function loadAliasDomains() {
12169
12365
  try {
12170
- if (!existsSync22(ALIAS_DOMAINS_PATH2)) return null;
12171
- const parsed = JSON.parse(readFileSync16(ALIAS_DOMAINS_PATH2, "utf-8"));
12366
+ if (!existsSync23(ALIAS_DOMAINS_PATH2)) return null;
12367
+ const parsed = JSON.parse(readFileSync17(ALIAS_DOMAINS_PATH2, "utf-8"));
12172
12368
  if (!Array.isArray(parsed)) {
12173
12369
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
12174
12370
  return null;
@@ -12514,14 +12710,14 @@ app37.get("/agent-assets/:slug/:filename", (c) => {
12514
12710
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
12515
12711
  return c.text("Forbidden", 403);
12516
12712
  }
12517
- if (!existsSync22(filePath)) {
12713
+ if (!existsSync23(filePath)) {
12518
12714
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
12519
12715
  return c.text("Not found", 404);
12520
12716
  }
12521
12717
  const ext = "." + filename.split(".").pop()?.toLowerCase();
12522
12718
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
12523
12719
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
12524
- const body = readFileSync16(filePath);
12720
+ const body = readFileSync17(filePath);
12525
12721
  return c.body(body, 200, {
12526
12722
  "Content-Type": contentType,
12527
12723
  "Cache-Control": "public, max-age=3600"
@@ -12544,14 +12740,14 @@ app37.get("/generated/:filename", (c) => {
12544
12740
  console.error(`[generated] serve file=${filename} status=403`);
12545
12741
  return c.text("Forbidden", 403);
12546
12742
  }
12547
- if (!existsSync22(filePath)) {
12743
+ if (!existsSync23(filePath)) {
12548
12744
  console.error(`[generated] serve file=${filename} status=404`);
12549
12745
  return c.text("Not found", 404);
12550
12746
  }
12551
12747
  const ext = "." + filename.split(".").pop()?.toLowerCase();
12552
12748
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
12553
12749
  console.log(`[generated] serve file=${filename} status=200`);
12554
- const body = readFileSync16(filePath);
12750
+ const body = readFileSync17(filePath);
12555
12751
  return c.body(body, 200, {
12556
12752
  "Content-Type": contentType,
12557
12753
  "Cache-Control": "public, max-age=86400"
@@ -12561,9 +12757,9 @@ app37.route("/sites", sites_default);
12561
12757
  var htmlCache = /* @__PURE__ */ new Map();
12562
12758
  var brandLogoPath = "/brand/maxy-monochrome.png";
12563
12759
  var brandIconPath = "/brand/maxy-monochrome.png";
12564
- if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
12760
+ if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
12565
12761
  try {
12566
- const fullBrand = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
12762
+ const fullBrand = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
12567
12763
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
12568
12764
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
12569
12765
  } catch {
@@ -12580,9 +12776,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
12580
12776
  function readInstalledVersion() {
12581
12777
  try {
12582
12778
  if (!PLATFORM_ROOT8) return "unknown";
12583
- const versionFile = join10(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
12584
- if (!existsSync22(versionFile)) return "unknown";
12585
- const content = readFileSync16(versionFile, "utf-8").trim();
12779
+ const versionFile = join12(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
12780
+ if (!existsSync23(versionFile)) return "unknown";
12781
+ const content = readFileSync17(versionFile, "utf-8").trim();
12586
12782
  return content || "unknown";
12587
12783
  } catch {
12588
12784
  return "unknown";
@@ -12623,7 +12819,7 @@ var clientErrorReporterScript = `<script>
12623
12819
  function cachedHtml(file) {
12624
12820
  let html = htmlCache.get(file);
12625
12821
  if (!html) {
12626
- html = readFileSync16(resolve22(process.cwd(), "public", file), "utf-8");
12822
+ html = readFileSync17(resolve22(process.cwd(), "public", file), "utf-8");
12627
12823
  const productNameEsc = escapeHtml(BRAND.productName);
12628
12824
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
12629
12825
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -12639,26 +12835,26 @@ ${clientErrorReporterScript}
12639
12835
  }
12640
12836
  var brandedHtmlCache = /* @__PURE__ */ new Map();
12641
12837
  function loadBrandingCache(agentSlug) {
12642
- const configDir2 = join10(homedir2(), BRAND.configDir);
12838
+ const configDir2 = join12(homedir2(), BRAND.configDir);
12643
12839
  try {
12644
- const accountJsonPath = join10(configDir2, "account.json");
12645
- if (!existsSync22(accountJsonPath)) return null;
12646
- const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
12840
+ const accountJsonPath = join12(configDir2, "account.json");
12841
+ if (!existsSync23(accountJsonPath)) return null;
12842
+ const account = JSON.parse(readFileSync17(accountJsonPath, "utf-8"));
12647
12843
  const accountId = account.accountId;
12648
12844
  if (!accountId) return null;
12649
- const cachePath = join10(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
12650
- if (!existsSync22(cachePath)) return null;
12651
- return JSON.parse(readFileSync16(cachePath, "utf-8"));
12845
+ const cachePath = join12(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
12846
+ if (!existsSync23(cachePath)) return null;
12847
+ return JSON.parse(readFileSync17(cachePath, "utf-8"));
12652
12848
  } catch {
12653
12849
  return null;
12654
12850
  }
12655
12851
  }
12656
12852
  function resolveDefaultSlug() {
12657
12853
  try {
12658
- const configDir2 = join10(homedir2(), BRAND.configDir);
12659
- const accountJsonPath = join10(configDir2, "account.json");
12660
- if (!existsSync22(accountJsonPath)) return null;
12661
- const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
12854
+ const configDir2 = join12(homedir2(), BRAND.configDir);
12855
+ const accountJsonPath = join12(configDir2, "account.json");
12856
+ if (!existsSync23(accountJsonPath)) return null;
12857
+ const account = JSON.parse(readFileSync17(accountJsonPath, "utf-8"));
12662
12858
  return account.defaultAgent || null;
12663
12859
  } catch {
12664
12860
  return null;
@@ -12731,7 +12927,7 @@ app37.use("/vnc-popout.html", logViewerFetch);
12731
12927
  app37.get("/vnc-popout.html", (c) => {
12732
12928
  let html = htmlCache.get("vnc-popout.html");
12733
12929
  if (!html) {
12734
- html = readFileSync16(resolve22(process.cwd(), "public", "vnc-popout.html"), "utf-8");
12930
+ html = readFileSync17(resolve22(process.cwd(), "public", "vnc-popout.html"), "utf-8");
12735
12931
  const name = escapeHtml(BRAND.productName);
12736
12932
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
12737
12933
  html = html.replace("</head>", ` ${brandScript}
@@ -12784,11 +12980,15 @@ app37.get("/:slug", async (c, next) => {
12784
12980
  }
12785
12981
  await next();
12786
12982
  });
12983
+ if (brandFaviconPath !== "/favicon.ico") {
12984
+ app37.get("/favicon.ico", (c) => c.redirect(brandFaviconPath, 302));
12985
+ }
12787
12986
  app37.use("/*", serveStatic({ root: "./public" }));
12788
12987
  var port = parseInt(process.env.MAXY_UI_INTERNAL_PORT ?? process.env.PORT ?? "19199", 10);
12789
12988
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
12790
12989
  var httpServer = serve({ fetch: app37.fetch, port, hostname });
12791
12990
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
12991
+ console.log("[boot] auth-mode summary: oauth=8 api-key=1 (api-key consumer: invokePublicAgent only)");
12792
12992
  var SUBAPP_MANIFEST = [
12793
12993
  { prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
12794
12994
  { prefix: "/api/session", file: "server/routes/session.ts", subapp: session_default },
@@ -12818,11 +13018,20 @@ try {
12818
13018
  } catch (err) {
12819
13019
  console.error(`[route-shadow] introspection unavailable: ${err instanceof Error ? err.message : String(err)}`);
12820
13020
  }
13021
+ try {
13022
+ checkAdminAuthInvariant({
13023
+ usersFile: USERS_FILE,
13024
+ accountsDir: ACCOUNTS_DIR,
13025
+ tag: "admin-invariant"
13026
+ });
13027
+ } catch (err) {
13028
+ console.error(`[admin-invariant] check threw \u2014 proceeding with boot: ${err instanceof Error ? err.message : String(err)}`);
13029
+ }
12821
13030
  (async () => {
12822
13031
  try {
12823
13032
  let userId = "";
12824
- if (existsSync22(USERS_FILE)) {
12825
- const users = JSON.parse(readFileSync16(USERS_FILE, "utf-8").trim() || "[]");
13033
+ if (existsSync23(USERS_FILE)) {
13034
+ const users = JSON.parse(readFileSync17(USERS_FILE, "utf-8").trim() || "[]");
12826
13035
  userId = users[0]?.userId ?? "";
12827
13036
  }
12828
13037
  await backfillNullUserIdConversations(userId);
@@ -12855,7 +13064,7 @@ autoDeliverPremiumPlugins(bootEntitlement?.purchasedPlugins ?? void 0);
12855
13064
  (async () => {
12856
13065
  if (!bootAccount) return;
12857
13066
  try {
12858
- const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-R4FIORFL.js");
13067
+ const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-FSPEJOTH.js");
12859
13068
  const result = await recoverRunningCloudflareTasks(
12860
13069
  bootAccount.accountId,
12861
13070
  configDirForWhatsApp,
@@ -12905,7 +13114,7 @@ if (bootAccountConfig?.whatsapp) {
12905
13114
  }
12906
13115
  init({
12907
13116
  configDir: configDirForWhatsApp,
12908
- platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ?? join10(__dirname, "..")),
13117
+ platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ?? join12(__dirname, "..")),
12909
13118
  accountConfig: bootAccountConfig,
12910
13119
  onMessage: async (msg) => {
12911
13120
  try {