@rubytech/create-maxy-code 0.1.468 → 0.1.470

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/dist/index.js +40 -0
  2. package/package.json +1 -1
  3. package/payload/platform/config/brand.json +1 -0
  4. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +12 -2
  5. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -1
  6. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +9 -1
  7. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
  8. package/payload/platform/lib/storage-broker/dist/cf-exec.js +10 -3
  9. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
  10. package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +26 -3
  11. package/payload/platform/lib/storage-broker/src/cf-exec.ts +16 -3
  12. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  13. package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +1 -0
  14. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +106 -1
  15. package/payload/platform/plugins/docs/references/admin-ui.md +32 -0
  16. package/payload/platform/plugins/docs/references/google-guide.md +68 -0
  17. package/payload/platform/plugins/google/.claude-plugin/plugin.json +21 -0
  18. package/payload/platform/plugins/google/PLUGIN.md +104 -0
  19. package/payload/platform/plugins/google/lib/mcp-spawn-tee/index.js +193 -0
  20. package/payload/platform/plugins/google/lib/mcp-spawn-tee/package.json +3 -0
  21. package/payload/platform/plugins/google/mcp/package.json +20 -0
  22. package/payload/platform/plugins/google/references/auth.md +43 -24
  23. package/payload/platform/services/claude-session-manager/dist/account-title-stores.d.ts +17 -4
  24. package/payload/platform/services/claude-session-manager/dist/account-title-stores.d.ts.map +1 -1
  25. package/payload/platform/services/claude-session-manager/dist/account-title-stores.js +50 -13
  26. package/payload/platform/services/claude-session-manager/dist/account-title-stores.js.map +1 -1
  27. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  28. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +12 -0
  29. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  30. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts +7 -0
  31. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
  32. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +8 -0
  33. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
  34. package/payload/platform/services/claude-session-manager/dist/http-server.js +8 -8
  35. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  36. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  37. package/payload/server/{chunk-FOYHK255.js → chunk-56WJMBQQ.js} +3 -3
  38. package/payload/server/{chunk-POBXIHOF.js → chunk-JRIBGO45.js} +15 -1
  39. package/payload/server/maxy-edge.js +1 -1
  40. package/payload/server/server.js +643 -379
  41. package/payload/server/{src-52M7SECF.js → src-JYPKMWJR.js} +1 -1
@@ -111,7 +111,7 @@ import {
111
111
  vncLog,
112
112
  walkPremiumBundles,
113
113
  writeAdminUserAndPerson
114
- } from "./chunk-POBXIHOF.js";
114
+ } from "./chunk-JRIBGO45.js";
115
115
  import {
116
116
  D1_MAX_SQL_STATEMENT_BYTES,
117
117
  D1_QUERY_MAX_BODY_BYTES,
@@ -126,7 +126,7 @@ import {
126
126
  registerResource,
127
127
  resolveOwner,
128
128
  tooLargeMessage
129
- } from "./chunk-FOYHK255.js";
129
+ } from "./chunk-56WJMBQQ.js";
130
130
  import {
131
131
  __commonJS,
132
132
  __toESM
@@ -1533,10 +1533,10 @@ var serveStatic = (options = { root: "" }) => {
1533
1533
  };
1534
1534
 
1535
1535
  // server/index.ts
1536
- import { readFileSync as readFileSync38, existsSync as existsSync36, watchFile, readdirSync as readdirSync21, statSync as statSync14 } from "fs";
1536
+ import { readFileSync as readFileSync39, existsSync as existsSync37, watchFile, readdirSync as readdirSync22, statSync as statSync14 } from "fs";
1537
1537
  import { spawn as spawn3 } from "child_process";
1538
1538
  import { createHash as createHash7 } from "crypto";
1539
- import { resolve as resolve36, join as join38, basename as basename12 } from "path";
1539
+ import { resolve as resolve36, join as join39, basename as basename12 } from "path";
1540
1540
  import { homedir as homedir4 } from "os";
1541
1541
  import { monitorEventLoopDelay } from "perf_hooks";
1542
1542
 
@@ -5316,9 +5316,6 @@ function getStatus() {
5316
5316
  terminalReason: conn.terminalReason
5317
5317
  }));
5318
5318
  }
5319
- function getSocket(accountId) {
5320
- return connections.get(accountId)?.sock ?? null;
5321
- }
5322
5319
  function findConnectionByKey(conns, accountId) {
5323
5320
  return conns.find((c) => c.accountId === accountId) ?? conns.find((c) => c.platformAccountId === accountId);
5324
5321
  }
@@ -7085,6 +7082,21 @@ function createScheduleInjectRoutes(deps) {
7085
7082
  // server/index.ts
7086
7083
  var import_dist9 = __toESM(require_dist(), 1);
7087
7084
 
7085
+ // app/lib/whatsapp/socket-resolution-error.ts
7086
+ function formatPresentKeys(presentKeys) {
7087
+ return presentKeys.join(",") || "none";
7088
+ }
7089
+ function formatSocketResolutionReason(res) {
7090
+ return res.reason === "key-miss" ? `key-miss presentKeys=${formatPresentKeys(res.presentKeys)}` : "disconnected";
7091
+ }
7092
+ function formatSocketResolutionMessage(res, accountId, opts = {}) {
7093
+ if (res.reason === "key-miss") {
7094
+ return `WhatsApp socket key miss: no socket is registered for accountId=${accountId} (present keys: ${formatPresentKeys(res.presentKeys)}). This is an account-keying fault, not a dropped link \u2014 do not advise re-pairing.`;
7095
+ }
7096
+ const clause = opts.disconnectedClause ? `; ${opts.disconnectedClause}` : "";
7097
+ return `WhatsApp account "${accountId}" is registered but its transport is down${clause}.`;
7098
+ }
7099
+
7088
7100
  // app/lib/telegram/outbound/send-text.ts
7089
7101
  async function sendTelegramText(botToken, chatId, text) {
7090
7102
  try {
@@ -7907,16 +7919,9 @@ async function sendWhatsAppDocument(input) {
7907
7919
  const jid = normalizeJid2(to);
7908
7920
  const res = resolveSocket(accountId);
7909
7921
  if (!res.ok) {
7910
- const reason = res.reason === "key-miss" ? `key-miss presentKeys=${res.presentKeys.join(",") || "none"}` : "disconnected";
7922
+ const reason = formatSocketResolutionReason(res);
7911
7923
  console.error(`${TAG20} sent document to=${jid} file=${filename} bytes=${fileStat.size} ok=false reason=${reason}`);
7912
- if (res.reason === "key-miss") {
7913
- return {
7914
- ok: false,
7915
- status: 503,
7916
- error: `WhatsApp socket key miss: no socket is registered for accountId=${accountId} (present keys: ${res.presentKeys.join(",") || "none"}). This is an account-keying fault, not a dropped link \u2014 do not advise re-pairing.`
7917
- };
7918
- }
7919
- return { ok: false, status: 503, error: `WhatsApp account "${accountId}" is registered but its transport is down.` };
7924
+ return { ok: false, status: 503, error: formatSocketResolutionMessage(res, accountId) };
7920
7925
  }
7921
7926
  const sock = res.sock;
7922
7927
  const buffer = Buffer.from(await readFile(resolvedPath));
@@ -8448,11 +8453,12 @@ app2.post("/config", async (c) => {
8448
8453
  }
8449
8454
  case "list-groups": {
8450
8455
  const groupAccountId = accountId ?? "default";
8451
- const sock = getSocket(groupAccountId);
8452
- if (!sock) {
8453
- console.error(`${TAG22} config action=list-groups error="not connected" accountId=${groupAccountId}`);
8454
- return c.json({ ok: false, error: `WhatsApp account "${groupAccountId}" is not connected. Connect first, then retry.` });
8456
+ const groupRes = resolveSocket(groupAccountId);
8457
+ if (!groupRes.ok) {
8458
+ console.error(`${TAG22} config action=list-groups error="${formatSocketResolutionReason(groupRes)}" accountId=${groupAccountId}`);
8459
+ return c.json({ ok: false, error: formatSocketResolutionMessage(groupRes, groupAccountId) });
8455
8460
  }
8461
+ const sock = groupRes.sock;
8456
8462
  try {
8457
8463
  const participating = await sock.groupFetchAllParticipating();
8458
8464
  const groups = Object.values(participating).map((g) => ({
@@ -8761,11 +8767,12 @@ app2.get("/group-info", async (c) => {
8761
8767
  console.error(`${TAG22} group-info error="not a group JID" jid=${jid} account=${accountId}`);
8762
8768
  return c.json({ error: `"${jid}" is not a group JID. Group JIDs end with @g.us.` }, 400);
8763
8769
  }
8764
- const sock = getSocket(accountId);
8765
- if (!sock) {
8766
- console.error(`${TAG22} group-info error="not connected" account=${accountId}`);
8767
- return c.json({ error: `WhatsApp account "${accountId}" is not connected. Connect first, then retry.` }, 400);
8770
+ const res = resolveSocket(accountId);
8771
+ if (!res.ok) {
8772
+ console.error(`${TAG22} group-info error="${formatSocketResolutionReason(res)}" account=${accountId}`);
8773
+ return c.json({ error: formatSocketResolutionMessage(res, accountId) }, 400);
8768
8774
  }
8775
+ const sock = res.sock;
8769
8776
  const meta = await sock.groupMetadata(jid);
8770
8777
  const result = {
8771
8778
  jid: meta.id,
@@ -9301,7 +9308,7 @@ app3.post("/r2/object/delete", envelopeBodyLimit("write"), async (c) => {
9301
9308
  });
9302
9309
  var storage_broker_default = app3;
9303
9310
  async function runStorageAudit(root) {
9304
- const { reconcileStorage } = await import("./src-52M7SECF.js");
9311
+ const { reconcileStorage } = await import("./src-JYPKMWJR.js");
9305
9312
  const session = getSession();
9306
9313
  try {
9307
9314
  const cf = await makeHouseCfExec(root);
@@ -9334,7 +9341,7 @@ async function runStorageAudit(root) {
9334
9341
  }
9335
9342
  }
9336
9343
  async function runPagesAudit(root) {
9337
- const { reconcilePages } = await import("./src-52M7SECF.js");
9344
+ const { reconcilePages } = await import("./src-JYPKMWJR.js");
9338
9345
  const session = getSession();
9339
9346
  try {
9340
9347
  const cf = await makeHousePagesExec(root);
@@ -12781,9 +12788,249 @@ app9.get("/callback", async (c) => {
12781
12788
  });
12782
12789
  var quickbooks_default = app9;
12783
12790
 
12791
+ // server/routes/google-oauth.ts
12792
+ import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
12793
+ import { chmodSync, existsSync as existsSync17, mkdirSync as mkdirSync5, readdirSync as readdirSync16, readFileSync as readFileSync25, renameSync as renameSync6, rmSync as rmSync2, writeFileSync as writeFileSync9 } from "fs";
12794
+ import { join as join24 } from "path";
12795
+ var TAG26 = "[google-oauth]";
12796
+ var TOKEN_URL = "https://oauth2.googleapis.com/token";
12797
+ var PRIMARY_CALENDAR_URL = "https://www.googleapis.com/calendar/v3/calendars/primary";
12798
+ var PENDING_LIFETIME_MS = 6e5;
12799
+ function sanitizeAccountKey(key) {
12800
+ const safe = key.replace(/[^A-Za-z0-9._-]/g, "_");
12801
+ return safe === "." || safe === ".." ? `_${safe}` : safe;
12802
+ }
12803
+ function secretsDir(accountsDir, accountId) {
12804
+ return join24(accountsDir, sanitizeAccountKey(accountId), "secrets", "google");
12805
+ }
12806
+ function esc(s) {
12807
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
12808
+ }
12809
+ function refreshTokenBelongsToAccount(accountsDir, accountId, refreshToken) {
12810
+ const dir = join24(secretsDir(accountsDir, accountId), "accounts");
12811
+ if (!existsSync17(dir)) return false;
12812
+ let key;
12813
+ try {
12814
+ key = loadKey(accountsDir, accountId);
12815
+ } catch {
12816
+ return false;
12817
+ }
12818
+ for (const entry of readdirSync16(dir)) {
12819
+ const path3 = join24(dir, entry, "tokens.enc");
12820
+ if (!existsSync17(path3)) continue;
12821
+ try {
12822
+ const blob = JSON.parse(decrypt(key, readFileSync25(path3, "utf-8").trim()));
12823
+ if (blob.refreshToken && blob.refreshToken === refreshToken) return true;
12824
+ } catch {
12825
+ }
12826
+ }
12827
+ return false;
12828
+ }
12829
+ function loadKey(accountsDir, accountId) {
12830
+ const dir = secretsDir(accountsDir, accountId);
12831
+ const keyPath = join24(dir, ".key");
12832
+ mkdirSync5(dir, { recursive: true, mode: 448 });
12833
+ if (existsSync17(keyPath)) return Buffer.from(readFileSync25(keyPath, "utf-8").trim(), "base64");
12834
+ const k = randomBytes(32);
12835
+ writeFileSync9(keyPath, k.toString("base64"), { mode: 384 });
12836
+ chmodSync(keyPath, 384);
12837
+ return k;
12838
+ }
12839
+ function decrypt(key, raw) {
12840
+ const [ivHex, payload] = raw.split(":");
12841
+ const d = createDecipheriv("aes-256-cbc", key, Buffer.from(ivHex, "hex"));
12842
+ return d.update(payload, "hex", "utf8") + d.final("utf8");
12843
+ }
12844
+ function encrypt(key, plain) {
12845
+ const iv = randomBytes(16);
12846
+ const c = createCipheriv("aes-256-cbc", key, iv);
12847
+ return `${iv.toString("hex")}:${c.update(plain, "utf8", "hex") + c.final("hex")}`;
12848
+ }
12849
+ function atomicWrite(path3, contents) {
12850
+ const temp = `${path3}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
12851
+ try {
12852
+ writeFileSync9(temp, contents, { mode: 384 });
12853
+ chmodSync(temp, 384);
12854
+ renameSync6(temp, path3);
12855
+ } catch (err) {
12856
+ try {
12857
+ rmSync2(temp, { force: true });
12858
+ } catch {
12859
+ }
12860
+ throw err;
12861
+ }
12862
+ }
12863
+ function readPending(accountsDir, accountId) {
12864
+ const path3 = join24(secretsDir(accountsDir, accountId), "pending-oauth.enc");
12865
+ if (!existsSync17(path3)) return null;
12866
+ const raw = readFileSync25(path3, "utf-8").trim();
12867
+ if (!raw) return null;
12868
+ try {
12869
+ return JSON.parse(decrypt(loadKey(accountsDir, accountId), raw));
12870
+ } catch {
12871
+ return null;
12872
+ }
12873
+ }
12874
+ function clearPending(accountsDir, accountId) {
12875
+ const path3 = join24(secretsDir(accountsDir, accountId), "pending-oauth.enc");
12876
+ if (existsSync17(path3)) rmSync2(path3, { force: true });
12877
+ }
12878
+ function writeTokens(accountsDir, accountId, email, tok) {
12879
+ const key = loadKey(accountsDir, accountId);
12880
+ const dir = join24(secretsDir(accountsDir, accountId), "accounts", sanitizeAccountKey(email));
12881
+ mkdirSync5(dir, { recursive: true, mode: 448 });
12882
+ const now = Date.now();
12883
+ const blob = {
12884
+ accessToken: tok.accessToken,
12885
+ refreshToken: tok.refreshToken,
12886
+ accessTokenExpiry: now + tok.expiresInSeconds * 1e3,
12887
+ lastRefresh: now,
12888
+ email,
12889
+ scopes: tok.scopes
12890
+ };
12891
+ atomicWrite(join24(dir, "tokens.enc"), encrypt(key, JSON.stringify(blob)));
12892
+ }
12893
+ function readHouseGoogleCreds(platformRoot5) {
12894
+ const path3 = join24(platformRoot5, "config", "google-house.env");
12895
+ if (!existsSync17(path3)) return null;
12896
+ const env = {};
12897
+ for (const line of readFileSync25(path3, "utf-8").split(/\r?\n/)) {
12898
+ const m = line.match(/^([A-Z0-9_]+)=(.*)$/);
12899
+ if (m) env[m[1]] = m[2].trim();
12900
+ }
12901
+ if (!env.GOOGLE_CLIENT_ID || !env.GOOGLE_CLIENT_SECRET) return null;
12902
+ return { clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET };
12903
+ }
12904
+ function page2(title, body) {
12905
+ return `<!doctype html><meta name="viewport" content="width=device-width,initial-scale=1"><title>${title}</title><div style="font:16px/1.5 system-ui;margin:3rem auto;max-width:30rem;padding:0 1rem"><h1 style="font-size:1.3rem">${title}</h1><p>${body}</p></div>`;
12906
+ }
12907
+ function createGoogleOAuthRoutes(platformRoot5, accountsDir) {
12908
+ const routes = new Hono();
12909
+ routes.get("/oauth/callback", async (c) => {
12910
+ const code = c.req.query("code");
12911
+ const state = c.req.query("state");
12912
+ const accountId = c.req.query("account");
12913
+ if (!code || !state || !accountId) {
12914
+ console.error(`${TAG26} op=callback outcome=error error=missing-params`);
12915
+ return c.html(page2("Missing parameters", "Return to your chat and start again."), 400);
12916
+ }
12917
+ const held = readPending(accountsDir, accountId);
12918
+ const stateMatch = held !== null && held.state === state;
12919
+ console.error(`${TAG26} op=callback reg=${state} account=${accountId} state-match=${stateMatch}`);
12920
+ if (!held || !stateMatch) {
12921
+ return c.html(page2("This link has expired", "Return to your chat and start again."), 400);
12922
+ }
12923
+ const ageMs = Date.now() - held.createdAt;
12924
+ if (ageMs > PENDING_LIFETIME_MS) {
12925
+ console.error(`${TAG26} op=callback reg=${state} outcome=error error=pending-expired ageMs=${ageMs}`);
12926
+ clearPending(accountsDir, accountId);
12927
+ return c.html(page2("This link has expired", "Return to your chat and start again."), 400);
12928
+ }
12929
+ const failed = (title, body, status) => {
12930
+ clearPending(accountsDir, accountId);
12931
+ return c.html(page2(title, body), status);
12932
+ };
12933
+ const creds = readHouseGoogleCreds(platformRoot5);
12934
+ if (!creds) {
12935
+ console.error(`${TAG26} op=token-exchange reg=${state} outcome=error error=house-env-missing`);
12936
+ return failed("Not configured", "This install has no Google credentials yet.", 500);
12937
+ }
12938
+ const publicBase = (process.env.GOOGLE_PUBLIC_BASE ?? "").replace(/\/+$/, "");
12939
+ if (!publicBase) {
12940
+ console.error(`${TAG26} op=callback reg=${state} outcome=error error=public-base-unset`);
12941
+ return failed("Not configured", "This install has no public base configured.", 500);
12942
+ }
12943
+ const redirectUri = `${publicBase}/api/google/oauth/callback?account=${encodeURIComponent(accountId)}`;
12944
+ try {
12945
+ const res = await fetch(TOKEN_URL, {
12946
+ method: "POST",
12947
+ headers: { "content-type": "application/x-www-form-urlencoded" },
12948
+ body: new URLSearchParams({
12949
+ code,
12950
+ client_id: creds.clientId,
12951
+ client_secret: creds.clientSecret,
12952
+ redirect_uri: redirectUri,
12953
+ grant_type: "authorization_code",
12954
+ code_verifier: held.verifier
12955
+ })
12956
+ });
12957
+ const text = await res.text();
12958
+ if (!res.ok) {
12959
+ console.error(`${TAG26} op=token-exchange reg=${state} outcome=error status=${res.status} body=${text.slice(0, 300)}`);
12960
+ return failed("Could not connect", `Google refused the exchange (${res.status}).`, 502);
12961
+ }
12962
+ console.error(`${TAG26} op=token-exchange reg=${state} outcome=ok`);
12963
+ const tok = JSON.parse(text);
12964
+ const calRes = await fetch(PRIMARY_CALENDAR_URL, {
12965
+ headers: { authorization: `Bearer ${tok.access_token}` }
12966
+ });
12967
+ const calText = await calRes.text();
12968
+ if (!calRes.ok) {
12969
+ console.error(`${TAG26} op=identity reg=${state} outcome=error status=${calRes.status} body=${calText.slice(0, 300)}`);
12970
+ return failed("Could not connect", "Connected, but the calendar identity could not be read.", 502);
12971
+ }
12972
+ const email = JSON.parse(calText).id;
12973
+ console.error(`${TAG26} op=identity reg=${state} email=${email}`);
12974
+ writeTokens(accountsDir, accountId, email, {
12975
+ accessToken: tok.access_token,
12976
+ refreshToken: tok.refresh_token ?? null,
12977
+ expiresInSeconds: tok.expires_in,
12978
+ scopes: tok.scope ? tok.scope.split(" ") : []
12979
+ });
12980
+ console.error(
12981
+ `${TAG26} op=tokens-write reg=${state} account=${accountId} refreshIssued=${tok.refresh_token ? "true" : "false"}`
12982
+ );
12983
+ clearPending(accountsDir, accountId);
12984
+ console.error(`${TAG26} op=pending-clear reg=${state} verified=${readPending(accountsDir, accountId) === null}`);
12985
+ console.error(`${TAG26} op=registered reg=${state} account=${accountId} email=${email}`);
12986
+ return c.html(
12987
+ page2(
12988
+ "Calendar connected",
12989
+ `${esc(email)} is connected to this account. You can close this page and return to your chat.`
12990
+ )
12991
+ );
12992
+ } catch (err) {
12993
+ const msg = err.message;
12994
+ console.error(`${TAG26} op=token-exchange reg=${state} outcome=error error=${msg}`);
12995
+ return failed("Could not connect", "Something went wrong. Return to your chat and try again.", 502);
12996
+ }
12997
+ });
12998
+ routes.post("/oauth/refresh", async (c) => {
12999
+ const body = await c.req.json().catch(() => ({}));
13000
+ const { accountId, refreshToken } = body;
13001
+ if (!accountId || !refreshToken) {
13002
+ return c.json({ error: "accountId and refreshToken are required" }, 400);
13003
+ }
13004
+ if (!refreshTokenBelongsToAccount(accountsDir, accountId, refreshToken)) {
13005
+ console.error(`${TAG26} op=refresh account=${accountId} outcome=denied reason=token-not-held`);
13006
+ return c.json({ error: "refresh token is not held by this account" }, 403);
13007
+ }
13008
+ const creds = readHouseGoogleCreds(platformRoot5);
13009
+ if (!creds) return c.json({ error: "google-house.env is absent or incomplete" }, 500);
13010
+ const res = await fetch(TOKEN_URL, {
13011
+ method: "POST",
13012
+ headers: { "content-type": "application/x-www-form-urlencoded" },
13013
+ body: new URLSearchParams({
13014
+ client_id: creds.clientId,
13015
+ client_secret: creds.clientSecret,
13016
+ refresh_token: refreshToken,
13017
+ grant_type: "refresh_token"
13018
+ })
13019
+ });
13020
+ const text = await res.text();
13021
+ if (!res.ok) {
13022
+ console.error(`${TAG26} op=refresh account=${accountId} outcome=error status=${res.status} body=${text.slice(0, 300)}`);
13023
+ return c.json({ error: text.slice(0, 300) }, 502);
13024
+ }
13025
+ console.error(`${TAG26} op=refresh account=${accountId} outcome=ok`);
13026
+ return c.json(JSON.parse(text));
13027
+ });
13028
+ return routes;
13029
+ }
13030
+
12784
13031
  // server/routes/onboarding.ts
12785
13032
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync3 } from "child_process";
12786
- import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync10, writeSync, existsSync as existsSync18, readFileSync as readFileSync26, unlinkSync as unlinkSync3, renameSync as renameSync7 } from "fs";
13033
+ import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync11, writeSync, existsSync as existsSync19, readFileSync as readFileSync27, unlinkSync as unlinkSync3, renameSync as renameSync8 } from "fs";
12787
13034
  import { createHash as createHash4, randomUUID as randomUUID8 } from "crypto";
12788
13035
 
12789
13036
  // app/lib/claude-spawn-env.ts
@@ -12792,7 +13039,7 @@ function claudeBin() {
12792
13039
  }
12793
13040
 
12794
13041
  // server/routes/onboarding.ts
12795
- import { dirname as dirname9, join as join25 } from "path";
13042
+ import { dirname as dirname9, join as join26 } from "path";
12796
13043
 
12797
13044
  // app/lib/claude-keychain.ts
12798
13045
  import { execFileSync as execFileSync2 } from "child_process";
@@ -12921,8 +13168,8 @@ function readHostCredsBlob(service) {
12921
13168
  }
12922
13169
 
12923
13170
  // ../lib/admins-write/src/index.ts
12924
- import { existsSync as existsSync17, readFileSync as readFileSync25, writeFileSync as writeFileSync9, renameSync as renameSync6, mkdirSync as mkdirSync5, readdirSync as readdirSync16, statSync as statSync8, appendFileSync as appendFileSync2 } from "fs";
12925
- import { dirname as dirname8, join as join24 } from "path";
13171
+ import { existsSync as existsSync18, readFileSync as readFileSync26, writeFileSync as writeFileSync10, renameSync as renameSync7, mkdirSync as mkdirSync6, readdirSync as readdirSync17, statSync as statSync8, appendFileSync as appendFileSync2 } from "fs";
13172
+ import { dirname as dirname8, join as join25 } from "path";
12926
13173
  function id8(value) {
12927
13174
  return value.slice(0, 8);
12928
13175
  }
@@ -12936,7 +13183,7 @@ function appendUsersAuditLine(audit, fields) {
12936
13183
  const line = `[users-audit] action=${fields.action} actor=${actor}${targetFields}${sess} field=${fields.field} rowsBefore=${fields.rowsBefore} rowsAfter=${fields.rowsAfter} ts=${(/* @__PURE__ */ new Date()).toISOString()}
12937
13184
  `;
12938
13185
  try {
12939
- mkdirSync5(dirname8(audit.logFile), { recursive: true, mode: 448 });
13186
+ mkdirSync6(dirname8(audit.logFile), { recursive: true, mode: 448 });
12940
13187
  appendFileSync2(audit.logFile, line, { mode: 384 });
12941
13188
  } catch (err) {
12942
13189
  console.error(
@@ -12954,17 +13201,17 @@ function logLine(input, result) {
12954
13201
  );
12955
13202
  }
12956
13203
  function writeFileAtomic(filePath, contents, mode) {
12957
- mkdirSync5(dirname8(filePath), { recursive: true });
13204
+ mkdirSync6(dirname8(filePath), { recursive: true });
12958
13205
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
12959
- writeFileSync9(tempPath, contents, mode !== void 0 ? { mode } : void 0);
12960
- renameSync6(tempPath, filePath);
13206
+ writeFileSync10(tempPath, contents, mode !== void 0 ? { mode } : void 0);
13207
+ renameSync7(tempPath, filePath);
12961
13208
  }
12962
13209
  function writeAdminEntry(input) {
12963
13210
  const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
12964
13211
  try {
12965
13212
  let users = [];
12966
- if (existsSync17(input.usersFile)) {
12967
- const raw = readFileSync25(input.usersFile, "utf-8").trim();
13213
+ if (existsSync18(input.usersFile)) {
13214
+ const raw = readFileSync26(input.usersFile, "utf-8").trim();
12968
13215
  if (raw) {
12969
13216
  const parsed = JSON.parse(raw);
12970
13217
  if (!Array.isArray(parsed)) {
@@ -12995,11 +13242,11 @@ function writeAdminEntry(input) {
12995
13242
  return result;
12996
13243
  }
12997
13244
  try {
12998
- const accountJsonPath = join24(input.accountDir, "account.json");
12999
- if (!existsSync17(accountJsonPath)) {
13245
+ const accountJsonPath = join25(input.accountDir, "account.json");
13246
+ if (!existsSync18(accountJsonPath)) {
13000
13247
  throw new Error(`account.json not found at ${accountJsonPath}`);
13001
13248
  }
13002
- const config = JSON.parse(readFileSync25(accountJsonPath, "utf-8"));
13249
+ const config = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
13003
13250
  const admins = config.admins ?? [];
13004
13251
  if (admins.some((a) => a.userId === input.userId)) {
13005
13252
  result.accountJsonResult = "noop";
@@ -13019,9 +13266,9 @@ function writeAdminEntry(input) {
13019
13266
  function computeAdminStoreDivergence(input) {
13020
13267
  const result = { divergences: 0, accountWithoutUsers: [], usersWithoutAccount: [], errors: [] };
13021
13268
  const usersUserIds = /* @__PURE__ */ new Set();
13022
- if (existsSync17(input.usersFile)) {
13269
+ if (existsSync18(input.usersFile)) {
13023
13270
  try {
13024
- const raw = readFileSync25(input.usersFile, "utf-8").trim();
13271
+ const raw = readFileSync26(input.usersFile, "utf-8").trim();
13025
13272
  if (raw) {
13026
13273
  const users = JSON.parse(raw);
13027
13274
  for (const u of users) {
@@ -13033,27 +13280,27 @@ function computeAdminStoreDivergence(input) {
13033
13280
  }
13034
13281
  }
13035
13282
  const accountUserIds = /* @__PURE__ */ new Set();
13036
- if (existsSync17(input.accountsDir)) {
13283
+ if (existsSync18(input.accountsDir)) {
13037
13284
  let entries;
13038
13285
  try {
13039
- entries = readdirSync16(input.accountsDir);
13286
+ entries = readdirSync17(input.accountsDir);
13040
13287
  } catch (err) {
13041
13288
  result.errors.push({ source: input.accountsDir, detail: err instanceof Error ? err.message : String(err) });
13042
13289
  return result;
13043
13290
  }
13044
13291
  for (const entry of entries) {
13045
13292
  if (entry.startsWith(".")) continue;
13046
- const accountDir = join24(input.accountsDir, entry);
13293
+ const accountDir = join25(input.accountsDir, entry);
13047
13294
  try {
13048
13295
  if (!statSync8(accountDir).isDirectory()) continue;
13049
13296
  } catch {
13050
13297
  continue;
13051
13298
  }
13052
- const accountJsonPath = join24(accountDir, "account.json");
13053
- if (!existsSync17(accountJsonPath)) continue;
13299
+ const accountJsonPath = join25(accountDir, "account.json");
13300
+ if (!existsSync18(accountJsonPath)) continue;
13054
13301
  let admins = [];
13055
13302
  try {
13056
- const config = JSON.parse(readFileSync25(accountJsonPath, "utf-8"));
13303
+ const config = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
13057
13304
  admins = config.admins ?? [];
13058
13305
  } catch (err) {
13059
13306
  result.errors.push({ source: accountJsonPath, detail: err instanceof Error ? err.message : String(err) });
@@ -13101,8 +13348,8 @@ function hashPin2(pin) {
13101
13348
  return createHash4("sha256").update(pin).digest("hex");
13102
13349
  }
13103
13350
  function readUsersFile2() {
13104
- if (!existsSync18(USERS_FILE)) return null;
13105
- const raw = readFileSync26(USERS_FILE, "utf-8").trim();
13351
+ if (!existsSync19(USERS_FILE)) return null;
13352
+ const raw = readFileSync27(USERS_FILE, "utf-8").trim();
13106
13353
  if (!raw) return [];
13107
13354
  return JSON.parse(raw);
13108
13355
  }
@@ -13161,7 +13408,7 @@ app10.post("/claude-auth", async (c) => {
13161
13408
  } catch (err) {
13162
13409
  logoutError = err instanceof Error ? err.message : String(err);
13163
13410
  }
13164
- const credentialsPresent = existsSync18(CLAUDE_CREDENTIALS_FILE);
13411
+ const credentialsPresent = existsSync19(CLAUDE_CREDENTIALS_FILE);
13165
13412
  const ranMs = Date.now() - start;
13166
13413
  console.log(`[onboarding] op=claude-logout credentialsPresent=${credentialsPresent} ranMs=${ranMs} logoutError=${logoutError ? JSON.stringify(logoutError.slice(0, 120)) : "none"}`);
13167
13414
  return c.json({ logged_out: !credentialsPresent });
@@ -13195,7 +13442,7 @@ app10.post("/claude-auth", async (c) => {
13195
13442
  return c.json({ launched: cdpReady });
13196
13443
  }
13197
13444
  ensureLogDir();
13198
- writeFileSync10(logPath("claude-auth"), "");
13445
+ writeFileSync11(logPath("claude-auth"), "");
13199
13446
  const claudeAuthLogFd = openSync3(logPath("claude-auth"), "a");
13200
13447
  const onClaudeOutput = (chunk) => writeSync(claudeAuthLogFd, chunk);
13201
13448
  if (process.platform === "darwin") {
@@ -13220,14 +13467,14 @@ app10.post("/claude-auth", async (c) => {
13220
13467
  readBlob: readHostCredsBlob,
13221
13468
  writeFile: (blob) => {
13222
13469
  const tmp = `${CLAUDE_CREDENTIALS_FILE}.${process.pid}.tmp`;
13223
- writeFileSync10(tmp, blob, { mode: 384 });
13224
- renameSync7(tmp, CLAUDE_CREDENTIALS_FILE);
13470
+ writeFileSync11(tmp, blob, { mode: 384 });
13471
+ renameSync8(tmp, CLAUDE_CREDENTIALS_FILE);
13225
13472
  },
13226
13473
  log: (line) => console.log(line)
13227
13474
  });
13228
13475
  persistKeychainService(
13229
13476
  writebackResult,
13230
- (service) => writeFileSync10(join25(dirname9(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
13477
+ (service) => writeFileSync11(join26(dirname9(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
13231
13478
  (line) => console.log(line)
13232
13479
  );
13233
13480
  if (darwinAuthChild === claudeProc2) darwinAuthChild = null;
@@ -13310,9 +13557,9 @@ app10.post("/set-pin", async (c) => {
13310
13557
  console.log(`[set-pin] wrote users.json + account.json admins: userId=${userId.slice(0, 8)}\u2026 role=owner`);
13311
13558
  if (process.platform === "linux") {
13312
13559
  let installOwner = null;
13313
- if (existsSync18(INSTALL_OWNER_FILE)) {
13560
+ if (existsSync19(INSTALL_OWNER_FILE)) {
13314
13561
  try {
13315
- const raw = readFileSync26(INSTALL_OWNER_FILE, "utf-8").trim();
13562
+ const raw = readFileSync27(INSTALL_OWNER_FILE, "utf-8").trim();
13316
13563
  if (raw.length > 0) installOwner = raw;
13317
13564
  } catch (err) {
13318
13565
  console.error(`[set-pin] install-owner-read-failed path=${INSTALL_OWNER_FILE} error=${err instanceof Error ? err.message : String(err)}`);
@@ -13393,7 +13640,7 @@ app10.delete("/set-pin", requireAdminSession, async (c) => {
13393
13640
  unlinkSync3(USERS_FILE);
13394
13641
  console.log(`[set-pin] cleared users.json (last entry removed): userId=${sessionUserId.slice(0, 8)}\u2026`);
13395
13642
  } else {
13396
- writeFileSync10(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
13643
+ writeFileSync11(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
13397
13644
  console.log(`[set-pin] removed entry from users.json: userId=${sessionUserId.slice(0, 8)}\u2026 remaining=${remaining.length}`);
13398
13645
  }
13399
13646
  logUsersAudit(
@@ -13458,9 +13705,9 @@ app10.put("/set-pin", requireAdminSession, async (c) => {
13458
13705
  console.log(`[set-pin] changed PIN in place: userId=${sessionUserId.slice(0, 8)}\u2026`);
13459
13706
  if (process.platform === "linux") {
13460
13707
  let installOwner = null;
13461
- if (existsSync18(INSTALL_OWNER_FILE)) {
13708
+ if (existsSync19(INSTALL_OWNER_FILE)) {
13462
13709
  try {
13463
- const raw = readFileSync26(INSTALL_OWNER_FILE, "utf-8").trim();
13710
+ const raw = readFileSync27(INSTALL_OWNER_FILE, "utf-8").trim();
13464
13711
  if (raw.length > 0) installOwner = raw;
13465
13712
  } catch (err) {
13466
13713
  console.error(`[set-pin] install-owner-read-failed path=${INSTALL_OWNER_FILE} error=${err instanceof Error ? err.message : String(err)}`);
@@ -13492,9 +13739,9 @@ ${body.newPin}
13492
13739
  var onboarding_default = app10;
13493
13740
 
13494
13741
  // server/routes/client-error.ts
13495
- import { appendFileSync as appendFileSync3, existsSync as existsSync19, renameSync as renameSync8, statSync as statSync9 } from "fs";
13496
- import { join as join26 } from "path";
13497
- var CLIENT_ERRORS_LOG = join26(LOG_DIR, "client-errors.log");
13742
+ import { appendFileSync as appendFileSync3, existsSync as existsSync20, renameSync as renameSync9, statSync as statSync9 } from "fs";
13743
+ import { join as join27 } from "path";
13744
+ var CLIENT_ERRORS_LOG = join27(LOG_DIR, "client-errors.log");
13498
13745
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
13499
13746
  var MAX_BODY_SIZE = 8 * 1024;
13500
13747
  var MAX_STACK_LEN = 2e3;
@@ -13542,10 +13789,10 @@ function stackHead(stack) {
13542
13789
  }
13543
13790
  function rotateIfNeeded() {
13544
13791
  try {
13545
- if (!existsSync19(CLIENT_ERRORS_LOG)) return;
13792
+ if (!existsSync20(CLIENT_ERRORS_LOG)) return;
13546
13793
  const stats = statSync9(CLIENT_ERRORS_LOG);
13547
13794
  if (stats.size < MAX_LOG_SIZE) return;
13548
- renameSync8(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
13795
+ renameSync9(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
13549
13796
  } catch (err) {
13550
13797
  console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
13551
13798
  }
@@ -13869,18 +14116,18 @@ app13.get("/", requireAdminSession, async (c) => {
13869
14116
  var accounts_default = app13;
13870
14117
 
13871
14118
  // server/routes/admin/logs.ts
13872
- import { existsSync as existsSync21, readdirSync as readdirSync17, readFileSync as readFileSync27, statSync as statSync10 } from "fs";
14119
+ import { existsSync as existsSync22, readdirSync as readdirSync18, readFileSync as readFileSync28, statSync as statSync10 } from "fs";
13873
14120
  import { resolve as resolve17, basename as basename7 } from "path";
13874
14121
 
13875
14122
  // app/lib/logs-read-resolve.ts
13876
- import { existsSync as existsSync20 } from "fs";
13877
- import { join as join27 } from "path";
14123
+ import { existsSync as existsSync21 } from "fs";
14124
+ import { join as join28 } from "path";
13878
14125
  function resolveSessionLogPaths(filename, logDirs) {
13879
14126
  const tried = [filename];
13880
14127
  const hits = [];
13881
14128
  for (const dir of logDirs) {
13882
- const fullPath = join27(dir, filename);
13883
- if (existsSync20(fullPath)) {
14129
+ const fullPath = join28(dir, filename);
14130
+ if (existsSync21(fullPath)) {
13884
14131
  hits.push({ path: fullPath, dir });
13885
14132
  }
13886
14133
  }
@@ -13908,7 +14155,7 @@ app14.get("/", async (c) => {
13908
14155
  const filePath = resolve17(dir, safe);
13909
14156
  searched.push(filePath);
13910
14157
  try {
13911
- const buffer = readFileSync27(filePath);
14158
+ const buffer = readFileSync28(filePath);
13912
14159
  const onDiskBytes = statSync10(filePath).size;
13913
14160
  const headers = {
13914
14161
  "Content-Type": "text/plain; charset=utf-8",
@@ -13973,7 +14220,7 @@ app14.get("/", async (c) => {
13973
14220
  console.info(`[admin/logs] resolved cacheKey=${cacheKeySlice} sessionId=${sessionIdSlice} via=${primaryId === cacheKey ? "cacheKey" : primaryId === sessionKeyFromConv ? "reverse-lookup" : "sessionId-fallback"}`);
13974
14221
  try {
13975
14222
  const filename = basename7(hit.path);
13976
- const buffer = readFileSync27(hit.path);
14223
+ const buffer = readFileSync28(hit.path);
13977
14224
  const onDiskBytes = statSync10(hit.path).size;
13978
14225
  const headers = {
13979
14226
  "Content-Type": "text/plain; charset=utf-8",
@@ -14008,10 +14255,10 @@ app14.get("/", async (c) => {
14008
14255
  const seen = /* @__PURE__ */ new Set();
14009
14256
  const logs = {};
14010
14257
  for (const dir of logDirs) {
14011
- if (!existsSync21(dir)) continue;
14258
+ if (!existsSync22(dir)) continue;
14012
14259
  let files;
14013
14260
  try {
14014
- files = readdirSync17(dir).filter((f) => f.endsWith(".log"));
14261
+ files = readdirSync18(dir).filter((f) => f.endsWith(".log"));
14015
14262
  } catch (err) {
14016
14263
  const reason = err instanceof Error ? err.message : String(err);
14017
14264
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
@@ -14020,7 +14267,7 @@ app14.get("/", async (c) => {
14020
14267
  files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync10(resolve17(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
14021
14268
  seen.add(name);
14022
14269
  try {
14023
- const content = readFileSync27(resolve17(dir, name));
14270
+ const content = readFileSync28(resolve17(dir, name));
14024
14271
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
14025
14272
  logs[name] = tail.trim() || "(empty)";
14026
14273
  } catch (err) {
@@ -14060,7 +14307,7 @@ var claude_info_default = app15;
14060
14307
 
14061
14308
  // server/routes/admin/attachment.ts
14062
14309
  import { readFile as readFile2, readdir } from "fs/promises";
14063
- import { existsSync as existsSync22 } from "fs";
14310
+ import { existsSync as existsSync23 } from "fs";
14064
14311
  import { resolve as resolve18 } from "path";
14065
14312
  var app16 = new Hono();
14066
14313
  var ATTACHMENT_ID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
@@ -14083,12 +14330,12 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
14083
14330
  }
14084
14331
  let accountId = pinnedAccountId;
14085
14332
  let dir = uploadsDirFor2(accountId, attachmentId);
14086
- let found = existsSync22(dir);
14333
+ let found = existsSync23(dir);
14087
14334
  if (!found) {
14088
14335
  for (const candidate of listValidAccounts()) {
14089
14336
  if (candidate.accountId === pinnedAccountId) continue;
14090
14337
  const candidateDir = uploadsDirFor2(candidate.accountId, attachmentId);
14091
- if (existsSync22(candidateDir)) {
14338
+ if (existsSync23(candidateDir)) {
14092
14339
  accountId = candidate.accountId;
14093
14340
  dir = candidateDir;
14094
14341
  found = true;
@@ -14103,7 +14350,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
14103
14350
  return new Response("Not found", { status: 404 });
14104
14351
  }
14105
14352
  const metaPath = resolve18(dir, `${attachmentId}.meta.json`);
14106
- if (!existsSync22(metaPath)) {
14353
+ if (!existsSync23(metaPath)) {
14107
14354
  return new Response("Not found", { status: 404 });
14108
14355
  }
14109
14356
  let meta;
@@ -14137,23 +14384,23 @@ var attachment_default = app16;
14137
14384
 
14138
14385
  // server/routes/admin/agents.ts
14139
14386
  import { resolve as resolve19 } from "path";
14140
- import { readdirSync as readdirSync18, readFileSync as readFileSync28, existsSync as existsSync23, rmSync as rmSync2 } from "fs";
14387
+ import { readdirSync as readdirSync19, readFileSync as readFileSync29, existsSync as existsSync24, rmSync as rmSync3 } from "fs";
14141
14388
  var app17 = new Hono();
14142
14389
  app17.get("/", (c) => {
14143
14390
  const account = resolveAccount();
14144
14391
  if (!account) return c.json({ agents: [] });
14145
14392
  const agentsDir = resolve19(account.accountDir, "agents");
14146
- if (!existsSync23(agentsDir)) return c.json({ agents: [] });
14393
+ if (!existsSync24(agentsDir)) return c.json({ agents: [] });
14147
14394
  const agents = [];
14148
14395
  try {
14149
- const entries = readdirSync18(agentsDir, { withFileTypes: true });
14396
+ const entries = readdirSync19(agentsDir, { withFileTypes: true });
14150
14397
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
14151
14398
  if (!entry.isDirectory()) continue;
14152
14399
  if (entry.name === "admin") continue;
14153
14400
  const configPath2 = resolve19(agentsDir, entry.name, "config.json");
14154
- if (!existsSync23(configPath2)) continue;
14401
+ if (!existsSync24(configPath2)) continue;
14155
14402
  try {
14156
- const config = JSON.parse(readFileSync28(configPath2, "utf-8"));
14403
+ const config = JSON.parse(readFileSync29(configPath2, "utf-8"));
14157
14404
  agents.push({
14158
14405
  slug: entry.name,
14159
14406
  displayName: config.displayName ?? entry.name,
@@ -14180,7 +14427,7 @@ app17.delete("/:slug", async (c) => {
14180
14427
  return c.json({ error: "Invalid agent slug" }, 400);
14181
14428
  }
14182
14429
  const agentDir = resolve19(account.accountDir, "agents", slug);
14183
- if (!existsSync23(agentDir)) {
14430
+ if (!existsSync24(agentDir)) {
14184
14431
  return c.json({ error: "Agent not found" }, 404);
14185
14432
  }
14186
14433
  try {
@@ -14191,7 +14438,7 @@ app17.delete("/:slug", async (c) => {
14191
14438
  return c.json({ error: `Graph cleanup failed: ${msg}` }, 500);
14192
14439
  }
14193
14440
  try {
14194
- rmSync2(agentDir, { recursive: true, force: true });
14441
+ rmSync3(agentDir, { recursive: true, force: true });
14195
14442
  console.log(`[admin/agents] deleted agent "${slug}"`);
14196
14443
  return c.json({ ok: true });
14197
14444
  } catch (err) {
@@ -14210,7 +14457,7 @@ app17.post("/:slug/project", async (c) => {
14210
14457
  return c.json({ error: "Invalid agent slug" }, 400);
14211
14458
  }
14212
14459
  const agentDir = resolve19(account.accountDir, "agents", slug);
14213
- if (!existsSync23(agentDir)) {
14460
+ if (!existsSync24(agentDir)) {
14214
14461
  return c.json({ error: "Agent not found on disk" }, 404);
14215
14462
  }
14216
14463
  try {
@@ -14226,7 +14473,7 @@ var agents_default = app17;
14226
14473
  // server/routes/admin/sessions.ts
14227
14474
  import crypto2 from "crypto";
14228
14475
  import { resolve as resolvePath } from "path";
14229
- import { existsSync as existsSync24, mkdirSync as mkdirSync6, createWriteStream } from "fs";
14476
+ import { existsSync as existsSync25, mkdirSync as mkdirSync7, createWriteStream } from "fs";
14230
14477
 
14231
14478
  // ../lib/admin-conversation-purge/src/index.ts
14232
14479
  async function purgeAdminConversationJsonls(args) {
@@ -14373,7 +14620,7 @@ var pickComponentBytes = (..._args) => null;
14373
14620
  function openResumeStreamLog(accountId, sessionId) {
14374
14621
  const dir = resolvePath(ACCOUNTS_DIR, accountId, "resume-logs");
14375
14622
  try {
14376
- mkdirSync6(dir, { recursive: true });
14623
+ mkdirSync7(dir, { recursive: true });
14377
14624
  } catch {
14378
14625
  }
14379
14626
  return createWriteStream(resolvePath(dir, `${sessionId}.log`), { flags: "a" });
@@ -14386,7 +14633,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, sessionId, mes
14386
14633
  let reason = null;
14387
14634
  if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
14388
14635
  else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
14389
- else if (!existsSync24(a.storagePath)) reason = "missing-file";
14636
+ else if (!existsSync25(a.storagePath)) reason = "missing-file";
14390
14637
  if (reason) {
14391
14638
  invalid++;
14392
14639
  try {
@@ -14912,8 +15159,8 @@ app18.put("/:id/label", requireAdminSession, async (c) => {
14912
15159
  var sessions_default = app18;
14913
15160
 
14914
15161
  // app/lib/claude-agent/spawn-context.ts
14915
- import { existsSync as existsSync25, readFileSync as readFileSync29, readdirSync as readdirSync19, statSync as statSync11 } from "fs";
14916
- import { dirname as dirname10, resolve as resolve20, join as join28 } from "path";
15162
+ import { existsSync as existsSync26, readFileSync as readFileSync30, readdirSync as readdirSync20, statSync as statSync11 } from "fs";
15163
+ import { dirname as dirname10, resolve as resolve20, join as join29 } from "path";
14917
15164
  async function resolveOwnerProfileBlock(accountId, userId) {
14918
15165
  if (!userId) return { ok: false, reason: "missing-user-id" };
14919
15166
  try {
@@ -14954,14 +15201,14 @@ function frontmatterField(manifest, field2) {
14954
15201
  function extractPluginToolDescriptions(pluginDir) {
14955
15202
  const out = /* @__PURE__ */ new Map();
14956
15203
  const candidates = [
14957
- join28(pluginDir, "mcp/dist/index.js"),
14958
- join28(pluginDir, "mcp/src/index.ts")
15204
+ join29(pluginDir, "mcp/dist/index.js"),
15205
+ join29(pluginDir, "mcp/src/index.ts")
14959
15206
  ];
14960
15207
  let raw = null;
14961
15208
  for (const path3 of candidates) {
14962
- if (!existsSync25(path3)) continue;
15209
+ if (!existsSync26(path3)) continue;
14963
15210
  try {
14964
- raw = readFileSync29(path3, "utf-8");
15211
+ raw = readFileSync30(path3, "utf-8");
14965
15212
  break;
14966
15213
  } catch {
14967
15214
  }
@@ -15011,9 +15258,9 @@ function parseSkillPathsFromFrontmatter(fm) {
15011
15258
  function listPluginDirs() {
15012
15259
  const out = /* @__PURE__ */ new Map();
15013
15260
  const platformPlugins = resolve20(PLATFORM_ROOT, "plugins");
15014
- if (existsSync25(platformPlugins)) {
15015
- for (const name of readdirSync19(platformPlugins)) {
15016
- const dir = join28(platformPlugins, name);
15261
+ if (existsSync26(platformPlugins)) {
15262
+ for (const name of readdirSync20(platformPlugins)) {
15263
+ const dir = join29(platformPlugins, name);
15017
15264
  try {
15018
15265
  if (statSync11(dir).isDirectory()) out.set(name, dir);
15019
15266
  } catch {
@@ -15021,13 +15268,13 @@ function listPluginDirs() {
15021
15268
  }
15022
15269
  }
15023
15270
  const premiumRoot = resolve20(dirname10(PLATFORM_ROOT), "premium-plugins");
15024
- if (existsSync25(premiumRoot)) {
15025
- for (const bundle of readdirSync19(premiumRoot)) {
15026
- const bundlePlugins = join28(premiumRoot, bundle, "plugins");
15027
- if (!existsSync25(bundlePlugins)) continue;
15271
+ if (existsSync26(premiumRoot)) {
15272
+ for (const bundle of readdirSync20(premiumRoot)) {
15273
+ const bundlePlugins = join29(premiumRoot, bundle, "plugins");
15274
+ if (!existsSync26(bundlePlugins)) continue;
15028
15275
  try {
15029
- for (const name of readdirSync19(bundlePlugins)) {
15030
- const dir = join28(bundlePlugins, name);
15276
+ for (const name of readdirSync20(bundlePlugins)) {
15277
+ const dir = join29(bundlePlugins, name);
15031
15278
  try {
15032
15279
  if (statSync11(dir).isDirectory()) out.set(name, dir);
15033
15280
  } catch {
@@ -15041,9 +15288,9 @@ function listPluginDirs() {
15041
15288
  }
15042
15289
  function readEnabledPlugins(accountId) {
15043
15290
  const accountFile = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
15044
- if (!existsSync25(accountFile)) return /* @__PURE__ */ new Set();
15291
+ if (!existsSync26(accountFile)) return /* @__PURE__ */ new Set();
15045
15292
  try {
15046
- const parsed = JSON.parse(readFileSync29(accountFile, "utf-8"));
15293
+ const parsed = JSON.parse(readFileSync30(accountFile, "utf-8"));
15047
15294
  return new Set(
15048
15295
  Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : []
15049
15296
  );
@@ -15052,10 +15299,10 @@ function readEnabledPlugins(accountId) {
15052
15299
  }
15053
15300
  }
15054
15301
  function readFrontmatter(path3) {
15055
- if (!existsSync25(path3)) return null;
15302
+ if (!existsSync26(path3)) return null;
15056
15303
  let raw;
15057
15304
  try {
15058
- raw = readFileSync29(path3, "utf-8");
15305
+ raw = readFileSync30(path3, "utf-8");
15059
15306
  } catch {
15060
15307
  return null;
15061
15308
  }
@@ -15070,7 +15317,7 @@ function computeActivePlugins(accountId) {
15070
15317
  for (const name of Array.from(enabled).sort()) {
15071
15318
  const dir = pluginDirs.get(name);
15072
15319
  if (!dir) continue;
15073
- const fm = readFrontmatter(join28(dir, "PLUGIN.md"));
15320
+ const fm = readFrontmatter(join29(dir, "PLUGIN.md"));
15074
15321
  if (!fm) continue;
15075
15322
  const description = frontmatterField(`---
15076
15323
  ${fm}
@@ -15087,7 +15334,7 @@ ${fm}
15087
15334
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
15088
15335
  );
15089
15336
  if (toolNames.length > 0 && descMap.size === 0) {
15090
- const hasSource = existsSync25(join28(dir, "mcp/dist/index.js")) || existsSync25(join28(dir, "mcp/src/index.ts"));
15337
+ const hasSource = existsSync26(join29(dir, "mcp/dist/index.js")) || existsSync26(join29(dir, "mcp/src/index.ts"));
15091
15338
  if (hasSource) {
15092
15339
  console.warn(
15093
15340
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -15097,7 +15344,7 @@ ${fm}
15097
15344
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
15098
15345
  const skills = [];
15099
15346
  for (const relPath of skillPaths) {
15100
- const skillPath = join28(dir, relPath);
15347
+ const skillPath = join29(dir, relPath);
15101
15348
  const skillFm = readFrontmatter(skillPath);
15102
15349
  if (!skillFm) continue;
15103
15350
  const skillName = frontmatterField(`---
@@ -15114,10 +15361,10 @@ ${skillFm}
15114
15361
  }
15115
15362
  function computeSpecialistDomains(accountId) {
15116
15363
  const specialistsDir = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
15117
- if (!existsSync25(specialistsDir)) return [];
15364
+ if (!existsSync26(specialistsDir)) return [];
15118
15365
  let entries;
15119
15366
  try {
15120
- entries = readdirSync19(specialistsDir);
15367
+ entries = readdirSync20(specialistsDir);
15121
15368
  } catch {
15122
15369
  return [];
15123
15370
  }
@@ -15141,7 +15388,7 @@ function computeSpecialistDomains(accountId) {
15141
15388
  const out = [];
15142
15389
  for (const file of entries.sort()) {
15143
15390
  if (!file.endsWith(".md")) continue;
15144
- const fm = readFrontmatter(join28(specialistsDir, file));
15391
+ const fm = readFrontmatter(join29(specialistsDir, file));
15145
15392
  if (!fm) continue;
15146
15393
  const wrapped = `---
15147
15394
  ${fm}
@@ -15160,10 +15407,10 @@ ${fm}
15160
15407
  }
15161
15408
  function computeDormantPlugins(accountId) {
15162
15409
  const accountFile = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
15163
- if (!existsSync25(accountFile)) return [];
15410
+ if (!existsSync26(accountFile)) return [];
15164
15411
  let enabled;
15165
15412
  try {
15166
- const raw = readFileSync29(accountFile, "utf-8");
15413
+ const raw = readFileSync30(accountFile, "utf-8");
15167
15414
  const parsed = JSON.parse(raw);
15168
15415
  enabled = new Set(
15169
15416
  Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : []
@@ -15175,10 +15422,10 @@ function computeDormantPlugins(accountId) {
15175
15422
  return [];
15176
15423
  }
15177
15424
  const pluginsDir = resolve20(PLATFORM_ROOT, "plugins");
15178
- if (!existsSync25(pluginsDir)) return [];
15425
+ if (!existsSync26(pluginsDir)) return [];
15179
15426
  let entries;
15180
15427
  try {
15181
- entries = readdirSync19(pluginsDir);
15428
+ entries = readdirSync20(pluginsDir);
15182
15429
  } catch {
15183
15430
  return [];
15184
15431
  }
@@ -15186,10 +15433,10 @@ function computeDormantPlugins(accountId) {
15186
15433
  for (const name of entries) {
15187
15434
  if (enabled.has(name)) continue;
15188
15435
  const manifestPath = resolve20(pluginsDir, name, "PLUGIN.md");
15189
- if (!existsSync25(manifestPath)) continue;
15436
+ if (!existsSync26(manifestPath)) continue;
15190
15437
  let manifest;
15191
15438
  try {
15192
- manifest = readFileSync29(manifestPath, "utf-8");
15439
+ manifest = readFileSync30(manifestPath, "utf-8");
15193
15440
  } catch {
15194
15441
  continue;
15195
15442
  }
@@ -15203,13 +15450,13 @@ function computeDormantPlugins(accountId) {
15203
15450
  }
15204
15451
 
15205
15452
  // server/routes/admin/claude-sessions.ts
15206
- import { existsSync as existsSync26, readFileSync as readFileSync30 } from "fs";
15453
+ import { existsSync as existsSync27, readFileSync as readFileSync31 } from "fs";
15207
15454
  import { resolve as resolve21 } from "path";
15208
15455
  function readTunnelState(brandConfigDir) {
15209
15456
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
15210
- if (!existsSync26(statePath)) return null;
15457
+ if (!existsSync27(statePath)) return null;
15211
15458
  try {
15212
- const parsed = JSON.parse(readFileSync30(statePath, "utf-8"));
15459
+ const parsed = JSON.parse(readFileSync31(statePath, "utf-8"));
15213
15460
  const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
15214
15461
  const tunnelName = typeof parsed.tunnelName === "string" ? parsed.tunnelName : null;
15215
15462
  const domain = typeof parsed.domain === "string" ? parsed.domain : null;
@@ -15223,7 +15470,7 @@ function resolveTunnelUrl() {
15223
15470
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve21(process.cwd(), "..");
15224
15471
  let brand;
15225
15472
  try {
15226
- brand = JSON.parse(readFileSync30(resolve21(platformRoot5, "config", "brand.json"), "utf-8"));
15473
+ brand = JSON.parse(readFileSync31(resolve21(platformRoot5, "config", "brand.json"), "utf-8"));
15227
15474
  } catch {
15228
15475
  return null;
15229
15476
  }
@@ -15234,7 +15481,7 @@ function resolveTunnelUrl() {
15234
15481
  if (!state) return null;
15235
15482
  return `https://${hostname2}.${state.domain}`;
15236
15483
  }
15237
- var TAG26 = "[claude-session-manager:wrapper]";
15484
+ var TAG27 = "[claude-session-manager:wrapper]";
15238
15485
  async function refuseIfClaudeAuthDead(c, route, sessionId) {
15239
15486
  const auth = await ensureAuth();
15240
15487
  if (auth.status !== "dead" && auth.status !== "missing") return null;
@@ -15252,12 +15499,12 @@ async function performSpawnWithInitialMessage(args) {
15252
15499
  const aboutOwner = await resolveOwnerProfileBlock(args.senderId, args.userId);
15253
15500
  const ownerMs = Date.now() - ownerStart;
15254
15501
  const aboutOwnerStatus = aboutOwner == null ? "absent" : "ok" in aboutOwner && aboutOwner.ok === false ? `unresolved:${aboutOwner.reason}` : "ok";
15255
- console.log(`${TAG26} about-owner-resolved status=${aboutOwnerStatus} ms=${ownerMs}`);
15502
+ console.log(`${TAG27} about-owner-resolved status=${aboutOwnerStatus} ms=${ownerMs}`);
15256
15503
  const dormantPlugins = computeDormantPlugins(args.senderId);
15257
15504
  const activePlugins = computeActivePlugins(args.senderId);
15258
15505
  const specialistDomains = computeSpecialistDomains(args.senderId);
15259
15506
  const tunnelUrl = resolveTunnelUrl();
15260
- console.log(`${TAG26} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
15507
+ console.log(`${TAG27} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
15261
15508
  const upstreamPayload = JSON.stringify({
15262
15509
  senderId: args.senderId,
15263
15510
  // Task 205 — pass userId through to the manager so it lands as
@@ -15284,24 +15531,24 @@ async function performSpawnWithInitialMessage(args) {
15284
15531
  // unshapely values.
15285
15532
  conversationNodeId: args.conversationNodeId
15286
15533
  });
15287
- console.log(`${TAG26} forward-spawn-start managerBase=${managerBase("claude-session-manager:wrapper")} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
15534
+ console.log(`${TAG27} forward-spawn-start managerBase=${managerBase("claude-session-manager:wrapper")} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
15288
15535
  const forwardStart = Date.now();
15289
15536
  const upstream = await fetch(`${managerBase("claude-session-manager:wrapper")}/public-spawn`, {
15290
15537
  method: "POST",
15291
15538
  headers: { "content-type": "application/json" },
15292
15539
  body: upstreamPayload
15293
15540
  }).catch((err) => {
15294
- console.error(`${TAG26} fetch-failed op=spawn message=${err instanceof Error ? err.message : String(err)} ms=${Date.now() - forwardStart}`);
15541
+ console.error(`${TAG27} fetch-failed op=spawn message=${err instanceof Error ? err.message : String(err)} ms=${Date.now() - forwardStart}`);
15295
15542
  return null;
15296
15543
  });
15297
15544
  if (!upstream) return {
15298
15545
  response: new Response(JSON.stringify({ error: "manager-unreachable" }), { status: 503, headers: { "content-type": "application/json" } }),
15299
15546
  claudeSessionId: null
15300
15547
  };
15301
- console.log(`${TAG26} forward-spawn-done status=${upstream.status} ms=${Date.now() - forwardStart}`);
15548
+ console.log(`${TAG27} forward-spawn-done status=${upstream.status} ms=${Date.now() - forwardStart}`);
15302
15549
  if (args.initialMessage) {
15303
15550
  const inputBytes = Buffer.byteLength(args.initialMessage, "utf8");
15304
- console.log(`${TAG26} initial-message-inlined bytes=${inputBytes}`);
15551
+ console.log(`${TAG27} initial-message-inlined bytes=${inputBytes}`);
15305
15552
  }
15306
15553
  const bodyText = await upstream.text().catch(() => "");
15307
15554
  let claudeSessionId = null;
@@ -15336,7 +15583,7 @@ app19.post("/", async (c) => {
15336
15583
  if (refusal) return refusal;
15337
15584
  const senderId = getAccountIdForSession(cacheKey) ?? "";
15338
15585
  if (!senderId) {
15339
- console.error(`${TAG26} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
15586
+ console.error(`${TAG27} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
15340
15587
  return c.json({ error: "admin-account-not-resolved" }, 500);
15341
15588
  }
15342
15589
  const userId = getUserIdForSession(cacheKey) ?? void 0;
@@ -15345,7 +15592,7 @@ app19.post("/", async (c) => {
15345
15592
  const permissionMode = typeof body.permissionMode === "string" ? body.permissionMode : void 0;
15346
15593
  const specialist = typeof body.specialist === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(body.specialist) ? body.specialist : void 0;
15347
15594
  const model = typeof body.model === "string" && /^[A-Za-z0-9._-]{1,64}$/.test(body.model) ? body.model : void 0;
15348
- console.log(`${TAG26} spawn-request-in surface=cookie accountId=${senderId.slice(0, 8)} userId=${userId ? userId.slice(0, 8) : "absent"} channel=${channel} permissionMode=${permissionMode ?? "default"} specialist=${specialist ?? "none"} model=${model ?? "default"} initialMessage=${initialMessage ? "yes" : "no"}`);
15595
+ console.log(`${TAG27} spawn-request-in surface=cookie accountId=${senderId.slice(0, 8)} userId=${userId ? userId.slice(0, 8) : "absent"} channel=${channel} permissionMode=${permissionMode ?? "default"} specialist=${specialist ?? "none"} model=${model ?? "default"} initialMessage=${initialMessage ? "yes" : "no"}`);
15349
15596
  const conversationNodeId = cacheKey ? getSessionIdForSession(cacheKey) : void 0;
15350
15597
  const { response, claudeSessionId } = await performSpawnWithInitialMessage({
15351
15598
  senderId,
@@ -15364,13 +15611,13 @@ app19.post("/", async (c) => {
15364
15611
  claudeSessionId,
15365
15612
  senderId
15366
15613
  );
15367
- console.log(`${TAG26} route-done surface=cookie status=${response.status} route-ms=${Date.now() - routeStart}`);
15614
+ console.log(`${TAG27} route-done surface=cookie status=${response.status} route-ms=${Date.now() - routeStart}`);
15368
15615
  return response;
15369
15616
  });
15370
15617
  var claude_sessions_default = app19;
15371
15618
 
15372
15619
  // server/routes/admin/log-ingest.ts
15373
- var TAG27 = "[log-ingest]";
15620
+ var TAG28 = "[log-ingest]";
15374
15621
  var TAG_PATTERN = /^[A-Za-z0-9_:-]{1,32}$/;
15375
15622
  var LEVELS = /* @__PURE__ */ new Set(["debug", "info", "warn", "error"]);
15376
15623
  var MAX_LINE_BYTES = 4096;
@@ -15381,7 +15628,7 @@ function isLoopbackAddr2(addr) {
15381
15628
  app20.post("/", async (c) => {
15382
15629
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15383
15630
  if (!isLoopbackAddr2(remoteAddr)) {
15384
- console.error(`${TAG27} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15631
+ console.error(`${TAG28} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15385
15632
  return c.json({ error: "log-ingest-loopback-only" }, 403);
15386
15633
  }
15387
15634
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15390,7 +15637,7 @@ app20.post("/", async (c) => {
15390
15637
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15391
15638
  const offender = tokens.find((t) => !isLoopbackAddr2(t));
15392
15639
  if (offender !== void 0) {
15393
- console.error(`${TAG27} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15640
+ console.error(`${TAG28} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
15394
15641
  return c.json({ error: "log-ingest-loopback-only" }, 403);
15395
15642
  }
15396
15643
  }
@@ -15432,18 +15679,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
15432
15679
  ]);
15433
15680
  var app21 = new Hono();
15434
15681
  app21.post("/", async (c) => {
15435
- const TAG47 = "[admin:events]";
15682
+ const TAG48 = "[admin:events]";
15436
15683
  let body;
15437
15684
  try {
15438
15685
  body = await c.req.json();
15439
15686
  } catch (err) {
15440
15687
  const detail = err instanceof Error ? err.message : String(err);
15441
- console.error(`${TAG47} reject reason=body-not-json detail=${detail}`);
15688
+ console.error(`${TAG48} reject reason=body-not-json detail=${detail}`);
15442
15689
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
15443
15690
  }
15444
15691
  const event = typeof body.event === "string" ? body.event : "";
15445
15692
  if (!ALLOWED_EVENTS.has(event)) {
15446
- console.error(`${TAG47} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
15693
+ console.error(`${TAG48} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
15447
15694
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
15448
15695
  }
15449
15696
  const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
@@ -15465,11 +15712,11 @@ app21.post("/", async (c) => {
15465
15712
  var events_default = app21;
15466
15713
 
15467
15714
  // server/routes/admin/files.ts
15468
- import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync27 } from "fs";
15715
+ import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync28 } from "fs";
15469
15716
  import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, unlink as unlink2, rename, rmdir } from "fs/promises";
15470
15717
  import { realpathSync as realpathSync6 } from "fs";
15471
15718
  import { randomUUID as randomUUID10 } from "crypto";
15472
- import { basename as basename9, dirname as dirname11, join as join30, relative as relative4, resolve as resolve23, sep as sep6 } from "path";
15719
+ import { basename as basename9, dirname as dirname11, join as join31, relative as relative4, resolve as resolve23, sep as sep6 } from "path";
15473
15720
  import { Readable as Readable2 } from "stream";
15474
15721
 
15475
15722
  // ../lib/graph-trash/src/index.ts
@@ -15787,7 +16034,7 @@ async function cascadeDeleteDocument(params) {
15787
16034
 
15788
16035
  // app/lib/file-index.ts
15789
16036
  import * as fsp from "fs/promises";
15790
- import { resolve as resolve22, relative as relative3, join as join29, basename as basename8, extname as extname2, sep as sep5 } from "path";
16037
+ import { resolve as resolve22, relative as relative3, join as join30, basename as basename8, extname as extname2, sep as sep5 } from "path";
15791
16038
  import { tmpdir as tmpdir2 } from "os";
15792
16039
  import { execFile as execFile2 } from "child_process";
15793
16040
  import { promisify as promisify2 } from "util";
@@ -15869,7 +16116,7 @@ async function extractPdf(absolute) {
15869
16116
  return stdout.trim();
15870
16117
  }
15871
16118
  async function ocrPdf(absolute) {
15872
- const outPdf = join29(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
16119
+ const outPdf = join30(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
15873
16120
  try {
15874
16121
  await execFileAsync2(
15875
16122
  "ocrmypdf",
@@ -15931,7 +16178,7 @@ async function readDisplayName(absolute) {
15931
16178
  const stem = dot === -1 ? base : base.slice(0, dot);
15932
16179
  if (base === `${stem}.meta.json`) return null;
15933
16180
  try {
15934
- const raw = await fsp.readFile(join29(dir, `${stem}.meta.json`), "utf-8");
16181
+ const raw = await fsp.readFile(join30(dir, `${stem}.meta.json`), "utf-8");
15935
16182
  const meta = JSON.parse(raw);
15936
16183
  const dn = meta.displayName ?? meta.filename;
15937
16184
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -15952,7 +16199,7 @@ async function walkSubtree(root, dataRoot, out) {
15952
16199
  for (const entry of entries) {
15953
16200
  if (entry.isSymbolicLink()) continue;
15954
16201
  if (entry.isDirectory() && entry.name === ".uploads-tmp") continue;
15955
- const abs = join29(root, entry.name);
16202
+ const abs = join30(root, entry.name);
15956
16203
  if (entry.isDirectory()) {
15957
16204
  const sub = await walkSubtree(abs, dataRoot, out);
15958
16205
  if (!sub.clean) clean = false;
@@ -16308,7 +16555,7 @@ var UPLOAD_TMP_DIR = ".uploads-tmp";
16308
16555
  var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16309
16556
  async function readMeta(absDir, baseName) {
16310
16557
  try {
16311
- const raw = await readFile4(join30(absDir, `${baseName}.meta.json`), "utf8");
16558
+ const raw = await readFile4(join31(absDir, `${baseName}.meta.json`), "utf8");
16312
16559
  const parsed = JSON.parse(raw);
16313
16560
  if (typeof parsed?.filename === "string") {
16314
16561
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -16363,7 +16610,7 @@ async function servableFilesIn(dirAbs, uuid) {
16363
16610
  }
16364
16611
  async function enrich(absolute, entry, accountNames) {
16365
16612
  if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
16366
- const dirAbs = join30(absolute, entry.name);
16613
+ const dirAbs = join31(absolute, entry.name);
16367
16614
  const meta = await readMeta(dirAbs, entry.name);
16368
16615
  if (meta?.filename) {
16369
16616
  const servable = await servableFilesIn(dirAbs, entry.name);
@@ -16372,7 +16619,7 @@ async function enrich(absolute, entry, accountNames) {
16372
16619
  let size = null;
16373
16620
  let modifiedAt = entry.modifiedAt;
16374
16621
  try {
16375
- const st = await stat4(join30(dirAbs, innerName));
16622
+ const st = await stat4(join31(dirAbs, innerName));
16376
16623
  size = st.size;
16377
16624
  modifiedAt = st.mtime.toISOString();
16378
16625
  } catch {
@@ -16547,7 +16794,7 @@ app22.get("/", requireAdminSession, async (c) => {
16547
16794
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
16548
16795
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
16549
16796
  try {
16550
- const entryPath = join30(absolute, name);
16797
+ const entryPath = join31(absolute, name);
16551
16798
  const s = await stat4(entryPath);
16552
16799
  entries.push({
16553
16800
  name,
@@ -16610,7 +16857,7 @@ app22.get("/download", requireAdminSession, async (c) => {
16610
16857
  console.error(`[data] op=scratchpad-no-session sessionId="${sessionId.slice(0, 8)}\u2026"`);
16611
16858
  return c.json({ error: "Not found" }, 404);
16612
16859
  }
16613
- const meta = readSidecarMeta(join30(projectDir, `${sessionId}.meta.json`));
16860
+ const meta = readSidecarMeta(join31(projectDir, `${sessionId}.meta.json`));
16614
16861
  if (!meta.accountId || meta.accountId !== accountId) {
16615
16862
  console.error(`[data] account-scope-blocked root="scratchpad" sessionId="${sessionId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
16616
16863
  return c.json({ error: "Not found" }, 404);
@@ -16705,7 +16952,7 @@ async function* walkRegularFiles(dirAbsolute) {
16705
16952
  const dirents = await readdir3(dirAbsolute, { withFileTypes: true });
16706
16953
  for (const d of dirents) {
16707
16954
  if (d.isSymbolicLink()) continue;
16708
- const child = join30(dirAbsolute, d.name);
16955
+ const child = join31(dirAbsolute, d.name);
16709
16956
  if (d.isDirectory()) {
16710
16957
  yield* walkRegularFiles(child);
16711
16958
  continue;
@@ -16815,7 +17062,7 @@ async function resolveUploadTarget(c, accountId, uid) {
16815
17062
  const base = resolveOwnAccountWrite(rawDir, accountId, "POST /api/admin/files/upload");
16816
17063
  if (!base.ok) return { ok: false, status: base.status, error: base.error };
16817
17064
  const relDir = relpath ? dirname11(relpath) : ".";
16818
- const destRel = relDir === "." ? base.relative : join30(base.relative, relDir);
17065
+ const destRel = relDir === "." ? base.relative : join31(base.relative, relDir);
16819
17066
  if (crossesForeignAccountPartition(destRel, accountId)) {
16820
17067
  console.error(`[data] account-scope-blocked endpoint="POST /api/admin/files/upload" path="${destRel}" account=${accountId.slice(0, 8)}\u2026`);
16821
17068
  return { ok: false, status: 404, error: "Not found" };
@@ -16889,7 +17136,7 @@ app22.post("/upload", requireAdminSession, async (c) => {
16889
17136
  });
16890
17137
  await unlink2(tmpPath).catch(() => {
16891
17138
  });
16892
- const tempRemoved = !existsSync27(tmpPath);
17139
+ const tempRemoved = !existsSync28(tmpPath);
16893
17140
  console.error(`[data-upload] op=cleanup uid=${uid} tempRemoved=${tempRemoved}`);
16894
17141
  };
16895
17142
  const reader = body.getReader();
@@ -16963,7 +17210,7 @@ async function discardChunkUpload(uploadId, state) {
16963
17210
  });
16964
17211
  await unlink2(state.tmpPath).catch(() => {
16965
17212
  });
16966
- const tempRemoved = !existsSync27(state.tmpPath);
17213
+ const tempRemoved = !existsSync28(state.tmpPath);
16967
17214
  console.error(`[data-upload] op=cleanup uid=${uploadId} tempRemoved=${tempRemoved}`);
16968
17215
  }
16969
17216
  async function writeChunkBody(body, out, alreadyReceived, ceiling) {
@@ -17192,7 +17439,7 @@ app22.delete("/", requireAdminSession, async (c) => {
17192
17439
  const dot = base.lastIndexOf(".");
17193
17440
  const stem = dot === -1 ? base : base.slice(0, dot);
17194
17441
  const containerDir = dirname11(absolute);
17195
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join30(containerDir, `${stem}.meta.json`) : null;
17442
+ const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join31(containerDir, `${stem}.meta.json`) : null;
17196
17443
  const isAttachmentContainer = UUID_RE3.test(stem) && basename9(containerDir) === stem;
17197
17444
  await unlink2(absolute);
17198
17445
  if (sidecarPath) {
@@ -17202,7 +17449,7 @@ app22.delete("/", requireAdminSession, async (c) => {
17202
17449
  }
17203
17450
  }
17204
17451
  if (isAttachmentContainer) {
17205
- await unlink2(join30(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
17452
+ await unlink2(join31(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
17206
17453
  });
17207
17454
  await rmdir(containerDir).catch(() => {
17208
17455
  });
@@ -18306,8 +18553,8 @@ function isHiddenByDefault(label) {
18306
18553
  }
18307
18554
 
18308
18555
  // server/lib/top-level-labels.ts
18309
- import { readdirSync as readdirSync20, readFileSync as readFileSync31 } from "fs";
18310
- import { join as join31, resolve as resolve24 } from "path";
18556
+ import { readdirSync as readdirSync21, readFileSync as readFileSync32 } from "fs";
18557
+ import { join as join32, resolve as resolve24 } from "path";
18311
18558
  var STATIC_TOP_LEVEL_LABELS = Object.freeze(
18312
18559
  /* @__PURE__ */ new Set([
18313
18560
  // Base-schema infra (schema-base.md has no top-level section).
@@ -18400,7 +18647,7 @@ function parseTopLevelLabels(content) {
18400
18647
  }
18401
18648
  function resolveReferencesDir() {
18402
18649
  if (process.env.MAXY_PLATFORM_ROOT) {
18403
- return join31(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
18650
+ return join32(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
18404
18651
  }
18405
18652
  return resolve24(import.meta.dirname, "../../../plugins/memory/references");
18406
18653
  }
@@ -18408,9 +18655,9 @@ function parseTableTopLevelLabels(referencesDir) {
18408
18655
  const labels = /* @__PURE__ */ new Set();
18409
18656
  const contributingFiles = [];
18410
18657
  try {
18411
- const fileNames = readdirSync20(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
18658
+ const fileNames = readdirSync21(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
18412
18659
  for (const fileName of fileNames) {
18413
- const content = readFileSync31(join31(referencesDir, fileName), "utf-8");
18660
+ const content = readFileSync32(join32(referencesDir, fileName), "utf-8");
18414
18661
  const parsed = parseTopLevelLabels(content);
18415
18662
  if (parsed.length > 0) contributingFiles.push(fileName);
18416
18663
  for (const label of parsed) labels.add(label);
@@ -19564,7 +19811,7 @@ var graph_default_view_default = app28;
19564
19811
  // server/routes/admin/sidebar-artefacts.ts
19565
19812
  import { readdir as readdir4, stat as stat5 } from "fs/promises";
19566
19813
  import { resolve as resolve25, relative as relative5, isAbsolute as isAbsolute2, sep as sep7, basename as basename10 } from "path";
19567
- import { existsSync as existsSync28 } from "fs";
19814
+ import { existsSync as existsSync29 } from "fs";
19568
19815
  var LIMIT = 50;
19569
19816
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
19570
19817
  function toDataRootRelPath(absPath) {
@@ -19671,7 +19918,7 @@ async function fetchAgentTemplateRows(accountDir) {
19671
19918
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
19672
19919
  const names = /* @__PURE__ */ new Set();
19673
19920
  for (const dir of [overrideDir, bundledDir]) {
19674
- if (!existsSync28(dir)) continue;
19921
+ if (!existsSync29(dir)) continue;
19675
19922
  try {
19676
19923
  const entries = await readdir4(dir);
19677
19924
  for (const entry of entries) {
@@ -19686,7 +19933,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
19686
19933
  }
19687
19934
  async function readAgentTemplateRow(inp) {
19688
19935
  let chosenPath = null;
19689
- if (existsSync28(inp.overridePath)) {
19936
+ if (existsSync29(inp.overridePath)) {
19690
19937
  try {
19691
19938
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
19692
19939
  chosenPath = inp.overridePath;
@@ -19697,7 +19944,7 @@ async function readAgentTemplateRow(inp) {
19697
19944
  );
19698
19945
  return null;
19699
19946
  }
19700
- } else if (existsSync28(inp.bundledPath)) {
19947
+ } else if (existsSync29(inp.bundledPath)) {
19701
19948
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
19702
19949
  console.error(
19703
19950
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -20299,14 +20546,14 @@ app37.get("/", async (c) => {
20299
20546
  var system_stats_default = app37;
20300
20547
 
20301
20548
  // server/routes/admin/health.ts
20302
- import { existsSync as existsSync29, readFileSync as readFileSync32 } from "fs";
20303
- import { resolve as resolve26, join as join32 } from "path";
20549
+ import { existsSync as existsSync30, readFileSync as readFileSync33 } from "fs";
20550
+ import { resolve as resolve26, join as join33 } from "path";
20304
20551
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
20305
20552
  var brandHostname = "maxy";
20306
- var brandJsonPath = join32(PLATFORM_ROOT6, "config", "brand.json");
20307
- if (existsSync29(brandJsonPath)) {
20553
+ var brandJsonPath = join33(PLATFORM_ROOT6, "config", "brand.json");
20554
+ if (existsSync30(brandJsonPath)) {
20308
20555
  try {
20309
- const brand = JSON.parse(readFileSync32(brandJsonPath, "utf-8"));
20556
+ const brand = JSON.parse(readFileSync33(brandJsonPath, "utf-8"));
20310
20557
  if (brand.hostname) brandHostname = brand.hostname;
20311
20558
  } catch {
20312
20559
  }
@@ -20315,8 +20562,8 @@ var VERSION_FILE = resolve26(PLATFORM_ROOT6, `config/.${brandHostname}-version`)
20315
20562
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
20316
20563
  var PROBE_TIMEOUT_MS = 1e3;
20317
20564
  function readVersion() {
20318
- if (!existsSync29(VERSION_FILE)) return "unknown";
20319
- return readFileSync32(VERSION_FILE, "utf-8").trim() || "unknown";
20565
+ if (!existsSync30(VERSION_FILE)) return "unknown";
20566
+ return readFileSync33(VERSION_FILE, "utf-8").trim() || "unknown";
20320
20567
  }
20321
20568
  async function probeConversationDb() {
20322
20569
  let session;
@@ -20495,7 +20742,7 @@ function managerLogFollowUrl(sessionId, opts) {
20495
20742
  }
20496
20743
 
20497
20744
  // server/routes/admin/linkedin-ingest.ts
20498
- var TAG28 = "[linkedin-ingest-route]";
20745
+ var TAG29 = "[linkedin-ingest-route]";
20499
20746
  var UUID2 = /^[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}$/;
20500
20747
  var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
20501
20748
  var LINKEDIN_URL = /^https:\/\/www\.linkedin\.com\//;
@@ -20599,29 +20846,29 @@ app39.post("/", requireAdminSession, async (c) => {
20599
20846
  try {
20600
20847
  body = await c.req.json();
20601
20848
  } catch {
20602
- console.error(TAG28 + " rejected status=400 reason=schema:body-not-json");
20849
+ console.error(TAG29 + " rejected status=400 reason=schema:body-not-json");
20603
20850
  return c.json({ ok: false, error: "schema", reason: "body-not-json" }, 400);
20604
20851
  }
20605
20852
  const v = validate(body);
20606
20853
  if (!v.ok) {
20607
- console.error(TAG28 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
20854
+ console.error(TAG29 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
20608
20855
  return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
20609
20856
  }
20610
20857
  const envelope = v.envelope;
20611
20858
  const cacheKey = c.var.cacheKey ?? "";
20612
20859
  const senderId = getAccountIdForSession(cacheKey) ?? "";
20613
20860
  if (!senderId) {
20614
- console.error(TAG28 + " rejected status=500 reason=admin-account-not-resolved");
20861
+ console.error(TAG29 + " rejected status=500 reason=admin-account-not-resolved");
20615
20862
  return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
20616
20863
  }
20617
20864
  const payloadBytes = JSON.stringify(envelope).length;
20618
20865
  console.log(
20619
- TAG28 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
20866
+ TAG29 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
20620
20867
  );
20621
20868
  const initialMessage = buildInitialMessage(envelope);
20622
20869
  const spawnStart = Date.now();
20623
20870
  const sessionId = randomUUID13();
20624
- console.log(TAG28 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
20871
+ console.log(TAG29 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
20625
20872
  const spawned = await managerRcSpawn({
20626
20873
  sessionId,
20627
20874
  initialMessage,
@@ -20630,12 +20877,12 @@ app39.post("/", requireAdminSession, async (c) => {
20630
20877
  });
20631
20878
  if ("error" in spawned) {
20632
20879
  console.error(
20633
- TAG28 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
20880
+ TAG29 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
20634
20881
  );
20635
20882
  return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: spawned.status, detail: spawned.error }, 502);
20636
20883
  }
20637
20884
  console.log(
20638
- TAG28 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
20885
+ TAG29 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
20639
20886
  );
20640
20887
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
20641
20888
  });
@@ -20643,7 +20890,7 @@ var linkedin_ingest_default = app39;
20643
20890
 
20644
20891
  // server/routes/admin/post-turn-context.ts
20645
20892
  import neo4j3 from "neo4j-driver";
20646
- var TAG29 = "[post-turn-context]";
20893
+ var TAG30 = "[post-turn-context]";
20647
20894
  var STRIPPED_PROPERTIES2 = /* @__PURE__ */ new Set([
20648
20895
  "embedding",
20649
20896
  "passwordHash",
@@ -20685,7 +20932,7 @@ var app40 = new Hono();
20685
20932
  app40.get("/", async (c) => {
20686
20933
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20687
20934
  if (!isLoopbackAddr3(remoteAddr)) {
20688
- console.error(`${TAG29} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20935
+ console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20689
20936
  return c.json({ error: "post-turn-context-loopback-only" }, 403);
20690
20937
  }
20691
20938
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20694,7 +20941,7 @@ app40.get("/", async (c) => {
20694
20941
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
20695
20942
  const offender = tokens.find((t) => !isLoopbackAddr3(t));
20696
20943
  if (offender !== void 0) {
20697
- console.error(`${TAG29} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
20944
+ console.error(`${TAG30} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
20698
20945
  return c.json({ error: "post-turn-context-loopback-only" }, 403);
20699
20946
  }
20700
20947
  }
@@ -20726,7 +20973,7 @@ app40.get("/", async (c) => {
20726
20973
  writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
20727
20974
  const total = Date.now() - started;
20728
20975
  console.log(
20729
- `${TAG29} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
20976
+ `${TAG30} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
20730
20977
  );
20731
20978
  return c.json({
20732
20979
  writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
@@ -20735,7 +20982,7 @@ app40.get("/", async (c) => {
20735
20982
  const elapsed = Date.now() - started;
20736
20983
  const message = err instanceof Error ? err.message : String(err);
20737
20984
  console.error(
20738
- `${TAG29} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
20985
+ `${TAG30} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
20739
20986
  );
20740
20987
  return c.json({ error: `post-turn-context unavailable: ${message}` }, 503);
20741
20988
  } finally {
@@ -20848,7 +21095,7 @@ function formatPreviousContext(writes) {
20848
21095
  }
20849
21096
 
20850
21097
  // server/routes/admin/public-session-context.ts
20851
- var TAG30 = "[public-session-context]";
21098
+ var TAG31 = "[public-session-context]";
20852
21099
  function isLoopbackAddr4(addr) {
20853
21100
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
20854
21101
  }
@@ -20856,7 +21103,7 @@ var app41 = new Hono();
20856
21103
  app41.get("/", async (c) => {
20857
21104
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20858
21105
  if (!isLoopbackAddr4(remoteAddr)) {
20859
- console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21106
+ console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20860
21107
  return c.json({ error: "public-session-context-loopback-only" }, 403);
20861
21108
  }
20862
21109
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20865,7 +21112,7 @@ app41.get("/", async (c) => {
20865
21112
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
20866
21113
  const offender = tokens.find((t) => !isLoopbackAddr4(t));
20867
21114
  if (offender !== void 0) {
20868
- console.error(`${TAG30} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
21115
+ console.error(`${TAG31} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
20869
21116
  return c.json({ error: "public-session-context-loopback-only" }, 403);
20870
21117
  }
20871
21118
  }
@@ -20879,14 +21126,14 @@ app41.get("/", async (c) => {
20879
21126
  const writes = await fetchSliceWrites(session, sliceToken, accountId);
20880
21127
  const total = Date.now() - started;
20881
21128
  console.log(
20882
- `${TAG30} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
21129
+ `${TAG31} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
20883
21130
  );
20884
21131
  return c.json({ writes });
20885
21132
  } catch (err) {
20886
21133
  const elapsed = Date.now() - started;
20887
21134
  const message = err instanceof Error ? err.message : String(err);
20888
21135
  console.error(
20889
- `${TAG30} neo4j-unreachable sliceToken=${sliceToken.slice(0, 8)} ms=${elapsed} err="${message}"`
21136
+ `${TAG31} neo4j-unreachable sliceToken=${sliceToken.slice(0, 8)} ms=${elapsed} err="${message}"`
20890
21137
  );
20891
21138
  return c.json({ error: `public-session-context unavailable: ${message}` }, 503);
20892
21139
  } finally {
@@ -20905,7 +21152,7 @@ function getWebchatGateway() {
20905
21152
  }
20906
21153
 
20907
21154
  // server/routes/admin/public-session-exit.ts
20908
- var TAG31 = "[public-session-exit-route]";
21155
+ var TAG32 = "[public-session-exit-route]";
20909
21156
  function isLoopbackAddr5(addr) {
20910
21157
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
20911
21158
  }
@@ -20913,7 +21160,7 @@ var app42 = new Hono();
20913
21160
  app42.post("/", async (c) => {
20914
21161
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20915
21162
  if (!isLoopbackAddr5(remoteAddr)) {
20916
- console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21163
+ console.error(`${TAG32} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20917
21164
  return c.json({ error: "public-session-exit-loopback-only" }, 403);
20918
21165
  }
20919
21166
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20922,7 +21169,7 @@ app42.post("/", async (c) => {
20922
21169
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
20923
21170
  const offender = tokens.find((t) => !isLoopbackAddr5(t));
20924
21171
  if (offender !== void 0) {
20925
- console.error(`${TAG31} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
21172
+ console.error(`${TAG32} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
20926
21173
  return c.json({ error: "public-session-exit-loopback-only" }, 403);
20927
21174
  }
20928
21175
  }
@@ -20936,7 +21183,7 @@ app42.post("/", async (c) => {
20936
21183
  if (!sessionId) return c.json({ error: "sessionId required" }, 400);
20937
21184
  const gateway = getWebchatGateway();
20938
21185
  if (!gateway) {
20939
- console.error(`${TAG31} reject reason=gateway-unset sessionId=${sessionId.slice(0, 8)}`);
21186
+ console.error(`${TAG32} reject reason=gateway-unset sessionId=${sessionId.slice(0, 8)}`);
20940
21187
  return c.json({ error: "webchat-gateway-unset" }, 503);
20941
21188
  }
20942
21189
  gateway.handlePublicSessionExit(sessionId);
@@ -20945,7 +21192,7 @@ app42.post("/", async (c) => {
20945
21192
  var public_session_exit_default = app42;
20946
21193
 
20947
21194
  // server/routes/admin/access-session-evict.ts
20948
- var TAG32 = "[access-session-evict]";
21195
+ var TAG33 = "[access-session-evict]";
20949
21196
  function isLoopbackAddr6(addr) {
20950
21197
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
20951
21198
  }
@@ -20953,7 +21200,7 @@ var app43 = new Hono();
20953
21200
  app43.post("/", async (c) => {
20954
21201
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20955
21202
  if (!isLoopbackAddr6(remoteAddr)) {
20956
- console.error(`${TAG32} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21203
+ console.error(`${TAG33} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20957
21204
  return c.json({ error: "access-session-evict-loopback-only" }, 403);
20958
21205
  }
20959
21206
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20962,7 +21209,7 @@ app43.post("/", async (c) => {
20962
21209
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
20963
21210
  const offender = tokens.find((t) => !isLoopbackAddr6(t));
20964
21211
  if (offender !== void 0) {
20965
- console.error(`${TAG32} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
21212
+ console.error(`${TAG33} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
20966
21213
  return c.json({ error: "access-session-evict-loopback-only" }, 403);
20967
21214
  }
20968
21215
  }
@@ -20975,13 +21222,13 @@ app43.post("/", async (c) => {
20975
21222
  const grantId = typeof body.grantId === "string" ? body.grantId.trim() : "";
20976
21223
  if (!grantId) return c.json({ error: "grantId required" }, 400);
20977
21224
  const dropped = evictAccessSessionsByGrant(grantId);
20978
- console.log(`${TAG32} grantId=${grantId} dropped=${dropped}`);
21225
+ console.log(`${TAG33} grantId=${grantId} dropped=${dropped}`);
20979
21226
  return c.json({ ok: true, dropped });
20980
21227
  });
20981
21228
  var access_session_evict_default = app43;
20982
21229
 
20983
21230
  // server/routes/admin/enrol-person.ts
20984
- var TAG33 = "[enrol]";
21231
+ var TAG34 = "[enrol]";
20985
21232
  function isLoopbackAddr7(addr) {
20986
21233
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
20987
21234
  }
@@ -20990,7 +21237,7 @@ var app44 = new Hono();
20990
21237
  app44.post("/", async (c) => {
20991
21238
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20992
21239
  if (!isLoopbackAddr7(remoteAddr)) {
20993
- console.error(`${TAG33} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21240
+ console.error(`${TAG34} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20994
21241
  return c.json({ error: "enrol-person-loopback-only" }, 403);
20995
21242
  }
20996
21243
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20999,7 +21246,7 @@ app44.post("/", async (c) => {
20999
21246
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
21000
21247
  const offender = tokens.find((t) => !isLoopbackAddr7(t));
21001
21248
  if (offender !== void 0) {
21002
- console.error(`${TAG33} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
21249
+ console.error(`${TAG34} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
21003
21250
  return c.json({ error: "enrol-person-loopback-only" }, 403);
21004
21251
  }
21005
21252
  }
@@ -21024,7 +21271,7 @@ app44.post("/", async (c) => {
21024
21271
  }
21025
21272
  const accountId = process.env.ACCOUNT_ID ?? "";
21026
21273
  if (!accountId) {
21027
- console.error(`${TAG33} op=person result=no-account-id`);
21274
+ console.error(`${TAG34} op=person result=no-account-id`);
21028
21275
  return c.json({ error: "no-account-id" }, 500);
21029
21276
  }
21030
21277
  let personId;
@@ -21032,7 +21279,7 @@ app44.post("/", async (c) => {
21032
21279
  personId = await enrolPerson({ accountId, phone, email, agentSlug });
21033
21280
  } catch (err) {
21034
21281
  console.error(
21035
- `${TAG33} op=person result=write-failed agentSlug=${agentSlug} contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
21282
+ `${TAG34} op=person result=write-failed agentSlug=${agentSlug} contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
21036
21283
  );
21037
21284
  return c.json({ error: "enrol-failed" }, 500);
21038
21285
  }
@@ -21042,11 +21289,11 @@ app44.post("/", async (c) => {
21042
21289
  if (g) grant = { grantId: g.grantId, status: g.status, contactValue: g.contactValue };
21043
21290
  } catch (err) {
21044
21291
  console.error(
21045
- `${TAG33} op=person result=grant-lookup-failed contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
21292
+ `${TAG34} op=person result=grant-lookup-failed contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
21046
21293
  );
21047
21294
  }
21048
21295
  console.log(
21049
- `${TAG33} op=person personId=${personId} account=${accountId} agentSlug=${agentSlug} contact=${maskContact(email)}`
21296
+ `${TAG34} op=person personId=${personId} account=${accountId} agentSlug=${agentSlug} contact=${maskContact(email)}`
21050
21297
  );
21051
21298
  return c.json({ personId, grant }, 200);
21052
21299
  });
@@ -21092,8 +21339,8 @@ app45.post("/launch", requireAdminSession, async (c) => {
21092
21339
  var browser_default = app45;
21093
21340
 
21094
21341
  // server/routes/admin/calendar.ts
21095
- import { existsSync as existsSync30 } from "fs";
21096
- import { join as join34 } from "path";
21342
+ import { existsSync as existsSync31 } from "fs";
21343
+ import { join as join35 } from "path";
21097
21344
 
21098
21345
  // server/lib/calendar-ics.ts
21099
21346
  var CRLF = "\r\n";
@@ -21192,8 +21439,8 @@ function countVEvents(ics) {
21192
21439
  }
21193
21440
 
21194
21441
  // server/lib/calendar-availability.ts
21195
- import { readFileSync as readFileSync33 } from "fs";
21196
- import { join as join33 } from "path";
21442
+ import { readFileSync as readFileSync34 } from "fs";
21443
+ import { join as join34 } from "path";
21197
21444
  var AVAILABILITY_FILENAME = "calendar-availability.json";
21198
21445
  var REQUIRED_KEYS = [
21199
21446
  "timezone",
@@ -21202,10 +21449,10 @@ var REQUIRED_KEYS = [
21202
21449
  "weekly"
21203
21450
  ];
21204
21451
  function readAvailabilityConfig(accountDir) {
21205
- const path3 = join33(accountDir, AVAILABILITY_FILENAME);
21452
+ const path3 = join34(accountDir, AVAILABILITY_FILENAME);
21206
21453
  let raw;
21207
21454
  try {
21208
- raw = readFileSync33(path3, "utf-8");
21455
+ raw = readFileSync34(path3, "utf-8");
21209
21456
  } catch {
21210
21457
  throw new Error(`availability not configured: ${path3} not found`);
21211
21458
  }
@@ -21564,7 +21811,7 @@ app46.get("/booking-link", requireAdminSession, (c) => {
21564
21811
  console.error('[calendar] op=booking-link-fail err="no account configured"');
21565
21812
  return c.json({ bookingDomain: null });
21566
21813
  }
21567
- if (!existsSync30(join34(account.accountDir, AVAILABILITY_FILENAME))) {
21814
+ if (!existsSync31(join35(account.accountDir, AVAILABILITY_FILENAME))) {
21568
21815
  console.log("[calendar] op=booking-link bookingDomain=none source=availability-config");
21569
21816
  return c.json({ bookingDomain: null });
21570
21817
  }
@@ -21600,7 +21847,7 @@ function toNum(v) {
21600
21847
  }
21601
21848
 
21602
21849
  // server/routes/admin/tasks-list.ts
21603
- var TAG34 = "[task-timer]";
21850
+ var TAG35 = "[task-timer]";
21604
21851
  var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
21605
21852
  var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
21606
21853
  var app47 = new Hono();
@@ -21608,7 +21855,7 @@ app47.get("/", requireAdminSession, async (c) => {
21608
21855
  const cacheKey = c.var.cacheKey;
21609
21856
  const accountId = getAccountIdForSession(cacheKey);
21610
21857
  if (!accountId) {
21611
- console.error(`${TAG34} op=list auth-rejected reason="no account for session"`);
21858
+ console.error(`${TAG35} op=list auth-rejected reason="no account for session"`);
21612
21859
  return c.json({ error: "Account not found for session" }, 401);
21613
21860
  }
21614
21861
  const session = getSession();
@@ -21646,10 +21893,10 @@ app47.get("/", requireAdminSession, async (c) => {
21646
21893
  if (COMPLETED.has(status)) completed.push(row);
21647
21894
  else if (!HIDDEN_FROM_OPEN.has(status)) open.push(row);
21648
21895
  }
21649
- console.log(`${TAG34} op=list account=${accountId} open=${open.length} completed=${completed.length}`);
21896
+ console.log(`${TAG35} op=list account=${accountId} open=${open.length} completed=${completed.length}`);
21650
21897
  return c.json({ open, completed });
21651
21898
  } catch (err) {
21652
- console.error(`${TAG34} op=list error="${err instanceof Error ? err.message : String(err)}"`);
21899
+ console.error(`${TAG35} op=list error="${err instanceof Error ? err.message : String(err)}"`);
21653
21900
  return c.json({ error: "tasks-list-failed" }, 500);
21654
21901
  } finally {
21655
21902
  await session.close();
@@ -21659,7 +21906,7 @@ var tasks_list_default = app47;
21659
21906
 
21660
21907
  // server/routes/admin/task-timer-start.ts
21661
21908
  import { randomUUID as randomUUID14 } from "crypto";
21662
- var TAG35 = "[task-timer]";
21909
+ var TAG36 = "[task-timer]";
21663
21910
  var app48 = new Hono();
21664
21911
  app48.post("/", requireAdminSession, async (c) => {
21665
21912
  const cacheKey = c.var.cacheKey;
@@ -21681,7 +21928,7 @@ app48.post("/", requireAdminSession, async (c) => {
21681
21928
  { taskId, accountId }
21682
21929
  );
21683
21930
  if (target.records.length === 0) {
21684
- console.error(`${TAG35} op=start taskId=${taskId} accountId=${accountId} result=task-not-found`);
21931
+ console.error(`${TAG36} op=start taskId=${taskId} accountId=${accountId} result=task-not-found`);
21685
21932
  return c.json({ error: "task-not-found" }, 404);
21686
21933
  }
21687
21934
  const open = await session.run(
@@ -21693,7 +21940,7 @@ app48.post("/", requireAdminSession, async (c) => {
21693
21940
  const priorEntryId = open.records[0]?.get("entryId");
21694
21941
  const priorStartedAt = open.records[0]?.get("startedAt");
21695
21942
  if (priorEntryId) {
21696
- console.log(`${TAG35} op=start taskId=${taskId} accountId=${accountId} result=already-running`);
21943
+ console.log(`${TAG36} op=start taskId=${taskId} accountId=${accountId} result=already-running`);
21697
21944
  return c.json({ ok: true, running: true, entryId: priorEntryId, startedAt: priorStartedAt });
21698
21945
  }
21699
21946
  const entryId = randomUUID14();
@@ -21703,10 +21950,10 @@ app48.post("/", requireAdminSession, async (c) => {
21703
21950
  CREATE (te)-[:LOGGED_AGAINST]->(t)`,
21704
21951
  { taskId, accountId, entryId, now }
21705
21952
  );
21706
- console.log(`${TAG35} op=opened taskId=${taskId} entryId=${entryId} startedAt=${now}`);
21953
+ console.log(`${TAG36} op=opened taskId=${taskId} entryId=${entryId} startedAt=${now}`);
21707
21954
  return c.json({ ok: true, running: true, entryId, startedAt: now });
21708
21955
  } catch (err) {
21709
- console.error(`${TAG35} op=start error="${err instanceof Error ? err.message : String(err)}"`);
21956
+ console.error(`${TAG36} op=start error="${err instanceof Error ? err.message : String(err)}"`);
21710
21957
  return c.json({ error: "task-timer-start-failed" }, 500);
21711
21958
  } finally {
21712
21959
  await session.close();
@@ -21716,7 +21963,7 @@ var task_timer_start_default = app48;
21716
21963
 
21717
21964
  // server/routes/admin/task-timer-stop.ts
21718
21965
  import neo4j5 from "neo4j-driver";
21719
- var TAG36 = "[task-timer]";
21966
+ var TAG37 = "[task-timer]";
21720
21967
  var app49 = new Hono();
21721
21968
  app49.post("/", requireAdminSession, async (c) => {
21722
21969
  const cacheKey = c.var.cacheKey;
@@ -21748,7 +21995,7 @@ app49.post("/", requireAdminSession, async (c) => {
21748
21995
  { taskId, accountId }
21749
21996
  );
21750
21997
  const secondsLogged2 = toNum(cur.records[0]?.get("secondsLogged"));
21751
- console.log(`${TAG36} op=stop taskId=${taskId} entryId=none seconds=0 totalAfter=${secondsLogged2}`);
21998
+ console.log(`${TAG37} op=stop taskId=${taskId} entryId=none seconds=0 totalAfter=${secondsLogged2}`);
21752
21999
  return c.json({ ok: true, running: false, seconds: 0, secondsLogged: secondsLogged2 });
21753
22000
  }
21754
22001
  const seconds = secondsBetween(startedAt, now);
@@ -21771,11 +22018,11 @@ app49.post("/", requireAdminSession, async (c) => {
21771
22018
  const sumEntries = toNum(verify.records[0]?.get("sumEntries"));
21772
22019
  const sumAdjustments = toNum(verify.records[0]?.get("sumAdjustments"));
21773
22020
  const secondsLogged = toNum(verify.records[0]?.get("secondsLogged"));
21774
- console.log(`${TAG36} op=stop taskId=${taskId} entryId=${entryId} seconds=${seconds} totalAfter=${secondsLogged}`);
21775
- console.log(`${TAG36} op=persisted taskId=${taskId} entryId=${entryId} sumEntries=${sumEntries} sumAdjustments=${sumAdjustments} secondsLogged=${secondsLogged}`);
22021
+ console.log(`${TAG37} op=stop taskId=${taskId} entryId=${entryId} seconds=${seconds} totalAfter=${secondsLogged}`);
22022
+ console.log(`${TAG37} op=persisted taskId=${taskId} entryId=${entryId} sumEntries=${sumEntries} sumAdjustments=${sumAdjustments} secondsLogged=${secondsLogged}`);
21776
22023
  return c.json({ ok: true, running: false, seconds, secondsLogged });
21777
22024
  } catch (err) {
21778
- console.error(`${TAG36} op=stop error="${err instanceof Error ? err.message : String(err)}"`);
22025
+ console.error(`${TAG37} op=stop error="${err instanceof Error ? err.message : String(err)}"`);
21779
22026
  return c.json({ error: "task-timer-stop-failed" }, 500);
21780
22027
  } finally {
21781
22028
  await session.close();
@@ -21784,7 +22031,7 @@ app49.post("/", requireAdminSession, async (c) => {
21784
22031
  var task_timer_stop_default = app49;
21785
22032
 
21786
22033
  // server/routes/admin/task-complete.ts
21787
- var TAG37 = "[task-timer]";
22034
+ var TAG38 = "[task-timer]";
21788
22035
  var app50 = new Hono();
21789
22036
  app50.post("/", requireAdminSession, async (c) => {
21790
22037
  const cacheKey = c.var.cacheKey;
@@ -21811,10 +22058,10 @@ app50.post("/", requireAdminSession, async (c) => {
21811
22058
  return c.json({ error: "task-not-found" }, 404);
21812
22059
  }
21813
22060
  const secondsLogged = toNum(result.records[0].get("secondsLogged"));
21814
- console.log(`${TAG37} op=complete taskId=${taskId} status=completed secondsLogged=${secondsLogged}`);
22061
+ console.log(`${TAG38} op=complete taskId=${taskId} status=completed secondsLogged=${secondsLogged}`);
21815
22062
  return c.json({ ok: true, status: "completed", secondsLogged });
21816
22063
  } catch (err) {
21817
- console.error(`${TAG37} op=complete error="${err instanceof Error ? err.message : String(err)}"`);
22064
+ console.error(`${TAG38} op=complete error="${err instanceof Error ? err.message : String(err)}"`);
21818
22065
  return c.json({ error: "task-complete-failed" }, 500);
21819
22066
  } finally {
21820
22067
  await session.close();
@@ -21825,7 +22072,7 @@ var task_complete_default = app50;
21825
22072
  // server/routes/admin/task-time-adjust.ts
21826
22073
  import { randomUUID as randomUUID15 } from "crypto";
21827
22074
  import neo4j6 from "neo4j-driver";
21828
- var TAG38 = "[task-time-adjust]";
22075
+ var TAG39 = "[task-time-adjust]";
21829
22076
  var app51 = new Hono();
21830
22077
  app51.post("/", requireAdminSession, async (c) => {
21831
22078
  const cacheKey = c.var.cacheKey;
@@ -21835,22 +22082,22 @@ app51.post("/", requireAdminSession, async (c) => {
21835
22082
  try {
21836
22083
  body = await c.req.json();
21837
22084
  } catch {
21838
- console.error(`${TAG38} op=reject reason=bad-json`);
22085
+ console.error(`${TAG39} op=reject reason=bad-json`);
21839
22086
  return c.json({ error: "invalid-json" }, 400);
21840
22087
  }
21841
22088
  const taskId = typeof body.taskId === "string" ? body.taskId : "";
21842
22089
  if (!taskId) {
21843
- console.error(`${TAG38} op=reject reason=no-task`);
22090
+ console.error(`${TAG39} op=reject reason=no-task`);
21844
22091
  return c.json({ error: "taskId required" }, 400);
21845
22092
  }
21846
22093
  const newSeconds = body.newSeconds;
21847
22094
  if (typeof newSeconds !== "number" || !Number.isInteger(newSeconds) || newSeconds < 0) {
21848
- console.error(`${TAG38} op=reject reason=invalid-seconds taskId=${taskId} accountId=${accountId}`);
22095
+ console.error(`${TAG39} op=reject reason=invalid-seconds taskId=${taskId} accountId=${accountId}`);
21849
22096
  return c.json({ error: "newSeconds must be a non-negative integer" }, 400);
21850
22097
  }
21851
22098
  const adjustmentId = randomUUID15();
21852
22099
  const now = (/* @__PURE__ */ new Date()).toISOString();
21853
- console.log(`${TAG38} op=request adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId} newSeconds=${newSeconds}`);
22100
+ console.log(`${TAG39} op=request adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId} newSeconds=${newSeconds}`);
21854
22101
  const session = getSession();
21855
22102
  try {
21856
22103
  const guard = await session.run(
@@ -21860,12 +22107,12 @@ app51.post("/", requireAdminSession, async (c) => {
21860
22107
  { taskId, accountId }
21861
22108
  );
21862
22109
  if (guard.records.length === 0) {
21863
- console.error(`${TAG38} op=reject reason=no-task adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId}`);
22110
+ console.error(`${TAG39} op=reject reason=no-task adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId}`);
21864
22111
  return c.json({ error: "task-not-found" }, 404);
21865
22112
  }
21866
22113
  const openCount = toNum(guard.records[0].get("openCount"));
21867
22114
  if (openCount > 0) {
21868
- console.error(`${TAG38} op=reject reason=running adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId}`);
22115
+ console.error(`${TAG39} op=reject reason=running adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId}`);
21869
22116
  return c.json({ error: "task-timer-running" }, 409);
21870
22117
  }
21871
22118
  const previousSeconds = toNum(guard.records[0].get("previousSeconds"));
@@ -21891,10 +22138,10 @@ app51.post("/", requireAdminSession, async (c) => {
21891
22138
  }
21892
22139
  );
21893
22140
  const secondsLoggedAfter = toNum(write.records[0]?.get("secondsLoggedAfter"));
21894
- console.log(`${TAG38} op=persisted adjustmentId=${adjustmentId} previousSeconds=${previousSeconds} newSeconds=${newSeconds} delta=${delta} secondsLoggedAfter=${secondsLoggedAfter}`);
22141
+ console.log(`${TAG39} op=persisted adjustmentId=${adjustmentId} previousSeconds=${previousSeconds} newSeconds=${newSeconds} delta=${delta} secondsLoggedAfter=${secondsLoggedAfter}`);
21895
22142
  return c.json({ ok: true, secondsLogged: secondsLoggedAfter });
21896
22143
  } catch (err) {
21897
- console.error(`${TAG38} op=error adjustmentId=${adjustmentId} taskId=${taskId} error="${err instanceof Error ? err.message : String(err)}"`);
22144
+ console.error(`${TAG39} op=error adjustmentId=${adjustmentId} taskId=${taskId} error="${err instanceof Error ? err.message : String(err)}"`);
21898
22145
  return c.json({ error: "task-time-adjust-failed" }, 500);
21899
22146
  } finally {
21900
22147
  await session.close();
@@ -21948,7 +22195,7 @@ app52.route("/task-time-adjust", task_time_adjust_default);
21948
22195
  var admin_default = app52;
21949
22196
 
21950
22197
  // server/routes/access/verify-token.ts
21951
- var TAG39 = "[access-verify]";
22198
+ var TAG40 = "[access-verify]";
21952
22199
  var MINT_TAG = "[access-session-mint]";
21953
22200
  var COOKIE_NAME = "__access_session";
21954
22201
  var app53 = new Hono();
@@ -21967,39 +22214,39 @@ app53.post("/", async (c) => {
21967
22214
  }
21968
22215
  const rateMsg = checkAccessRateLimit(ip, agentSlug);
21969
22216
  if (rateMsg) {
21970
- console.error(`${TAG39} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
22217
+ console.error(`${TAG40} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
21971
22218
  return c.json({ error: rateMsg }, 429);
21972
22219
  }
21973
22220
  const grant = await findGrantByMagicToken(token);
21974
22221
  if (!grant) {
21975
22222
  recordAccessFailedAttempt(ip, agentSlug);
21976
- console.error(`${TAG39} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
22223
+ console.error(`${TAG40} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
21977
22224
  return c.json({ error: "invalid-or-expired-link" }, 401);
21978
22225
  }
21979
22226
  if (grant.agentSlug !== agentSlug) {
21980
22227
  recordAccessFailedAttempt(ip, agentSlug);
21981
22228
  console.error(
21982
- `${TAG39} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
22229
+ `${TAG40} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
21983
22230
  );
21984
22231
  return c.json({ error: "invalid-or-expired-link" }, 401);
21985
22232
  }
21986
22233
  if (grant.status === "expired" || grant.status === "revoked") {
21987
22234
  recordAccessFailedAttempt(ip, agentSlug);
21988
22235
  console.error(
21989
- `${TAG39} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
22236
+ `${TAG40} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
21990
22237
  );
21991
22238
  return c.json({ error: "access-no-longer-valid" }, 401);
21992
22239
  }
21993
22240
  if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
21994
22241
  recordAccessFailedAttempt(ip, agentSlug);
21995
22242
  console.error(
21996
- `${TAG39} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
22243
+ `${TAG40} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
21997
22244
  );
21998
22245
  return c.json({ error: "access-no-longer-valid" }, 401);
21999
22246
  }
22000
22247
  if (!grant.sliceToken) {
22001
22248
  console.error(
22002
- `${TAG39} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
22249
+ `${TAG40} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
22003
22250
  );
22004
22251
  return c.json({ error: "grant-misconfigured" }, 500);
22005
22252
  }
@@ -22015,12 +22262,12 @@ app53.post("/", async (c) => {
22015
22262
  await consumeMagicTokenAndActivate(grant.grantId);
22016
22263
  } catch (err) {
22017
22264
  console.error(
22018
- `${TAG39} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
22265
+ `${TAG40} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
22019
22266
  );
22020
22267
  return c.json({ error: "verification-failed" }, 500);
22021
22268
  }
22022
22269
  clearAccessRateLimit(ip, agentSlug);
22023
- console.log(`${TAG39} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
22270
+ console.log(`${TAG40} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
22024
22271
  console.log(
22025
22272
  `${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
22026
22273
  );
@@ -22096,7 +22343,7 @@ async function sendMagicLinkEmail(payload) {
22096
22343
  }
22097
22344
 
22098
22345
  // server/routes/access/request-magic-link.ts
22099
- var TAG40 = "[access-request-link]";
22346
+ var TAG41 = "[access-request-link]";
22100
22347
  var app54 = new Hono();
22101
22348
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
22102
22349
  app54.post("/", async (c) => {
@@ -22113,18 +22360,18 @@ app54.post("/", async (c) => {
22113
22360
  }
22114
22361
  const rateMsg = checkRequestLinkRateLimit(contactValue);
22115
22362
  if (rateMsg) {
22116
- console.error(`${TAG40} contactValue=${maskContact(contactValue)} result=rate-limited`);
22363
+ console.error(`${TAG41} contactValue=${maskContact(contactValue)} result=rate-limited`);
22117
22364
  return c.json({ error: rateMsg }, 429);
22118
22365
  }
22119
22366
  recordRequestLinkAttempt(contactValue);
22120
22367
  const accountId = process.env.ACCOUNT_ID ?? "";
22121
22368
  if (!accountId) {
22122
- console.error(`${TAG40} contactValue=${maskContact(contactValue)} result=no-account-id`);
22369
+ console.error(`${TAG41} contactValue=${maskContact(contactValue)} result=no-account-id`);
22123
22370
  return c.json({ message: VISITOR_MESSAGE }, 200);
22124
22371
  }
22125
22372
  const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
22126
22373
  if (!grant) {
22127
- console.log(`${TAG40} contactValue=${maskContact(contactValue)} result=notfound`);
22374
+ console.log(`${TAG41} contactValue=${maskContact(contactValue)} result=notfound`);
22128
22375
  return c.json({ message: VISITOR_MESSAGE }, 200);
22129
22376
  }
22130
22377
  let token;
@@ -22132,7 +22379,7 @@ app54.post("/", async (c) => {
22132
22379
  token = await generateNewMagicToken(grant.grantId);
22133
22380
  } catch (err) {
22134
22381
  console.error(
22135
- `${TAG40} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
22382
+ `${TAG41} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
22136
22383
  );
22137
22384
  return c.json({ message: VISITOR_MESSAGE }, 200);
22138
22385
  }
@@ -22164,12 +22411,12 @@ app54.post("/", async (c) => {
22164
22411
  });
22165
22412
  if (!sendResult.ok) {
22166
22413
  console.error(
22167
- `${TAG40} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
22414
+ `${TAG41} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
22168
22415
  );
22169
22416
  return c.json({ message: VISITOR_MESSAGE }, 200);
22170
22417
  }
22171
22418
  console.log(
22172
- `${TAG40} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
22419
+ `${TAG41} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
22173
22420
  );
22174
22421
  return c.json({ message: VISITOR_MESSAGE }, 200);
22175
22422
  });
@@ -22182,7 +22429,7 @@ app55.route("/request-magic-link", request_magic_link_default);
22182
22429
  var access_default = app55;
22183
22430
 
22184
22431
  // server/routes/sites.ts
22185
- import { existsSync as existsSync31, readFileSync as readFileSync34, realpathSync as realpathSync7, statSync as statSync12 } from "fs";
22432
+ import { existsSync as existsSync32, readFileSync as readFileSync35, realpathSync as realpathSync7, statSync as statSync12 } from "fs";
22186
22433
  import { resolve as resolve28 } from "path";
22187
22434
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
22188
22435
  var MIME = {
@@ -22248,7 +22495,7 @@ app56.get("/:rel{.*}", (c) => {
22248
22495
  }
22249
22496
  let stat8;
22250
22497
  try {
22251
- stat8 = existsSync31(filePath) ? statSync12(filePath) : null;
22498
+ stat8 = existsSync32(filePath) ? statSync12(filePath) : null;
22252
22499
  } catch {
22253
22500
  stat8 = null;
22254
22501
  }
@@ -22267,7 +22514,7 @@ app56.get("/:rel{.*}", (c) => {
22267
22514
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
22268
22515
  return c.text("Forbidden", 403);
22269
22516
  }
22270
- if (!existsSync31(filePath)) {
22517
+ if (!existsSync32(filePath)) {
22271
22518
  console.error(`[sites] not-found path=${reqPath} status=404`);
22272
22519
  return c.text("Not found", 404);
22273
22520
  }
@@ -22286,7 +22533,7 @@ app56.get("/:rel{.*}", (c) => {
22286
22533
  }
22287
22534
  let body;
22288
22535
  try {
22289
- body = readFileSync34(realPath);
22536
+ body = readFileSync35(realPath);
22290
22537
  } catch (err) {
22291
22538
  const code = err?.code;
22292
22539
  if (code === "EISDIR") {
@@ -22321,8 +22568,8 @@ app56.get("/:rel{.*}", (c) => {
22321
22568
  var sites_default = app56;
22322
22569
 
22323
22570
  // app/lib/visitor-token.ts
22324
- import { createHmac, randomBytes, timingSafeEqual } from "crypto";
22325
- import { mkdirSync as mkdirSync7, readFileSync as readFileSync35, writeFileSync as writeFileSync11 } from "fs";
22571
+ import { createHmac, randomBytes as randomBytes2, timingSafeEqual } from "crypto";
22572
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync36, writeFileSync as writeFileSync12 } from "fs";
22326
22573
  import { dirname as dirname12 } from "path";
22327
22574
  var TOKEN_PREFIX = "v1.";
22328
22575
  var SECRET_BYTES = 32;
@@ -22331,21 +22578,21 @@ var cachedSecret = null;
22331
22578
  function getSecret() {
22332
22579
  if (cachedSecret) return cachedSecret;
22333
22580
  try {
22334
- const hex2 = readFileSync35(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
22581
+ const hex2 = readFileSync36(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
22335
22582
  if (hex2.length === SECRET_BYTES * 2) {
22336
22583
  cachedSecret = Buffer.from(hex2, "hex");
22337
22584
  return cachedSecret;
22338
22585
  }
22339
22586
  } catch {
22340
22587
  }
22341
- const fresh = randomBytes(SECRET_BYTES).toString("hex");
22588
+ const fresh = randomBytes2(SECRET_BYTES).toString("hex");
22342
22589
  try {
22343
- mkdirSync7(dirname12(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
22344
- writeFileSync11(VISITOR_TOKEN_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
22590
+ mkdirSync8(dirname12(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
22591
+ writeFileSync12(VISITOR_TOKEN_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
22345
22592
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
22346
22593
  } catch {
22347
22594
  }
22348
- const hex = readFileSync35(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
22595
+ const hex = readFileSync36(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
22349
22596
  cachedSecret = Buffer.from(hex, "hex");
22350
22597
  return cachedSecret;
22351
22598
  }
@@ -22398,8 +22645,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
22398
22645
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
22399
22646
 
22400
22647
  // app/lib/brand-config.ts
22401
- import { existsSync as existsSync32, readFileSync as readFileSync36 } from "fs";
22402
- import { join as join35 } from "path";
22648
+ import { existsSync as existsSync33, readFileSync as readFileSync37 } from "fs";
22649
+ import { join as join36 } from "path";
22403
22650
  var cached2 = null;
22404
22651
  var cachedAttempted = false;
22405
22652
  function readBrandConfig() {
@@ -22407,10 +22654,10 @@ function readBrandConfig() {
22407
22654
  cachedAttempted = true;
22408
22655
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
22409
22656
  if (!platformRoot5) return null;
22410
- const brandPath = join35(platformRoot5, "config", "brand.json");
22411
- if (!existsSync32(brandPath)) return null;
22657
+ const brandPath = join36(platformRoot5, "config", "brand.json");
22658
+ if (!existsSync33(brandPath)) return null;
22412
22659
  try {
22413
- cached2 = JSON.parse(readFileSync36(brandPath, "utf-8"));
22660
+ cached2 = JSON.parse(readFileSync37(brandPath, "utf-8"));
22414
22661
  return cached2;
22415
22662
  } catch {
22416
22663
  return null;
@@ -22899,13 +23146,13 @@ var visitor_event_default = app59;
22899
23146
 
22900
23147
  // server/routes/session.ts
22901
23148
  import { resolve as resolve29 } from "path";
22902
- import { existsSync as existsSync33, writeFileSync as writeFileSync12, mkdirSync as mkdirSync8 } from "fs";
23149
+ import { existsSync as existsSync34, writeFileSync as writeFileSync13, mkdirSync as mkdirSync9 } from "fs";
22903
23150
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
22904
23151
  function writeBrandingCache(accountId, agentSlug, branding) {
22905
23152
  try {
22906
23153
  const cacheDir = resolve29(MAXY_DIR, "branding-cache", accountId);
22907
- mkdirSync8(cacheDir, { recursive: true });
22908
- writeFileSync12(resolve29(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
23154
+ mkdirSync9(cacheDir, { recursive: true });
23155
+ writeFileSync13(resolve29(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
22909
23156
  } catch (err) {
22910
23157
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
22911
23158
  }
@@ -22983,7 +23230,7 @@ app60.post("/", async (c) => {
22983
23230
  let agentConfig = null;
22984
23231
  if (account) {
22985
23232
  const agentDir = resolve29(account.accountDir, "agents", agentSlug);
22986
- if (!existsSync33(agentDir) || !existsSync33(resolve29(agentDir, "config.json"))) {
23233
+ if (!existsSync34(agentDir) || !existsSync34(resolve29(agentDir, "config.json"))) {
22987
23234
  return c.json({ error: "Agent not found" }, 404);
22988
23235
  }
22989
23236
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -23231,7 +23478,7 @@ app61.get("/free-busy", async (c) => {
23231
23478
  var calendar_public_default = app61;
23232
23479
 
23233
23480
  // app/lib/timeentry-census.ts
23234
- var TAG41 = "[timeentry-census]";
23481
+ var TAG42 = "[timeentry-census]";
23235
23482
  function reconcileTimeEntries(rows, now, horizonMs) {
23236
23483
  const openEntries = rows.openEntries.length;
23237
23484
  let oldestOpenAgeMs = 0;
@@ -23271,12 +23518,12 @@ async function runTimeEntryCensusOnce(session, now, horizonMs) {
23271
23518
  sumAdjustments: toNum(r.get("sumAdjustments"))
23272
23519
  }));
23273
23520
  const finding = reconcileTimeEntries({ openEntries, taskSums }, now, horizonMs);
23274
- const line = `${TAG41} openEntries=${finding.openEntries} oldestOpenAgeMin=${finding.oldestOpenAgeMin} maxOpenPerAccount=${finding.maxOpenPerAccount} driftTasks=${finding.driftTasks}`;
23521
+ const line = `${TAG42} openEntries=${finding.openEntries} oldestOpenAgeMin=${finding.oldestOpenAgeMin} maxOpenPerAccount=${finding.maxOpenPerAccount} driftTasks=${finding.driftTasks}`;
23275
23522
  if (finding.alarm) console.error(`${line} alarm=true`);
23276
23523
  else console.log(line);
23277
23524
  return finding;
23278
23525
  } catch (err) {
23279
- console.error(`${TAG41} error="${err instanceof Error ? err.message : String(err)}"`);
23526
+ console.error(`${TAG42} error="${err instanceof Error ? err.message : String(err)}"`);
23280
23527
  return null;
23281
23528
  }
23282
23529
  }
@@ -23290,13 +23537,13 @@ function startTimeEntryCensus(openSession, opts = {}) {
23290
23537
  try {
23291
23538
  session = openSession();
23292
23539
  } catch (err) {
23293
- console.error(`${TAG41} open-session-failed error="${err instanceof Error ? err.message : String(err)}"`);
23540
+ console.error(`${TAG42} open-session-failed error="${err instanceof Error ? err.message : String(err)}"`);
23294
23541
  return;
23295
23542
  }
23296
23543
  try {
23297
23544
  await runTimeEntryCensusOnce(session, Date.now(), horizonMs);
23298
23545
  } catch (err) {
23299
- console.error(`${TAG41} tick-failed error="${err instanceof Error ? err.message : String(err)}"`);
23546
+ console.error(`${TAG42} tick-failed error="${err instanceof Error ? err.message : String(err)}"`);
23300
23547
  } finally {
23301
23548
  try {
23302
23549
  await session.close();
@@ -23659,8 +23906,8 @@ async function migrateUploads(opts = {}) {
23659
23906
 
23660
23907
  // app/lib/migrate-admin-webchat-sidecars.ts
23661
23908
  import { readdir as readdir6, readFile as readFile6, rename as rename3, writeFile as writeFile4, unlink as unlink3 } from "fs/promises";
23662
- import { existsSync as existsSync34 } from "fs";
23663
- import { join as join36 } from "path";
23909
+ import { existsSync as existsSync35 } from "fs";
23910
+ import { join as join37 } from "path";
23664
23911
  var ADMIN_ROLE2 = "admin";
23665
23912
  var WEBCHAT_CHANNEL2 = "webchat";
23666
23913
  var SESSION_META_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
@@ -23689,7 +23936,7 @@ async function writeRaw(path3, obj) {
23689
23936
  await rename3(tmp, path3);
23690
23937
  } catch (err) {
23691
23938
  try {
23692
- if (existsSync34(tmp)) await unlink3(tmp);
23939
+ if (existsSync35(tmp)) await unlink3(tmp);
23693
23940
  } catch {
23694
23941
  }
23695
23942
  throw err;
@@ -23705,7 +23952,7 @@ async function collectLiveSidecars(projectsRoot) {
23705
23952
  }
23706
23953
  for (const slug of slugs) {
23707
23954
  if (!slug.isDirectory()) continue;
23708
- const slugDir = join36(projectsRoot, slug.name);
23955
+ const slugDir = join37(projectsRoot, slug.name);
23709
23956
  let entries;
23710
23957
  try {
23711
23958
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -23714,9 +23961,9 @@ async function collectLiveSidecars(projectsRoot) {
23714
23961
  }
23715
23962
  for (const entry of entries) {
23716
23963
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
23717
- out.push(join36(slugDir, entry.name));
23964
+ out.push(join37(slugDir, entry.name));
23718
23965
  } else if (entry.isDirectory() && entry.name === "subagents") {
23719
- const subDir = join36(slugDir, entry.name);
23966
+ const subDir = join37(slugDir, entry.name);
23720
23967
  let subs;
23721
23968
  try {
23722
23969
  subs = await readdir6(subDir, { withFileTypes: true });
@@ -23724,7 +23971,7 @@ async function collectLiveSidecars(projectsRoot) {
23724
23971
  continue;
23725
23972
  }
23726
23973
  for (const s of subs) {
23727
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join36(subDir, s.name));
23974
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join37(subDir, s.name));
23728
23975
  }
23729
23976
  }
23730
23977
  }
@@ -23736,7 +23983,7 @@ function shortId(path3) {
23736
23983
  return base.slice(0, 8);
23737
23984
  }
23738
23985
  async function migrateAdminWebchatSidecars(opts = {}) {
23739
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join36(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
23986
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join37(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
23740
23987
  const usersFile = opts.usersFile ?? USERS_FILE;
23741
23988
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
23742
23989
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -25404,14 +25651,14 @@ function makeFileDelivery(opts) {
25404
25651
  }
25405
25652
 
25406
25653
  // app/lib/webchat/file-delivery.ts
25407
- var TAG42 = "[webchat-adaptor]";
25654
+ var TAG43 = "[webchat-adaptor]";
25408
25655
  function platformRoot2() {
25409
25656
  return process.env.MAXY_PLATFORM_ROOT || "";
25410
25657
  }
25411
25658
  function makeWebchatSendFile(entry) {
25412
25659
  return async (filePath) => {
25413
25660
  if (!entry.accountId) {
25414
- console.error(`${TAG42} file-delivery reject reason=no-account sender=${entry.senderId}`);
25661
+ console.error(`${TAG43} file-delivery reject reason=no-account sender=${entry.senderId}`);
25415
25662
  return { ok: false, error: "no-account" };
25416
25663
  }
25417
25664
  const accountDir = resolve32(platformRoot2(), "..", "data/accounts", entry.accountId);
@@ -25419,14 +25666,14 @@ function makeWebchatSendFile(entry) {
25419
25666
  const resolved = realpathSync8(filePath);
25420
25667
  const accountResolved = realpathSync8(accountDir);
25421
25668
  if (!resolved.startsWith(accountResolved + "/")) {
25422
- console.error(`${TAG42} file-delivery reject reason=outside_account_directory sender=${entry.senderId}`);
25669
+ console.error(`${TAG43} file-delivery reject reason=outside_account_directory sender=${entry.senderId}`);
25423
25670
  return { ok: false, error: "outside-account" };
25424
25671
  }
25425
25672
  return { ok: true };
25426
25673
  } catch (err) {
25427
25674
  const code = err.code;
25428
25675
  console.error(
25429
- `${TAG42} file-delivery reject reason=${code === "ENOENT" ? "not-found" : "path-error"} sender=${entry.senderId}`
25676
+ `${TAG43} file-delivery reject reason=${code === "ENOENT" ? "not-found" : "path-error"} sender=${entry.senderId}`
25430
25677
  );
25431
25678
  return { ok: false, error: code === "ENOENT" ? "not-found" : "path-error" };
25432
25679
  }
@@ -25435,7 +25682,7 @@ function makeWebchatSendFile(entry) {
25435
25682
  function makeWebchatFileDelivery(entry) {
25436
25683
  return makeFileDelivery({
25437
25684
  entry,
25438
- tag: TAG42,
25685
+ tag: TAG43,
25439
25686
  channel: "webchat",
25440
25687
  sendFile: makeWebchatSendFile(entry),
25441
25688
  deferUntilVerdict: true
@@ -25497,7 +25744,7 @@ function buildPublicWebchatSpawnRequest(input) {
25497
25744
  }
25498
25745
 
25499
25746
  // app/lib/whatsapp/inbound/file-delivery-bridge.ts
25500
- var TAG43 = "[whatsapp-adaptor]";
25747
+ var TAG44 = "[whatsapp-adaptor]";
25501
25748
  var SEND_USER_FILE2 = "SendUserFile";
25502
25749
  var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
25503
25750
  function platformRoot3() {
@@ -25515,7 +25762,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
25515
25762
  });
25516
25763
  if (result.ok) return { ok: true };
25517
25764
  console.error(
25518
- `${TAG43} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
25765
+ `${TAG44} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
25519
25766
  );
25520
25767
  return { ok: false, error: result.error };
25521
25768
  };
@@ -25523,7 +25770,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
25523
25770
  function makeWhatsAppFileDelivery(entry, maxyAccountId) {
25524
25771
  const shared = makeFileDelivery({
25525
25772
  entry,
25526
- tag: TAG43,
25773
+ tag: TAG44,
25527
25774
  channel: "whatsapp",
25528
25775
  sendFile: makeWhatsAppSendFile(entry, maxyAccountId)
25529
25776
  });
@@ -25558,7 +25805,7 @@ function makeWhatsAppFileDelivery(entry, maxyAccountId) {
25558
25805
  if (!delivered) {
25559
25806
  const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
25560
25807
  console.error(
25561
- `${TAG43} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
25808
+ `${TAG44} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
25562
25809
  );
25563
25810
  }
25564
25811
  }
@@ -25590,20 +25837,29 @@ function startNativeFileFollower(input) {
25590
25837
  };
25591
25838
  const sid = input.senderId.slice(0, 8);
25592
25839
  let lastComposingAt = Number.NEGATIVE_INFINITY;
25840
+ const presenceSock = (state) => {
25841
+ const res = resolveSocket(input.accountId);
25842
+ if (!res.ok) {
25843
+ console.error(
25844
+ `[whatsapp-adaptor] op=presence state=${state} sender=${sid} ok=false reason=${formatSocketResolutionReason(res)}`
25845
+ );
25846
+ return null;
25847
+ }
25848
+ console.error(`[whatsapp-adaptor] op=presence state=${state} sender=${sid}`);
25849
+ return res.sock;
25850
+ };
25593
25851
  const onActivity = () => {
25594
25852
  const now = Date.now();
25595
25853
  if (now - lastComposingAt < COMPOSING_REFRESH_MS) return;
25596
25854
  lastComposingAt = now;
25597
- const sock = getSocket(input.accountId);
25855
+ const sock = presenceSock("composing");
25598
25856
  if (!sock) return;
25599
- console.error(`[whatsapp-adaptor] op=presence state=composing sender=${sid}`);
25600
25857
  void sendComposing(sock, input.senderId);
25601
25858
  };
25602
25859
  const onTurnComplete = () => {
25603
25860
  lastComposingAt = Number.NEGATIVE_INFINITY;
25604
- const sock = getSocket(input.accountId);
25861
+ const sock = presenceSock("paused");
25605
25862
  if (!sock) return;
25606
- console.error(`[whatsapp-adaptor] op=presence state=paused sender=${sid}`);
25607
25863
  void sendPaused(sock, input.senderId);
25608
25864
  };
25609
25865
  return startFollower({
@@ -25953,7 +26209,7 @@ function buildTelegramSpawnRequest(input) {
25953
26209
  import { realpathSync as realpathSync9 } from "fs";
25954
26210
  import { readFile as readFile7, stat as stat7 } from "fs/promises";
25955
26211
  import { resolve as resolve33, basename as basename11 } from "path";
25956
- var TAG44 = "[telegram:outbound]";
26212
+ var TAG45 = "[telegram:outbound]";
25957
26213
  var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
25958
26214
  async function sendTelegramDocument(input) {
25959
26215
  const { botToken, chatId, filePath, caption, maxyAccountId, platformRoot: platformRoot5 } = input;
@@ -25969,16 +26225,16 @@ async function sendTelegramDocument(input) {
25969
26225
  resolvedPath = realpathSync9(filePath);
25970
26226
  const accountResolved = realpathSync9(accountDir);
25971
26227
  if (!resolvedPath.startsWith(accountResolved + "/")) {
25972
- console.error(`${TAG44} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
26228
+ console.error(`${TAG45} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
25973
26229
  return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
25974
26230
  }
25975
26231
  } catch (err) {
25976
26232
  const code = err.code;
25977
26233
  if (code === "ENOENT") {
25978
- console.error(`${TAG44} document ENOENT path=${filePath}`);
26234
+ console.error(`${TAG45} document ENOENT path=${filePath}`);
25979
26235
  return { ok: false, status: 404, error: `File not found: ${filePath}` };
25980
26236
  }
25981
- console.error(`${TAG44} document path error: ${String(err)}`);
26237
+ console.error(`${TAG45} document path error: ${String(err)}`);
25982
26238
  return { ok: false, status: 500, error: String(err) };
25983
26239
  }
25984
26240
  const fileStat = await stat7(resolvedPath);
@@ -26011,13 +26267,13 @@ async function sendTelegramDocument(input) {
26011
26267
  error = e instanceof Error ? e.message : String(e);
26012
26268
  }
26013
26269
  console.error(
26014
- `${TAG44} sent document to=${chatId} file=${filename} bytes=${fileStat.size} ok=${ok}` + (messageId !== void 0 ? ` id=${messageId}` : "")
26270
+ `${TAG45} sent document to=${chatId} file=${filename} bytes=${fileStat.size} ok=${ok}` + (messageId !== void 0 ? ` id=${messageId}` : "")
26015
26271
  );
26016
26272
  return ok ? { ok: true, messageId } : { ok: false, status: 500, error };
26017
26273
  }
26018
26274
 
26019
26275
  // app/lib/telegram/outbound/file-delivery.ts
26020
- var TAG45 = "[telegram:outbound]";
26276
+ var TAG46 = "[telegram:outbound]";
26021
26277
  function platformRoot4() {
26022
26278
  return process.env.MAXY_PLATFORM_ROOT || "";
26023
26279
  }
@@ -26029,11 +26285,11 @@ function makeTelegramSendFile(entry) {
26029
26285
  botToken = (entry.role === "admin" ? tg?.adminBotToken : tg?.publicBotToken) ?? null;
26030
26286
  }
26031
26287
  if (!botToken) {
26032
- console.error(`${TAG45} file-delivery reject reason=no-bot-token sender=${entry.senderId} role=${entry.role}`);
26288
+ console.error(`${TAG46} file-delivery reject reason=no-bot-token sender=${entry.senderId} role=${entry.role}`);
26033
26289
  return { ok: false, error: "no-bot-token" };
26034
26290
  }
26035
26291
  if (entry.replyTarget == null) {
26036
- console.error(`${TAG45} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
26292
+ console.error(`${TAG46} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
26037
26293
  return { ok: false, error: "no-reply-target" };
26038
26294
  }
26039
26295
  const result = await sendTelegramDocument({
@@ -26050,7 +26306,7 @@ function makeTelegramSendFile(entry) {
26050
26306
  function makeTelegramFileDelivery(entry) {
26051
26307
  return makeFileDelivery({
26052
26308
  entry,
26053
- tag: TAG45,
26309
+ tag: TAG46,
26054
26310
  channel: "telegram",
26055
26311
  sendFile: makeTelegramSendFile(entry)
26056
26312
  });
@@ -26090,17 +26346,17 @@ function startTelegramNativeFileFollower(input) {
26090
26346
  }
26091
26347
 
26092
26348
  // server/telegram-descriptor.ts
26093
- import { resolve as resolve34, join as join37 } from "path";
26349
+ import { resolve as resolve34, join as join38 } from "path";
26094
26350
  function telegramGatewayUrl() {
26095
26351
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
26096
26352
  }
26097
26353
  function telegramServerPath() {
26098
- return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve34(process.env.MAXY_PLATFORM_ROOT ?? join37(__dirname, ".."), "services/telegram-channel/dist/server.js");
26354
+ return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve34(process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, ".."), "services/telegram-channel/dist/server.js");
26099
26355
  }
26100
26356
 
26101
26357
  // app/lib/channel-pty-bridge/public-session-end-review.ts
26102
26358
  import { randomUUID as randomUUID16 } from "crypto";
26103
- var TAG46 = "[public-session-review]";
26359
+ var TAG47 = "[public-session-review]";
26104
26360
  var CONSUMED_CAP = 500;
26105
26361
  var consumed = /* @__PURE__ */ new Set();
26106
26362
  function consumeOnce(sessionId) {
@@ -26127,7 +26383,7 @@ async function fetchJsonl(sessionId) {
26127
26383
  return await res.text();
26128
26384
  } catch (err) {
26129
26385
  console.error(
26130
- `${TAG46} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
26386
+ `${TAG47} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
26131
26387
  );
26132
26388
  return null;
26133
26389
  }
@@ -26151,7 +26407,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
26151
26407
  const res = await fetch(url);
26152
26408
  if (!res.ok) {
26153
26409
  console.error(
26154
- `${TAG46} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
26410
+ `${TAG47} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
26155
26411
  );
26156
26412
  return [];
26157
26413
  }
@@ -26159,7 +26415,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
26159
26415
  return Array.isArray(body.writes) ? body.writes : [];
26160
26416
  } catch (err) {
26161
26417
  console.error(
26162
- `${TAG46} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
26418
+ `${TAG47} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
26163
26419
  );
26164
26420
  return [];
26165
26421
  }
@@ -26188,7 +26444,7 @@ function composeInitialMessage(input) {
26188
26444
  }
26189
26445
  async function dispatchReviewer(input, initialMessage) {
26190
26446
  const sessionId = randomUUID16();
26191
- console.log(`${TAG46} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
26447
+ console.log(`${TAG47} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
26192
26448
  const spawned = await managerRcSpawn({
26193
26449
  sessionId,
26194
26450
  initialMessage,
@@ -26208,21 +26464,21 @@ async function firePublicSessionEndReview(input) {
26208
26464
  const dispatchedAt = Date.now();
26209
26465
  if (consumed.has(input.sessionId)) {
26210
26466
  console.log(
26211
- `${TAG46} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
26467
+ `${TAG47} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
26212
26468
  );
26213
26469
  return;
26214
26470
  }
26215
26471
  const jsonl = await fetchJsonl(input.sessionId);
26216
26472
  if (!jsonl) {
26217
26473
  console.log(
26218
- `${TAG46} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
26474
+ `${TAG47} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
26219
26475
  );
26220
26476
  return;
26221
26477
  }
26222
26478
  const operatorTurns = countOperatorTurns(jsonl);
26223
26479
  if (operatorTurns === 0) {
26224
26480
  console.log(
26225
- `${TAG46} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
26481
+ `${TAG47} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
26226
26482
  );
26227
26483
  return;
26228
26484
  }
@@ -26236,19 +26492,19 @@ async function firePublicSessionEndReview(input) {
26236
26492
  });
26237
26493
  if (!consumeOnce(input.sessionId)) {
26238
26494
  console.log(
26239
- `${TAG46} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
26495
+ `${TAG47} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
26240
26496
  );
26241
26497
  return;
26242
26498
  }
26243
26499
  const dispatched = await dispatchReviewer(input, initialMessage);
26244
26500
  if (!dispatched.ok) {
26245
26501
  console.error(
26246
- `${TAG46} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
26502
+ `${TAG47} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
26247
26503
  );
26248
26504
  return;
26249
26505
  }
26250
26506
  console.log(
26251
- `${TAG46} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
26507
+ `${TAG47} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
26252
26508
  );
26253
26509
  }
26254
26510
 
@@ -26382,7 +26638,7 @@ function broadcastAdminShutdown(reason) {
26382
26638
 
26383
26639
  // ../lib/entitlement/src/index.ts
26384
26640
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
26385
- import { existsSync as existsSync35, readFileSync as readFileSync37, statSync as statSync13 } from "fs";
26641
+ import { existsSync as existsSync36, readFileSync as readFileSync38, statSync as statSync13 } from "fs";
26386
26642
  import { resolve as resolve35 } from "path";
26387
26643
 
26388
26644
  // ../lib/entitlement/src/canonicalize.ts
@@ -26431,7 +26687,7 @@ function resolveEntitlement(brand, account) {
26431
26687
  return logResolved(implicitTrust(account), null);
26432
26688
  }
26433
26689
  const entitlementPath = resolve35(brand.configDir, "entitlement.json");
26434
- if (!existsSync35(entitlementPath)) {
26690
+ if (!existsSync36(entitlementPath)) {
26435
26691
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
26436
26692
  }
26437
26693
  const stat8 = statSync13(entitlementPath);
@@ -26446,7 +26702,7 @@ function resolveEntitlement(brand, account) {
26446
26702
  function verifyAndResolve(brand, entitlementPath, account) {
26447
26703
  let pubkeyPem;
26448
26704
  try {
26449
- pubkeyPem = readFileSync37(pubkeyPath(brand), "utf-8");
26705
+ pubkeyPem = readFileSync38(pubkeyPath(brand), "utf-8");
26450
26706
  } catch (err) {
26451
26707
  return logResolved(anonymousFallback("pubkey-missing"), {
26452
26708
  reason: "pubkey-missing"
@@ -26460,7 +26716,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
26460
26716
  }
26461
26717
  let envelope;
26462
26718
  try {
26463
- envelope = JSON.parse(readFileSync37(entitlementPath, "utf-8"));
26719
+ envelope = JSON.parse(readFileSync38(entitlementPath, "utf-8"));
26464
26720
  } catch {
26465
26721
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
26466
26722
  }
@@ -26621,14 +26877,14 @@ function clientFrom(c) {
26621
26877
  );
26622
26878
  }
26623
26879
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
26624
- var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join38(PLATFORM_ROOT8, "config", "brand.json") : "";
26880
+ var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join39(PLATFORM_ROOT8, "config", "brand.json") : "";
26625
26881
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
26626
- if (BRAND_JSON_PATH && !existsSync36(BRAND_JSON_PATH)) {
26882
+ if (BRAND_JSON_PATH && !existsSync37(BRAND_JSON_PATH)) {
26627
26883
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
26628
26884
  }
26629
- if (BRAND_JSON_PATH && existsSync36(BRAND_JSON_PATH)) {
26885
+ if (BRAND_JSON_PATH && existsSync37(BRAND_JSON_PATH)) {
26630
26886
  try {
26631
- const parsed = JSON.parse(readFileSync38(BRAND_JSON_PATH, "utf-8"));
26887
+ const parsed = JSON.parse(readFileSync39(BRAND_JSON_PATH, "utf-8"));
26632
26888
  BRAND = { ...BRAND, ...parsed };
26633
26889
  } catch (err) {
26634
26890
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -26660,11 +26916,11 @@ var brandLoginOpts = {
26660
26916
  appleTouchIconPath: brandAppIcon512Path,
26661
26917
  themeColor: BRAND.defaultColors?.primary
26662
26918
  };
26663
- var ALIAS_DOMAINS_PATH = join38(homedir4(), BRAND.configDir, "alias-domains.json");
26919
+ var ALIAS_DOMAINS_PATH = join39(homedir4(), BRAND.configDir, "alias-domains.json");
26664
26920
  function loadAliasDomains() {
26665
26921
  try {
26666
- if (!existsSync36(ALIAS_DOMAINS_PATH)) return null;
26667
- const parsed = JSON.parse(readFileSync38(ALIAS_DOMAINS_PATH, "utf-8"));
26922
+ if (!existsSync37(ALIAS_DOMAINS_PATH)) return null;
26923
+ const parsed = JSON.parse(readFileSync39(ALIAS_DOMAINS_PATH, "utf-8"));
26668
26924
  if (!Array.isArray(parsed)) {
26669
26925
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
26670
26926
  return null;
@@ -26728,7 +26984,7 @@ async function recordPassiveDispatch(input) {
26728
26984
  var waGateway = new WaGateway({
26729
26985
  fetchStandingRules: fetchAccountStandingRules,
26730
26986
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
26731
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve36(process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
26987
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve36(process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
26732
26988
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
26733
26989
  // path-validation scope) is the sender's effective SESSION account, resolved
26734
26990
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -26743,7 +26999,7 @@ var waGateway = new WaGateway({
26743
26999
  caption,
26744
27000
  accountId,
26745
27001
  maxyAccountId,
26746
- platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, ".."))
27002
+ platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, ".."))
26747
27003
  });
26748
27004
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
26749
27005
  },
@@ -26840,7 +27096,7 @@ function runDuplicateSenderAudit() {
26840
27096
  try {
26841
27097
  const configDir2 = process.env.CLAUDE_CONFIG_DIR;
26842
27098
  if (!configDir2) return;
26843
- const projectsRoot = join38(configDir2, "projects");
27099
+ const projectsRoot = join39(configDir2, "projects");
26844
27100
  const records = [];
26845
27101
  for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
26846
27102
  if (isSubagent || archived) continue;
@@ -27000,10 +27256,11 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
27000
27256
  const res = resolveSocket(accountId);
27001
27257
  if (!res.ok) {
27002
27258
  if (res.reason === "key-miss") {
27003
- console.error(`[whatsapp-native] op=socket-key-miss accountId=${accountId} presentKeys=${res.presentKeys.join(",") || "none"}`);
27004
- throw new Error(`WhatsApp socket key miss: no socket is registered for accountId=${accountId} (present keys: ${res.presentKeys.join(",") || "none"}). This is an account-keying fault, not a dropped link \u2014 do not advise re-pairing.`);
27259
+ console.error(`[whatsapp-native] op=socket-key-miss accountId=${accountId} presentKeys=${formatPresentKeys(res.presentKeys)}`);
27005
27260
  }
27006
- throw new Error(`WhatsApp disconnected: the socket for accountId=${accountId} is registered but its transport is down; cannot deliver scheduled reply.`);
27261
+ throw new Error(
27262
+ formatSocketResolutionMessage(res, accountId, { disconnectedClause: "cannot deliver scheduled reply" })
27263
+ );
27007
27264
  }
27008
27265
  await sendTextMessage(res.sock, toWhatsappJid(destination), text, { accountId: res.accountId });
27009
27266
  },
@@ -27353,6 +27610,13 @@ app62.route("/api/webchat", createWebchatRoutes({
27353
27610
  app62.route("/api/webchat/greeting", webchat_greeting_default);
27354
27611
  app62.route("/api/telegram", telegram_default);
27355
27612
  app62.route("/api/quickbooks", quickbooks_default);
27613
+ app62.route(
27614
+ "/api/google",
27615
+ createGoogleOAuthRoutes(
27616
+ resolve36(process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..")),
27617
+ resolve36(process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, ".."), "..", "data/accounts")
27618
+ )
27619
+ );
27356
27620
  app62.route("/api/onboarding", onboarding_default);
27357
27621
  app62.route("/api/admin", admin_default);
27358
27622
  app62.route("/api/access", access_default);
@@ -27391,14 +27655,14 @@ app62.get("/agent-assets/:slug/:filename", (c) => {
27391
27655
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
27392
27656
  return c.text("Forbidden", 403);
27393
27657
  }
27394
- if (!existsSync36(filePath)) {
27658
+ if (!existsSync37(filePath)) {
27395
27659
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
27396
27660
  return c.text("Not found", 404);
27397
27661
  }
27398
27662
  const ext = "." + filename.split(".").pop()?.toLowerCase();
27399
27663
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
27400
27664
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
27401
- const body = readFileSync38(filePath);
27665
+ const body = readFileSync39(filePath);
27402
27666
  return c.body(body, 200, {
27403
27667
  "Content-Type": contentType,
27404
27668
  "Cache-Control": "public, max-age=3600"
@@ -27421,14 +27685,14 @@ app62.get("/generated/:filename", (c) => {
27421
27685
  console.error(`[generated] serve file=${filename} status=403`);
27422
27686
  return c.text("Forbidden", 403);
27423
27687
  }
27424
- if (!existsSync36(filePath)) {
27688
+ if (!existsSync37(filePath)) {
27425
27689
  console.error(`[generated] serve file=${filename} status=404`);
27426
27690
  return c.text("Not found", 404);
27427
27691
  }
27428
27692
  const ext = "." + filename.split(".").pop()?.toLowerCase();
27429
27693
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
27430
27694
  console.log(`[generated] serve file=${filename} status=200`);
27431
- const body = readFileSync38(filePath);
27695
+ const body = readFileSync39(filePath);
27432
27696
  return c.body(body, 200, {
27433
27697
  "Content-Type": contentType,
27434
27698
  "Cache-Control": "public, max-age=86400"
@@ -27441,9 +27705,9 @@ app62.route("/v", visitor_consent_default);
27441
27705
  var htmlCache = /* @__PURE__ */ new Map();
27442
27706
  var brandLogoPath = "/brand/maxy-monochrome.png";
27443
27707
  var brandIconPath = "/brand/maxy-monochrome.png";
27444
- if (BRAND_JSON_PATH && existsSync36(BRAND_JSON_PATH)) {
27708
+ if (BRAND_JSON_PATH && existsSync37(BRAND_JSON_PATH)) {
27445
27709
  try {
27446
- const fullBrand = JSON.parse(readFileSync38(BRAND_JSON_PATH, "utf-8"));
27710
+ const fullBrand = JSON.parse(readFileSync39(BRAND_JSON_PATH, "utf-8"));
27447
27711
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
27448
27712
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
27449
27713
  } catch {
@@ -27470,11 +27734,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
27470
27734
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
27471
27735
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
27472
27736
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
27473
- (p) => existsSync36(resolve36(process.cwd(), "public", p.replace(/^\//, "")))
27737
+ (p) => existsSync37(resolve36(process.cwd(), "public", p.replace(/^\//, "")))
27474
27738
  );
27475
27739
  var SW_SOURCE = (() => {
27476
27740
  try {
27477
- return readFileSync38(resolve36(process.cwd(), "public", "sw.js"), "utf-8");
27741
+ return readFileSync39(resolve36(process.cwd(), "public", "sw.js"), "utf-8");
27478
27742
  } catch {
27479
27743
  return null;
27480
27744
  }
@@ -27482,9 +27746,9 @@ var SW_SOURCE = (() => {
27482
27746
  function readInstalledVersion() {
27483
27747
  try {
27484
27748
  if (!PLATFORM_ROOT8) return "unknown";
27485
- const versionFile = join38(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
27486
- if (!existsSync36(versionFile)) return "unknown";
27487
- const content = readFileSync38(versionFile, "utf-8").trim();
27749
+ const versionFile = join39(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
27750
+ if (!existsSync37(versionFile)) return "unknown";
27751
+ const content = readFileSync39(versionFile, "utf-8").trim();
27488
27752
  return content || "unknown";
27489
27753
  } catch {
27490
27754
  return "unknown";
@@ -27525,7 +27789,7 @@ var clientErrorReporterScript = `<script>
27525
27789
  function cachedHtml(file) {
27526
27790
  let html = htmlCache.get(file);
27527
27791
  if (!html) {
27528
- html = readFileSync38(resolve36(process.cwd(), "public", file), "utf-8");
27792
+ html = readFileSync39(resolve36(process.cwd(), "public", file), "utf-8");
27529
27793
  const productNameEsc = escapeHtml(BRAND.productName);
27530
27794
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
27531
27795
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -27542,13 +27806,13 @@ ${clientErrorReporterScript}
27542
27806
  return html;
27543
27807
  }
27544
27808
  function loadBrandingCache(agentSlug) {
27545
- const configDir2 = join38(homedir4(), BRAND.configDir);
27809
+ const configDir2 = join39(homedir4(), BRAND.configDir);
27546
27810
  try {
27547
27811
  const accountId = getDefaultAccountId();
27548
27812
  if (!accountId) return null;
27549
- const cachePath = join38(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
27550
- if (!existsSync36(cachePath)) return null;
27551
- return JSON.parse(readFileSync38(cachePath, "utf-8"));
27813
+ const cachePath = join39(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
27814
+ if (!existsSync37(cachePath)) return null;
27815
+ return JSON.parse(readFileSync39(cachePath, "utf-8"));
27552
27816
  } catch {
27553
27817
  return null;
27554
27818
  }
@@ -27643,7 +27907,7 @@ app62.use("/vnc-popout.html", logViewerFetch);
27643
27907
  app62.get("/vnc-popout.html", (c) => {
27644
27908
  let html = htmlCache.get("vnc-popout.html");
27645
27909
  if (!html) {
27646
- html = readFileSync38(resolve36(process.cwd(), "public", "vnc-popout.html"), "utf-8");
27910
+ html = readFileSync39(resolve36(process.cwd(), "public", "vnc-popout.html"), "utf-8");
27647
27911
  const name = escapeHtml(BRAND.productName);
27648
27912
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
27649
27913
  html = html.replace("</head>", ` ${brandScript}
@@ -27775,11 +28039,11 @@ var hostname = process.env.HOSTNAME ?? "127.0.0.1";
27775
28039
  var httpServer = serve({ fetch: app62.fetch, port, hostname });
27776
28040
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27777
28041
  {
27778
- const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28042
+ const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27779
28043
  const reconcileScript = resolve36(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
27780
28044
  const RECONCILE_INTERVAL_MS = 12e4;
27781
28045
  const runReconcile = () => {
27782
- if (!existsSync36(reconcileScript)) return;
28046
+ if (!existsSync37(reconcileScript)) return;
27783
28047
  try {
27784
28048
  const child = spawn3(process.execPath, [reconcileScript], {
27785
28049
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -27797,11 +28061,11 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27797
28061
  loop.unref();
27798
28062
  }
27799
28063
  {
27800
- const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28064
+ const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27801
28065
  const outlookScript = resolve36(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
27802
28066
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
27803
28067
  const runOutlookComplete = () => {
27804
- if (!existsSync36(outlookScript)) return;
28068
+ if (!existsSync37(outlookScript)) return;
27805
28069
  try {
27806
28070
  const child = spawn3(process.execPath, [outlookScript], {
27807
28071
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -27819,19 +28083,19 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27819
28083
  outlookLoop.unref();
27820
28084
  }
27821
28085
  {
27822
- const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28086
+ const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27823
28087
  const strandedAccountsDir = resolve36(auditRoot, "..", "data/accounts");
27824
28088
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
27825
28089
  const STRANDED_AGE_MS = 16 * 6e4;
27826
28090
  const STRANDED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
27827
28091
  const runStrandedAudit = () => {
27828
28092
  try {
27829
- if (!existsSync36(strandedAccountsDir)) return;
28093
+ if (!existsSync37(strandedAccountsDir)) return;
27830
28094
  const now = Date.now();
27831
- for (const name of readdirSync21(strandedAccountsDir)) {
28095
+ for (const name of readdirSync22(strandedAccountsDir)) {
27832
28096
  if (!STRANDED_UUID_RE.test(name)) continue;
27833
28097
  const pendingPath2 = resolve36(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
27834
- if (!existsSync36(pendingPath2)) continue;
28098
+ if (!existsSync37(pendingPath2)) continue;
27835
28099
  const ageMs = now - statSync14(pendingPath2).mtimeMs;
27836
28100
  if (ageMs > STRANDED_AGE_MS) {
27837
28101
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs / 1e3)}`);
@@ -27847,7 +28111,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27847
28111
  strandedLoop.unref();
27848
28112
  }
27849
28113
  {
27850
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28114
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27851
28115
  const STORAGE_AUDIT_INTERVAL_MS = 3e5;
27852
28116
  const runStorageAuditSafe = () => {
27853
28117
  runStorageAudit(auditPlatformRoot).catch(
@@ -27869,7 +28133,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27869
28133
  pagesAuditLoop.unref();
27870
28134
  }
27871
28135
  {
27872
- const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28136
+ const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27873
28137
  const publishScript = resolve36(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
27874
28138
  const PUBLISH_INTERVAL_MS = 3e5;
27875
28139
  const currentAccount = () => {
@@ -27881,7 +28145,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27881
28145
  }
27882
28146
  };
27883
28147
  const spawnPublish = (account) => {
27884
- if (!existsSync36(publishScript)) return;
28148
+ if (!existsSync37(publishScript)) return;
27885
28149
  try {
27886
28150
  const child = spawn3(process.execPath, [publishScript], {
27887
28151
  env: {
@@ -27902,8 +28166,8 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27902
28166
  const availPath = resolve36(account.accountDir, "calendar-availability.json");
27903
28167
  let hasBookingSite = false;
27904
28168
  try {
27905
- if (existsSync36(availPath)) {
27906
- const cfg = JSON.parse(readFileSync38(availPath, "utf-8"));
28169
+ if (existsSync37(availPath)) {
28170
+ const cfg = JSON.parse(readFileSync39(availPath, "utf-8"));
27907
28171
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
27908
28172
  }
27909
28173
  } catch {
@@ -27911,9 +28175,9 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27911
28175
  if (!hasBookingSite) return;
27912
28176
  const statePath = resolve36(account.accountDir, "state", "booking-availability", "last-publish.json");
27913
28177
  let lastSuccessAt = null;
27914
- if (existsSync36(statePath)) {
28178
+ if (existsSync37(statePath)) {
27915
28179
  try {
27916
- const rec = JSON.parse(readFileSync38(statePath, "utf-8"));
28180
+ const rec = JSON.parse(readFileSync39(statePath, "utf-8"));
27917
28181
  lastSuccessAt = rec.lastSuccessAt ?? null;
27918
28182
  } catch {
27919
28183
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
@@ -27937,12 +28201,12 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27937
28201
  }
27938
28202
  startTimeEntryCensus(() => getSession());
27939
28203
  {
27940
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28204
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27941
28205
  const auditScript = resolve36(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
27942
28206
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
27943
28207
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
27944
28208
  const runConnectorAudit = () => {
27945
- if (!existsSync36(auditScript)) return;
28209
+ if (!existsSync37(auditScript)) return;
27946
28210
  try {
27947
28211
  const child = spawn3(process.execPath, [auditScript], {
27948
28212
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -28053,11 +28317,11 @@ try {
28053
28317
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
28054
28318
  async function runAdminUserReconcileTick() {
28055
28319
  try {
28056
- if (!existsSync36(USERS_FILE)) {
28320
+ if (!existsSync37(USERS_FILE)) {
28057
28321
  console.error("[adminuser-self-heal] skip reason=no-users-file");
28058
28322
  return;
28059
28323
  }
28060
- const usersRaw = readFileSync38(USERS_FILE, "utf-8").trim();
28324
+ const usersRaw = readFileSync39(USERS_FILE, "utf-8").trim();
28061
28325
  if (!usersRaw) {
28062
28326
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
28063
28327
  return;
@@ -28086,8 +28350,8 @@ var adminUserReconcileTimer = setInterval(() => {
28086
28350
  if (typeof adminUserReconcileTimer.unref === "function") adminUserReconcileTimer.unref();
28087
28351
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
28088
28352
  function countUsersRows() {
28089
- if (!existsSync36(USERS_FILE)) return 0;
28090
- const raw = readFileSync38(USERS_FILE, "utf-8").trim();
28353
+ if (!existsSync37(USERS_FILE)) return 0;
28354
+ const raw = readFileSync39(USERS_FILE, "utf-8").trim();
28091
28355
  if (!raw) return 0;
28092
28356
  const users = JSON.parse(raw);
28093
28357
  return users.filter((u) => typeof u.userId === "string").length;
@@ -28207,7 +28471,7 @@ if (bootAccountConfig?.whatsapp) {
28207
28471
  }
28208
28472
  init({
28209
28473
  configDir: configDirForWhatsApp,
28210
- platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..")),
28474
+ platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..")),
28211
28475
  accountConfig: bootAccountConfig,
28212
28476
  onMessage: async (msg) => {
28213
28477
  if (msg.isOwnerMirror) {