@rubytech/create-maxy-code 0.1.246 → 0.1.247

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 (41) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  3. package/payload/platform/plugins/admin/PLUGIN.md +4 -1
  4. package/payload/platform/plugins/admin/hooks/__tests__/pin-identity-gate.test.sh +96 -0
  5. package/payload/platform/plugins/admin/hooks/pin-identity-gate.sh +136 -0
  6. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.d.ts +2 -0
  7. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.d.ts.map +1 -0
  8. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.js +34 -0
  9. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.js.map +1 -0
  10. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.d.ts +2 -0
  11. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.d.ts.map +1 -0
  12. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.js +50 -0
  13. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.js.map +1 -0
  14. package/payload/platform/plugins/admin/mcp/dist/index.js +8 -0
  15. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  16. package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.d.ts +6 -0
  17. package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.d.ts.map +1 -0
  18. package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.js +32 -0
  19. package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.js.map +1 -0
  20. package/payload/platform/plugins/admin/skills/investigate/SKILL.md +34 -17
  21. package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +9 -4
  22. package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +5 -0
  23. package/payload/platform/plugins/admin/skills/unzip-attachment/SKILL.md +5 -0
  24. package/payload/platform/plugins/admin/skills/update-knowledge/SKILL.md +5 -0
  25. package/payload/platform/plugins/docs/references/admin-identity-gate.md +81 -0
  26. package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +1 -0
  27. package/payload/platform/plugins/memory/skills/conversational-memory/SKILL.md +5 -0
  28. package/payload/platform/plugins/workflows/skills/workflow-manager/SKILL.md +5 -0
  29. package/payload/platform/scripts/check-skill-frontmatter.mjs +139 -0
  30. package/payload/platform/scripts/setup-account.sh +5 -0
  31. package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.d.ts +39 -0
  32. package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.d.ts.map +1 -0
  33. package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.js +133 -0
  34. package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.js.map +1 -0
  35. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  36. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  37. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  38. package/payload/platform/services/claude-session-manager/dist/index.js +17 -0
  39. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  40. package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
  41. package/payload/server/server.js +260 -152
@@ -600,6 +600,46 @@ var require_dist2 = __commonJS({
600
600
  }
601
601
  });
602
602
 
603
+ // ../lib/require-port-env/dist/index.js
604
+ var require_dist3 = __commonJS({
605
+ "../lib/require-port-env/dist/index.js"(exports) {
606
+ "use strict";
607
+ Object.defineProperty(exports, "__esModule", { value: true });
608
+ exports.MissingPortEnvError = void 0;
609
+ exports.requirePortEnv = requirePortEnv3;
610
+ var MissingPortEnvError = class extends Error {
611
+ envName;
612
+ tag;
613
+ failLine;
614
+ constructor(envName, tag, failLine, message) {
615
+ super(message);
616
+ this.name = "MissingPortEnvError";
617
+ this.envName = envName;
618
+ this.tag = tag;
619
+ this.failLine = failLine;
620
+ }
621
+ };
622
+ exports.MissingPortEnvError = MissingPortEnvError;
623
+ var VALID_PORT_MIN = 1;
624
+ var VALID_PORT_MAX = 65535;
625
+ function requirePortEnv3(envName, options = {}) {
626
+ const tag = options.tag ?? "port-env";
627
+ const failLine = options.failLine ?? "missing-port-env";
628
+ const raw = process.env[envName];
629
+ if (raw === void 0 || raw === "") {
630
+ const msg = `[${tag}] ${failLine} reason=missing-env env=${envName}`;
631
+ throw new MissingPortEnvError(envName, tag, failLine, msg);
632
+ }
633
+ const parsed = Number.parseInt(raw, 10);
634
+ if (!Number.isInteger(parsed) || parsed < VALID_PORT_MIN || parsed > VALID_PORT_MAX || String(parsed) !== raw.trim()) {
635
+ const msg = `[${tag}] ${failLine} reason=invalid-port-env env=${envName} value=${JSON.stringify(raw)}`;
636
+ throw new MissingPortEnvError(envName, tag, failLine, msg);
637
+ }
638
+ return parsed;
639
+ }
640
+ }
641
+ });
642
+
603
643
  // node_modules/hono/dist/utils/mime.js
604
644
  var getMimeType = (filename, mimes = baseMimes) => {
605
645
  const regexp = /\.([a-zA-Z0-9]+?)$/;
@@ -6662,32 +6702,46 @@ app5.post("/", async (c) => {
6662
6702
  var client_error_default = app5;
6663
6703
 
6664
6704
  // server/routes/admin/session.ts
6665
- import { readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync4, existsSync as existsSync8 } from "fs";
6666
- import { join as join8 } from "path";
6667
- import { createHash as createHash2 } from "crypto";
6668
6705
  import { randomUUID as randomUUID7 } from "crypto";
6706
+
6707
+ // app/lib/admin-identity/pin-validator.ts
6708
+ import { createHash as createHash2 } from "crypto";
6709
+ import { existsSync as existsSync8, readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
6710
+ import { join as join8 } from "path";
6669
6711
  function hashPin2(pin) {
6670
6712
  return createHash2("sha256").update(pin).digest("hex");
6671
6713
  }
6672
- function readUsersFile2() {
6673
- if (!existsSync8(USERS_FILE)) return null;
6674
- const raw = readFileSync9(USERS_FILE, "utf-8").trim();
6714
+ function readUsersFile2(usersFilePath) {
6715
+ if (!existsSync8(usersFilePath)) return null;
6716
+ const raw = readFileSync9(usersFilePath, "utf-8").trim();
6675
6717
  if (!raw) return [];
6676
6718
  return JSON.parse(raw);
6677
6719
  }
6678
- function scanForOrphanedAccountAdmins(users) {
6679
- const usersUserIds = new Set(users.map((u) => u.userId));
6720
+ function validatePin(pin, usersFilePath) {
6721
+ let users;
6722
+ try {
6723
+ users = readUsersFile2(usersFilePath);
6724
+ } catch (err) {
6725
+ return { kind: "corrupt", message: err instanceof Error ? err.message : String(err) };
6726
+ }
6727
+ if (users === null || users.length === 0) return { kind: "unavailable" };
6728
+ const inputHash = hashPin2(pin);
6729
+ const matched = users.find((u) => u.pin === inputHash);
6730
+ return matched ? { kind: "match", userId: matched.userId } : { kind: "miss" };
6731
+ }
6732
+ function scanForOrphanedAccountAdmins(users, accountsDir) {
6733
+ const known = new Set(users.map((u) => u.userId));
6680
6734
  const orphans = [];
6681
- if (!existsSync8(ACCOUNTS_DIR)) return orphans;
6735
+ if (!existsSync8(accountsDir)) return orphans;
6682
6736
  let entries;
6683
6737
  try {
6684
- entries = readdirSync4(ACCOUNTS_DIR);
6738
+ entries = readdirSync4(accountsDir);
6685
6739
  } catch {
6686
6740
  return orphans;
6687
6741
  }
6688
6742
  for (const entry of entries) {
6689
6743
  if (entry.startsWith(".")) continue;
6690
- const accountDir = join8(ACCOUNTS_DIR, entry);
6744
+ const accountDir = join8(accountsDir, entry);
6691
6745
  try {
6692
6746
  if (!statSync4(accountDir).isDirectory()) continue;
6693
6747
  } catch {
@@ -6699,9 +6753,7 @@ function scanForOrphanedAccountAdmins(users) {
6699
6753
  const config = JSON.parse(readFileSync9(accountJsonPath, "utf-8"));
6700
6754
  const admins = config.admins ?? [];
6701
6755
  for (const a of admins) {
6702
- if (typeof a.userId === "string" && !usersUserIds.has(a.userId)) {
6703
- orphans.push(a.userId);
6704
- }
6756
+ if (typeof a.userId === "string" && !known.has(a.userId)) orphans.push(a.userId);
6705
6757
  }
6706
6758
  } catch {
6707
6759
  continue;
@@ -6709,6 +6761,8 @@ function scanForOrphanedAccountAdmins(users) {
6709
6761
  }
6710
6762
  return orphans;
6711
6763
  }
6764
+
6765
+ // server/routes/admin/session.ts
6712
6766
  async function resolveUserIdentity(accountId, userId) {
6713
6767
  const result = await loadAdminUserName(accountId, userId);
6714
6768
  if (result.source === "neo4j") {
@@ -6818,20 +6872,21 @@ app6.post("/", async (c) => {
6818
6872
  return c.json({ error: "Invalid request" }, 400);
6819
6873
  }
6820
6874
  if (!body.pin) return c.json({ error: "Invalid request" }, 400);
6821
- const inputHash = hashPin2(body.pin);
6822
- let users = null;
6823
- try {
6824
- users = readUsersFile2();
6825
- } catch (err) {
6826
- console.error(`[session] users.json corrupt: ${err instanceof Error ? err.message : String(err)}`);
6875
+ const verdict = validatePin(body.pin, USERS_FILE);
6876
+ if (verdict.kind === "corrupt") {
6877
+ console.error(`[session] users.json corrupt: ${verdict.message}`);
6827
6878
  return c.json({ error: "User configuration is corrupt. Re-run the seed script." }, 503);
6828
6879
  }
6829
- if (users === null || users.length === 0) {
6880
+ if (verdict.kind === "unavailable") {
6830
6881
  return c.json({ error: "PIN not configured. Complete onboarding first." }, 503);
6831
6882
  }
6832
- const matchedUser = users.find((u) => u.pin === inputHash);
6833
- if (!matchedUser) {
6834
- const orphanUserIds = scanForOrphanedAccountAdmins(users);
6883
+ if (verdict.kind === "miss") {
6884
+ let users = [];
6885
+ try {
6886
+ users = readUsersFile2(USERS_FILE) ?? [];
6887
+ } catch {
6888
+ }
6889
+ const orphanUserIds = scanForOrphanedAccountAdmins(users, ACCOUNTS_DIR);
6835
6890
  if (orphanUserIds.length > 0) {
6836
6891
  const prefix = orphanUserIds[0].slice(0, 8);
6837
6892
  console.log(
@@ -6842,7 +6897,7 @@ app6.post("/", async (c) => {
6842
6897
  }
6843
6898
  return c.json({ error: "Invalid PIN" }, 401);
6844
6899
  }
6845
- const { userId } = matchedUser;
6900
+ const { userId } = verdict;
6846
6901
  const accounts = resolveUserAccounts(userId);
6847
6902
  if (accounts.length === 0) {
6848
6903
  console.log(`[session] user has no accounts: userId=${userId}`);
@@ -7551,11 +7606,11 @@ app11.delete("/:id", requireAdminSession, async (c) => {
7551
7606
  const owned = await verifyConversationOwnership(sessionId, accountId);
7552
7607
  if (!owned) return c.json({ error: "Conversation not found" }, 404);
7553
7608
  const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-conversation-delete" });
7554
- const managerBase5 = `http://127.0.0.1:${managerPort}`;
7609
+ const managerBase6 = `http://127.0.0.1:${managerPort}`;
7555
7610
  const outcome = await cascadeAdminConversationDelete({
7556
7611
  sessionId,
7557
7612
  accountId,
7558
- managerBase: managerBase5
7613
+ managerBase: managerBase6
7559
7614
  });
7560
7615
  if (outcome.ok) return c.json({ ok: true, claudeSessionIds: outcome.claudeSessionIds });
7561
7616
  if (outcome.reason === "pty-still-alive") {
@@ -8437,18 +8492,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
8437
8492
  ]);
8438
8493
  var app14 = new Hono();
8439
8494
  app14.post("/", async (c) => {
8440
- const TAG28 = "[admin:events]";
8495
+ const TAG29 = "[admin:events]";
8441
8496
  let body;
8442
8497
  try {
8443
8498
  body = await c.req.json();
8444
8499
  } catch (err) {
8445
8500
  const detail = err instanceof Error ? err.message : String(err);
8446
- console.error(`${TAG28} reject reason=body-not-json detail=${detail}`);
8501
+ console.error(`${TAG29} reject reason=body-not-json detail=${detail}`);
8447
8502
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
8448
8503
  }
8449
8504
  const event = typeof body.event === "string" ? body.event : "";
8450
8505
  if (!ALLOWED_EVENTS.has(event)) {
8451
- console.error(`${TAG28} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
8506
+ console.error(`${TAG29} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
8452
8507
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
8453
8508
  }
8454
8509
  const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
@@ -11259,7 +11314,7 @@ app18.post("/", requireAdminSession, async (c) => {
11259
11314
  return c.json({ error: "AdminConversation node is missing sessionId" }, 500);
11260
11315
  }
11261
11316
  const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "graph-page-cascade" });
11262
- const managerBase5 = `http://127.0.0.1:${managerPort}`;
11317
+ const managerBase6 = `http://127.0.0.1:${managerPort}`;
11263
11318
  try {
11264
11319
  await session.close();
11265
11320
  } catch {
@@ -11267,7 +11322,7 @@ app18.post("/", requireAdminSession, async (c) => {
11267
11322
  const outcome = await cascadeAdminConversationDelete({
11268
11323
  sessionId,
11269
11324
  accountId,
11270
- managerBase: managerBase5
11325
+ managerBase: managerBase6
11271
11326
  });
11272
11327
  const elapsed2 = Date.now() - started;
11273
11328
  const labelSummary2 = preflightLabels.join(",");
@@ -12899,36 +12954,89 @@ app32.post("/", async (c) => {
12899
12954
  });
12900
12955
  var access_session_evict_default = app32;
12901
12956
 
12902
- // server/routes/admin/index.ts
12957
+ // server/routes/admin/identity.ts
12958
+ var import_dist4 = __toESM(require_dist3(), 1);
12903
12959
  var app33 = new Hono();
12904
- app33.route("/session", session_default);
12905
- app33.route("/logs", logs_default);
12906
- app33.route("/claude-info", claude_info_default);
12907
- app33.route("/attachment", attachment_default);
12908
- app33.route("/agents", agents_default);
12909
- app33.route("/sessions", sessions_default);
12910
- app33.route("/claude-sessions", claude_sessions_default);
12911
- app33.route("/log-ingest", log_ingest_default);
12912
- app33.route("/events", events_default);
12913
- app33.route("/files", files_default);
12914
- app33.route("/graph-search", graph_search_default);
12915
- app33.route("/graph-subgraph", graph_subgraph_default);
12916
- app33.route("/graph-delete", graph_delete_default);
12917
- app33.route("/graph-restore", graph_restore_default);
12918
- app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12919
- app33.route("/graph-default-view", graph_default_view_default);
12920
- app33.route("/sidebar-artefacts", sidebar_artefacts_default);
12921
- app33.route("/sidebar-sessions", sidebar_sessions_default);
12922
- app33.route("/session-delete", session_delete_default);
12923
- app33.route("/session-rc-spawn", session_rc_spawn_default);
12924
- app33.route("/system-stats", system_stats_default);
12925
- app33.route("/health-brand", health_default2);
12926
- app33.route("/linkedin-ingest", linkedin_ingest_default);
12927
- app33.route("/post-turn-context", post_turn_context_default);
12928
- app33.route("/public-session-context", public_session_context_default);
12929
- app33.route("/public-session-exit", public_session_exit_default);
12930
- app33.route("/access-session-evict", access_session_evict_default);
12931
- var admin_default = app33;
12960
+ var TAG25 = "[admin-identity]";
12961
+ function managerBase5() {
12962
+ const port2 = (0, import_dist4.requirePortEnv)("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-identity" });
12963
+ return `http://127.0.0.1:${port2}`;
12964
+ }
12965
+ app33.post("/validate", async (c) => {
12966
+ const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12967
+ const isLoopback = remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1";
12968
+ if (!isLoopback || c.req.header("x-forwarded-for")) {
12969
+ return c.json({ error: "forbidden" }, 403);
12970
+ }
12971
+ let body;
12972
+ try {
12973
+ body = await c.req.json();
12974
+ } catch {
12975
+ return c.json({ error: "bad-request" }, 400);
12976
+ }
12977
+ const pin = typeof body.pin === "string" ? body.pin : "";
12978
+ const sessionId = typeof body.sessionId === "string" ? body.sessionId : void 0;
12979
+ if (!pin) return c.json({ error: "bad-request" }, 400);
12980
+ const fireStop = () => {
12981
+ if (sessionId) {
12982
+ void fetch(`${managerBase5()}/${encodeURIComponent(sessionId)}/stop`, { method: "POST" }).catch(
12983
+ () => {
12984
+ }
12985
+ );
12986
+ }
12987
+ };
12988
+ const verdict = validatePin(pin, USERS_FILE);
12989
+ if (verdict.kind !== "match") {
12990
+ if (verdict.kind === "miss") fireStop();
12991
+ console.log(`${TAG25} op=endpoint-validate result=${verdict.kind}${sessionId ? ` sessionId=${sessionId.slice(0, 8)}` : ""}`);
12992
+ return c.json({ kind: verdict.kind });
12993
+ }
12994
+ const { userId } = verdict;
12995
+ const accounts = resolveUserAccounts(userId);
12996
+ if (accounts.length === 0) {
12997
+ fireStop();
12998
+ console.log(`${TAG25} op=endpoint-validate result=no-account userId=${userId.slice(0, 8)}`);
12999
+ return c.json({ kind: "miss" });
13000
+ }
13001
+ const accountId = accounts[0].accountId;
13002
+ const { userName } = await resolveUserIdentity(accountId, userId);
13003
+ const aboutOwner = await resolveOwnerProfileBlock(accountId, userId);
13004
+ console.log(`${TAG25} op=endpoint-validate result=match userId=${userId.slice(0, 8)} aboutOwner=${aboutOwner.ok ? "ok" : `unresolved:${aboutOwner.reason}`}`);
13005
+ return c.json({ kind: "match", userId, userName, aboutOwner });
13006
+ });
13007
+ var identity_default = app33;
13008
+
13009
+ // server/routes/admin/index.ts
13010
+ var app34 = new Hono();
13011
+ app34.route("/session", session_default);
13012
+ app34.route("/identity", identity_default);
13013
+ app34.route("/logs", logs_default);
13014
+ app34.route("/claude-info", claude_info_default);
13015
+ app34.route("/attachment", attachment_default);
13016
+ app34.route("/agents", agents_default);
13017
+ app34.route("/sessions", sessions_default);
13018
+ app34.route("/claude-sessions", claude_sessions_default);
13019
+ app34.route("/log-ingest", log_ingest_default);
13020
+ app34.route("/events", events_default);
13021
+ app34.route("/files", files_default);
13022
+ app34.route("/graph-search", graph_search_default);
13023
+ app34.route("/graph-subgraph", graph_subgraph_default);
13024
+ app34.route("/graph-delete", graph_delete_default);
13025
+ app34.route("/graph-restore", graph_restore_default);
13026
+ app34.route("/graph-labels-in-graph", graph_labels_in_graph_default);
13027
+ app34.route("/graph-default-view", graph_default_view_default);
13028
+ app34.route("/sidebar-artefacts", sidebar_artefacts_default);
13029
+ app34.route("/sidebar-sessions", sidebar_sessions_default);
13030
+ app34.route("/session-delete", session_delete_default);
13031
+ app34.route("/session-rc-spawn", session_rc_spawn_default);
13032
+ app34.route("/system-stats", system_stats_default);
13033
+ app34.route("/health-brand", health_default2);
13034
+ app34.route("/linkedin-ingest", linkedin_ingest_default);
13035
+ app34.route("/post-turn-context", post_turn_context_default);
13036
+ app34.route("/public-session-context", public_session_context_default);
13037
+ app34.route("/public-session-exit", public_session_exit_default);
13038
+ app34.route("/access-session-evict", access_session_evict_default);
13039
+ var admin_default = app34;
12932
13040
 
12933
13041
  // app/lib/access-gate.ts
12934
13042
  import neo4j4 from "neo4j-driver";
@@ -13139,11 +13247,11 @@ async function generateNewMagicToken(grantId) {
13139
13247
  }
13140
13248
 
13141
13249
  // server/routes/access/verify-token.ts
13142
- var TAG25 = "[access-verify]";
13250
+ var TAG26 = "[access-verify]";
13143
13251
  var MINT_TAG = "[access-session-mint]";
13144
13252
  var COOKIE_NAME = "__access_session";
13145
- var app34 = new Hono();
13146
- app34.post("/", async (c) => {
13253
+ var app35 = new Hono();
13254
+ app35.post("/", async (c) => {
13147
13255
  const ip = c.var.clientIp || "unknown";
13148
13256
  let body;
13149
13257
  try {
@@ -13158,39 +13266,39 @@ app34.post("/", async (c) => {
13158
13266
  }
13159
13267
  const rateMsg = checkAccessRateLimit(ip, agentSlug);
13160
13268
  if (rateMsg) {
13161
- console.error(`${TAG25} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
13269
+ console.error(`${TAG26} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
13162
13270
  return c.json({ error: rateMsg }, 429);
13163
13271
  }
13164
13272
  const grant = await findGrantByMagicToken(token);
13165
13273
  if (!grant) {
13166
13274
  recordAccessFailedAttempt(ip, agentSlug);
13167
- console.error(`${TAG25} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
13275
+ console.error(`${TAG26} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
13168
13276
  return c.json({ error: "invalid-or-expired-link" }, 401);
13169
13277
  }
13170
13278
  if (grant.agentSlug !== agentSlug) {
13171
13279
  recordAccessFailedAttempt(ip, agentSlug);
13172
13280
  console.error(
13173
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
13281
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
13174
13282
  );
13175
13283
  return c.json({ error: "invalid-or-expired-link" }, 401);
13176
13284
  }
13177
13285
  if (grant.status === "expired" || grant.status === "revoked") {
13178
13286
  recordAccessFailedAttempt(ip, agentSlug);
13179
13287
  console.error(
13180
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
13288
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
13181
13289
  );
13182
13290
  return c.json({ error: "access-no-longer-valid" }, 401);
13183
13291
  }
13184
13292
  if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
13185
13293
  recordAccessFailedAttempt(ip, agentSlug);
13186
13294
  console.error(
13187
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
13295
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
13188
13296
  );
13189
13297
  return c.json({ error: "access-no-longer-valid" }, 401);
13190
13298
  }
13191
13299
  if (!grant.sliceToken) {
13192
13300
  console.error(
13193
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
13301
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
13194
13302
  );
13195
13303
  return c.json({ error: "grant-misconfigured" }, 500);
13196
13304
  }
@@ -13206,12 +13314,12 @@ app34.post("/", async (c) => {
13206
13314
  await consumeMagicTokenAndActivate(grant.grantId);
13207
13315
  } catch (err) {
13208
13316
  console.error(
13209
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
13317
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
13210
13318
  );
13211
13319
  return c.json({ error: "verification-failed" }, 500);
13212
13320
  }
13213
13321
  clearAccessRateLimit(ip, agentSlug);
13214
- console.log(`${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
13322
+ console.log(`${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
13215
13323
  console.log(
13216
13324
  `${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
13217
13325
  );
@@ -13225,7 +13333,7 @@ app34.post("/", async (c) => {
13225
13333
  displayName: grant.displayName
13226
13334
  });
13227
13335
  });
13228
- var verify_token_default = app34;
13336
+ var verify_token_default = app35;
13229
13337
 
13230
13338
  // app/lib/access-email.ts
13231
13339
  import { spawn as spawn2 } from "child_process";
@@ -13287,10 +13395,10 @@ async function sendMagicLinkEmail(payload) {
13287
13395
  }
13288
13396
 
13289
13397
  // server/routes/access/request-magic-link.ts
13290
- var TAG26 = "[access-request-link]";
13291
- var app35 = new Hono();
13398
+ var TAG27 = "[access-request-link]";
13399
+ var app36 = new Hono();
13292
13400
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
13293
- app35.post("/", async (c) => {
13401
+ app36.post("/", async (c) => {
13294
13402
  let body;
13295
13403
  try {
13296
13404
  body = await c.req.json();
@@ -13304,18 +13412,18 @@ app35.post("/", async (c) => {
13304
13412
  }
13305
13413
  const rateMsg = checkRequestLinkRateLimit(contactValue);
13306
13414
  if (rateMsg) {
13307
- console.error(`${TAG26} contactValue=${maskContact(contactValue)} result=rate-limited`);
13415
+ console.error(`${TAG27} contactValue=${maskContact(contactValue)} result=rate-limited`);
13308
13416
  return c.json({ error: rateMsg }, 429);
13309
13417
  }
13310
13418
  recordRequestLinkAttempt(contactValue);
13311
13419
  const accountId = process.env.ACCOUNT_ID ?? "";
13312
13420
  if (!accountId) {
13313
- console.error(`${TAG26} contactValue=${maskContact(contactValue)} result=no-account-id`);
13421
+ console.error(`${TAG27} contactValue=${maskContact(contactValue)} result=no-account-id`);
13314
13422
  return c.json({ message: VISITOR_MESSAGE }, 200);
13315
13423
  }
13316
13424
  const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
13317
13425
  if (!grant) {
13318
- console.log(`${TAG26} contactValue=${maskContact(contactValue)} result=notfound`);
13426
+ console.log(`${TAG27} contactValue=${maskContact(contactValue)} result=notfound`);
13319
13427
  return c.json({ message: VISITOR_MESSAGE }, 200);
13320
13428
  }
13321
13429
  let token;
@@ -13323,7 +13431,7 @@ app35.post("/", async (c) => {
13323
13431
  token = await generateNewMagicToken(grant.grantId);
13324
13432
  } catch (err) {
13325
13433
  console.error(
13326
- `${TAG26} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
13434
+ `${TAG27} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
13327
13435
  );
13328
13436
  return c.json({ message: VISITOR_MESSAGE }, 200);
13329
13437
  }
@@ -13355,22 +13463,22 @@ app35.post("/", async (c) => {
13355
13463
  });
13356
13464
  if (!sendResult.ok) {
13357
13465
  console.error(
13358
- `${TAG26} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
13466
+ `${TAG27} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
13359
13467
  );
13360
13468
  return c.json({ message: VISITOR_MESSAGE }, 200);
13361
13469
  }
13362
13470
  console.log(
13363
- `${TAG26} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
13471
+ `${TAG27} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
13364
13472
  );
13365
13473
  return c.json({ message: VISITOR_MESSAGE }, 200);
13366
13474
  });
13367
- var request_magic_link_default = app35;
13475
+ var request_magic_link_default = app36;
13368
13476
 
13369
13477
  // server/routes/access/index.ts
13370
- var app36 = new Hono();
13371
- app36.route("/verify-token", verify_token_default);
13372
- app36.route("/request-magic-link", request_magic_link_default);
13373
- var access_default = app36;
13478
+ var app37 = new Hono();
13479
+ app37.route("/verify-token", verify_token_default);
13480
+ app37.route("/request-magic-link", request_magic_link_default);
13481
+ var access_default = app37;
13374
13482
 
13375
13483
  // server/routes/sites.ts
13376
13484
  import { existsSync as existsSync19, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
@@ -13405,8 +13513,8 @@ function getExt(p) {
13405
13513
  if (idx < p.lastIndexOf("/")) return "";
13406
13514
  return p.slice(idx).toLowerCase();
13407
13515
  }
13408
- var app37 = new Hono();
13409
- app37.get("/:rel{.*}", (c) => {
13516
+ var app38 = new Hono();
13517
+ app38.get("/:rel{.*}", (c) => {
13410
13518
  const reqPath = c.req.path;
13411
13519
  const rawRel = c.req.param("rel") ?? "";
13412
13520
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -13509,7 +13617,7 @@ app37.get("/:rel{.*}", (c) => {
13509
13617
  "X-Content-Type-Options": "nosniff"
13510
13618
  });
13511
13619
  });
13512
- var sites_default = app37;
13620
+ var sites_default = app38;
13513
13621
 
13514
13622
  // app/lib/visitor-token.ts
13515
13623
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
@@ -13609,7 +13717,7 @@ function readBrandConfig() {
13609
13717
  }
13610
13718
 
13611
13719
  // server/routes/visitor-consent.ts
13612
- var app38 = new Hono();
13720
+ var app39 = new Hono();
13613
13721
  var CONSENT_COOKIE_NAME = "mxy_consent";
13614
13722
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
13615
13723
  var DEFAULT_CONSENT_COPY = {
@@ -13654,17 +13762,17 @@ function siteSlugFromReferer(referer) {
13654
13762
  return "";
13655
13763
  }
13656
13764
  }
13657
- app38.options("/consent", (c) => {
13765
+ app39.options("/consent", (c) => {
13658
13766
  const origin = getOrigin(c);
13659
13767
  setCorsHeaders(c, origin);
13660
13768
  return c.body(null, 204);
13661
13769
  });
13662
- app38.options("/brand-config", (c) => {
13770
+ app39.options("/brand-config", (c) => {
13663
13771
  const origin = getOrigin(c);
13664
13772
  setCorsHeaders(c, origin);
13665
13773
  return c.body(null, 204);
13666
13774
  });
13667
- app38.post("/consent", async (c) => {
13775
+ app39.post("/consent", async (c) => {
13668
13776
  const origin = getOrigin(c);
13669
13777
  setCorsHeaders(c, origin);
13670
13778
  let raw;
@@ -13704,7 +13812,7 @@ app38.post("/consent", async (c) => {
13704
13812
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
13705
13813
  return c.body(null, 204);
13706
13814
  });
13707
- app38.get("/brand-config", (c) => {
13815
+ app39.get("/brand-config", (c) => {
13708
13816
  const origin = getOrigin(c);
13709
13817
  setCorsHeaders(c, origin);
13710
13818
  const brand = readBrandConfig();
@@ -13714,7 +13822,7 @@ app38.get("/brand-config", (c) => {
13714
13822
  c.header("Cache-Control", "public, max-age=300");
13715
13823
  return c.json({ consent: { copy, palette } });
13716
13824
  });
13717
- var visitor_consent_default = app38;
13825
+ var visitor_consent_default = app39;
13718
13826
 
13719
13827
  // server/routes/listings.ts
13720
13828
  function getCookie(headerValue, name) {
@@ -13741,8 +13849,8 @@ function appendConsentParams(pageUrl, token) {
13741
13849
  }
13742
13850
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
13743
13851
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
13744
- var app39 = new Hono();
13745
- app39.get("/:slug/click", async (c) => {
13852
+ var app40 = new Hono();
13853
+ app40.get("/:slug/click", async (c) => {
13746
13854
  const slug = c.req.param("slug") ?? "";
13747
13855
  const rawSession = c.req.query("session") ?? "";
13748
13856
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -13806,10 +13914,10 @@ app39.get("/:slug/click", async (c) => {
13806
13914
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
13807
13915
  return c.redirect(redirectUrl, 302);
13808
13916
  });
13809
- var listings_default = app39;
13917
+ var listings_default = app40;
13810
13918
 
13811
13919
  // server/routes/visitor-event.ts
13812
- var app40 = new Hono();
13920
+ var app41 = new Hono();
13813
13921
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
13814
13922
  var buckets = /* @__PURE__ */ new Map();
13815
13923
  var RATE_LIMIT = 60;
@@ -13876,12 +13984,12 @@ function originAllowed(origin, allowlist) {
13876
13984
  return false;
13877
13985
  }
13878
13986
  }
13879
- app40.options("/event", (c) => {
13987
+ app41.options("/event", (c) => {
13880
13988
  const origin = getOrigin2(c);
13881
13989
  setCorsHeaders2(c, origin);
13882
13990
  return c.body(null, 204);
13883
13991
  });
13884
- app40.post("/event", async (c) => {
13992
+ app41.post("/event", async (c) => {
13885
13993
  const origin = getOrigin2(c);
13886
13994
  setCorsHeaders2(c, origin);
13887
13995
  const ua = c.req.header("user-agent") ?? "";
@@ -14086,7 +14194,7 @@ async function writeEvent(opts) {
14086
14194
  );
14087
14195
  }
14088
14196
  }
14089
- var visitor_event_default = app40;
14197
+ var visitor_event_default = app41;
14090
14198
 
14091
14199
  // server/routes/session.ts
14092
14200
  import { resolve as resolve22 } from "path";
@@ -14123,8 +14231,8 @@ function withVisitorCookie(response, visitorId) {
14123
14231
  headers
14124
14232
  });
14125
14233
  }
14126
- var app41 = new Hono();
14127
- app41.post("/", async (c) => {
14234
+ var app42 = new Hono();
14235
+ app42.post("/", async (c) => {
14128
14236
  let body;
14129
14237
  try {
14130
14238
  body = await c.req.json();
@@ -14324,7 +14432,7 @@ app41.post("/", async (c) => {
14324
14432
  newVisitorId
14325
14433
  );
14326
14434
  });
14327
- var session_default2 = app41;
14435
+ var session_default2 = app42;
14328
14436
 
14329
14437
  // app/lib/graph-health.ts
14330
14438
  var HOUR_MS = 60 * 60 * 1e3;
@@ -14511,7 +14619,7 @@ async function startFileWatcher(opts = {}) {
14511
14619
  }
14512
14620
 
14513
14621
  // app/lib/whatsapp/inbound/claude-bridge.ts
14514
- var TAG27 = "[whatsapp-adaptor]";
14622
+ var TAG28 = "[whatsapp-adaptor]";
14515
14623
  function whatsappTurnTimeoutMs() {
14516
14624
  return Number(process.env.WHATSAPP_PTY_TURN_TIMEOUT_MS ?? String(5 * 6e4));
14517
14625
  }
@@ -14533,7 +14641,7 @@ async function dispatchToClaude(input) {
14533
14641
  await input.reply(result.turnText);
14534
14642
  } catch (err) {
14535
14643
  const m = err instanceof Error ? err.message : String(err);
14536
- console.error(`${TAG27} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
14644
+ console.error(`${TAG28} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
14537
14645
  }
14538
14646
  }
14539
14647
  function startReaper2() {
@@ -14863,9 +14971,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
14863
14971
  function isPublicHost(host) {
14864
14972
  return host.startsWith("public.") || aliasDomains.has(host);
14865
14973
  }
14866
- var app42 = new Hono();
14867
- app42.use("*", clientIpMiddleware);
14868
- app42.use("*", async (c, next) => {
14974
+ var app43 = new Hono();
14975
+ app43.use("*", clientIpMiddleware);
14976
+ app43.use("*", async (c, next) => {
14869
14977
  await next();
14870
14978
  c.header("X-Content-Type-Options", "nosniff");
14871
14979
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -14875,7 +14983,7 @@ app42.use("*", async (c, next) => {
14875
14983
  );
14876
14984
  });
14877
14985
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
14878
- app42.use("*", async (c, next) => {
14986
+ app43.use("*", async (c, next) => {
14879
14987
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
14880
14988
  await next();
14881
14989
  return;
@@ -14893,7 +15001,7 @@ app42.use("*", async (c, next) => {
14893
15001
  });
14894
15002
  }
14895
15003
  });
14896
- app42.use("*", async (c, next) => {
15004
+ app43.use("*", async (c, next) => {
14897
15005
  const host = (c.req.header("host") ?? "").split(":")[0];
14898
15006
  if (!isPublicHost(host)) {
14899
15007
  await next();
@@ -14924,7 +15032,7 @@ function resolveRemoteAuthOpts() {
14924
15032
  return brandLoginOpts;
14925
15033
  }
14926
15034
  var MAX_LOGIN_BODY = 8 * 1024;
14927
- app42.post("/__remote-auth/login", async (c) => {
15035
+ app43.post("/__remote-auth/login", async (c) => {
14928
15036
  const client = clientFrom(c);
14929
15037
  const clientIp = client.ip || "unknown";
14930
15038
  if (!requestIsTlsTerminated(c)) {
@@ -14969,7 +15077,7 @@ app42.post("/__remote-auth/login", async (c) => {
14969
15077
  }
14970
15078
  });
14971
15079
  });
14972
- app42.get("/__remote-auth/logout", (c) => {
15080
+ app43.get("/__remote-auth/logout", (c) => {
14973
15081
  const client = clientFrom(c);
14974
15082
  const clientIp = client.ip || "unknown";
14975
15083
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -14982,7 +15090,7 @@ app42.get("/__remote-auth/logout", (c) => {
14982
15090
  }
14983
15091
  });
14984
15092
  });
14985
- app42.post("/__remote-auth/change-password", async (c) => {
15093
+ app43.post("/__remote-auth/change-password", async (c) => {
14986
15094
  const client = clientFrom(c);
14987
15095
  const clientIp = client.ip || "unknown";
14988
15096
  const rateLimited = checkRateLimit(client);
@@ -15033,13 +15141,13 @@ app42.post("/__remote-auth/change-password", async (c) => {
15033
15141
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
15034
15142
  }
15035
15143
  });
15036
- app42.get("/__remote-auth/setup", (c) => {
15144
+ app43.get("/__remote-auth/setup", (c) => {
15037
15145
  if (isRemoteAuthConfigured()) {
15038
15146
  return c.redirect("/");
15039
15147
  }
15040
15148
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
15041
15149
  });
15042
- app42.post("/__remote-auth/set-initial-password", async (c) => {
15150
+ app43.post("/__remote-auth/set-initial-password", async (c) => {
15043
15151
  if (isRemoteAuthConfigured()) {
15044
15152
  return c.redirect("/");
15045
15153
  }
@@ -15077,10 +15185,10 @@ app42.post("/__remote-auth/set-initial-password", async (c) => {
15077
15185
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
15078
15186
  }
15079
15187
  });
15080
- app42.get("/api/remote-auth/status", (c) => {
15188
+ app43.get("/api/remote-auth/status", (c) => {
15081
15189
  return c.json({ configured: isRemoteAuthConfigured() });
15082
15190
  });
15083
- app42.post("/api/remote-auth/set-password", async (c) => {
15191
+ app43.post("/api/remote-auth/set-password", async (c) => {
15084
15192
  let body;
15085
15193
  try {
15086
15194
  body = await c.req.json();
@@ -15111,9 +15219,9 @@ app42.post("/api/remote-auth/set-password", async (c) => {
15111
15219
  return c.json({ error: "Failed to save password" }, 500);
15112
15220
  }
15113
15221
  });
15114
- app42.route("/api/_client-error", client_error_default);
15222
+ app43.route("/api/_client-error", client_error_default);
15115
15223
  console.log("[client-error-route] mounted");
15116
- app42.use("*", async (c, next) => {
15224
+ app43.use("*", async (c, next) => {
15117
15225
  const host = (c.req.header("host") ?? "").split(":")[0];
15118
15226
  const path2 = c.req.path;
15119
15227
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -15146,13 +15254,13 @@ app42.use("*", async (c, next) => {
15146
15254
  console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
15147
15255
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
15148
15256
  });
15149
- app42.route("/api/health", health_default);
15150
- app42.route("/api/chat", chat_default);
15151
- app42.route("/api/whatsapp", whatsapp_default);
15152
- app42.route("/api/onboarding", onboarding_default);
15153
- app42.route("/api/admin", admin_default);
15154
- app42.route("/api/access", access_default);
15155
- app42.route("/api/session", session_default2);
15257
+ app43.route("/api/health", health_default);
15258
+ app43.route("/api/chat", chat_default);
15259
+ app43.route("/api/whatsapp", whatsapp_default);
15260
+ app43.route("/api/onboarding", onboarding_default);
15261
+ app43.route("/api/admin", admin_default);
15262
+ app43.route("/api/access", access_default);
15263
+ app43.route("/api/session", session_default2);
15156
15264
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
15157
15265
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
15158
15266
  var IMAGE_MIME = {
@@ -15164,7 +15272,7 @@ var IMAGE_MIME = {
15164
15272
  ".svg": "image/svg+xml",
15165
15273
  ".ico": "image/x-icon"
15166
15274
  };
15167
- app42.get("/agent-assets/:slug/:filename", (c) => {
15275
+ app43.get("/agent-assets/:slug/:filename", (c) => {
15168
15276
  const slug = c.req.param("slug");
15169
15277
  const filename = c.req.param("filename");
15170
15278
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -15199,7 +15307,7 @@ app42.get("/agent-assets/:slug/:filename", (c) => {
15199
15307
  "Cache-Control": "public, max-age=3600"
15200
15308
  });
15201
15309
  });
15202
- app42.get("/generated/:filename", (c) => {
15310
+ app43.get("/generated/:filename", (c) => {
15203
15311
  const filename = c.req.param("filename");
15204
15312
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
15205
15313
  console.error(`[generated] serve file=${filename} status=403`);
@@ -15229,10 +15337,10 @@ app42.get("/generated/:filename", (c) => {
15229
15337
  "Cache-Control": "public, max-age=86400"
15230
15338
  });
15231
15339
  });
15232
- app42.route("/sites", sites_default);
15233
- app42.route("/listings", listings_default);
15234
- app42.route("/v", visitor_event_default);
15235
- app42.route("/v", visitor_consent_default);
15340
+ app43.route("/sites", sites_default);
15341
+ app43.route("/listings", listings_default);
15342
+ app43.route("/v", visitor_event_default);
15343
+ app43.route("/v", visitor_consent_default);
15236
15344
  var htmlCache = /* @__PURE__ */ new Map();
15237
15345
  var brandLogoPath = "/brand/maxy-monochrome.png";
15238
15346
  var brandIconPath = "/brand/maxy-monochrome.png";
@@ -15369,7 +15477,7 @@ function brandedPublicHtml(agentSlug) {
15369
15477
  function escapeHtml(s) {
15370
15478
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
15371
15479
  }
15372
- app42.get("/", (c) => {
15480
+ app43.get("/", (c) => {
15373
15481
  const host = (c.req.header("host") ?? "").split(":")[0];
15374
15482
  if (isPublicHost(host)) {
15375
15483
  const defaultSlug = resolveDefaultSlug();
@@ -15377,12 +15485,12 @@ app42.get("/", (c) => {
15377
15485
  }
15378
15486
  return c.html(cachedHtml("index.html"));
15379
15487
  });
15380
- app42.get("/public", (c) => {
15488
+ app43.get("/public", (c) => {
15381
15489
  const host = (c.req.header("host") ?? "").split(":")[0];
15382
15490
  if (isPublicHost(host)) return c.text("Not found", 404);
15383
15491
  return c.html(cachedHtml("public.html"));
15384
15492
  });
15385
- app42.get("/chat", (c) => {
15493
+ app43.get("/chat", (c) => {
15386
15494
  const host = (c.req.header("host") ?? "").split(":")[0];
15387
15495
  if (isPublicHost(host)) return c.text("Not found", 404);
15388
15496
  return c.html(cachedHtml("public.html"));
@@ -15401,9 +15509,9 @@ async function logViewerFetch(c, next) {
15401
15509
  duration_ms: Date.now() - start
15402
15510
  });
15403
15511
  }
15404
- app42.use("/vnc-viewer.html", logViewerFetch);
15405
- app42.use("/vnc-popout.html", logViewerFetch);
15406
- app42.get("/vnc-popout.html", (c) => {
15512
+ app43.use("/vnc-viewer.html", logViewerFetch);
15513
+ app43.use("/vnc-popout.html", logViewerFetch);
15514
+ app43.get("/vnc-popout.html", (c) => {
15407
15515
  let html = htmlCache.get("vnc-popout.html");
15408
15516
  if (!html) {
15409
15517
  html = readFileSync22(resolve25(process.cwd(), "public", "vnc-popout.html"), "utf-8");
@@ -15416,7 +15524,7 @@ app42.get("/vnc-popout.html", (c) => {
15416
15524
  }
15417
15525
  return c.html(html);
15418
15526
  });
15419
- app42.post("/api/vnc/client-event", async (c) => {
15527
+ app43.post("/api/vnc/client-event", async (c) => {
15420
15528
  let body;
15421
15529
  try {
15422
15530
  body = await c.req.json();
@@ -15437,25 +15545,25 @@ app42.post("/api/vnc/client-event", async (c) => {
15437
15545
  });
15438
15546
  return c.json({ ok: true });
15439
15547
  });
15440
- app42.get("/g/:slug", (c) => {
15548
+ app43.get("/g/:slug", (c) => {
15441
15549
  return c.html(brandedPublicHtml());
15442
15550
  });
15443
- app42.get("/graph", (c) => {
15551
+ app43.get("/graph", (c) => {
15444
15552
  const host = (c.req.header("host") ?? "").split(":")[0];
15445
15553
  if (isPublicHost(host)) return c.text("Not found", 404);
15446
15554
  return c.html(cachedHtml("graph.html"));
15447
15555
  });
15448
- app42.get("/sessions", (c) => {
15556
+ app43.get("/sessions", (c) => {
15449
15557
  const host = (c.req.header("host") ?? "").split(":")[0];
15450
15558
  if (isPublicHost(host)) return c.text("Not found", 404);
15451
15559
  return c.html(cachedHtml("sessions.html"));
15452
15560
  });
15453
- app42.get("/data", (c) => {
15561
+ app43.get("/data", (c) => {
15454
15562
  const host = (c.req.header("host") ?? "").split(":")[0];
15455
15563
  if (isPublicHost(host)) return c.text("Not found", 404);
15456
15564
  return c.html(cachedHtml("data.html"));
15457
15565
  });
15458
- app42.get("/:slug", async (c, next) => {
15566
+ app43.get("/:slug", async (c, next) => {
15459
15567
  const slug = c.req.param("slug");
15460
15568
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
15461
15569
  const branding = loadBrandingCache(slug);
@@ -15465,13 +15573,13 @@ app42.get("/:slug", async (c, next) => {
15465
15573
  await next();
15466
15574
  });
15467
15575
  if (brandFaviconPath !== "/favicon.ico") {
15468
- app42.get("/favicon.ico", (c) => {
15576
+ app43.get("/favicon.ico", (c) => {
15469
15577
  c.header("Cache-Control", "public, max-age=300");
15470
15578
  return c.redirect(brandFaviconPath, 302);
15471
15579
  });
15472
15580
  }
15473
- app42.use("/*", serveStatic({ root: "./public" }));
15474
- app42.all("*", (c) => {
15581
+ app43.use("/*", serveStatic({ root: "./public" }));
15582
+ app43.all("*", (c) => {
15475
15583
  const host = (c.req.header("host") ?? "").split(":")[0];
15476
15584
  const path2 = c.req.path;
15477
15585
  if (isPublicHost(host)) {
@@ -15485,7 +15593,7 @@ app42.all("*", (c) => {
15485
15593
  });
15486
15594
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
15487
15595
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
15488
- var httpServer = serve({ fetch: app42.fetch, port, hostname });
15596
+ var httpServer = serve({ fetch: app43.fetch, port, hostname });
15489
15597
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
15490
15598
  startAuthHealthHeartbeat();
15491
15599
  {
@@ -15523,7 +15631,7 @@ for (const m of SUBAPP_MANIFEST) {
15523
15631
  }
15524
15632
  try {
15525
15633
  const registered = [];
15526
- for (const r of app42.routes ?? []) {
15634
+ for (const r of app43.routes ?? []) {
15527
15635
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
15528
15636
  if (AGENT_SLUG_PATTERN.test(r.path)) {
15529
15637
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });