@rubytech/create-maxy-code 0.1.108 → 0.1.110

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 (124) hide show
  1. package/dist/index.js +11 -125
  2. package/dist/snap-chromium.js +1 -2
  3. package/dist/uninstall.js +10 -9
  4. package/package.json +1 -1
  5. package/payload/platform/plugins/admin/PLUGIN.md +1 -0
  6. package/payload/platform/plugins/admin/mcp/dist/index.js +1 -1
  7. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  8. package/payload/platform/plugins/admin/skills/upgrade/SKILL.md +34 -0
  9. package/payload/platform/plugins/cloudflare/.claude-plugin/plugin.json +1 -1
  10. package/payload/platform/plugins/cloudflare/PLUGIN.md +9 -16
  11. package/payload/platform/plugins/cloudflare/mcp/dist/index.js +7 -12
  12. package/payload/platform/plugins/cloudflare/mcp/dist/index.js.map +1 -1
  13. package/payload/platform/plugins/cloudflare/references/dashboard-guide.md +3 -3
  14. package/payload/platform/plugins/cloudflare/references/manual-setup.md +16 -51
  15. package/payload/platform/plugins/cloudflare/references/reset-guide.md +24 -25
  16. package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +29 -144
  17. package/payload/platform/plugins/docs/references/admin-session.md +1 -1
  18. package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
  19. package/payload/platform/plugins/docs/references/cloudflare.md +20 -29
  20. package/payload/platform/plugins/docs/references/platform.md +4 -22
  21. package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
  22. package/payload/platform/plugins/docs/references/troubleshooting.md +4 -316
  23. package/payload/platform/plugins/venture-studio/PLUGIN.md +35 -4
  24. package/payload/platform/plugins/venture-studio/bin/scaffold.sh +104 -0
  25. package/payload/platform/plugins/venture-studio/skills/investor-data-room/SKILL.md +3 -1
  26. package/payload/platform/plugins/work/mcp/dist/cli/project-create-cli.d.ts +2 -0
  27. package/payload/platform/plugins/work/mcp/dist/cli/project-create-cli.d.ts.map +1 -0
  28. package/payload/platform/plugins/work/mcp/dist/cli/project-create-cli.js +78 -0
  29. package/payload/platform/plugins/work/mcp/dist/cli/project-create-cli.js.map +1 -0
  30. package/payload/platform/scripts/check-no-task-id-leaks.mjs +1 -1
  31. package/payload/platform/scripts/vnc.sh +4 -3
  32. package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
  33. package/payload/premium-plugins/venture-studio/PLUGIN.md +35 -4
  34. package/payload/premium-plugins/venture-studio/bin/scaffold.sh +104 -0
  35. package/payload/premium-plugins/venture-studio/skills/investor-data-room/SKILL.md +3 -1
  36. package/payload/server/{chunk-AGFS3TVN.js → chunk-FSPPVVWM.js} +1303 -496
  37. package/payload/server/maxy-edge.js +21 -259
  38. package/payload/server/public/assets/{ChatInput-DJsqm_Gf.js → ChatInput-CsnIedhS.js} +1 -5
  39. package/payload/server/public/assets/{Checkbox-DGZG9BKc.js → Checkbox-CWugFyFT.js} +1 -1
  40. package/payload/server/public/assets/admin-D3gZuyUn.js +217 -0
  41. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-Dw16BhiX.js → architectureDiagram-Q4EWVU46-CeTRKWDb.js} +1 -1
  42. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DIOpmf5Y.js → blockDiagram-DXYQGD6D-DeeIX5U3.js} +1 -1
  43. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Tdb_HZeX.js → c4Diagram-AHTNJAMY-CFsqZuil.js} +1 -1
  44. package/payload/server/public/assets/channel-CrSx5mnG.js +1 -0
  45. package/payload/server/public/assets/{chunk-336JU56O-CebpwDDe.js → chunk-336JU56O-DpIXuFM0.js} +2 -2
  46. package/payload/server/public/assets/{chunk-426QAEUC-BtRCmfDU.js → chunk-426QAEUC-Qk8qqrvA.js} +1 -1
  47. package/payload/server/public/assets/{chunk-4TB4RGXK-BZ3GEWs3.js → chunk-4TB4RGXK-DtM8-CUn.js} +1 -1
  48. package/payload/server/public/assets/{chunk-5FUZZQ4R-iDI6Xu0U.js → chunk-5FUZZQ4R-CrSQ4ySU.js} +1 -1
  49. package/payload/server/public/assets/{chunk-5PVQY5BW-SQD_EpYa.js → chunk-5PVQY5BW-Bn2nQwdj.js} +1 -1
  50. package/payload/server/public/assets/{chunk-EDXVE4YY-CtCcA7_e.js → chunk-EDXVE4YY-CzCPnR0P.js} +1 -1
  51. package/payload/server/public/assets/{chunk-ENJZ2VHE-pXVGVCbb.js → chunk-ENJZ2VHE-CgZj9RoG.js} +1 -1
  52. package/payload/server/public/assets/{chunk-ICPOFSXX-Dkzg9o2N.js → chunk-ICPOFSXX-wy-eNjwW.js} +1 -1
  53. package/payload/server/public/assets/{chunk-OYMX7WX6-1ZZWzf9F.js → chunk-OYMX7WX6-CMmJtL8S.js} +1 -1
  54. package/payload/server/public/assets/{chunk-U2HBQHQK-CpQ3kzO0.js → chunk-U2HBQHQK-CFCW7OaT.js} +1 -1
  55. package/payload/server/public/assets/{chunk-X2U36JSP-C2LkxroC.js → chunk-X2U36JSP-Bgh-CJSN.js} +1 -1
  56. package/payload/server/public/assets/{chunk-YZCP3GAM-Bl5jBOt5.js → chunk-YZCP3GAM-BXKwZ4vN.js} +1 -1
  57. package/payload/server/public/assets/{chunk-ZZ45TVLE-CHtnptPS.js → chunk-ZZ45TVLE-BiOuK5NP.js} +1 -1
  58. package/payload/server/public/assets/classDiagram-6PBFFD2Q-C3IDJsqN.js +1 -0
  59. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BOIrJ5Zb.js +1 -0
  60. package/payload/server/public/assets/clone-P8Fkz7JD.js +1 -0
  61. package/payload/server/public/assets/{dagre-BziN0Nkh.js → dagre-DyCxa9Q2.js} +1 -1
  62. package/payload/server/public/assets/{dagre-KV5264BT-B7OG1g1Y.js → dagre-KV5264BT-Cffo_hmf.js} +1 -1
  63. package/payload/server/public/assets/data-DRfwJPja.js +1 -0
  64. package/payload/server/public/assets/{diagram-5BDNPKRD-Bf31nIDs.js → diagram-5BDNPKRD-Bt93Du3V.js} +1 -1
  65. package/payload/server/public/assets/{diagram-G4DWMVQ6-DQu85hhH.js → diagram-G4DWMVQ6-v4r-tBsC.js} +1 -1
  66. package/payload/server/public/assets/{diagram-MMDJMWI5-5tstbs4y.js → diagram-MMDJMWI5-DKrVPOP-.js} +1 -1
  67. package/payload/server/public/assets/{diagram-TYMM5635--MOV1U4o.js → diagram-TYMM5635-B1PzWQb9.js} +1 -1
  68. package/payload/server/public/assets/{erDiagram-SMLLAGMA-BtAnOJmd.js → erDiagram-SMLLAGMA-ClQzsQAs.js} +1 -1
  69. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CybiCIih.js → flowDiagram-DWJPFMVM-h3IbpN_7.js} +1 -1
  70. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-B44jN7Cy.js → ganttDiagram-T4ZO3ILL-ClaxOJi8.js} +1 -1
  71. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CT7iYcwg.js → gitGraphDiagram-UUTBAWPF-pM-U4ClD.js} +1 -1
  72. package/payload/server/public/assets/graph-B4FFYwus.js +1 -0
  73. package/payload/server/public/assets/graph-labels-Cpk9Ktt0.js +1 -0
  74. package/payload/server/public/assets/{graphlib-DP4o0pYL.js → graphlib-CwimOv_M.js} +1 -1
  75. package/payload/server/public/assets/{infoDiagram-42DDH7IO-CvxFpFHN.js → infoDiagram-42DDH7IO-DcO3Giwe.js} +1 -1
  76. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CUwWLPeR.js → ishikawaDiagram-UXIWVN3A-BcdSL5VS.js} +1 -1
  77. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-y-OnGgLi.js → journeyDiagram-VCZTEJTY-CYahHYzf.js} +1 -1
  78. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BhrSe8R4.js → kanban-definition-6JOO6SKY-Cl5KhoS4.js} +1 -1
  79. package/payload/server/public/assets/lib--yuBd0Xi.js +33 -0
  80. package/payload/server/public/assets/{line-C9uS7z4J.js → line-d_2oTxLp.js} +1 -1
  81. package/payload/server/public/assets/{mermaid-parser.core-Cg4ZdKp-.js → mermaid-parser.core-CMMDGv3x.js} +1 -1
  82. package/payload/server/public/assets/{mermaid.core-BHdKOsex.js → mermaid.core-DK9ENGbr.js} +3 -3
  83. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-NBYiXHo7.js → mindmap-definition-QFDTVHPH-mA3x3MFG.js} +1 -1
  84. package/payload/server/public/assets/page-CgDmg_fX.js +1 -0
  85. package/payload/server/public/assets/{page-D9YpwhIu.js → page-D9lluVl7.js} +2 -2
  86. package/payload/server/public/assets/{pieDiagram-DEJITSTG-CbojC64C.js → pieDiagram-DEJITSTG-CW1nGFlY.js} +1 -1
  87. package/payload/server/public/assets/public-DdLMkNdS.js +7 -0
  88. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CnnoZXcL.js → quadrantDiagram-34T5L4WZ-DI5igJhR.js} +1 -1
  89. package/payload/server/public/assets/{requirementDiagram-MS252O5E-DFRFRtyJ.js → requirementDiagram-MS252O5E-DyVeI4e_.js} +1 -1
  90. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DU5gcpzO.js → sankeyDiagram-XADWPNL6-CCTTBYKY.js} +1 -1
  91. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BN7HZ6Hq.js → sequenceDiagram-FGHM5R23-hVVf35ly.js} +1 -1
  92. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DG6cCjvg.js → stateDiagram-FHFEXIEX-CSLuQDUX.js} +1 -1
  93. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-C5JejhQU.js +1 -0
  94. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-qmV-8SEV.js → timeline-definition-GMOUNBTQ-sxC3W8Q4.js} +1 -1
  95. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BMXQ1s3n.js → vennDiagram-DHZGUBPP-Ro-ton6Z.js} +1 -1
  96. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CoAdP1Gw.js → wardleyDiagram-NUSXRM2D-T-dKD0Zx.js} +1 -1
  97. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CZlfGTEn.js → xychartDiagram-5P7HB3ND-CfProPts.js} +1 -1
  98. package/payload/server/public/data.html +4 -4
  99. package/payload/server/public/graph.html +5 -5
  100. package/payload/server/public/index.html +7 -7
  101. package/payload/server/public/public.html +4 -4
  102. package/payload/server/server.js +299 -1392
  103. package/payload/platform/plugins/cloudflare/scripts/__tests__/tunnel-ingress.test.ts +0 -241
  104. package/payload/platform/plugins/cloudflare/scripts/_stream-log.sh +0 -154
  105. package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.sh +0 -98
  106. package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.ts +0 -749
  107. package/payload/platform/plugins/cloudflare/scripts/reset-tunnel.sh +0 -107
  108. package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +0 -854
  109. package/payload/platform/plugins/cloudflare/scripts/tunnel-ingress.ts +0 -291
  110. package/payload/server/chunk-BDFOTLPW.js +0 -759
  111. package/payload/server/chunk-JRBCOVA4.js +0 -1305
  112. package/payload/server/cloudflare-task-tracker-M5ONAGUT.js +0 -22
  113. package/payload/server/public/assets/admin-BvzMvMGo.js +0 -217
  114. package/payload/server/public/assets/channel-DThrH4QF.js +0 -1
  115. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BC6oGTNX.js +0 -1
  116. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-COwC5Umh.js +0 -1
  117. package/payload/server/public/assets/clone-Chp7hvnA.js +0 -1
  118. package/payload/server/public/assets/data-BAgaPs4j.js +0 -1
  119. package/payload/server/public/assets/graph-Cma7EArf.js +0 -1
  120. package/payload/server/public/assets/graph-labels-DyKk6Sxf.js +0 -1
  121. package/payload/server/public/assets/lib-CpkYtEDz.js +0 -29
  122. package/payload/server/public/assets/page-B4IWl3aZ.js +0 -1
  123. package/payload/server/public/assets/public-BtOXjy3A.js +0 -8
  124. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CvVd1Q_q.js +0 -1
@@ -6,6 +6,7 @@ import {
6
6
  CHROMIUM_PROFILE_DIR,
7
7
  CLAUDE_CREDENTIALS_FILE,
8
8
  COMMERCIAL_MODE,
9
+ GREETING_DIRECTIVE,
9
10
  Hono,
10
11
  LOG_DIR,
11
12
  MAXY_DIR,
@@ -15,37 +16,53 @@ import {
15
16
  VNC_DISPLAY,
16
17
  WEBSOCKIFY_PORT,
17
18
  autoDeliverPremiumPlugins,
18
- browserViewerLog,
19
19
  canAccessAdmin,
20
20
  checkRateLimit,
21
21
  cleanupLeakedPremiumSubs,
22
22
  clearRateLimit,
23
23
  clientIpMiddleware,
24
24
  createRemoteSession,
25
+ deleteAgentProjection,
26
+ deleteConversation,
27
+ embed,
25
28
  emitMissingOnResolve,
29
+ ensureConversation,
30
+ fetchBranding,
26
31
  findMissingPlugins,
27
32
  fingerprintSessionKey,
28
33
  getAccountIdForSession,
34
+ getAgentSessionIdForConversation,
35
+ getConversationClaudeSessionIds,
36
+ getConversationIdByClaudeSessionId,
29
37
  getConversationIdForSession,
38
+ getRecentMessages,
30
39
  getRoleForSession,
40
+ getSession,
31
41
  getSessionKeyByConversationId,
32
42
  getUserIdForSession,
33
43
  getUserNameForSession,
44
+ getUserTimezone,
34
45
  httpLog,
35
- isActionActive,
36
46
  isPasswordValid,
37
47
  isRemoteAuthConfigured,
38
- launchAction,
48
+ linkConversationTranscript,
49
+ listAdminSessions,
39
50
  listValidAccounts,
51
+ loadAdminUserName,
52
+ loadUserProfile,
53
+ persistMessage,
54
+ projectAgent,
40
55
  reconcileEnabledPlugins,
41
56
  recordFailedAttempt,
42
57
  registerSession,
58
+ renameConversation,
43
59
  renderLoginPage,
44
60
  requireAdminSession,
45
61
  requirePortEnv,
46
62
  resolveAccount,
47
63
  resolveClientIp,
48
64
  resolveUserAccounts,
65
+ runAdminUserSelfHeal,
49
66
  safeJson,
50
67
  sanitizeClientCorrId,
51
68
  serve,
@@ -57,45 +74,13 @@ import {
57
74
  unregisterSession,
58
75
  validatePasswordStrength,
59
76
  validateSession,
60
- verifyRemotePassword,
61
- vncLog,
62
- waitForExit,
63
- walkPremiumBundles
64
- } from "./chunk-AGFS3TVN.js";
65
- import {
66
- CLOUDFLARE_TASK_DIAGNOSTICS,
67
- appendCloudflareSteps,
68
- completeCloudflareTask,
69
- findMostRecentTerminalCloudflareTask,
70
- openCloudflareTask,
71
- readTunnelState,
72
- resolveUnitGoneVerdict
73
- } from "./chunk-BDFOTLPW.js";
74
- import {
75
- GREETING_DIRECTIVE,
76
- deleteAgentProjection,
77
- deleteConversation,
78
- embed,
79
- ensureConversation,
80
- fetchBranding,
81
- getAgentSessionIdForConversation,
82
- getConversationClaudeSessionIds,
83
- getConversationIdByClaudeSessionId,
84
- getRecentMessages,
85
- getSession,
86
- getUserTimezone,
87
- linkConversationTranscript,
88
- listAdminSessions,
89
- loadAdminUserName,
90
- loadUserProfile,
91
- persistMessage,
92
- projectAgent,
93
- renameConversation,
94
- runAdminUserSelfHeal,
95
77
  verifyAndGetConversationUpdatedAt,
96
78
  verifyConversationOwnership,
79
+ verifyRemotePassword,
80
+ vncLog,
81
+ walkPremiumBundles,
97
82
  writeAdminUserAndPerson
98
- } from "./chunk-JRBCOVA4.js";
83
+ } from "./chunk-FSPPVVWM.js";
99
84
  import {
100
85
  __commonJS,
101
86
  __toESM
@@ -600,9 +585,9 @@ var serveStatic = (options = { root: "" }) => {
600
585
  };
601
586
 
602
587
  // server/index.ts
603
- import { readFileSync as readFileSync21, existsSync as existsSync23, watchFile } from "fs";
604
- import { resolve as resolve23, join as join14, basename as basename5 } from "path";
605
- import { homedir as homedir5 } from "os";
588
+ import { readFileSync as readFileSync19, existsSync as existsSync23, watchFile } from "fs";
589
+ import { resolve as resolve21, join as join14, basename as basename5 } from "path";
590
+ import { homedir as homedir4 } from "os";
606
591
  import { monitorEventLoopDelay } from "perf_hooks";
607
592
 
608
593
  // app/lib/agent-slug-pattern.ts
@@ -1059,7 +1044,7 @@ var credsSaveQueue = Promise.resolve();
1059
1044
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
1060
1045
  console.error(`${TAG2} draining credential save queue\u2026`);
1061
1046
  const timer2 = new Promise(
1062
- (resolve24) => setTimeout(() => resolve24("timeout"), timeoutMs)
1047
+ (resolve22) => setTimeout(() => resolve22("timeout"), timeoutMs)
1063
1048
  );
1064
1049
  const result = await Promise.race([
1065
1050
  credsSaveQueue.then(() => "drained"),
@@ -1187,11 +1172,11 @@ async function createWaSocket(opts) {
1187
1172
  return sock;
1188
1173
  }
1189
1174
  async function waitForConnection(sock) {
1190
- return new Promise((resolve24, reject) => {
1175
+ return new Promise((resolve22, reject) => {
1191
1176
  const handler = (update) => {
1192
1177
  if (update.connection === "open") {
1193
1178
  sock.ev.off("connection.update", handler);
1194
- resolve24();
1179
+ resolve22();
1195
1180
  }
1196
1181
  if (update.connection === "close") {
1197
1182
  sock.ev.off("connection.update", handler);
@@ -1305,14 +1290,14 @@ ${inspected}`;
1305
1290
  return inspect2(err, INSPECT_OPTS2);
1306
1291
  }
1307
1292
  function withTimeout(label, promise, timeoutMs) {
1308
- return new Promise((resolve24, reject) => {
1293
+ return new Promise((resolve22, reject) => {
1309
1294
  const timer2 = setTimeout(() => {
1310
1295
  reject(new Error(`${label} timed out after ${timeoutMs}ms`));
1311
1296
  }, timeoutMs);
1312
1297
  promise.then(
1313
1298
  (value) => {
1314
1299
  clearTimeout(timer2);
1315
- resolve24(value);
1300
+ resolve22(value);
1316
1301
  },
1317
1302
  (err) => {
1318
1303
  clearTimeout(timer2);
@@ -1847,8 +1832,8 @@ async function persistWhatsAppMessage(input) {
1847
1832
  const { givenName, familyName } = splitName(input.pushName);
1848
1833
  const prev = sessionWriteLocks.get(input.cacheKey);
1849
1834
  let release;
1850
- const mine = new Promise((resolve24) => {
1851
- release = resolve24;
1835
+ const mine = new Promise((resolve22) => {
1836
+ release = resolve22;
1852
1837
  });
1853
1838
  const chained = (prev ?? Promise.resolve()).then(() => mine);
1854
1839
  sessionWriteLocks.set(input.cacheKey, chained);
@@ -2884,11 +2869,11 @@ async function connectWithReconnect(conn) {
2884
2869
  console.error(
2885
2870
  `${TAG12} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
2886
2871
  );
2887
- await new Promise((resolve24) => {
2888
- const timer2 = setTimeout(resolve24, delay);
2872
+ await new Promise((resolve22) => {
2873
+ const timer2 = setTimeout(resolve22, delay);
2889
2874
  conn.abortController.signal.addEventListener("abort", () => {
2890
2875
  clearTimeout(timer2);
2891
- resolve24();
2876
+ resolve22();
2892
2877
  }, { once: true });
2893
2878
  });
2894
2879
  }
@@ -2896,16 +2881,16 @@ async function connectWithReconnect(conn) {
2896
2881
  }
2897
2882
  }
2898
2883
  function waitForDisconnectEvent(conn) {
2899
- return new Promise((resolve24) => {
2884
+ return new Promise((resolve22) => {
2900
2885
  if (!conn.sock) {
2901
- resolve24();
2886
+ resolve22();
2902
2887
  return;
2903
2888
  }
2904
2889
  const sock = conn.sock;
2905
2890
  const handler = (update) => {
2906
2891
  if (update.connection === "close") {
2907
2892
  sock.ev.off("connection.update", handler);
2908
- resolve24();
2893
+ resolve22();
2909
2894
  }
2910
2895
  };
2911
2896
  sock.ev.on("connection.update", handler);
@@ -3167,8 +3152,8 @@ async function handleInboundMessage(conn, msg) {
3167
3152
  const conversationKey = isGroup ? remoteJid : senderPhone;
3168
3153
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
3169
3154
  let resolvePending;
3170
- const sttPending = new Promise((resolve24) => {
3171
- resolvePending = resolve24;
3155
+ const sttPending = new Promise((resolve22) => {
3156
+ resolvePending = resolve22;
3172
3157
  });
3173
3158
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
3174
3159
  try {
@@ -3572,20 +3557,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
3572
3557
 
3573
3558
  // server/routes/health.ts
3574
3559
  function checkPort(port2, timeoutMs = 500) {
3575
- return new Promise((resolve24) => {
3560
+ return new Promise((resolve22) => {
3576
3561
  const socket = createConnection2(port2, "127.0.0.1");
3577
3562
  socket.setTimeout(timeoutMs);
3578
3563
  socket.once("connect", () => {
3579
3564
  socket.destroy();
3580
- resolve24(true);
3565
+ resolve22(true);
3581
3566
  });
3582
3567
  socket.once("error", () => {
3583
3568
  socket.destroy();
3584
- resolve24(false);
3569
+ resolve22(false);
3585
3570
  });
3586
3571
  socket.once("timeout", () => {
3587
3572
  socket.destroy();
3588
- resolve24(false);
3573
+ resolve22(false);
3589
3574
  });
3590
3575
  });
3591
3576
  }
@@ -4673,12 +4658,12 @@ async function dispatchOnce(input) {
4673
4658
  });
4674
4659
  if (!entry) return { error: "spawn-failed" };
4675
4660
  entry.lastInboundAt = Date.now();
4676
- let resolve24;
4661
+ let resolve22;
4677
4662
  const turnPromise = new Promise((r) => {
4678
- resolve24 = r;
4663
+ resolve22 = r;
4679
4664
  });
4680
4665
  const listener = (text) => {
4681
- resolve24(text);
4666
+ resolve22(text);
4682
4667
  };
4683
4668
  entry.subscribers.add(listener);
4684
4669
  const writeOk = await writeInput(entry, input.text);
@@ -5041,8 +5026,8 @@ async function startLogin(opts) {
5041
5026
  resetActiveLogin(accountId);
5042
5027
  let resolveQr = null;
5043
5028
  let rejectQr = null;
5044
- const qrPromise = new Promise((resolve24, reject) => {
5045
- resolveQr = resolve24;
5029
+ const qrPromise = new Promise((resolve22, reject) => {
5030
+ resolveQr = resolve22;
5046
5031
  rejectQr = reject;
5047
5032
  });
5048
5033
  const qrTimer = setTimeout(
@@ -8223,8 +8208,22 @@ function computeDormantPlugins(accountId) {
8223
8208
  }
8224
8209
 
8225
8210
  // server/routes/admin/claude-sessions.ts
8226
- import { readFileSync as readFileSync15 } from "fs";
8211
+ import { existsSync as existsSync16, readFileSync as readFileSync15 } from "fs";
8227
8212
  import { resolve as resolve12 } from "path";
8213
+ function readTunnelState(brandConfigDir) {
8214
+ const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
8215
+ if (!existsSync16(statePath)) return null;
8216
+ try {
8217
+ const parsed = JSON.parse(readFileSync15(statePath, "utf-8"));
8218
+ const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
8219
+ const tunnelName = typeof parsed.tunnelName === "string" ? parsed.tunnelName : null;
8220
+ const domain = typeof parsed.domain === "string" ? parsed.domain : null;
8221
+ if (!tunnelId || !tunnelName || !domain) return null;
8222
+ return { tunnelId, tunnelName, domain };
8223
+ } catch {
8224
+ return null;
8225
+ }
8226
+ }
8228
8227
  function resolveTunnelUrl() {
8229
8228
  const platformRoot = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve12(process.cwd(), "..");
8230
8229
  let brand;
@@ -8692,211 +8691,15 @@ app16.post("/", async (c) => {
8692
8691
  });
8693
8692
  var log_ingest_default = app16;
8694
8693
 
8695
- // server/routes/admin/browser.ts
8696
- var app17 = new Hono();
8697
- app17.post("/launch", async (c) => {
8698
- try {
8699
- const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
8700
- if (transport === "vnc") {
8701
- const vncOk = await ensureVnc();
8702
- if (!vncOk) {
8703
- return c.json({ ok: false, error: "VNC failed to start" }, 502);
8704
- }
8705
- }
8706
- const cdpOk = await ensureCdp(transport);
8707
- if (!cdpOk) {
8708
- return c.json({ ok: false, error: "Chrome failed to start" }, 502);
8709
- }
8710
- return c.json({ ok: true, transport });
8711
- } catch (err) {
8712
- console.error("[admin/browser/launch] Failed to start browser:", err);
8713
- return c.json(
8714
- { ok: false, error: err instanceof Error ? err.message : "Unknown error" },
8715
- 500
8716
- );
8717
- }
8718
- });
8719
- var browser_default = app17;
8720
-
8721
- // server/routes/admin/browser-iframe.ts
8722
- var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
8723
- "mount",
8724
- "unmount",
8725
- "rfb-connected",
8726
- "rfb-error",
8727
- "iframe-load"
8728
- ]);
8729
- function asString(v, max = 500) {
8730
- if (typeof v !== "string") return void 0;
8731
- return v.length > max ? v.slice(0, max) : v;
8732
- }
8733
- function asNumber(v) {
8734
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
8735
- }
8736
- var app18 = new Hono();
8737
- app18.post("/event", async (c) => {
8738
- let body = {};
8739
- try {
8740
- body = await c.req.json();
8741
- } catch {
8742
- browserViewerLog("invalid", { reason: "body-not-json" });
8743
- return c.body(null, 204);
8744
- }
8745
- const eventRaw = asString(body.event, 64);
8746
- const event = eventRaw && ALLOWED_EVENTS.has(eventRaw) ? eventRaw : "invalid";
8747
- browserViewerLog(event, {
8748
- brand: asString(body.brand, 64),
8749
- conversationId: asString(body.conversationId, 64),
8750
- session_key: asString(body.session_key, 128),
8751
- durationMs: asNumber(body.durationMs),
8752
- errorCode: asString(body.errorCode, 64),
8753
- message: asString(body.message, 200),
8754
- surface: asString(body.surface, 32)
8755
- });
8756
- return c.body(null, 204);
8757
- });
8758
- var browser_iframe_default = app18;
8759
-
8760
- // app/lib/cdp-client.ts
8761
- var CDP_HOST = "127.0.0.1";
8762
- var CDP_PORT2 = CDP_PORT;
8763
- var DEFAULT_TIMEOUT_MS = 5e3;
8764
- async function cdpNavigateNewTab(url, opts = {}) {
8765
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
8766
- const endpoint = `http://${CDP_HOST}:${CDP_PORT2}/json/new?${encodeURIComponent(url)}`;
8767
- let res;
8768
- try {
8769
- res = await fetch(endpoint, {
8770
- method: "PUT",
8771
- signal: AbortSignal.timeout(timeoutMs)
8772
- });
8773
- } catch (err) {
8774
- const msg = err instanceof Error ? err.message : String(err);
8775
- if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed") || msg.includes("ENOTFOUND")) {
8776
- return { result: "cdp-unreachable", detail: msg };
8777
- }
8778
- if (err instanceof Error && err.name === "TimeoutError") {
8779
- return { result: "timeout", detail: msg };
8780
- }
8781
- return { result: "error", detail: msg };
8782
- }
8783
- if (!res.ok) {
8784
- const body = await res.text().catch(() => "<unreadable>");
8785
- return {
8786
- result: "error",
8787
- detail: `CDP /json/new returned ${res.status}: ${body.slice(0, 200)}`
8788
- };
8789
- }
8790
- let target;
8791
- try {
8792
- target = await res.json();
8793
- } catch (err) {
8794
- const msg = err instanceof Error ? err.message : String(err);
8795
- return { result: "error", detail: `CDP /json/new response not JSON: ${msg}` };
8796
- }
8797
- return { result: "ok", targetId: target?.id };
8798
- }
8799
-
8800
- // server/routes/admin/device-browser.ts
8801
- var app19 = new Hono();
8802
- app19.post("/navigate", async (c) => {
8803
- const TAG22 = "[device-url:click]";
8804
- let body;
8805
- try {
8806
- body = await c.req.json();
8807
- } catch (err) {
8808
- const detail = err instanceof Error ? err.message : String(err);
8809
- console.error(`${TAG22} reject reason=body-not-json detail=${detail} browser=fallback navigateResult=error`);
8810
- return c.json(
8811
- { ok: false, navigateResult: "error", browser: "fallback", detail: "Request body was not valid JSON" },
8812
- 400
8813
- );
8814
- }
8815
- const url = typeof body.url === "string" ? body.url : "";
8816
- const intent = typeof body.intent === "string" ? body.intent : "";
8817
- const hostname2 = typeof body.hostname === "string" ? body.hostname : "";
8818
- if (!url) {
8819
- console.error(`${TAG22} reject reason=missing-url intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`);
8820
- return c.json(
8821
- { ok: false, navigateResult: "error", browser: "fallback", detail: "url field is required" },
8822
- 400
8823
- );
8824
- }
8825
- let parsed;
8826
- try {
8827
- parsed = new URL(url);
8828
- } catch {
8829
- console.error(`${TAG22} reject reason=url-malformed intent=${JSON.stringify(intent)} url=${url} browser=fallback navigateResult=error`);
8830
- return c.json(
8831
- { ok: false, navigateResult: "error", browser: "fallback", detail: "url is not a valid URL" },
8832
- 400
8833
- );
8834
- }
8835
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
8836
- console.error(
8837
- `${TAG22} reject reason=scheme-not-allowed scheme=${parsed.protocol} intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`
8838
- );
8839
- return c.json(
8840
- {
8841
- ok: false,
8842
- navigateResult: "error",
8843
- browser: "fallback",
8844
- detail: `URL scheme ${parsed.protocol} is not permitted; only http and https are accepted`
8845
- },
8846
- 400
8847
- );
8848
- }
8849
- const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
8850
- const cdpOk = await ensureCdp(transport);
8851
- if (!cdpOk) {
8852
- console.error(
8853
- `${TAG22} intent=${JSON.stringify(intent)} browser=fallback navigateResult=cdp-unreachable hostname=${JSON.stringify(hostname2)}`
8854
- );
8855
- return c.json(
8856
- {
8857
- ok: false,
8858
- navigateResult: "cdp-unreachable",
8859
- browser: "fallback",
8860
- detail: `Device browser (Chromium/CDP on :${CDP_PORT}) did not start`
8861
- },
8862
- 502
8863
- );
8864
- }
8865
- const outcome = await cdpNavigateNewTab(parsed.toString());
8866
- const browser = outcome.result === "ok" ? "vnc" : "fallback";
8867
- const detailStr = outcome.detail ? ` detail=${JSON.stringify(outcome.detail.length > 230 ? outcome.detail.slice(0, 227) + "..." : outcome.detail)}` : "";
8868
- console.error(
8869
- `${TAG22} intent=${JSON.stringify(intent)} browser=${browser} navigateResult=${outcome.result} hostname=${JSON.stringify(hostname2)} targetId=${outcome.targetId ?? "none"}${detailStr}`
8870
- );
8871
- if (outcome.result !== "ok") {
8872
- return c.json(
8873
- {
8874
- ok: false,
8875
- navigateResult: outcome.result,
8876
- browser: "fallback",
8877
- detail: outcome.detail
8878
- },
8879
- 502
8880
- );
8881
- }
8882
- return c.json({
8883
- ok: true,
8884
- navigateResult: "ok",
8885
- browser: "vnc",
8886
- targetId: outcome.targetId
8887
- });
8888
- });
8889
- var device_browser_default = app19;
8890
-
8891
8694
  // server/routes/admin/events.ts
8892
- var ALLOWED_EVENTS2 = /* @__PURE__ */ new Set([
8695
+ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
8893
8696
  "device-url:render",
8894
8697
  "device-url:fallback-shown",
8895
8698
  "device-url:vnc-surface-shown",
8896
8699
  "device-url:malformed"
8897
8700
  ]);
8898
- var app20 = new Hono();
8899
- app20.post("/", async (c) => {
8701
+ var app17 = new Hono();
8702
+ app17.post("/", async (c) => {
8900
8703
  const TAG22 = "[admin:events]";
8901
8704
  let body;
8902
8705
  try {
@@ -8907,7 +8710,7 @@ app20.post("/", async (c) => {
8907
8710
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
8908
8711
  }
8909
8712
  const event = typeof body.event === "string" ? body.event : "";
8910
- if (!ALLOWED_EVENTS2.has(event)) {
8713
+ if (!ALLOWED_EVENTS.has(event)) {
8911
8714
  console.error(`${TAG22} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
8912
8715
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
8913
8716
  }
@@ -8927,914 +8730,23 @@ app20.post("/", async (c) => {
8927
8730
  console.error(`[${event}] ${formatted}`);
8928
8731
  return c.json({ ok: true });
8929
8732
  });
8930
- var events_default = app20;
8931
-
8932
- // server/routes/admin/cloudflare.ts
8933
- import { homedir as homedir4 } from "os";
8934
- import { resolve as resolve14 } from "path";
8935
- import { readFileSync as readFileSync17 } from "fs";
8936
-
8937
- // app/lib/dns-label.ts
8938
- var VALID_LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
8939
- function isValidLabel(value) {
8940
- if (!value) return false;
8941
- return VALID_LABEL.test(value);
8942
- }
8943
- function isValidDomain(value) {
8944
- if (!value || value.length > 253) return false;
8945
- const parts = value.split(".");
8946
- if (parts.length < 2) return false;
8947
- return parts.every((p) => isValidLabel(p));
8948
- }
8949
-
8950
- // app/lib/alias-domains.ts
8951
- import { existsSync as existsSync16, mkdirSync as mkdirSync4, readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
8952
- import { dirname as dirname4 } from "path";
8953
- import { resolve as resolve13 } from "path";
8954
- var ALIAS_DOMAINS_PATH = resolve13(MAXY_DIR, "alias-domains.json");
8955
- function readExisting() {
8956
- if (!existsSync16(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
8957
- try {
8958
- const parsed = JSON.parse(readFileSync16(ALIAS_DOMAINS_PATH, "utf-8"));
8959
- if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
8960
- return new Set(parsed.filter((h) => typeof h === "string"));
8961
- } catch {
8962
- return /* @__PURE__ */ new Set();
8963
- }
8964
- }
8965
- function addAliasDomain(hostname2) {
8966
- const existing = readExisting();
8967
- if (existing.has(hostname2)) return;
8968
- existing.add(hostname2);
8969
- mkdirSync4(dirname4(ALIAS_DOMAINS_PATH), { recursive: true });
8970
- writeFileSync7(ALIAS_DOMAINS_PATH, JSON.stringify([...existing], null, 2) + "\n", "utf-8");
8971
- }
8972
-
8973
- // app/lib/script-stream-tailer.ts
8974
- import * as childProcess from "child_process";
8975
- import { appendFileSync as appendFileSync2, createReadStream as createReadStream2, mkdirSync as mkdirSync5, statSync as statSync7 } from "fs";
8976
- import { dirname as dirname5 } from "path";
8977
- import { StringDecoder } from "string_decoder";
8978
- var SCRIPT_STREAM_RE = /^\[([^\]]+)\] \[script:([a-z][a-z0-9-]*)((?::[a-z0-9:_-]+)?)\] (.*)$/;
8979
- function parseLine(line) {
8980
- const m = line.match(SCRIPT_STREAM_RE);
8981
- if (!m) return void 0;
8982
- const [, timestamp, scope, tagSuffix, rest] = m;
8983
- return {
8984
- type: "script_stream",
8985
- source: scope + (tagSuffix ?? ""),
8986
- timestamp,
8987
- line: rest
8988
- };
8989
- }
8990
- function startScriptStreamTailer(opts) {
8991
- const { path: path2, onEvent, onError } = opts;
8992
- let offset;
8993
- try {
8994
- offset = statSync7(path2).size;
8995
- } catch {
8996
- offset = 0;
8997
- }
8998
- const utf8 = new StringDecoder("utf8");
8999
- let buffer = "";
9000
- let stopped = false;
9001
- let pendingRead = false;
9002
- let timer2;
9003
- const processLine = (line) => {
9004
- const event = parseLine(line);
9005
- if (event) onEvent(event);
9006
- };
9007
- const readDelta = async () => {
9008
- if (pendingRead) return;
9009
- pendingRead = true;
9010
- try {
9011
- let size;
9012
- try {
9013
- size = statSync7(path2).size;
9014
- } catch {
9015
- return;
9016
- }
9017
- if (size === offset) return;
9018
- if (size < offset) {
9019
- offset = 0;
9020
- buffer = "";
9021
- }
9022
- await new Promise((res, rej) => {
9023
- const stream = createReadStream2(path2, { start: offset, end: size - 1 });
9024
- stream.on("data", (chunk) => {
9025
- buffer += typeof chunk === "string" ? chunk : utf8.write(chunk);
9026
- let idx;
9027
- while ((idx = buffer.indexOf("\n")) !== -1) {
9028
- const line = buffer.slice(0, idx);
9029
- buffer = buffer.slice(idx + 1);
9030
- if (line.length > 0) processLine(line);
9031
- }
9032
- });
9033
- stream.on("end", () => {
9034
- offset = size;
9035
- res();
9036
- });
9037
- stream.on("error", rej);
9038
- });
9039
- } catch (err) {
9040
- if (onError) onError(err instanceof Error ? err : new Error(String(err)));
9041
- } finally {
9042
- pendingRead = false;
9043
- }
9044
- };
9045
- const tick = () => {
9046
- if (stopped) return;
9047
- readDelta().catch(() => {
9048
- }).finally(() => {
9049
- if (!stopped) timer2 = setTimeout(tick, 200);
9050
- });
9051
- };
9052
- timer2 = setTimeout(tick, 0);
9053
- return {
9054
- async stop() {
9055
- if (stopped) return;
9056
- stopped = true;
9057
- if (timer2) clearTimeout(timer2);
9058
- while (pendingRead) {
9059
- await new Promise((r) => setImmediate(r));
9060
- }
9061
- await readDelta();
9062
- buffer += utf8.end();
9063
- if (buffer.length > 0) {
9064
- const event = parseLine(buffer);
9065
- if (event) onEvent(event);
9066
- buffer = "";
9067
- }
9068
- }
9069
- };
9070
- }
9071
- var SCOPE_TOKEN_RE = /^[a-z][a-z0-9-]*$/;
9072
- function writeRouteMilestone(streamLogPath, scope, line) {
9073
- if (scope.startsWith("script:")) {
9074
- throw new Error(
9075
- `writeRouteMilestone: scope "${scope}" must not start with "script:" \u2014 the helper prepends it`
9076
- );
9077
- }
9078
- if (!SCOPE_TOKEN_RE.test(scope)) {
9079
- throw new Error(
9080
- `writeRouteMilestone: scope "${scope}" must match [a-z][a-z0-9-]* \u2014 the tailer regex won't match otherwise`
9081
- );
9082
- }
9083
- const ts = (/* @__PURE__ */ new Date()).toISOString();
9084
- try {
9085
- mkdirSync5(dirname5(streamLogPath), { recursive: true });
9086
- appendFileSync2(streamLogPath, `[${ts}] [script:${scope}] ${line}
9087
- `);
9088
- } catch (err) {
9089
- console.error(
9090
- `[script-stream-tailer] writeRouteMilestone failed path=${streamLogPath} scope=${scope}: ${err instanceof Error ? err.message : String(err)}`
9091
- );
9092
- }
9093
- }
9094
- function runFormSpawn(opts) {
9095
- const { scriptPath, args, streamLogPath, correlationId, timeoutMs, log, logErr, broadcast } = opts;
9096
- return new Promise((resolveP) => {
9097
- let tailer = null;
9098
- try {
9099
- tailer = startScriptStreamTailer({
9100
- path: streamLogPath,
9101
- onEvent: (event) => {
9102
- try {
9103
- broadcast(correlationId, event);
9104
- } catch (e) {
9105
- logErr(
9106
- `phase=tailer-broadcast-failed detail="${e instanceof Error ? e.message : String(e)}"`
9107
- );
9108
- }
9109
- },
9110
- onError: (e) => {
9111
- logErr(`phase=tailer-error message="${e.message.slice(0, 160).replace(/"/g, "'")}"`);
9112
- }
9113
- });
9114
- log(`phase=tailer-started`);
9115
- } catch (e) {
9116
- logErr(`phase=tailer-start-failed detail="${e instanceof Error ? e.message : String(e)}"`);
9117
- tailer = null;
9118
- }
9119
- const child = childProcess.spawn(scriptPath, args, {
9120
- env: { ...process.env, STREAM_LOG_PATH: streamLogPath },
9121
- stdio: ["ignore", "pipe", "pipe"]
9122
- });
9123
- log(`phase=script-spawn pid=${child.pid ?? "unknown"} args="${args.join(" ")}"`);
9124
- let stdout = "";
9125
- let stderr = "";
9126
- let timedOut = false;
9127
- const killer = setTimeout(() => {
9128
- timedOut = true;
9129
- try {
9130
- child.kill("SIGTERM");
9131
- } catch {
9132
- }
9133
- }, timeoutMs);
9134
- child.stdout?.on("data", (chunk) => {
9135
- stdout += chunk.toString("utf-8");
9136
- });
9137
- child.stderr?.on("data", (chunk) => {
9138
- stderr += chunk.toString("utf-8");
9139
- });
9140
- let finalized = false;
9141
- const finalize = async (result) => {
9142
- if (finalized) return;
9143
- finalized = true;
9144
- if (tailer) {
9145
- try {
9146
- await tailer.stop();
9147
- log(`phase=tailer-stopped`);
9148
- } catch (e) {
9149
- logErr(
9150
- `phase=tailer-stop-failed detail="${e instanceof Error ? e.message : String(e)}"`
9151
- );
9152
- }
9153
- }
9154
- resolveP(result);
9155
- };
9156
- child.on("error", (e) => {
9157
- clearTimeout(killer);
9158
- void finalize({
9159
- code: null,
9160
- signal: null,
9161
- stdout,
9162
- stderr: `${stderr}
9163
- ${e.message}`,
9164
- timedOut: false
9165
- });
9166
- });
9167
- child.on("exit", (code, signal) => {
9168
- clearTimeout(killer);
9169
- log(
9170
- `phase=script-exit code=${code ?? "null"} signal=${signal ?? "null"} timedOut=${timedOut}`
9171
- );
9172
- void finalize({ code, signal, stdout, stderr, timedOut });
9173
- });
9174
- });
9175
- }
9176
-
9177
- // app/lib/admin-sse-registry.ts
9178
- var activeAdminSSEControllers = /* @__PURE__ */ new Set();
9179
- function broadcastAdminShutdown(reason) {
9180
- const encoder = new TextEncoder();
9181
- const payload = JSON.stringify({ type: "server_shutdown", reason });
9182
- const frame = encoder.encode(`data: ${payload}
9183
-
9184
- `);
9185
- const done = encoder.encode(`data: [DONE]
9186
-
9187
- `);
9188
- for (const entry of activeAdminSSEControllers) {
9189
- try {
9190
- entry.controller.enqueue(frame);
9191
- } catch {
9192
- }
9193
- try {
9194
- entry.controller.enqueue(done);
9195
- } catch {
9196
- }
9197
- try {
9198
- entry.controller.close();
9199
- } catch {
9200
- }
9201
- }
9202
- activeAdminSSEControllers.clear();
9203
- }
9204
- function broadcastToConversation(conversationId, event) {
9205
- const encoder = new TextEncoder();
9206
- const frame = encoder.encode(`data: ${JSON.stringify(event)}
9207
-
9208
- `);
9209
- for (const entry of activeAdminSSEControllers) {
9210
- if (entry.conversationId !== conversationId) continue;
9211
- try {
9212
- entry.controller.enqueue(frame);
9213
- } catch {
9214
- }
9215
- }
9216
- }
9217
-
9218
- // app/lib/cloudflare-setup-types.ts
9219
- var CLOUDFLARE_SETUP_FORM_SCHEMA = {
9220
- secretFields: ["password", "session_key", "messageId"]
9221
- };
9222
-
9223
- // app/lib/cloudflare-bundle-mtime.ts
9224
- import { statSync as statSync8 } from "fs";
9225
- var cachedBundleMtimeIso;
9226
- function getBundleMtimeIso(entry = process.argv[1]) {
9227
- if (cachedBundleMtimeIso !== void 0) return cachedBundleMtimeIso;
9228
- if (!entry) {
9229
- process.stderr.write(`[bundle-mtime] fallback reason=empty-path
9230
- `);
9231
- cachedBundleMtimeIso = "unknown";
9232
- return cachedBundleMtimeIso;
9233
- }
9234
- try {
9235
- cachedBundleMtimeIso = statSync8(entry).mtime.toISOString();
9236
- } catch (e) {
9237
- const reason = e instanceof Error ? e.message : String(e);
9238
- process.stderr.write(`[bundle-mtime] fallback reason=stat-threw error="${reason}"
9239
- `);
9240
- cachedBundleMtimeIso = "unknown";
9241
- }
9242
- return cachedBundleMtimeIso;
9243
- }
9244
- function decideRetryBranch(args) {
9245
- const { bundleMtimeIso, prior } = args;
9246
- if (!prior || prior.outcome !== "failed") return "proceed";
9247
- if (bundleMtimeIso === "unknown") return "surface-error";
9248
- return bundleMtimeIso > prior.completedAt ? "re-invoke" : "surface-error";
9249
- }
9250
-
9251
- // server/routes/admin/cloudflare.ts
9252
- function cloudflareStreamLogPath(accountId, correlationId) {
9253
- return resolve14(ACCOUNTS_DIR, accountId, "cloudflare-stream-logs", `${correlationId}.log`);
9254
- }
9255
- var SETUP_TIMEOUT_MS = 10 * 60 * 1e3;
9256
- var DOMAINS_TIMEOUT_MS = 40 * 1e3;
9257
- var discoveryCache = /* @__PURE__ */ new Map();
9258
- function getDiscoveryEntry(accountId) {
9259
- let entry = discoveryCache.get(accountId);
9260
- if (!entry) {
9261
- entry = { tunnels: [], domains: [] };
9262
- discoveryCache.set(accountId, entry);
9263
- }
9264
- return entry;
9265
- }
9266
- function rememberDomains(accountId, domains) {
9267
- const entry = getDiscoveryEntry(accountId);
9268
- entry.domains = domains;
9269
- entry.domainsUpdatedAt = Date.now();
9270
- }
9271
- function rememberTunnels(accountId, tunnels) {
9272
- const entry = getDiscoveryEntry(accountId);
9273
- entry.tunnels = tunnels;
9274
- entry.tunnelsUpdatedAt = Date.now();
9275
- }
9276
- function readDiscoveryResults(accountId) {
9277
- if (!accountId) return { tunnels: [], domains: [] };
9278
- const entry = discoveryCache.get(accountId);
9279
- if (!entry) return { tunnels: [], domains: [] };
9280
- return { tunnels: entry.tunnels, domains: entry.domains };
9281
- }
9282
- function loadBrandInfo() {
9283
- const platformRoot = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
9284
- const brandPath = resolve14(platformRoot, "config", "brand.json");
9285
- try {
9286
- const parsed = JSON.parse(readFileSync17(brandPath, "utf-8"));
9287
- const hostname2 = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
9288
- const configDir2 = typeof parsed.configDir === "string" && parsed.configDir ? parsed.configDir : ".maxy";
9289
- return { hostname: hostname2, configDir: configDir2 };
9290
- } catch {
9291
- return { hostname: "maxy", configDir: ".maxy" };
9292
- }
9293
- }
9294
- function resolvePort() {
9295
- const raw = process.env.PORT;
9296
- if (!raw) throw new Error("PORT env var is not set \u2014 refusing to guess");
9297
- const n = Number(raw);
9298
- if (!Number.isInteger(n) || n <= 0 || n > 65535) {
9299
- throw new Error(`PORT env var is not a valid port: ${raw}`);
9300
- }
9301
- return n;
9302
- }
9303
- function isValidTunnelId(s) {
9304
- return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);
9305
- }
9306
- function isValidTunnelName(s) {
9307
- return /^[A-Za-z0-9_.-]{1,64}$/.test(s);
9308
- }
9309
- function validateBody(body) {
9310
- if (!body || typeof body !== "object") return { field: "request", message: "Invalid request body" };
9311
- if (typeof body.adminLabel !== "string" || !isValidLabel(body.adminLabel)) {
9312
- return { field: "admin", message: "Admin address is invalid." };
9313
- }
9314
- if (typeof body.adminDomain !== "string" || !isValidDomain(body.adminDomain)) {
9315
- return { field: "admin", message: "Admin domain is invalid." };
9316
- }
9317
- if (body.publicLabel !== void 0 && body.publicLabel !== "") {
9318
- if (typeof body.publicLabel !== "string" || !isValidLabel(body.publicLabel)) {
9319
- return { field: "public", message: "Public address is invalid." };
9320
- }
9321
- if (typeof body.publicDomain !== "string" || !isValidDomain(body.publicDomain)) {
9322
- return { field: "public", message: "Public domain is invalid." };
9323
- }
9324
- }
9325
- if (typeof body.password !== "string" || !isPasswordValid(body.password)) {
9326
- return { field: "password", message: "Password does not meet the strength requirements." };
9327
- }
9328
- if (body.apex !== void 0 && body.apex !== "") {
9329
- if (typeof body.apex !== "string" || !isValidDomain(body.apex)) {
9330
- return { field: "request", message: "Apex must be a valid domain or omitted." };
9331
- }
9332
- }
9333
- const idSet = typeof body.tunnelId === "string" && body.tunnelId.length > 0;
9334
- const nameSet = typeof body.tunnelName === "string" && body.tunnelName.length > 0;
9335
- if (!idSet && !nameSet) {
9336
- return { field: "tunnel", message: "Pick an existing tunnel from the list, or type a name to create a new one." };
9337
- }
9338
- if (idSet && nameSet) {
9339
- return { field: "tunnel", message: "Pick OR create \u2014 not both. Clear one of the tunnel inputs." };
9340
- }
9341
- if (idSet && !isValidTunnelId(body.tunnelId)) {
9342
- return { field: "tunnel", message: "Selected tunnel UUID is malformed." };
9343
- }
9344
- if (nameSet && !isValidTunnelName(body.tunnelName)) {
9345
- return { field: "tunnel", message: "New-tunnel name must be 1\u201364 characters of letters, digits, dot, dash, underscore." };
9346
- }
9347
- return null;
9348
- }
9349
- var app21 = new Hono();
9350
- function fieldFromReason(reason) {
9351
- switch (reason) {
9352
- case "not-signed-in":
9353
- return "dashboard";
9354
- case "brand-arg-missing":
9355
- case "brand-config-missing":
9356
- case "cdp-port-unresolved":
9357
- return "config";
9358
- case "cdp-unreachable":
9359
- case "target-create-failed":
9360
- case "ws-connect-failed":
9361
- case "navigate-failed":
9362
- case "runtime-error":
9363
- case "table-wait-timeout":
9364
- case "entry-missing":
9365
- case "wrapper-timeout":
9366
- default:
9367
- return "script";
9368
- }
9369
- }
9370
- app21.get("/domains", requireAdminSession, async (c) => {
9371
- const started = Date.now();
9372
- const cacheKey = c.var.cacheKey;
9373
- let correlationId;
9374
- let cacheKeyTail;
9375
- let streamLogPath;
9376
- function tag() {
9377
- if (!correlationId) return "";
9378
- return ` conversationId=${correlationId} session_key=${cacheKeyTail ?? "unknown"}`;
9379
- }
9380
- function log(line) {
9381
- console.log(`[cloudflare-domains] ${line}${tag()}`);
9382
- }
9383
- function logErr(line) {
9384
- console.error(`[cloudflare-domains] ${line}${tag()}`);
9385
- }
9386
- function err(field, message, output, brand2) {
9387
- logErr(`phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`);
9388
- if (streamLogPath) {
9389
- writeRouteMilestone(
9390
- streamLogPath,
9391
- "cloudflare-domains",
9392
- `phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`
9393
- );
9394
- }
9395
- const body = {
9396
- ok: false,
9397
- field,
9398
- message,
9399
- output,
9400
- correlationId,
9401
- streamLogPath,
9402
- brand: brand2
9403
- };
9404
- return c.json(body, 200);
9405
- }
9406
- const accountId = getAccountIdForSession(cacheKey);
9407
- correlationId = getConversationIdForSession(cacheKey);
9408
- cacheKeyTail = cacheKey.slice(-8);
9409
- if (!accountId) return err("session", "No account bound to session \u2014 refresh chat.");
9410
- if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
9411
- streamLogPath = cloudflareStreamLogPath(accountId, correlationId);
9412
- log(`phase=stream-log-resolved path=${streamLogPath}`);
9413
- const brand = loadBrandInfo();
9414
- const scriptPath = resolve14(homedir4(), "list-cf-domains.sh");
9415
- const result = await runFormSpawn({
9416
- scriptPath,
9417
- args: [brand.hostname],
9418
- streamLogPath,
9419
- correlationId,
9420
- timeoutMs: DOMAINS_TIMEOUT_MS,
9421
- log,
9422
- logErr,
9423
- broadcast: broadcastToConversation
9424
- });
9425
- const combined = `${result.stdout}${result.stderr ? `
9426
- ---
9427
- ${result.stderr}` : ""}`;
9428
- if (result.code !== 0) {
9429
- const reasonMatch = result.stderr.match(/reason=([a-z0-9-]+)/);
9430
- const reason = reasonMatch ? reasonMatch[1] : void 0;
9431
- const field = fieldFromReason(reason);
9432
- const message = reason ? `Domain discovery failed: ${reason}` : result.timedOut ? `Domain discovery timed out after ${DOMAINS_TIMEOUT_MS / 1e3}s` : `Domain discovery exited with code ${result.code ?? "null"}${result.signal ? ` (signal ${result.signal})` : ""}`;
9433
- return err(field, message, combined, field === "config" ? brand.hostname : void 0);
9434
- }
9435
- let domains;
9436
- try {
9437
- const parsed = JSON.parse(result.stdout.trim());
9438
- if (!Array.isArray(parsed) || !parsed.every((d) => typeof d === "string")) {
9439
- throw new Error("response is not string[]");
9440
- }
9441
- domains = parsed;
9442
- } catch (e) {
9443
- return err(
9444
- "script",
9445
- `Domain discovery returned malformed output: ${e instanceof Error ? e.message : String(e)}`,
9446
- combined
9447
- );
9448
- }
9449
- const success = {
9450
- ok: true,
9451
- domains,
9452
- correlationId,
9453
- streamLogPath
9454
- };
9455
- rememberDomains(accountId, domains);
9456
- const total = Date.now() - started;
9457
- log(`phase=response-sent total_ms=${total} count=${domains.length}`);
9458
- writeRouteMilestone(
9459
- streamLogPath,
9460
- "cloudflare-domains",
9461
- `phase=response-sent total_ms=${total} count=${domains.length}`
9462
- );
9463
- return c.json(success, 200);
9464
- });
9465
- var TUNNELS_TIMEOUT_MS = 30 * 1e3;
9466
- app21.get("/tunnels", requireAdminSession, async (c) => {
9467
- const started = Date.now();
9468
- const cacheKey = c.var.cacheKey;
9469
- let correlationId;
9470
- let cacheKeyTail;
9471
- let streamLogPath;
9472
- function tag() {
9473
- if (!correlationId) return "";
9474
- return ` conversationId=${correlationId} session_key=${cacheKeyTail ?? "unknown"}`;
9475
- }
9476
- function log(line) {
9477
- console.log(`[cloudflare-tunnels] ${line}${tag()}`);
9478
- }
9479
- function logErr(line) {
9480
- console.error(`[cloudflare-tunnels] ${line}${tag()}`);
9481
- }
9482
- const brand = loadBrandInfo();
9483
- const { hostname: deviceHostnameFn } = await import("os");
9484
- const rawDeviceHostname = (deviceHostnameFn() || "").split(".")[0];
9485
- const sanitizedDevice = rawDeviceHostname.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") || "device";
9486
- const defaultName = `${brand.hostname}-${sanitizedDevice}`;
9487
- function err(field, message, output) {
9488
- logErr(`phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`);
9489
- if (streamLogPath) {
9490
- writeRouteMilestone(
9491
- streamLogPath,
9492
- "cloudflare-tunnels",
9493
- `phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`
9494
- );
9495
- }
9496
- const body = { ok: false, field, message, output, defaultName, correlationId, streamLogPath };
9497
- return c.json(body, 200);
9498
- }
9499
- const accountId = getAccountIdForSession(cacheKey);
9500
- correlationId = getConversationIdForSession(cacheKey);
9501
- cacheKeyTail = cacheKey.slice(-8);
9502
- if (!accountId) return err("session", "No account bound to session \u2014 refresh chat.");
9503
- if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
9504
- streamLogPath = cloudflareStreamLogPath(accountId, correlationId);
9505
- const certPath = resolve14(homedir4(), brand.configDir, "cloudflared", "cert.pem");
9506
- const { existsSync: existsSync24 } = await import("fs");
9507
- if (!existsSync24(certPath)) {
9508
- 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.`);
9509
- }
9510
- const result = await runFormSpawn({
9511
- scriptPath: "cloudflared",
9512
- args: ["--origincert", certPath, "tunnel", "list", "--output", "json"],
9513
- streamLogPath,
9514
- correlationId,
9515
- timeoutMs: TUNNELS_TIMEOUT_MS,
9516
- log,
9517
- logErr,
9518
- broadcast: broadcastToConversation
9519
- });
9520
- const combined = `${result.stdout}${result.stderr ? `
9521
- ---
9522
- ${result.stderr}` : ""}`;
9523
- if (result.code !== 0) {
9524
- const message = result.timedOut ? `cloudflared tunnel list timed out after ${TUNNELS_TIMEOUT_MS / 1e3}s` : `cloudflared tunnel list exited with code ${result.code ?? "null"}${result.signal ? ` (signal ${result.signal})` : ""}`;
9525
- return err("script", message, combined);
9526
- }
9527
- let tunnels;
9528
- let nullNormalised = false;
9529
- try {
9530
- const parsed = JSON.parse(result.stdout.trim());
9531
- if (parsed === null) {
9532
- tunnels = [];
9533
- nullNormalised = true;
9534
- } else if (!Array.isArray(parsed)) {
9535
- throw new Error("cloudflared response is not an array");
9536
- } else {
9537
- tunnels = parsed.filter((t) => t.deleted_at == null).map((t) => {
9538
- if (typeof t.id !== "string" || typeof t.name !== "string") {
9539
- throw new Error("tunnel entry missing id or name");
9540
- }
9541
- return { id: t.id, name: t.name };
9542
- });
9543
- }
9544
- } catch (e) {
9545
- return err(
9546
- "script",
9547
- `cloudflared returned malformed JSON: ${e instanceof Error ? e.message : String(e)}`,
9548
- combined
9549
- );
9550
- }
9551
- const total = Date.now() - started;
9552
- const nullTag = nullNormalised ? " null_normalised=true" : "";
9553
- log(`phase=response-sent total_ms=${total} count=${tunnels.length}${nullTag}`);
9554
- writeRouteMilestone(
9555
- streamLogPath,
9556
- "cloudflare-tunnels",
9557
- `phase=response-sent total_ms=${total} count=${tunnels.length} source=cloudflared${nullTag}`
9558
- );
9559
- rememberTunnels(accountId, tunnels);
9560
- const success = { ok: true, tunnels, defaultName, correlationId, streamLogPath };
9561
- return c.json(success, 200);
9562
- });
9563
- app21.post("/setup", requireAdminSession, async (c) => {
9564
- const started = Date.now();
9565
- const cacheKey = c.var.cacheKey;
9566
- let correlationId;
9567
- let cacheKeyTail;
9568
- let streamLogPath;
9569
- let resolvedAccountId;
9570
- const heldInputs = {};
9571
- function tag() {
9572
- if (!correlationId) return "";
9573
- return ` conversationId=${correlationId} session_key=${cacheKeyTail ?? "unknown"}`;
9574
- }
9575
- function log(line) {
9576
- console.log(`[cloudflare-setup] ${line}${tag()}`);
9577
- }
9578
- function logErr(line) {
9579
- console.error(`[cloudflare-setup] ${line}${tag()}`);
9580
- }
9581
- function err(field, message, output) {
9582
- logErr(`phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`);
9583
- if (streamLogPath) {
9584
- writeRouteMilestone(
9585
- streamLogPath,
9586
- "cloudflare-setup",
9587
- `phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`
9588
- );
9589
- }
9590
- const body2 = {
9591
- ok: false,
9592
- field,
9593
- message,
9594
- output,
9595
- correlationId,
9596
- streamLogPath,
9597
- inputsAlreadyHeld: { ...heldInputs },
9598
- discoveryResults: readDiscoveryResults(resolvedAccountId)
9599
- };
9600
- return c.json(body2, 200);
9601
- }
9602
- function ok(result) {
9603
- return c.json(result, 200);
9604
- }
9605
- let body;
9606
- try {
9607
- body = await c.req.json();
9608
- } catch {
9609
- return err("request", "Invalid JSON body");
9610
- }
9611
- const accountId = getAccountIdForSession(cacheKey);
9612
- correlationId = getConversationIdForSession(cacheKey);
9613
- cacheKeyTail = cacheKey.slice(-8);
9614
- if (!accountId) {
9615
- return err("request", "No account bound to session \u2014 refresh chat.");
9616
- }
9617
- resolvedAccountId = accountId;
9618
- if (!correlationId) {
9619
- return err("request", "No active conversation for session \u2014 refresh chat.");
9620
- }
9621
- const invalid = validateBody(body);
9622
- if (invalid) return err(invalid.field, invalid.message);
9623
- const adminFqdn = `${body.adminLabel}.${body.adminDomain}`;
9624
- const publicFqdn = body.publicLabel ? `${body.publicLabel}.${body.publicDomain}` : void 0;
9625
- const apex = body.apex && body.apex.length > 0 ? body.apex : void 0;
9626
- heldInputs.admin = adminFqdn;
9627
- if (publicFqdn) heldInputs.public = publicFqdn;
9628
- if (apex) heldInputs.apex = apex;
9629
- log(`phase=submit-received admin=${adminFqdn} public=${publicFqdn ?? "absent"} apex=${apex ?? "absent"}`);
9630
- const bundleMtimeIso = getBundleMtimeIso();
9631
- try {
9632
- const prior = await findMostRecentTerminalCloudflareTask(accountId, correlationId);
9633
- const branch = decideRetryBranch({ bundleMtimeIso, prior });
9634
- const lastErrorAt = prior && prior.outcome === "failed" ? prior.completedAt : "none";
9635
- log(`retry-decision bundleMtime=${bundleMtimeIso} lastErrorAt=${lastErrorAt} branch=${branch}`);
9636
- if (branch === "surface-error" && prior) {
9637
- const literal = prior.errorMessage ?? CLOUDFLARE_TASK_DIAGNOSTICS.scriptExitedNonzero;
9638
- return err("script", literal);
9639
- }
9640
- } catch (e) {
9641
- log(`retry-decision lookup-failed reason="${e instanceof Error ? e.message : String(e)}" branch=proceed`);
9642
- }
9643
- const account = resolveAccount();
9644
- if (!account) {
9645
- return err("script", "No account on disk for this device \u2014 re-run installer.");
9646
- }
9647
- if (account.accountId !== accountId) {
9648
- return err("script", `Session/device account drift: session=${accountId.slice(0, 8)} device=${account.accountId.slice(0, 8)}`);
9649
- }
9650
- const accountDir = account.accountDir;
9651
- try {
9652
- await setRemotePassword(body.password);
9653
- log(`phase=password-set`);
9654
- } catch (e) {
9655
- return err("password", `Failed to write password: ${e instanceof Error ? e.message : String(e)}`);
9656
- }
9657
- let brand;
9658
- let port2;
9659
- try {
9660
- brand = loadBrandInfo();
9661
- port2 = resolvePort();
9662
- } catch (e) {
9663
- return err("script", `Server misconfigured: ${e instanceof Error ? e.message : String(e)}`);
9664
- }
9665
- streamLogPath = cloudflareStreamLogPath(accountId, correlationId);
9666
- log(`phase=stream-log-resolved path=${streamLogPath}`);
9667
- const args = [brand.hostname, String(port2), adminFqdn];
9668
- if (publicFqdn) args.push(publicFqdn);
9669
- if (apex) args.push(apex);
9670
- if (await isActionActive("cloudflare-setup")) {
9671
- return err("request", "Another Cloudflare setup is already running. Wait for it to finish before starting a new one.");
9672
- }
9673
- const taskInputs = {};
9674
- for (const [key, value] of Object.entries(body)) {
9675
- if (value !== void 0 && value !== null && value !== "") {
9676
- taskInputs[key] = value;
9677
- }
9678
- }
9679
- let cloudflareTask;
9680
- try {
9681
- cloudflareTask = await openCloudflareTask({
9682
- accountId,
9683
- conversationId: correlationId,
9684
- inputsProvided: Object.keys(taskInputs),
9685
- inputs: taskInputs,
9686
- inputSchema: CLOUDFLARE_SETUP_FORM_SCHEMA,
9687
- messageId: typeof body.messageId === "string" && body.messageId.length > 0 ? body.messageId : void 0
9688
- });
9689
- log(`phase=task-opened taskId=${cloudflareTask.taskId}`);
9690
- } catch (e) {
9691
- return err("script", `Failed to open process-provenance Task record: ${e instanceof Error ? e.message : String(e)}`);
9692
- }
9693
- let actionId;
9694
- let unit;
9695
- try {
9696
- const launched = await launchAction("cloudflare-setup", {
9697
- positional: args,
9698
- streamLogPath,
9699
- accountDir,
9700
- tunnelId: typeof body.tunnelId === "string" && body.tunnelId.length > 0 ? body.tunnelId : void 0,
9701
- tunnelName: typeof body.tunnelName === "string" && body.tunnelName.length > 0 ? body.tunnelName : void 0
9702
- });
9703
- actionId = launched.actionId;
9704
- unit = launched.unit;
9705
- } catch (e) {
9706
- return err("script", `Failed to launch cloudflare-setup action: ${e instanceof Error ? e.message : String(e)}`);
9707
- }
9708
- log(`phase=action-launched id=${actionId} unit=${unit}`);
9709
- void (async () => {
9710
- const status = await waitForExit(unit, SETUP_TIMEOUT_MS);
9711
- try {
9712
- const appendedSteps = await appendCloudflareSteps(cloudflareTask.taskId, accountId, streamLogPath);
9713
- log(`phase=task-steps-appended count=${appendedSteps.length}`);
9714
- } catch (e) {
9715
- logErr(`phase=task-steps-append-failed reason="${e instanceof Error ? e.message : String(e)}"`);
9716
- }
9717
- let unitGoneWithDiskProof = false;
9718
- if (status === null) {
9719
- const verdict = resolveUnitGoneVerdict({
9720
- tunnelState: readTunnelState(brand.configDir),
9721
- expected: { tunnelName: body.tunnelName, tunnelId: body.tunnelId }
9722
- });
9723
- const resolution = verdict.kind === "close-completed" ? "close-completed" : "close-failed-diagnostic";
9724
- log(`phase=post-exit-disk-check tunnel-state-found=${verdict.tunnelStateFound} identity-match=${verdict.identityMatch} resolution=${resolution}`);
9725
- if (verdict.kind === "close-failed") {
9726
- try {
9727
- await completeCloudflareTask({
9728
- taskId: cloudflareTask.taskId,
9729
- taskElementId: cloudflareTask.taskElementId,
9730
- accountId,
9731
- conversationId: correlationId,
9732
- status: "failed",
9733
- errorMessage: CLOUDFLARE_TASK_DIAGNOSTICS.endpointDiedPreReconcile
9734
- });
9735
- } catch (e) {
9736
- logErr(`phase=task-close-failed status=failed reason="${e instanceof Error ? e.message : String(e)}"`);
9737
- }
9738
- return;
9739
- }
9740
- unitGoneWithDiskProof = true;
9741
- } else if (status.execMainStatus !== 0) {
9742
- logErr(`phase=post-exit-skipped reason=exit=${status.execMainStatus} id=${actionId}`);
9743
- try {
9744
- await completeCloudflareTask({
9745
- taskId: cloudflareTask.taskId,
9746
- taskElementId: cloudflareTask.taskElementId,
9747
- accountId,
9748
- conversationId: correlationId,
9749
- status: "failed",
9750
- errorMessage: `${CLOUDFLARE_TASK_DIAGNOSTICS.scriptExitedNonzero} exit=${status.execMainStatus}`
9751
- });
9752
- } catch (e) {
9753
- logErr(`phase=task-close-failed status=failed reason="${e instanceof Error ? e.message : String(e)}"`);
9754
- }
9755
- return;
9756
- }
9757
- if (!unitGoneWithDiskProof) {
9758
- const candidates = [publicFqdn, apex].filter((h) => typeof h === "string" && h.length > 0);
9759
- for (const host of candidates) {
9760
- if (host === adminFqdn) {
9761
- log(`phase=alias-domain-write host=${host} result=skipped-admin`);
9762
- continue;
9763
- }
9764
- if (host.startsWith("public.")) {
9765
- log(`phase=alias-domain-write host=${host} result=skipped-public-prefix`);
9766
- continue;
9767
- }
9768
- try {
9769
- addAliasDomain(host);
9770
- log(`phase=alias-domain-write host=${host} result=written`);
9771
- } catch (e) {
9772
- logErr(`phase=alias-domain-write host=${host} result=error reason="${e instanceof Error ? e.message : String(e)}"`);
9773
- }
9774
- }
9775
- }
9776
- try {
9777
- const tunnelState = readTunnelState(brand.configDir);
9778
- const allHostnames = [adminFqdn, publicFqdn, apex].filter(
9779
- (h) => typeof h === "string" && h.length > 0
9780
- );
9781
- const hostnameRecords = allHostnames.map((value) => ({
9782
- hostnameValue: value,
9783
- // Apex heuristic: exactly one dot in the FQDN. Mirrors setup-tunnel.sh:332.
9784
- isApex: (value.match(/\./g)?.length ?? 0) === 1
9785
- }));
9786
- await completeCloudflareTask({
9787
- taskId: cloudflareTask.taskId,
9788
- taskElementId: cloudflareTask.taskElementId,
9789
- accountId,
9790
- conversationId: correlationId,
9791
- tunnelId: tunnelState?.tunnelId,
9792
- tunnelName: tunnelState?.tunnelName,
9793
- hostnames: tunnelState ? hostnameRecords : void 0,
9794
- status: "completed"
9795
- });
9796
- log(`phase=task-closed status=completed tunnelId=${tunnelState?.tunnelId ?? "absent"} hostnames=${allHostnames.length}`);
9797
- } catch (e) {
9798
- logErr(`phase=task-close-failed status=completed reason="${e instanceof Error ? e.message : String(e)}"`);
9799
- }
9800
- log(`phase=done action=${actionId}`);
9801
- })().catch((e) => logErr(`post-exit handler threw: ${e}`));
9802
- const total = Date.now() - started;
9803
- log(`phase=response-sent action_id=${actionId} total_ms=${total}`);
9804
- writeRouteMilestone(
9805
- streamLogPath,
9806
- "cloudflare-setup",
9807
- `phase=action-launched id=${actionId}`
9808
- );
9809
- const success = {
9810
- ok: true,
9811
- output: `Action launched \u2014 see live log in the form panel.
9812
- actionId: ${actionId}`,
9813
- adminFqdn,
9814
- publicFqdn,
9815
- apex,
9816
- aliasesWritten: [],
9817
- actionId
9818
- };
9819
- return ok(success);
9820
- });
9821
- var cloudflare_default = app21;
8733
+ var events_default = app17;
9822
8734
 
9823
8735
  // server/routes/admin/files.ts
9824
- import { createReadStream as createReadStream3 } from "fs";
8736
+ import { createReadStream as createReadStream2 } from "fs";
9825
8737
  import { readdir as readdir2, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
9826
8738
  import { realpathSync as realpathSync4 } from "fs";
9827
- import { basename as basename4, dirname as dirname6, join as join12, resolve as resolve16, sep as sep3 } from "path";
8739
+ import { basename as basename4, dirname as dirname4, join as join12, resolve as resolve14, sep as sep3 } from "path";
9828
8740
  import { Readable as Readable2 } from "stream";
9829
8741
 
9830
8742
  // app/lib/data-path.ts
9831
8743
  import { realpathSync as realpathSync3 } from "fs";
9832
- import { resolve as resolve15, normalize, sep as sep2, relative } from "path";
9833
- var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve15(process.cwd(), "../platform");
9834
- var DATA_ROOT = resolve15(PLATFORM_ROOT5, "..", "data");
8744
+ import { resolve as resolve13, normalize, sep as sep2, relative } from "path";
8745
+ var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve13(process.cwd(), "../platform");
8746
+ var DATA_ROOT = resolve13(PLATFORM_ROOT5, "..", "data");
9835
8747
  function resolveDataPath(raw) {
9836
8748
  const cleaned = normalize("/" + (raw ?? "").replace(/\\/g, "/")).replace(/^\/+/, "");
9837
- const absolute = resolve15(DATA_ROOT, cleaned);
8749
+ const absolute = resolve13(DATA_ROOT, cleaned);
9838
8750
  let dataRootReal;
9839
8751
  try {
9840
8752
  dataRootReal = realpathSync3(DATA_ROOT);
@@ -10192,7 +9104,7 @@ async function readMeta(absDir, baseName) {
10192
9104
  }
10193
9105
  async function readAccountNames() {
10194
9106
  const map = /* @__PURE__ */ new Map();
10195
- const accountsDir = resolve16(DATA_ROOT, "accounts");
9107
+ const accountsDir = resolve14(DATA_ROOT, "accounts");
10196
9108
  let names;
10197
9109
  try {
10198
9110
  names = await readdir2(accountsDir);
@@ -10201,7 +9113,7 @@ async function readAccountNames() {
10201
9113
  }
10202
9114
  for (const name of names) {
10203
9115
  if (!UUID_RE3.test(name)) continue;
10204
- const configPath2 = resolve16(accountsDir, name, "account.json");
9116
+ const configPath2 = resolve14(accountsDir, name, "account.json");
10205
9117
  try {
10206
9118
  const raw = await readFile4(configPath2, "utf8");
10207
9119
  const parsed = JSON.parse(raw);
@@ -10250,8 +9162,8 @@ function buildDisplayPath(relPath2, accountNames) {
10250
9162
  return dn ? { name: seg, displayName: dn } : { name: seg };
10251
9163
  });
10252
9164
  }
10253
- var app22 = new Hono();
10254
- app22.get("/", requireAdminSession, async (c) => {
9165
+ var app18 = new Hono();
9166
+ app18.get("/", requireAdminSession, async (c) => {
10255
9167
  const cacheKey = c.var.cacheKey;
10256
9168
  if (!getAccountIdForSession(cacheKey)) {
10257
9169
  console.error(`[data] auth-rejected endpoint="/api/admin/files" reason="no account for session"`);
@@ -10312,7 +9224,7 @@ app22.get("/", requireAdminSession, async (c) => {
10312
9224
  return c.json({ error: message }, 500);
10313
9225
  }
10314
9226
  });
10315
- app22.get("/download", requireAdminSession, async (c) => {
9227
+ app18.get("/download", requireAdminSession, async (c) => {
10316
9228
  const cacheKey = c.var.cacheKey;
10317
9229
  if (!getAccountIdForSession(cacheKey)) {
10318
9230
  console.error(`[data] auth-rejected endpoint="/api/admin/files/download" reason="no account for session"`);
@@ -10335,7 +9247,7 @@ app22.get("/download", requireAdminSession, async (c) => {
10335
9247
  }
10336
9248
  const filename = basename4(absolute);
10337
9249
  const mimeType = detectMimeType(absolute);
10338
- const nodeStream = createReadStream3(absolute);
9250
+ const nodeStream = createReadStream2(absolute);
10339
9251
  const webStream = Readable2.toWeb(nodeStream);
10340
9252
  console.error(`[data] file-download path="${relPath2}" size=${info.size}`);
10341
9253
  const safeQuotedName = filename.replace(/[\r\n"\\]/g, "_");
@@ -10360,7 +9272,7 @@ app22.get("/download", requireAdminSession, async (c) => {
10360
9272
  return c.json({ error: message }, 500);
10361
9273
  }
10362
9274
  });
10363
- app22.post("/upload", requireAdminSession, async (c) => {
9275
+ app18.post("/upload", requireAdminSession, async (c) => {
10364
9276
  const cacheKey = c.var.cacheKey;
10365
9277
  const accountId = getAccountIdForSession(cacheKey);
10366
9278
  if (!accountId) {
@@ -10392,8 +9304,8 @@ app22.post("/upload", requireAdminSession, async (c) => {
10392
9304
  }
10393
9305
  const safeName = basename4(file.name).replace(/[\0/\\]/g, "_");
10394
9306
  const finalName = `${Date.now()}-${safeName}`;
10395
- const destDir = resolve16(DATA_ROOT, "uploads", accountId);
10396
- const destPath = resolve16(destDir, finalName);
9307
+ const destDir = resolve14(DATA_ROOT, "uploads", accountId);
9308
+ const destPath = resolve14(destDir, finalName);
10397
9309
  try {
10398
9310
  await mkdir3(destDir, { recursive: true });
10399
9311
  const dataRootReal = realpathSync4(DATA_ROOT);
@@ -10418,7 +9330,7 @@ app22.post("/upload", requireAdminSession, async (c) => {
10418
9330
  mimeType: file.type
10419
9331
  });
10420
9332
  });
10421
- app22.delete("/", requireAdminSession, async (c) => {
9333
+ app18.delete("/", requireAdminSession, async (c) => {
10422
9334
  const cacheKey = c.var.cacheKey;
10423
9335
  const accountId = getAccountIdForSession(cacheKey);
10424
9336
  if (!accountId) {
@@ -10451,7 +9363,7 @@ app22.delete("/", requireAdminSession, async (c) => {
10451
9363
  }
10452
9364
  const dot = base.lastIndexOf(".");
10453
9365
  const stem = dot === -1 ? base : base.slice(0, dot);
10454
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join12(dirname6(absolute), `${stem}.meta.json`) : null;
9366
+ const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join12(dirname4(absolute), `${stem}.meta.json`) : null;
10455
9367
  await unlink2(absolute);
10456
9368
  if (sidecarPath) {
10457
9369
  try {
@@ -10485,7 +9397,7 @@ app22.delete("/", requireAdminSession, async (c) => {
10485
9397
  return c.json({ error: message }, 500);
10486
9398
  }
10487
9399
  });
10488
- var files_default = app22;
9400
+ var files_default = app18;
10489
9401
 
10490
9402
  // ../lib/graph-search/src/index.ts
10491
9403
  var import_dist = __toESM(require_dist());
@@ -10865,8 +9777,8 @@ var MAX_LIMIT = 2e3;
10865
9777
  var DEFAULT_VECTOR_THRESHOLD = 0.82;
10866
9778
  var MESSAGE_FAMILY_LABELS = ["Message", "UserMessage", "AssistantMessage", "WhatsAppMessage"];
10867
9779
  var CONVERSATION_PARENT_LABELS = /* @__PURE__ */ new Set(["AdminConversation", "PublicConversation"]);
10868
- var app23 = new Hono();
10869
- app23.get("/", requireAdminSession, async (c) => {
9780
+ var app19 = new Hono();
9781
+ app19.get("/", requireAdminSession, async (c) => {
10870
9782
  const cacheKey = c.var.cacheKey;
10871
9783
  const q = (c.req.query("q") ?? "").trim();
10872
9784
  const rawLimit = c.req.query("limit");
@@ -10997,7 +9909,7 @@ app23.get("/", requireAdminSession, async (c) => {
10997
9909
  await session.close();
10998
9910
  }
10999
9911
  });
11000
- var graph_search_default = app23;
9912
+ var graph_search_default = app19;
11001
9913
 
11002
9914
  // server/routes/admin/graph-subgraph.ts
11003
9915
  import neo4j from "neo4j-driver";
@@ -11151,8 +10063,8 @@ var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
11151
10063
  "otpCode",
11152
10064
  "cacheKey"
11153
10065
  ]);
11154
- var app24 = new Hono();
11155
- app24.get("/", requireAdminSession, async (c) => {
10066
+ var app20 = new Hono();
10067
+ app20.get("/", requireAdminSession, async (c) => {
11156
10068
  const cacheKey = c.var.cacheKey;
11157
10069
  const accountId = getAccountIdForSession(cacheKey);
11158
10070
  if (!accountId) {
@@ -11735,12 +10647,12 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
11735
10647
  }
11736
10648
  return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
11737
10649
  }
11738
- var graph_subgraph_default = app24;
10650
+ var graph_subgraph_default = app20;
11739
10651
 
11740
10652
  // server/routes/admin/graph-delete.ts
11741
10653
  var ALLOWED_BY = ["graph-page", "graph-drag-trash", "graph-side-panel-trash"];
11742
- var app25 = new Hono();
11743
- app25.post("/", requireAdminSession, async (c) => {
10654
+ var app21 = new Hono();
10655
+ app21.post("/", requireAdminSession, async (c) => {
11744
10656
  const cacheKey = c.var.cacheKey;
11745
10657
  const accountId = getAccountIdForSession(cacheKey);
11746
10658
  if (!accountId) {
@@ -11903,11 +10815,11 @@ app25.post("/", requireAdminSession, async (c) => {
11903
10815
  }
11904
10816
  }
11905
10817
  });
11906
- var graph_delete_default = app25;
10818
+ var graph_delete_default = app21;
11907
10819
 
11908
10820
  // server/routes/admin/graph-restore.ts
11909
- var app26 = new Hono();
11910
- app26.post("/", requireAdminSession, async (c) => {
10821
+ var app22 = new Hono();
10822
+ app22.post("/", requireAdminSession, async (c) => {
11911
10823
  const cacheKey = c.var.cacheKey;
11912
10824
  const accountId = getAccountIdForSession(cacheKey);
11913
10825
  if (!accountId) {
@@ -11971,11 +10883,11 @@ app26.post("/", requireAdminSession, async (c) => {
11971
10883
  }
11972
10884
  }
11973
10885
  });
11974
- var graph_restore_default = app26;
10886
+ var graph_restore_default = app22;
11975
10887
 
11976
10888
  // server/routes/admin/graph-labels-in-graph.ts
11977
- var app27 = new Hono();
11978
- app27.get("/", requireAdminSession, async (c) => {
10889
+ var app23 = new Hono();
10890
+ app23.get("/", requireAdminSession, async (c) => {
11979
10891
  const cacheKey = c.var.cacheKey;
11980
10892
  const accountId = getAccountIdForSession(cacheKey);
11981
10893
  if (!accountId) {
@@ -12041,11 +10953,11 @@ var LABELS_IN_GRAPH_CYPHER = `
12041
10953
  sum(halfEdges) AS relDegree
12042
10954
  RETURN label, nodeCount, relDegree
12043
10955
  `;
12044
- var graph_labels_in_graph_default = app27;
10956
+ var graph_labels_in_graph_default = app23;
12045
10957
 
12046
10958
  // server/routes/admin/graph-default-view.ts
12047
- var app28 = new Hono();
12048
- app28.get("/", requireAdminSession, async (c) => {
10959
+ var app24 = new Hono();
10960
+ app24.get("/", requireAdminSession, async (c) => {
12049
10961
  const cacheKey = c.var.cacheKey;
12050
10962
  const accountId = getAccountIdForSession(cacheKey);
12051
10963
  const userId = getUserIdForSession(cacheKey);
@@ -12083,7 +10995,7 @@ app28.get("/", requireAdminSession, async (c) => {
12083
10995
  }
12084
10996
  }
12085
10997
  });
12086
- app28.put("/", requireAdminSession, async (c) => {
10998
+ app24.put("/", requireAdminSession, async (c) => {
12087
10999
  const cacheKey = c.var.cacheKey;
12088
11000
  const accountId = getAccountIdForSession(cacheKey);
12089
11001
  const userId = getUserIdForSession(cacheKey);
@@ -12095,7 +11007,7 @@ app28.put("/", requireAdminSession, async (c) => {
12095
11007
  if (!body) {
12096
11008
  return c.json({ error: "Request body must be JSON" }, 400);
12097
11009
  }
12098
- const validation = validateBody2(body);
11010
+ const validation = validateBody(body);
12099
11011
  if (!validation.ok) {
12100
11012
  console.error(
12101
11013
  `[graph-page] default-view-rejected op=save account=${accountId} reason="${validation.reason}"`
@@ -12136,7 +11048,7 @@ app28.put("/", requireAdminSession, async (c) => {
12136
11048
  }
12137
11049
  }
12138
11050
  });
12139
- function validateBody2(body) {
11051
+ function validateBody(body) {
12140
11052
  if (!Array.isArray(body.labels)) {
12141
11053
  return { ok: false, code: "shape", reason: "labels must be an array of strings" };
12142
11054
  }
@@ -12172,13 +11084,13 @@ var WRITE_CYPHER = `
12172
11084
  p.updatedAt = $updatedAt
12173
11085
  RETURN p.labels AS labels
12174
11086
  `;
12175
- var graph_default_view_default = app28;
11087
+ var graph_default_view_default = app24;
12176
11088
 
12177
11089
  // server/routes/admin/session-defaults.ts
12178
- var app29 = new Hono();
11090
+ var app25 = new Hono();
12179
11091
  var MODE_OPTIONS = ["default", "acceptEdits", "plan", "auto", "bypassPermissions"];
12180
11092
  var MODEL_OPTIONS = ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5"];
12181
- app29.get("/", requireAdminSession, async (c) => {
11093
+ app25.get("/", requireAdminSession, async (c) => {
12182
11094
  const cacheKey = c.var.cacheKey;
12183
11095
  const accountId = getAccountIdForSession(cacheKey);
12184
11096
  const userId = getUserIdForSession(cacheKey);
@@ -12216,7 +11128,7 @@ app29.get("/", requireAdminSession, async (c) => {
12216
11128
  }
12217
11129
  }
12218
11130
  });
12219
- app29.put("/", requireAdminSession, async (c) => {
11131
+ app25.put("/", requireAdminSession, async (c) => {
12220
11132
  const cacheKey = c.var.cacheKey;
12221
11133
  const accountId = getAccountIdForSession(cacheKey);
12222
11134
  const userId = getUserIdForSession(cacheKey);
@@ -12228,7 +11140,7 @@ app29.put("/", requireAdminSession, async (c) => {
12228
11140
  if (!body) {
12229
11141
  return c.json({ error: "Request body must be JSON" }, 400);
12230
11142
  }
12231
- const validation = validateBody3(body);
11143
+ const validation = validateBody2(body);
12232
11144
  if (!validation.ok) {
12233
11145
  console.error(
12234
11146
  `[session-defaults] rejected op=save account=${accountId} reason="${validation.reason}"`
@@ -12267,7 +11179,7 @@ app29.put("/", requireAdminSession, async (c) => {
12267
11179
  }
12268
11180
  }
12269
11181
  });
12270
- function validateBody3(body) {
11182
+ function validateBody2(body) {
12271
11183
  if (typeof body.permissionMode !== "string") {
12272
11184
  return { ok: false, reason: "permissionMode must be a string" };
12273
11185
  }
@@ -12300,11 +11212,11 @@ var WRITE_CYPHER2 = `
12300
11212
  p.updatedAt = $updatedAt
12301
11213
  RETURN p.permissionMode AS permissionMode
12302
11214
  `;
12303
- var session_defaults_default = app29;
11215
+ var session_defaults_default = app25;
12304
11216
 
12305
11217
  // server/routes/admin/file-attach.ts
12306
- var app30 = new Hono();
12307
- app30.post("/", async (c) => {
11218
+ var app26 = new Hono();
11219
+ app26.post("/", async (c) => {
12308
11220
  try {
12309
11221
  const body = await c.req.json();
12310
11222
  const { filePath, accountId } = body;
@@ -12327,18 +11239,18 @@ app30.post("/", async (c) => {
12327
11239
  return c.json({ error: message }, 500);
12328
11240
  }
12329
11241
  });
12330
- var file_attach_default = app30;
11242
+ var file_attach_default = app26;
12331
11243
 
12332
11244
  // server/routes/admin/sidebar-artefacts.ts
12333
11245
  import neo4j2 from "neo4j-driver";
12334
11246
  import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
12335
- import { resolve as resolve17, relative as relative2, isAbsolute } from "path";
11247
+ import { resolve as resolve15, relative as relative2, isAbsolute } from "path";
12336
11248
  import { existsSync as existsSync17 } from "fs";
12337
11249
  var LIMIT = 50;
12338
11250
  var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
12339
11251
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
12340
- var app31 = new Hono();
12341
- app31.get("/", requireAdminSession, async (c) => {
11252
+ var app27 = new Hono();
11253
+ app27.get("/", requireAdminSession, async (c) => {
12342
11254
  const cacheKey = c.var.cacheKey;
12343
11255
  const accountId = getAccountIdForSession(cacheKey);
12344
11256
  if (!accountId) {
@@ -12349,7 +11261,7 @@ app31.get("/", requireAdminSession, async (c) => {
12349
11261
  if (docs === null) {
12350
11262
  return c.json({ error: "Failed to load artefacts" }, 500);
12351
11263
  }
12352
- const accountDir = resolve17(ACCOUNTS_DIR, accountId);
11264
+ const accountDir = resolve15(ACCOUNTS_DIR, accountId);
12353
11265
  const agents = await fetchAgentTemplateRows(accountDir);
12354
11266
  const artefacts = [...docs, ...agents].sort(
12355
11267
  (a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
@@ -12412,8 +11324,8 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
12412
11324
  logSkip(displayName, "non-text-mime", mimeType);
12413
11325
  return { content: "", skipReason: "non-text-mime" };
12414
11326
  }
12415
- const accountDir = resolve17(ATTACHMENTS_ROOT, accountId);
12416
- const dir = resolve17(accountDir, attachmentId);
11327
+ const accountDir = resolve15(ATTACHMENTS_ROOT, accountId);
11328
+ const dir = resolve15(accountDir, attachmentId);
12417
11329
  try {
12418
11330
  validateFilePathInAccount(dir, accountDir);
12419
11331
  } catch {
@@ -12427,7 +11339,7 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
12427
11339
  logSkip(displayName, "missing-on-disk", mimeType);
12428
11340
  return { content: "", skipReason: "missing-on-disk" };
12429
11341
  }
12430
- return { content: await readFile5(resolve17(dir, dataFile), "utf-8"), skipReason: null };
11342
+ return { content: await readFile5(resolve15(dir, dataFile), "utf-8"), skipReason: null };
12431
11343
  } catch (err) {
12432
11344
  const message = err instanceof Error ? err.message : String(err);
12433
11345
  console.error(`[admin/sidebar-artefacts] read-failed attachmentId=${attachmentId.slice(0, 8)} error="${message}"`);
@@ -12443,8 +11355,8 @@ function logSkip(name, reason, mimeType) {
12443
11355
  async function fetchAgentTemplateRows(accountDir) {
12444
11356
  const rows = [];
12445
11357
  for (const filename of ADMIN_AGENT_FILES) {
12446
- const overridePath = resolve17(accountDir, "agents", "admin", filename);
12447
- const bundledPath = resolve17(PLATFORM_ROOT, "templates", "agents", "admin", filename);
11358
+ const overridePath = resolve15(accountDir, "agents", "admin", filename);
11359
+ const bundledPath = resolve15(PLATFORM_ROOT, "templates", "agents", "admin", filename);
12448
11360
  const labelStem = filename.replace(/\.md$/, "");
12449
11361
  const row = await readAgentTemplateRow({
12450
11362
  id: `agent-template:admin:${filename}`,
@@ -12458,12 +11370,12 @@ async function fetchAgentTemplateRows(accountDir) {
12458
11370
  });
12459
11371
  if (row) rows.push(row);
12460
11372
  }
12461
- const overrideDir = resolve17(accountDir, "specialists", "agents");
12462
- const bundledDir = resolve17(PLATFORM_ROOT, "templates", "specialists", "agents");
11373
+ const overrideDir = resolve15(accountDir, "specialists", "agents");
11374
+ const bundledDir = resolve15(PLATFORM_ROOT, "templates", "specialists", "agents");
12463
11375
  const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
12464
11376
  for (const filename of specialistNames) {
12465
- const overridePath = resolve17(overrideDir, filename);
12466
- const bundledPath = resolve17(bundledDir, filename);
11377
+ const overridePath = resolve15(overrideDir, filename);
11378
+ const bundledPath = resolve15(bundledDir, filename);
12467
11379
  const row = await readAgentTemplateRow({
12468
11380
  id: `agent-template:specialist:${filename}`,
12469
11381
  displayName: filename.replace(/\.md$/, ""),
@@ -12544,16 +11456,16 @@ function isWithin(target, root) {
12544
11456
  const rel = relative2(root, target);
12545
11457
  return !rel.startsWith("..") && !isAbsolute(rel);
12546
11458
  }
12547
- var sidebar_artefacts_default = app31;
11459
+ var sidebar_artefacts_default = app27;
12548
11460
 
12549
11461
  // server/routes/admin/sidebar-artefact-save.ts
12550
11462
  import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
12551
- import { resolve as resolve18 } from "path";
11463
+ import { resolve as resolve16 } from "path";
12552
11464
  import { existsSync as existsSync18 } from "fs";
12553
11465
  var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
12554
11466
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
12555
- var app32 = new Hono();
12556
- app32.post("/", requireAdminSession, async (c) => {
11467
+ var app28 = new Hono();
11468
+ app28.post("/", requireAdminSession, async (c) => {
12557
11469
  const cacheKey = c.var.cacheKey;
12558
11470
  const accountId = getAccountIdForSession(cacheKey);
12559
11471
  if (!accountId) return c.json({ error: "Account not found for session" }, 401);
@@ -12561,7 +11473,7 @@ app32.post("/", requireAdminSession, async (c) => {
12561
11473
  if (!body || typeof body.id !== "string" || typeof body.content !== "string") {
12562
11474
  return c.json({ error: "id and content required" }, 400);
12563
11475
  }
12564
- const accountDir = resolve18(ACCOUNTS_DIR, accountId);
11476
+ const accountDir = resolve16(ACCOUNTS_DIR, accountId);
12565
11477
  const resolved = await resolveSavePath(body.id, accountId, accountDir);
12566
11478
  if (resolved.kind === "heal-race") {
12567
11479
  c.header("Retry-After", "2");
@@ -12606,17 +11518,17 @@ async function resolveSavePath(id, accountId, accountDir) {
12606
11518
  if (role !== "admin" || !ADMIN_AGENT_FILES2.has(filename)) {
12607
11519
  return { kind: "reject", status: 400, reason: "invalid-id" };
12608
11520
  }
12609
- const parent = resolve18(accountDir, "agents", "admin");
11521
+ const parent = resolve16(accountDir, "agents", "admin");
12610
11522
  await mkdir4(parent, { recursive: true });
12611
11523
  try {
12612
11524
  validateFilePathInAccount(parent, accountDir);
12613
11525
  } catch {
12614
11526
  return { kind: "reject", status: 400, reason: "containment-rejected" };
12615
11527
  }
12616
- return { kind: "admin-template", path: resolve18(parent, filename) };
11528
+ return { kind: "admin-template", path: resolve16(parent, filename) };
12617
11529
  }
12618
11530
  if (UUID_RE4.test(id)) {
12619
- const dir = resolve18(ATTACHMENTS_ROOT, accountId, id);
11531
+ const dir = resolve16(ATTACHMENTS_ROOT, accountId, id);
12620
11532
  if (!existsSync18(dir)) {
12621
11533
  const attShort = id.slice(0, 8);
12622
11534
  if (isHealPending(accountId, id)) {
@@ -12649,7 +11561,7 @@ async function resolveSavePath(id, accountId, accountDir) {
12649
11561
  }
12650
11562
  }
12651
11563
  try {
12652
- validateFilePathInAccount(dir, resolve18(ATTACHMENTS_ROOT, accountId));
11564
+ validateFilePathInAccount(dir, resolve16(ATTACHMENTS_ROOT, accountId));
12653
11565
  } catch {
12654
11566
  return { kind: "reject", status: 400, reason: "containment-rejected" };
12655
11567
  }
@@ -12658,22 +11570,22 @@ async function resolveSavePath(id, accountId, accountDir) {
12658
11570
  if (!dataFile) {
12659
11571
  return { kind: "reject", status: 400, reason: "not-found" };
12660
11572
  }
12661
- return { kind: "knowledge-doc", path: resolve18(dir, dataFile) };
11573
+ return { kind: "knowledge-doc", path: resolve16(dir, dataFile) };
12662
11574
  }
12663
11575
  return { kind: "reject", status: 400, reason: "invalid-id" };
12664
11576
  }
12665
11577
  function relPath(absPath, root) {
12666
11578
  return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
12667
11579
  }
12668
- var sidebar_artefact_save_default = app32;
11580
+ var sidebar_artefact_save_default = app28;
12669
11581
 
12670
11582
  // server/routes/admin/sidebar-artefact-content.ts
12671
11583
  import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
12672
11584
  import { existsSync as existsSync19 } from "fs";
12673
- import { resolve as resolve19 } from "path";
11585
+ import { resolve as resolve17 } from "path";
12674
11586
  var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
12675
- var app33 = new Hono();
12676
- app33.get("/", requireAdminSession, async (c) => {
11587
+ var app29 = new Hono();
11588
+ app29.get("/", requireAdminSession, async (c) => {
12677
11589
  const cacheKey = c.var.cacheKey;
12678
11590
  const accountId = getAccountIdForSession(cacheKey);
12679
11591
  if (!accountId) return new Response("Unauthorized", { status: 401 });
@@ -12682,14 +11594,14 @@ app33.get("/", requireAdminSession, async (c) => {
12682
11594
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
12683
11595
  return new Response("Not found", { status: 404 });
12684
11596
  }
12685
- const dir = resolve19(ATTACHMENTS_ROOT, accountId, id);
11597
+ const dir = resolve17(ATTACHMENTS_ROOT, accountId, id);
12686
11598
  if (!existsSync19(dir)) {
12687
11599
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
12688
11600
  return new Response("Not found", { status: 404 });
12689
11601
  }
12690
11602
  let meta;
12691
11603
  try {
12692
- meta = JSON.parse(await readFile6(resolve19(dir, `${id}.meta.json`), "utf-8"));
11604
+ meta = JSON.parse(await readFile6(resolve17(dir, `${id}.meta.json`), "utf-8"));
12693
11605
  } catch {
12694
11606
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
12695
11607
  return new Response("Not found", { status: 404 });
@@ -12701,7 +11613,7 @@ app33.get("/", requireAdminSession, async (c) => {
12701
11613
  return new Response("Not found", { status: 404 });
12702
11614
  }
12703
11615
  const start = Date.now();
12704
- const buffer = await readFile6(resolve19(dir, dataFile));
11616
+ const buffer = await readFile6(resolve17(dir, dataFile));
12705
11617
  const ms = Date.now() - start;
12706
11618
  console.log(
12707
11619
  `[admin/sidebar-artefact-content] account=${accountId} id=${id.slice(0, 8)} mime=${meta.mimeType} bytes=${buffer.length} ms=${ms}`
@@ -12714,7 +11626,7 @@ app33.get("/", requireAdminSession, async (c) => {
12714
11626
  }
12715
11627
  });
12716
11628
  });
12717
- var sidebar_artefact_content_default = app33;
11629
+ var sidebar_artefact_content_default = app29;
12718
11630
 
12719
11631
  // server/routes/admin/system-stats.ts
12720
11632
  import { readFile as readFile7 } from "fs/promises";
@@ -12811,8 +11723,8 @@ async function sample() {
12811
11723
  if (process.platform === "linux") return sampleLinux();
12812
11724
  return sampleOsFallback();
12813
11725
  }
12814
- var app34 = new Hono();
12815
- app34.get("/", async (c) => {
11726
+ var app30 = new Hono();
11727
+ app30.get("/", async (c) => {
12816
11728
  const started = Date.now();
12817
11729
  if (!inflight) {
12818
11730
  inflight = sample().finally(() => {
@@ -12835,27 +11747,27 @@ app34.get("/", async (c) => {
12835
11747
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
12836
11748
  }
12837
11749
  });
12838
- var system_stats_default = app34;
11750
+ var system_stats_default = app30;
12839
11751
 
12840
11752
  // server/routes/admin/health.ts
12841
- import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
12842
- import { resolve as resolve20, join as join13 } from "path";
12843
- var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
11753
+ import { existsSync as existsSync20, readFileSync as readFileSync16 } from "fs";
11754
+ import { resolve as resolve18, join as join13 } from "path";
11755
+ var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
12844
11756
  var brandHostname = "maxy";
12845
11757
  var brandJsonPath = join13(PLATFORM_ROOT6, "config", "brand.json");
12846
11758
  if (existsSync20(brandJsonPath)) {
12847
11759
  try {
12848
- const brand = JSON.parse(readFileSync18(brandJsonPath, "utf-8"));
11760
+ const brand = JSON.parse(readFileSync16(brandJsonPath, "utf-8"));
12849
11761
  if (brand.hostname) brandHostname = brand.hostname;
12850
11762
  } catch {
12851
11763
  }
12852
11764
  }
12853
- var VERSION_FILE = resolve20(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
11765
+ var VERSION_FILE = resolve18(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
12854
11766
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
12855
11767
  var PROBE_TIMEOUT_MS = 1e3;
12856
11768
  function readVersion() {
12857
11769
  if (!existsSync20(VERSION_FILE)) return "unknown";
12858
- return readFileSync18(VERSION_FILE, "utf-8").trim() || "unknown";
11770
+ return readFileSync16(VERSION_FILE, "utf-8").trim() || "unknown";
12859
11771
  }
12860
11772
  async function probeConversationDb() {
12861
11773
  let session;
@@ -12880,8 +11792,8 @@ async function probeConversationDb() {
12880
11792
  });
12881
11793
  }
12882
11794
  }
12883
- var app35 = new Hono();
12884
- app35.get("/", async (c) => {
11795
+ var app31 = new Hono();
11796
+ app31.get("/", async (c) => {
12885
11797
  const version = readVersion();
12886
11798
  const probe = await probeConversationDb();
12887
11799
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -12903,7 +11815,7 @@ app35.get("/", async (c) => {
12903
11815
  uptimeMs
12904
11816
  });
12905
11817
  });
12906
- var health_default2 = app35;
11818
+ var health_default2 = app31;
12907
11819
 
12908
11820
  // server/routes/admin/linkedin-ingest.ts
12909
11821
  var TAG20 = "[linkedin-ingest-route]";
@@ -12999,8 +11911,8 @@ function buildInitialMessage(env) {
12999
11911
  }
13000
11912
  return header;
13001
11913
  }
13002
- var app36 = new Hono();
13003
- app36.post("/", requireAdminSession, async (c) => {
11914
+ var app32 = new Hono();
11915
+ app32.post("/", requireAdminSession, async (c) => {
13004
11916
  let body;
13005
11917
  try {
13006
11918
  body = await c.req.json();
@@ -13050,46 +11962,42 @@ app36.post("/", requireAdminSession, async (c) => {
13050
11962
  );
13051
11963
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: claudeSessionId }, 202);
13052
11964
  });
13053
- var linkedin_ingest_default = app36;
11965
+ var linkedin_ingest_default = app32;
13054
11966
 
13055
11967
  // server/routes/admin/index.ts
13056
- var app37 = new Hono();
13057
- app37.route("/session", session_default);
13058
- app37.route("/new-session-failure", new_session_failure_default);
13059
- app37.route("/new-session-submit", new_session_submit_default);
13060
- app37.route("/logs", logs_default);
13061
- app37.route("/claude-info", claude_info_default);
13062
- app37.route("/claude-capabilities", claude_capabilities_default);
13063
- app37.route("/attachment", attachment_default);
13064
- app37.route("/agents", agents_default);
13065
- app37.route("/sessions", sessions_default);
13066
- app37.route("/claude-sessions", claude_sessions_default);
13067
- app37.route("/log-ingest", log_ingest_default);
13068
- app37.route("/browser", browser_default);
13069
- app37.route("/browser-iframe", browser_iframe_default);
13070
- app37.route("/device-browser", device_browser_default);
13071
- app37.route("/events", events_default);
13072
- app37.route("/cloudflare", cloudflare_default);
13073
- app37.route("/files", files_default);
13074
- app37.route("/graph-search", graph_search_default);
13075
- app37.route("/graph-subgraph", graph_subgraph_default);
13076
- app37.route("/graph-delete", graph_delete_default);
13077
- app37.route("/graph-restore", graph_restore_default);
13078
- app37.route("/graph-labels-in-graph", graph_labels_in_graph_default);
13079
- app37.route("/graph-default-view", graph_default_view_default);
13080
- app37.route("/session-defaults", session_defaults_default);
13081
- app37.route("/file-attach", file_attach_default);
13082
- app37.route("/sidebar-artefacts", sidebar_artefacts_default);
13083
- app37.route("/sidebar-artefact-save", sidebar_artefact_save_default);
13084
- app37.route("/sidebar-artefact-content", sidebar_artefact_content_default);
13085
- app37.route("/system-stats", system_stats_default);
13086
- app37.route("/health-brand", health_default2);
13087
- app37.route("/linkedin-ingest", linkedin_ingest_default);
13088
- var admin_default = app37;
11968
+ var app33 = new Hono();
11969
+ app33.route("/session", session_default);
11970
+ app33.route("/new-session-failure", new_session_failure_default);
11971
+ app33.route("/new-session-submit", new_session_submit_default);
11972
+ app33.route("/logs", logs_default);
11973
+ app33.route("/claude-info", claude_info_default);
11974
+ app33.route("/claude-capabilities", claude_capabilities_default);
11975
+ app33.route("/attachment", attachment_default);
11976
+ app33.route("/agents", agents_default);
11977
+ app33.route("/sessions", sessions_default);
11978
+ app33.route("/claude-sessions", claude_sessions_default);
11979
+ app33.route("/log-ingest", log_ingest_default);
11980
+ app33.route("/events", events_default);
11981
+ app33.route("/files", files_default);
11982
+ app33.route("/graph-search", graph_search_default);
11983
+ app33.route("/graph-subgraph", graph_subgraph_default);
11984
+ app33.route("/graph-delete", graph_delete_default);
11985
+ app33.route("/graph-restore", graph_restore_default);
11986
+ app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
11987
+ app33.route("/graph-default-view", graph_default_view_default);
11988
+ app33.route("/session-defaults", session_defaults_default);
11989
+ app33.route("/file-attach", file_attach_default);
11990
+ app33.route("/sidebar-artefacts", sidebar_artefacts_default);
11991
+ app33.route("/sidebar-artefact-save", sidebar_artefact_save_default);
11992
+ app33.route("/sidebar-artefact-content", sidebar_artefact_content_default);
11993
+ app33.route("/system-stats", system_stats_default);
11994
+ app33.route("/health-brand", health_default2);
11995
+ app33.route("/linkedin-ingest", linkedin_ingest_default);
11996
+ var admin_default = app33;
13089
11997
 
13090
11998
  // server/routes/sites.ts
13091
- import { existsSync as existsSync21, readFileSync as readFileSync19, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
13092
- import { resolve as resolve21 } from "path";
11999
+ import { existsSync as existsSync21, readFileSync as readFileSync17, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
12000
+ import { resolve as resolve19 } from "path";
13093
12001
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
13094
12002
  var MIME = {
13095
12003
  ".html": "text/html; charset=utf-8",
@@ -13120,8 +12028,8 @@ function getExt(p) {
13120
12028
  if (idx < p.lastIndexOf("/")) return "";
13121
12029
  return p.slice(idx).toLowerCase();
13122
12030
  }
13123
- var app38 = new Hono();
13124
- app38.get("/:rel{.*}", (c) => {
12031
+ var app34 = new Hono();
12032
+ app34.get("/:rel{.*}", (c) => {
13125
12033
  const reqPath = c.req.path;
13126
12034
  const rawRel = c.req.param("rel") ?? "";
13127
12035
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -13146,15 +12054,15 @@ app38.get("/:rel{.*}", (c) => {
13146
12054
  }
13147
12055
  segments.push(seg);
13148
12056
  }
13149
- const rootDir = resolve21(account.accountDir, "sites");
13150
- let filePath = segments.length === 0 ? rootDir : resolve21(rootDir, ...segments);
12057
+ const rootDir = resolve19(account.accountDir, "sites");
12058
+ let filePath = segments.length === 0 ? rootDir : resolve19(rootDir, ...segments);
13151
12059
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
13152
12060
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
13153
12061
  return c.text("Forbidden", 403);
13154
12062
  }
13155
12063
  let stat7;
13156
12064
  try {
13157
- stat7 = existsSync21(filePath) ? statSync9(filePath) : null;
12065
+ stat7 = existsSync21(filePath) ? statSync7(filePath) : null;
13158
12066
  } catch {
13159
12067
  stat7 = null;
13160
12068
  }
@@ -13167,7 +12075,7 @@ app38.get("/:rel{.*}", (c) => {
13167
12075
  return c.redirect(target, 301);
13168
12076
  }
13169
12077
  if (stat7?.isDirectory()) {
13170
- filePath = resolve21(filePath, "index.html");
12078
+ filePath = resolve19(filePath, "index.html");
13171
12079
  }
13172
12080
  if (!filePath.startsWith(rootDir + "/")) {
13173
12081
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
@@ -13192,7 +12100,7 @@ app38.get("/:rel{.*}", (c) => {
13192
12100
  }
13193
12101
  let body;
13194
12102
  try {
13195
- body = readFileSync19(realPath);
12103
+ body = readFileSync17(realPath);
13196
12104
  } catch (err) {
13197
12105
  const code = err?.code;
13198
12106
  if (code === "EISDIR") {
@@ -13224,7 +12132,7 @@ app38.get("/:rel{.*}", (c) => {
13224
12132
  "X-Content-Type-Options": "nosniff"
13225
12133
  });
13226
12134
  });
13227
- var sites_default = app38;
12135
+ var sites_default = app34;
13228
12136
 
13229
12137
  // app/lib/graph-health.ts
13230
12138
  var HOUR_MS = 60 * 60 * 1e3;
@@ -13336,10 +12244,38 @@ function startReaper2() {
13336
12244
  startReaper();
13337
12245
  }
13338
12246
 
12247
+ // app/lib/admin-sse-registry.ts
12248
+ var activeAdminSSEControllers = /* @__PURE__ */ new Set();
12249
+ function broadcastAdminShutdown(reason) {
12250
+ const encoder = new TextEncoder();
12251
+ const payload = JSON.stringify({ type: "server_shutdown", reason });
12252
+ const frame = encoder.encode(`data: ${payload}
12253
+
12254
+ `);
12255
+ const done = encoder.encode(`data: [DONE]
12256
+
12257
+ `);
12258
+ for (const entry of activeAdminSSEControllers) {
12259
+ try {
12260
+ entry.controller.enqueue(frame);
12261
+ } catch {
12262
+ }
12263
+ try {
12264
+ entry.controller.enqueue(done);
12265
+ } catch {
12266
+ }
12267
+ try {
12268
+ entry.controller.close();
12269
+ } catch {
12270
+ }
12271
+ }
12272
+ activeAdminSSEControllers.clear();
12273
+ }
12274
+
13339
12275
  // ../lib/entitlement/src/index.ts
13340
12276
  import { createPublicKey, createHash as createHash3, verify as cryptoVerify } from "crypto";
13341
- import { existsSync as existsSync22, readFileSync as readFileSync20, statSync as statSync10 } from "fs";
13342
- import { resolve as resolve22 } from "path";
12277
+ import { existsSync as existsSync22, readFileSync as readFileSync18, statSync as statSync8 } from "fs";
12278
+ import { resolve as resolve20 } from "path";
13343
12279
 
13344
12280
  // ../lib/entitlement/src/canonicalize.ts
13345
12281
  function canonicalize(value) {
@@ -13374,7 +12310,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
13374
12310
  var GRACE_DAYS = 7;
13375
12311
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
13376
12312
  function pubkeyPath(brand) {
13377
- return resolve22(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
12313
+ return resolve20(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
13378
12314
  }
13379
12315
  var memo = null;
13380
12316
  function memoKey(mtimeMs, account) {
@@ -13386,11 +12322,11 @@ function resolveEntitlement(brand, account) {
13386
12322
  if (brand.commercialMode !== true) {
13387
12323
  return logResolved(implicitTrust(account), null);
13388
12324
  }
13389
- const entitlementPath = resolve22(brand.configDir, "entitlement.json");
12325
+ const entitlementPath = resolve20(brand.configDir, "entitlement.json");
13390
12326
  if (!existsSync22(entitlementPath)) {
13391
12327
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
13392
12328
  }
13393
- const stat7 = statSync10(entitlementPath);
12329
+ const stat7 = statSync8(entitlementPath);
13394
12330
  const key = memoKey(stat7.mtimeMs, account);
13395
12331
  if (memo && memo.key === key) {
13396
12332
  return memo.result;
@@ -13402,7 +12338,7 @@ function resolveEntitlement(brand, account) {
13402
12338
  function verifyAndResolve(brand, entitlementPath, account) {
13403
12339
  let pubkeyPem;
13404
12340
  try {
13405
- pubkeyPem = readFileSync20(pubkeyPath(brand), "utf-8");
12341
+ pubkeyPem = readFileSync18(pubkeyPath(brand), "utf-8");
13406
12342
  } catch (err) {
13407
12343
  return logResolved(anonymousFallback("pubkey-missing"), {
13408
12344
  reason: "pubkey-missing"
@@ -13416,7 +12352,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
13416
12352
  }
13417
12353
  let envelope;
13418
12354
  try {
13419
- envelope = JSON.parse(readFileSync20(entitlementPath, "utf-8"));
12355
+ envelope = JSON.parse(readFileSync18(entitlementPath, "utf-8"));
13420
12356
  } catch {
13421
12357
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
13422
12358
  }
@@ -13584,7 +12520,7 @@ if (BRAND_JSON_PATH && !existsSync23(BRAND_JSON_PATH)) {
13584
12520
  }
13585
12521
  if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
13586
12522
  try {
13587
- const parsed = JSON.parse(readFileSync21(BRAND_JSON_PATH, "utf-8"));
12523
+ const parsed = JSON.parse(readFileSync19(BRAND_JSON_PATH, "utf-8"));
13588
12524
  BRAND = { ...BRAND, ...parsed };
13589
12525
  } catch (err) {
13590
12526
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -13603,11 +12539,11 @@ var brandLoginOpts = {
13603
12539
  bodyFont: BRAND.defaultFonts?.body,
13604
12540
  logoContainsName: !!BRAND.logoContainsName
13605
12541
  };
13606
- var ALIAS_DOMAINS_PATH2 = join14(homedir5(), BRAND.configDir, "alias-domains.json");
12542
+ var ALIAS_DOMAINS_PATH = join14(homedir4(), BRAND.configDir, "alias-domains.json");
13607
12543
  function loadAliasDomains() {
13608
12544
  try {
13609
- if (!existsSync23(ALIAS_DOMAINS_PATH2)) return null;
13610
- const parsed = JSON.parse(readFileSync21(ALIAS_DOMAINS_PATH2, "utf-8"));
12545
+ if (!existsSync23(ALIAS_DOMAINS_PATH)) return null;
12546
+ const parsed = JSON.parse(readFileSync19(ALIAS_DOMAINS_PATH, "utf-8"));
13611
12547
  if (!Array.isArray(parsed)) {
13612
12548
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
13613
12549
  return null;
@@ -13622,7 +12558,7 @@ var aliasDomains = loadAliasDomains() ?? /* @__PURE__ */ new Set();
13622
12558
  if (aliasDomains.size > 0) {
13623
12559
  console.log(`[alias-domains] loaded ${aliasDomains.size} alias domain(s): ${[...aliasDomains].join(", ")}`);
13624
12560
  }
13625
- watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
12561
+ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
13626
12562
  const updated = loadAliasDomains();
13627
12563
  if (!updated) return;
13628
12564
  aliasDomains = updated;
@@ -13631,9 +12567,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
13631
12567
  function isPublicHost(host) {
13632
12568
  return host.startsWith("public.") || aliasDomains.has(host);
13633
12569
  }
13634
- var app39 = new Hono();
13635
- app39.use("*", clientIpMiddleware);
13636
- app39.use("*", async (c, next) => {
12570
+ var app35 = new Hono();
12571
+ app35.use("*", clientIpMiddleware);
12572
+ app35.use("*", async (c, next) => {
13637
12573
  await next();
13638
12574
  c.header("X-Content-Type-Options", "nosniff");
13639
12575
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -13643,7 +12579,7 @@ app39.use("*", async (c, next) => {
13643
12579
  );
13644
12580
  });
13645
12581
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
13646
- app39.use("*", async (c, next) => {
12582
+ app35.use("*", async (c, next) => {
13647
12583
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
13648
12584
  await next();
13649
12585
  return;
@@ -13676,7 +12612,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
13676
12612
  "/sites/"
13677
12613
  ];
13678
12614
  var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
13679
- app39.use("*", async (c, next) => {
12615
+ app35.use("*", async (c, next) => {
13680
12616
  const host = (c.req.header("host") ?? "").split(":")[0];
13681
12617
  if (!isPublicHost(host)) {
13682
12618
  await next();
@@ -13716,7 +12652,7 @@ function resolveRemoteAuthOpts() {
13716
12652
  return brandLoginOpts;
13717
12653
  }
13718
12654
  var MAX_LOGIN_BODY = 8 * 1024;
13719
- app39.post("/__remote-auth/login", async (c) => {
12655
+ app35.post("/__remote-auth/login", async (c) => {
13720
12656
  const client = clientFrom(c);
13721
12657
  const clientIp = client.ip || "unknown";
13722
12658
  if (!requestIsTlsTerminated(c)) {
@@ -13761,7 +12697,7 @@ app39.post("/__remote-auth/login", async (c) => {
13761
12697
  }
13762
12698
  });
13763
12699
  });
13764
- app39.get("/__remote-auth/logout", (c) => {
12700
+ app35.get("/__remote-auth/logout", (c) => {
13765
12701
  const client = clientFrom(c);
13766
12702
  const clientIp = client.ip || "unknown";
13767
12703
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -13774,7 +12710,7 @@ app39.get("/__remote-auth/logout", (c) => {
13774
12710
  }
13775
12711
  });
13776
12712
  });
13777
- app39.post("/__remote-auth/change-password", async (c) => {
12713
+ app35.post("/__remote-auth/change-password", async (c) => {
13778
12714
  const client = clientFrom(c);
13779
12715
  const clientIp = client.ip || "unknown";
13780
12716
  const rateLimited = checkRateLimit(client);
@@ -13825,13 +12761,13 @@ app39.post("/__remote-auth/change-password", async (c) => {
13825
12761
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
13826
12762
  }
13827
12763
  });
13828
- app39.get("/__remote-auth/setup", (c) => {
12764
+ app35.get("/__remote-auth/setup", (c) => {
13829
12765
  if (isRemoteAuthConfigured()) {
13830
12766
  return c.redirect("/");
13831
12767
  }
13832
12768
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
13833
12769
  });
13834
- app39.post("/__remote-auth/set-initial-password", async (c) => {
12770
+ app35.post("/__remote-auth/set-initial-password", async (c) => {
13835
12771
  if (isRemoteAuthConfigured()) {
13836
12772
  return c.redirect("/");
13837
12773
  }
@@ -13869,10 +12805,10 @@ app39.post("/__remote-auth/set-initial-password", async (c) => {
13869
12805
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
13870
12806
  }
13871
12807
  });
13872
- app39.get("/api/remote-auth/status", (c) => {
12808
+ app35.get("/api/remote-auth/status", (c) => {
13873
12809
  return c.json({ configured: isRemoteAuthConfigured() });
13874
12810
  });
13875
- app39.post("/api/remote-auth/set-password", async (c) => {
12811
+ app35.post("/api/remote-auth/set-password", async (c) => {
13876
12812
  let body;
13877
12813
  try {
13878
12814
  body = await c.req.json();
@@ -13903,9 +12839,9 @@ app39.post("/api/remote-auth/set-password", async (c) => {
13903
12839
  return c.json({ error: "Failed to save password" }, 500);
13904
12840
  }
13905
12841
  });
13906
- app39.route("/api/_client-error", client_error_default);
12842
+ app35.route("/api/_client-error", client_error_default);
13907
12843
  console.log("[client-error-route] mounted");
13908
- app39.use("*", async (c, next) => {
12844
+ app35.use("*", async (c, next) => {
13909
12845
  const host = (c.req.header("host") ?? "").split(":")[0];
13910
12846
  const path2 = c.req.path;
13911
12847
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -13931,13 +12867,6 @@ app39.use("*", async (c, next) => {
13931
12867
  return;
13932
12868
  }
13933
12869
  const disambig = `remoteAddress="${rawRemote ?? ""}" xff="${rawXff ?? ""}" resolvedKind=${decision.client.kind}`;
13934
- if (path2 === "/api/admin/browser-iframe/event") {
13935
- browserViewerLog("auth-rejected", {
13936
- ip: clientIp,
13937
- reason: decision.reason,
13938
- brand: BRAND.productName
13939
- });
13940
- }
13941
12870
  if (decision.reason === "remote-unconfigured") {
13942
12871
  console.error(`[remote-auth] not configured, redirecting to setup ip=${clientIp} path=${path2} ${disambig}`);
13943
12872
  return c.redirect("/__remote-auth/setup");
@@ -13945,11 +12874,11 @@ app39.use("*", async (c, next) => {
13945
12874
  console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
13946
12875
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
13947
12876
  });
13948
- app39.route("/api/health", health_default);
13949
- app39.route("/api/chat", chat_default);
13950
- app39.route("/api/whatsapp", whatsapp_default);
13951
- app39.route("/api/onboarding", onboarding_default);
13952
- app39.route("/api/admin", admin_default);
12877
+ app35.route("/api/health", health_default);
12878
+ app35.route("/api/chat", chat_default);
12879
+ app35.route("/api/whatsapp", whatsapp_default);
12880
+ app35.route("/api/onboarding", onboarding_default);
12881
+ app35.route("/api/admin", admin_default);
13953
12882
  var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
13954
12883
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
13955
12884
  var IMAGE_MIME = {
@@ -13961,7 +12890,7 @@ var IMAGE_MIME = {
13961
12890
  ".svg": "image/svg+xml",
13962
12891
  ".ico": "image/x-icon"
13963
12892
  };
13964
- app39.get("/agent-assets/:slug/:filename", (c) => {
12893
+ app35.get("/agent-assets/:slug/:filename", (c) => {
13965
12894
  const slug = c.req.param("slug");
13966
12895
  const filename = c.req.param("filename");
13967
12896
  if (!SAFE_SLUG_RE.test(slug)) {
@@ -13977,8 +12906,8 @@ app39.get("/agent-assets/:slug/:filename", (c) => {
13977
12906
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
13978
12907
  return c.text("Not found", 404);
13979
12908
  }
13980
- const filePath = resolve23(account.accountDir, "agents", slug, "assets", filename);
13981
- const expectedDir = resolve23(account.accountDir, "agents", slug, "assets");
12909
+ const filePath = resolve21(account.accountDir, "agents", slug, "assets", filename);
12910
+ const expectedDir = resolve21(account.accountDir, "agents", slug, "assets");
13982
12911
  if (!filePath.startsWith(expectedDir + "/")) {
13983
12912
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
13984
12913
  return c.text("Forbidden", 403);
@@ -13990,13 +12919,13 @@ app39.get("/agent-assets/:slug/:filename", (c) => {
13990
12919
  const ext = "." + filename.split(".").pop()?.toLowerCase();
13991
12920
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
13992
12921
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
13993
- const body = readFileSync21(filePath);
12922
+ const body = readFileSync19(filePath);
13994
12923
  return c.body(body, 200, {
13995
12924
  "Content-Type": contentType,
13996
12925
  "Cache-Control": "public, max-age=3600"
13997
12926
  });
13998
12927
  });
13999
- app39.get("/generated/:filename", (c) => {
12928
+ app35.get("/generated/:filename", (c) => {
14000
12929
  const filename = c.req.param("filename");
14001
12930
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
14002
12931
  console.error(`[generated] serve file=${filename} status=403`);
@@ -14007,8 +12936,8 @@ app39.get("/generated/:filename", (c) => {
14007
12936
  console.error(`[generated] serve file=${filename} status=404`);
14008
12937
  return c.text("Not found", 404);
14009
12938
  }
14010
- const filePath = resolve23(account.accountDir, "generated", filename);
14011
- const expectedDir = resolve23(account.accountDir, "generated");
12939
+ const filePath = resolve21(account.accountDir, "generated", filename);
12940
+ const expectedDir = resolve21(account.accountDir, "generated");
14012
12941
  if (!filePath.startsWith(expectedDir + "/")) {
14013
12942
  console.error(`[generated] serve file=${filename} status=403`);
14014
12943
  return c.text("Forbidden", 403);
@@ -14020,19 +12949,19 @@ app39.get("/generated/:filename", (c) => {
14020
12949
  const ext = "." + filename.split(".").pop()?.toLowerCase();
14021
12950
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
14022
12951
  console.log(`[generated] serve file=${filename} status=200`);
14023
- const body = readFileSync21(filePath);
12952
+ const body = readFileSync19(filePath);
14024
12953
  return c.body(body, 200, {
14025
12954
  "Content-Type": contentType,
14026
12955
  "Cache-Control": "public, max-age=86400"
14027
12956
  });
14028
12957
  });
14029
- app39.route("/sites", sites_default);
12958
+ app35.route("/sites", sites_default);
14030
12959
  var htmlCache = /* @__PURE__ */ new Map();
14031
12960
  var brandLogoPath = "/brand/maxy-monochrome.png";
14032
12961
  var brandIconPath = "/brand/maxy-monochrome.png";
14033
12962
  if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
14034
12963
  try {
14035
- const fullBrand = JSON.parse(readFileSync21(BRAND_JSON_PATH, "utf-8"));
12964
+ const fullBrand = JSON.parse(readFileSync19(BRAND_JSON_PATH, "utf-8"));
14036
12965
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
14037
12966
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
14038
12967
  } catch {
@@ -14051,7 +12980,7 @@ function readInstalledVersion() {
14051
12980
  if (!PLATFORM_ROOT7) return "unknown";
14052
12981
  const versionFile = join14(PLATFORM_ROOT7, "config", `.${BRAND.hostname}-version`);
14053
12982
  if (!existsSync23(versionFile)) return "unknown";
14054
- const content = readFileSync21(versionFile, "utf-8").trim();
12983
+ const content = readFileSync19(versionFile, "utf-8").trim();
14055
12984
  return content || "unknown";
14056
12985
  } catch {
14057
12986
  return "unknown";
@@ -14092,7 +13021,7 @@ var clientErrorReporterScript = `<script>
14092
13021
  function cachedHtml(file) {
14093
13022
  let html = htmlCache.get(file);
14094
13023
  if (!html) {
14095
- html = readFileSync21(resolve23(process.cwd(), "public", file), "utf-8");
13024
+ html = readFileSync19(resolve21(process.cwd(), "public", file), "utf-8");
14096
13025
  const productNameEsc = escapeHtml(BRAND.productName);
14097
13026
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
14098
13027
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -14108,26 +13037,26 @@ ${clientErrorReporterScript}
14108
13037
  }
14109
13038
  var brandedHtmlCache = /* @__PURE__ */ new Map();
14110
13039
  function loadBrandingCache(agentSlug) {
14111
- const configDir2 = join14(homedir5(), BRAND.configDir);
13040
+ const configDir2 = join14(homedir4(), BRAND.configDir);
14112
13041
  try {
14113
13042
  const accountJsonPath = join14(configDir2, "account.json");
14114
13043
  if (!existsSync23(accountJsonPath)) return null;
14115
- const account = JSON.parse(readFileSync21(accountJsonPath, "utf-8"));
13044
+ const account = JSON.parse(readFileSync19(accountJsonPath, "utf-8"));
14116
13045
  const accountId = account.accountId;
14117
13046
  if (!accountId) return null;
14118
13047
  const cachePath = join14(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
14119
13048
  if (!existsSync23(cachePath)) return null;
14120
- return JSON.parse(readFileSync21(cachePath, "utf-8"));
13049
+ return JSON.parse(readFileSync19(cachePath, "utf-8"));
14121
13050
  } catch {
14122
13051
  return null;
14123
13052
  }
14124
13053
  }
14125
13054
  function resolveDefaultSlug() {
14126
13055
  try {
14127
- const configDir2 = join14(homedir5(), BRAND.configDir);
13056
+ const configDir2 = join14(homedir4(), BRAND.configDir);
14128
13057
  const accountJsonPath = join14(configDir2, "account.json");
14129
13058
  if (!existsSync23(accountJsonPath)) return null;
14130
- const account = JSON.parse(readFileSync21(accountJsonPath, "utf-8"));
13059
+ const account = JSON.parse(readFileSync19(accountJsonPath, "utf-8"));
14131
13060
  return account.defaultAgent || null;
14132
13061
  } catch {
14133
13062
  return null;
@@ -14163,7 +13092,7 @@ function brandedPublicHtml(agentSlug) {
14163
13092
  function escapeHtml(s) {
14164
13093
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
14165
13094
  }
14166
- app39.get("/", (c) => {
13095
+ app35.get("/", (c) => {
14167
13096
  const host = (c.req.header("host") ?? "").split(":")[0];
14168
13097
  if (isPublicHost(host)) {
14169
13098
  const defaultSlug = resolveDefaultSlug();
@@ -14171,12 +13100,12 @@ app39.get("/", (c) => {
14171
13100
  }
14172
13101
  return c.html(cachedHtml("index.html"));
14173
13102
  });
14174
- app39.get("/public", (c) => {
13103
+ app35.get("/public", (c) => {
14175
13104
  const host = (c.req.header("host") ?? "").split(":")[0];
14176
13105
  if (isPublicHost(host)) return c.text("Not found", 404);
14177
13106
  return c.html(cachedHtml("public.html"));
14178
13107
  });
14179
- app39.get("/chat", (c) => {
13108
+ app35.get("/chat", (c) => {
14180
13109
  const host = (c.req.header("host") ?? "").split(":")[0];
14181
13110
  if (isPublicHost(host)) return c.text("Not found", 404);
14182
13111
  return c.html(cachedHtml("public.html"));
@@ -14195,12 +13124,12 @@ async function logViewerFetch(c, next) {
14195
13124
  duration_ms: Date.now() - start
14196
13125
  });
14197
13126
  }
14198
- app39.use("/vnc-viewer.html", logViewerFetch);
14199
- app39.use("/vnc-popout.html", logViewerFetch);
14200
- app39.get("/vnc-popout.html", (c) => {
13127
+ app35.use("/vnc-viewer.html", logViewerFetch);
13128
+ app35.use("/vnc-popout.html", logViewerFetch);
13129
+ app35.get("/vnc-popout.html", (c) => {
14201
13130
  let html = htmlCache.get("vnc-popout.html");
14202
13131
  if (!html) {
14203
- html = readFileSync21(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
13132
+ html = readFileSync19(resolve21(process.cwd(), "public", "vnc-popout.html"), "utf-8");
14204
13133
  const name = escapeHtml(BRAND.productName);
14205
13134
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
14206
13135
  html = html.replace("</head>", ` ${brandScript}
@@ -14210,7 +13139,7 @@ app39.get("/vnc-popout.html", (c) => {
14210
13139
  }
14211
13140
  return c.html(html);
14212
13141
  });
14213
- app39.post("/api/vnc/client-event", async (c) => {
13142
+ app35.post("/api/vnc/client-event", async (c) => {
14214
13143
  let body;
14215
13144
  try {
14216
13145
  body = await c.req.json();
@@ -14231,25 +13160,25 @@ app39.post("/api/vnc/client-event", async (c) => {
14231
13160
  });
14232
13161
  return c.json({ ok: true });
14233
13162
  });
14234
- app39.get("/g/:slug", (c) => {
13163
+ app35.get("/g/:slug", (c) => {
14235
13164
  return c.html(brandedPublicHtml());
14236
13165
  });
14237
- app39.get("/graph", (c) => {
13166
+ app35.get("/graph", (c) => {
14238
13167
  const host = (c.req.header("host") ?? "").split(":")[0];
14239
13168
  if (isPublicHost(host)) return c.text("Not found", 404);
14240
13169
  return c.html(cachedHtml("graph.html"));
14241
13170
  });
14242
- app39.get("/sessions", (c) => {
13171
+ app35.get("/sessions", (c) => {
14243
13172
  const host = (c.req.header("host") ?? "").split(":")[0];
14244
13173
  if (isPublicHost(host)) return c.text("Not found", 404);
14245
13174
  return c.html(cachedHtml("sessions.html"));
14246
13175
  });
14247
- app39.get("/data", (c) => {
13176
+ app35.get("/data", (c) => {
14248
13177
  const host = (c.req.header("host") ?? "").split(":")[0];
14249
13178
  if (isPublicHost(host)) return c.text("Not found", 404);
14250
13179
  return c.html(cachedHtml("data.html"));
14251
13180
  });
14252
- app39.get("/:slug", async (c, next) => {
13181
+ app35.get("/:slug", async (c, next) => {
14253
13182
  const slug = c.req.param("slug");
14254
13183
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
14255
13184
  const branding = loadBrandingCache(slug);
@@ -14259,15 +13188,15 @@ app39.get("/:slug", async (c, next) => {
14259
13188
  await next();
14260
13189
  });
14261
13190
  if (brandFaviconPath !== "/favicon.ico") {
14262
- app39.get("/favicon.ico", (c) => {
13191
+ app35.get("/favicon.ico", (c) => {
14263
13192
  c.header("Cache-Control", "public, max-age=300");
14264
13193
  return c.redirect(brandFaviconPath, 302);
14265
13194
  });
14266
13195
  }
14267
- app39.use("/*", serveStatic({ root: "./public" }));
13196
+ app35.use("/*", serveStatic({ root: "./public" }));
14268
13197
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
14269
13198
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
14270
- var httpServer = serve({ fetch: app39.fetch, port, hostname });
13199
+ var httpServer = serve({ fetch: app35.fetch, port, hostname });
14271
13200
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
14272
13201
  {
14273
13202
  const loopHist = monitorEventLoopDelay({ resolution: 50 });
@@ -14299,7 +13228,7 @@ for (const m of SUBAPP_MANIFEST) {
14299
13228
  }
14300
13229
  try {
14301
13230
  const registered = [];
14302
- for (const r of app39.routes ?? []) {
13231
+ for (const r of app35.routes ?? []) {
14303
13232
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
14304
13233
  if (AGENT_SLUG_PATTERN.test(r.path)) {
14305
13234
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -14322,7 +13251,7 @@ try {
14322
13251
  (async () => {
14323
13252
  try {
14324
13253
  if (!existsSync23(USERS_FILE)) return;
14325
- const usersRaw = readFileSync21(USERS_FILE, "utf-8").trim();
13254
+ const usersRaw = readFileSync19(USERS_FILE, "utf-8").trim();
14326
13255
  if (!usersRaw) return;
14327
13256
  const users = JSON.parse(usersRaw);
14328
13257
  const userId = users[0]?.userId;
@@ -14373,28 +13302,6 @@ reconcileEnabledPlugins(bootAccount?.accountDir, bootAccount?.config, bootAccoun
14373
13302
  for (const acct of listValidAccounts()) {
14374
13303
  cleanupLeakedPremiumSubs(acct.accountDir, acct.config, acct.accountId);
14375
13304
  }
14376
- (async () => {
14377
- if (!bootAccount) return;
14378
- try {
14379
- const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-M5ONAGUT.js");
14380
- const result = await recoverRunningCloudflareTasks(
14381
- bootAccount.accountId,
14382
- configDirForWhatsApp,
14383
- // no conversationId at boot. The reconciler operates on
14384
- // Tasks whose Conversation is already linked via RAISED_DURING; the
14385
- // tracker resolves the conversationId off that edge when present.
14386
- // Pass null and let the recovery path pick it up.
14387
- null
14388
- );
14389
- if (result.scanned > 0) {
14390
- console.error(
14391
- `[task] reconciler-startup kind=cloudflare-tunnel-login scanned=${result.scanned} resolved=${result.resolved.length}`
14392
- );
14393
- }
14394
- } catch (err) {
14395
- console.error(`[task] reconciler-startup failed: ${err instanceof Error ? err.message : String(err)}`);
14396
- }
14397
- })();
14398
13305
  var bootEnabled = Array.isArray(bootAccountConfig?.enabledPlugins) ? bootAccountConfig.enabledPlugins : [];
14399
13306
  var bootDelivered = [];
14400
13307
  var bootDistMissing = [];
@@ -14436,7 +13343,7 @@ if (bootAccountConfig?.whatsapp) {
14436
13343
  }
14437
13344
  init({
14438
13345
  configDir: configDirForWhatsApp,
14439
- platformRoot: resolve23(process.env.MAXY_PLATFORM_ROOT ?? join14(__dirname, "..")),
13346
+ platformRoot: resolve21(process.env.MAXY_PLATFORM_ROOT ?? join14(__dirname, "..")),
14440
13347
  accountConfig: bootAccountConfig,
14441
13348
  onMessage: async (msg) => {
14442
13349
  if (process.env.WHATSAPP_PTY_BRIDGE_ENABLED === "true" && msg.text && !msg.isOwnerMirror) {