@rubytech/create-maxy-code 0.1.469 → 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.
@@ -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,
@@ -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
 
@@ -12788,9 +12788,249 @@ app9.get("/callback", async (c) => {
12788
12788
  });
12789
12789
  var quickbooks_default = app9;
12790
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
+
12791
13031
  // server/routes/onboarding.ts
12792
13032
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync3 } from "child_process";
12793
- 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";
12794
13034
  import { createHash as createHash4, randomUUID as randomUUID8 } from "crypto";
12795
13035
 
12796
13036
  // app/lib/claude-spawn-env.ts
@@ -12799,7 +13039,7 @@ function claudeBin() {
12799
13039
  }
12800
13040
 
12801
13041
  // server/routes/onboarding.ts
12802
- import { dirname as dirname9, join as join25 } from "path";
13042
+ import { dirname as dirname9, join as join26 } from "path";
12803
13043
 
12804
13044
  // app/lib/claude-keychain.ts
12805
13045
  import { execFileSync as execFileSync2 } from "child_process";
@@ -12928,8 +13168,8 @@ function readHostCredsBlob(service) {
12928
13168
  }
12929
13169
 
12930
13170
  // ../lib/admins-write/src/index.ts
12931
- 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";
12932
- 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";
12933
13173
  function id8(value) {
12934
13174
  return value.slice(0, 8);
12935
13175
  }
@@ -12943,7 +13183,7 @@ function appendUsersAuditLine(audit, fields) {
12943
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()}
12944
13184
  `;
12945
13185
  try {
12946
- mkdirSync5(dirname8(audit.logFile), { recursive: true, mode: 448 });
13186
+ mkdirSync6(dirname8(audit.logFile), { recursive: true, mode: 448 });
12947
13187
  appendFileSync2(audit.logFile, line, { mode: 384 });
12948
13188
  } catch (err) {
12949
13189
  console.error(
@@ -12961,17 +13201,17 @@ function logLine(input, result) {
12961
13201
  );
12962
13202
  }
12963
13203
  function writeFileAtomic(filePath, contents, mode) {
12964
- mkdirSync5(dirname8(filePath), { recursive: true });
13204
+ mkdirSync6(dirname8(filePath), { recursive: true });
12965
13205
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
12966
- writeFileSync9(tempPath, contents, mode !== void 0 ? { mode } : void 0);
12967
- renameSync6(tempPath, filePath);
13206
+ writeFileSync10(tempPath, contents, mode !== void 0 ? { mode } : void 0);
13207
+ renameSync7(tempPath, filePath);
12968
13208
  }
12969
13209
  function writeAdminEntry(input) {
12970
13210
  const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
12971
13211
  try {
12972
13212
  let users = [];
12973
- if (existsSync17(input.usersFile)) {
12974
- const raw = readFileSync25(input.usersFile, "utf-8").trim();
13213
+ if (existsSync18(input.usersFile)) {
13214
+ const raw = readFileSync26(input.usersFile, "utf-8").trim();
12975
13215
  if (raw) {
12976
13216
  const parsed = JSON.parse(raw);
12977
13217
  if (!Array.isArray(parsed)) {
@@ -13002,11 +13242,11 @@ function writeAdminEntry(input) {
13002
13242
  return result;
13003
13243
  }
13004
13244
  try {
13005
- const accountJsonPath = join24(input.accountDir, "account.json");
13006
- if (!existsSync17(accountJsonPath)) {
13245
+ const accountJsonPath = join25(input.accountDir, "account.json");
13246
+ if (!existsSync18(accountJsonPath)) {
13007
13247
  throw new Error(`account.json not found at ${accountJsonPath}`);
13008
13248
  }
13009
- const config = JSON.parse(readFileSync25(accountJsonPath, "utf-8"));
13249
+ const config = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
13010
13250
  const admins = config.admins ?? [];
13011
13251
  if (admins.some((a) => a.userId === input.userId)) {
13012
13252
  result.accountJsonResult = "noop";
@@ -13026,9 +13266,9 @@ function writeAdminEntry(input) {
13026
13266
  function computeAdminStoreDivergence(input) {
13027
13267
  const result = { divergences: 0, accountWithoutUsers: [], usersWithoutAccount: [], errors: [] };
13028
13268
  const usersUserIds = /* @__PURE__ */ new Set();
13029
- if (existsSync17(input.usersFile)) {
13269
+ if (existsSync18(input.usersFile)) {
13030
13270
  try {
13031
- const raw = readFileSync25(input.usersFile, "utf-8").trim();
13271
+ const raw = readFileSync26(input.usersFile, "utf-8").trim();
13032
13272
  if (raw) {
13033
13273
  const users = JSON.parse(raw);
13034
13274
  for (const u of users) {
@@ -13040,27 +13280,27 @@ function computeAdminStoreDivergence(input) {
13040
13280
  }
13041
13281
  }
13042
13282
  const accountUserIds = /* @__PURE__ */ new Set();
13043
- if (existsSync17(input.accountsDir)) {
13283
+ if (existsSync18(input.accountsDir)) {
13044
13284
  let entries;
13045
13285
  try {
13046
- entries = readdirSync16(input.accountsDir);
13286
+ entries = readdirSync17(input.accountsDir);
13047
13287
  } catch (err) {
13048
13288
  result.errors.push({ source: input.accountsDir, detail: err instanceof Error ? err.message : String(err) });
13049
13289
  return result;
13050
13290
  }
13051
13291
  for (const entry of entries) {
13052
13292
  if (entry.startsWith(".")) continue;
13053
- const accountDir = join24(input.accountsDir, entry);
13293
+ const accountDir = join25(input.accountsDir, entry);
13054
13294
  try {
13055
13295
  if (!statSync8(accountDir).isDirectory()) continue;
13056
13296
  } catch {
13057
13297
  continue;
13058
13298
  }
13059
- const accountJsonPath = join24(accountDir, "account.json");
13060
- if (!existsSync17(accountJsonPath)) continue;
13299
+ const accountJsonPath = join25(accountDir, "account.json");
13300
+ if (!existsSync18(accountJsonPath)) continue;
13061
13301
  let admins = [];
13062
13302
  try {
13063
- const config = JSON.parse(readFileSync25(accountJsonPath, "utf-8"));
13303
+ const config = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
13064
13304
  admins = config.admins ?? [];
13065
13305
  } catch (err) {
13066
13306
  result.errors.push({ source: accountJsonPath, detail: err instanceof Error ? err.message : String(err) });
@@ -13108,8 +13348,8 @@ function hashPin2(pin) {
13108
13348
  return createHash4("sha256").update(pin).digest("hex");
13109
13349
  }
13110
13350
  function readUsersFile2() {
13111
- if (!existsSync18(USERS_FILE)) return null;
13112
- const raw = readFileSync26(USERS_FILE, "utf-8").trim();
13351
+ if (!existsSync19(USERS_FILE)) return null;
13352
+ const raw = readFileSync27(USERS_FILE, "utf-8").trim();
13113
13353
  if (!raw) return [];
13114
13354
  return JSON.parse(raw);
13115
13355
  }
@@ -13168,7 +13408,7 @@ app10.post("/claude-auth", async (c) => {
13168
13408
  } catch (err) {
13169
13409
  logoutError = err instanceof Error ? err.message : String(err);
13170
13410
  }
13171
- const credentialsPresent = existsSync18(CLAUDE_CREDENTIALS_FILE);
13411
+ const credentialsPresent = existsSync19(CLAUDE_CREDENTIALS_FILE);
13172
13412
  const ranMs = Date.now() - start;
13173
13413
  console.log(`[onboarding] op=claude-logout credentialsPresent=${credentialsPresent} ranMs=${ranMs} logoutError=${logoutError ? JSON.stringify(logoutError.slice(0, 120)) : "none"}`);
13174
13414
  return c.json({ logged_out: !credentialsPresent });
@@ -13202,7 +13442,7 @@ app10.post("/claude-auth", async (c) => {
13202
13442
  return c.json({ launched: cdpReady });
13203
13443
  }
13204
13444
  ensureLogDir();
13205
- writeFileSync10(logPath("claude-auth"), "");
13445
+ writeFileSync11(logPath("claude-auth"), "");
13206
13446
  const claudeAuthLogFd = openSync3(logPath("claude-auth"), "a");
13207
13447
  const onClaudeOutput = (chunk) => writeSync(claudeAuthLogFd, chunk);
13208
13448
  if (process.platform === "darwin") {
@@ -13227,14 +13467,14 @@ app10.post("/claude-auth", async (c) => {
13227
13467
  readBlob: readHostCredsBlob,
13228
13468
  writeFile: (blob) => {
13229
13469
  const tmp = `${CLAUDE_CREDENTIALS_FILE}.${process.pid}.tmp`;
13230
- writeFileSync10(tmp, blob, { mode: 384 });
13231
- renameSync7(tmp, CLAUDE_CREDENTIALS_FILE);
13470
+ writeFileSync11(tmp, blob, { mode: 384 });
13471
+ renameSync8(tmp, CLAUDE_CREDENTIALS_FILE);
13232
13472
  },
13233
13473
  log: (line) => console.log(line)
13234
13474
  });
13235
13475
  persistKeychainService(
13236
13476
  writebackResult,
13237
- (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 }),
13238
13478
  (line) => console.log(line)
13239
13479
  );
13240
13480
  if (darwinAuthChild === claudeProc2) darwinAuthChild = null;
@@ -13317,9 +13557,9 @@ app10.post("/set-pin", async (c) => {
13317
13557
  console.log(`[set-pin] wrote users.json + account.json admins: userId=${userId.slice(0, 8)}\u2026 role=owner`);
13318
13558
  if (process.platform === "linux") {
13319
13559
  let installOwner = null;
13320
- if (existsSync18(INSTALL_OWNER_FILE)) {
13560
+ if (existsSync19(INSTALL_OWNER_FILE)) {
13321
13561
  try {
13322
- const raw = readFileSync26(INSTALL_OWNER_FILE, "utf-8").trim();
13562
+ const raw = readFileSync27(INSTALL_OWNER_FILE, "utf-8").trim();
13323
13563
  if (raw.length > 0) installOwner = raw;
13324
13564
  } catch (err) {
13325
13565
  console.error(`[set-pin] install-owner-read-failed path=${INSTALL_OWNER_FILE} error=${err instanceof Error ? err.message : String(err)}`);
@@ -13400,7 +13640,7 @@ app10.delete("/set-pin", requireAdminSession, async (c) => {
13400
13640
  unlinkSync3(USERS_FILE);
13401
13641
  console.log(`[set-pin] cleared users.json (last entry removed): userId=${sessionUserId.slice(0, 8)}\u2026`);
13402
13642
  } else {
13403
- writeFileSync10(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
13643
+ writeFileSync11(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
13404
13644
  console.log(`[set-pin] removed entry from users.json: userId=${sessionUserId.slice(0, 8)}\u2026 remaining=${remaining.length}`);
13405
13645
  }
13406
13646
  logUsersAudit(
@@ -13465,9 +13705,9 @@ app10.put("/set-pin", requireAdminSession, async (c) => {
13465
13705
  console.log(`[set-pin] changed PIN in place: userId=${sessionUserId.slice(0, 8)}\u2026`);
13466
13706
  if (process.platform === "linux") {
13467
13707
  let installOwner = null;
13468
- if (existsSync18(INSTALL_OWNER_FILE)) {
13708
+ if (existsSync19(INSTALL_OWNER_FILE)) {
13469
13709
  try {
13470
- const raw = readFileSync26(INSTALL_OWNER_FILE, "utf-8").trim();
13710
+ const raw = readFileSync27(INSTALL_OWNER_FILE, "utf-8").trim();
13471
13711
  if (raw.length > 0) installOwner = raw;
13472
13712
  } catch (err) {
13473
13713
  console.error(`[set-pin] install-owner-read-failed path=${INSTALL_OWNER_FILE} error=${err instanceof Error ? err.message : String(err)}`);
@@ -13499,9 +13739,9 @@ ${body.newPin}
13499
13739
  var onboarding_default = app10;
13500
13740
 
13501
13741
  // server/routes/client-error.ts
13502
- import { appendFileSync as appendFileSync3, existsSync as existsSync19, renameSync as renameSync8, statSync as statSync9 } from "fs";
13503
- import { join as join26 } from "path";
13504
- 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");
13505
13745
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
13506
13746
  var MAX_BODY_SIZE = 8 * 1024;
13507
13747
  var MAX_STACK_LEN = 2e3;
@@ -13549,10 +13789,10 @@ function stackHead(stack) {
13549
13789
  }
13550
13790
  function rotateIfNeeded() {
13551
13791
  try {
13552
- if (!existsSync19(CLIENT_ERRORS_LOG)) return;
13792
+ if (!existsSync20(CLIENT_ERRORS_LOG)) return;
13553
13793
  const stats = statSync9(CLIENT_ERRORS_LOG);
13554
13794
  if (stats.size < MAX_LOG_SIZE) return;
13555
- renameSync8(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
13795
+ renameSync9(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
13556
13796
  } catch (err) {
13557
13797
  console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
13558
13798
  }
@@ -13876,18 +14116,18 @@ app13.get("/", requireAdminSession, async (c) => {
13876
14116
  var accounts_default = app13;
13877
14117
 
13878
14118
  // server/routes/admin/logs.ts
13879
- 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";
13880
14120
  import { resolve as resolve17, basename as basename7 } from "path";
13881
14121
 
13882
14122
  // app/lib/logs-read-resolve.ts
13883
- import { existsSync as existsSync20 } from "fs";
13884
- import { join as join27 } from "path";
14123
+ import { existsSync as existsSync21 } from "fs";
14124
+ import { join as join28 } from "path";
13885
14125
  function resolveSessionLogPaths(filename, logDirs) {
13886
14126
  const tried = [filename];
13887
14127
  const hits = [];
13888
14128
  for (const dir of logDirs) {
13889
- const fullPath = join27(dir, filename);
13890
- if (existsSync20(fullPath)) {
14129
+ const fullPath = join28(dir, filename);
14130
+ if (existsSync21(fullPath)) {
13891
14131
  hits.push({ path: fullPath, dir });
13892
14132
  }
13893
14133
  }
@@ -13915,7 +14155,7 @@ app14.get("/", async (c) => {
13915
14155
  const filePath = resolve17(dir, safe);
13916
14156
  searched.push(filePath);
13917
14157
  try {
13918
- const buffer = readFileSync27(filePath);
14158
+ const buffer = readFileSync28(filePath);
13919
14159
  const onDiskBytes = statSync10(filePath).size;
13920
14160
  const headers = {
13921
14161
  "Content-Type": "text/plain; charset=utf-8",
@@ -13980,7 +14220,7 @@ app14.get("/", async (c) => {
13980
14220
  console.info(`[admin/logs] resolved cacheKey=${cacheKeySlice} sessionId=${sessionIdSlice} via=${primaryId === cacheKey ? "cacheKey" : primaryId === sessionKeyFromConv ? "reverse-lookup" : "sessionId-fallback"}`);
13981
14221
  try {
13982
14222
  const filename = basename7(hit.path);
13983
- const buffer = readFileSync27(hit.path);
14223
+ const buffer = readFileSync28(hit.path);
13984
14224
  const onDiskBytes = statSync10(hit.path).size;
13985
14225
  const headers = {
13986
14226
  "Content-Type": "text/plain; charset=utf-8",
@@ -14015,10 +14255,10 @@ app14.get("/", async (c) => {
14015
14255
  const seen = /* @__PURE__ */ new Set();
14016
14256
  const logs = {};
14017
14257
  for (const dir of logDirs) {
14018
- if (!existsSync21(dir)) continue;
14258
+ if (!existsSync22(dir)) continue;
14019
14259
  let files;
14020
14260
  try {
14021
- files = readdirSync17(dir).filter((f) => f.endsWith(".log"));
14261
+ files = readdirSync18(dir).filter((f) => f.endsWith(".log"));
14022
14262
  } catch (err) {
14023
14263
  const reason = err instanceof Error ? err.message : String(err);
14024
14264
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
@@ -14027,7 +14267,7 @@ app14.get("/", async (c) => {
14027
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 }) => {
14028
14268
  seen.add(name);
14029
14269
  try {
14030
- const content = readFileSync27(resolve17(dir, name));
14270
+ const content = readFileSync28(resolve17(dir, name));
14031
14271
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
14032
14272
  logs[name] = tail.trim() || "(empty)";
14033
14273
  } catch (err) {
@@ -14067,7 +14307,7 @@ var claude_info_default = app15;
14067
14307
 
14068
14308
  // server/routes/admin/attachment.ts
14069
14309
  import { readFile as readFile2, readdir } from "fs/promises";
14070
- import { existsSync as existsSync22 } from "fs";
14310
+ import { existsSync as existsSync23 } from "fs";
14071
14311
  import { resolve as resolve18 } from "path";
14072
14312
  var app16 = new Hono();
14073
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}$/;
@@ -14090,12 +14330,12 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
14090
14330
  }
14091
14331
  let accountId = pinnedAccountId;
14092
14332
  let dir = uploadsDirFor2(accountId, attachmentId);
14093
- let found = existsSync22(dir);
14333
+ let found = existsSync23(dir);
14094
14334
  if (!found) {
14095
14335
  for (const candidate of listValidAccounts()) {
14096
14336
  if (candidate.accountId === pinnedAccountId) continue;
14097
14337
  const candidateDir = uploadsDirFor2(candidate.accountId, attachmentId);
14098
- if (existsSync22(candidateDir)) {
14338
+ if (existsSync23(candidateDir)) {
14099
14339
  accountId = candidate.accountId;
14100
14340
  dir = candidateDir;
14101
14341
  found = true;
@@ -14110,7 +14350,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
14110
14350
  return new Response("Not found", { status: 404 });
14111
14351
  }
14112
14352
  const metaPath = resolve18(dir, `${attachmentId}.meta.json`);
14113
- if (!existsSync22(metaPath)) {
14353
+ if (!existsSync23(metaPath)) {
14114
14354
  return new Response("Not found", { status: 404 });
14115
14355
  }
14116
14356
  let meta;
@@ -14144,23 +14384,23 @@ var attachment_default = app16;
14144
14384
 
14145
14385
  // server/routes/admin/agents.ts
14146
14386
  import { resolve as resolve19 } from "path";
14147
- 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";
14148
14388
  var app17 = new Hono();
14149
14389
  app17.get("/", (c) => {
14150
14390
  const account = resolveAccount();
14151
14391
  if (!account) return c.json({ agents: [] });
14152
14392
  const agentsDir = resolve19(account.accountDir, "agents");
14153
- if (!existsSync23(agentsDir)) return c.json({ agents: [] });
14393
+ if (!existsSync24(agentsDir)) return c.json({ agents: [] });
14154
14394
  const agents = [];
14155
14395
  try {
14156
- const entries = readdirSync18(agentsDir, { withFileTypes: true });
14396
+ const entries = readdirSync19(agentsDir, { withFileTypes: true });
14157
14397
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
14158
14398
  if (!entry.isDirectory()) continue;
14159
14399
  if (entry.name === "admin") continue;
14160
14400
  const configPath2 = resolve19(agentsDir, entry.name, "config.json");
14161
- if (!existsSync23(configPath2)) continue;
14401
+ if (!existsSync24(configPath2)) continue;
14162
14402
  try {
14163
- const config = JSON.parse(readFileSync28(configPath2, "utf-8"));
14403
+ const config = JSON.parse(readFileSync29(configPath2, "utf-8"));
14164
14404
  agents.push({
14165
14405
  slug: entry.name,
14166
14406
  displayName: config.displayName ?? entry.name,
@@ -14187,7 +14427,7 @@ app17.delete("/:slug", async (c) => {
14187
14427
  return c.json({ error: "Invalid agent slug" }, 400);
14188
14428
  }
14189
14429
  const agentDir = resolve19(account.accountDir, "agents", slug);
14190
- if (!existsSync23(agentDir)) {
14430
+ if (!existsSync24(agentDir)) {
14191
14431
  return c.json({ error: "Agent not found" }, 404);
14192
14432
  }
14193
14433
  try {
@@ -14198,7 +14438,7 @@ app17.delete("/:slug", async (c) => {
14198
14438
  return c.json({ error: `Graph cleanup failed: ${msg}` }, 500);
14199
14439
  }
14200
14440
  try {
14201
- rmSync2(agentDir, { recursive: true, force: true });
14441
+ rmSync3(agentDir, { recursive: true, force: true });
14202
14442
  console.log(`[admin/agents] deleted agent "${slug}"`);
14203
14443
  return c.json({ ok: true });
14204
14444
  } catch (err) {
@@ -14217,7 +14457,7 @@ app17.post("/:slug/project", async (c) => {
14217
14457
  return c.json({ error: "Invalid agent slug" }, 400);
14218
14458
  }
14219
14459
  const agentDir = resolve19(account.accountDir, "agents", slug);
14220
- if (!existsSync23(agentDir)) {
14460
+ if (!existsSync24(agentDir)) {
14221
14461
  return c.json({ error: "Agent not found on disk" }, 404);
14222
14462
  }
14223
14463
  try {
@@ -14233,7 +14473,7 @@ var agents_default = app17;
14233
14473
  // server/routes/admin/sessions.ts
14234
14474
  import crypto2 from "crypto";
14235
14475
  import { resolve as resolvePath } from "path";
14236
- import { existsSync as existsSync24, mkdirSync as mkdirSync6, createWriteStream } from "fs";
14476
+ import { existsSync as existsSync25, mkdirSync as mkdirSync7, createWriteStream } from "fs";
14237
14477
 
14238
14478
  // ../lib/admin-conversation-purge/src/index.ts
14239
14479
  async function purgeAdminConversationJsonls(args) {
@@ -14380,7 +14620,7 @@ var pickComponentBytes = (..._args) => null;
14380
14620
  function openResumeStreamLog(accountId, sessionId) {
14381
14621
  const dir = resolvePath(ACCOUNTS_DIR, accountId, "resume-logs");
14382
14622
  try {
14383
- mkdirSync6(dir, { recursive: true });
14623
+ mkdirSync7(dir, { recursive: true });
14384
14624
  } catch {
14385
14625
  }
14386
14626
  return createWriteStream(resolvePath(dir, `${sessionId}.log`), { flags: "a" });
@@ -14393,7 +14633,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, sessionId, mes
14393
14633
  let reason = null;
14394
14634
  if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
14395
14635
  else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
14396
- else if (!existsSync24(a.storagePath)) reason = "missing-file";
14636
+ else if (!existsSync25(a.storagePath)) reason = "missing-file";
14397
14637
  if (reason) {
14398
14638
  invalid++;
14399
14639
  try {
@@ -14919,8 +15159,8 @@ app18.put("/:id/label", requireAdminSession, async (c) => {
14919
15159
  var sessions_default = app18;
14920
15160
 
14921
15161
  // app/lib/claude-agent/spawn-context.ts
14922
- import { existsSync as existsSync25, readFileSync as readFileSync29, readdirSync as readdirSync19, statSync as statSync11 } from "fs";
14923
- 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";
14924
15164
  async function resolveOwnerProfileBlock(accountId, userId) {
14925
15165
  if (!userId) return { ok: false, reason: "missing-user-id" };
14926
15166
  try {
@@ -14961,14 +15201,14 @@ function frontmatterField(manifest, field2) {
14961
15201
  function extractPluginToolDescriptions(pluginDir) {
14962
15202
  const out = /* @__PURE__ */ new Map();
14963
15203
  const candidates = [
14964
- join28(pluginDir, "mcp/dist/index.js"),
14965
- join28(pluginDir, "mcp/src/index.ts")
15204
+ join29(pluginDir, "mcp/dist/index.js"),
15205
+ join29(pluginDir, "mcp/src/index.ts")
14966
15206
  ];
14967
15207
  let raw = null;
14968
15208
  for (const path3 of candidates) {
14969
- if (!existsSync25(path3)) continue;
15209
+ if (!existsSync26(path3)) continue;
14970
15210
  try {
14971
- raw = readFileSync29(path3, "utf-8");
15211
+ raw = readFileSync30(path3, "utf-8");
14972
15212
  break;
14973
15213
  } catch {
14974
15214
  }
@@ -15018,9 +15258,9 @@ function parseSkillPathsFromFrontmatter(fm) {
15018
15258
  function listPluginDirs() {
15019
15259
  const out = /* @__PURE__ */ new Map();
15020
15260
  const platformPlugins = resolve20(PLATFORM_ROOT, "plugins");
15021
- if (existsSync25(platformPlugins)) {
15022
- for (const name of readdirSync19(platformPlugins)) {
15023
- const dir = join28(platformPlugins, name);
15261
+ if (existsSync26(platformPlugins)) {
15262
+ for (const name of readdirSync20(platformPlugins)) {
15263
+ const dir = join29(platformPlugins, name);
15024
15264
  try {
15025
15265
  if (statSync11(dir).isDirectory()) out.set(name, dir);
15026
15266
  } catch {
@@ -15028,13 +15268,13 @@ function listPluginDirs() {
15028
15268
  }
15029
15269
  }
15030
15270
  const premiumRoot = resolve20(dirname10(PLATFORM_ROOT), "premium-plugins");
15031
- if (existsSync25(premiumRoot)) {
15032
- for (const bundle of readdirSync19(premiumRoot)) {
15033
- const bundlePlugins = join28(premiumRoot, bundle, "plugins");
15034
- 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;
15035
15275
  try {
15036
- for (const name of readdirSync19(bundlePlugins)) {
15037
- const dir = join28(bundlePlugins, name);
15276
+ for (const name of readdirSync20(bundlePlugins)) {
15277
+ const dir = join29(bundlePlugins, name);
15038
15278
  try {
15039
15279
  if (statSync11(dir).isDirectory()) out.set(name, dir);
15040
15280
  } catch {
@@ -15048,9 +15288,9 @@ function listPluginDirs() {
15048
15288
  }
15049
15289
  function readEnabledPlugins(accountId) {
15050
15290
  const accountFile = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
15051
- if (!existsSync25(accountFile)) return /* @__PURE__ */ new Set();
15291
+ if (!existsSync26(accountFile)) return /* @__PURE__ */ new Set();
15052
15292
  try {
15053
- const parsed = JSON.parse(readFileSync29(accountFile, "utf-8"));
15293
+ const parsed = JSON.parse(readFileSync30(accountFile, "utf-8"));
15054
15294
  return new Set(
15055
15295
  Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : []
15056
15296
  );
@@ -15059,10 +15299,10 @@ function readEnabledPlugins(accountId) {
15059
15299
  }
15060
15300
  }
15061
15301
  function readFrontmatter(path3) {
15062
- if (!existsSync25(path3)) return null;
15302
+ if (!existsSync26(path3)) return null;
15063
15303
  let raw;
15064
15304
  try {
15065
- raw = readFileSync29(path3, "utf-8");
15305
+ raw = readFileSync30(path3, "utf-8");
15066
15306
  } catch {
15067
15307
  return null;
15068
15308
  }
@@ -15077,7 +15317,7 @@ function computeActivePlugins(accountId) {
15077
15317
  for (const name of Array.from(enabled).sort()) {
15078
15318
  const dir = pluginDirs.get(name);
15079
15319
  if (!dir) continue;
15080
- const fm = readFrontmatter(join28(dir, "PLUGIN.md"));
15320
+ const fm = readFrontmatter(join29(dir, "PLUGIN.md"));
15081
15321
  if (!fm) continue;
15082
15322
  const description = frontmatterField(`---
15083
15323
  ${fm}
@@ -15094,7 +15334,7 @@ ${fm}
15094
15334
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
15095
15335
  );
15096
15336
  if (toolNames.length > 0 && descMap.size === 0) {
15097
- 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"));
15098
15338
  if (hasSource) {
15099
15339
  console.warn(
15100
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`
@@ -15104,7 +15344,7 @@ ${fm}
15104
15344
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
15105
15345
  const skills = [];
15106
15346
  for (const relPath of skillPaths) {
15107
- const skillPath = join28(dir, relPath);
15347
+ const skillPath = join29(dir, relPath);
15108
15348
  const skillFm = readFrontmatter(skillPath);
15109
15349
  if (!skillFm) continue;
15110
15350
  const skillName = frontmatterField(`---
@@ -15121,10 +15361,10 @@ ${skillFm}
15121
15361
  }
15122
15362
  function computeSpecialistDomains(accountId) {
15123
15363
  const specialistsDir = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
15124
- if (!existsSync25(specialistsDir)) return [];
15364
+ if (!existsSync26(specialistsDir)) return [];
15125
15365
  let entries;
15126
15366
  try {
15127
- entries = readdirSync19(specialistsDir);
15367
+ entries = readdirSync20(specialistsDir);
15128
15368
  } catch {
15129
15369
  return [];
15130
15370
  }
@@ -15148,7 +15388,7 @@ function computeSpecialistDomains(accountId) {
15148
15388
  const out = [];
15149
15389
  for (const file of entries.sort()) {
15150
15390
  if (!file.endsWith(".md")) continue;
15151
- const fm = readFrontmatter(join28(specialistsDir, file));
15391
+ const fm = readFrontmatter(join29(specialistsDir, file));
15152
15392
  if (!fm) continue;
15153
15393
  const wrapped = `---
15154
15394
  ${fm}
@@ -15167,10 +15407,10 @@ ${fm}
15167
15407
  }
15168
15408
  function computeDormantPlugins(accountId) {
15169
15409
  const accountFile = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
15170
- if (!existsSync25(accountFile)) return [];
15410
+ if (!existsSync26(accountFile)) return [];
15171
15411
  let enabled;
15172
15412
  try {
15173
- const raw = readFileSync29(accountFile, "utf-8");
15413
+ const raw = readFileSync30(accountFile, "utf-8");
15174
15414
  const parsed = JSON.parse(raw);
15175
15415
  enabled = new Set(
15176
15416
  Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : []
@@ -15182,10 +15422,10 @@ function computeDormantPlugins(accountId) {
15182
15422
  return [];
15183
15423
  }
15184
15424
  const pluginsDir = resolve20(PLATFORM_ROOT, "plugins");
15185
- if (!existsSync25(pluginsDir)) return [];
15425
+ if (!existsSync26(pluginsDir)) return [];
15186
15426
  let entries;
15187
15427
  try {
15188
- entries = readdirSync19(pluginsDir);
15428
+ entries = readdirSync20(pluginsDir);
15189
15429
  } catch {
15190
15430
  return [];
15191
15431
  }
@@ -15193,10 +15433,10 @@ function computeDormantPlugins(accountId) {
15193
15433
  for (const name of entries) {
15194
15434
  if (enabled.has(name)) continue;
15195
15435
  const manifestPath = resolve20(pluginsDir, name, "PLUGIN.md");
15196
- if (!existsSync25(manifestPath)) continue;
15436
+ if (!existsSync26(manifestPath)) continue;
15197
15437
  let manifest;
15198
15438
  try {
15199
- manifest = readFileSync29(manifestPath, "utf-8");
15439
+ manifest = readFileSync30(manifestPath, "utf-8");
15200
15440
  } catch {
15201
15441
  continue;
15202
15442
  }
@@ -15210,13 +15450,13 @@ function computeDormantPlugins(accountId) {
15210
15450
  }
15211
15451
 
15212
15452
  // server/routes/admin/claude-sessions.ts
15213
- import { existsSync as existsSync26, readFileSync as readFileSync30 } from "fs";
15453
+ import { existsSync as existsSync27, readFileSync as readFileSync31 } from "fs";
15214
15454
  import { resolve as resolve21 } from "path";
15215
15455
  function readTunnelState(brandConfigDir) {
15216
15456
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
15217
- if (!existsSync26(statePath)) return null;
15457
+ if (!existsSync27(statePath)) return null;
15218
15458
  try {
15219
- const parsed = JSON.parse(readFileSync30(statePath, "utf-8"));
15459
+ const parsed = JSON.parse(readFileSync31(statePath, "utf-8"));
15220
15460
  const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
15221
15461
  const tunnelName = typeof parsed.tunnelName === "string" ? parsed.tunnelName : null;
15222
15462
  const domain = typeof parsed.domain === "string" ? parsed.domain : null;
@@ -15230,7 +15470,7 @@ function resolveTunnelUrl() {
15230
15470
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve21(process.cwd(), "..");
15231
15471
  let brand;
15232
15472
  try {
15233
- brand = JSON.parse(readFileSync30(resolve21(platformRoot5, "config", "brand.json"), "utf-8"));
15473
+ brand = JSON.parse(readFileSync31(resolve21(platformRoot5, "config", "brand.json"), "utf-8"));
15234
15474
  } catch {
15235
15475
  return null;
15236
15476
  }
@@ -15241,7 +15481,7 @@ function resolveTunnelUrl() {
15241
15481
  if (!state) return null;
15242
15482
  return `https://${hostname2}.${state.domain}`;
15243
15483
  }
15244
- var TAG26 = "[claude-session-manager:wrapper]";
15484
+ var TAG27 = "[claude-session-manager:wrapper]";
15245
15485
  async function refuseIfClaudeAuthDead(c, route, sessionId) {
15246
15486
  const auth = await ensureAuth();
15247
15487
  if (auth.status !== "dead" && auth.status !== "missing") return null;
@@ -15259,12 +15499,12 @@ async function performSpawnWithInitialMessage(args) {
15259
15499
  const aboutOwner = await resolveOwnerProfileBlock(args.senderId, args.userId);
15260
15500
  const ownerMs = Date.now() - ownerStart;
15261
15501
  const aboutOwnerStatus = aboutOwner == null ? "absent" : "ok" in aboutOwner && aboutOwner.ok === false ? `unresolved:${aboutOwner.reason}` : "ok";
15262
- console.log(`${TAG26} about-owner-resolved status=${aboutOwnerStatus} ms=${ownerMs}`);
15502
+ console.log(`${TAG27} about-owner-resolved status=${aboutOwnerStatus} ms=${ownerMs}`);
15263
15503
  const dormantPlugins = computeDormantPlugins(args.senderId);
15264
15504
  const activePlugins = computeActivePlugins(args.senderId);
15265
15505
  const specialistDomains = computeSpecialistDomains(args.senderId);
15266
15506
  const tunnelUrl = resolveTunnelUrl();
15267
- console.log(`${TAG26} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
15507
+ console.log(`${TAG27} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
15268
15508
  const upstreamPayload = JSON.stringify({
15269
15509
  senderId: args.senderId,
15270
15510
  // Task 205 — pass userId through to the manager so it lands as
@@ -15291,24 +15531,24 @@ async function performSpawnWithInitialMessage(args) {
15291
15531
  // unshapely values.
15292
15532
  conversationNodeId: args.conversationNodeId
15293
15533
  });
15294
- 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"}`);
15295
15535
  const forwardStart = Date.now();
15296
15536
  const upstream = await fetch(`${managerBase("claude-session-manager:wrapper")}/public-spawn`, {
15297
15537
  method: "POST",
15298
15538
  headers: { "content-type": "application/json" },
15299
15539
  body: upstreamPayload
15300
15540
  }).catch((err) => {
15301
- 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}`);
15302
15542
  return null;
15303
15543
  });
15304
15544
  if (!upstream) return {
15305
15545
  response: new Response(JSON.stringify({ error: "manager-unreachable" }), { status: 503, headers: { "content-type": "application/json" } }),
15306
15546
  claudeSessionId: null
15307
15547
  };
15308
- 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}`);
15309
15549
  if (args.initialMessage) {
15310
15550
  const inputBytes = Buffer.byteLength(args.initialMessage, "utf8");
15311
- console.log(`${TAG26} initial-message-inlined bytes=${inputBytes}`);
15551
+ console.log(`${TAG27} initial-message-inlined bytes=${inputBytes}`);
15312
15552
  }
15313
15553
  const bodyText = await upstream.text().catch(() => "");
15314
15554
  let claudeSessionId = null;
@@ -15343,7 +15583,7 @@ app19.post("/", async (c) => {
15343
15583
  if (refusal) return refusal;
15344
15584
  const senderId = getAccountIdForSession(cacheKey) ?? "";
15345
15585
  if (!senderId) {
15346
- 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)}`);
15347
15587
  return c.json({ error: "admin-account-not-resolved" }, 500);
15348
15588
  }
15349
15589
  const userId = getUserIdForSession(cacheKey) ?? void 0;
@@ -15352,7 +15592,7 @@ app19.post("/", async (c) => {
15352
15592
  const permissionMode = typeof body.permissionMode === "string" ? body.permissionMode : void 0;
15353
15593
  const specialist = typeof body.specialist === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(body.specialist) ? body.specialist : void 0;
15354
15594
  const model = typeof body.model === "string" && /^[A-Za-z0-9._-]{1,64}$/.test(body.model) ? body.model : void 0;
15355
- 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"}`);
15356
15596
  const conversationNodeId = cacheKey ? getSessionIdForSession(cacheKey) : void 0;
15357
15597
  const { response, claudeSessionId } = await performSpawnWithInitialMessage({
15358
15598
  senderId,
@@ -15371,13 +15611,13 @@ app19.post("/", async (c) => {
15371
15611
  claudeSessionId,
15372
15612
  senderId
15373
15613
  );
15374
- 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}`);
15375
15615
  return response;
15376
15616
  });
15377
15617
  var claude_sessions_default = app19;
15378
15618
 
15379
15619
  // server/routes/admin/log-ingest.ts
15380
- var TAG27 = "[log-ingest]";
15620
+ var TAG28 = "[log-ingest]";
15381
15621
  var TAG_PATTERN = /^[A-Za-z0-9_:-]{1,32}$/;
15382
15622
  var LEVELS = /* @__PURE__ */ new Set(["debug", "info", "warn", "error"]);
15383
15623
  var MAX_LINE_BYTES = 4096;
@@ -15388,7 +15628,7 @@ function isLoopbackAddr2(addr) {
15388
15628
  app20.post("/", async (c) => {
15389
15629
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
15390
15630
  if (!isLoopbackAddr2(remoteAddr)) {
15391
- console.error(`${TAG27} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15631
+ console.error(`${TAG28} reject reason=non-loopback remoteAddr=${remoteAddr}`);
15392
15632
  return c.json({ error: "log-ingest-loopback-only" }, 403);
15393
15633
  }
15394
15634
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -15397,7 +15637,7 @@ app20.post("/", async (c) => {
15397
15637
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
15398
15638
  const offender = tokens.find((t) => !isLoopbackAddr2(t));
15399
15639
  if (offender !== void 0) {
15400
- 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)}`);
15401
15641
  return c.json({ error: "log-ingest-loopback-only" }, 403);
15402
15642
  }
15403
15643
  }
@@ -15439,18 +15679,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
15439
15679
  ]);
15440
15680
  var app21 = new Hono();
15441
15681
  app21.post("/", async (c) => {
15442
- const TAG47 = "[admin:events]";
15682
+ const TAG48 = "[admin:events]";
15443
15683
  let body;
15444
15684
  try {
15445
15685
  body = await c.req.json();
15446
15686
  } catch (err) {
15447
15687
  const detail = err instanceof Error ? err.message : String(err);
15448
- console.error(`${TAG47} reject reason=body-not-json detail=${detail}`);
15688
+ console.error(`${TAG48} reject reason=body-not-json detail=${detail}`);
15449
15689
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
15450
15690
  }
15451
15691
  const event = typeof body.event === "string" ? body.event : "";
15452
15692
  if (!ALLOWED_EVENTS.has(event)) {
15453
- 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)}`);
15454
15694
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
15455
15695
  }
15456
15696
  const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
@@ -15472,11 +15712,11 @@ app21.post("/", async (c) => {
15472
15712
  var events_default = app21;
15473
15713
 
15474
15714
  // server/routes/admin/files.ts
15475
- 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";
15476
15716
  import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, unlink as unlink2, rename, rmdir } from "fs/promises";
15477
15717
  import { realpathSync as realpathSync6 } from "fs";
15478
15718
  import { randomUUID as randomUUID10 } from "crypto";
15479
- 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";
15480
15720
  import { Readable as Readable2 } from "stream";
15481
15721
 
15482
15722
  // ../lib/graph-trash/src/index.ts
@@ -15794,7 +16034,7 @@ async function cascadeDeleteDocument(params) {
15794
16034
 
15795
16035
  // app/lib/file-index.ts
15796
16036
  import * as fsp from "fs/promises";
15797
- 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";
15798
16038
  import { tmpdir as tmpdir2 } from "os";
15799
16039
  import { execFile as execFile2 } from "child_process";
15800
16040
  import { promisify as promisify2 } from "util";
@@ -15876,7 +16116,7 @@ async function extractPdf(absolute) {
15876
16116
  return stdout.trim();
15877
16117
  }
15878
16118
  async function ocrPdf(absolute) {
15879
- 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`);
15880
16120
  try {
15881
16121
  await execFileAsync2(
15882
16122
  "ocrmypdf",
@@ -15938,7 +16178,7 @@ async function readDisplayName(absolute) {
15938
16178
  const stem = dot === -1 ? base : base.slice(0, dot);
15939
16179
  if (base === `${stem}.meta.json`) return null;
15940
16180
  try {
15941
- 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");
15942
16182
  const meta = JSON.parse(raw);
15943
16183
  const dn = meta.displayName ?? meta.filename;
15944
16184
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -15959,7 +16199,7 @@ async function walkSubtree(root, dataRoot, out) {
15959
16199
  for (const entry of entries) {
15960
16200
  if (entry.isSymbolicLink()) continue;
15961
16201
  if (entry.isDirectory() && entry.name === ".uploads-tmp") continue;
15962
- const abs = join29(root, entry.name);
16202
+ const abs = join30(root, entry.name);
15963
16203
  if (entry.isDirectory()) {
15964
16204
  const sub = await walkSubtree(abs, dataRoot, out);
15965
16205
  if (!sub.clean) clean = false;
@@ -16315,7 +16555,7 @@ var UPLOAD_TMP_DIR = ".uploads-tmp";
16315
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;
16316
16556
  async function readMeta(absDir, baseName) {
16317
16557
  try {
16318
- const raw = await readFile4(join30(absDir, `${baseName}.meta.json`), "utf8");
16558
+ const raw = await readFile4(join31(absDir, `${baseName}.meta.json`), "utf8");
16319
16559
  const parsed = JSON.parse(raw);
16320
16560
  if (typeof parsed?.filename === "string") {
16321
16561
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -16370,7 +16610,7 @@ async function servableFilesIn(dirAbs, uuid) {
16370
16610
  }
16371
16611
  async function enrich(absolute, entry, accountNames) {
16372
16612
  if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
16373
- const dirAbs = join30(absolute, entry.name);
16613
+ const dirAbs = join31(absolute, entry.name);
16374
16614
  const meta = await readMeta(dirAbs, entry.name);
16375
16615
  if (meta?.filename) {
16376
16616
  const servable = await servableFilesIn(dirAbs, entry.name);
@@ -16379,7 +16619,7 @@ async function enrich(absolute, entry, accountNames) {
16379
16619
  let size = null;
16380
16620
  let modifiedAt = entry.modifiedAt;
16381
16621
  try {
16382
- const st = await stat4(join30(dirAbs, innerName));
16622
+ const st = await stat4(join31(dirAbs, innerName));
16383
16623
  size = st.size;
16384
16624
  modifiedAt = st.mtime.toISOString();
16385
16625
  } catch {
@@ -16554,7 +16794,7 @@ app22.get("/", requireAdminSession, async (c) => {
16554
16794
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
16555
16795
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
16556
16796
  try {
16557
- const entryPath = join30(absolute, name);
16797
+ const entryPath = join31(absolute, name);
16558
16798
  const s = await stat4(entryPath);
16559
16799
  entries.push({
16560
16800
  name,
@@ -16617,7 +16857,7 @@ app22.get("/download", requireAdminSession, async (c) => {
16617
16857
  console.error(`[data] op=scratchpad-no-session sessionId="${sessionId.slice(0, 8)}\u2026"`);
16618
16858
  return c.json({ error: "Not found" }, 404);
16619
16859
  }
16620
- const meta = readSidecarMeta(join30(projectDir, `${sessionId}.meta.json`));
16860
+ const meta = readSidecarMeta(join31(projectDir, `${sessionId}.meta.json`));
16621
16861
  if (!meta.accountId || meta.accountId !== accountId) {
16622
16862
  console.error(`[data] account-scope-blocked root="scratchpad" sessionId="${sessionId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
16623
16863
  return c.json({ error: "Not found" }, 404);
@@ -16712,7 +16952,7 @@ async function* walkRegularFiles(dirAbsolute) {
16712
16952
  const dirents = await readdir3(dirAbsolute, { withFileTypes: true });
16713
16953
  for (const d of dirents) {
16714
16954
  if (d.isSymbolicLink()) continue;
16715
- const child = join30(dirAbsolute, d.name);
16955
+ const child = join31(dirAbsolute, d.name);
16716
16956
  if (d.isDirectory()) {
16717
16957
  yield* walkRegularFiles(child);
16718
16958
  continue;
@@ -16822,7 +17062,7 @@ async function resolveUploadTarget(c, accountId, uid) {
16822
17062
  const base = resolveOwnAccountWrite(rawDir, accountId, "POST /api/admin/files/upload");
16823
17063
  if (!base.ok) return { ok: false, status: base.status, error: base.error };
16824
17064
  const relDir = relpath ? dirname11(relpath) : ".";
16825
- const destRel = relDir === "." ? base.relative : join30(base.relative, relDir);
17065
+ const destRel = relDir === "." ? base.relative : join31(base.relative, relDir);
16826
17066
  if (crossesForeignAccountPartition(destRel, accountId)) {
16827
17067
  console.error(`[data] account-scope-blocked endpoint="POST /api/admin/files/upload" path="${destRel}" account=${accountId.slice(0, 8)}\u2026`);
16828
17068
  return { ok: false, status: 404, error: "Not found" };
@@ -16896,7 +17136,7 @@ app22.post("/upload", requireAdminSession, async (c) => {
16896
17136
  });
16897
17137
  await unlink2(tmpPath).catch(() => {
16898
17138
  });
16899
- const tempRemoved = !existsSync27(tmpPath);
17139
+ const tempRemoved = !existsSync28(tmpPath);
16900
17140
  console.error(`[data-upload] op=cleanup uid=${uid} tempRemoved=${tempRemoved}`);
16901
17141
  };
16902
17142
  const reader = body.getReader();
@@ -16970,7 +17210,7 @@ async function discardChunkUpload(uploadId, state) {
16970
17210
  });
16971
17211
  await unlink2(state.tmpPath).catch(() => {
16972
17212
  });
16973
- const tempRemoved = !existsSync27(state.tmpPath);
17213
+ const tempRemoved = !existsSync28(state.tmpPath);
16974
17214
  console.error(`[data-upload] op=cleanup uid=${uploadId} tempRemoved=${tempRemoved}`);
16975
17215
  }
16976
17216
  async function writeChunkBody(body, out, alreadyReceived, ceiling) {
@@ -17199,7 +17439,7 @@ app22.delete("/", requireAdminSession, async (c) => {
17199
17439
  const dot = base.lastIndexOf(".");
17200
17440
  const stem = dot === -1 ? base : base.slice(0, dot);
17201
17441
  const containerDir = dirname11(absolute);
17202
- 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;
17203
17443
  const isAttachmentContainer = UUID_RE3.test(stem) && basename9(containerDir) === stem;
17204
17444
  await unlink2(absolute);
17205
17445
  if (sidecarPath) {
@@ -17209,7 +17449,7 @@ app22.delete("/", requireAdminSession, async (c) => {
17209
17449
  }
17210
17450
  }
17211
17451
  if (isAttachmentContainer) {
17212
- await unlink2(join30(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
17452
+ await unlink2(join31(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
17213
17453
  });
17214
17454
  await rmdir(containerDir).catch(() => {
17215
17455
  });
@@ -18313,8 +18553,8 @@ function isHiddenByDefault(label) {
18313
18553
  }
18314
18554
 
18315
18555
  // server/lib/top-level-labels.ts
18316
- import { readdirSync as readdirSync20, readFileSync as readFileSync31 } from "fs";
18317
- 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";
18318
18558
  var STATIC_TOP_LEVEL_LABELS = Object.freeze(
18319
18559
  /* @__PURE__ */ new Set([
18320
18560
  // Base-schema infra (schema-base.md has no top-level section).
@@ -18407,7 +18647,7 @@ function parseTopLevelLabels(content) {
18407
18647
  }
18408
18648
  function resolveReferencesDir() {
18409
18649
  if (process.env.MAXY_PLATFORM_ROOT) {
18410
- return join31(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
18650
+ return join32(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
18411
18651
  }
18412
18652
  return resolve24(import.meta.dirname, "../../../plugins/memory/references");
18413
18653
  }
@@ -18415,9 +18655,9 @@ function parseTableTopLevelLabels(referencesDir) {
18415
18655
  const labels = /* @__PURE__ */ new Set();
18416
18656
  const contributingFiles = [];
18417
18657
  try {
18418
- 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();
18419
18659
  for (const fileName of fileNames) {
18420
- const content = readFileSync31(join31(referencesDir, fileName), "utf-8");
18660
+ const content = readFileSync32(join32(referencesDir, fileName), "utf-8");
18421
18661
  const parsed = parseTopLevelLabels(content);
18422
18662
  if (parsed.length > 0) contributingFiles.push(fileName);
18423
18663
  for (const label of parsed) labels.add(label);
@@ -19571,7 +19811,7 @@ var graph_default_view_default = app28;
19571
19811
  // server/routes/admin/sidebar-artefacts.ts
19572
19812
  import { readdir as readdir4, stat as stat5 } from "fs/promises";
19573
19813
  import { resolve as resolve25, relative as relative5, isAbsolute as isAbsolute2, sep as sep7, basename as basename10 } from "path";
19574
- import { existsSync as existsSync28 } from "fs";
19814
+ import { existsSync as existsSync29 } from "fs";
19575
19815
  var LIMIT = 50;
19576
19816
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
19577
19817
  function toDataRootRelPath(absPath) {
@@ -19678,7 +19918,7 @@ async function fetchAgentTemplateRows(accountDir) {
19678
19918
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
19679
19919
  const names = /* @__PURE__ */ new Set();
19680
19920
  for (const dir of [overrideDir, bundledDir]) {
19681
- if (!existsSync28(dir)) continue;
19921
+ if (!existsSync29(dir)) continue;
19682
19922
  try {
19683
19923
  const entries = await readdir4(dir);
19684
19924
  for (const entry of entries) {
@@ -19693,7 +19933,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
19693
19933
  }
19694
19934
  async function readAgentTemplateRow(inp) {
19695
19935
  let chosenPath = null;
19696
- if (existsSync28(inp.overridePath)) {
19936
+ if (existsSync29(inp.overridePath)) {
19697
19937
  try {
19698
19938
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
19699
19939
  chosenPath = inp.overridePath;
@@ -19704,7 +19944,7 @@ async function readAgentTemplateRow(inp) {
19704
19944
  );
19705
19945
  return null;
19706
19946
  }
19707
- } else if (existsSync28(inp.bundledPath)) {
19947
+ } else if (existsSync29(inp.bundledPath)) {
19708
19948
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
19709
19949
  console.error(
19710
19950
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -20306,14 +20546,14 @@ app37.get("/", async (c) => {
20306
20546
  var system_stats_default = app37;
20307
20547
 
20308
20548
  // server/routes/admin/health.ts
20309
- import { existsSync as existsSync29, readFileSync as readFileSync32 } from "fs";
20310
- 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";
20311
20551
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
20312
20552
  var brandHostname = "maxy";
20313
- var brandJsonPath = join32(PLATFORM_ROOT6, "config", "brand.json");
20314
- if (existsSync29(brandJsonPath)) {
20553
+ var brandJsonPath = join33(PLATFORM_ROOT6, "config", "brand.json");
20554
+ if (existsSync30(brandJsonPath)) {
20315
20555
  try {
20316
- const brand = JSON.parse(readFileSync32(brandJsonPath, "utf-8"));
20556
+ const brand = JSON.parse(readFileSync33(brandJsonPath, "utf-8"));
20317
20557
  if (brand.hostname) brandHostname = brand.hostname;
20318
20558
  } catch {
20319
20559
  }
@@ -20322,8 +20562,8 @@ var VERSION_FILE = resolve26(PLATFORM_ROOT6, `config/.${brandHostname}-version`)
20322
20562
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
20323
20563
  var PROBE_TIMEOUT_MS = 1e3;
20324
20564
  function readVersion() {
20325
- if (!existsSync29(VERSION_FILE)) return "unknown";
20326
- return readFileSync32(VERSION_FILE, "utf-8").trim() || "unknown";
20565
+ if (!existsSync30(VERSION_FILE)) return "unknown";
20566
+ return readFileSync33(VERSION_FILE, "utf-8").trim() || "unknown";
20327
20567
  }
20328
20568
  async function probeConversationDb() {
20329
20569
  let session;
@@ -20502,7 +20742,7 @@ function managerLogFollowUrl(sessionId, opts) {
20502
20742
  }
20503
20743
 
20504
20744
  // server/routes/admin/linkedin-ingest.ts
20505
- var TAG28 = "[linkedin-ingest-route]";
20745
+ var TAG29 = "[linkedin-ingest-route]";
20506
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}$/;
20507
20747
  var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
20508
20748
  var LINKEDIN_URL = /^https:\/\/www\.linkedin\.com\//;
@@ -20606,29 +20846,29 @@ app39.post("/", requireAdminSession, async (c) => {
20606
20846
  try {
20607
20847
  body = await c.req.json();
20608
20848
  } catch {
20609
- console.error(TAG28 + " rejected status=400 reason=schema:body-not-json");
20849
+ console.error(TAG29 + " rejected status=400 reason=schema:body-not-json");
20610
20850
  return c.json({ ok: false, error: "schema", reason: "body-not-json" }, 400);
20611
20851
  }
20612
20852
  const v = validate(body);
20613
20853
  if (!v.ok) {
20614
- 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(","));
20615
20855
  return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
20616
20856
  }
20617
20857
  const envelope = v.envelope;
20618
20858
  const cacheKey = c.var.cacheKey ?? "";
20619
20859
  const senderId = getAccountIdForSession(cacheKey) ?? "";
20620
20860
  if (!senderId) {
20621
- console.error(TAG28 + " rejected status=500 reason=admin-account-not-resolved");
20861
+ console.error(TAG29 + " rejected status=500 reason=admin-account-not-resolved");
20622
20862
  return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
20623
20863
  }
20624
20864
  const payloadBytes = JSON.stringify(envelope).length;
20625
20865
  console.log(
20626
- 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
20627
20867
  );
20628
20868
  const initialMessage = buildInitialMessage(envelope);
20629
20869
  const spawnStart = Date.now();
20630
20870
  const sessionId = randomUUID13();
20631
- 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));
20632
20872
  const spawned = await managerRcSpawn({
20633
20873
  sessionId,
20634
20874
  initialMessage,
@@ -20637,12 +20877,12 @@ app39.post("/", requireAdminSession, async (c) => {
20637
20877
  });
20638
20878
  if ("error" in spawned) {
20639
20879
  console.error(
20640
- 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
20641
20881
  );
20642
20882
  return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: spawned.status, detail: spawned.error }, 502);
20643
20883
  }
20644
20884
  console.log(
20645
- 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)
20646
20886
  );
20647
20887
  return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
20648
20888
  });
@@ -20650,7 +20890,7 @@ var linkedin_ingest_default = app39;
20650
20890
 
20651
20891
  // server/routes/admin/post-turn-context.ts
20652
20892
  import neo4j3 from "neo4j-driver";
20653
- var TAG29 = "[post-turn-context]";
20893
+ var TAG30 = "[post-turn-context]";
20654
20894
  var STRIPPED_PROPERTIES2 = /* @__PURE__ */ new Set([
20655
20895
  "embedding",
20656
20896
  "passwordHash",
@@ -20692,7 +20932,7 @@ var app40 = new Hono();
20692
20932
  app40.get("/", async (c) => {
20693
20933
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20694
20934
  if (!isLoopbackAddr3(remoteAddr)) {
20695
- console.error(`${TAG29} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20935
+ console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20696
20936
  return c.json({ error: "post-turn-context-loopback-only" }, 403);
20697
20937
  }
20698
20938
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20701,7 +20941,7 @@ app40.get("/", async (c) => {
20701
20941
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
20702
20942
  const offender = tokens.find((t) => !isLoopbackAddr3(t));
20703
20943
  if (offender !== void 0) {
20704
- 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)}`);
20705
20945
  return c.json({ error: "post-turn-context-loopback-only" }, 403);
20706
20946
  }
20707
20947
  }
@@ -20733,7 +20973,7 @@ app40.get("/", async (c) => {
20733
20973
  writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
20734
20974
  const total = Date.now() - started;
20735
20975
  console.log(
20736
- `${TAG29} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
20976
+ `${TAG30} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
20737
20977
  );
20738
20978
  return c.json({
20739
20979
  writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
@@ -20742,7 +20982,7 @@ app40.get("/", async (c) => {
20742
20982
  const elapsed = Date.now() - started;
20743
20983
  const message = err instanceof Error ? err.message : String(err);
20744
20984
  console.error(
20745
- `${TAG29} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
20985
+ `${TAG30} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
20746
20986
  );
20747
20987
  return c.json({ error: `post-turn-context unavailable: ${message}` }, 503);
20748
20988
  } finally {
@@ -20855,7 +21095,7 @@ function formatPreviousContext(writes) {
20855
21095
  }
20856
21096
 
20857
21097
  // server/routes/admin/public-session-context.ts
20858
- var TAG30 = "[public-session-context]";
21098
+ var TAG31 = "[public-session-context]";
20859
21099
  function isLoopbackAddr4(addr) {
20860
21100
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
20861
21101
  }
@@ -20863,7 +21103,7 @@ var app41 = new Hono();
20863
21103
  app41.get("/", async (c) => {
20864
21104
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20865
21105
  if (!isLoopbackAddr4(remoteAddr)) {
20866
- console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21106
+ console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20867
21107
  return c.json({ error: "public-session-context-loopback-only" }, 403);
20868
21108
  }
20869
21109
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20872,7 +21112,7 @@ app41.get("/", async (c) => {
20872
21112
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
20873
21113
  const offender = tokens.find((t) => !isLoopbackAddr4(t));
20874
21114
  if (offender !== void 0) {
20875
- 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)}`);
20876
21116
  return c.json({ error: "public-session-context-loopback-only" }, 403);
20877
21117
  }
20878
21118
  }
@@ -20886,14 +21126,14 @@ app41.get("/", async (c) => {
20886
21126
  const writes = await fetchSliceWrites(session, sliceToken, accountId);
20887
21127
  const total = Date.now() - started;
20888
21128
  console.log(
20889
- `${TAG30} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
21129
+ `${TAG31} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
20890
21130
  );
20891
21131
  return c.json({ writes });
20892
21132
  } catch (err) {
20893
21133
  const elapsed = Date.now() - started;
20894
21134
  const message = err instanceof Error ? err.message : String(err);
20895
21135
  console.error(
20896
- `${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}"`
20897
21137
  );
20898
21138
  return c.json({ error: `public-session-context unavailable: ${message}` }, 503);
20899
21139
  } finally {
@@ -20912,7 +21152,7 @@ function getWebchatGateway() {
20912
21152
  }
20913
21153
 
20914
21154
  // server/routes/admin/public-session-exit.ts
20915
- var TAG31 = "[public-session-exit-route]";
21155
+ var TAG32 = "[public-session-exit-route]";
20916
21156
  function isLoopbackAddr5(addr) {
20917
21157
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
20918
21158
  }
@@ -20920,7 +21160,7 @@ var app42 = new Hono();
20920
21160
  app42.post("/", async (c) => {
20921
21161
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20922
21162
  if (!isLoopbackAddr5(remoteAddr)) {
20923
- console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21163
+ console.error(`${TAG32} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20924
21164
  return c.json({ error: "public-session-exit-loopback-only" }, 403);
20925
21165
  }
20926
21166
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20929,7 +21169,7 @@ app42.post("/", async (c) => {
20929
21169
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
20930
21170
  const offender = tokens.find((t) => !isLoopbackAddr5(t));
20931
21171
  if (offender !== void 0) {
20932
- 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)}`);
20933
21173
  return c.json({ error: "public-session-exit-loopback-only" }, 403);
20934
21174
  }
20935
21175
  }
@@ -20943,7 +21183,7 @@ app42.post("/", async (c) => {
20943
21183
  if (!sessionId) return c.json({ error: "sessionId required" }, 400);
20944
21184
  const gateway = getWebchatGateway();
20945
21185
  if (!gateway) {
20946
- 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)}`);
20947
21187
  return c.json({ error: "webchat-gateway-unset" }, 503);
20948
21188
  }
20949
21189
  gateway.handlePublicSessionExit(sessionId);
@@ -20952,7 +21192,7 @@ app42.post("/", async (c) => {
20952
21192
  var public_session_exit_default = app42;
20953
21193
 
20954
21194
  // server/routes/admin/access-session-evict.ts
20955
- var TAG32 = "[access-session-evict]";
21195
+ var TAG33 = "[access-session-evict]";
20956
21196
  function isLoopbackAddr6(addr) {
20957
21197
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
20958
21198
  }
@@ -20960,7 +21200,7 @@ var app43 = new Hono();
20960
21200
  app43.post("/", async (c) => {
20961
21201
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20962
21202
  if (!isLoopbackAddr6(remoteAddr)) {
20963
- console.error(`${TAG32} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21203
+ console.error(`${TAG33} reject reason=non-loopback remoteAddr=${remoteAddr}`);
20964
21204
  return c.json({ error: "access-session-evict-loopback-only" }, 403);
20965
21205
  }
20966
21206
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -20969,7 +21209,7 @@ app43.post("/", async (c) => {
20969
21209
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
20970
21210
  const offender = tokens.find((t) => !isLoopbackAddr6(t));
20971
21211
  if (offender !== void 0) {
20972
- 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)}`);
20973
21213
  return c.json({ error: "access-session-evict-loopback-only" }, 403);
20974
21214
  }
20975
21215
  }
@@ -20982,13 +21222,13 @@ app43.post("/", async (c) => {
20982
21222
  const grantId = typeof body.grantId === "string" ? body.grantId.trim() : "";
20983
21223
  if (!grantId) return c.json({ error: "grantId required" }, 400);
20984
21224
  const dropped = evictAccessSessionsByGrant(grantId);
20985
- console.log(`${TAG32} grantId=${grantId} dropped=${dropped}`);
21225
+ console.log(`${TAG33} grantId=${grantId} dropped=${dropped}`);
20986
21226
  return c.json({ ok: true, dropped });
20987
21227
  });
20988
21228
  var access_session_evict_default = app43;
20989
21229
 
20990
21230
  // server/routes/admin/enrol-person.ts
20991
- var TAG33 = "[enrol]";
21231
+ var TAG34 = "[enrol]";
20992
21232
  function isLoopbackAddr7(addr) {
20993
21233
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
20994
21234
  }
@@ -20997,7 +21237,7 @@ var app44 = new Hono();
20997
21237
  app44.post("/", async (c) => {
20998
21238
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
20999
21239
  if (!isLoopbackAddr7(remoteAddr)) {
21000
- console.error(`${TAG33} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21240
+ console.error(`${TAG34} reject reason=non-loopback remoteAddr=${remoteAddr}`);
21001
21241
  return c.json({ error: "enrol-person-loopback-only" }, 403);
21002
21242
  }
21003
21243
  const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
@@ -21006,7 +21246,7 @@ app44.post("/", async (c) => {
21006
21246
  const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
21007
21247
  const offender = tokens.find((t) => !isLoopbackAddr7(t));
21008
21248
  if (offender !== void 0) {
21009
- 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)}`);
21010
21250
  return c.json({ error: "enrol-person-loopback-only" }, 403);
21011
21251
  }
21012
21252
  }
@@ -21031,7 +21271,7 @@ app44.post("/", async (c) => {
21031
21271
  }
21032
21272
  const accountId = process.env.ACCOUNT_ID ?? "";
21033
21273
  if (!accountId) {
21034
- console.error(`${TAG33} op=person result=no-account-id`);
21274
+ console.error(`${TAG34} op=person result=no-account-id`);
21035
21275
  return c.json({ error: "no-account-id" }, 500);
21036
21276
  }
21037
21277
  let personId;
@@ -21039,7 +21279,7 @@ app44.post("/", async (c) => {
21039
21279
  personId = await enrolPerson({ accountId, phone, email, agentSlug });
21040
21280
  } catch (err) {
21041
21281
  console.error(
21042
- `${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)}"`
21043
21283
  );
21044
21284
  return c.json({ error: "enrol-failed" }, 500);
21045
21285
  }
@@ -21049,11 +21289,11 @@ app44.post("/", async (c) => {
21049
21289
  if (g) grant = { grantId: g.grantId, status: g.status, contactValue: g.contactValue };
21050
21290
  } catch (err) {
21051
21291
  console.error(
21052
- `${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)}"`
21053
21293
  );
21054
21294
  }
21055
21295
  console.log(
21056
- `${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)}`
21057
21297
  );
21058
21298
  return c.json({ personId, grant }, 200);
21059
21299
  });
@@ -21099,8 +21339,8 @@ app45.post("/launch", requireAdminSession, async (c) => {
21099
21339
  var browser_default = app45;
21100
21340
 
21101
21341
  // server/routes/admin/calendar.ts
21102
- import { existsSync as existsSync30 } from "fs";
21103
- import { join as join34 } from "path";
21342
+ import { existsSync as existsSync31 } from "fs";
21343
+ import { join as join35 } from "path";
21104
21344
 
21105
21345
  // server/lib/calendar-ics.ts
21106
21346
  var CRLF = "\r\n";
@@ -21199,8 +21439,8 @@ function countVEvents(ics) {
21199
21439
  }
21200
21440
 
21201
21441
  // server/lib/calendar-availability.ts
21202
- import { readFileSync as readFileSync33 } from "fs";
21203
- import { join as join33 } from "path";
21442
+ import { readFileSync as readFileSync34 } from "fs";
21443
+ import { join as join34 } from "path";
21204
21444
  var AVAILABILITY_FILENAME = "calendar-availability.json";
21205
21445
  var REQUIRED_KEYS = [
21206
21446
  "timezone",
@@ -21209,10 +21449,10 @@ var REQUIRED_KEYS = [
21209
21449
  "weekly"
21210
21450
  ];
21211
21451
  function readAvailabilityConfig(accountDir) {
21212
- const path3 = join33(accountDir, AVAILABILITY_FILENAME);
21452
+ const path3 = join34(accountDir, AVAILABILITY_FILENAME);
21213
21453
  let raw;
21214
21454
  try {
21215
- raw = readFileSync33(path3, "utf-8");
21455
+ raw = readFileSync34(path3, "utf-8");
21216
21456
  } catch {
21217
21457
  throw new Error(`availability not configured: ${path3} not found`);
21218
21458
  }
@@ -21571,7 +21811,7 @@ app46.get("/booking-link", requireAdminSession, (c) => {
21571
21811
  console.error('[calendar] op=booking-link-fail err="no account configured"');
21572
21812
  return c.json({ bookingDomain: null });
21573
21813
  }
21574
- if (!existsSync30(join34(account.accountDir, AVAILABILITY_FILENAME))) {
21814
+ if (!existsSync31(join35(account.accountDir, AVAILABILITY_FILENAME))) {
21575
21815
  console.log("[calendar] op=booking-link bookingDomain=none source=availability-config");
21576
21816
  return c.json({ bookingDomain: null });
21577
21817
  }
@@ -21607,7 +21847,7 @@ function toNum(v) {
21607
21847
  }
21608
21848
 
21609
21849
  // server/routes/admin/tasks-list.ts
21610
- var TAG34 = "[task-timer]";
21850
+ var TAG35 = "[task-timer]";
21611
21851
  var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
21612
21852
  var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
21613
21853
  var app47 = new Hono();
@@ -21615,7 +21855,7 @@ app47.get("/", requireAdminSession, async (c) => {
21615
21855
  const cacheKey = c.var.cacheKey;
21616
21856
  const accountId = getAccountIdForSession(cacheKey);
21617
21857
  if (!accountId) {
21618
- 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"`);
21619
21859
  return c.json({ error: "Account not found for session" }, 401);
21620
21860
  }
21621
21861
  const session = getSession();
@@ -21653,10 +21893,10 @@ app47.get("/", requireAdminSession, async (c) => {
21653
21893
  if (COMPLETED.has(status)) completed.push(row);
21654
21894
  else if (!HIDDEN_FROM_OPEN.has(status)) open.push(row);
21655
21895
  }
21656
- 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}`);
21657
21897
  return c.json({ open, completed });
21658
21898
  } catch (err) {
21659
- 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)}"`);
21660
21900
  return c.json({ error: "tasks-list-failed" }, 500);
21661
21901
  } finally {
21662
21902
  await session.close();
@@ -21666,7 +21906,7 @@ var tasks_list_default = app47;
21666
21906
 
21667
21907
  // server/routes/admin/task-timer-start.ts
21668
21908
  import { randomUUID as randomUUID14 } from "crypto";
21669
- var TAG35 = "[task-timer]";
21909
+ var TAG36 = "[task-timer]";
21670
21910
  var app48 = new Hono();
21671
21911
  app48.post("/", requireAdminSession, async (c) => {
21672
21912
  const cacheKey = c.var.cacheKey;
@@ -21688,7 +21928,7 @@ app48.post("/", requireAdminSession, async (c) => {
21688
21928
  { taskId, accountId }
21689
21929
  );
21690
21930
  if (target.records.length === 0) {
21691
- 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`);
21692
21932
  return c.json({ error: "task-not-found" }, 404);
21693
21933
  }
21694
21934
  const open = await session.run(
@@ -21700,7 +21940,7 @@ app48.post("/", requireAdminSession, async (c) => {
21700
21940
  const priorEntryId = open.records[0]?.get("entryId");
21701
21941
  const priorStartedAt = open.records[0]?.get("startedAt");
21702
21942
  if (priorEntryId) {
21703
- 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`);
21704
21944
  return c.json({ ok: true, running: true, entryId: priorEntryId, startedAt: priorStartedAt });
21705
21945
  }
21706
21946
  const entryId = randomUUID14();
@@ -21710,10 +21950,10 @@ app48.post("/", requireAdminSession, async (c) => {
21710
21950
  CREATE (te)-[:LOGGED_AGAINST]->(t)`,
21711
21951
  { taskId, accountId, entryId, now }
21712
21952
  );
21713
- console.log(`${TAG35} op=opened taskId=${taskId} entryId=${entryId} startedAt=${now}`);
21953
+ console.log(`${TAG36} op=opened taskId=${taskId} entryId=${entryId} startedAt=${now}`);
21714
21954
  return c.json({ ok: true, running: true, entryId, startedAt: now });
21715
21955
  } catch (err) {
21716
- 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)}"`);
21717
21957
  return c.json({ error: "task-timer-start-failed" }, 500);
21718
21958
  } finally {
21719
21959
  await session.close();
@@ -21723,7 +21963,7 @@ var task_timer_start_default = app48;
21723
21963
 
21724
21964
  // server/routes/admin/task-timer-stop.ts
21725
21965
  import neo4j5 from "neo4j-driver";
21726
- var TAG36 = "[task-timer]";
21966
+ var TAG37 = "[task-timer]";
21727
21967
  var app49 = new Hono();
21728
21968
  app49.post("/", requireAdminSession, async (c) => {
21729
21969
  const cacheKey = c.var.cacheKey;
@@ -21755,7 +21995,7 @@ app49.post("/", requireAdminSession, async (c) => {
21755
21995
  { taskId, accountId }
21756
21996
  );
21757
21997
  const secondsLogged2 = toNum(cur.records[0]?.get("secondsLogged"));
21758
- 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}`);
21759
21999
  return c.json({ ok: true, running: false, seconds: 0, secondsLogged: secondsLogged2 });
21760
22000
  }
21761
22001
  const seconds = secondsBetween(startedAt, now);
@@ -21778,11 +22018,11 @@ app49.post("/", requireAdminSession, async (c) => {
21778
22018
  const sumEntries = toNum(verify.records[0]?.get("sumEntries"));
21779
22019
  const sumAdjustments = toNum(verify.records[0]?.get("sumAdjustments"));
21780
22020
  const secondsLogged = toNum(verify.records[0]?.get("secondsLogged"));
21781
- console.log(`${TAG36} op=stop taskId=${taskId} entryId=${entryId} seconds=${seconds} totalAfter=${secondsLogged}`);
21782
- 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}`);
21783
22023
  return c.json({ ok: true, running: false, seconds, secondsLogged });
21784
22024
  } catch (err) {
21785
- 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)}"`);
21786
22026
  return c.json({ error: "task-timer-stop-failed" }, 500);
21787
22027
  } finally {
21788
22028
  await session.close();
@@ -21791,7 +22031,7 @@ app49.post("/", requireAdminSession, async (c) => {
21791
22031
  var task_timer_stop_default = app49;
21792
22032
 
21793
22033
  // server/routes/admin/task-complete.ts
21794
- var TAG37 = "[task-timer]";
22034
+ var TAG38 = "[task-timer]";
21795
22035
  var app50 = new Hono();
21796
22036
  app50.post("/", requireAdminSession, async (c) => {
21797
22037
  const cacheKey = c.var.cacheKey;
@@ -21818,10 +22058,10 @@ app50.post("/", requireAdminSession, async (c) => {
21818
22058
  return c.json({ error: "task-not-found" }, 404);
21819
22059
  }
21820
22060
  const secondsLogged = toNum(result.records[0].get("secondsLogged"));
21821
- console.log(`${TAG37} op=complete taskId=${taskId} status=completed secondsLogged=${secondsLogged}`);
22061
+ console.log(`${TAG38} op=complete taskId=${taskId} status=completed secondsLogged=${secondsLogged}`);
21822
22062
  return c.json({ ok: true, status: "completed", secondsLogged });
21823
22063
  } catch (err) {
21824
- 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)}"`);
21825
22065
  return c.json({ error: "task-complete-failed" }, 500);
21826
22066
  } finally {
21827
22067
  await session.close();
@@ -21832,7 +22072,7 @@ var task_complete_default = app50;
21832
22072
  // server/routes/admin/task-time-adjust.ts
21833
22073
  import { randomUUID as randomUUID15 } from "crypto";
21834
22074
  import neo4j6 from "neo4j-driver";
21835
- var TAG38 = "[task-time-adjust]";
22075
+ var TAG39 = "[task-time-adjust]";
21836
22076
  var app51 = new Hono();
21837
22077
  app51.post("/", requireAdminSession, async (c) => {
21838
22078
  const cacheKey = c.var.cacheKey;
@@ -21842,22 +22082,22 @@ app51.post("/", requireAdminSession, async (c) => {
21842
22082
  try {
21843
22083
  body = await c.req.json();
21844
22084
  } catch {
21845
- console.error(`${TAG38} op=reject reason=bad-json`);
22085
+ console.error(`${TAG39} op=reject reason=bad-json`);
21846
22086
  return c.json({ error: "invalid-json" }, 400);
21847
22087
  }
21848
22088
  const taskId = typeof body.taskId === "string" ? body.taskId : "";
21849
22089
  if (!taskId) {
21850
- console.error(`${TAG38} op=reject reason=no-task`);
22090
+ console.error(`${TAG39} op=reject reason=no-task`);
21851
22091
  return c.json({ error: "taskId required" }, 400);
21852
22092
  }
21853
22093
  const newSeconds = body.newSeconds;
21854
22094
  if (typeof newSeconds !== "number" || !Number.isInteger(newSeconds) || newSeconds < 0) {
21855
- 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}`);
21856
22096
  return c.json({ error: "newSeconds must be a non-negative integer" }, 400);
21857
22097
  }
21858
22098
  const adjustmentId = randomUUID15();
21859
22099
  const now = (/* @__PURE__ */ new Date()).toISOString();
21860
- 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}`);
21861
22101
  const session = getSession();
21862
22102
  try {
21863
22103
  const guard = await session.run(
@@ -21867,12 +22107,12 @@ app51.post("/", requireAdminSession, async (c) => {
21867
22107
  { taskId, accountId }
21868
22108
  );
21869
22109
  if (guard.records.length === 0) {
21870
- 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}`);
21871
22111
  return c.json({ error: "task-not-found" }, 404);
21872
22112
  }
21873
22113
  const openCount = toNum(guard.records[0].get("openCount"));
21874
22114
  if (openCount > 0) {
21875
- 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}`);
21876
22116
  return c.json({ error: "task-timer-running" }, 409);
21877
22117
  }
21878
22118
  const previousSeconds = toNum(guard.records[0].get("previousSeconds"));
@@ -21898,10 +22138,10 @@ app51.post("/", requireAdminSession, async (c) => {
21898
22138
  }
21899
22139
  );
21900
22140
  const secondsLoggedAfter = toNum(write.records[0]?.get("secondsLoggedAfter"));
21901
- 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}`);
21902
22142
  return c.json({ ok: true, secondsLogged: secondsLoggedAfter });
21903
22143
  } catch (err) {
21904
- 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)}"`);
21905
22145
  return c.json({ error: "task-time-adjust-failed" }, 500);
21906
22146
  } finally {
21907
22147
  await session.close();
@@ -21955,7 +22195,7 @@ app52.route("/task-time-adjust", task_time_adjust_default);
21955
22195
  var admin_default = app52;
21956
22196
 
21957
22197
  // server/routes/access/verify-token.ts
21958
- var TAG39 = "[access-verify]";
22198
+ var TAG40 = "[access-verify]";
21959
22199
  var MINT_TAG = "[access-session-mint]";
21960
22200
  var COOKIE_NAME = "__access_session";
21961
22201
  var app53 = new Hono();
@@ -21974,39 +22214,39 @@ app53.post("/", async (c) => {
21974
22214
  }
21975
22215
  const rateMsg = checkAccessRateLimit(ip, agentSlug);
21976
22216
  if (rateMsg) {
21977
- console.error(`${TAG39} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
22217
+ console.error(`${TAG40} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
21978
22218
  return c.json({ error: rateMsg }, 429);
21979
22219
  }
21980
22220
  const grant = await findGrantByMagicToken(token);
21981
22221
  if (!grant) {
21982
22222
  recordAccessFailedAttempt(ip, agentSlug);
21983
- console.error(`${TAG39} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
22223
+ console.error(`${TAG40} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
21984
22224
  return c.json({ error: "invalid-or-expired-link" }, 401);
21985
22225
  }
21986
22226
  if (grant.agentSlug !== agentSlug) {
21987
22227
  recordAccessFailedAttempt(ip, agentSlug);
21988
22228
  console.error(
21989
- `${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}`
21990
22230
  );
21991
22231
  return c.json({ error: "invalid-or-expired-link" }, 401);
21992
22232
  }
21993
22233
  if (grant.status === "expired" || grant.status === "revoked") {
21994
22234
  recordAccessFailedAttempt(ip, agentSlug);
21995
22235
  console.error(
21996
- `${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}`
21997
22237
  );
21998
22238
  return c.json({ error: "access-no-longer-valid" }, 401);
21999
22239
  }
22000
22240
  if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
22001
22241
  recordAccessFailedAttempt(ip, agentSlug);
22002
22242
  console.error(
22003
- `${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}`
22004
22244
  );
22005
22245
  return c.json({ error: "access-no-longer-valid" }, 401);
22006
22246
  }
22007
22247
  if (!grant.sliceToken) {
22008
22248
  console.error(
22009
- `${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`
22010
22250
  );
22011
22251
  return c.json({ error: "grant-misconfigured" }, 500);
22012
22252
  }
@@ -22022,12 +22262,12 @@ app53.post("/", async (c) => {
22022
22262
  await consumeMagicTokenAndActivate(grant.grantId);
22023
22263
  } catch (err) {
22024
22264
  console.error(
22025
- `${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)}"`
22026
22266
  );
22027
22267
  return c.json({ error: "verification-failed" }, 500);
22028
22268
  }
22029
22269
  clearAccessRateLimit(ip, agentSlug);
22030
- 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}`);
22031
22271
  console.log(
22032
22272
  `${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
22033
22273
  );
@@ -22103,7 +22343,7 @@ async function sendMagicLinkEmail(payload) {
22103
22343
  }
22104
22344
 
22105
22345
  // server/routes/access/request-magic-link.ts
22106
- var TAG40 = "[access-request-link]";
22346
+ var TAG41 = "[access-request-link]";
22107
22347
  var app54 = new Hono();
22108
22348
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
22109
22349
  app54.post("/", async (c) => {
@@ -22120,18 +22360,18 @@ app54.post("/", async (c) => {
22120
22360
  }
22121
22361
  const rateMsg = checkRequestLinkRateLimit(contactValue);
22122
22362
  if (rateMsg) {
22123
- console.error(`${TAG40} contactValue=${maskContact(contactValue)} result=rate-limited`);
22363
+ console.error(`${TAG41} contactValue=${maskContact(contactValue)} result=rate-limited`);
22124
22364
  return c.json({ error: rateMsg }, 429);
22125
22365
  }
22126
22366
  recordRequestLinkAttempt(contactValue);
22127
22367
  const accountId = process.env.ACCOUNT_ID ?? "";
22128
22368
  if (!accountId) {
22129
- console.error(`${TAG40} contactValue=${maskContact(contactValue)} result=no-account-id`);
22369
+ console.error(`${TAG41} contactValue=${maskContact(contactValue)} result=no-account-id`);
22130
22370
  return c.json({ message: VISITOR_MESSAGE }, 200);
22131
22371
  }
22132
22372
  const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
22133
22373
  if (!grant) {
22134
- console.log(`${TAG40} contactValue=${maskContact(contactValue)} result=notfound`);
22374
+ console.log(`${TAG41} contactValue=${maskContact(contactValue)} result=notfound`);
22135
22375
  return c.json({ message: VISITOR_MESSAGE }, 200);
22136
22376
  }
22137
22377
  let token;
@@ -22139,7 +22379,7 @@ app54.post("/", async (c) => {
22139
22379
  token = await generateNewMagicToken(grant.grantId);
22140
22380
  } catch (err) {
22141
22381
  console.error(
22142
- `${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)}"`
22143
22383
  );
22144
22384
  return c.json({ message: VISITOR_MESSAGE }, 200);
22145
22385
  }
@@ -22171,12 +22411,12 @@ app54.post("/", async (c) => {
22171
22411
  });
22172
22412
  if (!sendResult.ok) {
22173
22413
  console.error(
22174
- `${TAG40} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
22414
+ `${TAG41} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
22175
22415
  );
22176
22416
  return c.json({ message: VISITOR_MESSAGE }, 200);
22177
22417
  }
22178
22418
  console.log(
22179
- `${TAG40} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
22419
+ `${TAG41} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
22180
22420
  );
22181
22421
  return c.json({ message: VISITOR_MESSAGE }, 200);
22182
22422
  });
@@ -22189,7 +22429,7 @@ app55.route("/request-magic-link", request_magic_link_default);
22189
22429
  var access_default = app55;
22190
22430
 
22191
22431
  // server/routes/sites.ts
22192
- 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";
22193
22433
  import { resolve as resolve28 } from "path";
22194
22434
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
22195
22435
  var MIME = {
@@ -22255,7 +22495,7 @@ app56.get("/:rel{.*}", (c) => {
22255
22495
  }
22256
22496
  let stat8;
22257
22497
  try {
22258
- stat8 = existsSync31(filePath) ? statSync12(filePath) : null;
22498
+ stat8 = existsSync32(filePath) ? statSync12(filePath) : null;
22259
22499
  } catch {
22260
22500
  stat8 = null;
22261
22501
  }
@@ -22274,7 +22514,7 @@ app56.get("/:rel{.*}", (c) => {
22274
22514
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
22275
22515
  return c.text("Forbidden", 403);
22276
22516
  }
22277
- if (!existsSync31(filePath)) {
22517
+ if (!existsSync32(filePath)) {
22278
22518
  console.error(`[sites] not-found path=${reqPath} status=404`);
22279
22519
  return c.text("Not found", 404);
22280
22520
  }
@@ -22293,7 +22533,7 @@ app56.get("/:rel{.*}", (c) => {
22293
22533
  }
22294
22534
  let body;
22295
22535
  try {
22296
- body = readFileSync34(realPath);
22536
+ body = readFileSync35(realPath);
22297
22537
  } catch (err) {
22298
22538
  const code = err?.code;
22299
22539
  if (code === "EISDIR") {
@@ -22328,8 +22568,8 @@ app56.get("/:rel{.*}", (c) => {
22328
22568
  var sites_default = app56;
22329
22569
 
22330
22570
  // app/lib/visitor-token.ts
22331
- import { createHmac, randomBytes, timingSafeEqual } from "crypto";
22332
- 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";
22333
22573
  import { dirname as dirname12 } from "path";
22334
22574
  var TOKEN_PREFIX = "v1.";
22335
22575
  var SECRET_BYTES = 32;
@@ -22338,21 +22578,21 @@ var cachedSecret = null;
22338
22578
  function getSecret() {
22339
22579
  if (cachedSecret) return cachedSecret;
22340
22580
  try {
22341
- const hex2 = readFileSync35(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
22581
+ const hex2 = readFileSync36(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
22342
22582
  if (hex2.length === SECRET_BYTES * 2) {
22343
22583
  cachedSecret = Buffer.from(hex2, "hex");
22344
22584
  return cachedSecret;
22345
22585
  }
22346
22586
  } catch {
22347
22587
  }
22348
- const fresh = randomBytes(SECRET_BYTES).toString("hex");
22588
+ const fresh = randomBytes2(SECRET_BYTES).toString("hex");
22349
22589
  try {
22350
- mkdirSync7(dirname12(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
22351
- 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" });
22352
22592
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
22353
22593
  } catch {
22354
22594
  }
22355
- const hex = readFileSync35(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
22595
+ const hex = readFileSync36(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
22356
22596
  cachedSecret = Buffer.from(hex, "hex");
22357
22597
  return cachedSecret;
22358
22598
  }
@@ -22405,8 +22645,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
22405
22645
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
22406
22646
 
22407
22647
  // app/lib/brand-config.ts
22408
- import { existsSync as existsSync32, readFileSync as readFileSync36 } from "fs";
22409
- import { join as join35 } from "path";
22648
+ import { existsSync as existsSync33, readFileSync as readFileSync37 } from "fs";
22649
+ import { join as join36 } from "path";
22410
22650
  var cached2 = null;
22411
22651
  var cachedAttempted = false;
22412
22652
  function readBrandConfig() {
@@ -22414,10 +22654,10 @@ function readBrandConfig() {
22414
22654
  cachedAttempted = true;
22415
22655
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
22416
22656
  if (!platformRoot5) return null;
22417
- const brandPath = join35(platformRoot5, "config", "brand.json");
22418
- if (!existsSync32(brandPath)) return null;
22657
+ const brandPath = join36(platformRoot5, "config", "brand.json");
22658
+ if (!existsSync33(brandPath)) return null;
22419
22659
  try {
22420
- cached2 = JSON.parse(readFileSync36(brandPath, "utf-8"));
22660
+ cached2 = JSON.parse(readFileSync37(brandPath, "utf-8"));
22421
22661
  return cached2;
22422
22662
  } catch {
22423
22663
  return null;
@@ -22906,13 +23146,13 @@ var visitor_event_default = app59;
22906
23146
 
22907
23147
  // server/routes/session.ts
22908
23148
  import { resolve as resolve29 } from "path";
22909
- 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";
22910
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;
22911
23151
  function writeBrandingCache(accountId, agentSlug, branding) {
22912
23152
  try {
22913
23153
  const cacheDir = resolve29(MAXY_DIR, "branding-cache", accountId);
22914
- mkdirSync8(cacheDir, { recursive: true });
22915
- 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");
22916
23156
  } catch (err) {
22917
23157
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
22918
23158
  }
@@ -22990,7 +23230,7 @@ app60.post("/", async (c) => {
22990
23230
  let agentConfig = null;
22991
23231
  if (account) {
22992
23232
  const agentDir = resolve29(account.accountDir, "agents", agentSlug);
22993
- if (!existsSync33(agentDir) || !existsSync33(resolve29(agentDir, "config.json"))) {
23233
+ if (!existsSync34(agentDir) || !existsSync34(resolve29(agentDir, "config.json"))) {
22994
23234
  return c.json({ error: "Agent not found" }, 404);
22995
23235
  }
22996
23236
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -23238,7 +23478,7 @@ app61.get("/free-busy", async (c) => {
23238
23478
  var calendar_public_default = app61;
23239
23479
 
23240
23480
  // app/lib/timeentry-census.ts
23241
- var TAG41 = "[timeentry-census]";
23481
+ var TAG42 = "[timeentry-census]";
23242
23482
  function reconcileTimeEntries(rows, now, horizonMs) {
23243
23483
  const openEntries = rows.openEntries.length;
23244
23484
  let oldestOpenAgeMs = 0;
@@ -23278,12 +23518,12 @@ async function runTimeEntryCensusOnce(session, now, horizonMs) {
23278
23518
  sumAdjustments: toNum(r.get("sumAdjustments"))
23279
23519
  }));
23280
23520
  const finding = reconcileTimeEntries({ openEntries, taskSums }, now, horizonMs);
23281
- 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}`;
23282
23522
  if (finding.alarm) console.error(`${line} alarm=true`);
23283
23523
  else console.log(line);
23284
23524
  return finding;
23285
23525
  } catch (err) {
23286
- console.error(`${TAG41} error="${err instanceof Error ? err.message : String(err)}"`);
23526
+ console.error(`${TAG42} error="${err instanceof Error ? err.message : String(err)}"`);
23287
23527
  return null;
23288
23528
  }
23289
23529
  }
@@ -23297,13 +23537,13 @@ function startTimeEntryCensus(openSession, opts = {}) {
23297
23537
  try {
23298
23538
  session = openSession();
23299
23539
  } catch (err) {
23300
- 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)}"`);
23301
23541
  return;
23302
23542
  }
23303
23543
  try {
23304
23544
  await runTimeEntryCensusOnce(session, Date.now(), horizonMs);
23305
23545
  } catch (err) {
23306
- 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)}"`);
23307
23547
  } finally {
23308
23548
  try {
23309
23549
  await session.close();
@@ -23666,8 +23906,8 @@ async function migrateUploads(opts = {}) {
23666
23906
 
23667
23907
  // app/lib/migrate-admin-webchat-sidecars.ts
23668
23908
  import { readdir as readdir6, readFile as readFile6, rename as rename3, writeFile as writeFile4, unlink as unlink3 } from "fs/promises";
23669
- import { existsSync as existsSync34 } from "fs";
23670
- import { join as join36 } from "path";
23909
+ import { existsSync as existsSync35 } from "fs";
23910
+ import { join as join37 } from "path";
23671
23911
  var ADMIN_ROLE2 = "admin";
23672
23912
  var WEBCHAT_CHANNEL2 = "webchat";
23673
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;
@@ -23696,7 +23936,7 @@ async function writeRaw(path3, obj) {
23696
23936
  await rename3(tmp, path3);
23697
23937
  } catch (err) {
23698
23938
  try {
23699
- if (existsSync34(tmp)) await unlink3(tmp);
23939
+ if (existsSync35(tmp)) await unlink3(tmp);
23700
23940
  } catch {
23701
23941
  }
23702
23942
  throw err;
@@ -23712,7 +23952,7 @@ async function collectLiveSidecars(projectsRoot) {
23712
23952
  }
23713
23953
  for (const slug of slugs) {
23714
23954
  if (!slug.isDirectory()) continue;
23715
- const slugDir = join36(projectsRoot, slug.name);
23955
+ const slugDir = join37(projectsRoot, slug.name);
23716
23956
  let entries;
23717
23957
  try {
23718
23958
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -23721,9 +23961,9 @@ async function collectLiveSidecars(projectsRoot) {
23721
23961
  }
23722
23962
  for (const entry of entries) {
23723
23963
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
23724
- out.push(join36(slugDir, entry.name));
23964
+ out.push(join37(slugDir, entry.name));
23725
23965
  } else if (entry.isDirectory() && entry.name === "subagents") {
23726
- const subDir = join36(slugDir, entry.name);
23966
+ const subDir = join37(slugDir, entry.name);
23727
23967
  let subs;
23728
23968
  try {
23729
23969
  subs = await readdir6(subDir, { withFileTypes: true });
@@ -23731,7 +23971,7 @@ async function collectLiveSidecars(projectsRoot) {
23731
23971
  continue;
23732
23972
  }
23733
23973
  for (const s of subs) {
23734
- 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));
23735
23975
  }
23736
23976
  }
23737
23977
  }
@@ -23743,7 +23983,7 @@ function shortId(path3) {
23743
23983
  return base.slice(0, 8);
23744
23984
  }
23745
23985
  async function migrateAdminWebchatSidecars(opts = {}) {
23746
- 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) ?? "";
23747
23987
  const usersFile = opts.usersFile ?? USERS_FILE;
23748
23988
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
23749
23989
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -25411,14 +25651,14 @@ function makeFileDelivery(opts) {
25411
25651
  }
25412
25652
 
25413
25653
  // app/lib/webchat/file-delivery.ts
25414
- var TAG42 = "[webchat-adaptor]";
25654
+ var TAG43 = "[webchat-adaptor]";
25415
25655
  function platformRoot2() {
25416
25656
  return process.env.MAXY_PLATFORM_ROOT || "";
25417
25657
  }
25418
25658
  function makeWebchatSendFile(entry) {
25419
25659
  return async (filePath) => {
25420
25660
  if (!entry.accountId) {
25421
- 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}`);
25422
25662
  return { ok: false, error: "no-account" };
25423
25663
  }
25424
25664
  const accountDir = resolve32(platformRoot2(), "..", "data/accounts", entry.accountId);
@@ -25426,14 +25666,14 @@ function makeWebchatSendFile(entry) {
25426
25666
  const resolved = realpathSync8(filePath);
25427
25667
  const accountResolved = realpathSync8(accountDir);
25428
25668
  if (!resolved.startsWith(accountResolved + "/")) {
25429
- 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}`);
25430
25670
  return { ok: false, error: "outside-account" };
25431
25671
  }
25432
25672
  return { ok: true };
25433
25673
  } catch (err) {
25434
25674
  const code = err.code;
25435
25675
  console.error(
25436
- `${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}`
25437
25677
  );
25438
25678
  return { ok: false, error: code === "ENOENT" ? "not-found" : "path-error" };
25439
25679
  }
@@ -25442,7 +25682,7 @@ function makeWebchatSendFile(entry) {
25442
25682
  function makeWebchatFileDelivery(entry) {
25443
25683
  return makeFileDelivery({
25444
25684
  entry,
25445
- tag: TAG42,
25685
+ tag: TAG43,
25446
25686
  channel: "webchat",
25447
25687
  sendFile: makeWebchatSendFile(entry),
25448
25688
  deferUntilVerdict: true
@@ -25504,7 +25744,7 @@ function buildPublicWebchatSpawnRequest(input) {
25504
25744
  }
25505
25745
 
25506
25746
  // app/lib/whatsapp/inbound/file-delivery-bridge.ts
25507
- var TAG43 = "[whatsapp-adaptor]";
25747
+ var TAG44 = "[whatsapp-adaptor]";
25508
25748
  var SEND_USER_FILE2 = "SendUserFile";
25509
25749
  var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
25510
25750
  function platformRoot3() {
@@ -25522,7 +25762,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
25522
25762
  });
25523
25763
  if (result.ok) return { ok: true };
25524
25764
  console.error(
25525
- `${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}`
25526
25766
  );
25527
25767
  return { ok: false, error: result.error };
25528
25768
  };
@@ -25530,7 +25770,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
25530
25770
  function makeWhatsAppFileDelivery(entry, maxyAccountId) {
25531
25771
  const shared = makeFileDelivery({
25532
25772
  entry,
25533
- tag: TAG43,
25773
+ tag: TAG44,
25534
25774
  channel: "whatsapp",
25535
25775
  sendFile: makeWhatsAppSendFile(entry, maxyAccountId)
25536
25776
  });
@@ -25565,7 +25805,7 @@ function makeWhatsAppFileDelivery(entry, maxyAccountId) {
25565
25805
  if (!delivered) {
25566
25806
  const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
25567
25807
  console.error(
25568
- `${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}`
25569
25809
  );
25570
25810
  }
25571
25811
  }
@@ -25969,7 +26209,7 @@ function buildTelegramSpawnRequest(input) {
25969
26209
  import { realpathSync as realpathSync9 } from "fs";
25970
26210
  import { readFile as readFile7, stat as stat7 } from "fs/promises";
25971
26211
  import { resolve as resolve33, basename as basename11 } from "path";
25972
- var TAG44 = "[telegram:outbound]";
26212
+ var TAG45 = "[telegram:outbound]";
25973
26213
  var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
25974
26214
  async function sendTelegramDocument(input) {
25975
26215
  const { botToken, chatId, filePath, caption, maxyAccountId, platformRoot: platformRoot5 } = input;
@@ -25985,16 +26225,16 @@ async function sendTelegramDocument(input) {
25985
26225
  resolvedPath = realpathSync9(filePath);
25986
26226
  const accountResolved = realpathSync9(accountDir);
25987
26227
  if (!resolvedPath.startsWith(accountResolved + "/")) {
25988
- console.error(`${TAG44} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
26228
+ console.error(`${TAG45} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
25989
26229
  return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
25990
26230
  }
25991
26231
  } catch (err) {
25992
26232
  const code = err.code;
25993
26233
  if (code === "ENOENT") {
25994
- console.error(`${TAG44} document ENOENT path=${filePath}`);
26234
+ console.error(`${TAG45} document ENOENT path=${filePath}`);
25995
26235
  return { ok: false, status: 404, error: `File not found: ${filePath}` };
25996
26236
  }
25997
- console.error(`${TAG44} document path error: ${String(err)}`);
26237
+ console.error(`${TAG45} document path error: ${String(err)}`);
25998
26238
  return { ok: false, status: 500, error: String(err) };
25999
26239
  }
26000
26240
  const fileStat = await stat7(resolvedPath);
@@ -26027,13 +26267,13 @@ async function sendTelegramDocument(input) {
26027
26267
  error = e instanceof Error ? e.message : String(e);
26028
26268
  }
26029
26269
  console.error(
26030
- `${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}` : "")
26031
26271
  );
26032
26272
  return ok ? { ok: true, messageId } : { ok: false, status: 500, error };
26033
26273
  }
26034
26274
 
26035
26275
  // app/lib/telegram/outbound/file-delivery.ts
26036
- var TAG45 = "[telegram:outbound]";
26276
+ var TAG46 = "[telegram:outbound]";
26037
26277
  function platformRoot4() {
26038
26278
  return process.env.MAXY_PLATFORM_ROOT || "";
26039
26279
  }
@@ -26045,11 +26285,11 @@ function makeTelegramSendFile(entry) {
26045
26285
  botToken = (entry.role === "admin" ? tg?.adminBotToken : tg?.publicBotToken) ?? null;
26046
26286
  }
26047
26287
  if (!botToken) {
26048
- 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}`);
26049
26289
  return { ok: false, error: "no-bot-token" };
26050
26290
  }
26051
26291
  if (entry.replyTarget == null) {
26052
- 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}`);
26053
26293
  return { ok: false, error: "no-reply-target" };
26054
26294
  }
26055
26295
  const result = await sendTelegramDocument({
@@ -26066,7 +26306,7 @@ function makeTelegramSendFile(entry) {
26066
26306
  function makeTelegramFileDelivery(entry) {
26067
26307
  return makeFileDelivery({
26068
26308
  entry,
26069
- tag: TAG45,
26309
+ tag: TAG46,
26070
26310
  channel: "telegram",
26071
26311
  sendFile: makeTelegramSendFile(entry)
26072
26312
  });
@@ -26106,17 +26346,17 @@ function startTelegramNativeFileFollower(input) {
26106
26346
  }
26107
26347
 
26108
26348
  // server/telegram-descriptor.ts
26109
- import { resolve as resolve34, join as join37 } from "path";
26349
+ import { resolve as resolve34, join as join38 } from "path";
26110
26350
  function telegramGatewayUrl() {
26111
26351
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
26112
26352
  }
26113
26353
  function telegramServerPath() {
26114
- 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");
26115
26355
  }
26116
26356
 
26117
26357
  // app/lib/channel-pty-bridge/public-session-end-review.ts
26118
26358
  import { randomUUID as randomUUID16 } from "crypto";
26119
- var TAG46 = "[public-session-review]";
26359
+ var TAG47 = "[public-session-review]";
26120
26360
  var CONSUMED_CAP = 500;
26121
26361
  var consumed = /* @__PURE__ */ new Set();
26122
26362
  function consumeOnce(sessionId) {
@@ -26143,7 +26383,7 @@ async function fetchJsonl(sessionId) {
26143
26383
  return await res.text();
26144
26384
  } catch (err) {
26145
26385
  console.error(
26146
- `${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)}"`
26147
26387
  );
26148
26388
  return null;
26149
26389
  }
@@ -26167,7 +26407,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
26167
26407
  const res = await fetch(url);
26168
26408
  if (!res.ok) {
26169
26409
  console.error(
26170
- `${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}`
26171
26411
  );
26172
26412
  return [];
26173
26413
  }
@@ -26175,7 +26415,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
26175
26415
  return Array.isArray(body.writes) ? body.writes : [];
26176
26416
  } catch (err) {
26177
26417
  console.error(
26178
- `${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)}"`
26179
26419
  );
26180
26420
  return [];
26181
26421
  }
@@ -26204,7 +26444,7 @@ function composeInitialMessage(input) {
26204
26444
  }
26205
26445
  async function dispatchReviewer(input, initialMessage) {
26206
26446
  const sessionId = randomUUID16();
26207
- 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)}`);
26208
26448
  const spawned = await managerRcSpawn({
26209
26449
  sessionId,
26210
26450
  initialMessage,
@@ -26224,21 +26464,21 @@ async function firePublicSessionEndReview(input) {
26224
26464
  const dispatchedAt = Date.now();
26225
26465
  if (consumed.has(input.sessionId)) {
26226
26466
  console.log(
26227
- `${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`
26228
26468
  );
26229
26469
  return;
26230
26470
  }
26231
26471
  const jsonl = await fetchJsonl(input.sessionId);
26232
26472
  if (!jsonl) {
26233
26473
  console.log(
26234
- `${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`
26235
26475
  );
26236
26476
  return;
26237
26477
  }
26238
26478
  const operatorTurns = countOperatorTurns(jsonl);
26239
26479
  if (operatorTurns === 0) {
26240
26480
  console.log(
26241
- `${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`
26242
26482
  );
26243
26483
  return;
26244
26484
  }
@@ -26252,19 +26492,19 @@ async function firePublicSessionEndReview(input) {
26252
26492
  });
26253
26493
  if (!consumeOnce(input.sessionId)) {
26254
26494
  console.log(
26255
- `${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`
26256
26496
  );
26257
26497
  return;
26258
26498
  }
26259
26499
  const dispatched = await dispatchReviewer(input, initialMessage);
26260
26500
  if (!dispatched.ok) {
26261
26501
  console.error(
26262
- `${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}`
26263
26503
  );
26264
26504
  return;
26265
26505
  }
26266
26506
  console.log(
26267
- `${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}`
26268
26508
  );
26269
26509
  }
26270
26510
 
@@ -26398,7 +26638,7 @@ function broadcastAdminShutdown(reason) {
26398
26638
 
26399
26639
  // ../lib/entitlement/src/index.ts
26400
26640
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
26401
- 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";
26402
26642
  import { resolve as resolve35 } from "path";
26403
26643
 
26404
26644
  // ../lib/entitlement/src/canonicalize.ts
@@ -26447,7 +26687,7 @@ function resolveEntitlement(brand, account) {
26447
26687
  return logResolved(implicitTrust(account), null);
26448
26688
  }
26449
26689
  const entitlementPath = resolve35(brand.configDir, "entitlement.json");
26450
- if (!existsSync35(entitlementPath)) {
26690
+ if (!existsSync36(entitlementPath)) {
26451
26691
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
26452
26692
  }
26453
26693
  const stat8 = statSync13(entitlementPath);
@@ -26462,7 +26702,7 @@ function resolveEntitlement(brand, account) {
26462
26702
  function verifyAndResolve(brand, entitlementPath, account) {
26463
26703
  let pubkeyPem;
26464
26704
  try {
26465
- pubkeyPem = readFileSync37(pubkeyPath(brand), "utf-8");
26705
+ pubkeyPem = readFileSync38(pubkeyPath(brand), "utf-8");
26466
26706
  } catch (err) {
26467
26707
  return logResolved(anonymousFallback("pubkey-missing"), {
26468
26708
  reason: "pubkey-missing"
@@ -26476,7 +26716,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
26476
26716
  }
26477
26717
  let envelope;
26478
26718
  try {
26479
- envelope = JSON.parse(readFileSync37(entitlementPath, "utf-8"));
26719
+ envelope = JSON.parse(readFileSync38(entitlementPath, "utf-8"));
26480
26720
  } catch {
26481
26721
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
26482
26722
  }
@@ -26637,14 +26877,14 @@ function clientFrom(c) {
26637
26877
  );
26638
26878
  }
26639
26879
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
26640
- 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") : "";
26641
26881
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
26642
- if (BRAND_JSON_PATH && !existsSync36(BRAND_JSON_PATH)) {
26882
+ if (BRAND_JSON_PATH && !existsSync37(BRAND_JSON_PATH)) {
26643
26883
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
26644
26884
  }
26645
- if (BRAND_JSON_PATH && existsSync36(BRAND_JSON_PATH)) {
26885
+ if (BRAND_JSON_PATH && existsSync37(BRAND_JSON_PATH)) {
26646
26886
  try {
26647
- const parsed = JSON.parse(readFileSync38(BRAND_JSON_PATH, "utf-8"));
26887
+ const parsed = JSON.parse(readFileSync39(BRAND_JSON_PATH, "utf-8"));
26648
26888
  BRAND = { ...BRAND, ...parsed };
26649
26889
  } catch (err) {
26650
26890
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -26676,11 +26916,11 @@ var brandLoginOpts = {
26676
26916
  appleTouchIconPath: brandAppIcon512Path,
26677
26917
  themeColor: BRAND.defaultColors?.primary
26678
26918
  };
26679
- var ALIAS_DOMAINS_PATH = join38(homedir4(), BRAND.configDir, "alias-domains.json");
26919
+ var ALIAS_DOMAINS_PATH = join39(homedir4(), BRAND.configDir, "alias-domains.json");
26680
26920
  function loadAliasDomains() {
26681
26921
  try {
26682
- if (!existsSync36(ALIAS_DOMAINS_PATH)) return null;
26683
- 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"));
26684
26924
  if (!Array.isArray(parsed)) {
26685
26925
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
26686
26926
  return null;
@@ -26744,7 +26984,7 @@ async function recordPassiveDispatch(input) {
26744
26984
  var waGateway = new WaGateway({
26745
26985
  fetchStandingRules: fetchAccountStandingRules,
26746
26986
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
26747
- 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"),
26748
26988
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
26749
26989
  // path-validation scope) is the sender's effective SESSION account, resolved
26750
26990
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -26759,7 +26999,7 @@ var waGateway = new WaGateway({
26759
26999
  caption,
26760
27000
  accountId,
26761
27001
  maxyAccountId,
26762
- platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, ".."))
27002
+ platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, ".."))
26763
27003
  });
26764
27004
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
26765
27005
  },
@@ -26856,7 +27096,7 @@ function runDuplicateSenderAudit() {
26856
27096
  try {
26857
27097
  const configDir2 = process.env.CLAUDE_CONFIG_DIR;
26858
27098
  if (!configDir2) return;
26859
- const projectsRoot = join38(configDir2, "projects");
27099
+ const projectsRoot = join39(configDir2, "projects");
26860
27100
  const records = [];
26861
27101
  for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
26862
27102
  if (isSubagent || archived) continue;
@@ -27370,6 +27610,13 @@ app62.route("/api/webchat", createWebchatRoutes({
27370
27610
  app62.route("/api/webchat/greeting", webchat_greeting_default);
27371
27611
  app62.route("/api/telegram", telegram_default);
27372
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
+ );
27373
27620
  app62.route("/api/onboarding", onboarding_default);
27374
27621
  app62.route("/api/admin", admin_default);
27375
27622
  app62.route("/api/access", access_default);
@@ -27408,14 +27655,14 @@ app62.get("/agent-assets/:slug/:filename", (c) => {
27408
27655
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
27409
27656
  return c.text("Forbidden", 403);
27410
27657
  }
27411
- if (!existsSync36(filePath)) {
27658
+ if (!existsSync37(filePath)) {
27412
27659
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
27413
27660
  return c.text("Not found", 404);
27414
27661
  }
27415
27662
  const ext = "." + filename.split(".").pop()?.toLowerCase();
27416
27663
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
27417
27664
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
27418
- const body = readFileSync38(filePath);
27665
+ const body = readFileSync39(filePath);
27419
27666
  return c.body(body, 200, {
27420
27667
  "Content-Type": contentType,
27421
27668
  "Cache-Control": "public, max-age=3600"
@@ -27438,14 +27685,14 @@ app62.get("/generated/:filename", (c) => {
27438
27685
  console.error(`[generated] serve file=${filename} status=403`);
27439
27686
  return c.text("Forbidden", 403);
27440
27687
  }
27441
- if (!existsSync36(filePath)) {
27688
+ if (!existsSync37(filePath)) {
27442
27689
  console.error(`[generated] serve file=${filename} status=404`);
27443
27690
  return c.text("Not found", 404);
27444
27691
  }
27445
27692
  const ext = "." + filename.split(".").pop()?.toLowerCase();
27446
27693
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
27447
27694
  console.log(`[generated] serve file=${filename} status=200`);
27448
- const body = readFileSync38(filePath);
27695
+ const body = readFileSync39(filePath);
27449
27696
  return c.body(body, 200, {
27450
27697
  "Content-Type": contentType,
27451
27698
  "Cache-Control": "public, max-age=86400"
@@ -27458,9 +27705,9 @@ app62.route("/v", visitor_consent_default);
27458
27705
  var htmlCache = /* @__PURE__ */ new Map();
27459
27706
  var brandLogoPath = "/brand/maxy-monochrome.png";
27460
27707
  var brandIconPath = "/brand/maxy-monochrome.png";
27461
- if (BRAND_JSON_PATH && existsSync36(BRAND_JSON_PATH)) {
27708
+ if (BRAND_JSON_PATH && existsSync37(BRAND_JSON_PATH)) {
27462
27709
  try {
27463
- const fullBrand = JSON.parse(readFileSync38(BRAND_JSON_PATH, "utf-8"));
27710
+ const fullBrand = JSON.parse(readFileSync39(BRAND_JSON_PATH, "utf-8"));
27464
27711
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
27465
27712
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
27466
27713
  } catch {
@@ -27487,11 +27734,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
27487
27734
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
27488
27735
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
27489
27736
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
27490
- (p) => existsSync36(resolve36(process.cwd(), "public", p.replace(/^\//, "")))
27737
+ (p) => existsSync37(resolve36(process.cwd(), "public", p.replace(/^\//, "")))
27491
27738
  );
27492
27739
  var SW_SOURCE = (() => {
27493
27740
  try {
27494
- return readFileSync38(resolve36(process.cwd(), "public", "sw.js"), "utf-8");
27741
+ return readFileSync39(resolve36(process.cwd(), "public", "sw.js"), "utf-8");
27495
27742
  } catch {
27496
27743
  return null;
27497
27744
  }
@@ -27499,9 +27746,9 @@ var SW_SOURCE = (() => {
27499
27746
  function readInstalledVersion() {
27500
27747
  try {
27501
27748
  if (!PLATFORM_ROOT8) return "unknown";
27502
- const versionFile = join38(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
27503
- if (!existsSync36(versionFile)) return "unknown";
27504
- 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();
27505
27752
  return content || "unknown";
27506
27753
  } catch {
27507
27754
  return "unknown";
@@ -27542,7 +27789,7 @@ var clientErrorReporterScript = `<script>
27542
27789
  function cachedHtml(file) {
27543
27790
  let html = htmlCache.get(file);
27544
27791
  if (!html) {
27545
- html = readFileSync38(resolve36(process.cwd(), "public", file), "utf-8");
27792
+ html = readFileSync39(resolve36(process.cwd(), "public", file), "utf-8");
27546
27793
  const productNameEsc = escapeHtml(BRAND.productName);
27547
27794
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
27548
27795
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -27559,13 +27806,13 @@ ${clientErrorReporterScript}
27559
27806
  return html;
27560
27807
  }
27561
27808
  function loadBrandingCache(agentSlug) {
27562
- const configDir2 = join38(homedir4(), BRAND.configDir);
27809
+ const configDir2 = join39(homedir4(), BRAND.configDir);
27563
27810
  try {
27564
27811
  const accountId = getDefaultAccountId();
27565
27812
  if (!accountId) return null;
27566
- const cachePath = join38(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
27567
- if (!existsSync36(cachePath)) return null;
27568
- 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"));
27569
27816
  } catch {
27570
27817
  return null;
27571
27818
  }
@@ -27660,7 +27907,7 @@ app62.use("/vnc-popout.html", logViewerFetch);
27660
27907
  app62.get("/vnc-popout.html", (c) => {
27661
27908
  let html = htmlCache.get("vnc-popout.html");
27662
27909
  if (!html) {
27663
- html = readFileSync38(resolve36(process.cwd(), "public", "vnc-popout.html"), "utf-8");
27910
+ html = readFileSync39(resolve36(process.cwd(), "public", "vnc-popout.html"), "utf-8");
27664
27911
  const name = escapeHtml(BRAND.productName);
27665
27912
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
27666
27913
  html = html.replace("</head>", ` ${brandScript}
@@ -27792,11 +28039,11 @@ var hostname = process.env.HOSTNAME ?? "127.0.0.1";
27792
28039
  var httpServer = serve({ fetch: app62.fetch, port, hostname });
27793
28040
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27794
28041
  {
27795
- const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28042
+ const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27796
28043
  const reconcileScript = resolve36(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
27797
28044
  const RECONCILE_INTERVAL_MS = 12e4;
27798
28045
  const runReconcile = () => {
27799
- if (!existsSync36(reconcileScript)) return;
28046
+ if (!existsSync37(reconcileScript)) return;
27800
28047
  try {
27801
28048
  const child = spawn3(process.execPath, [reconcileScript], {
27802
28049
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -27814,11 +28061,11 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27814
28061
  loop.unref();
27815
28062
  }
27816
28063
  {
27817
- const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28064
+ const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27818
28065
  const outlookScript = resolve36(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
27819
28066
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
27820
28067
  const runOutlookComplete = () => {
27821
- if (!existsSync36(outlookScript)) return;
28068
+ if (!existsSync37(outlookScript)) return;
27822
28069
  try {
27823
28070
  const child = spawn3(process.execPath, [outlookScript], {
27824
28071
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -27836,19 +28083,19 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27836
28083
  outlookLoop.unref();
27837
28084
  }
27838
28085
  {
27839
- const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28086
+ const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27840
28087
  const strandedAccountsDir = resolve36(auditRoot, "..", "data/accounts");
27841
28088
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
27842
28089
  const STRANDED_AGE_MS = 16 * 6e4;
27843
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;
27844
28091
  const runStrandedAudit = () => {
27845
28092
  try {
27846
- if (!existsSync36(strandedAccountsDir)) return;
28093
+ if (!existsSync37(strandedAccountsDir)) return;
27847
28094
  const now = Date.now();
27848
- for (const name of readdirSync21(strandedAccountsDir)) {
28095
+ for (const name of readdirSync22(strandedAccountsDir)) {
27849
28096
  if (!STRANDED_UUID_RE.test(name)) continue;
27850
28097
  const pendingPath2 = resolve36(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
27851
- if (!existsSync36(pendingPath2)) continue;
28098
+ if (!existsSync37(pendingPath2)) continue;
27852
28099
  const ageMs = now - statSync14(pendingPath2).mtimeMs;
27853
28100
  if (ageMs > STRANDED_AGE_MS) {
27854
28101
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs / 1e3)}`);
@@ -27864,7 +28111,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27864
28111
  strandedLoop.unref();
27865
28112
  }
27866
28113
  {
27867
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28114
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27868
28115
  const STORAGE_AUDIT_INTERVAL_MS = 3e5;
27869
28116
  const runStorageAuditSafe = () => {
27870
28117
  runStorageAudit(auditPlatformRoot).catch(
@@ -27886,7 +28133,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27886
28133
  pagesAuditLoop.unref();
27887
28134
  }
27888
28135
  {
27889
- const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28136
+ const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27890
28137
  const publishScript = resolve36(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
27891
28138
  const PUBLISH_INTERVAL_MS = 3e5;
27892
28139
  const currentAccount = () => {
@@ -27898,7 +28145,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27898
28145
  }
27899
28146
  };
27900
28147
  const spawnPublish = (account) => {
27901
- if (!existsSync36(publishScript)) return;
28148
+ if (!existsSync37(publishScript)) return;
27902
28149
  try {
27903
28150
  const child = spawn3(process.execPath, [publishScript], {
27904
28151
  env: {
@@ -27919,8 +28166,8 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27919
28166
  const availPath = resolve36(account.accountDir, "calendar-availability.json");
27920
28167
  let hasBookingSite = false;
27921
28168
  try {
27922
- if (existsSync36(availPath)) {
27923
- const cfg = JSON.parse(readFileSync38(availPath, "utf-8"));
28169
+ if (existsSync37(availPath)) {
28170
+ const cfg = JSON.parse(readFileSync39(availPath, "utf-8"));
27924
28171
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
27925
28172
  }
27926
28173
  } catch {
@@ -27928,9 +28175,9 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27928
28175
  if (!hasBookingSite) return;
27929
28176
  const statePath = resolve36(account.accountDir, "state", "booking-availability", "last-publish.json");
27930
28177
  let lastSuccessAt = null;
27931
- if (existsSync36(statePath)) {
28178
+ if (existsSync37(statePath)) {
27932
28179
  try {
27933
- const rec = JSON.parse(readFileSync38(statePath, "utf-8"));
28180
+ const rec = JSON.parse(readFileSync39(statePath, "utf-8"));
27934
28181
  lastSuccessAt = rec.lastSuccessAt ?? null;
27935
28182
  } catch {
27936
28183
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
@@ -27954,12 +28201,12 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
27954
28201
  }
27955
28202
  startTimeEntryCensus(() => getSession());
27956
28203
  {
27957
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..");
28204
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..");
27958
28205
  const auditScript = resolve36(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
27959
28206
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
27960
28207
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
27961
28208
  const runConnectorAudit = () => {
27962
- if (!existsSync36(auditScript)) return;
28209
+ if (!existsSync37(auditScript)) return;
27963
28210
  try {
27964
28211
  const child = spawn3(process.execPath, [auditScript], {
27965
28212
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -28070,11 +28317,11 @@ try {
28070
28317
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
28071
28318
  async function runAdminUserReconcileTick() {
28072
28319
  try {
28073
- if (!existsSync36(USERS_FILE)) {
28320
+ if (!existsSync37(USERS_FILE)) {
28074
28321
  console.error("[adminuser-self-heal] skip reason=no-users-file");
28075
28322
  return;
28076
28323
  }
28077
- const usersRaw = readFileSync38(USERS_FILE, "utf-8").trim();
28324
+ const usersRaw = readFileSync39(USERS_FILE, "utf-8").trim();
28078
28325
  if (!usersRaw) {
28079
28326
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
28080
28327
  return;
@@ -28103,8 +28350,8 @@ var adminUserReconcileTimer = setInterval(() => {
28103
28350
  if (typeof adminUserReconcileTimer.unref === "function") adminUserReconcileTimer.unref();
28104
28351
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
28105
28352
  function countUsersRows() {
28106
- if (!existsSync36(USERS_FILE)) return 0;
28107
- const raw = readFileSync38(USERS_FILE, "utf-8").trim();
28353
+ if (!existsSync37(USERS_FILE)) return 0;
28354
+ const raw = readFileSync39(USERS_FILE, "utf-8").trim();
28108
28355
  if (!raw) return 0;
28109
28356
  const users = JSON.parse(raw);
28110
28357
  return users.filter((u) => typeof u.userId === "string").length;
@@ -28224,7 +28471,7 @@ if (bootAccountConfig?.whatsapp) {
28224
28471
  }
28225
28472
  init({
28226
28473
  configDir: configDirForWhatsApp,
28227
- platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join38(__dirname, "..")),
28474
+ platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join39(__dirname, "..")),
28228
28475
  accountConfig: bootAccountConfig,
28229
28476
  onMessage: async (msg) => {
28230
28477
  if (msg.isOwnerMirror) {