@rubytech/create-maxy-code 0.1.388 → 0.1.389

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 (100) hide show
  1. package/dist/__tests__/joblogic-excluded.test.js +39 -0
  2. package/dist/index.js +21 -0
  3. package/package.json +1 -1
  4. package/payload/platform/config/brand.json +1 -1
  5. package/payload/platform/plugins/.claude-plugin/marketplace.json +0 -5
  6. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +21 -2
  7. package/payload/platform/plugins/docs/references/admin-session.md +4 -0
  8. package/payload/platform/plugins/docs/references/admin-ui.md +18 -1
  9. package/payload/platform/plugins/docs/references/joblogic.md +2 -0
  10. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +2 -0
  11. package/payload/platform/plugins/work/PLUGIN.md +3 -0
  12. package/payload/platform/plugins/work/mcp/dist/__tests__/session-metering.test.d.ts +2 -0
  13. package/payload/platform/plugins/work/mcp/dist/__tests__/session-metering.test.d.ts.map +1 -0
  14. package/payload/platform/plugins/work/mcp/dist/__tests__/session-metering.test.js +98 -0
  15. package/payload/platform/plugins/work/mcp/dist/__tests__/session-metering.test.js.map +1 -0
  16. package/payload/platform/plugins/work/mcp/dist/index.js +16 -0
  17. package/payload/platform/plugins/work/mcp/dist/index.js.map +1 -1
  18. package/payload/platform/plugins/work/mcp/dist/tools/session-metering.d.ts +53 -0
  19. package/payload/platform/plugins/work/mcp/dist/tools/session-metering.d.ts.map +1 -0
  20. package/payload/platform/plugins/work/mcp/dist/tools/session-metering.js +80 -0
  21. package/payload/platform/plugins/work/mcp/dist/tools/session-metering.js.map +1 -0
  22. package/payload/platform/plugins/work/mcp/package.json +2 -1
  23. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  24. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  25. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  26. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  27. package/payload/platform/services/claude-session-manager/dist/http-server.js +98 -8
  28. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  29. package/payload/platform/services/claude-session-manager/dist/pricing.d.ts +45 -0
  30. package/payload/platform/services/claude-session-manager/dist/pricing.d.ts.map +1 -0
  31. package/payload/platform/services/claude-session-manager/dist/pricing.js +57 -0
  32. package/payload/platform/services/claude-session-manager/dist/pricing.js.map +1 -0
  33. package/payload/platform/services/claude-session-manager/dist/session-metering.d.ts +38 -0
  34. package/payload/platform/services/claude-session-manager/dist/session-metering.d.ts.map +1 -0
  35. package/payload/platform/services/claude-session-manager/dist/session-metering.js +292 -0
  36. package/payload/platform/services/claude-session-manager/dist/session-metering.js.map +1 -0
  37. package/payload/platform/templates/specialists/agents/project-manager.md +1 -1
  38. package/payload/server/public/assets/{AdminLoginScreens-BejIjbmU.js → AdminLoginScreens-CerrEc_m.js} +1 -1
  39. package/payload/server/public/assets/AdminShell-cRTvNRbo.js +1 -0
  40. package/payload/server/public/assets/{Checkbox-1F1tzqca.js → Checkbox-Dh2pLMFN.js} +1 -1
  41. package/payload/server/public/assets/{Transcript-DkGa4CQH.js → Transcript-B_GVJujB.js} +1 -1
  42. package/payload/server/public/assets/{admin-DqQARkjy.js → admin-BXaYelnR.js} +1 -1
  43. package/payload/server/public/assets/{browser-nDtEK6RC.js → browser-fhjGE7fH.js} +1 -1
  44. package/payload/server/public/assets/calendar-PnZudAtc.js +1 -0
  45. package/payload/server/public/assets/chat-Dy_zrjKS.js +1 -0
  46. package/payload/server/public/assets/chevron-left-IB6TmMZ_.js +1 -0
  47. package/payload/server/public/assets/data-B2IcjAj6.js +1 -0
  48. package/payload/server/public/assets/{graph-DFyicKd7.js → graph-CycO3tkW.js} +2 -2
  49. package/payload/server/public/assets/{graph-labels-D3BQdcpD.js → graph-labels-DlSsSpBV.js} +1 -1
  50. package/payload/server/public/assets/{operator-BxrjWdT9.js → operator-L4kBC-zS.js} +1 -1
  51. package/payload/server/public/assets/page-D5E-Ng4D.js +1 -0
  52. package/payload/server/public/assets/page-M8sD9LOi.js +32 -0
  53. package/payload/server/public/assets/{public-DbdqfdYq.js → public-BmnajF3K.js} +1 -1
  54. package/payload/server/public/assets/{rotate-ccw-BkX8HODe.js → rotate-ccw-W5HhvAbo.js} +1 -1
  55. package/payload/server/public/assets/useSubAccountSwitcher-D1TI1xvd.css +1 -0
  56. package/payload/server/public/assets/useSubAccountSwitcher-UqZbmzYy.js +9 -0
  57. package/payload/server/public/browser.html +4 -4
  58. package/payload/server/public/calendar.html +5 -5
  59. package/payload/server/public/chat.html +8 -8
  60. package/payload/server/public/data.html +7 -7
  61. package/payload/server/public/graph.html +8 -8
  62. package/payload/server/public/index.html +10 -10
  63. package/payload/server/public/operator.html +10 -10
  64. package/payload/server/public/public.html +8 -8
  65. package/payload/server/server.js +275 -248
  66. package/payload/platform/plugins/joblogic/.claude-plugin/plugin.json +0 -21
  67. package/payload/platform/plugins/joblogic/PLUGIN.md +0 -182
  68. package/payload/platform/plugins/joblogic/lib/mcp-spawn-tee/index.js +0 -193
  69. package/payload/platform/plugins/joblogic/lib/mcp-spawn-tee/package.json +0 -3
  70. package/payload/platform/plugins/joblogic/mcp/dist/index.d.ts +0 -2
  71. package/payload/platform/plugins/joblogic/mcp/dist/index.d.ts.map +0 -1
  72. package/payload/platform/plugins/joblogic/mcp/dist/index.js +0 -229
  73. package/payload/platform/plugins/joblogic/mcp/dist/index.js.map +0 -1
  74. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.d.ts +0 -31
  75. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.d.ts.map +0 -1
  76. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.js +0 -78
  77. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.js.map +0 -1
  78. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.d.ts +0 -35
  79. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.d.ts.map +0 -1
  80. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.js +0 -106
  81. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.js.map +0 -1
  82. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.d.ts +0 -8
  83. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.d.ts.map +0 -1
  84. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.js +0 -41
  85. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.js.map +0 -1
  86. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.d.ts +0 -21
  87. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.d.ts.map +0 -1
  88. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.js +0 -47
  89. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.js.map +0 -1
  90. package/payload/platform/plugins/joblogic/mcp/package.json +0 -10
  91. package/payload/platform/plugins/joblogic/skills/joblogic/SKILL.md +0 -32
  92. package/payload/server/public/assets/AdminShell-D2-uBSB5.js +0 -1
  93. package/payload/server/public/assets/calendar-CO4Bwmho.js +0 -1
  94. package/payload/server/public/assets/chat-DeIge_bC.js +0 -1
  95. package/payload/server/public/assets/chevron-left-DhVdq0aN.js +0 -1
  96. package/payload/server/public/assets/data-B1GIdzHk.js +0 -1
  97. package/payload/server/public/assets/page-ByDLq_o1.js +0 -1
  98. package/payload/server/public/assets/page-D-Ep4bXd.js +0 -32
  99. package/payload/server/public/assets/useSubAccountSwitcher-DMbRhLPv.js +0 -9
  100. package/payload/server/public/assets/useSubAccountSwitcher-DS0iqSkP.css +0 -1
@@ -5740,8 +5740,8 @@ function webchatTurnTimeoutMs() {
5740
5740
  return Number(process.env.WEBCHAT_TURN_TIMEOUT_MS ?? String(2 * 6e4));
5741
5741
  }
5742
5742
  function createChatRoutes(deps) {
5743
- const app56 = new Hono();
5744
- app56.post("/", async (c) => {
5743
+ const app57 = new Hono();
5744
+ app57.post("/", async (c) => {
5745
5745
  console.log(`[chat-route] entered route=public method=POST`);
5746
5746
  const contentType = c.req.header("content-type") ?? "";
5747
5747
  const account = resolveAccount();
@@ -6004,7 +6004,7 @@ ${result.result.text}` : result.result.text;
6004
6004
  }
6005
6005
  });
6006
6006
  });
6007
- return app56;
6007
+ return app57;
6008
6008
  }
6009
6009
 
6010
6010
  // app/lib/channel-pty-bridge/admin-session-id.ts
@@ -6025,8 +6025,8 @@ function isLoopbackAddr(addr) {
6025
6025
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
6026
6026
  }
6027
6027
  function createScheduleInjectRoutes(deps) {
6028
- const app56 = new Hono();
6029
- app56.post("/", async (c) => {
6028
+ const app57 = new Hono();
6029
+ app57.post("/", async (c) => {
6030
6030
  const env = c.env;
6031
6031
  const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
6032
6032
  if (!isLoopbackAddr(remoteAddr)) {
@@ -6065,6 +6065,10 @@ function createScheduleInjectRoutes(deps) {
6065
6065
  console.error(`${TAG16} op=received eventId=${eventId} channel=${channel} destination=${destination} account=${houseAccountId}`);
6066
6066
  if (channel === "whatsapp") {
6067
6067
  const effectiveAccount2 = deps.effectiveAccountFor(houseAccountId, account.accountDir, destination);
6068
+ if (effectiveAccount2 === null) {
6069
+ console.error(`${TAG16} op=schedule-account-manager-reject eventId=${eventId} destination=${destination} reason=unresolved-effective-account`);
6070
+ return c.json({ ok: false, error: "account-manager-unresolved" }, 403);
6071
+ }
6068
6072
  console.error(`${TAG16} op=effective-account eventId=${eventId} effectiveAccount=${effectiveAccount2}`);
6069
6073
  const sessionId2 = adminSessionIdFor(effectiveAccount2, destination);
6070
6074
  const reply2 = (text) => deps.sendWhatsAppText(houseAccountId, destination, text);
@@ -6120,7 +6124,7 @@ function createScheduleInjectRoutes(deps) {
6120
6124
  console.error(`${TAG16} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
6121
6125
  return c.json({ ok: true }, 200);
6122
6126
  });
6123
- return app56;
6127
+ return app57;
6124
6128
  }
6125
6129
 
6126
6130
  // app/lib/telegram/outbound/send-text.ts
@@ -6908,7 +6912,7 @@ async function sendWhatsAppDocument(input) {
6908
6912
  const accountResolved = realpathSync3(accountDir);
6909
6913
  if (!resolvedPath.startsWith(accountResolved + "/")) {
6910
6914
  const sanitised = filePath.replace(accountDir, "<account>/");
6911
- console.error(`${TAG19} document REJECTED path=${sanitised} reason=outside_account_directory`);
6915
+ console.error(`${TAG19} document REJECTED path=${sanitised} reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
6912
6916
  return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
6913
6917
  }
6914
6918
  } catch (err) {
@@ -9674,8 +9678,8 @@ async function reapplyLeversViaManager() {
9674
9678
  var WEBCHAT_SEND_TURN_WINDOW_MS = Number(process.env.WEBCHAT_SEND_TURN_WINDOW_MS ?? String(15e3));
9675
9679
  var sendSeq = 0;
9676
9680
  function createWebchatRoutes(deps) {
9677
- const app56 = new Hono();
9678
- app56.post("/send", requireAdminSession, async (c) => {
9681
+ const app57 = new Hono();
9682
+ app57.post("/send", requireAdminSession, async (c) => {
9679
9683
  let accountId;
9680
9684
  try {
9681
9685
  accountId = resolvePlatformAccountId();
@@ -9875,7 +9879,7 @@ ${note}` : note;
9875
9879
  if (turnTimer.unref) turnTimer.unref();
9876
9880
  return c.json({ ok: true });
9877
9881
  });
9878
- app56.post("/interrupt", requireAdminSession, async (c) => {
9882
+ app57.post("/interrupt", requireAdminSession, async (c) => {
9879
9883
  const cacheKey = c.get("cacheKey");
9880
9884
  const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
9881
9885
  const primaryUserId = resolvePrimaryAdminUserId();
@@ -9903,7 +9907,7 @@ ${note}` : note;
9903
9907
  }
9904
9908
  return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
9905
9909
  });
9906
- app56.post("/settings", requireAdminSession, async (c) => {
9910
+ app57.post("/settings", requireAdminSession, async (c) => {
9907
9911
  const body = await c.req.json().catch(() => null);
9908
9912
  const op = body?.op;
9909
9913
  const value = body?.value;
@@ -9943,7 +9947,7 @@ ${note}` : note;
9943
9947
  console.log(`[webchat:settings] op=${op} outcome=accepted value=${value} settingsApplied=${settingsApplied}`);
9944
9948
  return c.json({ ok: true, settingsApplied });
9945
9949
  });
9946
- app56.get("/session", requireAdminSession, async (c) => {
9950
+ app57.get("/session", requireAdminSession, async (c) => {
9947
9951
  let accountId;
9948
9952
  try {
9949
9953
  accountId = resolvePlatformAccountId();
@@ -10021,7 +10025,7 @@ ${note}` : note;
10021
10025
  const indicators = await fetchComposerIndicators(sessionId);
10022
10026
  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
10027
  });
10024
- app56.post("/permission-verdict", requireAdminSession, async (c) => {
10028
+ app57.post("/permission-verdict", requireAdminSession, async (c) => {
10025
10029
  const body = await c.req.json().catch(() => null);
10026
10030
  const sessionId = body?.sessionId;
10027
10031
  const requestId = body?.request_id;
@@ -10038,7 +10042,7 @@ ${note}` : note;
10038
10042
  const ok = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
10039
10043
  return c.json({ ok });
10040
10044
  });
10041
- return app56;
10045
+ return app57;
10042
10046
  }
10043
10047
 
10044
10048
  // server/routes/webchat-greeting.ts
@@ -17147,6 +17151,36 @@ app32.post("/", requireAdminSession, async (c) => {
17147
17151
  });
17148
17152
  var session_rename_default = app32;
17149
17153
 
17154
+ // server/routes/admin/session-usage.ts
17155
+ var app33 = new Hono();
17156
+ app33.get("/", requireAdminSession, async (c) => {
17157
+ const sessionId = c.req.query("sessionId") ?? "";
17158
+ if (!SESSION_ID_RE2.test(sessionId)) {
17159
+ return c.json({ error: "sessionId must be a v4 UUID" }, 400);
17160
+ }
17161
+ let res;
17162
+ try {
17163
+ res = await fetch(`${managerBase("session-usage:wrapper")}/${sessionId}/metering`);
17164
+ } catch (err) {
17165
+ console.error(`[session-usage] sessionId=${sessionId.slice(0, 8)} manager-unreachable err=${err instanceof Error ? err.message : String(err)}`);
17166
+ return c.json({ error: "manager-unreachable" }, 502);
17167
+ }
17168
+ if (res.status === 200) {
17169
+ const summary = await res.json().catch(() => null);
17170
+ if (!summary) {
17171
+ console.error(`[session-usage] sessionId=${sessionId.slice(0, 8)} manager-bad-json`);
17172
+ return c.json({ error: "manager-bad-json" }, 502);
17173
+ }
17174
+ return c.json(summary);
17175
+ }
17176
+ if (res.status === 404) {
17177
+ return c.json({ error: "session-not-found" }, 404);
17178
+ }
17179
+ console.error(`[session-usage] sessionId=${sessionId.slice(0, 8)} manager-status=${res.status}`);
17180
+ return c.json({ error: `manager-status-${res.status}` }, 502);
17181
+ });
17182
+ var session_usage_default = app33;
17183
+
17150
17184
  // server/routes/admin/session-rc-spawn.ts
17151
17185
  import { randomUUID as randomUUID10 } from "crypto";
17152
17186
  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 +17226,8 @@ function shapeWebchatResponse(sessionId, manager) {
17192
17226
  const landed = redirected ? manager.sessionId : sessionId;
17193
17227
  return { sessionId: landed, outcome, target: `/chat?session=${landed}` };
17194
17228
  }
17195
- var app33 = new Hono();
17196
- app33.post("/", requireAdminSession, async (c) => {
17229
+ var app34 = new Hono();
17230
+ app34.post("/", requireAdminSession, async (c) => {
17197
17231
  let body;
17198
17232
  try {
17199
17233
  body = await c.req.json();
@@ -17276,7 +17310,7 @@ app33.post("/", requireAdminSession, async (c) => {
17276
17310
  }
17277
17311
  return c.json(parsed ?? {});
17278
17312
  });
17279
- var session_rc_spawn_default = app33;
17313
+ var session_rc_spawn_default = app34;
17280
17314
 
17281
17315
  // server/routes/admin/session-reseat.ts
17282
17316
  import { randomUUID as randomUUID11 } from "crypto";
@@ -17299,9 +17333,9 @@ function resolveReseatPlan(body, mintId = randomUUID11, adminUserId, authenticat
17299
17333
  if (authenticatedName) payload.authenticatedName = authenticatedName;
17300
17334
  return { sessionId, payload };
17301
17335
  }
17302
- var app34 = new Hono();
17336
+ var app35 = new Hono();
17303
17337
  var reseatsInFlight = /* @__PURE__ */ new Set();
17304
- app34.post("/", requireAdminSession, async (c) => {
17338
+ app35.post("/", requireAdminSession, async (c) => {
17305
17339
  let body;
17306
17340
  try {
17307
17341
  body = await c.req.json();
@@ -17389,7 +17423,7 @@ app34.post("/", requireAdminSession, async (c) => {
17389
17423
  reseatsInFlight.delete(fromSessionId);
17390
17424
  }
17391
17425
  });
17392
- var session_reseat_default = app34;
17426
+ var session_reseat_default = app35;
17393
17427
 
17394
17428
  // server/routes/admin/system-stats.ts
17395
17429
  import { readFile as readFile5 } from "fs/promises";
@@ -17486,8 +17520,8 @@ async function sample() {
17486
17520
  if (process.platform === "linux") return sampleLinux();
17487
17521
  return sampleOsFallback();
17488
17522
  }
17489
- var app35 = new Hono();
17490
- app35.get("/", async (c) => {
17523
+ var app36 = new Hono();
17524
+ app36.get("/", async (c) => {
17491
17525
  const started = Date.now();
17492
17526
  if (!inflight) {
17493
17527
  inflight = sample().finally(() => {
@@ -17510,7 +17544,7 @@ app35.get("/", async (c) => {
17510
17544
  return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
17511
17545
  }
17512
17546
  });
17513
- var system_stats_default = app35;
17547
+ var system_stats_default = app36;
17514
17548
 
17515
17549
  // server/routes/admin/health.ts
17516
17550
  import { existsSync as existsSync26, readFileSync as readFileSync29 } from "fs";
@@ -17555,8 +17589,8 @@ async function probeConversationDb() {
17555
17589
  });
17556
17590
  }
17557
17591
  }
17558
- var app36 = new Hono();
17559
- app36.get("/", async (c) => {
17592
+ var app37 = new Hono();
17593
+ app37.get("/", async (c) => {
17560
17594
  const version = readVersion();
17561
17595
  const probe = await probeConversationDb();
17562
17596
  const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
@@ -17578,7 +17612,7 @@ app36.get("/", async (c) => {
17578
17612
  uptimeMs
17579
17613
  });
17580
17614
  });
17581
- var health_default2 = app36;
17615
+ var health_default2 = app37;
17582
17616
 
17583
17617
  // server/routes/admin/linkedin-ingest.ts
17584
17618
  import { randomUUID as randomUUID12 } from "crypto";
@@ -17804,8 +17838,8 @@ function buildInitialMessage(env) {
17804
17838
  }
17805
17839
  return header;
17806
17840
  }
17807
- var app37 = new Hono();
17808
- app37.post("/", requireAdminSession, async (c) => {
17841
+ var app38 = new Hono();
17842
+ app38.post("/", requireAdminSession, async (c) => {
17809
17843
  let body;
17810
17844
  try {
17811
17845
  body = await c.req.json();
@@ -17850,7 +17884,7 @@ app37.post("/", requireAdminSession, async (c) => {
17850
17884
  );
17851
17885
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
17852
17886
  });
17853
- var linkedin_ingest_default = app37;
17887
+ var linkedin_ingest_default = app38;
17854
17888
 
17855
17889
  // server/routes/admin/post-turn-context.ts
17856
17890
  import neo4j3 from "neo4j-driver";
@@ -17892,8 +17926,8 @@ function pruneProperties(raw) {
17892
17926
  }
17893
17927
  return out;
17894
17928
  }
17895
- var app38 = new Hono();
17896
- app38.get("/", async (c) => {
17929
+ var app39 = new Hono();
17930
+ app39.get("/", async (c) => {
17897
17931
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
17898
17932
  if (!isLoopbackAddr3(remoteAddr)) {
17899
17933
  console.error(`${TAG28} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -17953,7 +17987,7 @@ app38.get("/", async (c) => {
17953
17987
  await session.close();
17954
17988
  }
17955
17989
  });
17956
- var post_turn_context_default = app38;
17990
+ var post_turn_context_default = app39;
17957
17991
 
17958
17992
  // app/lib/slice-writes.ts
17959
17993
  import neo4j4 from "neo4j-driver";
@@ -18063,8 +18097,8 @@ var TAG29 = "[public-session-context]";
18063
18097
  function isLoopbackAddr4(addr) {
18064
18098
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
18065
18099
  }
18066
- var app39 = new Hono();
18067
- app39.get("/", async (c) => {
18100
+ var app40 = new Hono();
18101
+ app40.get("/", async (c) => {
18068
18102
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
18069
18103
  if (!isLoopbackAddr4(remoteAddr)) {
18070
18104
  console.error(`${TAG29} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -18104,7 +18138,7 @@ app39.get("/", async (c) => {
18104
18138
  await session.close();
18105
18139
  }
18106
18140
  });
18107
- var public_session_context_default = app39;
18141
+ var public_session_context_default = app40;
18108
18142
 
18109
18143
  // app/lib/webchat/gateway/instance.ts
18110
18144
  var instance2 = null;
@@ -18120,8 +18154,8 @@ var TAG30 = "[public-session-exit-route]";
18120
18154
  function isLoopbackAddr5(addr) {
18121
18155
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
18122
18156
  }
18123
- var app40 = new Hono();
18124
- app40.post("/", async (c) => {
18157
+ var app41 = new Hono();
18158
+ app41.post("/", async (c) => {
18125
18159
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
18126
18160
  if (!isLoopbackAddr5(remoteAddr)) {
18127
18161
  console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -18153,15 +18187,15 @@ app40.post("/", async (c) => {
18153
18187
  gateway.handlePublicSessionExit(sessionId);
18154
18188
  return c.json({ ok: true });
18155
18189
  });
18156
- var public_session_exit_default = app40;
18190
+ var public_session_exit_default = app41;
18157
18191
 
18158
18192
  // server/routes/admin/access-session-evict.ts
18159
18193
  var TAG31 = "[access-session-evict]";
18160
18194
  function isLoopbackAddr6(addr) {
18161
18195
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
18162
18196
  }
18163
- var app41 = new Hono();
18164
- app41.post("/", async (c) => {
18197
+ var app42 = new Hono();
18198
+ app42.post("/", async (c) => {
18165
18199
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
18166
18200
  if (!isLoopbackAddr6(remoteAddr)) {
18167
18201
  console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -18189,7 +18223,7 @@ app41.post("/", async (c) => {
18189
18223
  console.log(`${TAG31} grantId=${grantId} dropped=${dropped}`);
18190
18224
  return c.json({ ok: true, dropped });
18191
18225
  });
18192
- var access_session_evict_default = app41;
18226
+ var access_session_evict_default = app42;
18193
18227
 
18194
18228
  // server/routes/admin/enrol-person.ts
18195
18229
  var TAG32 = "[enrol]";
@@ -18197,8 +18231,8 @@ function isLoopbackAddr7(addr) {
18197
18231
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
18198
18232
  }
18199
18233
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
18200
- var app42 = new Hono();
18201
- app42.post("/", async (c) => {
18234
+ var app43 = new Hono();
18235
+ app43.post("/", async (c) => {
18202
18236
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
18203
18237
  if (!isLoopbackAddr7(remoteAddr)) {
18204
18238
  console.error(`${TAG32} reject reason=non-loopback remoteAddr=${remoteAddr}`);
@@ -18261,11 +18295,11 @@ app42.post("/", async (c) => {
18261
18295
  );
18262
18296
  return c.json({ personId, grant }, 200);
18263
18297
  });
18264
- var enrol_person_default = app42;
18298
+ var enrol_person_default = app43;
18265
18299
 
18266
18300
  // server/routes/admin/browser.ts
18267
- var app43 = new Hono();
18268
- app43.post("/launch", requireAdminSession, async (c) => {
18301
+ var app44 = new Hono();
18302
+ app44.post("/launch", requireAdminSession, async (c) => {
18269
18303
  try {
18270
18304
  const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
18271
18305
  console.error(`[admin/browser/launch] op=request transport=${transport}`);
@@ -18293,7 +18327,7 @@ app43.post("/launch", requireAdminSession, async (c) => {
18293
18327
  );
18294
18328
  }
18295
18329
  });
18296
- var browser_default = app43;
18330
+ var browser_default = app44;
18297
18331
 
18298
18332
  // server/routes/admin/calendar.ts
18299
18333
  import { existsSync as existsSync27 } from "fs";
@@ -18439,7 +18473,7 @@ function readAvailabilityConfig(accountDir) {
18439
18473
  }
18440
18474
 
18441
18475
  // server/routes/admin/calendar.ts
18442
- var app44 = new Hono();
18476
+ var app45 = new Hono();
18443
18477
  function normalizeAttendees(raw) {
18444
18478
  if (!Array.isArray(raw)) return [];
18445
18479
  return raw.map((a) => {
@@ -18470,7 +18504,7 @@ function mapMeeting(r) {
18470
18504
  privateNote: r.get("privateNote")
18471
18505
  };
18472
18506
  }
18473
- app44.get("/meetings", requireAdminSession, async (c) => {
18507
+ app45.get("/meetings", requireAdminSession, async (c) => {
18474
18508
  const cacheKey = c.var.cacheKey;
18475
18509
  const accountId = getAccountIdForSession(cacheKey);
18476
18510
  if (!accountId) {
@@ -18533,7 +18567,7 @@ function icsFilename(title) {
18533
18567
  const slug = (title ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
18534
18568
  return `${slug || "meeting"}.ics`;
18535
18569
  }
18536
- app44.get("/meetings/:id/ics", requireAdminSession, async (c) => {
18570
+ app45.get("/meetings/:id/ics", requireAdminSession, async (c) => {
18537
18571
  const cacheKey = c.var.cacheKey;
18538
18572
  const accountId = getAccountIdForSession(cacheKey);
18539
18573
  if (!accountId) {
@@ -18591,7 +18625,7 @@ app44.get("/meetings/:id/ics", requireAdminSession, async (c) => {
18591
18625
  await session.close();
18592
18626
  }
18593
18627
  });
18594
- app44.patch("/meetings/:id", requireAdminSession, async (c) => {
18628
+ app45.patch("/meetings/:id", requireAdminSession, async (c) => {
18595
18629
  const cacheKey = c.var.cacheKey;
18596
18630
  const accountId = getAccountIdForSession(cacheKey);
18597
18631
  if (!accountId) {
@@ -18635,7 +18669,7 @@ app44.patch("/meetings/:id", requireAdminSession, async (c) => {
18635
18669
  await session.close();
18636
18670
  }
18637
18671
  });
18638
- app44.post("/meetings/:id/attendees", requireAdminSession, async (c) => {
18672
+ app45.post("/meetings/:id/attendees", requireAdminSession, async (c) => {
18639
18673
  const cacheKey = c.var.cacheKey;
18640
18674
  const accountId = getAccountIdForSession(cacheKey);
18641
18675
  if (!accountId) {
@@ -18685,7 +18719,7 @@ app44.post("/meetings/:id/attendees", requireAdminSession, async (c) => {
18685
18719
  await session.close();
18686
18720
  }
18687
18721
  });
18688
- app44.delete("/meetings/:id/attendees", requireAdminSession, async (c) => {
18722
+ app45.delete("/meetings/:id/attendees", requireAdminSession, async (c) => {
18689
18723
  const cacheKey = c.var.cacheKey;
18690
18724
  const accountId = getAccountIdForSession(cacheKey);
18691
18725
  if (!accountId) {
@@ -18731,7 +18765,7 @@ app44.delete("/meetings/:id/attendees", requireAdminSession, async (c) => {
18731
18765
  await session.close();
18732
18766
  }
18733
18767
  });
18734
- app44.delete("/meetings/:id", requireAdminSession, async (c) => {
18768
+ app45.delete("/meetings/:id", requireAdminSession, async (c) => {
18735
18769
  const cacheKey = c.var.cacheKey;
18736
18770
  const accountId = getAccountIdForSession(cacheKey);
18737
18771
  if (!accountId) {
@@ -18761,7 +18795,7 @@ app44.delete("/meetings/:id", requireAdminSession, async (c) => {
18761
18795
  await session.close();
18762
18796
  }
18763
18797
  });
18764
- app44.get("/booking-link", requireAdminSession, (c) => {
18798
+ app45.get("/booking-link", requireAdminSession, (c) => {
18765
18799
  try {
18766
18800
  const account = resolveAccount();
18767
18801
  if (!account) {
@@ -18784,53 +18818,54 @@ app44.get("/booking-link", requireAdminSession, (c) => {
18784
18818
  return c.json({ bookingDomain: null });
18785
18819
  }
18786
18820
  });
18787
- var calendar_default = app44;
18821
+ var calendar_default = app45;
18788
18822
 
18789
18823
  // 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;
18824
+ var app46 = new Hono();
18825
+ app46.route("/session", session_default);
18826
+ app46.route("/accounts", accounts_default);
18827
+ app46.route("/logs", logs_default);
18828
+ app46.route("/claude-info", claude_info_default);
18829
+ app46.route("/attachment", attachment_default);
18830
+ app46.route("/agents", agents_default);
18831
+ app46.route("/sessions", sessions_default);
18832
+ app46.route("/claude-sessions", claude_sessions_default);
18833
+ app46.route("/log-ingest", log_ingest_default);
18834
+ app46.route("/events", events_default);
18835
+ app46.route("/files", files_default);
18836
+ app46.route("/graph-search", graph_search_default);
18837
+ app46.route("/graph-subgraph", graph_subgraph_default);
18838
+ app46.route("/graph-delete", graph_delete_default);
18839
+ app46.route("/graph-restore", graph_restore_default);
18840
+ app46.route("/graph-labels-in-graph", graph_labels_in_graph_default);
18841
+ app46.route("/graph-default-view", graph_default_view_default);
18842
+ app46.route("/sidebar-artefacts", sidebar_artefacts_default);
18843
+ app46.route("/sidebar-sessions", sidebar_sessions_default);
18844
+ app46.route("/session-delete", session_delete_default);
18845
+ app46.route("/session-stop", session_stop_default);
18846
+ app46.route("/session-archive", session_archive_default);
18847
+ app46.route("/session-rename", session_rename_default);
18848
+ app46.route("/session-usage", session_usage_default);
18849
+ app46.route("/browser", browser_default);
18850
+ app46.route("/session-rc-spawn", session_rc_spawn_default);
18851
+ app46.route("/session-reseat", session_reseat_default);
18852
+ app46.route("/system-stats", system_stats_default);
18853
+ app46.route("/health-brand", health_default2);
18854
+ app46.route("/linkedin-ingest", linkedin_ingest_default);
18855
+ app46.route("/post-turn-context", post_turn_context_default);
18856
+ app46.route("/public-session-context", public_session_context_default);
18857
+ app46.route("/public-session-exit", public_session_exit_default);
18858
+ app46.route("/access-session-evict", access_session_evict_default);
18859
+ app46.route("/enrol-person", enrol_person_default);
18860
+ app46.route("/calendar", calendar_default);
18861
+ var admin_default = app46;
18827
18862
 
18828
18863
  // server/routes/access/verify-token.ts
18829
18864
  var TAG33 = "[access-verify]";
18830
18865
  var MINT_TAG = "[access-session-mint]";
18831
18866
  var COOKIE_NAME = "__access_session";
18832
- var app46 = new Hono();
18833
- app46.post("/", async (c) => {
18867
+ var app47 = new Hono();
18868
+ app47.post("/", async (c) => {
18834
18869
  const ip = c.var.clientIp || "unknown";
18835
18870
  let body;
18836
18871
  try {
@@ -18912,7 +18947,7 @@ app46.post("/", async (c) => {
18912
18947
  displayName: grant.displayName
18913
18948
  });
18914
18949
  });
18915
- var verify_token_default = app46;
18950
+ var verify_token_default = app47;
18916
18951
 
18917
18952
  // app/lib/access-email.ts
18918
18953
  import { spawn as spawn2 } from "child_process";
@@ -18975,9 +19010,9 @@ async function sendMagicLinkEmail(payload) {
18975
19010
 
18976
19011
  // server/routes/access/request-magic-link.ts
18977
19012
  var TAG34 = "[access-request-link]";
18978
- var app47 = new Hono();
19013
+ var app48 = new Hono();
18979
19014
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
18980
- app47.post("/", async (c) => {
19015
+ app48.post("/", async (c) => {
18981
19016
  let body;
18982
19017
  try {
18983
19018
  body = await c.req.json();
@@ -19051,13 +19086,13 @@ app47.post("/", async (c) => {
19051
19086
  );
19052
19087
  return c.json({ message: VISITOR_MESSAGE }, 200);
19053
19088
  });
19054
- var request_magic_link_default = app47;
19089
+ var request_magic_link_default = app48;
19055
19090
 
19056
19091
  // 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;
19092
+ var app49 = new Hono();
19093
+ app49.route("/verify-token", verify_token_default);
19094
+ app49.route("/request-magic-link", request_magic_link_default);
19095
+ var access_default = app49;
19061
19096
 
19062
19097
  // server/routes/sites.ts
19063
19098
  import { existsSync as existsSync28, readFileSync as readFileSync31, realpathSync as realpathSync6, statSync as statSync12 } from "fs";
@@ -19092,8 +19127,8 @@ function getExt(p) {
19092
19127
  if (idx < p.lastIndexOf("/")) return "";
19093
19128
  return p.slice(idx).toLowerCase();
19094
19129
  }
19095
- var app49 = new Hono();
19096
- app49.get("/:rel{.*}", (c) => {
19130
+ var app50 = new Hono();
19131
+ app50.get("/:rel{.*}", (c) => {
19097
19132
  const reqPath = c.req.path;
19098
19133
  const rawRel = c.req.param("rel") ?? "";
19099
19134
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -19196,7 +19231,7 @@ app49.get("/:rel{.*}", (c) => {
19196
19231
  "X-Content-Type-Options": "nosniff"
19197
19232
  });
19198
19233
  });
19199
- var sites_default = app49;
19234
+ var sites_default = app50;
19200
19235
 
19201
19236
  // app/lib/visitor-token.ts
19202
19237
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
@@ -19296,7 +19331,7 @@ function readBrandConfig() {
19296
19331
  }
19297
19332
 
19298
19333
  // server/routes/visitor-consent.ts
19299
- var app50 = new Hono();
19334
+ var app51 = new Hono();
19300
19335
  var CONSENT_COOKIE_NAME = "mxy_consent";
19301
19336
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
19302
19337
  var DEFAULT_CONSENT_COPY = {
@@ -19341,17 +19376,17 @@ function siteSlugFromReferer(referer) {
19341
19376
  return "";
19342
19377
  }
19343
19378
  }
19344
- app50.options("/consent", (c) => {
19379
+ app51.options("/consent", (c) => {
19345
19380
  const origin = getOrigin(c);
19346
19381
  setCorsHeaders(c, origin);
19347
19382
  return c.body(null, 204);
19348
19383
  });
19349
- app50.options("/brand-config", (c) => {
19384
+ app51.options("/brand-config", (c) => {
19350
19385
  const origin = getOrigin(c);
19351
19386
  setCorsHeaders(c, origin);
19352
19387
  return c.body(null, 204);
19353
19388
  });
19354
- app50.post("/consent", async (c) => {
19389
+ app51.post("/consent", async (c) => {
19355
19390
  const origin = getOrigin(c);
19356
19391
  setCorsHeaders(c, origin);
19357
19392
  let raw;
@@ -19391,7 +19426,7 @@ app50.post("/consent", async (c) => {
19391
19426
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
19392
19427
  return c.body(null, 204);
19393
19428
  });
19394
- app50.get("/brand-config", (c) => {
19429
+ app51.get("/brand-config", (c) => {
19395
19430
  const origin = getOrigin(c);
19396
19431
  setCorsHeaders(c, origin);
19397
19432
  const brand = readBrandConfig();
@@ -19401,7 +19436,7 @@ app50.get("/brand-config", (c) => {
19401
19436
  c.header("Cache-Control", "public, max-age=300");
19402
19437
  return c.json({ consent: { copy, palette } });
19403
19438
  });
19404
- var visitor_consent_default = app50;
19439
+ var visitor_consent_default = app51;
19405
19440
 
19406
19441
  // server/routes/listings.ts
19407
19442
  function getCookie(headerValue, name) {
@@ -19428,8 +19463,8 @@ function appendConsentParams(pageUrl, token) {
19428
19463
  }
19429
19464
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
19430
19465
  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) => {
19466
+ var app52 = new Hono();
19467
+ app52.get("/:slug/click", async (c) => {
19433
19468
  const slug = c.req.param("slug") ?? "";
19434
19469
  const rawSession = c.req.query("session") ?? "";
19435
19470
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -19493,10 +19528,10 @@ app51.get("/:slug/click", async (c) => {
19493
19528
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
19494
19529
  return c.redirect(redirectUrl, 302);
19495
19530
  });
19496
- var listings_default = app51;
19531
+ var listings_default = app52;
19497
19532
 
19498
19533
  // server/routes/visitor-event.ts
19499
- var app52 = new Hono();
19534
+ var app53 = new Hono();
19500
19535
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
19501
19536
  var buckets = /* @__PURE__ */ new Map();
19502
19537
  var RATE_LIMIT = 60;
@@ -19563,12 +19598,12 @@ function originAllowed(origin, allowlist) {
19563
19598
  return false;
19564
19599
  }
19565
19600
  }
19566
- app52.options("/event", (c) => {
19601
+ app53.options("/event", (c) => {
19567
19602
  const origin = getOrigin2(c);
19568
19603
  setCorsHeaders2(c, origin);
19569
19604
  return c.body(null, 204);
19570
19605
  });
19571
- app52.post("/event", async (c) => {
19606
+ app53.post("/event", async (c) => {
19572
19607
  const origin = getOrigin2(c);
19573
19608
  setCorsHeaders2(c, origin);
19574
19609
  const ua = c.req.header("user-agent") ?? "";
@@ -19773,7 +19808,7 @@ async function writeEvent(opts) {
19773
19808
  );
19774
19809
  }
19775
19810
  }
19776
- var visitor_event_default = app52;
19811
+ var visitor_event_default = app53;
19777
19812
 
19778
19813
  // server/routes/session.ts
19779
19814
  import { resolve as resolve27 } from "path";
@@ -19819,8 +19854,8 @@ function withVisitorCookie(response, visitorId) {
19819
19854
  headers
19820
19855
  });
19821
19856
  }
19822
- var app53 = new Hono();
19823
- app53.post("/", async (c) => {
19857
+ var app54 = new Hono();
19858
+ app54.post("/", async (c) => {
19824
19859
  let body;
19825
19860
  try {
19826
19861
  body = await c.req.json();
@@ -19967,7 +20002,7 @@ app53.post("/", async (c) => {
19967
20002
  newVisitorId
19968
20003
  );
19969
20004
  });
19970
- var session_default2 = app53;
20005
+ var session_default2 = app54;
19971
20006
 
19972
20007
  // server/lib/calendar-slots.ts
19973
20008
  var WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
@@ -20050,17 +20085,17 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
20050
20085
  }
20051
20086
 
20052
20087
  // server/routes/calendar-public.ts
20053
- var app54 = new Hono();
20088
+ var app55 = new Hono();
20054
20089
  function setCors(c) {
20055
20090
  c.header("Access-Control-Allow-Origin", "*");
20056
20091
  c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
20057
20092
  c.header("Access-Control-Allow-Headers", "content-type");
20058
20093
  }
20059
- app54.options("/free-busy", (c) => {
20094
+ app55.options("/free-busy", (c) => {
20060
20095
  setCors(c);
20061
20096
  return c.body(null, 204);
20062
20097
  });
20063
- app54.get("/free-busy", async (c) => {
20098
+ app55.get("/free-busy", async (c) => {
20064
20099
  setCors(c);
20065
20100
  const from = c.req.query("from");
20066
20101
  const to = c.req.query("to");
@@ -20102,7 +20137,7 @@ app54.get("/free-busy", async (c) => {
20102
20137
  await session.close();
20103
20138
  }
20104
20139
  });
20105
- var calendar_public_default = app54;
20140
+ var calendar_public_default = app55;
20106
20141
 
20107
20142
  // app/lib/graph-health.ts
20108
20143
  var import_dist4 = __toESM(require_dist3(), 1);
@@ -20868,8 +20903,8 @@ var streamSSE = (c, cb, onError) => {
20868
20903
 
20869
20904
  // app/lib/whatsapp/gateway/routes.ts
20870
20905
  function createWaChannelRoutes(deps) {
20871
- const app56 = new Hono();
20872
- app56.get("/wa-channel/inbound", (c) => {
20906
+ const app57 = new Hono();
20907
+ app57.get("/wa-channel/inbound", (c) => {
20873
20908
  const senderId = c.req.query("senderId");
20874
20909
  if (!senderId) return c.json({ error: "senderId required" }, 400);
20875
20910
  return streamSSE(c, async (stream2) => {
@@ -20887,7 +20922,7 @@ function createWaChannelRoutes(deps) {
20887
20922
  }
20888
20923
  });
20889
20924
  });
20890
- app56.post("/wa-channel/reply", async (c) => {
20925
+ app57.post("/wa-channel/reply", async (c) => {
20891
20926
  const body = await c.req.json().catch(() => null);
20892
20927
  const senderId = body?.senderId;
20893
20928
  const text = body?.text;
@@ -20908,7 +20943,7 @@ function createWaChannelRoutes(deps) {
20908
20943
  console.error(`[whatsapp-native] op=reply-dispatch senderId=${senderId} bytes=${bytes}`);
20909
20944
  return c.json({ ok: true });
20910
20945
  });
20911
- app56.post("/wa-channel/reply-document", async (c) => {
20946
+ app57.post("/wa-channel/reply-document", async (c) => {
20912
20947
  const body = await c.req.json().catch(() => null);
20913
20948
  const senderId = body?.senderId;
20914
20949
  const files = body?.files;
@@ -20947,7 +20982,7 @@ function createWaChannelRoutes(deps) {
20947
20982
  }
20948
20983
  return c.json({ ok: true, results });
20949
20984
  });
20950
- app56.post("/wa-channel/ready", async (c) => {
20985
+ app57.post("/wa-channel/ready", async (c) => {
20951
20986
  const body = await c.req.json().catch(() => null);
20952
20987
  const senderId = body?.senderId;
20953
20988
  if (typeof senderId !== "string") {
@@ -20956,7 +20991,7 @@ function createWaChannelRoutes(deps) {
20956
20991
  deps.onReady?.(senderId);
20957
20992
  return c.json({ ok: true });
20958
20993
  });
20959
- app56.post("/wa-channel/received", async (c) => {
20994
+ app57.post("/wa-channel/received", async (c) => {
20960
20995
  const body = await c.req.json().catch(() => null);
20961
20996
  const senderId = body?.senderId;
20962
20997
  const waMessageId = body?.waMessageId;
@@ -20966,7 +21001,7 @@ function createWaChannelRoutes(deps) {
20966
21001
  deps.onReceived?.(senderId, waMessageId);
20967
21002
  return c.json({ ok: true });
20968
21003
  });
20969
- app56.post("/wa-channel/turn-end", async (c) => {
21004
+ app57.post("/wa-channel/turn-end", async (c) => {
20970
21005
  const body = await c.req.json().catch(() => null);
20971
21006
  const senderId = body?.senderId;
20972
21007
  const sessionId = body?.sessionId;
@@ -20997,7 +21032,7 @@ function createWaChannelRoutes(deps) {
20997
21032
  console.error(`[whatsapp-native] op=turn-end sessionId=${sid} replied=no delivered=fallback bytes=${bytes}`);
20998
21033
  return c.json({ ok: true, delivered: "fallback" });
20999
21034
  });
21000
- return app56;
21035
+ return app57;
21001
21036
  }
21002
21037
 
21003
21038
  // app/lib/whatsapp/gateway/wa-gateway.ts
@@ -21010,9 +21045,11 @@ var WaGateway = class {
21010
21045
  }
21011
21046
  hub = new InboundHub();
21012
21047
  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.
21048
+ // Per-sender document-delivery context, set on every inbound. Its presence is
21049
+ // the reply-only guard: a sender with no inbound has no context, so a file
21050
+ // reply to a cold recipient is refused. `accountId` is the Baileys socket
21051
+ // owner (reply transport); `maxyAccountId` (Task 1390) is the sender's
21052
+ // effective session account — the file-path validation scope.
21016
21053
  docContexts = /* @__PURE__ */ new Map();
21017
21054
  spawning = /* @__PURE__ */ new Set();
21018
21055
  seq = 0;
@@ -21067,7 +21104,7 @@ var WaGateway = class {
21067
21104
  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
21105
  const source = input.source ?? "user";
21069
21106
  this.replies.set(input.senderId, input.reply);
21070
- this.docContexts.set(input.senderId, { accountId: input.accountId });
21107
+ this.docContexts.set(input.senderId, { accountId: input.accountId, maxyAccountId: input.effectiveAccountId });
21071
21108
  this.hub.deliver(
21072
21109
  {
21073
21110
  senderId: input.senderId,
@@ -21110,7 +21147,7 @@ var WaGateway = class {
21110
21147
  async sendDocument(senderId, filePath, caption) {
21111
21148
  const ctx = this.docContexts.get(senderId);
21112
21149
  if (!ctx) throw new WaReplyError(`no conversation for sender ${senderId}`, false);
21113
- return this.deps.sendDocument({ senderId, accountId: ctx.accountId, filePath, caption });
21150
+ return this.deps.sendDocument({ senderId, accountId: ctx.accountId, maxyAccountId: ctx.maxyAccountId, filePath, caption });
21114
21151
  }
21115
21152
  };
21116
21153
 
@@ -21299,8 +21336,8 @@ var InboundHub2 = class {
21299
21336
 
21300
21337
  // app/lib/webchat/gateway/routes.ts
21301
21338
  function createWebchatChannelRoutes(deps) {
21302
- const app56 = new Hono();
21303
- app56.get("/webchat-channel/inbound", (c) => {
21339
+ const app57 = new Hono();
21340
+ app57.get("/webchat-channel/inbound", (c) => {
21304
21341
  const key = c.req.query("key");
21305
21342
  if (!key) return c.json({ error: "key required" }, 400);
21306
21343
  return streamSSE(c, async (stream2) => {
@@ -21318,7 +21355,7 @@ function createWebchatChannelRoutes(deps) {
21318
21355
  }
21319
21356
  });
21320
21357
  });
21321
- app56.post("/webchat-channel/reply", async (c) => {
21358
+ app57.post("/webchat-channel/reply", async (c) => {
21322
21359
  const body = await c.req.json().catch(() => null);
21323
21360
  const key = body?.key;
21324
21361
  const text = body?.text;
@@ -21328,7 +21365,7 @@ function createWebchatChannelRoutes(deps) {
21328
21365
  deps.onReply?.(key, text);
21329
21366
  return c.json({ ok: true });
21330
21367
  });
21331
- app56.post("/webchat-channel/connector-auth", async (c) => {
21368
+ app57.post("/webchat-channel/connector-auth", async (c) => {
21332
21369
  const body = await c.req.json().catch(() => null);
21333
21370
  const key = body?.key;
21334
21371
  const sessionId = body?.sessionId;
@@ -21341,7 +21378,7 @@ function createWebchatChannelRoutes(deps) {
21341
21378
  const result = await deps.onConnectorAuth({ key, sessionId, name, completed });
21342
21379
  return c.json(result);
21343
21380
  });
21344
- app56.post("/webchat-channel/ready", async (c) => {
21381
+ app57.post("/webchat-channel/ready", async (c) => {
21345
21382
  const body = await c.req.json().catch(() => null);
21346
21383
  const key = body?.key;
21347
21384
  if (typeof key !== "string") {
@@ -21350,7 +21387,7 @@ function createWebchatChannelRoutes(deps) {
21350
21387
  deps.onReady?.(key);
21351
21388
  return c.json({ ok: true });
21352
21389
  });
21353
- app56.post("/webchat-channel/permission-request", async (c) => {
21390
+ app57.post("/webchat-channel/permission-request", async (c) => {
21354
21391
  const body = await c.req.json().catch(() => null);
21355
21392
  const key = body?.key;
21356
21393
  const requestId = body?.request_id;
@@ -21364,7 +21401,7 @@ function createWebchatChannelRoutes(deps) {
21364
21401
  const verdict = await deps.awaitPermissionVerdict({ key, requestId, toolName, description, inputPreview });
21365
21402
  return c.json(verdict);
21366
21403
  });
21367
- app56.post("/webchat-channel/received", async (c) => {
21404
+ app57.post("/webchat-channel/received", async (c) => {
21368
21405
  const body = await c.req.json().catch(() => null);
21369
21406
  const key = body?.key;
21370
21407
  const messageId = body?.messageId;
@@ -21374,7 +21411,7 @@ function createWebchatChannelRoutes(deps) {
21374
21411
  deps.onReceived?.(key, messageId);
21375
21412
  return c.json({ ok: true });
21376
21413
  });
21377
- app56.post("/webchat-channel/turn-end", async (c) => {
21414
+ app57.post("/webchat-channel/turn-end", async (c) => {
21378
21415
  const body = await c.req.json().catch(() => null);
21379
21416
  const key = body?.key;
21380
21417
  const sessionId = body?.sessionId;
@@ -21394,7 +21431,7 @@ function createWebchatChannelRoutes(deps) {
21394
21431
  console.error(`[webchat-native] op=turn-undelivered channel=webchat key=${k} sessionId=${sid} bytes=${finalBytes}`);
21395
21432
  return c.json({ ok: true, delivered: "undelivered" });
21396
21433
  });
21397
- return app56;
21434
+ return app57;
21398
21435
  }
21399
21436
 
21400
21437
  // app/lib/webchat/gateway/webchat-gateway.ts
@@ -22023,17 +22060,8 @@ var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
22023
22060
  function platformRoot() {
22024
22061
  return process.env.MAXY_PLATFORM_ROOT || "";
22025
22062
  }
22026
- function makeWhatsAppSendFile(entry) {
22063
+ function makeWhatsAppSendFile(entry, maxyAccountId) {
22027
22064
  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
22065
  const result = await sendWhatsAppDocument({
22038
22066
  to: entry.senderId,
22039
22067
  filePath,
@@ -22049,12 +22077,12 @@ function makeWhatsAppSendFile(entry) {
22049
22077
  return { ok: false, error: result.error };
22050
22078
  };
22051
22079
  }
22052
- function makeWhatsAppFileDelivery(entry) {
22080
+ function makeWhatsAppFileDelivery(entry, maxyAccountId) {
22053
22081
  const shared = makeFileDelivery({
22054
22082
  entry,
22055
22083
  tag: TAG35,
22056
22084
  channel: "whatsapp",
22057
- sendFile: makeWhatsAppSendFile(entry)
22085
+ sendFile: makeWhatsAppSendFile(entry, maxyAccountId)
22058
22086
  });
22059
22087
  let turnStartedAt = null;
22060
22088
  let routeCalls = [];
@@ -22138,7 +22166,7 @@ function startNativeFileFollower(input) {
22138
22166
  return startFollower({
22139
22167
  entry,
22140
22168
  tag: "[whatsapp-adaptor]",
22141
- fileDelivery: makeWhatsAppFileDelivery(entry),
22169
+ fileDelivery: makeWhatsAppFileDelivery(entry, input.maxyAccountId),
22142
22170
  // A resumed session's JSONL already holds prior SendUserFile tool_uses;
22143
22171
  // suppress replay so historical files are not re-sent on attach.
22144
22172
  suppressResumeReplay: true,
@@ -22261,8 +22289,8 @@ var InboundHub3 = class {
22261
22289
 
22262
22290
  // app/lib/telegram/gateway/routes.ts
22263
22291
  function createTelegramChannelRoutes(deps) {
22264
- const app56 = new Hono();
22265
- app56.get("/tg-channel/inbound", (c) => {
22292
+ const app57 = new Hono();
22293
+ app57.get("/tg-channel/inbound", (c) => {
22266
22294
  const key = c.req.query("key");
22267
22295
  if (!key) return c.json({ error: "key required" }, 400);
22268
22296
  return streamSSE(c, async (stream2) => {
@@ -22280,7 +22308,7 @@ function createTelegramChannelRoutes(deps) {
22280
22308
  }
22281
22309
  });
22282
22310
  });
22283
- app56.post("/tg-channel/reply", async (c) => {
22311
+ app57.post("/tg-channel/reply", async (c) => {
22284
22312
  const body = await c.req.json().catch(() => null);
22285
22313
  const key = body?.key;
22286
22314
  const text = body?.text;
@@ -22296,7 +22324,7 @@ function createTelegramChannelRoutes(deps) {
22296
22324
  console.error(`[telegram-native] op=reply key=${key} bytes=${Buffer.byteLength(text, "utf8")}`);
22297
22325
  return c.json({ ok: true });
22298
22326
  });
22299
- app56.post("/tg-channel/ready", async (c) => {
22327
+ app57.post("/tg-channel/ready", async (c) => {
22300
22328
  const body = await c.req.json().catch(() => null);
22301
22329
  const key = body?.key;
22302
22330
  if (typeof key !== "string") {
@@ -22305,7 +22333,7 @@ function createTelegramChannelRoutes(deps) {
22305
22333
  deps.onReady?.(key);
22306
22334
  return c.json({ ok: true });
22307
22335
  });
22308
- app56.post("/tg-channel/received", async (c) => {
22336
+ app57.post("/tg-channel/received", async (c) => {
22309
22337
  const body = await c.req.json().catch(() => null);
22310
22338
  const key = body?.key;
22311
22339
  const messageId = body?.messageId;
@@ -22315,7 +22343,7 @@ function createTelegramChannelRoutes(deps) {
22315
22343
  deps.onReceived?.(key, messageId);
22316
22344
  return c.json({ ok: true });
22317
22345
  });
22318
- app56.post("/tg-channel/turn-end", async (c) => {
22346
+ app57.post("/tg-channel/turn-end", async (c) => {
22319
22347
  const body = await c.req.json().catch(() => null);
22320
22348
  const key = body?.key;
22321
22349
  const sessionId = body?.sessionId;
@@ -22340,7 +22368,7 @@ function createTelegramChannelRoutes(deps) {
22340
22368
  console.error(`[telegram-native] op=turn-fallback key=${key} sessionId=${sid} bytes=${Buffer.byteLength(finalText, "utf8")}`);
22341
22369
  return c.json({ ok: true, delivered: "fallback" });
22342
22370
  });
22343
- return app56;
22371
+ return app57;
22344
22372
  }
22345
22373
 
22346
22374
  // app/lib/telegram/gateway/telegram-gateway.ts
@@ -22469,7 +22497,7 @@ async function sendTelegramDocument(input) {
22469
22497
  resolvedPath = realpathSync7(filePath);
22470
22498
  const accountResolved = realpathSync7(accountDir);
22471
22499
  if (!resolvedPath.startsWith(accountResolved + "/")) {
22472
- console.error(`${TAG36} document REJECTED reason=outside_account_directory`);
22500
+ console.error(`${TAG36} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
22473
22501
  return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
22474
22502
  }
22475
22503
  } catch (err) {
@@ -22536,21 +22564,12 @@ function makeTelegramSendFile(entry) {
22536
22564
  console.error(`${TAG37} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
22537
22565
  return { ok: false, error: "no-reply-target" };
22538
22566
  }
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
22567
  const result = await sendTelegramDocument({
22549
22568
  botToken,
22550
22569
  chatId: Number(entry.replyTarget),
22551
22570
  filePath,
22552
22571
  caption,
22553
- maxyAccountId,
22572
+ maxyAccountId: entry.accountId,
22554
22573
  platformRoot: platformRoot2()
22555
22574
  });
22556
22575
  return result.ok ? { ok: true } : { ok: false, error: result.error };
@@ -23171,20 +23190,19 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
23171
23190
  function isPublicHost(host) {
23172
23191
  return host.startsWith("public.") || aliasDomains.has(host);
23173
23192
  }
23174
- var app55 = new Hono();
23193
+ var app56 = new Hono();
23175
23194
  var nativeFileFollowers = /* @__PURE__ */ new Map();
23176
23195
  var waGateway = new WaGateway({
23177
23196
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
23178
23197
  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
- }
23198
+ // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
23199
+ // path-validation scope) is the sender's effective SESSION account, resolved
23200
+ // once at the inbound gate and threaded here via the gateway's per-sender doc
23201
+ // context. For an account-manager that is the bound sub-account (where the
23202
+ // session's files live); using the house account (resolvePlatformAccountId)
23203
+ // rejected an in-account file as outside_account_directory. `accountId` stays
23204
+ // the house Baileys socket (the reply transport, two-account invariant).
23205
+ sendDocument: async ({ senderId, accountId, maxyAccountId, filePath, caption }) => {
23188
23206
  const result = await sendWhatsAppDocument({
23189
23207
  to: senderId,
23190
23208
  filePath,
@@ -23218,6 +23236,10 @@ var waGateway = new WaGateway({
23218
23236
  sessionId: req.sessionId,
23219
23237
  senderId,
23220
23238
  accountId,
23239
+ // Task 1390 — the file-path validation scope is the sender's effective
23240
+ // session account (the sub-account for an account-manager), not the house
23241
+ // socket account. accountId stays the getSocket key.
23242
+ maxyAccountId: effectiveAccountId,
23221
23243
  onClose: () => {
23222
23244
  if (nativeFileFollowers.get(senderId) === ac) nativeFileFollowers.delete(senderId);
23223
23245
  }
@@ -23225,7 +23247,7 @@ var waGateway = new WaGateway({
23225
23247
  nativeFileFollowers.set(senderId, ac);
23226
23248
  }
23227
23249
  });
23228
- app55.route("/", waGateway.routes());
23250
+ app56.route("/", waGateway.routes());
23229
23251
  waGateway.startSweeper();
23230
23252
  var webchatGateway = new WebchatGateway({
23231
23253
  gatewayUrl: webchatGatewayUrl(),
@@ -23308,7 +23330,7 @@ var webchatGateway = new WebchatGateway({
23308
23330
  firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
23309
23331
  });
23310
23332
  setWebchatGateway(webchatGateway);
23311
- app55.route("/", webchatGateway.routes());
23333
+ app56.route("/", webchatGateway.routes());
23312
23334
  webchatGateway.startSweeper();
23313
23335
  webchatGateway.startPublicReaper();
23314
23336
  var telegramFileFollowers = /* @__PURE__ */ new Map();
@@ -23341,7 +23363,7 @@ var telegramGateway = new TelegramGateway({
23341
23363
  }
23342
23364
  });
23343
23365
  setTelegramGateway(telegramGateway);
23344
- app55.route("/", telegramGateway.routes());
23366
+ app56.route("/", telegramGateway.routes());
23345
23367
  telegramGateway.startSweeper();
23346
23368
  var chatRoutes = createChatRoutes({
23347
23369
  handleInbound: (input) => webchatGateway.handleInbound(input),
@@ -23360,21 +23382,26 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
23360
23382
  const sent = await sendTelegramText(botToken, chatId, text);
23361
23383
  if (!sent.ok) throw new Error(sent.error ?? "telegram send failed");
23362
23384
  },
23363
- effectiveAccountFor: (accountId, accountDir, destination) => managedAccountFor(readAccountManagers(accountDir), destination) ?? accountId
23385
+ effectiveAccountFor: (accountId, accountDir, destination) => {
23386
+ const managedSub = managedAccountFor(readAccountManagers(accountDir), destination);
23387
+ if (managedSub === null) return accountId;
23388
+ if (!listValidAccounts().some((a) => a.accountId === managedSub)) return null;
23389
+ return managedSub;
23390
+ }
23364
23391
  });
23365
- app55.route("/api/channel/schedule-inject", scheduleInjectRoutes);
23366
- app55.use("*", clientIpMiddleware);
23392
+ app56.route("/api/channel/schedule-inject", scheduleInjectRoutes);
23393
+ app56.use("*", clientIpMiddleware);
23367
23394
  function allowsSameOriginFraming(path2) {
23368
23395
  return path2 === "/vnc-viewer.html" || path2.startsWith("/api/admin/attachment/") || path2.startsWith("/api/public-reader/attachment/") || path2 === "/api/admin/files/download";
23369
23396
  }
23370
- app55.use("*", async (c, next) => {
23397
+ app56.use("*", async (c, next) => {
23371
23398
  await next();
23372
23399
  c.header("X-Content-Type-Options", "nosniff");
23373
23400
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
23374
23401
  c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
23375
23402
  });
23376
23403
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
23377
- app55.use("*", async (c, next) => {
23404
+ app56.use("*", async (c, next) => {
23378
23405
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
23379
23406
  await next();
23380
23407
  return;
@@ -23392,7 +23419,7 @@ app55.use("*", async (c, next) => {
23392
23419
  });
23393
23420
  }
23394
23421
  });
23395
- app55.use("*", async (c, next) => {
23422
+ app56.use("*", async (c, next) => {
23396
23423
  const host = (c.req.header("host") ?? "").split(":")[0];
23397
23424
  if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
23398
23425
  await next();
@@ -23430,7 +23457,7 @@ function resolveRemoteAuthOpts(c) {
23430
23457
  return { ...brandLoginOpts, origin };
23431
23458
  }
23432
23459
  var MAX_LOGIN_BODY = 8 * 1024;
23433
- app55.post("/__remote-auth/login", async (c) => {
23460
+ app56.post("/__remote-auth/login", async (c) => {
23434
23461
  const client = clientFrom(c);
23435
23462
  const clientIp = client.ip || "unknown";
23436
23463
  if (!requestIsTlsTerminated(c)) {
@@ -23475,7 +23502,7 @@ app55.post("/__remote-auth/login", async (c) => {
23475
23502
  }
23476
23503
  });
23477
23504
  });
23478
- app55.get("/__remote-auth/logout", (c) => {
23505
+ app56.get("/__remote-auth/logout", (c) => {
23479
23506
  const client = clientFrom(c);
23480
23507
  const clientIp = client.ip || "unknown";
23481
23508
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -23488,7 +23515,7 @@ app55.get("/__remote-auth/logout", (c) => {
23488
23515
  }
23489
23516
  });
23490
23517
  });
23491
- app55.post("/__remote-auth/change-password", async (c) => {
23518
+ app56.post("/__remote-auth/change-password", async (c) => {
23492
23519
  const client = clientFrom(c);
23493
23520
  const clientIp = client.ip || "unknown";
23494
23521
  const rateLimited = checkRateLimit(client);
@@ -23547,13 +23574,13 @@ app55.post("/__remote-auth/change-password", async (c) => {
23547
23574
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
23548
23575
  }
23549
23576
  });
23550
- app55.get("/__remote-auth/setup", (c) => {
23577
+ app56.get("/__remote-auth/setup", (c) => {
23551
23578
  if (isRemoteAuthConfigured()) {
23552
23579
  return c.redirect("/");
23553
23580
  }
23554
23581
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
23555
23582
  });
23556
- app55.post("/__remote-auth/set-initial-password", async (c) => {
23583
+ app56.post("/__remote-auth/set-initial-password", async (c) => {
23557
23584
  if (isRemoteAuthConfigured()) {
23558
23585
  return c.redirect("/");
23559
23586
  }
@@ -23591,10 +23618,10 @@ app55.post("/__remote-auth/set-initial-password", async (c) => {
23591
23618
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
23592
23619
  }
23593
23620
  });
23594
- app55.get("/api/remote-auth/status", (c) => {
23621
+ app56.get("/api/remote-auth/status", (c) => {
23595
23622
  return c.json({ configured: isRemoteAuthConfigured() });
23596
23623
  });
23597
- app55.post("/api/remote-auth/set-password", async (c) => {
23624
+ app56.post("/api/remote-auth/set-password", async (c) => {
23598
23625
  let body;
23599
23626
  try {
23600
23627
  body = await c.req.json();
@@ -23633,10 +23660,10 @@ app55.post("/api/remote-auth/set-password", async (c) => {
23633
23660
  return c.json({ error: "Failed to save password" }, 500);
23634
23661
  }
23635
23662
  });
23636
- app55.route("/api/_client-error", client_error_default);
23663
+ app56.route("/api/_client-error", client_error_default);
23637
23664
  console.log("[client-error-route] mounted");
23638
23665
  var PWA_PUBLIC_PATHS = /* @__PURE__ */ new Set(["/sw.js", ...PWA_SURFACES.map((s) => s.manifestPath)]);
23639
- app55.use("*", async (c, next) => {
23666
+ app56.use("*", async (c, next) => {
23640
23667
  const host = (c.req.header("host") ?? "").split(":")[0];
23641
23668
  const path2 = c.req.path;
23642
23669
  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 +23707,26 @@ app55.use("*", async (c, next) => {
23680
23707
  }
23681
23708
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path2 }), 200);
23682
23709
  });
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({
23710
+ app56.route("/api/health", health_default);
23711
+ app56.route("/api/chat", chatRoutes);
23712
+ app56.route("/api/whatsapp", whatsapp_default);
23713
+ app56.route("/api/whatsapp-reader", whatsapp_reader_default);
23714
+ app56.route("/api/public-reader", public_reader_default);
23715
+ app56.route("/api/webchat", createWebchatRoutes({
23689
23716
  handleInbound: (input) => webchatGateway.handleInbound(input),
23690
23717
  // Task 940 — the permission relay's pointer read + verdict write.
23691
23718
  pendingPromptFor: (key) => webchatGateway.pendingPromptFor(key),
23692
23719
  deliveryFailureFor: (key) => webchatGateway.deliveryFailureFor(key),
23693
23720
  resolvePermissionVerdict: (key, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key, requestId, behavior)
23694
23721
  }));
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);
23722
+ app56.route("/api/webchat/greeting", webchat_greeting_default);
23723
+ app56.route("/api/telegram", telegram_default);
23724
+ app56.route("/api/quickbooks", quickbooks_default);
23725
+ app56.route("/api/onboarding", onboarding_default);
23726
+ app56.route("/api/admin", admin_default);
23727
+ app56.route("/api/access", access_default);
23728
+ app56.route("/api/session", session_default2);
23729
+ app56.route("/api/calendar", calendar_public_default);
23703
23730
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
23704
23731
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
23705
23732
  var IMAGE_MIME = {
@@ -23711,7 +23738,7 @@ var IMAGE_MIME = {
23711
23738
  ".svg": "image/svg+xml",
23712
23739
  ".ico": "image/x-icon"
23713
23740
  };
23714
- app55.get("/agent-assets/:slug/:filename", (c) => {
23741
+ app56.get("/agent-assets/:slug/:filename", (c) => {
23715
23742
  const slug = c.req.param("slug");
23716
23743
  const filename = c.req.param("filename");
23717
23744
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -23746,7 +23773,7 @@ app55.get("/agent-assets/:slug/:filename", (c) => {
23746
23773
  "Cache-Control": "public, max-age=3600"
23747
23774
  });
23748
23775
  });
23749
- app55.get("/generated/:filename", (c) => {
23776
+ app56.get("/generated/:filename", (c) => {
23750
23777
  const filename = c.req.param("filename");
23751
23778
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
23752
23779
  console.error(`[generated] serve file=${filename} status=403`);
@@ -23776,10 +23803,10 @@ app55.get("/generated/:filename", (c) => {
23776
23803
  "Cache-Control": "public, max-age=86400"
23777
23804
  });
23778
23805
  });
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);
23806
+ app56.route("/sites", sites_default);
23807
+ app56.route("/listings", listings_default);
23808
+ app56.route("/v", visitor_event_default);
23809
+ app56.route("/v", visitor_consent_default);
23783
23810
  var htmlCache = /* @__PURE__ */ new Map();
23784
23811
  var brandLogoPath = "/brand/maxy-monochrome.png";
23785
23812
  var brandIconPath = "/brand/maxy-monochrome.png";
@@ -23934,7 +23961,7 @@ function brandedPublicHtml(agentSlug) {
23934
23961
  function agentUnavailableHtml() {
23935
23962
  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
23963
  }
23937
- app55.get("/", (c) => {
23964
+ app56.get("/", (c) => {
23938
23965
  const host = (c.req.header("host") ?? "").split(":")[0];
23939
23966
  const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
23940
23967
  if (klass === "operator") {
@@ -23956,12 +23983,12 @@ app55.get("/", (c) => {
23956
23983
  console.log(`[host-class] host=${host} class=admin served=index.html`);
23957
23984
  return c.html(cachedHtml("index.html"));
23958
23985
  });
23959
- app55.get("/public", (c) => {
23986
+ app56.get("/public", (c) => {
23960
23987
  const host = (c.req.header("host") ?? "").split(":")[0];
23961
23988
  if (isPublicHost(host)) return c.text("Not found", 404);
23962
23989
  return c.html(cachedHtml("public.html"));
23963
23990
  });
23964
- app55.get("/public-chat", (c) => {
23991
+ app56.get("/public-chat", (c) => {
23965
23992
  const host = (c.req.header("host") ?? "").split(":")[0];
23966
23993
  if (isPublicHost(host)) return c.text("Not found", 404);
23967
23994
  return c.html(cachedHtml("public.html"));
@@ -23980,9 +24007,9 @@ async function logViewerFetch(c, next) {
23980
24007
  duration_ms: Date.now() - start
23981
24008
  });
23982
24009
  }
23983
- app55.use("/vnc-viewer.html", logViewerFetch);
23984
- app55.use("/vnc-popout.html", logViewerFetch);
23985
- app55.get("/vnc-popout.html", (c) => {
24010
+ app56.use("/vnc-viewer.html", logViewerFetch);
24011
+ app56.use("/vnc-popout.html", logViewerFetch);
24012
+ app56.get("/vnc-popout.html", (c) => {
23986
24013
  let html = htmlCache.get("vnc-popout.html");
23987
24014
  if (!html) {
23988
24015
  html = readFileSync35(resolve33(process.cwd(), "public", "vnc-popout.html"), "utf-8");
@@ -23995,7 +24022,7 @@ app55.get("/vnc-popout.html", (c) => {
23995
24022
  }
23996
24023
  return c.html(html);
23997
24024
  });
23998
- app55.post("/api/vnc/client-event", async (c) => {
24025
+ app56.post("/api/vnc/client-event", async (c) => {
23999
24026
  let body;
24000
24027
  try {
24001
24028
  body = await c.req.json();
@@ -24016,11 +24043,11 @@ app55.post("/api/vnc/client-event", async (c) => {
24016
24043
  });
24017
24044
  return c.json({ ok: true });
24018
24045
  });
24019
- app55.get("/g/:slug", (c) => {
24046
+ app56.get("/g/:slug", (c) => {
24020
24047
  return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
24021
24048
  });
24022
24049
  for (const pwa of PWA_SURFACES) {
24023
- app55.get(pwa.manifestPath, (c) => {
24050
+ app56.get(pwa.manifestPath, (c) => {
24024
24051
  const manifest = buildManifest(pwa, {
24025
24052
  productName: BRAND.productName,
24026
24053
  appIcon192: brandAppIcon192Path,
@@ -24036,7 +24063,7 @@ for (const pwa of PWA_SURFACES) {
24036
24063
  return c.body(JSON.stringify(manifest));
24037
24064
  });
24038
24065
  }
24039
- app55.get("/sw.js", (c) => {
24066
+ app56.get("/sw.js", (c) => {
24040
24067
  if (SW_SOURCE == null) {
24041
24068
  console.error("[pwa] op=sw status=500 reason=sw-source-missing");
24042
24069
  return c.text("Service worker unavailable", 500);
@@ -24045,12 +24072,12 @@ app55.get("/sw.js", (c) => {
24045
24072
  console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
24046
24073
  return c.body(SW_SOURCE);
24047
24074
  });
24048
- app55.get("/graph", (c) => {
24075
+ app56.get("/graph", (c) => {
24049
24076
  const host = (c.req.header("host") ?? "").split(":")[0];
24050
24077
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
24051
24078
  return c.html(cachedHtml("graph.html"));
24052
24079
  });
24053
- app55.get("/chat", (c) => {
24080
+ app56.get("/chat", (c) => {
24054
24081
  const host = (c.req.header("host") ?? "").split(":")[0];
24055
24082
  if (isOperatorHost(host, getOperatorDomains())) {
24056
24083
  console.log(`[host-class] host=${host} class=operator served=operator.html`);
@@ -24059,22 +24086,22 @@ app55.get("/chat", (c) => {
24059
24086
  if (isPublicHost(host)) return c.text("Not found", 404);
24060
24087
  return c.html(cachedHtml("chat.html"));
24061
24088
  });
24062
- app55.get("/data", (c) => {
24089
+ app56.get("/data", (c) => {
24063
24090
  const host = (c.req.header("host") ?? "").split(":")[0];
24064
24091
  if (isPublicHost(host)) return c.text("Not found", 404);
24065
24092
  return c.html(cachedHtml("data.html"));
24066
24093
  });
24067
- app55.get("/calendar", (c) => {
24094
+ app56.get("/calendar", (c) => {
24068
24095
  const host = (c.req.header("host") ?? "").split(":")[0];
24069
24096
  if (isPublicHost(host)) return c.text("Not found", 404);
24070
24097
  return c.html(cachedHtml("calendar.html"));
24071
24098
  });
24072
- app55.get("/browser", (c) => {
24099
+ app56.get("/browser", (c) => {
24073
24100
  const host = (c.req.header("host") ?? "").split(":")[0];
24074
24101
  if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
24075
24102
  return c.html(cachedHtml("browser.html"));
24076
24103
  });
24077
- app55.get("/:slug", async (c, next) => {
24104
+ app56.get("/:slug", async (c, next) => {
24078
24105
  const slug = c.req.param("slug");
24079
24106
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
24080
24107
  const account = resolveAccount();
@@ -24089,13 +24116,13 @@ app55.get("/:slug", async (c, next) => {
24089
24116
  await next();
24090
24117
  });
24091
24118
  if (brandFaviconPath !== "/favicon.ico") {
24092
- app55.get("/favicon.ico", (c) => {
24119
+ app56.get("/favicon.ico", (c) => {
24093
24120
  c.header("Cache-Control", "public, max-age=300");
24094
24121
  return c.redirect(brandFaviconPath, 302);
24095
24122
  });
24096
24123
  }
24097
- app55.use("/*", serveStatic({ root: "./public" }));
24098
- app55.all("*", (c) => {
24124
+ app56.use("/*", serveStatic({ root: "./public" }));
24125
+ app56.all("*", (c) => {
24099
24126
  const host = (c.req.header("host") ?? "").split(":")[0];
24100
24127
  const path2 = c.req.path;
24101
24128
  if (isPublicHost(host)) {
@@ -24109,7 +24136,7 @@ app55.all("*", (c) => {
24109
24136
  });
24110
24137
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
24111
24138
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
24112
- var httpServer = serve({ fetch: app55.fetch, port, hostname });
24139
+ var httpServer = serve({ fetch: app56.fetch, port, hostname });
24113
24140
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
24114
24141
  {
24115
24142
  const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join34(__dirname, "..");
@@ -24209,7 +24236,7 @@ for (const m of SUBAPP_MANIFEST) {
24209
24236
  }
24210
24237
  try {
24211
24238
  const registered = [];
24212
- for (const r of app55.routes ?? []) {
24239
+ for (const r of app56.routes ?? []) {
24213
24240
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
24214
24241
  if (AGENT_SLUG_PATTERN.test(r.path)) {
24215
24242
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });