@rubytech/create-maxy-code 0.1.388 → 0.1.391

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 (121) hide show
  1. package/dist/__tests__/claude-bin.test.js +51 -0
  2. package/dist/__tests__/claude-upgrade-privilege.test.js +17 -0
  3. package/dist/__tests__/joblogic-excluded.test.js +39 -0
  4. package/dist/__tests__/launchd-plist.test.js +36 -1
  5. package/dist/__tests__/macos-darwin-branch.test.js +18 -0
  6. package/dist/__tests__/neo4j-datadir.test.js +14 -0
  7. package/dist/claude-bin.js +78 -0
  8. package/dist/claude-upgrade-privilege.js +21 -0
  9. package/dist/index.js +262 -34
  10. package/dist/launchd-plist.js +25 -9
  11. package/dist/neo4j-datadir.js +15 -0
  12. package/package.json +1 -1
  13. package/payload/platform/config/brand.json +1 -1
  14. package/payload/platform/plugins/.claude-plugin/marketplace.json +0 -5
  15. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +24 -5
  16. package/payload/platform/plugins/docs/references/admin-session.md +4 -0
  17. package/payload/platform/plugins/docs/references/admin-ui.md +18 -1
  18. package/payload/platform/plugins/docs/references/joblogic.md +2 -0
  19. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +2 -0
  20. package/payload/platform/plugins/work/PLUGIN.md +3 -0
  21. package/payload/platform/plugins/work/mcp/dist/__tests__/session-metering.test.d.ts +2 -0
  22. package/payload/platform/plugins/work/mcp/dist/__tests__/session-metering.test.d.ts.map +1 -0
  23. package/payload/platform/plugins/work/mcp/dist/__tests__/session-metering.test.js +98 -0
  24. package/payload/platform/plugins/work/mcp/dist/__tests__/session-metering.test.js.map +1 -0
  25. package/payload/platform/plugins/work/mcp/dist/index.js +16 -0
  26. package/payload/platform/plugins/work/mcp/dist/index.js.map +1 -1
  27. package/payload/platform/plugins/work/mcp/dist/tools/session-metering.d.ts +53 -0
  28. package/payload/platform/plugins/work/mcp/dist/tools/session-metering.d.ts.map +1 -0
  29. package/payload/platform/plugins/work/mcp/dist/tools/session-metering.js +80 -0
  30. package/payload/platform/plugins/work/mcp/dist/tools/session-metering.js.map +1 -0
  31. package/payload/platform/plugins/work/mcp/package.json +2 -1
  32. package/payload/platform/scripts/smoke-boot-services.sh +35 -10
  33. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  34. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  35. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  36. package/payload/platform/services/claude-session-manager/dist/claude-host-creds.d.ts +11 -0
  37. package/payload/platform/services/claude-session-manager/dist/claude-host-creds.d.ts.map +1 -0
  38. package/payload/platform/services/claude-session-manager/dist/claude-host-creds.js +37 -0
  39. package/payload/platform/services/claude-session-manager/dist/claude-host-creds.js.map +1 -0
  40. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  41. package/payload/platform/services/claude-session-manager/dist/http-server.js +98 -8
  42. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  43. package/payload/platform/services/claude-session-manager/dist/pricing.d.ts +45 -0
  44. package/payload/platform/services/claude-session-manager/dist/pricing.d.ts.map +1 -0
  45. package/payload/platform/services/claude-session-manager/dist/pricing.js +57 -0
  46. package/payload/platform/services/claude-session-manager/dist/pricing.js.map +1 -0
  47. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  48. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +7 -0
  49. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  50. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +1 -1
  51. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  52. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +5 -1
  53. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  54. package/payload/platform/services/claude-session-manager/dist/session-metering.d.ts +38 -0
  55. package/payload/platform/services/claude-session-manager/dist/session-metering.d.ts.map +1 -0
  56. package/payload/platform/services/claude-session-manager/dist/session-metering.js +292 -0
  57. package/payload/platform/services/claude-session-manager/dist/session-metering.js.map +1 -0
  58. package/payload/platform/templates/specialists/agents/project-manager.md +1 -1
  59. package/payload/server/public/assets/{AdminLoginScreens-BejIjbmU.js → AdminLoginScreens-CL27ZV86.js} +1 -1
  60. package/payload/server/public/assets/AdminShell-CBcSh9Yd.js +1 -0
  61. package/payload/server/public/assets/{Checkbox-1F1tzqca.js → Checkbox-DRIcYN9r.js} +1 -1
  62. package/payload/server/public/assets/{Transcript-DkGa4CQH.js → Transcript-CRc72hkG.js} +1 -1
  63. package/payload/server/public/assets/{admin-DqQARkjy.js → admin-iKYYnv3w.js} +1 -1
  64. package/payload/server/public/assets/{browser-nDtEK6RC.js → browser--8gzAe-E.js} +1 -1
  65. package/payload/server/public/assets/calendar-7xAT81N_.js +1 -0
  66. package/payload/server/public/assets/chat-B8Z9W42Z.js +1 -0
  67. package/payload/server/public/assets/chevron-left-DDselYau.js +1 -0
  68. package/payload/server/public/assets/data-Ece320dZ.js +1 -0
  69. package/payload/server/public/assets/{graph-DFyicKd7.js → graph-B3haz2DN.js} +2 -2
  70. package/payload/server/public/assets/{graph-labels-D3BQdcpD.js → graph-labels-Ba_fyw6I.js} +1 -1
  71. package/payload/server/public/assets/{operator-BxrjWdT9.js → operator-BYL1IFz9.js} +1 -1
  72. package/payload/server/public/assets/page-Bj6lB07z.js +32 -0
  73. package/payload/server/public/assets/page-CLKVCquw.js +1 -0
  74. package/payload/server/public/assets/{public-DbdqfdYq.js → public-BKJUKC76.js} +1 -1
  75. package/payload/server/public/assets/{rotate-ccw-BkX8HODe.js → rotate-ccw-BypBbSI4.js} +1 -1
  76. package/payload/server/public/assets/useSubAccountSwitcher-4qilMyPX.css +1 -0
  77. package/payload/server/public/assets/useSubAccountSwitcher-CsRv6MEd.js +9 -0
  78. package/payload/server/public/browser.html +4 -4
  79. package/payload/server/public/calendar.html +5 -5
  80. package/payload/server/public/chat.html +8 -8
  81. package/payload/server/public/data.html +7 -7
  82. package/payload/server/public/graph.html +8 -8
  83. package/payload/server/public/index.html +10 -10
  84. package/payload/server/public/operator.html +10 -10
  85. package/payload/server/public/public.html +8 -8
  86. package/payload/server/server.js +327 -255
  87. package/payload/platform/plugins/joblogic/.claude-plugin/plugin.json +0 -21
  88. package/payload/platform/plugins/joblogic/PLUGIN.md +0 -182
  89. package/payload/platform/plugins/joblogic/lib/mcp-spawn-tee/index.js +0 -193
  90. package/payload/platform/plugins/joblogic/lib/mcp-spawn-tee/package.json +0 -3
  91. package/payload/platform/plugins/joblogic/mcp/dist/index.d.ts +0 -2
  92. package/payload/platform/plugins/joblogic/mcp/dist/index.d.ts.map +0 -1
  93. package/payload/platform/plugins/joblogic/mcp/dist/index.js +0 -229
  94. package/payload/platform/plugins/joblogic/mcp/dist/index.js.map +0 -1
  95. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.d.ts +0 -31
  96. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.d.ts.map +0 -1
  97. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.js +0 -78
  98. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.js.map +0 -1
  99. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.d.ts +0 -35
  100. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.d.ts.map +0 -1
  101. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.js +0 -106
  102. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.js.map +0 -1
  103. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.d.ts +0 -8
  104. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.d.ts.map +0 -1
  105. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.js +0 -41
  106. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.js.map +0 -1
  107. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.d.ts +0 -21
  108. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.d.ts.map +0 -1
  109. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.js +0 -47
  110. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.js.map +0 -1
  111. package/payload/platform/plugins/joblogic/mcp/package.json +0 -10
  112. package/payload/platform/plugins/joblogic/skills/joblogic/SKILL.md +0 -32
  113. package/payload/server/public/assets/AdminShell-D2-uBSB5.js +0 -1
  114. package/payload/server/public/assets/calendar-CO4Bwmho.js +0 -1
  115. package/payload/server/public/assets/chat-DeIge_bC.js +0 -1
  116. package/payload/server/public/assets/chevron-left-DhVdq0aN.js +0 -1
  117. package/payload/server/public/assets/data-B1GIdzHk.js +0 -1
  118. package/payload/server/public/assets/page-ByDLq_o1.js +0 -1
  119. package/payload/server/public/assets/page-D-Ep4bXd.js +0 -32
  120. package/payload/server/public/assets/useSubAccountSwitcher-DMbRhLPv.js +0 -9
  121. package/payload/server/public/assets/useSubAccountSwitcher-DS0iqSkP.css +0 -1
@@ -1623,8 +1623,9 @@ function startAuthHealthHeartbeat(intervalMs = 5 * 60 * 1e3) {
1623
1623
  try {
1624
1624
  const h = computeAuthHealth();
1625
1625
  const expiresIn = h.expiresAt != null ? Math.round((h.expiresAt - Date.now()) / 1e3) : null;
1626
+ const store2 = process.platform === "darwin" ? "host-creds-file" : "file";
1626
1627
  console.log(
1627
- `[auth-health] brand=${BRAND_NAME} status=${h.status} expiresIn=${expiresIn != null ? expiresIn + "s" : "n/a"}`
1628
+ `[auth-health] brand=${BRAND_NAME} store=${store2} status=${h.status} expiresIn=${expiresIn != null ? expiresIn + "s" : "n/a"}`
1628
1629
  );
1629
1630
  if (h.status === "dead") {
1630
1631
  console.log(`[auth-health] op=reauth-required status=dead`);
@@ -5740,8 +5741,8 @@ function webchatTurnTimeoutMs() {
5740
5741
  return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
5741
5742
  }
5742
5743
  function createChatRoutes(deps) {
5743
- const app56 = new Hono();
5744
- app56.post("/", async (c) => {
5744
+ const app57 = new Hono();
5745
+ app57.post("/", async (c) => {
5745
5746
  console.log(`[chat-route] entered route=public method=POST`);
5746
5747
  const contentType = c.req.header("content-type") ?? "";
5747
5748
  const account = resolveAccount();
@@ -6004,7 +6005,7 @@ ${result.result.text}` : result.result.text;
6004
6005
  }
6005
6006
  });
6006
6007
  });
6007
- return app56;
6008
+ return app57;
6008
6009
  }
6009
6010
 
6010
6011
  // app/lib/channel-pty-bridge/admin-session-id.ts
@@ -6025,8 +6026,8 @@ function isLoopbackAddr(addr) {
6025
6026
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
6026
6027
  }
6027
6028
  function createScheduleInjectRoutes(deps) {
6028
- const app56 = new Hono();
6029
- app56.post("/", async (c) => {
6029
+ const app57 = new Hono();
6030
+ app57.post("/", async (c) => {
6030
6031
  const env = c.env;
6031
6032
  const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
6032
6033
  if (!isLoopbackAddr(remoteAddr)) {
@@ -6065,6 +6066,10 @@ function createScheduleInjectRoutes(deps) {
6065
6066
  console.error(`${TAG16} op=received eventId=${eventId} channel=${channel} destination=${destination} account=${houseAccountId}`);
6066
6067
  if (channel === "whatsapp") {
6067
6068
  const effectiveAccount2 = deps.effectiveAccountFor(houseAccountId, account.accountDir, destination);
6069
+ if (effectiveAccount2 === null) {
6070
+ console.error(`${TAG16} op=schedule-account-manager-reject eventId=${eventId} destination=${destination} reason=unresolved-effective-account`);
6071
+ return c.json({ ok: false, error: "account-manager-unresolved" }, 403);
6072
+ }
6068
6073
  console.error(`${TAG16} op=effective-account eventId=${eventId} effectiveAccount=${effectiveAccount2}`);
6069
6074
  const sessionId2 = adminSessionIdFor(effectiveAccount2, destination);
6070
6075
  const reply2 = (text) => deps.sendWhatsAppText(houseAccountId, destination, text);
@@ -6120,7 +6125,7 @@ function createScheduleInjectRoutes(deps) {
6120
6125
  console.error(`${TAG16} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
6121
6126
  return c.json({ ok: true }, 200);
6122
6127
  });
6123
- return app56;
6128
+ return app57;
6124
6129
  }
6125
6130
 
6126
6131
  // app/lib/telegram/outbound/send-text.ts
@@ -6908,7 +6913,7 @@ async function sendWhatsAppDocument(input) {
6908
6913
  const accountResolved = realpathSync3(accountDir);
6909
6914
  if (!resolvedPath.startsWith(accountResolved + "/")) {
6910
6915
  const sanitised = filePath.replace(accountDir, "<account>/");
6911
- console.error(`${TAG19} document REJECTED path=${sanitised} reason=outside_account_directory`);
6916
+ console.error(`${TAG19} document REJECTED path=${sanitised} reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
6912
6917
  return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
6913
6918
  }
6914
6919
  } catch (err) {
@@ -9674,8 +9679,8 @@ async function reapplyLeversViaManager() {
9674
9679
  var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
9675
9680
  var sendSeq = 0;
9676
9681
  function createWebchatRoutes(deps) {
9677
- const app56 = new Hono();
9678
- app56.post("/send", requireAdminSession, async (c) => {
9682
+ const app57 = new Hono();
9683
+ app57.post("/send", requireAdminSession, async (c) => {
9679
9684
  let accountId;
9680
9685
  try {
9681
9686
  accountId = resolvePlatformAccountId();
@@ -9875,7 +9880,7 @@ ${note}` : note;
9875
9880
  if (turnTimer.unref) turnTimer.unref();
9876
9881
  return c.json({ ok: true });
9877
9882
  });
9878
- app56.post("/interrupt", requireAdminSession, async (c) => {
9883
+ app57.post("/interrupt", requireAdminSession, async (c) => {
9879
9884
  const cacheKey = c.get("cacheKey");
9880
9885
  const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
9881
9886
  const primaryUserId = resolvePrimaryAdminUserId();
@@ -9903,7 +9908,7 @@ ${note}` : note;
9903
9908
  }
9904
9909
  return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
9905
9910
  });
9906
- app56.post("/settings", requireAdminSession, async (c) => {
9911
+ app57.post("/settings", requireAdminSession, async (c) => {
9907
9912
  const body = await c.req.json().catch(() => null);
9908
9913
  const op = body?.op;
9909
9914
  const value = body?.value;
@@ -9943,7 +9948,7 @@ ${note}` : note;
9943
9948
  console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
9944
9949
  return c.json({ ok: true, settingsApplied });
9945
9950
  });
9946
- app56.get("/session", requireAdminSession, async (c) => {
9951
+ app57.get("/session", requireAdminSession, async (c) => {
9947
9952
  let accountId;
9948
9953
  try {
9949
9954
  accountId = resolvePlatformAccountId();
@@ -10021,7 +10026,7 @@ ${note}` : note;
10021
10026
  const indicators = await fetchComposerIndicators(sessionId);
10022
10027
  return c.json({ sessionId, projectDir, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
10023
10028
  });
10024
- app56.post("/permission-verdict", requireAdminSession, async (c) => {
10029
+ app57.post("/permission-verdict", requireAdminSession, async (c) => {
10025
10030
  const body = await c.req.json().catch(() => null);
10026
10031
  const sessionId = body?.sessionId;
10027
10032
  const requestId = body?.request_id;
@@ -10038,7 +10043,7 @@ ${note}` : note;
10038
10043
  const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
10039
10044
  return c.json({ ok });
10040
10045
  });
10041
- return app56;
10046
+ return app57;
10042
10047
  }
10043
10048
 
10044
10049
  // server/routes/webchat-greeting.ts
@@ -10443,6 +10448,21 @@ import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync2 } from "c
10443
10448
  import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync10, writeSync, existsSync as existsSync15, readFileSync as readFileSync24, unlinkSync as unlinkSync2 } from "fs";
10444
10449
  import { createHash as createHash3, randomUUID as randomUUID7 } from "crypto";
10445
10450
 
10451
+ // app/lib/claude-spawn-env.ts
10452
+ var HOST_AUTH_REFRESH_TIMEOUT_MS = "30000";
10453
+ function hostCredsEnv(platform, credsFile) {
10454
+ if (platform === "darwin" && credsFile) {
10455
+ return {
10456
+ CLAUDE_CODE_HOST_CREDS_FILE: credsFile,
10457
+ CLAUDE_CODE_HOST_AUTH_REFRESH_TIMEOUT_MS: HOST_AUTH_REFRESH_TIMEOUT_MS
10458
+ };
10459
+ }
10460
+ return {};
10461
+ }
10462
+ function claudeBin() {
10463
+ return process.env.CLAUDE_BIN ?? "claude";
10464
+ }
10465
+
10446
10466
  // ../lib/admins-write/src/index.ts
10447
10467
  import { existsSync as existsSync14, readFileSync as readFileSync23, writeFileSync as writeFileSync9, renameSync as renameSync5, mkdirSync as mkdirSync5, readdirSync as readdirSync13, statSync as statSync8, appendFileSync as appendFileSync2 } from "fs";
10448
10468
  import { dirname as dirname7, join as join22 } from "path";
@@ -10628,6 +10648,7 @@ function readUsersFile2() {
10628
10648
  if (!raw) return [];
10629
10649
  return JSON.parse(raw);
10630
10650
  }
10651
+ var darwinAuthChild = null;
10631
10652
  async function checkAuthStatus() {
10632
10653
  let status;
10633
10654
  try {
@@ -10673,7 +10694,11 @@ app9.post("/claude-auth", async (c) => {
10673
10694
  const start = Date.now();
10674
10695
  let logoutError = null;
10675
10696
  try {
10676
- execFileSync2("claude", ["auth", "logout"], { encoding: "utf-8", timeout: 8e3 });
10697
+ execFileSync2(claudeBin(), ["auth", "logout"], {
10698
+ env: { ...process.env, ...hostCredsEnv(process.platform, CLAUDE_CREDENTIALS_FILE) },
10699
+ encoding: "utf-8",
10700
+ timeout: 8e3
10701
+ });
10677
10702
  } catch (err) {
10678
10703
  logoutError = err instanceof Error ? err.message : String(err);
10679
10704
  }
@@ -10686,6 +10711,22 @@ app9.post("/claude-auth", async (c) => {
10686
10711
  const authenticated = await checkAuthStatus();
10687
10712
  return c.json({ completed: authenticated, authenticated });
10688
10713
  }
10714
+ if (body.action === "paste-code") {
10715
+ const code = typeof body.code === "string" ? body.code : "";
10716
+ const child = darwinAuthChild;
10717
+ if (!child || !child.stdin || child.stdin.destroyed) {
10718
+ console.log("[onboarding] op=claude-paste-code accepted=false reason=no-active-login");
10719
+ return c.json({ accepted: false, error: "No active login to paste into. Start sign-in first." }, 400);
10720
+ }
10721
+ try {
10722
+ child.stdin.write(code.trim() + "\n");
10723
+ } catch (err) {
10724
+ console.log(`[onboarding] op=claude-paste-code accepted=false reason=write-failed err=${err instanceof Error ? err.message : String(err)}`);
10725
+ return c.json({ accepted: false, error: "Sign-in already finished or closed. Try again." }, 409);
10726
+ }
10727
+ console.log(`[onboarding] op=claude-paste-code accepted=true bytes=${code.trim().length}`);
10728
+ return c.json({ accepted: true });
10729
+ }
10689
10730
  if (body.action === "launch-browser") {
10690
10731
  if (transport === "vnc") {
10691
10732
  const vncReady = await ensureVnc();
@@ -10700,13 +10741,20 @@ app9.post("/claude-auth", async (c) => {
10700
10741
  const onClaudeOutput = (chunk) => writeSync(claudeAuthLogFd, chunk);
10701
10742
  if (process.platform === "darwin") {
10702
10743
  vncLog("claude-auth", { action: "start", transport: "native", platform: "darwin" });
10703
- const claudeProc2 = spawn("claude", ["auth", "login"], {
10704
- stdio: ["ignore", "pipe", "pipe"]
10744
+ const claudeProc2 = spawn(claudeBin(), ["auth", "login"], {
10745
+ env: { ...process.env, ...hostCredsEnv(process.platform, CLAUDE_CREDENTIALS_FILE) },
10746
+ stdio: ["pipe", "pipe", "pipe"]
10705
10747
  });
10706
10748
  claudeProc2.unref();
10749
+ darwinAuthChild = claudeProc2;
10750
+ claudeProc2.stdin?.on("error", () => {
10751
+ });
10707
10752
  claudeProc2.stdout?.on("data", onClaudeOutput);
10708
10753
  claudeProc2.stderr?.on("data", onClaudeOutput);
10709
- claudeProc2.once("close", () => closeSync3(claudeAuthLogFd));
10754
+ claudeProc2.once("close", () => {
10755
+ closeSync3(claudeAuthLogFd);
10756
+ if (darwinAuthChild === claudeProc2) darwinAuthChild = null;
10757
+ });
10710
10758
  return c.json({ started: true, transport: "native" });
10711
10759
  }
10712
10760
  if (transport === "vnc") {
@@ -11493,15 +11541,16 @@ var logs_default = app13;
11493
11541
  import { execFileSync as execFileSync3 } from "child_process";
11494
11542
  var app14 = new Hono();
11495
11543
  app14.get("/", (c) => {
11544
+ const claudeEnv = { ...process.env, ...hostCredsEnv(process.platform, CLAUDE_CREDENTIALS_FILE) };
11496
11545
  let version = "unknown";
11497
11546
  try {
11498
- const raw = execFileSync3("claude", ["--version"], { encoding: "utf-8", timeout: 5e3 });
11547
+ const raw = execFileSync3(claudeBin(), ["--version"], { env: claudeEnv, encoding: "utf-8", timeout: 5e3 });
11499
11548
  version = raw.trim().replace(" (Claude Code)", "");
11500
11549
  } catch {
11501
11550
  }
11502
11551
  let account = {};
11503
11552
  try {
11504
- const raw = execFileSync3("claude", ["auth", "status"], { encoding: "utf-8", timeout: 5e3 });
11553
+ const raw = execFileSync3(claudeBin(), ["auth", "status"], { env: claudeEnv, encoding: "utf-8", timeout: 5e3 });
11505
11554
  account = JSON.parse(raw);
11506
11555
  } catch {
11507
11556
  }
@@ -17147,6 +17196,36 @@ app32.post("/", requireAdminSession, async (c) => {
17147
17196
  });
17148
17197
  var session_rename_default = app32;
17149
17198
 
17199
+ // server/routes/admin/session-usage.ts
17200
+ var app33 = new Hono();
17201
+ app33.get("/", requireAdminSession, async (c) => {
17202
+ const sessionId = c.req.query("sessionId") ?? "";
17203
+ if (!SESSION_ID_RE2.test(sessionId)) {
17204
+ return c.json({ error: "sessionId must be a v4 UUID" }, 400);
17205
+ }
17206
+ let res;
17207
+ try {
17208
+ res = await fetch(`${managerBase("session-usage:wrapper")}/${sessionId}/metering`);
17209
+ } catch (err) {
17210
+ console.error(`[session-usage] sessionId=${sessionId.slice(0, 8)} manager-unreachable err=${err instanceof Error ? err.message : String(err)}`);
17211
+ return c.json({ error: "manager-unreachable" }, 502);
17212
+ }
17213
+ if (res.status === 200) {
17214
+ const summary = await res.json().catch(() => null);
17215
+ if (!summary) {
17216
+ console.error(`[session-usage] sessionId=${sessionId.slice(0, 8)} manager-bad-json`);
17217
+ return c.json({ error: "manager-bad-json" }, 502);
17218
+ }
17219
+ return c.json(summary);
17220
+ }
17221
+ if (res.status === 404) {
17222
+ return c.json({ error: "session-not-found" }, 404);
17223
+ }
17224
+ console.error(`[session-usage] sessionId=${sessionId.slice(0, 8)} manager-status=${res.status}`);
17225
+ return c.json({ error: `manager-status-${res.status}` }, 502);
17226
+ });
17227
+ var session_usage_default = app33;
17228
+
17150
17229
  // server/routes/admin/session-rc-spawn.ts
17151
17230
  import { randomUUID as randomUUID10 } from "crypto";
17152
17231
  var ACCOUNT_UUID_RE2 = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
@@ -17192,8 +17271,8 @@ function shapeWebchatResponse(sessionId, manager) {
17192
17271
  const landed = redirected ? manager.sessionId : sessionId;
17193
17272
  return { sessionId: landed, outcome, target: `/chat?session=${landed}` };
17194
17273
  }
17195
- var app33 = new Hono();
17196
- app33.post("/", requireAdminSession, async (c) => {
17274
+ var app34 = new Hono();
17275
+ app34.post("/", requireAdminSession, async (c) => {
17197
17276
  let body;
17198
17277
  try {
17199
17278
  body = await c.req.json();
@@ -17276,7 +17355,7 @@ app33.post("/", requireAdminSession, async (c) => {
17276
17355
  }
17277
17356
  return c.json(parsed ?? {});
17278
17357
  });
17279
- var session_rc_spawn_default = app33;
17358
+ var session_rc_spawn_default = app34;
17280
17359
 
17281
17360
  // server/routes/admin/session-reseat.ts
17282
17361
  import { randomUUID as randomUUID11 } from "crypto";
@@ -17299,9 +17378,9 @@ function resolveReseatPlan(body, mintId = randomUUID11, adminUserId, authenticat
17299
17378
  if (authenticatedName) payload.authenticatedName = authenticatedName;
17300
17379
  return { sessionId, payload };
17301
17380
  }
17302
- var app34 = new Hono();
17381
+ var app35 = new Hono();
17303
17382
  var reseatsInFlight = /* @__PURE__ */ new Set();
17304
- app34.post("/", requireAdminSession, async (c) => {
17383
+ app35.post("/", requireAdminSession, async (c) => {
17305
17384
  let body;
17306
17385
  try {
17307
17386
  body = await c.req.json();
@@ -17389,7 +17468,7 @@ app34.post("/", requireAdminSession, async (c) => {
17389
17468
  reseatsInFlight.delete(fromSessionId);
17390
17469
  }
17391
17470
  });
17392
- var session_reseat_default = app34;
17471
+ var session_reseat_default = app35;
17393
17472
 
17394
17473
  // server/routes/admin/system-stats.ts
17395
17474
  import { readFile as readFile5 } from "fs/promises";
@@ -17486,8 +17565,8 @@ async function sample() {
17486
17565
  if (process.platform === "linux") return sampleLinux();
17487
17566
  return sampleOsFallback();
17488
17567
  }
17489
- var app35 = new Hono();
17490
- app35.get("/", async (c) => {
17568
+ var app36 = new Hono();
17569
+ app36.get("/", async (c) => {
17491
17570
  const started = Date.now();
17492
17571
  if (!inflight) {
17493
17572
  inflight = sample().finally(() => {
@@ -17510,7 +17589,7 @@ app35.get("/", async (c) => {
17510
17589
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
17511
17590
  }
17512
17591
  });
17513
- var system_stats_default = app35;
17592
+ var system_stats_default = app36;
17514
17593
 
17515
17594
  // server/routes/admin/health.ts
17516
17595
  import { existsSync as existsSync26, readFileSync as readFileSync29 } from "fs";
@@ -17555,8 +17634,8 @@ async function probeConversationDb() {
17555
17634
  });
17556
17635
  }
17557
17636
  }
17558
- var app36 = new Hono();
17559
- app36.get("/", async (c) => {
17637
+ var app37 = new Hono();
17638
+ app37.get("/", async (c) => {
17560
17639
  const version = readVersion();
17561
17640
  const probe = await probeConversationDb();
17562
17641
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -17578,7 +17657,7 @@ app36.get("/", async (c) => {
17578
17657
  uptimeMs
17579
17658
  });
17580
17659
  });
17581
- var health_default2 = app36;
17660
+ var health_default2 = app37;
17582
17661
 
17583
17662
  // server/routes/admin/linkedin-ingest.ts
17584
17663
  import { randomUUID as randomUUID12 } from "crypto";
@@ -17804,8 +17883,8 @@ function buildInitialMessage(env) {
17804
17883
  }
17805
17884
  return header;
17806
17885
  }
17807
- var app37 = new Hono();
17808
- app37.post("/", requireAdminSession, async (c) => {
17886
+ var app38 = new Hono();
17887
+ app38.post("/", requireAdminSession, async (c) => {
17809
17888
  let body;
17810
17889
  try {
17811
17890
  body = await c.req.json();
@@ -17850,7 +17929,7 @@ app37.post("/", requireAdminSession, async (c) => {
17850
17929
  );
17851
17930
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
17852
17931
  });
17853
- var linkedin_ingest_default = app37;
17932
+ var linkedin_ingest_default = app38;
17854
17933
 
17855
17934
  // server/routes/admin/post-turn-context.ts
17856
17935
  import neo4j3 from "neo4j-driver";
@@ -17892,8 +17971,8 @@ function pruneProperties(raw) {
17892
17971
  }
17893
17972
  return out;
17894
17973
  }
17895
- var app38 = new Hono();
17896
- app38.get("/", async (c) => {
17974
+ var app39 = new Hono();
17975
+ app39.get("/", async (c) => {
17897
17976
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
17898
17977
  if (!isLoopbackAddr3(remoteAddr)) {
17899
17978
  console.error(`${TAG28} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -17953,7 +18032,7 @@ app38.get("/", async (c) => {
17953
18032
  await session.close();
17954
18033
  }
17955
18034
  });
17956
- var post_turn_context_default = app38;
18035
+ var post_turn_context_default = app39;
17957
18036
 
17958
18037
  // app/lib/slice-writes.ts
17959
18038
  import neo4j4 from "neo4j-driver";
@@ -18063,8 +18142,8 @@ var TAG29 = "[public-session-context]";
18063
18142
  function isLoopbackAddr4(addr) {
18064
18143
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
18065
18144
  }
18066
- var app39 = new Hono();
18067
- app39.get("/", async (c) => {
18145
+ var app40 = new Hono();
18146
+ app40.get("/", async (c) => {
18068
18147
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
18069
18148
  if (!isLoopbackAddr4(remoteAddr)) {
18070
18149
  console.error(`${TAG29} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -18104,7 +18183,7 @@ app39.get("/", async (c) => {
18104
18183
  await session.close();
18105
18184
  }
18106
18185
  });
18107
- var public_session_context_default = app39;
18186
+ var public_session_context_default = app40;
18108
18187
 
18109
18188
  // app/lib/webchat/gateway/instance.ts
18110
18189
  var instance2 = null;
@@ -18120,8 +18199,8 @@ var TAG30 = "[public-session-exit-route]";
18120
18199
  function isLoopbackAddr5(addr) {
18121
18200
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
18122
18201
  }
18123
- var app40 = new Hono();
18124
- app40.post("/", async (c) => {
18202
+ var app41 = new Hono();
18203
+ app41.post("/", async (c) => {
18125
18204
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
18126
18205
  if (!isLoopbackAddr5(remoteAddr)) {
18127
18206
  console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -18153,15 +18232,15 @@ app40.post("/", async (c) => {
18153
18232
  gateway.handlePublicSessionExit(sessionId);
18154
18233
  return c.json({ ok: true });
18155
18234
  });
18156
- var public_session_exit_default = app40;
18235
+ var public_session_exit_default = app41;
18157
18236
 
18158
18237
  // server/routes/admin/access-session-evict.ts
18159
18238
  var TAG31 = "[access-session-evict]";
18160
18239
  function isLoopbackAddr6(addr) {
18161
18240
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
18162
18241
  }
18163
- var app41 = new Hono();
18164
- app41.post("/", async (c) => {
18242
+ var app42 = new Hono();
18243
+ app42.post("/", async (c) => {
18165
18244
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
18166
18245
  if (!isLoopbackAddr6(remoteAddr)) {
18167
18246
  console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -18189,7 +18268,7 @@ app41.post("/", async (c) => {
18189
18268
  console.log(`${TAG31} grantId=${grantId} dropped=${dropped}`);
18190
18269
  return c.json({ ok: true, dropped });
18191
18270
  });
18192
- var access_session_evict_default = app41;
18271
+ var access_session_evict_default = app42;
18193
18272
 
18194
18273
  // server/routes/admin/enrol-person.ts
18195
18274
  var TAG32 = "[enrol]";
@@ -18197,8 +18276,8 @@ function isLoopbackAddr7(addr) {
18197
18276
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
18198
18277
  }
18199
18278
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
18200
- var app42 = new Hono();
18201
- app42.post("/", async (c) => {
18279
+ var app43 = new Hono();
18280
+ app43.post("/", async (c) => {
18202
18281
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
18203
18282
  if (!isLoopbackAddr7(remoteAddr)) {
18204
18283
  console.error(`${TAG32} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -18261,11 +18340,11 @@ app42.post("/", async (c) => {
18261
18340
  );
18262
18341
  return c.json({ personId, grant }, 200);
18263
18342
  });
18264
- var enrol_person_default = app42;
18343
+ var enrol_person_default = app43;
18265
18344
 
18266
18345
  // server/routes/admin/browser.ts
18267
- var app43 = new Hono();
18268
- app43.post("/launch", requireAdminSession, async (c) => {
18346
+ var app44 = new Hono();
18347
+ app44.post("/launch", requireAdminSession, async (c) => {
18269
18348
  try {
18270
18349
  const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
18271
18350
  console.error(`[admin/browser/launch] op=request transport=${transport}`);
@@ -18293,7 +18372,7 @@ app43.post("/launch", requireAdminSession, async (c) => {
18293
18372
  );
18294
18373
  }
18295
18374
  });
18296
- var browser_default = app43;
18375
+ var browser_default = app44;
18297
18376
 
18298
18377
  // server/routes/admin/calendar.ts
18299
18378
  import { existsSync as existsSync27 } from "fs";
@@ -18439,7 +18518,7 @@ function readAvailabilityConfig(accountDir) {
18439
18518
  }
18440
18519
 
18441
18520
  // server/routes/admin/calendar.ts
18442
- var app44 = new Hono();
18521
+ var app45 = new Hono();
18443
18522
  function normalizeAttendees(raw) {
18444
18523
  if (!Array.isArray(raw)) return [];
18445
18524
  return raw.map((a) => {
@@ -18470,7 +18549,7 @@ function mapMeeting(r) {
18470
18549
  privateNote: r.get("privateNote")
18471
18550
  };
18472
18551
  }
18473
- app44.get("/meetings", requireAdminSession, async (c) => {
18552
+ app45.get("/meetings", requireAdminSession, async (c) => {
18474
18553
  const cacheKey = c.var.cacheKey;
18475
18554
  const accountId = getAccountIdForSession(cacheKey);
18476
18555
  if (!accountId) {
@@ -18533,7 +18612,7 @@ function icsFilename(title) {
18533
18612
  const slug = (title ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
18534
18613
  return `${slug || "meeting"}.ics`;
18535
18614
  }
18536
- app44.get("/meetings/:id/ics", requireAdminSession, async (c) => {
18615
+ app45.get("/meetings/:id/ics", requireAdminSession, async (c) => {
18537
18616
  const cacheKey = c.var.cacheKey;
18538
18617
  const accountId = getAccountIdForSession(cacheKey);
18539
18618
  if (!accountId) {
@@ -18591,7 +18670,7 @@ app44.get("/meetings/:id/ics", requireAdminSession, async (c) => {
18591
18670
  await session.close();
18592
18671
  }
18593
18672
  });
18594
- app44.patch("/meetings/:id", requireAdminSession, async (c) => {
18673
+ app45.patch("/meetings/:id", requireAdminSession, async (c) => {
18595
18674
  const cacheKey = c.var.cacheKey;
18596
18675
  const accountId = getAccountIdForSession(cacheKey);
18597
18676
  if (!accountId) {
@@ -18635,7 +18714,7 @@ app44.patch("/meetings/:id", requireAdminSession, async (c) => {
18635
18714
  await session.close();
18636
18715
  }
18637
18716
  });
18638
- app44.post("/meetings/:id/attendees", requireAdminSession, async (c) => {
18717
+ app45.post("/meetings/:id/attendees", requireAdminSession, async (c) => {
18639
18718
  const cacheKey = c.var.cacheKey;
18640
18719
  const accountId = getAccountIdForSession(cacheKey);
18641
18720
  if (!accountId) {
@@ -18685,7 +18764,7 @@ app44.post("/meetings/:id/attendees", requireAdminSession, async (c) => {
18685
18764
  await session.close();
18686
18765
  }
18687
18766
  });
18688
- app44.delete("/meetings/:id/attendees", requireAdminSession, async (c) => {
18767
+ app45.delete("/meetings/:id/attendees", requireAdminSession, async (c) => {
18689
18768
  const cacheKey = c.var.cacheKey;
18690
18769
  const accountId = getAccountIdForSession(cacheKey);
18691
18770
  if (!accountId) {
@@ -18731,7 +18810,7 @@ app44.delete("/meetings/:id/attendees", requireAdminSession, async (c) => {
18731
18810
  await session.close();
18732
18811
  }
18733
18812
  });
18734
- app44.delete("/meetings/:id", requireAdminSession, async (c) => {
18813
+ app45.delete("/meetings/:id", requireAdminSession, async (c) => {
18735
18814
  const cacheKey = c.var.cacheKey;
18736
18815
  const accountId = getAccountIdForSession(cacheKey);
18737
18816
  if (!accountId) {
@@ -18761,7 +18840,7 @@ app44.delete("/meetings/:id", requireAdminSession, async (c) => {
18761
18840
  await session.close();
18762
18841
  }
18763
18842
  });
18764
- app44.get("/booking-link", requireAdminSession, (c) => {
18843
+ app45.get("/booking-link", requireAdminSession, (c) => {
18765
18844
  try {
18766
18845
  const account = resolveAccount();
18767
18846
  if (!account) {
@@ -18784,53 +18863,54 @@ app44.get("/booking-link", requireAdminSession, (c) => {
18784
18863
  return c.json({ bookingDomain: null });
18785
18864
  }
18786
18865
  });
18787
- var calendar_default = app44;
18866
+ var calendar_default = app45;
18788
18867
 
18789
18868
  // server/routes/admin/index.ts
18790
- var app45 = new Hono();
18791
- app45.route("/session", session_default);
18792
- app45.route("/accounts", accounts_default);
18793
- app45.route("/logs", logs_default);
18794
- app45.route("/claude-info", claude_info_default);
18795
- app45.route("/attachment", attachment_default);
18796
- app45.route("/agents", agents_default);
18797
- app45.route("/sessions", sessions_default);
18798
- app45.route("/claude-sessions", claude_sessions_default);
18799
- app45.route("/log-ingest", log_ingest_default);
18800
- app45.route("/events", events_default);
18801
- app45.route("/files", files_default);
18802
- app45.route("/graph-search", graph_search_default);
18803
- app45.route("/graph-subgraph", graph_subgraph_default);
18804
- app45.route("/graph-delete", graph_delete_default);
18805
- app45.route("/graph-restore", graph_restore_default);
18806
- app45.route("/graph-labels-in-graph", graph_labels_in_graph_default);
18807
- app45.route("/graph-default-view", graph_default_view_default);
18808
- app45.route("/sidebar-artefacts", sidebar_artefacts_default);
18809
- app45.route("/sidebar-sessions", sidebar_sessions_default);
18810
- app45.route("/session-delete", session_delete_default);
18811
- app45.route("/session-stop", session_stop_default);
18812
- app45.route("/session-archive", session_archive_default);
18813
- app45.route("/session-rename", session_rename_default);
18814
- app45.route("/browser", browser_default);
18815
- app45.route("/session-rc-spawn", session_rc_spawn_default);
18816
- app45.route("/session-reseat", session_reseat_default);
18817
- app45.route("/system-stats", system_stats_default);
18818
- app45.route("/health-brand", health_default2);
18819
- app45.route("/linkedin-ingest", linkedin_ingest_default);
18820
- app45.route("/post-turn-context", post_turn_context_default);
18821
- app45.route("/public-session-context", public_session_context_default);
18822
- app45.route("/public-session-exit", public_session_exit_default);
18823
- app45.route("/access-session-evict", access_session_evict_default);
18824
- app45.route("/enrol-person", enrol_person_default);
18825
- app45.route("/calendar", calendar_default);
18826
- var admin_default = app45;
18869
+ var app46 = new Hono();
18870
+ app46.route("/session", session_default);
18871
+ app46.route("/accounts", accounts_default);
18872
+ app46.route("/logs", logs_default);
18873
+ app46.route("/claude-info", claude_info_default);
18874
+ app46.route("/attachment", attachment_default);
18875
+ app46.route("/agents", agents_default);
18876
+ app46.route("/sessions", sessions_default);
18877
+ app46.route("/claude-sessions", claude_sessions_default);
18878
+ app46.route("/log-ingest", log_ingest_default);
18879
+ app46.route("/events", events_default);
18880
+ app46.route("/files", files_default);
18881
+ app46.route("/graph-search", graph_search_default);
18882
+ app46.route("/graph-subgraph", graph_subgraph_default);
18883
+ app46.route("/graph-delete", graph_delete_default);
18884
+ app46.route("/graph-restore", graph_restore_default);
18885
+ app46.route("/graph-labels-in-graph", graph_labels_in_graph_default);
18886
+ app46.route("/graph-default-view", graph_default_view_default);
18887
+ app46.route("/sidebar-artefacts", sidebar_artefacts_default);
18888
+ app46.route("/sidebar-sessions", sidebar_sessions_default);
18889
+ app46.route("/session-delete", session_delete_default);
18890
+ app46.route("/session-stop", session_stop_default);
18891
+ app46.route("/session-archive", session_archive_default);
18892
+ app46.route("/session-rename", session_rename_default);
18893
+ app46.route("/session-usage", session_usage_default);
18894
+ app46.route("/browser", browser_default);
18895
+ app46.route("/session-rc-spawn", session_rc_spawn_default);
18896
+ app46.route("/session-reseat", session_reseat_default);
18897
+ app46.route("/system-stats", system_stats_default);
18898
+ app46.route("/health-brand", health_default2);
18899
+ app46.route("/linkedin-ingest", linkedin_ingest_default);
18900
+ app46.route("/post-turn-context", post_turn_context_default);
18901
+ app46.route("/public-session-context", public_session_context_default);
18902
+ app46.route("/public-session-exit", public_session_exit_default);
18903
+ app46.route("/access-session-evict", access_session_evict_default);
18904
+ app46.route("/enrol-person", enrol_person_default);
18905
+ app46.route("/calendar", calendar_default);
18906
+ var admin_default = app46;
18827
18907
 
18828
18908
  // server/routes/access/verify-token.ts
18829
18909
  var TAG33 = "[access-verify]";
18830
18910
  var MINT_TAG = "[access-session-mint]";
18831
18911
  var COOKIE_NAME = "__access_session";
18832
- var app46 = new Hono();
18833
- app46.post("/", async (c) => {
18912
+ var app47 = new Hono();
18913
+ app47.post("/", async (c) => {
18834
18914
  const ip = c.var.clientIp || "unknown";
18835
18915
  let body;
18836
18916
  try {
@@ -18912,7 +18992,7 @@ app46.post("/", async (c) => {
18912
18992
  displayName: grant.displayName
18913
18993
  });
18914
18994
  });
18915
- var verify_token_default = app46;
18995
+ var verify_token_default = app47;
18916
18996
 
18917
18997
  // app/lib/access-email.ts
18918
18998
  import { spawn as spawn2 } from "child_process";
@@ -18975,9 +19055,9 @@ async function sendMagicLinkEmail(payload) {
18975
19055
 
18976
19056
  // server/routes/access/request-magic-link.ts
18977
19057
  var TAG34 = "[access-request-link]";
18978
- var app47 = new Hono();
19058
+ var app48 = new Hono();
18979
19059
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
18980
- app47.post("/", async (c) => {
19060
+ app48.post("/", async (c) => {
18981
19061
  let body;
18982
19062
  try {
18983
19063
  body = await c.req.json();
@@ -19051,13 +19131,13 @@ app47.post("/", async (c) => {
19051
19131
  );
19052
19132
  return c.json({ message: VISITOR_MESSAGE }, 200);
19053
19133
  });
19054
- var request_magic_link_default = app47;
19134
+ var request_magic_link_default = app48;
19055
19135
 
19056
19136
  // server/routes/access/index.ts
19057
- var app48 = new Hono();
19058
- app48.route("/verify-token", verify_token_default);
19059
- app48.route("/request-magic-link", request_magic_link_default);
19060
- var access_default = app48;
19137
+ var app49 = new Hono();
19138
+ app49.route("/verify-token", verify_token_default);
19139
+ app49.route("/request-magic-link", request_magic_link_default);
19140
+ var access_default = app49;
19061
19141
 
19062
19142
  // server/routes/sites.ts
19063
19143
  import { existsSync as existsSync28, readFileSync as readFileSync31, realpathSync as realpathSync6, statSync as statSync12 } from "fs";
@@ -19092,8 +19172,8 @@ function getExt(p) {
19092
19172
  if (idx < p.lastIndexOf("/")) return "";
19093
19173
  return p.slice(idx).toLowerCase();
19094
19174
  }
19095
- var app49 = new Hono();
19096
- app49.get("/:rel{.*}", (c) => {
19175
+ var app50 = new Hono();
19176
+ app50.get("/:rel{.*}", (c) => {
19097
19177
  const reqPath = c.req.path;
19098
19178
  const rawRel = c.req.param("rel") ?? "";
19099
19179
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -19196,7 +19276,7 @@ app49.get("/:rel{.*}", (c) => {
19196
19276
  "X-Content-Type-Options": "nosniff"
19197
19277
  });
19198
19278
  });
19199
- var sites_default = app49;
19279
+ var sites_default = app50;
19200
19280
 
19201
19281
  // app/lib/visitor-token.ts
19202
19282
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
@@ -19296,7 +19376,7 @@ function readBrandConfig() {
19296
19376
  }
19297
19377
 
19298
19378
  // server/routes/visitor-consent.ts
19299
- var app50 = new Hono();
19379
+ var app51 = new Hono();
19300
19380
  var CONSENT_COOKIE_NAME = "mxy_consent";
19301
19381
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
19302
19382
  var DEFAULT_CONSENT_COPY = {
@@ -19341,17 +19421,17 @@ function siteSlugFromReferer(referer) {
19341
19421
  return "";
19342
19422
  }
19343
19423
  }
19344
- app50.options("/consent", (c) => {
19424
+ app51.options("/consent", (c) => {
19345
19425
  const origin = getOrigin(c);
19346
19426
  setCorsHeaders(c, origin);
19347
19427
  return c.body(null, 204);
19348
19428
  });
19349
- app50.options("/brand-config", (c) => {
19429
+ app51.options("/brand-config", (c) => {
19350
19430
  const origin = getOrigin(c);
19351
19431
  setCorsHeaders(c, origin);
19352
19432
  return c.body(null, 204);
19353
19433
  });
19354
- app50.post("/consent", async (c) => {
19434
+ app51.post("/consent", async (c) => {
19355
19435
  const origin = getOrigin(c);
19356
19436
  setCorsHeaders(c, origin);
19357
19437
  let raw;
@@ -19391,7 +19471,7 @@ app50.post("/consent", async (c) => {
19391
19471
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
19392
19472
  return c.body(null, 204);
19393
19473
  });
19394
- app50.get("/brand-config", (c) => {
19474
+ app51.get("/brand-config", (c) => {
19395
19475
  const origin = getOrigin(c);
19396
19476
  setCorsHeaders(c, origin);
19397
19477
  const brand = readBrandConfig();
@@ -19401,7 +19481,7 @@ app50.get("/brand-config", (c) => {
19401
19481
  c.header("Cache-Control", "public, max-age=300");
19402
19482
  return c.json({ consent: { copy, palette } });
19403
19483
  });
19404
- var visitor_consent_default = app50;
19484
+ var visitor_consent_default = app51;
19405
19485
 
19406
19486
  // server/routes/listings.ts
19407
19487
  function getCookie(headerValue, name) {
@@ -19428,8 +19508,8 @@ function appendConsentParams(pageUrl, token) {
19428
19508
  }
19429
19509
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
19430
19510
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
19431
- var app51 = new Hono();
19432
- app51.get("/:slug/click", async (c) => {
19511
+ var app52 = new Hono();
19512
+ app52.get("/:slug/click", async (c) => {
19433
19513
  const slug = c.req.param("slug") ?? "";
19434
19514
  const rawSession = c.req.query("session") ?? "";
19435
19515
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -19493,10 +19573,10 @@ app51.get("/:slug/click", async (c) => {
19493
19573
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
19494
19574
  return c.redirect(redirectUrl, 302);
19495
19575
  });
19496
- var listings_default = app51;
19576
+ var listings_default = app52;
19497
19577
 
19498
19578
  // server/routes/visitor-event.ts
19499
- var app52 = new Hono();
19579
+ var app53 = new Hono();
19500
19580
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
19501
19581
  var buckets = /* @__PURE__ */ new Map();
19502
19582
  var RATE_LIMIT = 60;
@@ -19563,12 +19643,12 @@ function originAllowed(origin, allowlist) {
19563
19643
  return false;
19564
19644
  }
19565
19645
  }
19566
- app52.options("/event", (c) => {
19646
+ app53.options("/event", (c) => {
19567
19647
  const origin = getOrigin2(c);
19568
19648
  setCorsHeaders2(c, origin);
19569
19649
  return c.body(null, 204);
19570
19650
  });
19571
- app52.post("/event", async (c) => {
19651
+ app53.post("/event", async (c) => {
19572
19652
  const origin = getOrigin2(c);
19573
19653
  setCorsHeaders2(c, origin);
19574
19654
  const ua = c.req.header("user-agent") ?? "";
@@ -19773,7 +19853,7 @@ async function writeEvent(opts) {
19773
19853
  );
19774
19854
  }
19775
19855
  }
19776
- var visitor_event_default = app52;
19856
+ var visitor_event_default = app53;
19777
19857
 
19778
19858
  // server/routes/session.ts
19779
19859
  import { resolve as resolve27 } from "path";
@@ -19819,8 +19899,8 @@ function withVisitorCookie(response, visitorId) {
19819
19899
  headers
19820
19900
  });
19821
19901
  }
19822
- var app53 = new Hono();
19823
- app53.post("/", async (c) => {
19902
+ var app54 = new Hono();
19903
+ app54.post("/", async (c) => {
19824
19904
  let body;
19825
19905
  try {
19826
19906
  body = await c.req.json();
@@ -19967,7 +20047,7 @@ app53.post("/", async (c) => {
19967
20047
  newVisitorId
19968
20048
  );
19969
20049
  });
19970
- var session_default2 = app53;
20050
+ var session_default2 = app54;
19971
20051
 
19972
20052
  // server/lib/calendar-slots.ts
19973
20053
  var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
@@ -20050,17 +20130,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
20050
20130
  }
20051
20131
 
20052
20132
  // server/routes/calendar-public.ts
20053
- var app54 = new Hono();
20133
+ var app55 = new Hono();
20054
20134
  function setCors(c) {
20055
20135
  c.header("Access-Control-Allow-Origin", "*");
20056
20136
  c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
20057
20137
  c.header("Access-Control-Allow-Headers", "content-type");
20058
20138
  }
20059
- app54.options("/free-busy", (c) => {
20139
+ app55.options("/free-busy", (c) => {
20060
20140
  setCors(c);
20061
20141
  return c.body(null, 204);
20062
20142
  });
20063
- app54.get("/free-busy", async (c) => {
20143
+ app55.get("/free-busy", async (c) => {
20064
20144
  setCors(c);
20065
20145
  const from = c.req.query("from");
20066
20146
  const to = c.req.query("to");
@@ -20102,7 +20182,7 @@ app54.get("/free-busy", async (c) => {
20102
20182
  await session.close();
20103
20183
  }
20104
20184
  });
20105
- var calendar_public_default = app54;
20185
+ var calendar_public_default = app55;
20106
20186
 
20107
20187
  // app/lib/graph-health.ts
20108
20188
  var import_dist4 = __toESM(require_dist3(), 1);
@@ -20868,8 +20948,8 @@ var streamSSE = (c, cb, onError) => {
20868
20948
 
20869
20949
  // app/lib/whatsapp/gateway/routes.ts
20870
20950
  function createWaChannelRoutes(deps) {
20871
- const app56 = new Hono();
20872
- app56.get("/wa-channel/inbound", (c) => {
20951
+ const app57 = new Hono();
20952
+ app57.get("/wa-channel/inbound", (c) => {
20873
20953
  const senderId = c.req.query("senderId");
20874
20954
  if (!senderId) return c.json({ error: "senderId required" }, 400);
20875
20955
  return streamSSE(c, async (stream2) => {
@@ -20887,7 +20967,7 @@ function createWaChannelRoutes(deps) {
20887
20967
  }
20888
20968
  });
20889
20969
  });
20890
- app56.post("/wa-channel/reply", async (c) => {
20970
+ app57.post("/wa-channel/reply", async (c) => {
20891
20971
  const body = await c.req.json().catch(() => null);
20892
20972
  const senderId = body?.senderId;
20893
20973
  const text = body?.text;
@@ -20908,7 +20988,7 @@ function createWaChannelRoutes(deps) {
20908
20988
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
20909
20989
  return c.json({ ok: true });
20910
20990
  });
20911
- app56.post("/wa-channel/reply-document", async (c) => {
20991
+ app57.post("/wa-channel/reply-document", async (c) => {
20912
20992
  const body = await c.req.json().catch(() => null);
20913
20993
  const senderId = body?.senderId;
20914
20994
  const files = body?.files;
@@ -20947,7 +21027,7 @@ function createWaChannelRoutes(deps) {
20947
21027
  }
20948
21028
  return c.json({ ok: true, results });
20949
21029
  });
20950
- app56.post("/wa-channel/ready", async (c) => {
21030
+ app57.post("/wa-channel/ready", async (c) => {
20951
21031
  const body = await c.req.json().catch(() => null);
20952
21032
  const senderId = body?.senderId;
20953
21033
  if (typeof senderId !== "string") {
@@ -20956,7 +21036,7 @@ function createWaChannelRoutes(deps) {
20956
21036
  deps.onReady?.(senderId);
20957
21037
  return c.json({ ok: true });
20958
21038
  });
20959
- app56.post("/wa-channel/received", async (c) => {
21039
+ app57.post("/wa-channel/received", async (c) => {
20960
21040
  const body = await c.req.json().catch(() => null);
20961
21041
  const senderId = body?.senderId;
20962
21042
  const waMessageId = body?.waMessageId;
@@ -20966,7 +21046,7 @@ function createWaChannelRoutes(deps) {
20966
21046
  deps.onReceived?.(senderId, waMessageId);
20967
21047
  return c.json({ ok: true });
20968
21048
  });
20969
- app56.post("/wa-channel/turn-end", async (c) => {
21049
+ app57.post("/wa-channel/turn-end", async (c) => {
20970
21050
  const body = await c.req.json().catch(() => null);
20971
21051
  const senderId = body?.senderId;
20972
21052
  const sessionId = body?.sessionId;
@@ -20997,7 +21077,7 @@ function createWaChannelRoutes(deps) {
20997
21077
  console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=fallback bytes=${bytes}`);
20998
21078
  return c.json({ ok: true, delivered: "fallback" });
20999
21079
  });
21000
- return app56;
21080
+ return app57;
21001
21081
  }
21002
21082
 
21003
21083
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -21010,9 +21090,11 @@ var WaGateway = class {
21010
21090
  }
21011
21091
  hub = new InboundHub();
21012
21092
  replies = /* @__PURE__ */ new Map();
21013
- // Per-sender document-delivery context (the Baileys accountId), set on every
21014
- // inbound. Its presence is the reply-only guard: a sender with no inbound has
21015
- // no context, so a file reply to a cold recipient is refused.
21093
+ // Per-sender document-delivery context, set on every inbound. Its presence is
21094
+ // the reply-only guard: a sender with no inbound has no context, so a file
21095
+ // reply to a cold recipient is refused. `accountId` is the Baileys socket
21096
+ // owner (reply transport); `maxyAccountId` (Task 1390) is the sender's
21097
+ // effective session account — the file-path validation scope.
21016
21098
  docContexts = /* @__PURE__ */ new Map();
21017
21099
  spawning = /* @__PURE__ */ new Set();
21018
21100
  seq = 0;
@@ -21067,7 +21149,7 @@ var WaGateway = class {
21067
21149
  const mediaField = openable.length > 0 ? `media=${openable.map((m) => m.type).join(",")} mediaPaths=${openable.map((m) => m.path).join(",")}` : input.media.some((m) => m.type === "audio") ? "media=audio mediaPath=transcribed" : "media=none";
21068
21150
  const source = input.source ?? "user";
21069
21151
  this.replies.set(input.senderId, input.reply);
21070
- this.docContexts.set(input.senderId, { accountId: input.accountId });
21152
+ this.docContexts.set(input.senderId, { accountId: input.accountId, maxyAccountId: input.effectiveAccountId });
21071
21153
  this.hub.deliver(
21072
21154
  {
21073
21155
  senderId: input.senderId,
@@ -21110,7 +21192,7 @@ var WaGateway = class {
21110
21192
  async sendDocument(senderId, filePath, caption) {
21111
21193
  const ctx = this.docContexts.get(senderId);
21112
21194
  if (!ctx) throw new WaReplyError(`no conversation for sender ${senderId}`, false);
21113
- return this.deps.sendDocument({ senderId, accountId: ctx.accountId, filePath, caption });
21195
+ return this.deps.sendDocument({ senderId, accountId: ctx.accountId, maxyAccountId: ctx.maxyAccountId, filePath, caption });
21114
21196
  }
21115
21197
  };
21116
21198
 
@@ -21299,8 +21381,8 @@ var InboundHub2 = class {
21299
21381
 
21300
21382
  // app/lib/webchat/gateway/routes.ts
21301
21383
  function createWebchatChannelRoutes(deps) {
21302
- const app56 = new Hono();
21303
- app56.get("/webchat-channel/inbound", (c) => {
21384
+ const app57 = new Hono();
21385
+ app57.get("/webchat-channel/inbound", (c) => {
21304
21386
  const key = c.req.query("key");
21305
21387
  if (!key) return c.json({ error: "key required" }, 400);
21306
21388
  return streamSSE(c, async (stream2) => {
@@ -21318,7 +21400,7 @@ function createWebchatChannelRoutes(deps) {
21318
21400
  }
21319
21401
  });
21320
21402
  });
21321
- app56.post("/webchat-channel/reply", async (c) => {
21403
+ app57.post("/webchat-channel/reply", async (c) => {
21322
21404
  const body = await c.req.json().catch(() => null);
21323
21405
  const key = body?.key;
21324
21406
  const text = body?.text;
@@ -21328,7 +21410,7 @@ function createWebchatChannelRoutes(deps) {
21328
21410
  deps.onReply?.(key, text);
21329
21411
  return c.json({ ok: true });
21330
21412
  });
21331
- app56.post("/webchat-channel/connector-auth", async (c) => {
21413
+ app57.post("/webchat-channel/connector-auth", async (c) => {
21332
21414
  const body = await c.req.json().catch(() => null);
21333
21415
  const key = body?.key;
21334
21416
  const sessionId = body?.sessionId;
@@ -21341,7 +21423,7 @@ function createWebchatChannelRoutes(deps) {
21341
21423
  const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
21342
21424
  return c.json(result);
21343
21425
  });
21344
- app56.post("/webchat-channel/ready", async (c) => {
21426
+ app57.post("/webchat-channel/ready", async (c) => {
21345
21427
  const body = await c.req.json().catch(() => null);
21346
21428
  const key = body?.key;
21347
21429
  if (typeof key !== "string") {
@@ -21350,7 +21432,7 @@ function createWebchatChannelRoutes(deps) {
21350
21432
  deps.onReady?.(key);
21351
21433
  return c.json({ ok: true });
21352
21434
  });
21353
- app56.post("/webchat-channel/permission-request", async (c) => {
21435
+ app57.post("/webchat-channel/permission-request", async (c) => {
21354
21436
  const body = await c.req.json().catch(() => null);
21355
21437
  const key = body?.key;
21356
21438
  const requestId = body?.request_id;
@@ -21364,7 +21446,7 @@ function createWebchatChannelRoutes(deps) {
21364
21446
  const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
21365
21447
  return c.json(verdict);
21366
21448
  });
21367
- app56.post("/webchat-channel/received", async (c) => {
21449
+ app57.post("/webchat-channel/received", async (c) => {
21368
21450
  const body = await c.req.json().catch(() => null);
21369
21451
  const key = body?.key;
21370
21452
  const messageId = body?.messageId;
@@ -21374,7 +21456,7 @@ function createWebchatChannelRoutes(deps) {
21374
21456
  deps.onReceived?.(key, messageId);
21375
21457
  return c.json({ ok: true });
21376
21458
  });
21377
- app56.post("/webchat-channel/turn-end", async (c) => {
21459
+ app57.post("/webchat-channel/turn-end", async (c) => {
21378
21460
  const body = await c.req.json().catch(() => null);
21379
21461
  const key = body?.key;
21380
21462
  const sessionId = body?.sessionId;
@@ -21394,7 +21476,7 @@ function createWebchatChannelRoutes(deps) {
21394
21476
  console.error(`[webchat-native] op=turn-undelivered channel=webchat key=${k} sessionId=${sid} bytes=${finalBytes}`);
21395
21477
  return c.json({ ok: true, delivered: "undelivered" });
21396
21478
  });
21397
- return app56;
21479
+ return app57;
21398
21480
  }
21399
21481
 
21400
21482
  // app/lib/webchat/gateway/webchat-gateway.ts
@@ -22023,17 +22105,8 @@ var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
22023
22105
  function platformRoot() {
22024
22106
  return process.env.MAXY_PLATFORM_ROOT || "";
22025
22107
  }
22026
- function makeWhatsAppSendFile(entry) {
22108
+ function makeWhatsAppSendFile(entry, maxyAccountId) {
22027
22109
  return async (filePath, caption) => {
22028
- let maxyAccountId;
22029
- try {
22030
- maxyAccountId = resolvePlatformAccountId();
22031
- } catch (err) {
22032
- console.error(
22033
- `${TAG35} file-delivery reject reason=account-unresolved sender=${entry.senderId} message=${err instanceof Error ? err.message : String(err)}`
22034
- );
22035
- return { ok: false, error: "account-unresolved" };
22036
- }
22037
22110
  const result = await sendWhatsAppDocument({
22038
22111
  to: entry.senderId,
22039
22112
  filePath,
@@ -22049,12 +22122,12 @@ function makeWhatsAppSendFile(entry) {
22049
22122
  return { ok: false, error: result.error };
22050
22123
  };
22051
22124
  }
22052
- function makeWhatsAppFileDelivery(entry) {
22125
+ function makeWhatsAppFileDelivery(entry, maxyAccountId) {
22053
22126
  const shared = makeFileDelivery({
22054
22127
  entry,
22055
22128
  tag: TAG35,
22056
22129
  channel: "whatsapp",
22057
- sendFile: makeWhatsAppSendFile(entry)
22130
+ sendFile: makeWhatsAppSendFile(entry, maxyAccountId)
22058
22131
  });
22059
22132
  let turnStartedAt = null;
22060
22133
  let routeCalls = [];
@@ -22138,7 +22211,7 @@ function startNativeFileFollower(input) {
22138
22211
  return startFollower({
22139
22212
  entry,
22140
22213
  tag: "[whatsapp-adaptor]",
22141
- fileDelivery: makeWhatsAppFileDelivery(entry),
22214
+ fileDelivery: makeWhatsAppFileDelivery(entry, input.maxyAccountId),
22142
22215
  // A resumed session's JSONL already holds prior SendUserFile tool_uses;
22143
22216
  // suppress replay so historical files are not re-sent on attach.
22144
22217
  suppressResumeReplay: true,
@@ -22261,8 +22334,8 @@ var InboundHub3 = class {
22261
22334
 
22262
22335
  // app/lib/telegram/gateway/routes.ts
22263
22336
  function createTelegramChannelRoutes(deps) {
22264
- const app56 = new Hono();
22265
- app56.get("/tg-channel/inbound", (c) => {
22337
+ const app57 = new Hono();
22338
+ app57.get("/tg-channel/inbound", (c) => {
22266
22339
  const key = c.req.query("key");
22267
22340
  if (!key) return c.json({ error: "key required" }, 400);
22268
22341
  return streamSSE(c, async (stream2) => {
@@ -22280,7 +22353,7 @@ function createTelegramChannelRoutes(deps) {
22280
22353
  }
22281
22354
  });
22282
22355
  });
22283
- app56.post("/tg-channel/reply", async (c) => {
22356
+ app57.post("/tg-channel/reply", async (c) => {
22284
22357
  const body = await c.req.json().catch(() => null);
22285
22358
  const key = body?.key;
22286
22359
  const text = body?.text;
@@ -22296,7 +22369,7 @@ function createTelegramChannelRoutes(deps) {
22296
22369
  console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
22297
22370
  return c.json({ ok: true });
22298
22371
  });
22299
- app56.post("/tg-channel/ready", async (c) => {
22372
+ app57.post("/tg-channel/ready", async (c) => {
22300
22373
  const body = await c.req.json().catch(() => null);
22301
22374
  const key = body?.key;
22302
22375
  if (typeof key !== "string") {
@@ -22305,7 +22378,7 @@ function createTelegramChannelRoutes(deps) {
22305
22378
  deps.onReady?.(key);
22306
22379
  return c.json({ ok: true });
22307
22380
  });
22308
- app56.post("/tg-channel/received", async (c) => {
22381
+ app57.post("/tg-channel/received", async (c) => {
22309
22382
  const body = await c.req.json().catch(() => null);
22310
22383
  const key = body?.key;
22311
22384
  const messageId = body?.messageId;
@@ -22315,7 +22388,7 @@ function createTelegramChannelRoutes(deps) {
22315
22388
  deps.onReceived?.(key, messageId);
22316
22389
  return c.json({ ok: true });
22317
22390
  });
22318
- app56.post("/tg-channel/turn-end", async (c) => {
22391
+ app57.post("/tg-channel/turn-end", async (c) => {
22319
22392
  const body = await c.req.json().catch(() => null);
22320
22393
  const key = body?.key;
22321
22394
  const sessionId = body?.sessionId;
@@ -22340,7 +22413,7 @@ function createTelegramChannelRoutes(deps) {
22340
22413
  console.error(`[telegram-native] op=turn-fallback key=${key} sessionId=${sid} bytes=${Buffer.byteLength(finalText, "utf8")}`);
22341
22414
  return c.json({ ok: true, delivered: "fallback" });
22342
22415
  });
22343
- return app56;
22416
+ return app57;
22344
22417
  }
22345
22418
 
22346
22419
  // app/lib/telegram/gateway/telegram-gateway.ts
@@ -22469,7 +22542,7 @@ async function sendTelegramDocument(input) {
22469
22542
  resolvedPath = realpathSync7(filePath);
22470
22543
  const accountResolved = realpathSync7(accountDir);
22471
22544
  if (!resolvedPath.startsWith(accountResolved + "/")) {
22472
- console.error(`${TAG36} document REJECTED reason=outside_account_directory`);
22545
+ console.error(`${TAG36} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
22473
22546
  return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
22474
22547
  }
22475
22548
  } catch (err) {
@@ -22536,21 +22609,12 @@ function makeTelegramSendFile(entry) {
22536
22609
  console.error(`${TAG37} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
22537
22610
  return { ok: false, error: "no-reply-target" };
22538
22611
  }
22539
- let maxyAccountId;
22540
- try {
22541
- maxyAccountId = resolvePlatformAccountId();
22542
- } catch (err) {
22543
- console.error(
22544
- `${TAG37} file-delivery reject reason=account-unresolved sender=${entry.senderId} message=${err instanceof Error ? err.message : String(err)}`
22545
- );
22546
- return { ok: false, error: "account-unresolved" };
22547
- }
22548
22612
  const result = await sendTelegramDocument({
22549
22613
  botToken,
22550
22614
  chatId: Number(entry.replyTarget),
22551
22615
  filePath,
22552
22616
  caption,
22553
- maxyAccountId,
22617
+ maxyAccountId: entry.accountId,
22554
22618
  platformRoot: platformRoot2()
22555
22619
  });
22556
22620
  return result.ok ? { ok: true } : { ok: false, error: result.error };
@@ -23171,20 +23235,19 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
23171
23235
  function isPublicHost(host) {
23172
23236
  return host.startsWith("public.") || aliasDomains.has(host);
23173
23237
  }
23174
- var app55 = new Hono();
23238
+ var app56 = new Hono();
23175
23239
  var nativeFileFollowers = /* @__PURE__ */ new Map();
23176
23240
  var waGateway = new WaGateway({
23177
23241
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
23178
23242
  serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve33(process.env.MAXY_PLATFORM_ROOT ?? join34(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
23179
- // Task 751 — file delivery on the native channel: resolve the platform
23180
- // account + path validation here and funnel through the shared send core.
23181
- sendDocument: async ({ senderId, accountId, filePath, caption }) => {
23182
- let maxyAccountId;
23183
- try {
23184
- maxyAccountId = resolvePlatformAccountId();
23185
- } catch (err) {
23186
- return { ok: false, error: `account-unresolved: ${err instanceof Error ? err.message : String(err)}` };
23187
- }
23243
+ // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
23244
+ // path-validation scope) is the sender's effective SESSION account, resolved
23245
+ // once at the inbound gate and threaded here via the gateway's per-sender doc
23246
+ // context. For an account-manager that is the bound sub-account (where the
23247
+ // session's files live); using the house account (resolvePlatformAccountId)
23248
+ // rejected an in-account file as outside_account_directory. `accountId` stays
23249
+ // the house Baileys socket (the reply transport, two-account invariant).
23250
+ sendDocument: async ({ senderId, accountId, maxyAccountId, filePath, caption }) => {
23188
23251
  const result = await sendWhatsAppDocument({
23189
23252
  to: senderId,
23190
23253
  filePath,
@@ -23218,6 +23281,10 @@ var waGateway = new WaGateway({
23218
23281
  sessionId: req.sessionId,
23219
23282
  senderId,
23220
23283
  accountId,
23284
+ // Task 1390 — the file-path validation scope is the sender's effective
23285
+ // session account (the sub-account for an account-manager), not the house
23286
+ // socket account. accountId stays the getSocket key.
23287
+ maxyAccountId: effectiveAccountId,
23221
23288
  onClose: () => {
23222
23289
  if (nativeFileFollowers.get(senderId) === ac) nativeFileFollowers.delete(senderId);
23223
23290
  }
@@ -23225,7 +23292,7 @@ var waGateway = new WaGateway({
23225
23292
  nativeFileFollowers.set(senderId, ac);
23226
23293
  }
23227
23294
  });
23228
- app55.route("/", waGateway.routes());
23295
+ app56.route("/", waGateway.routes());
23229
23296
  waGateway.startSweeper();
23230
23297
  var webchatGateway = new WebchatGateway({
23231
23298
  gatewayUrl: webchatGatewayUrl(),
@@ -23308,7 +23375,7 @@ var webchatGateway = new WebchatGateway({
23308
23375
  firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
23309
23376
  });
23310
23377
  setWebchatGateway(webchatGateway);
23311
- app55.route("/", webchatGateway.routes());
23378
+ app56.route("/", webchatGateway.routes());
23312
23379
  webchatGateway.startSweeper();
23313
23380
  webchatGateway.startPublicReaper();
23314
23381
  var telegramFileFollowers = /* @__PURE__ */ new Map();
@@ -23341,7 +23408,7 @@ var telegramGateway = new TelegramGateway({
23341
23408
  }
23342
23409
  });
23343
23410
  setTelegramGateway(telegramGateway);
23344
- app55.route("/", telegramGateway.routes());
23411
+ app56.route("/", telegramGateway.routes());
23345
23412
  telegramGateway.startSweeper();
23346
23413
  var chatRoutes = createChatRoutes({
23347
23414
  handleInbound: (input) => webchatGateway.handleInbound(input),
@@ -23360,21 +23427,26 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
23360
23427
  const sent = await sendTelegramText(botToken, chatId, text);
23361
23428
  if (!sent.ok) throw new Error(sent.error ?? "telegram send failed");
23362
23429
  },
23363
- effectiveAccountFor: (accountId, accountDir, destination) => managedAccountFor(readAccountManagers(accountDir), destination) ?? accountId
23430
+ effectiveAccountFor: (accountId, accountDir, destination) => {
23431
+ const managedSub = managedAccountFor(readAccountManagers(accountDir), destination);
23432
+ if (managedSub === null) return accountId;
23433
+ if (!listValidAccounts().some((a) => a.accountId === managedSub)) return null;
23434
+ return managedSub;
23435
+ }
23364
23436
  });
23365
- app55.route("/api/channel/schedule-inject", scheduleInjectRoutes);
23366
- app55.use("*", clientIpMiddleware);
23437
+ app56.route("/api/channel/schedule-inject", scheduleInjectRoutes);
23438
+ app56.use("*", clientIpMiddleware);
23367
23439
  function allowsSameOriginFraming(path2) {
23368
23440
  return path2 === "/vnc-viewer.html" || path2.startsWith("/api/admin/attachment/") || path2.startsWith("/api/public-reader/attachment/") || path2 === "/api/admin/files/download";
23369
23441
  }
23370
- app55.use("*", async (c, next) => {
23442
+ app56.use("*", async (c, next) => {
23371
23443
  await next();
23372
23444
  c.header("X-Content-Type-Options", "nosniff");
23373
23445
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
23374
23446
  c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
23375
23447
  });
23376
23448
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
23377
- app55.use("*", async (c, next) => {
23449
+ app56.use("*", async (c, next) => {
23378
23450
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
23379
23451
  await next();
23380
23452
  return;
@@ -23392,7 +23464,7 @@ app55.use("*", async (c, next) => {
23392
23464
  });
23393
23465
  }
23394
23466
  });
23395
- app55.use("*", async (c, next) => {
23467
+ app56.use("*", async (c, next) => {
23396
23468
  const host = (c.req.header("host") ?? "").split(":")[0];
23397
23469
  if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
23398
23470
  await next();
@@ -23430,7 +23502,7 @@ function resolveRemoteAuthOpts(c) {
23430
23502
  return { ...brandLoginOpts, origin };
23431
23503
  }
23432
23504
  var MAX_LOGIN_BODY = 8 * 1024;
23433
- app55.post("/__remote-auth/login", async (c) => {
23505
+ app56.post("/__remote-auth/login", async (c) => {
23434
23506
  const client = clientFrom(c);
23435
23507
  const clientIp = client.ip || "unknown";
23436
23508
  if (!requestIsTlsTerminated(c)) {
@@ -23475,7 +23547,7 @@ app55.post("/__remote-auth/login", async (c) => {
23475
23547
  }
23476
23548
  });
23477
23549
  });
23478
- app55.get("/__remote-auth/logout", (c) => {
23550
+ app56.get("/__remote-auth/logout", (c) => {
23479
23551
  const client = clientFrom(c);
23480
23552
  const clientIp = client.ip || "unknown";
23481
23553
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -23488,7 +23560,7 @@ app55.get("/__remote-auth/logout", (c) => {
23488
23560
  }
23489
23561
  });
23490
23562
  });
23491
- app55.post("/__remote-auth/change-password", async (c) => {
23563
+ app56.post("/__remote-auth/change-password", async (c) => {
23492
23564
  const client = clientFrom(c);
23493
23565
  const clientIp = client.ip || "unknown";
23494
23566
  const rateLimited = checkRateLimit(client);
@@ -23547,13 +23619,13 @@ app55.post("/__remote-auth/change-password", async (c) => {
23547
23619
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
23548
23620
  }
23549
23621
  });
23550
- app55.get("/__remote-auth/setup", (c) => {
23622
+ app56.get("/__remote-auth/setup", (c) => {
23551
23623
  if (isRemoteAuthConfigured()) {
23552
23624
  return c.redirect("/");
23553
23625
  }
23554
23626
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
23555
23627
  });
23556
- app55.post("/__remote-auth/set-initial-password", async (c) => {
23628
+ app56.post("/__remote-auth/set-initial-password", async (c) => {
23557
23629
  if (isRemoteAuthConfigured()) {
23558
23630
  return c.redirect("/");
23559
23631
  }
@@ -23591,10 +23663,10 @@ app55.post("/__remote-auth/set-initial-password", async (c) => {
23591
23663
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
23592
23664
  }
23593
23665
  });
23594
- app55.get("/api/remote-auth/status", (c) => {
23666
+ app56.get("/api/remote-auth/status", (c) => {
23595
23667
  return c.json({ configured: isRemoteAuthConfigured() });
23596
23668
  });
23597
- app55.post("/api/remote-auth/set-password", async (c) => {
23669
+ app56.post("/api/remote-auth/set-password", async (c) => {
23598
23670
  let body;
23599
23671
  try {
23600
23672
  body = await c.req.json();
@@ -23633,10 +23705,10 @@ app55.post("/api/remote-auth/set-password", async (c) => {
23633
23705
  return c.json({ error: "Failed to save password" }, 500);
23634
23706
  }
23635
23707
  });
23636
- app55.route("/api/_client-error", client_error_default);
23708
+ app56.route("/api/_client-error", client_error_default);
23637
23709
  console.log("[client-error-route] mounted");
23638
23710
  var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
23639
- app55.use("*", async (c, next) => {
23711
+ app56.use("*", async (c, next) => {
23640
23712
  const host = (c.req.header("host") ?? "").split(":")[0];
23641
23713
  const path2 = c.req.path;
23642
23714
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/") || // Public free/busy is read by the booking page (a separate Cloudflare Pages
@@ -23680,26 +23752,26 @@ app55.use("*", async (c, next) => {
23680
23752
  }
23681
23753
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path2 }), 200);
23682
23754
  });
23683
- app55.route("/api/health", health_default);
23684
- app55.route("/api/chat", chatRoutes);
23685
- app55.route("/api/whatsapp", whatsapp_default);
23686
- app55.route("/api/whatsapp-reader", whatsapp_reader_default);
23687
- app55.route("/api/public-reader", public_reader_default);
23688
- app55.route("/api/webchat", createWebchatRoutes({
23755
+ app56.route("/api/health", health_default);
23756
+ app56.route("/api/chat", chatRoutes);
23757
+ app56.route("/api/whatsapp", whatsapp_default);
23758
+ app56.route("/api/whatsapp-reader", whatsapp_reader_default);
23759
+ app56.route("/api/public-reader", public_reader_default);
23760
+ app56.route("/api/webchat", createWebchatRoutes({
23689
23761
  handleInbound: (input) => webchatGateway.handleInbound(input),
23690
23762
  // Task 940 — the permission relay's pointer read + verdict write.
23691
23763
  pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
23692
23764
  deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
23693
23765
  resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
23694
23766
  }));
23695
- app55.route("/api/webchat/greeting", webchat_greeting_default);
23696
- app55.route("/api/telegram", telegram_default);
23697
- app55.route("/api/quickbooks", quickbooks_default);
23698
- app55.route("/api/onboarding", onboarding_default);
23699
- app55.route("/api/admin", admin_default);
23700
- app55.route("/api/access", access_default);
23701
- app55.route("/api/session", session_default2);
23702
- app55.route("/api/calendar", calendar_public_default);
23767
+ app56.route("/api/webchat/greeting", webchat_greeting_default);
23768
+ app56.route("/api/telegram", telegram_default);
23769
+ app56.route("/api/quickbooks", quickbooks_default);
23770
+ app56.route("/api/onboarding", onboarding_default);
23771
+ app56.route("/api/admin", admin_default);
23772
+ app56.route("/api/access", access_default);
23773
+ app56.route("/api/session", session_default2);
23774
+ app56.route("/api/calendar", calendar_public_default);
23703
23775
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
23704
23776
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
23705
23777
  var IMAGE_MIME = {
@@ -23711,7 +23783,7 @@ var IMAGE_MIME = {
23711
23783
  ".svg": "image/svg+xml",
23712
23784
  ".ico": "image/x-icon"
23713
23785
  };
23714
- app55.get("/agent-assets/:slug/:filename", (c) => {
23786
+ app56.get("/agent-assets/:slug/:filename", (c) => {
23715
23787
  const slug = c.req.param("slug");
23716
23788
  const filename = c.req.param("filename");
23717
23789
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -23746,7 +23818,7 @@ app55.get("/agent-assets/:slug/:filename", (c) => {
23746
23818
  "Cache-Control": "public, max-age=3600"
23747
23819
  });
23748
23820
  });
23749
- app55.get("/generated/:filename", (c) => {
23821
+ app56.get("/generated/:filename", (c) => {
23750
23822
  const filename = c.req.param("filename");
23751
23823
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
23752
23824
  console.error(`[generated] serve file=${filename} status=403`);
@@ -23776,10 +23848,10 @@ app55.get("/generated/:filename", (c) => {
23776
23848
  "Cache-Control": "public, max-age=86400"
23777
23849
  });
23778
23850
  });
23779
- app55.route("/sites", sites_default);
23780
- app55.route("/listings", listings_default);
23781
- app55.route("/v", visitor_event_default);
23782
- app55.route("/v", visitor_consent_default);
23851
+ app56.route("/sites", sites_default);
23852
+ app56.route("/listings", listings_default);
23853
+ app56.route("/v", visitor_event_default);
23854
+ app56.route("/v", visitor_consent_default);
23783
23855
  var htmlCache = /* @__PURE__ */ new Map();
23784
23856
  var brandLogoPath = "/brand/maxy-monochrome.png";
23785
23857
  var brandIconPath = "/brand/maxy-monochrome.png";
@@ -23934,7 +24006,7 @@ function brandedPublicHtml(agentSlug) {
23934
24006
  function agentUnavailableHtml() {
23935
24007
  return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
23936
24008
  }
23937
- app55.get("/", (c) => {
24009
+ app56.get("/", (c) => {
23938
24010
  const host = (c.req.header("host") ?? "").split(":")[0];
23939
24011
  const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
23940
24012
  if (klass === "operator") {
@@ -23956,12 +24028,12 @@ app55.get("/", (c) => {
23956
24028
  console.log(`[host-class] host=${host} class=admin served=index.html`);
23957
24029
  return c.html(cachedHtml("index.html"));
23958
24030
  });
23959
- app55.get("/public", (c) => {
24031
+ app56.get("/public", (c) => {
23960
24032
  const host = (c.req.header("host") ?? "").split(":")[0];
23961
24033
  if (isPublicHost(host)) return c.text("Not found", 404);
23962
24034
  return c.html(cachedHtml("public.html"));
23963
24035
  });
23964
- app55.get("/public-chat", (c) => {
24036
+ app56.get("/public-chat", (c) => {
23965
24037
  const host = (c.req.header("host") ?? "").split(":")[0];
23966
24038
  if (isPublicHost(host)) return c.text("Not found", 404);
23967
24039
  return c.html(cachedHtml("public.html"));
@@ -23980,9 +24052,9 @@ async function logViewerFetch(c, next) {
23980
24052
  duration_ms: Date.now() - start
23981
24053
  });
23982
24054
  }
23983
- app55.use("/vnc-viewer.html", logViewerFetch);
23984
- app55.use("/vnc-popout.html", logViewerFetch);
23985
- app55.get("/vnc-popout.html", (c) => {
24055
+ app56.use("/vnc-viewer.html", logViewerFetch);
24056
+ app56.use("/vnc-popout.html", logViewerFetch);
24057
+ app56.get("/vnc-popout.html", (c) => {
23986
24058
  let html = htmlCache.get("vnc-popout.html");
23987
24059
  if (!html) {
23988
24060
  html = readFileSync35(resolve33(process.cwd(), "public", "vnc-popout.html"), "utf-8");
@@ -23995,7 +24067,7 @@ app55.get("/vnc-popout.html", (c) => {
23995
24067
  }
23996
24068
  return c.html(html);
23997
24069
  });
23998
- app55.post("/api/vnc/client-event", async (c) => {
24070
+ app56.post("/api/vnc/client-event", async (c) => {
23999
24071
  let body;
24000
24072
  try {
24001
24073
  body = await c.req.json();
@@ -24016,11 +24088,11 @@ app55.post("/api/vnc/client-event", async (c) => {
24016
24088
  });
24017
24089
  return c.json({ ok: true });
24018
24090
  });
24019
- app55.get("/g/:slug", (c) => {
24091
+ app56.get("/g/:slug", (c) => {
24020
24092
  return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
24021
24093
  });
24022
24094
  for (const pwa of PWA_SURFACES) {
24023
- app55.get(pwa.manifestPath, (c) => {
24095
+ app56.get(pwa.manifestPath, (c) => {
24024
24096
  const manifest = buildManifest(pwa, {
24025
24097
  productName: BRAND.productName,
24026
24098
  appIcon192: brandAppIcon192Path,
@@ -24036,7 +24108,7 @@ for (const pwa of PWA_SURFACES) {
24036
24108
  return c.body(JSON.stringify(manifest));
24037
24109
  });
24038
24110
  }
24039
- app55.get("/sw.js", (c) => {
24111
+ app56.get("/sw.js", (c) => {
24040
24112
  if (SW_SOURCE == null) {
24041
24113
  console.error("[pwa] op=sw status=500 reason=sw-source-missing");
24042
24114
  return c.text("Service worker unavailable", 500);
@@ -24045,12 +24117,12 @@ app55.get("/sw.js", (c) => {
24045
24117
  console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
24046
24118
  return c.body(SW_SOURCE);
24047
24119
  });
24048
- app55.get("/graph", (c) => {
24120
+ app56.get("/graph", (c) => {
24049
24121
  const host = (c.req.header("host") ?? "").split(":")[0];
24050
24122
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
24051
24123
  return c.html(cachedHtml("graph.html"));
24052
24124
  });
24053
- app55.get("/chat", (c) => {
24125
+ app56.get("/chat", (c) => {
24054
24126
  const host = (c.req.header("host") ?? "").split(":")[0];
24055
24127
  if (isOperatorHost(host, getOperatorDomains())) {
24056
24128
  console.log(`[host-class] host=${host} class=operator served=operator.html`);
@@ -24059,22 +24131,22 @@ app55.get("/chat", (c) => {
24059
24131
  if (isPublicHost(host)) return c.text("Not found", 404);
24060
24132
  return c.html(cachedHtml("chat.html"));
24061
24133
  });
24062
- app55.get("/data", (c) => {
24134
+ app56.get("/data", (c) => {
24063
24135
  const host = (c.req.header("host") ?? "").split(":")[0];
24064
24136
  if (isPublicHost(host)) return c.text("Not found", 404);
24065
24137
  return c.html(cachedHtml("data.html"));
24066
24138
  });
24067
- app55.get("/calendar", (c) => {
24139
+ app56.get("/calendar", (c) => {
24068
24140
  const host = (c.req.header("host") ?? "").split(":")[0];
24069
24141
  if (isPublicHost(host)) return c.text("Not found", 404);
24070
24142
  return c.html(cachedHtml("calendar.html"));
24071
24143
  });
24072
- app55.get("/browser", (c) => {
24144
+ app56.get("/browser", (c) => {
24073
24145
  const host = (c.req.header("host") ?? "").split(":")[0];
24074
24146
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
24075
24147
  return c.html(cachedHtml("browser.html"));
24076
24148
  });
24077
- app55.get("/:slug", async (c, next) => {
24149
+ app56.get("/:slug", async (c, next) => {
24078
24150
  const slug = c.req.param("slug");
24079
24151
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
24080
24152
  const account = resolveAccount();
@@ -24089,13 +24161,13 @@ app55.get("/:slug", async (c, next) => {
24089
24161
  await next();
24090
24162
  });
24091
24163
  if (brandFaviconPath !== "/favicon.ico") {
24092
- app55.get("/favicon.ico", (c) => {
24164
+ app56.get("/favicon.ico", (c) => {
24093
24165
  c.header("Cache-Control", "public, max-age=300");
24094
24166
  return c.redirect(brandFaviconPath, 302);
24095
24167
  });
24096
24168
  }
24097
- app55.use("/*", serveStatic({ root: "./public" }));
24098
- app55.all("*", (c) => {
24169
+ app56.use("/*", serveStatic({ root: "./public" }));
24170
+ app56.all("*", (c) => {
24099
24171
  const host = (c.req.header("host") ?? "").split(":")[0];
24100
24172
  const path2 = c.req.path;
24101
24173
  if (isPublicHost(host)) {
@@ -24109,7 +24181,7 @@ app55.all("*", (c) => {
24109
24181
  });
24110
24182
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
24111
24183
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
24112
- var httpServer = serve({ fetch: app55.fetch, port, hostname });
24184
+ var httpServer = serve({ fetch: app56.fetch, port, hostname });
24113
24185
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
24114
24186
  {
24115
24187
  const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join34(__dirname, "..");
@@ -24209,7 +24281,7 @@ for (const m of SUBAPP_MANIFEST) {
24209
24281
  }
24210
24282
  try {
24211
24283
  const registered = [];
24212
- for (const r of app55.routes ?? []) {
24284
+ for (const r of app56.routes ?? []) {
24213
24285
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
24214
24286
  if (AGENT_SLUG_PATTERN.test(r.path)) {
24215
24287
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });