@rubytech/create-realagent-code 0.1.613 → 0.1.614

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts +34 -0
  3. package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/agent-dispatch-rule/dist/index.js +39 -0
  5. package/payload/platform/lib/agent-dispatch-rule/dist/index.js.map +1 -1
  6. package/payload/platform/lib/agent-dispatch-rule/src/__tests__/carrier-verdict.test.ts +92 -0
  7. package/payload/platform/lib/agent-dispatch-rule/src/index.ts +59 -0
  8. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +46 -1
  9. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
  10. package/payload/platform/plugins/docs/references/telegram-guide.md +45 -0
  11. package/payload/platform/plugins/scheduling/mcp/dist/index.js +2 -0
  12. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  13. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch-carrier.test.d.ts +2 -0
  14. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch-carrier.test.d.ts.map +1 -0
  15. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch-carrier.test.js +72 -0
  16. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch-carrier.test.js.map +1 -0
  17. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery-reconcile.test.d.ts +2 -0
  18. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery-reconcile.test.d.ts.map +1 -0
  19. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery-reconcile.test.js +327 -0
  20. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery-reconcile.test.js.map +1 -0
  21. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery.test.d.ts +2 -0
  22. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery.test.d.ts.map +1 -0
  23. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery.test.js +130 -0
  24. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery.test.js.map +1 -0
  25. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js +27 -58
  26. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js.map +1 -1
  27. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.d.ts +8 -3
  28. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.d.ts.map +1 -1
  29. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.js +37 -3
  30. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.js.map +1 -1
  31. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-delivery.d.ts +67 -0
  32. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-delivery.d.ts.map +1 -0
  33. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-delivery.js +133 -0
  34. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-delivery.js.map +1 -0
  35. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts +67 -12
  36. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts.map +1 -1
  37. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js +226 -72
  38. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js.map +1 -1
  39. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +66 -4
  40. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
  41. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/reconcile-run-controls.test.d.ts +2 -0
  42. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/reconcile-run-controls.test.d.ts.map +1 -0
  43. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/reconcile-run-controls.test.js +45 -0
  44. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/reconcile-run-controls.test.js.map +1 -0
  45. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +3 -1
  46. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  47. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +32 -7
  48. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  49. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +12 -1
  50. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  51. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +15 -2
  52. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  53. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +14 -0
  54. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
  55. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +4 -0
  56. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
  57. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts +3 -0
  58. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts.map +1 -1
  59. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js +2 -0
  60. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js.map +1 -1
  61. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
  62. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +14 -0
  63. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
  64. package/payload/server/public/operator.html +1 -1
  65. package/payload/server/server.js +663 -620
@@ -3220,10 +3220,10 @@ var require_dist10 = __commonJS({
3220
3220
  });
3221
3221
 
3222
3222
  // server/index.ts
3223
- import { readFileSync as readFileSync63, existsSync as existsSync63, watchFile, readdirSync as readdirSync37, statSync as statSync33 } from "fs";
3223
+ import { readFileSync as readFileSync64, existsSync as existsSync63, watchFile, readdirSync as readdirSync38, statSync as statSync34 } from "fs";
3224
3224
  import { spawn as spawn3 } from "child_process";
3225
3225
  import { createHash as createHash8 } from "crypto";
3226
- import { resolve as resolve55, join as join77, basename as basename19 } from "path";
3226
+ import { resolve as resolve55, join as join78, basename as basename19 } from "path";
3227
3227
  import { homedir as homedir5 } from "os";
3228
3228
 
3229
3229
  // server/lib/route-cache-watchers.ts
@@ -7196,17 +7196,17 @@ async function computeSessionList(scopeAccountId) {
7196
7196
  if (adminUserId && role === ADMIN_ROLE && sidecarChannel === WEBCHAT_CHANNEL) {
7197
7197
  adminUserIdBySession.set(sessionId, adminUserId);
7198
7198
  }
7199
- const tail = await lastAssistantModelFromTail(path, size);
7200
- if (tail.failure) {
7199
+ const tail2 = await lastAssistantModelFromTail(path, size);
7200
+ if (tail2.failure) {
7201
7201
  tailReadFails += 1;
7202
7202
  console.error(
7203
- `[admin-sessions-list] op=tail-read-failed sessionId=${sessionId.slice(0, 8)} reason=${tail.failure}`
7203
+ `[admin-sessions-list] op=tail-read-failed sessionId=${sessionId.slice(0, 8)} reason=${tail2.failure}`
7204
7204
  );
7205
7205
  } else {
7206
- if (tail.bytesRead > 0) tailReads += 1;
7207
- if (tail.model === null) tailModelMiss += 1;
7206
+ if (tail2.bytesRead > 0) tailReads += 1;
7207
+ if (tail2.model === null) tailModelMiss += 1;
7208
7208
  }
7209
- tailBytes += tail.bytesRead;
7209
+ tailBytes += tail2.bytesRead;
7210
7210
  rows.push({
7211
7211
  sessionId,
7212
7212
  title: resolved.title,
@@ -7225,7 +7225,7 @@ async function computeSessionList(scopeAccountId) {
7225
7225
  // diverge from the sidecar (e.g. an ai-titled channel row).
7226
7226
  channel: sidecarChannel,
7227
7227
  personName: null,
7228
- model: tail.model,
7228
+ model: tail2.model,
7229
7229
  accountId: rowAccountId,
7230
7230
  senderId,
7231
7231
  whatsappName: null
@@ -7445,33 +7445,53 @@ function createScheduleInjectRoutes(deps) {
7445
7445
  console.error(`${TAG6} op=inject-spawn eventId=${eventId} sessionId=${sessionId2} result=ok status=-`);
7446
7446
  return c.json({ ok: true, sessionKey: sessionId2, ...transcriptBoundary(sessionId2) }, 200);
7447
7447
  }
7448
- const resolution = deps.telegramAccountForDestination(destination);
7449
- if (resolution.kind === "none") {
7450
- console.error(`${TAG6} op=schedule-telegram-reject eventId=${eventId} destination=${destination} reason=unresolved-effective-account`);
7451
- return c.json({ ok: false, error: "unresolved-effective-account" }, 403);
7452
- }
7448
+ const namedBotId = typeof body.botId === "string" && body.botId.length > 0 ? body.botId : null;
7453
7449
  let claimant;
7454
- if (resolution.kind === "one") {
7455
- claimant = resolution;
7456
- } else {
7457
- const mine = resolution.claimants.filter((c2) => c2.accountId === eventAccountId);
7458
- if (mine.length === 0) {
7450
+ let carrierSource;
7451
+ let claimantCount = 0;
7452
+ if (namedBotId !== null && eventAccountId !== null) {
7453
+ carrierSource = "named";
7454
+ const carrier = deps.carrierFor(eventAccountId, namedBotId, destination);
7455
+ if ("error" in carrier) {
7459
7456
  console.error(
7460
- `${TAG6} op=event-account-scope-mismatch eventId=${eventId} eventAccount=${eventAccountId ?? "-"} effectiveAccount=none claimants=${resolution.claimants.length} destination=${destination} dispatched=no`
7457
+ `${TAG6} op=carrier-unavailable eventId=${eventId} botId=${namedBotId} reason=${carrier.error}`
7461
7458
  );
7462
- return c.json({ ok: false, error: "event-account-scope-mismatch" }, 403);
7459
+ return c.json({ ok: false, error: "carrier-unavailable" }, 403);
7463
7460
  }
7464
- if (mine.length > 1) {
7461
+ claimant = carrier;
7462
+ } else {
7463
+ carrierSource = "resolved";
7464
+ const resolution = deps.telegramAccountForDestination(destination);
7465
+ if (resolution.kind === "none") {
7466
+ console.error(`${TAG6} op=schedule-telegram-reject eventId=${eventId} destination=${destination} reason=unresolved-effective-account`);
7467
+ return c.json({ ok: false, error: "unresolved-effective-account" }, 403);
7468
+ }
7469
+ claimantCount = resolution.kind === "ambiguous" ? resolution.claimants.length : 1;
7470
+ if (resolution.kind === "one") {
7471
+ claimant = resolution;
7472
+ } else {
7473
+ const mine = resolution.claimants.filter((c2) => c2.accountId === eventAccountId);
7474
+ if (mine.length === 0) {
7475
+ console.error(
7476
+ `${TAG6} op=event-account-scope-mismatch eventId=${eventId} eventAccount=${eventAccountId ?? "-"} effectiveAccount=none claimants=${resolution.claimants.length} destination=${destination} dispatched=no`
7477
+ );
7478
+ return c.json({ ok: false, error: "event-account-scope-mismatch" }, 403);
7479
+ }
7480
+ if (mine.length > 1) {
7481
+ console.error(
7482
+ `${TAG6} op=telegram-destination-ambiguous eventId=${eventId} destination=${destination} accounts=${mine.length} scope=within-account dispatched=no`
7483
+ );
7484
+ return c.json({ ok: false, error: "telegram-destination-ambiguous" }, 403);
7485
+ }
7486
+ claimant = mine[0];
7465
7487
  console.error(
7466
- `${TAG6} op=telegram-destination-ambiguous eventId=${eventId} destination=${destination} accounts=${mine.length} scope=within-account dispatched=no`
7488
+ `${TAG6} op=telegram-destination-narrowed eventId=${eventId} destination=${destination} claimants=${resolution.claimants.length} account=${claimant.accountId} botId=${claimant.botId}`
7467
7489
  );
7468
- return c.json({ ok: false, error: "telegram-destination-ambiguous" }, 403);
7469
7490
  }
7470
- claimant = mine[0];
7471
- console.error(
7472
- `${TAG6} op=telegram-destination-narrowed eventId=${eventId} destination=${destination} claimants=${resolution.claimants.length} account=${claimant.accountId} botId=${claimant.botId}`
7473
- );
7474
7491
  }
7492
+ console.error(
7493
+ `${TAG6} op=carrier eventId=${eventId} botId=${claimant.botId} source=${carrierSource} claimants=${claimantCount}`
7494
+ );
7475
7495
  const { accountId: effectiveAccount, botId, botToken } = claimant;
7476
7496
  console.error(`${TAG6} op=effective-account eventId=${eventId} effectiveAccount=${effectiveAccount} botId=${botId}`);
7477
7497
  if (eventAccountId === null || eventAccountId !== effectiveAccount) {
@@ -8270,8 +8290,8 @@ function auditGroupOutbound() {
8270
8290
  }
8271
8291
  function auditGroupOutboundNote() {
8272
8292
  const a = auditGroupOutbound();
8273
- const tail = a.agent > 0 ? ` offenders=${a.offenders.join(",")}` : "";
8274
- const note = `convos=${a.convos} outbound=${a.outbound} operator=${a.operator} agent=${a.agent} unstamped=${a.unstamped}${tail}`;
8293
+ const tail2 = a.agent > 0 ? ` offenders=${a.offenders.join(",")}` : "";
8294
+ const note = `convos=${a.convos} outbound=${a.outbound} operator=${a.operator} agent=${a.agent} unstamped=${a.unstamped}${tail2}`;
8275
8295
  console.log(`${TAG13} op=group-outbound-audit ${note}`);
8276
8296
  return note;
8277
8297
  }
@@ -9302,10 +9322,10 @@ function resolveKey(accountId, ctx) {
9302
9322
  function setAccountPolicy(accountDir, accountId, policy, ctx) {
9303
9323
  const id = accountId.trim();
9304
9324
  if (!id) return { ok: false, reason: "missing-account-id", error: "Missing account id." };
9305
- const fields = ["dmPolicy", "adminPhones", "allowFrom"].filter(
9325
+ const fields2 = ["dmPolicy", "adminPhones", "allowFrom"].filter(
9306
9326
  (f) => policy[f] !== void 0
9307
9327
  );
9308
- if (fields.length === 0) {
9328
+ if (fields2.length === 0) {
9309
9329
  return {
9310
9330
  ok: false,
9311
9331
  reason: "empty-policy",
@@ -9327,7 +9347,7 @@ function setAccountPolicy(accountDir, accountId, policy, ctx) {
9327
9347
  const accounts = wa.accounts;
9328
9348
  if (!accounts[key2] || typeof accounts[key2] !== "object") accounts[key2] = { name: "Main" };
9329
9349
  const slice = accounts[key2];
9330
- for (const field2 of fields) slice[field2] = policy[field2];
9350
+ for (const field2 of fields2) slice[field2] = policy[field2];
9331
9351
  const parsed = WhatsAppConfigSchema.safeParse(wa);
9332
9352
  if (!parsed.success) {
9333
9353
  const msg = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
@@ -9337,7 +9357,7 @@ function setAccountPolicy(accountDir, accountId, policy, ctx) {
9337
9357
  config.whatsapp = parsed.data;
9338
9358
  writeConfig(accountDir, config);
9339
9359
  console.error(
9340
- `${TAG15} op=set-account-policy account=${id} key=${key2} keyKind=${verdict.kind} fields=[${fields.join(",")}] ok=true`
9360
+ `${TAG15} op=set-account-policy account=${id} key=${key2} keyKind=${verdict.kind} fields=[${fields2.join(",")}] ok=true`
9341
9361
  );
9342
9362
  reloadManagerConfig(accountDir);
9343
9363
  return { ok: true, key: key2 };
@@ -9599,8 +9619,8 @@ function resolvePublicAgentEnabled(accountDir, opts) {
9599
9619
  return { enabled: false, source: "default" };
9600
9620
  }
9601
9621
  }
9602
- function updateConfig(accountDir, fields) {
9603
- const fieldNames = Object.keys(fields);
9622
+ function updateConfig(accountDir, fields2) {
9623
+ const fieldNames = Object.keys(fields2);
9604
9624
  if (fieldNames.length === 0) {
9605
9625
  return { ok: false, error: "No fields provided to update." };
9606
9626
  }
@@ -9610,7 +9630,7 @@ function updateConfig(accountDir, fields) {
9610
9630
  config.whatsapp = {};
9611
9631
  }
9612
9632
  const wa = config.whatsapp;
9613
- for (const [key2, value] of Object.entries(fields)) {
9633
+ for (const [key2, value] of Object.entries(fields2)) {
9614
9634
  wa[key2] = value;
9615
9635
  }
9616
9636
  const parsed = WhatsAppConfigSchema.safeParse(wa);
@@ -10320,12 +10340,12 @@ function unwrapToShape(schema) {
10320
10340
  }
10321
10341
  function extractFields(schema) {
10322
10342
  const shape = unwrapToShape(schema);
10323
- const fields = [];
10343
+ const fields2 = [];
10324
10344
  for (const [name, fieldSchema] of Object.entries(shape)) {
10325
10345
  const def = fieldSchema?._def;
10326
10346
  const resolved = resolveZodType(def);
10327
10347
  const description = extractDescription(fieldSchema, def);
10328
- fields.push({
10348
+ fields2.push({
10329
10349
  name,
10330
10350
  type: resolved.type,
10331
10351
  required: resolved.required,
@@ -10333,14 +10353,14 @@ function extractFields(schema) {
10333
10353
  ...description !== void 0 ? { description } : {}
10334
10354
  });
10335
10355
  }
10336
- return fields;
10356
+ return fields2;
10337
10357
  }
10338
10358
  function escapeTableCell(text) {
10339
10359
  return text.replace(/\|/g, "\\|");
10340
10360
  }
10341
- function formatFieldTable(title, fields) {
10361
+ function formatFieldTable(title, fields2) {
10342
10362
  const lines = [`## ${title}`, "", "| Field | Type | Required | Default | Description |", "|-------|------|----------|---------|-------------|"];
10343
- for (const f of fields) {
10363
+ for (const f of fields2) {
10344
10364
  const desc = f.description ? escapeTableCell(f.description) : "\u2014";
10345
10365
  lines.push(`| ${f.name} | ${f.type} | ${f.required ? "yes" : "no"} | ${f.default ?? "\u2014"} | ${desc} |`);
10346
10366
  }
@@ -10497,12 +10517,12 @@ function houseSocketScopeDenial(c, op) {
10497
10517
  }
10498
10518
  function selfOrHouseScopeDenial(c, targetAccountId, op, targetSource = "explicit") {
10499
10519
  const { decision, callerAccountId, houseAdminScope } = evaluateCallerScope(c, targetAccountId);
10500
- const tail = `target=${targetAccountId} targetSource=${targetSource} caller=${callerAccountId ?? "none"} houseAdmin=${houseAdminScope ? "y" : "n"}`;
10520
+ const tail2 = `target=${targetAccountId} targetSource=${targetSource} caller=${callerAccountId ?? "none"} houseAdmin=${houseAdminScope ? "y" : "n"}`;
10501
10521
  if (decision.authorized) {
10502
- console.error(`${TAG20} op=authz-ok route=${op} ${tail}`);
10522
+ console.error(`${TAG20} op=authz-ok route=${op} ${tail2}`);
10503
10523
  return null;
10504
10524
  }
10505
- console.error(`${TAG20} op=authz-deny route=${op} ${tail}`);
10525
+ console.error(`${TAG20} op=authz-deny route=${op} ${tail2}`);
10506
10526
  return c.json({ ok: false, error: "Not authorized. This session may only pair or manage its own account." }, 403);
10507
10527
  }
10508
10528
  function bindingScopeDenial(c, targetAccountId, op) {
@@ -10776,7 +10796,7 @@ app3.post("/reconnect", async (c) => {
10776
10796
  app3.post("/config", async (c) => {
10777
10797
  try {
10778
10798
  const body = await c.req.json().catch(() => ({}));
10779
- const { action, phone, slug, fields, accountId, managesAccount, mode, policy, party, account: partyAccount, enabled } = body;
10799
+ const { action, phone, slug, fields: fields2, accountId, managesAccount, mode, policy, party, account: partyAccount, enabled } = body;
10780
10800
  if (!action || typeof action !== "string") {
10781
10801
  return c.json({ ok: false, error: 'Missing required field "action".' }, 400);
10782
10802
  }
@@ -11040,11 +11060,11 @@ app3.post("/config", async (c) => {
11040
11060
  }
11041
11061
  }
11042
11062
  case "update-config": {
11043
- if (!fields || typeof fields !== "object" || Array.isArray(fields)) {
11063
+ if (!fields2 || typeof fields2 !== "object" || Array.isArray(fields2)) {
11044
11064
  return c.json({ ok: false, error: 'Missing required field "fields" (object with config field names and values).' }, 400);
11045
11065
  }
11046
- const result = updateConfig(account.accountDir, fields);
11047
- const fieldNames = Object.keys(fields);
11066
+ const result = updateConfig(account.accountDir, fields2);
11067
+ const fieldNames = Object.keys(fields2);
11048
11068
  console.error(`${TAG20} config action=update-config fields=[${fieldNames.join(",")}] ok=${result.ok}`);
11049
11069
  return c.json(result, result.ok ? 200 : 400);
11050
11070
  }
@@ -14194,13 +14214,13 @@ async function pullVisitStatusForAccount(opts) {
14194
14214
  log2(
14195
14215
  `${TAG24} op=merged account=${accountId} id=${row.id} labour=${row.dayHundredths > 0} forWorker=${row.forOwnerId !== ""}`
14196
14216
  );
14197
- const fields = ["status"];
14198
- if (row.workDate !== "") fields.push("workDate");
14199
- if (row.workNote !== "") fields.push("workNote");
14200
- if (row.assignedOwnerId !== "") fields.push("assignedOwnerId");
14201
- if (row.startDate !== "") fields.push("startDate");
14202
- if (row.forOwnerId !== "") fields.push("forOwnerId");
14203
- for (const field2 of fields) {
14217
+ const fields2 = ["status"];
14218
+ if (row.workDate !== "") fields2.push("workDate");
14219
+ if (row.workNote !== "") fields2.push("workNote");
14220
+ if (row.assignedOwnerId !== "") fields2.push("assignedOwnerId");
14221
+ if (row.startDate !== "") fields2.push("startDate");
14222
+ if (row.forOwnerId !== "") fields2.push("forOwnerId");
14223
+ for (const field2 of fields2) {
14204
14224
  log2(`${TAG24} op=applied visitId=${row.visitId} field=${field2}`);
14205
14225
  }
14206
14226
  } catch (err) {
@@ -16298,10 +16318,97 @@ function runTelegramStoreCensus() {
16298
16318
  return c;
16299
16319
  }
16300
16320
 
16321
+ // app/lib/telegram/card-row-census.ts
16322
+ import { closeSync as closeSync6, openSync as openSync6, readdirSync as readdirSync15, readFileSync as readFileSync24, readSync as readSync6, statSync as statSync15 } from "fs";
16323
+ import { join as join30 } from "path";
16324
+ var CARD_ROW_CENSUS_TAG = "[telegram-card-row-census]";
16325
+ var CARD_ROW_WINDOW_MS = 60 * 60 * 1e3;
16326
+ var MAX_BYTES_PER_FILE = 4e6;
16327
+ function tail(path, size) {
16328
+ if (size <= MAX_BYTES_PER_FILE) return readFileSync24(path, "utf-8");
16329
+ const buf = Buffer.alloc(MAX_BYTES_PER_FILE);
16330
+ const fd = openSync6(path, "r");
16331
+ try {
16332
+ const read = readSync6(fd, buf, 0, MAX_BYTES_PER_FILE, size - MAX_BYTES_PER_FILE);
16333
+ const text = buf.subarray(0, read).toString("utf-8");
16334
+ const nl = text.indexOf("\n");
16335
+ return nl === -1 ? "" : text.slice(nl + 1);
16336
+ } finally {
16337
+ closeSync6(fd);
16338
+ }
16339
+ }
16340
+ function fields(line) {
16341
+ const out = {};
16342
+ for (const part of line.split(" ")) {
16343
+ const i = part.indexOf("=");
16344
+ if (i > 0) out[part.slice(0, i)] = part.slice(i + 1);
16345
+ }
16346
+ return out;
16347
+ }
16348
+ function parseCardSends(lines) {
16349
+ const out = [];
16350
+ for (const line of lines) {
16351
+ if (!line.startsWith("[telegram-tools] op=card-sent ")) continue;
16352
+ const f = fields(line);
16353
+ if (f.outcome !== "sent") continue;
16354
+ if (!f.accountId || !f.key || !f.messageId) continue;
16355
+ const atMs = Date.parse(f.at ?? "");
16356
+ if (!Number.isFinite(atMs)) continue;
16357
+ out.push({ accountId: f.accountId, channelKey: f.key, messageId: f.messageId, atMs });
16358
+ }
16359
+ return out;
16360
+ }
16361
+ function rowExists(send) {
16362
+ const rowId = `telegram:${send.accountId}:${send.channelKey}:card:${send.messageId}`;
16363
+ for (const row of readRows(send.accountId, send.channelKey)) {
16364
+ if (isUpdateRecord(row)) continue;
16365
+ if (row.messageId === rowId) return true;
16366
+ }
16367
+ return false;
16368
+ }
16369
+ function collectCardRowCensus(input) {
16370
+ const floor = input.nowMs - CARD_ROW_WINDOW_MS;
16371
+ const sends = /* @__PURE__ */ new Map();
16372
+ try {
16373
+ if (input.logDir) {
16374
+ for (const name of readdirSync15(input.logDir)) {
16375
+ if (!name.startsWith("mcp-") || !name.endsWith(".log")) continue;
16376
+ const path = join30(input.logDir, name);
16377
+ let text;
16378
+ try {
16379
+ text = tail(path, statSync15(path).size);
16380
+ } catch {
16381
+ continue;
16382
+ }
16383
+ for (const send of parseCardSends(text.split("\n"))) {
16384
+ if (send.atMs < floor || send.atMs > input.nowMs) continue;
16385
+ sends.set(`${send.accountId}:${send.channelKey}:${send.messageId}`, send);
16386
+ }
16387
+ }
16388
+ }
16389
+ } catch {
16390
+ }
16391
+ let rows = 0;
16392
+ const missingIds = [];
16393
+ for (const send of sends.values()) {
16394
+ if (rowExists(send)) rows += 1;
16395
+ else missingIds.push(send.messageId);
16396
+ }
16397
+ return { sent: sends.size, rows, missing: missingIds.length, missingIds };
16398
+ }
16399
+ function cardRowCensusLine(input) {
16400
+ const c = collectCardRowCensus(input);
16401
+ const head = `${CARD_ROW_CENSUS_TAG} sent=${c.sent} rows=${c.rows} missing=${c.missing} window=60m`;
16402
+ return c.missing > 0 ? `${head} missing-ids=[${c.missingIds.join(",")}]` : head;
16403
+ }
16404
+ function runTelegramCardRowCensus(logDir, nowMs = Date.now()) {
16405
+ console.error(cardRowCensusLine({ logDir, nowMs }));
16406
+ }
16407
+
16301
16408
  // app/lib/telegram/reach-census.ts
16302
16409
  var import_dist4 = __toESM(require_dist2(), 1);
16303
16410
  import { existsSync as existsSync21 } from "fs";
16304
- import { join as join30 } from "path";
16411
+ import { join as join31 } from "path";
16305
16412
  function collectTelegramReachCensus(accounts) {
16306
16413
  const out = {
16307
16414
  accounts: accounts.length,
@@ -16311,7 +16418,7 @@ function collectTelegramReachCensus(accounts) {
16311
16418
  };
16312
16419
  for (const account of accounts) {
16313
16420
  const reach = (0, import_dist4.collectTelegramReach)({
16314
- storeDir: join30(STORE_ROOT2(), account.accountId),
16421
+ storeDir: join31(STORE_ROOT2(), account.accountId),
16315
16422
  bots: account.bots
16316
16423
  });
16317
16424
  for (const bot of reach.bots) {
@@ -16365,7 +16472,7 @@ function runTelegramCheckoutCensus(bots, now) {
16365
16472
  }
16366
16473
 
16367
16474
  // app/lib/telegram/media-census.ts
16368
- import { join as join31, resolve as resolve20 } from "path";
16475
+ import { join as join32, resolve as resolve20 } from "path";
16369
16476
  function idsByTarget(rows) {
16370
16477
  const out = /* @__PURE__ */ new Map();
16371
16478
  for (const row of rows) {
@@ -16446,8 +16553,8 @@ function readWaOperatorTurns() {
16446
16553
  }
16447
16554
 
16448
16555
  // server/routes/session-reader.ts
16449
- import { readFileSync as readFileSync24, watch as watch4, statSync as statSync15, existsSync as existsSync22, readdirSync as readdirSync15, realpathSync as realpathSync5 } from "fs";
16450
- import { isAbsolute as isAbsolute2, join as join32, relative as relative3, resolve as resolve21, sep as sep5 } from "path";
16556
+ import { readFileSync as readFileSync25, watch as watch4, statSync as statSync16, existsSync as existsSync22, readdirSync as readdirSync16, realpathSync as realpathSync5 } from "fs";
16557
+ import { isAbsolute as isAbsolute2, join as join33, relative as relative3, resolve as resolve21, sep as sep5 } from "path";
16451
16558
 
16452
16559
  // server/routes/admin/manager-client.ts
16453
16560
  var SESSION_ID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -16552,7 +16659,7 @@ function openTaskKey(turns) {
16552
16659
  }
16553
16660
  function readSubagentMeta(dir, hex) {
16554
16661
  try {
16555
- const m = JSON.parse(readFileSync24(join32(dir, `agent-${hex}.meta.json`), "utf8"));
16662
+ const m = JSON.parse(readFileSync25(join33(dir, `agent-${hex}.meta.json`), "utf8"));
16556
16663
  if (typeof m.agentType === "string" && typeof m.description === "string" && typeof m.toolUseId === "string") {
16557
16664
  return { agentType: m.agentType, description: m.description, toolUseId: m.toolUseId };
16558
16665
  }
@@ -16575,7 +16682,7 @@ function runActivityTick(c) {
16575
16682
  c.parentGrewThisTick = false;
16576
16683
  let names = [];
16577
16684
  try {
16578
- names = readdirSync15(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
16685
+ names = readdirSync16(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
16579
16686
  } catch {
16580
16687
  }
16581
16688
  const entries2 = [];
@@ -16584,7 +16691,7 @@ function runActivityTick(c) {
16584
16691
  let size = 0;
16585
16692
  let mtimeMs = 0;
16586
16693
  try {
16587
- const st = statSync15(join32(c.subagentsDir, name));
16694
+ const st = statSync16(join33(c.subagentsDir, name));
16588
16695
  size = st.size;
16589
16696
  mtimeMs = st.mtimeMs;
16590
16697
  } catch {
@@ -16629,11 +16736,11 @@ app7.get("/stream", requireAdminSession, (c) => {
16629
16736
  const sessionId = c.req.query("sessionId") ?? "";
16630
16737
  const projectDir = c.req.query("projectDir") ?? "";
16631
16738
  const cfg = claudeConfigDir();
16632
- const projectsRoot = cfg ? resolve21(join32(cfg, "projects")) : null;
16739
+ const projectsRoot = cfg ? resolve21(join33(cfg, "projects")) : null;
16633
16740
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
16634
16741
  return c.json({ error: "bad session reference" }, 400);
16635
16742
  }
16636
- const jsonlPath = resolve21(join32(projectDir, `${sessionId}.jsonl`));
16743
+ const jsonlPath = resolve21(join33(projectDir, `${sessionId}.jsonl`));
16637
16744
  if (!jsonlPath.startsWith(projectsRoot + sep5)) {
16638
16745
  return c.json({ error: "bad session reference" }, 400);
16639
16746
  }
@@ -16653,7 +16760,7 @@ data: ${JSON.stringify(turn)}
16653
16760
  start(controller) {
16654
16761
  const fileEnd0 = (() => {
16655
16762
  try {
16656
- return statSync15(jsonlPath).size;
16763
+ return statSync16(jsonlPath).size;
16657
16764
  } catch {
16658
16765
  return 0;
16659
16766
  }
@@ -16661,7 +16768,7 @@ data: ${JSON.stringify(turn)}
16661
16768
  let offset = resumeOffset(lastEventId, fileEnd0);
16662
16769
  console.log(`[wa-stream] op=open conn=${connId} sessionId=${sessionId} channel=reader resume=${offset}`);
16663
16770
  const sessionKey = c.req.query("session_key") ?? "";
16664
- const subagentsDir = resolve21(join32(projectDir, sessionId, "subagents"));
16771
+ const subagentsDir = resolve21(join33(projectDir, sessionId, "subagents"));
16665
16772
  console.log(
16666
16773
  `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync22(subagentsDir)}`
16667
16774
  );
@@ -16814,11 +16921,11 @@ app7.get("/backfill", requireAdminSession, (c) => {
16814
16921
  const beforeRaw = c.req.query("before") ?? "";
16815
16922
  const before = Number(beforeRaw);
16816
16923
  const cfg = claudeConfigDir();
16817
- const projectsRoot = cfg ? resolve21(join32(cfg, "projects")) : null;
16924
+ const projectsRoot = cfg ? resolve21(join33(cfg, "projects")) : null;
16818
16925
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId) || beforeRaw === "" || !Number.isFinite(before) || before < 0) {
16819
16926
  return c.json({ error: "bad session reference" }, 400);
16820
16927
  }
16821
- const jsonlPath = resolve21(join32(projectDir, `${sessionId}.jsonl`));
16928
+ const jsonlPath = resolve21(join33(projectDir, `${sessionId}.jsonl`));
16822
16929
  if (!jsonlPath.startsWith(projectsRoot + sep5)) {
16823
16930
  return c.json({ error: "bad session reference" }, 400);
16824
16931
  }
@@ -16830,7 +16937,7 @@ app7.get("/backfill", requireAdminSession, (c) => {
16830
16937
  const scratchpadRoot = sessionScratchpadRoot(projectDir, sessionId);
16831
16938
  const fileEnd = (() => {
16832
16939
  try {
16833
- return statSync15(jsonlPath).size;
16940
+ return statSync16(jsonlPath).size;
16834
16941
  } catch {
16835
16942
  return 0;
16836
16943
  }
@@ -16873,7 +16980,7 @@ app7.get("/directives", requireAdminSession, (c) => {
16873
16980
  if (!dir || !existsSync22(dir)) return c.json({ entries: [] });
16874
16981
  let names;
16875
16982
  try {
16876
- names = readdirSync15(dir).filter((n) => DIRECTIVE_NAME_RE.test(n));
16983
+ names = readdirSync16(dir).filter((n) => DIRECTIVE_NAME_RE.test(n));
16877
16984
  } catch {
16878
16985
  return c.json({ entries: [] });
16879
16986
  }
@@ -16883,7 +16990,7 @@ app7.get("/directives", requireAdminSession, (c) => {
16883
16990
  const pid = Number(pidPart);
16884
16991
  let len = 0;
16885
16992
  try {
16886
- len = statSync15(join32(dir, name)).size;
16993
+ len = statSync16(join33(dir, name)).size;
16887
16994
  } catch {
16888
16995
  }
16889
16996
  return { name, secs, pid, ts: Number.isFinite(secs) ? new Date(secs * 1e3).toISOString() : null, len };
@@ -16898,11 +17005,11 @@ app7.get("/directive", requireAdminSession, (c) => {
16898
17005
  }
16899
17006
  const dir = directiveStoreDir(sessionId);
16900
17007
  if (!dir) return c.json({ error: "no account" }, 404);
16901
- const path = resolve21(join32(dir, name));
17008
+ const path = resolve21(join33(dir, name));
16902
17009
  if (!path.startsWith(dir + sep5)) return c.json({ error: "bad reference" }, 400);
16903
17010
  let body;
16904
17011
  try {
16905
- body = readFileSync24(path, "utf8");
17012
+ body = readFileSync25(path, "utf8");
16906
17013
  } catch {
16907
17014
  return c.json({ error: "not found" }, 404);
16908
17015
  }
@@ -16911,8 +17018,8 @@ app7.get("/directive", requireAdminSession, (c) => {
16911
17018
  var session_reader_default = app7;
16912
17019
 
16913
17020
  // server/routes/operator-conversations.ts
16914
- import { readFileSync as readFileSync25 } from "fs";
16915
- import { basename as basename9, dirname as dirname9, join as join33 } from "path";
17021
+ import { readFileSync as readFileSync26 } from "fs";
17022
+ import { basename as basename9, dirname as dirname9, join as join34 } from "path";
16916
17023
 
16917
17024
  // app/lib/reader/operator-conversations.ts
16918
17025
  function operatorConvName(row) {
@@ -17000,7 +17107,7 @@ app8.get("/conversations", requireAdminSession, async (c) => {
17000
17107
  }
17001
17108
  const cfg = claudeConfigDir();
17002
17109
  if (!cfg) return c.json({ conversations: [] });
17003
- const projectsRoot = join33(cfg, "projects");
17110
+ const projectsRoot = join34(cfg, "projects");
17004
17111
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
17005
17112
  const rows = [];
17006
17113
  let sessionRowsExcludedUntagged = 0;
@@ -17018,7 +17125,7 @@ app8.get("/conversations", requireAdminSession, async (c) => {
17018
17125
  enumeratedCount += 1;
17019
17126
  const sessionId = basename9(path).replace(/\.jsonl$/, "");
17020
17127
  const projectDir = dirname9(path);
17021
- const meta = readSidecarMeta(join33(projectDir, `${sessionId}.meta.json`));
17128
+ const meta = readSidecarMeta(join34(projectDir, `${sessionId}.meta.json`));
17022
17129
  if (!isReaderChannelSession(meta.role, meta.channel)) continue;
17023
17130
  if (multiAccount) {
17024
17131
  if (meta.accountId === null) {
@@ -17030,7 +17137,7 @@ app8.get("/conversations", requireAdminSession, async (c) => {
17030
17137
  let body = "";
17031
17138
  let bodyRead = false;
17032
17139
  try {
17033
- body = readFileSync25(path, "utf8");
17140
+ body = readFileSync26(path, "utf8");
17034
17141
  bodyRead = true;
17035
17142
  bodyReadCount += 1;
17036
17143
  } catch (err) {
@@ -17206,7 +17313,7 @@ app8.get("/conversations-all", requireAdminSession, async (c) => {
17206
17313
  const { value, state } = await getOrCompute("conversations-all", houseId, async () => {
17207
17314
  const cfg = claudeConfigDir();
17208
17315
  if (!cfg) return { conversations: [] };
17209
- const projectsRoot = join33(cfg, "projects");
17316
+ const projectsRoot = join34(cfg, "projects");
17210
17317
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
17211
17318
  const validAccounts = listValidAccounts();
17212
17319
  const validIds = new Set(validAccounts.map((a) => a.accountId));
@@ -17226,7 +17333,7 @@ app8.get("/conversations-all", requireAdminSession, async (c) => {
17226
17333
  enumeratedCount += 1;
17227
17334
  const sessionId = basename9(path).replace(/\.jsonl$/, "");
17228
17335
  const projectDir = dirname9(path);
17229
- const meta = readSidecarMeta(join33(projectDir, `${sessionId}.meta.json`));
17336
+ const meta = readSidecarMeta(join34(projectDir, `${sessionId}.meta.json`));
17230
17337
  if (!isReaderChannelSession(meta.role, meta.channel)) continue;
17231
17338
  if (meta.accountId === null) {
17232
17339
  untaggedCount += 1;
@@ -17237,7 +17344,7 @@ app8.get("/conversations-all", requireAdminSession, async (c) => {
17237
17344
  let body = "";
17238
17345
  let bodyRead = false;
17239
17346
  try {
17240
- body = readFileSync25(path, "utf8");
17347
+ body = readFileSync26(path, "utf8");
17241
17348
  bodyRead = true;
17242
17349
  bodyReadCount += 1;
17243
17350
  } catch (err) {
@@ -17362,8 +17469,8 @@ app8.get("/conversations-all", requireAdminSession, async (c) => {
17362
17469
  var operator_conversations_default = app8;
17363
17470
 
17364
17471
  // server/routes/public-reader.ts
17365
- import { statSync as statSync17, watch as watch6, readFileSync as readFileSync26, readdirSync as readdirSync17 } from "fs";
17366
- import { basename as basename10, dirname as dirname10, join as join34, resolve as resolve23, sep as sep7 } from "path";
17472
+ import { statSync as statSync18, watch as watch6, readFileSync as readFileSync27, readdirSync as readdirSync18 } from "fs";
17473
+ import { basename as basename10, dirname as dirname10, join as join35, resolve as resolve23, sep as sep7 } from "path";
17367
17474
 
17368
17475
  // app/lib/reader/delivered-kinds.ts
17369
17476
  var PUBLIC_DELIVERED_KINDS = /* @__PURE__ */ new Set([
@@ -17452,10 +17559,10 @@ function enumeratePublicRows() {
17452
17559
  const cfg = claudeConfigDir();
17453
17560
  if (!cfg) return [];
17454
17561
  const rows = [];
17455
- for (const { path } of enumerateJsonls(join34(cfg, "projects"))) {
17562
+ for (const { path } of enumerateJsonls(join35(cfg, "projects"))) {
17456
17563
  const sessionId = basename10(path).replace(/\.jsonl$/, "");
17457
17564
  const projectDir = dirname10(path);
17458
- const meta = readSidecarMeta(join34(projectDir, `${sessionId}.meta.json`));
17565
+ const meta = readSidecarMeta(join35(projectDir, `${sessionId}.meta.json`));
17459
17566
  rows.push({
17460
17567
  sessionId,
17461
17568
  projectDir,
@@ -17522,15 +17629,15 @@ app9.get("/backfill", (c) => {
17522
17629
  const beforeRaw = c.req.query("before") ?? "";
17523
17630
  const before = Number(beforeRaw);
17524
17631
  const cfg = claudeConfigDir();
17525
- const projectsRoot = cfg ? resolve23(join34(cfg, "projects")) : null;
17632
+ const projectsRoot = cfg ? resolve23(join35(cfg, "projects")) : null;
17526
17633
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId) || beforeRaw === "" || !Number.isFinite(before) || before < 0) {
17527
17634
  return c.json({ error: "bad session reference" }, 400);
17528
17635
  }
17529
- const jsonlPath = resolve23(join34(projectDir, `${sessionId}.jsonl`));
17636
+ const jsonlPath = resolve23(join35(projectDir, `${sessionId}.jsonl`));
17530
17637
  if (!jsonlPath.startsWith(projectsRoot + sep7)) {
17531
17638
  return c.json({ error: "bad session reference" }, 400);
17532
17639
  }
17533
- const meta = readSidecarMeta(join34(projectDir, `${sessionId}.meta.json`));
17640
+ const meta = readSidecarMeta(join35(projectDir, `${sessionId}.meta.json`));
17534
17641
  const isPublicWebchat = meta.role === "public" && meta.channel === "webchat";
17535
17642
  const owns = visitor.kind === "person" ? meta.personId === visitor.personId : meta.personId === null && meta.visitorId === visitor.visitorId;
17536
17643
  if (!(isPublicWebchat && owns)) {
@@ -17546,7 +17653,7 @@ app9.get("/backfill", (c) => {
17546
17653
  }
17547
17654
  const fileEnd = (() => {
17548
17655
  try {
17549
- return statSync17(jsonlPath).size;
17656
+ return statSync18(jsonlPath).size;
17550
17657
  } catch {
17551
17658
  return 0;
17552
17659
  }
@@ -17589,15 +17696,15 @@ app9.get("/stream", (c) => {
17589
17696
  const sessionId = c.req.query("sessionId") ?? "";
17590
17697
  const projectDir = c.req.query("projectDir") ?? "";
17591
17698
  const cfg = claudeConfigDir();
17592
- const projectsRoot = cfg ? resolve23(join34(cfg, "projects")) : null;
17699
+ const projectsRoot = cfg ? resolve23(join35(cfg, "projects")) : null;
17593
17700
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
17594
17701
  return c.json({ error: "bad session reference" }, 400);
17595
17702
  }
17596
- const jsonlPath = resolve23(join34(projectDir, `${sessionId}.jsonl`));
17703
+ const jsonlPath = resolve23(join35(projectDir, `${sessionId}.jsonl`));
17597
17704
  if (!jsonlPath.startsWith(projectsRoot + sep7)) {
17598
17705
  return c.json({ error: "bad session reference" }, 400);
17599
17706
  }
17600
- const meta = readSidecarMeta(join34(projectDir, `${sessionId}.meta.json`));
17707
+ const meta = readSidecarMeta(join35(projectDir, `${sessionId}.meta.json`));
17601
17708
  const isPublicWebchat = meta.role === "public" && meta.channel === "webchat";
17602
17709
  const owns = visitor.kind === "person" ? meta.personId === visitor.personId : meta.personId === null && meta.visitorId === visitor.visitorId;
17603
17710
  if (!(isPublicWebchat && owns)) {
@@ -17626,7 +17733,7 @@ data: ${JSON.stringify(turn)}
17626
17733
  };
17627
17734
  const fileEnd0 = (() => {
17628
17735
  try {
17629
- return statSync17(jsonlPath).size;
17736
+ return statSync18(jsonlPath).size;
17630
17737
  } catch {
17631
17738
  return 0;
17632
17739
  }
@@ -17741,9 +17848,9 @@ app9.get("/attachment/:attachmentId", (c) => {
17741
17848
  let dataFile;
17742
17849
  let buffer;
17743
17850
  try {
17744
- dataFile = readdirSync17(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
17851
+ dataFile = readdirSync18(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
17745
17852
  if (!dataFile) throw new Error("no data file");
17746
- buffer = readFileSync26(resolve23(dir, dataFile));
17853
+ buffer = readFileSync27(resolve23(dir, dataFile));
17747
17854
  } catch {
17748
17855
  console.error(`${ATT_TAG} op=denied session=${ses} att=${at} reason=not-found`);
17749
17856
  return new Response("Not found", { status: 404 });
@@ -17765,20 +17872,20 @@ var public_reader_default = app9;
17765
17872
 
17766
17873
  // server/routes/webchat.ts
17767
17874
  import { basename as basename11, dirname as dirname11 } from "path";
17768
- import { join as join37 } from "path";
17769
- import { existsSync as existsSync25, readdirSync as readdirSync19, readFileSync as readFileSync29, renameSync as renameSync4, statSync as statSync18, writeFileSync as writeFileSync11 } from "fs";
17875
+ import { join as join38 } from "path";
17876
+ import { existsSync as existsSync25, readdirSync as readdirSync20, readFileSync as readFileSync30, renameSync as renameSync4, statSync as statSync19, writeFileSync as writeFileSync11 } from "fs";
17770
17877
 
17771
17878
  // server/canonical-webchat-override.ts
17772
- import { readFileSync as readFileSync27, writeFileSync as writeFileSync9, renameSync as renameSync2 } from "fs";
17773
- import { join as join35 } from "path";
17879
+ import { readFileSync as readFileSync28, writeFileSync as writeFileSync9, renameSync as renameSync2 } from "fs";
17880
+ import { join as join36 } from "path";
17774
17881
  var FILE = "canonical-webchat-session.json";
17775
17882
  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}$/;
17776
17883
  function canonicalOverridePath(accountDir) {
17777
- return join35(accountDir, FILE);
17884
+ return join36(accountDir, FILE);
17778
17885
  }
17779
17886
  function readRaw(accountDir) {
17780
17887
  try {
17781
- return JSON.parse(readFileSync27(canonicalOverridePath(accountDir), "utf8"));
17888
+ return JSON.parse(readFileSync28(canonicalOverridePath(accountDir), "utf8"));
17782
17889
  } catch {
17783
17890
  return null;
17784
17891
  }
@@ -17891,8 +17998,8 @@ function isNewSessionEffortLevel(value) {
17891
17998
  }
17892
17999
 
17893
18000
  // ../services/claude-session-manager/src/sidecar-store.ts
17894
- import { existsSync as existsSync24, mkdirSync as mkdirSync4, readdirSync as readdirSync18, readFileSync as readFileSync28, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
17895
- import { join as join36 } from "path";
18001
+ import { existsSync as existsSync24, mkdirSync as mkdirSync4, readdirSync as readdirSync19, readFileSync as readFileSync29, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
18002
+ import { join as join37 } from "path";
17896
18003
  function escapeRegExp(s) {
17897
18004
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
17898
18005
  }
@@ -17900,7 +18007,7 @@ function createSidecarStore(config) {
17900
18007
  const { suffix, validate: validate3 } = config;
17901
18008
  const suffixRe = new RegExp(`${escapeRegExp(suffix)}$`);
17902
18009
  function pathFor(sessionsDir, id) {
17903
- return join36(sessionsDir, `${id}${suffix}`);
18010
+ return join37(sessionsDir, `${id}${suffix}`);
17904
18011
  }
17905
18012
  function write(sessionsDir, id, record) {
17906
18013
  mkdirSync4(sessionsDir, { recursive: true });
@@ -17921,7 +18028,7 @@ function createSidecarStore(config) {
17921
18028
  function readFileAt(path) {
17922
18029
  let raw;
17923
18030
  try {
17924
- raw = readFileSync28(path, "utf8");
18031
+ raw = readFileSync29(path, "utf8");
17925
18032
  } catch {
17926
18033
  return null;
17927
18034
  }
@@ -17937,17 +18044,17 @@ function createSidecarStore(config) {
17937
18044
  function readAll3(sessionsDir, onSkip) {
17938
18045
  let names;
17939
18046
  try {
17940
- names = readdirSync18(sessionsDir, { withFileTypes: true }).filter((entry3) => entry3.isFile()).map((entry3) => entry3.name);
18047
+ names = readdirSync19(sessionsDir, { withFileTypes: true }).filter((entry3) => entry3.isFile()).map((entry3) => entry3.name);
17941
18048
  } catch {
17942
18049
  return [];
17943
18050
  }
17944
18051
  const out = [];
17945
18052
  for (const name of names) {
17946
18053
  if (!suffixRe.test(name)) continue;
17947
- const path = join36(sessionsDir, name);
18054
+ const path = join37(sessionsDir, name);
17948
18055
  let raw;
17949
18056
  try {
17950
- raw = readFileSync28(path, "utf8");
18057
+ raw = readFileSync29(path, "utf8");
17951
18058
  } catch {
17952
18059
  onSkip?.(name, "unreadable");
17953
18060
  continue;
@@ -18020,7 +18127,7 @@ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9
18020
18127
  function locateSession(sessionId) {
18021
18128
  const dir = findSessionProjectDir(sessionId);
18022
18129
  if (!dir) return { projectDir: null, channel: null, accountId: null };
18023
- const meta = readSidecarMeta(join37(dir, `${sessionId}.meta.json`));
18130
+ const meta = readSidecarMeta(join38(dir, `${sessionId}.meta.json`));
18024
18131
  return { projectDir: dir, channel: meta.channel, accountId: meta.accountId };
18025
18132
  }
18026
18133
  function resolveQuoted(sessionId, quotedUuid, sendId) {
@@ -18038,7 +18145,7 @@ function resolveQuoted(sessionId, quotedUuid, sendId) {
18038
18145
  let line;
18039
18146
  try {
18040
18147
  const needle = `"uuid":"${quotedUuid}"`;
18041
- line = readFileSync29(join37(projectDir, `${sessionId}.jsonl`), "utf8").split("\n").find((l) => l.includes(needle));
18148
+ line = readFileSync30(join38(projectDir, `${sessionId}.jsonl`), "utf8").split("\n").find((l) => l.includes(needle));
18042
18149
  } catch {
18043
18150
  log2(false, 0);
18044
18151
  return void 0;
@@ -18055,15 +18162,15 @@ function resolveQuoted(sessionId, quotedUuid, sendId) {
18055
18162
  function locateSidecar(sessionId) {
18056
18163
  const cfg = claudeConfigDir();
18057
18164
  if (!cfg) return null;
18058
- const projectsRoot = join37(cfg, "projects");
18165
+ const projectsRoot = join38(cfg, "projects");
18059
18166
  let slugs;
18060
18167
  try {
18061
- slugs = readdirSync19(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
18168
+ slugs = readdirSync20(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
18062
18169
  } catch {
18063
18170
  return null;
18064
18171
  }
18065
18172
  for (const slug of slugs) {
18066
- const metaPath = join37(projectsRoot, slug, `${sessionId}.meta.json`);
18173
+ const metaPath = join38(projectsRoot, slug, `${sessionId}.meta.json`);
18067
18174
  if (existsSync25(metaPath)) return readSidecarMeta(metaPath);
18068
18175
  }
18069
18176
  return null;
@@ -18073,7 +18180,7 @@ function readTargetOwner(sessionId) {
18073
18180
  if (sidecar !== null) return { found: true, owner: sidecar.adminUserId };
18074
18181
  const { projectDir } = locateSession(sessionId);
18075
18182
  if (projectDir !== null) {
18076
- return { found: true, owner: readSidecarMeta(join37(projectDir, `${sessionId}.meta.json`)).adminUserId };
18183
+ return { found: true, owner: readSidecarMeta(join38(projectDir, `${sessionId}.meta.json`)).adminUserId };
18077
18184
  }
18078
18185
  return { found: false, owner: null };
18079
18186
  }
@@ -18081,7 +18188,7 @@ function readSourceRowMeta(sessionId) {
18081
18188
  const sidecar = locateSidecar(sessionId);
18082
18189
  if (sidecar !== null) return sidecar;
18083
18190
  const { projectDir } = locateSession(sessionId);
18084
- if (projectDir !== null) return readSidecarMeta(join37(projectDir, `${sessionId}.meta.json`));
18191
+ if (projectDir !== null) return readSidecarMeta(join38(projectDir, `${sessionId}.meta.json`));
18085
18192
  return null;
18086
18193
  }
18087
18194
  function ownedByRequester(owner, requesterUserId, primaryUserId) {
@@ -18094,7 +18201,7 @@ function sessionSidecarExists(sessionId) {
18094
18201
  function jsonlSizeBytes(projectDir, sessionId) {
18095
18202
  if (projectDir === null) return null;
18096
18203
  try {
18097
- return statSync18(join37(projectDir, `${sessionId}.jsonl`)).size;
18204
+ return statSync19(join38(projectDir, `${sessionId}.jsonl`)).size;
18098
18205
  } catch {
18099
18206
  return null;
18100
18207
  }
@@ -18222,15 +18329,15 @@ function latestAdminWebchatSessionId(requesterUserId, primaryUserId, scopeAccoun
18222
18329
  const cfg = claudeConfigDir();
18223
18330
  if (!cfg) return null;
18224
18331
  let best = null;
18225
- for (const { path, isSubagent, archived } of enumerateJsonls(join37(cfg, "projects"))) {
18332
+ for (const { path, isSubagent, archived } of enumerateJsonls(join38(cfg, "projects"))) {
18226
18333
  if (isSubagent || archived) continue;
18227
18334
  const id = basename11(path).slice(0, -".jsonl".length);
18228
- const meta = readSidecarMeta(join37(dirname11(path), `${id}.meta.json`));
18335
+ const meta = readSidecarMeta(join38(dirname11(path), `${id}.meta.json`));
18229
18336
  if (meta.role !== "admin" || meta.channel !== "webchat") continue;
18230
18337
  if (multiAccount && meta.accountId !== scopeAccountId) continue;
18231
18338
  let mtimeMs;
18232
18339
  try {
18233
- mtimeMs = statSync18(path).mtimeMs;
18340
+ mtimeMs = statSync19(path).mtimeMs;
18234
18341
  } catch {
18235
18342
  continue;
18236
18343
  }
@@ -18585,9 +18692,9 @@ ${timeline}`;
18585
18692
  console.error(`[webchat:settings] op=${op} outcome=refused value=${value} accountId=none reason=no-account-for-session`);
18586
18693
  return c.json({ error: "account unresolved" }, 503);
18587
18694
  }
18588
- const accountJsonPath = join37(account.accountDir, "account.json");
18695
+ const accountJsonPath = join38(account.accountDir, "account.json");
18589
18696
  try {
18590
- const parsed = JSON.parse(readFileSync29(accountJsonPath, "utf8"));
18697
+ const parsed = JSON.parse(readFileSync30(accountJsonPath, "utf8"));
18591
18698
  if (op === "model") parsed.adminModel = value;
18592
18699
  else if (op === "effort") parsed.effort = value;
18593
18700
  else parsed.adminPermissionMode = value;
@@ -18633,7 +18740,7 @@ ${timeline}`;
18633
18740
  const cfg2 = claudeConfigDir();
18634
18741
  if (cfg2) {
18635
18742
  const source2 = resolveBridgeSource(
18636
- join37(cfg2, "sessions"),
18743
+ join38(cfg2, "sessions"),
18637
18744
  target,
18638
18745
  (id) => locateSession(id).projectDir !== null
18639
18746
  );
@@ -18660,7 +18767,7 @@ ${timeline}`;
18660
18767
  const cfg = claudeConfigDir();
18661
18768
  let projectDir = null;
18662
18769
  if (cfg) {
18663
- for (const { path } of enumerateJsonls(join37(cfg, "projects"))) {
18770
+ for (const { path } of enumerateJsonls(join38(cfg, "projects"))) {
18664
18771
  if (basename11(path) === `${sessionId}.jsonl`) {
18665
18772
  projectDir = dirname11(path);
18666
18773
  break;
@@ -18668,7 +18775,7 @@ ${timeline}`;
18668
18775
  }
18669
18776
  }
18670
18777
  if (source === "latest" && requesterUserId !== null) {
18671
- const owner = readSidecarMeta(join37(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
18778
+ const owner = readSidecarMeta(join38(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
18672
18779
  if (owner !== null && owner !== requesterUserId && requesterUserId !== primaryUserId) {
18673
18780
  console.error(`[webchat:inbound] op=session-resolve-foreign key=${sessionId.slice(0, 8)} owner=${owner.slice(0, 8)} requester=${requesterUserId.slice(0, 8)}`);
18674
18781
  }
@@ -18793,13 +18900,13 @@ var webchat_greeting_default = app10;
18793
18900
 
18794
18901
  // server/routes/telegram.ts
18795
18902
  import { homedir as homedir2 } from "os";
18796
- import { resolve as resolve25, join as join42 } from "path";
18797
- import { existsSync as existsSync29, readFileSync as readFileSync33 } from "fs";
18903
+ import { resolve as resolve25, join as join43 } from "path";
18904
+ import { existsSync as existsSync29, readFileSync as readFileSync34 } from "fs";
18798
18905
 
18799
18906
  // ../lib/telegram-managed-bot/src/index.ts
18800
18907
  import { randomBytes } from "crypto";
18801
- import { existsSync as existsSync26, readFileSync as readFileSync30, writeFileSync as writeFileSync12, mkdirSync as mkdirSync5 } from "fs";
18802
- import { dirname as dirname12, join as join38 } from "path";
18908
+ import { existsSync as existsSync26, readFileSync as readFileSync31, writeFileSync as writeFileSync12, mkdirSync as mkdirSync5 } from "fs";
18909
+ import { dirname as dirname12, join as join39 } from "path";
18803
18910
  var TELEGRAM_API = "https://api.telegram.org";
18804
18911
  var TELEGRAM_ALLOWED_UPDATES = [
18805
18912
  "message",
@@ -18866,13 +18973,13 @@ async function setTelegramWebhook(botToken, webhookUrl, secretFilePath, fetchImp
18866
18973
  return { ok: true, secret };
18867
18974
  }
18868
18975
  function writeTelegramBotEntry(accountDir, entry3) {
18869
- const configPath3 = join38(accountDir, "account.json");
18976
+ const configPath3 = join39(accountDir, "account.json");
18870
18977
  if (!existsSync26(configPath3)) {
18871
18978
  return { ok: false, error: `account.json not found at ${configPath3}` };
18872
18979
  }
18873
18980
  let config;
18874
18981
  try {
18875
- config = JSON.parse(readFileSync30(configPath3, "utf-8"));
18982
+ config = JSON.parse(readFileSync31(configPath3, "utf-8"));
18876
18983
  } catch (e) {
18877
18984
  return { ok: false, error: `account.json parse failed: ${e.message}` };
18878
18985
  }
@@ -19767,7 +19874,7 @@ function routeTelegramUpdate(input) {
19767
19874
 
19768
19875
  // app/lib/telegram/inbound/media.ts
19769
19876
  var import_dist5 = __toESM(require_dist4(), 1);
19770
- import { join as join39 } from "path";
19877
+ import { join as join40 } from "path";
19771
19878
  var TAG30 = "[telegram-inbound]";
19772
19879
  var TELEGRAM_MEDIA_DIR = "/tmp/maxy-media";
19773
19880
  var DOWNLOAD_TIMEOUT_MS = 45e3;
@@ -19795,7 +19902,7 @@ async function downloadTelegramMedia(input) {
19795
19902
  if (!meta.ok) {
19796
19903
  result = { ...base, failure: meta.failure };
19797
19904
  } else {
19798
- const path = join39(
19905
+ const path = join40(
19799
19906
  dir,
19800
19907
  `tg-${(0, import_dist5.pathSafe)(input.botId)}-${(0, import_dist5.pathSafe)(item.fileUniqueId)}.${(0, import_dist5.extensionFor)(meta.filePath, item.mimetype)}`
19801
19908
  );
@@ -20662,8 +20769,8 @@ async function handleDispatchMedia(p) {
20662
20769
  }
20663
20770
 
20664
20771
  // app/lib/telegram/live-location.ts
20665
- import { existsSync as existsSync27, mkdirSync as mkdirSync6, readFileSync as readFileSync31, readdirSync as readdirSync20, statSync as statSync19, writeFileSync as writeFileSync13 } from "fs";
20666
- import { join as join40 } from "path";
20772
+ import { existsSync as existsSync27, mkdirSync as mkdirSync6, readFileSync as readFileSync32, readdirSync as readdirSync21, statSync as statSync20, writeFileSync as writeFileSync13 } from "fs";
20773
+ import { join as join41 } from "path";
20667
20774
  var TAG37 = "[telegram-inbound]";
20668
20775
  var LIVE_LOCATION_FILE = "telegram-live-location.json";
20669
20776
  var LIVE_LOCATION_CENSUS_TAG = "[telegram-live-location-census]";
@@ -20678,7 +20785,7 @@ function isRecord(v) {
20678
20785
  function readAll(path) {
20679
20786
  if (!existsSync27(path)) return {};
20680
20787
  try {
20681
- const parsed = JSON.parse(readFileSync31(path, "utf-8"));
20788
+ const parsed = JSON.parse(readFileSync32(path, "utf-8"));
20682
20789
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
20683
20790
  const out = {};
20684
20791
  for (const [k, v] of Object.entries(parsed)) {
@@ -20695,7 +20802,7 @@ function isExpired(rec, now) {
20695
20802
  function writeLiveLocation(input) {
20696
20803
  const { accountDir, botId, senderId, now, emit } = input;
20697
20804
  const key2 = liveLocationKey(botId, senderId);
20698
- const path = join40(accountDir, LIVE_LOCATION_FILE);
20805
+ const path = join41(accountDir, LIVE_LOCATION_FILE);
20699
20806
  const stored = readAll(path);
20700
20807
  const livePeriodS = input.livePeriodS ?? stored[key2]?.livePeriodS ?? null;
20701
20808
  if (livePeriodS === null) {
@@ -20744,9 +20851,9 @@ function liveLocationCensusLine(accountsRoot, now) {
20744
20851
  let expired = 0;
20745
20852
  let oldestAgeMs = 0;
20746
20853
  try {
20747
- for (const entry3 of readdirSync20(accountsRoot)) {
20748
- const path = join40(accountsRoot, entry3, LIVE_LOCATION_FILE);
20749
- if (!existsSync27(path) || !statSync19(path).isFile()) continue;
20854
+ for (const entry3 of readdirSync21(accountsRoot)) {
20855
+ const path = join41(accountsRoot, entry3, LIVE_LOCATION_FILE);
20856
+ if (!existsSync27(path) || !statSync20(path).isFile()) continue;
20750
20857
  for (const rec of Object.values(readAll(path))) {
20751
20858
  records5 += 1;
20752
20859
  if (isExpired(rec, now)) expired += 1;
@@ -20765,8 +20872,8 @@ function liveLocationCensusLine(accountsRoot, now) {
20765
20872
  }
20766
20873
 
20767
20874
  // app/lib/telegram/business-connection.ts
20768
- import { existsSync as existsSync28, mkdirSync as mkdirSync7, readFileSync as readFileSync32, writeFileSync as writeFileSync14 } from "fs";
20769
- import { join as join41 } from "path";
20875
+ import { existsSync as existsSync28, mkdirSync as mkdirSync7, readFileSync as readFileSync33, writeFileSync as writeFileSync14 } from "fs";
20876
+ import { join as join42 } from "path";
20770
20877
  var TAG38 = "[telegram-inbound]";
20771
20878
  var BUSINESS_CONNECTION_FILE = "telegram-business-connection.json";
20772
20879
  function truncateConnectionId(id) {
@@ -20780,7 +20887,7 @@ function isRecord2(v) {
20780
20887
  function readAll2(path) {
20781
20888
  if (!existsSync28(path)) return {};
20782
20889
  try {
20783
- const parsed = JSON.parse(readFileSync32(path, "utf-8"));
20890
+ const parsed = JSON.parse(readFileSync33(path, "utf-8"));
20784
20891
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
20785
20892
  const out = {};
20786
20893
  for (const [k, v] of Object.entries(parsed)) {
@@ -20816,7 +20923,7 @@ function writeBusinessConnection(input) {
20816
20923
  rights,
20817
20924
  at: now
20818
20925
  };
20819
- const path = join41(accountDir, BUSINESS_CONNECTION_FILE);
20926
+ const path = join42(accountDir, BUSINESS_CONNECTION_FILE);
20820
20927
  const all = readAll2(path);
20821
20928
  all[botId] = next;
20822
20929
  try {
@@ -20830,12 +20937,12 @@ function writeBusinessConnection(input) {
20830
20937
  return { written: true, reason: "ok" };
20831
20938
  }
20832
20939
  function readBusinessConnection(accountDir, botId) {
20833
- const rec = readAll2(join41(accountDir, BUSINESS_CONNECTION_FILE))[botId];
20940
+ const rec = readAll2(join42(accountDir, BUSINESS_CONNECTION_FILE))[botId];
20834
20941
  if (!rec || !rec.isEnabled) return null;
20835
20942
  return rec;
20836
20943
  }
20837
20944
  function readAllBusinessConnections(accountDir) {
20838
- return readAll2(join41(accountDir, BUSINESS_CONNECTION_FILE));
20945
+ return readAll2(join42(accountDir, BUSINESS_CONNECTION_FILE));
20839
20946
  }
20840
20947
 
20841
20948
  // app/lib/telegram/business-window.ts
@@ -20891,10 +20998,10 @@ function logValue4(v) {
20891
20998
  }
20892
20999
  function configDirName() {
20893
21000
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? resolve25(process.cwd(), "..");
20894
- const brandPath = join42(platformRoot5, "config", "brand.json");
21001
+ const brandPath = join43(platformRoot5, "config", "brand.json");
20895
21002
  if (existsSync29(brandPath)) {
20896
21003
  try {
20897
- return JSON.parse(readFileSync33(brandPath, "utf-8")).configDir ?? ".maxy";
21004
+ return JSON.parse(readFileSync34(brandPath, "utf-8")).configDir ?? ".maxy";
20898
21005
  } catch {
20899
21006
  }
20900
21007
  }
@@ -20922,7 +21029,7 @@ function provisionedWebhookUrl(c, botId) {
20922
21029
  }
20923
21030
  function accountConfig(accountDir) {
20924
21031
  try {
20925
- return JSON.parse(readFileSync33(join42(accountDir, "account.json"), "utf-8"));
21032
+ return JSON.parse(readFileSync34(join43(accountDir, "account.json"), "utf-8"));
20926
21033
  } catch {
20927
21034
  return {};
20928
21035
  }
@@ -21004,7 +21111,7 @@ app11.post("/", async (c) => {
21004
21111
  console.error(`${TAG39} op=secret botId=${botId} result=missing-file`);
21005
21112
  return c.json({ ok: false }, 401);
21006
21113
  }
21007
- const expected = readFileSync33(sp, "utf-8").trim();
21114
+ const expected = readFileSync34(sp, "utf-8").trim();
21008
21115
  const got = c.req.header("x-telegram-bot-api-secret-token") ?? "";
21009
21116
  if (got !== expected) {
21010
21117
  console.error(`${TAG39} op=secret botId=${botId} result=mismatch`);
@@ -21949,16 +22056,16 @@ function mountTelegramRoutes(app81, telegramRoutes) {
21949
22056
  }
21950
22057
 
21951
22058
  // server/routes/quickbooks.ts
21952
- import { join as join43 } from "path";
21953
- import { existsSync as existsSync30, readFileSync as readFileSync34, writeFileSync as writeFileSync15, mkdirSync as mkdirSync8, rmSync as rmSync4, renameSync as renameSync5 } from "fs";
22059
+ import { join as join44 } from "path";
22060
+ import { existsSync as existsSync30, readFileSync as readFileSync35, writeFileSync as writeFileSync15, mkdirSync as mkdirSync8, rmSync as rmSync4, renameSync as renameSync5 } from "fs";
21954
22061
  var TAG40 = "[quickbooks]";
21955
22062
  var INTUIT_TOKEN_URL = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
21956
22063
  var STATE_RE = /^[A-Za-z0-9_-]+$/;
21957
22064
  function pendingPath(accountDir, state) {
21958
- return join43(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
22065
+ return join44(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
21959
22066
  }
21960
22067
  function storePath(accountDir) {
21961
- return join43(accountDir, "secrets", "quickbooks.json");
22068
+ return join44(accountDir, "secrets", "quickbooks.json");
21962
22069
  }
21963
22070
  async function completeConsent(args) {
21964
22071
  const { accountDir, code, realmId } = args;
@@ -21977,7 +22084,7 @@ async function completeConsent(args) {
21977
22084
  try {
21978
22085
  let pending;
21979
22086
  try {
21980
- pending = JSON.parse(readFileSync34(claimFile, "utf-8"));
22087
+ pending = JSON.parse(readFileSync35(claimFile, "utf-8"));
21981
22088
  } catch {
21982
22089
  console.error(`${TAG40} op=callback state=${state} stateValid=false realmId=${realmId ?? ""}`);
21983
22090
  return { ok: false, status: 400, message: "Authorization state could not be read.", stateValid: false };
@@ -21993,7 +22100,7 @@ async function completeConsent(args) {
21993
22100
  if (!existsSync30(storePath(accountDir))) {
21994
22101
  return { ok: false, status: 500, message: "No QuickBooks credentials are stored for this account.", stateValid: true };
21995
22102
  }
21996
- const store2 = JSON.parse(readFileSync34(storePath(accountDir), "utf-8"));
22103
+ const store2 = JSON.parse(readFileSync35(storePath(accountDir), "utf-8"));
21997
22104
  const form = new URLSearchParams({
21998
22105
  grant_type: "authorization_code",
21999
22106
  code,
@@ -22025,9 +22132,9 @@ async function completeConsent(args) {
22025
22132
  refreshTokenExpiry: now + (body.x_refresh_token_expires_in ?? 864e4) * 1e3,
22026
22133
  lastRefresh: now
22027
22134
  };
22028
- mkdirSync8(join43(accountDir, "secrets"), { recursive: true });
22135
+ mkdirSync8(join44(accountDir, "secrets"), { recursive: true });
22029
22136
  writeFileSync15(storePath(accountDir), JSON.stringify(store2, null, 2), { mode: 384 });
22030
- const persisted = JSON.parse(readFileSync34(storePath(accountDir), "utf-8")).connections?.[realmId]?.refreshToken === body.refresh_token;
22137
+ const persisted = JSON.parse(readFileSync35(storePath(accountDir), "utf-8")).connections?.[realmId]?.refreshToken === body.refresh_token;
22031
22138
  console.error(`${TAG40} op=token-exchange realmId=${realmId} persisted=${persisted}`);
22032
22139
  return { ok: persisted, status: persisted ? 200 : 500, message: persisted ? `Connected company ${realmId}.` : "Failed to persist the connection.", stateValid: true };
22033
22140
  } finally {
@@ -22058,7 +22165,7 @@ var quickbooks_default = app12;
22058
22165
 
22059
22166
  // server/routes/onboarding.ts
22060
22167
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync4 } from "child_process";
22061
- import { openSync as openSync8, closeSync as closeSync8, appendFileSync as appendFileSync4, writeFileSync as writeFileSync17, writeSync, existsSync as existsSync32, readFileSync as readFileSync36, unlinkSync as unlinkSync3 } from "fs";
22168
+ import { openSync as openSync9, closeSync as closeSync9, appendFileSync as appendFileSync4, writeFileSync as writeFileSync17, writeSync, existsSync as existsSync32, readFileSync as readFileSync37, unlinkSync as unlinkSync3 } from "fs";
22062
22169
  import { createHash as createHash4, randomUUID as randomUUID5 } from "crypto";
22063
22170
 
22064
22171
  // app/lib/claude-spawn-env.ts
@@ -22067,7 +22174,7 @@ function claudeBin() {
22067
22174
  }
22068
22175
 
22069
22176
  // server/routes/onboarding.ts
22070
- import { dirname as dirname14, join as join45 } from "path";
22177
+ import { dirname as dirname14, join as join46 } from "path";
22071
22178
 
22072
22179
  // app/lib/claude-keychain.ts
22073
22180
  import { execFileSync as execFileSync3 } from "child_process";
@@ -22198,19 +22305,19 @@ function readHostCredsBlob(service) {
22198
22305
  }
22199
22306
 
22200
22307
  // ../lib/admins-write/src/index.ts
22201
- import { existsSync as existsSync31, readFileSync as readFileSync35, writeFileSync as writeFileSync16, renameSync as renameSync6, mkdirSync as mkdirSync9, readdirSync as readdirSync21, statSync as statSync20, appendFileSync as appendFileSync3 } from "fs";
22202
- import { dirname as dirname13, join as join44 } from "path";
22308
+ import { existsSync as existsSync31, readFileSync as readFileSync36, writeFileSync as writeFileSync16, renameSync as renameSync6, mkdirSync as mkdirSync9, readdirSync as readdirSync22, statSync as statSync21, appendFileSync as appendFileSync3 } from "fs";
22309
+ import { dirname as dirname13, join as join45 } from "path";
22203
22310
  function id8(value) {
22204
22311
  return value.slice(0, 8);
22205
22312
  }
22206
22313
  function formatAuditRowIds(userIds) {
22207
22314
  return userIds.map(id8).join(",");
22208
22315
  }
22209
- function appendUsersAuditLine(audit, fields) {
22316
+ function appendUsersAuditLine(audit, fields2) {
22210
22317
  const sess = audit.session ? ` session=${id8(audit.session)}` : "";
22211
22318
  const actor = audit.actor.includes("-") ? id8(audit.actor) : audit.actor;
22212
22319
  const targetFields = audit.target !== void 0 ? ` target=${audit.target.includes("-") ? id8(audit.target) : audit.target} explicitUserId=${audit.explicitUserId ? "true" : "false"}` : "";
22213
- 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()}
22320
+ const line = `[users-audit] action=${fields2.action} actor=${actor}${targetFields}${sess} field=${fields2.field} rowsBefore=${fields2.rowsBefore} rowsAfter=${fields2.rowsAfter} ts=${(/* @__PURE__ */ new Date()).toISOString()}
22214
22321
  `;
22215
22322
  try {
22216
22323
  mkdirSync9(dirname13(audit.logFile), { recursive: true, mode: 448 });
@@ -22221,8 +22328,8 @@ function appendUsersAuditLine(audit, fields) {
22221
22328
  );
22222
22329
  }
22223
22330
  }
22224
- function logUsersAudit(audit, fields) {
22225
- appendUsersAuditLine(audit, fields);
22331
+ function logUsersAudit(audit, fields2) {
22332
+ appendUsersAuditLine(audit, fields2);
22226
22333
  }
22227
22334
  function logLine(input, result) {
22228
22335
  const userIdShort = input.userId.slice(0, 8);
@@ -22241,7 +22348,7 @@ function writeAdminEntry(input) {
22241
22348
  try {
22242
22349
  let users = [];
22243
22350
  if (existsSync31(input.usersFile)) {
22244
- const raw = readFileSync35(input.usersFile, "utf-8").trim();
22351
+ const raw = readFileSync36(input.usersFile, "utf-8").trim();
22245
22352
  if (raw) {
22246
22353
  const parsed = JSON.parse(raw);
22247
22354
  if (!Array.isArray(parsed)) {
@@ -22283,11 +22390,11 @@ function writeAdminEntry(input) {
22283
22390
  return result;
22284
22391
  }
22285
22392
  try {
22286
- const accountJsonPath = join44(input.accountDir, "account.json");
22393
+ const accountJsonPath = join45(input.accountDir, "account.json");
22287
22394
  if (!existsSync31(accountJsonPath)) {
22288
22395
  throw new Error(`account.json not found at ${accountJsonPath}`);
22289
22396
  }
22290
- const config = JSON.parse(readFileSync35(accountJsonPath, "utf-8"));
22397
+ const config = JSON.parse(readFileSync36(accountJsonPath, "utf-8"));
22291
22398
  const admins = config.admins ?? [];
22292
22399
  if (admins.some((a) => a.userId === input.userId)) {
22293
22400
  result.accountJsonResult = "noop";
@@ -22309,7 +22416,7 @@ function computeAdminStoreDivergence(input) {
22309
22416
  const usersUserIds = /* @__PURE__ */ new Set();
22310
22417
  if (existsSync31(input.usersFile)) {
22311
22418
  try {
22312
- const raw = readFileSync35(input.usersFile, "utf-8").trim();
22419
+ const raw = readFileSync36(input.usersFile, "utf-8").trim();
22313
22420
  if (raw) {
22314
22421
  const users = JSON.parse(raw);
22315
22422
  for (const u of users) {
@@ -22324,24 +22431,24 @@ function computeAdminStoreDivergence(input) {
22324
22431
  if (existsSync31(input.accountsDir)) {
22325
22432
  let entries2;
22326
22433
  try {
22327
- entries2 = readdirSync21(input.accountsDir);
22434
+ entries2 = readdirSync22(input.accountsDir);
22328
22435
  } catch (err) {
22329
22436
  result.errors.push({ source: input.accountsDir, detail: err instanceof Error ? err.message : String(err) });
22330
22437
  return result;
22331
22438
  }
22332
22439
  for (const entry3 of entries2) {
22333
22440
  if (entry3.startsWith(".")) continue;
22334
- const accountDir = join44(input.accountsDir, entry3);
22441
+ const accountDir = join45(input.accountsDir, entry3);
22335
22442
  try {
22336
- if (!statSync20(accountDir).isDirectory()) continue;
22443
+ if (!statSync21(accountDir).isDirectory()) continue;
22337
22444
  } catch {
22338
22445
  continue;
22339
22446
  }
22340
- const accountJsonPath = join44(accountDir, "account.json");
22447
+ const accountJsonPath = join45(accountDir, "account.json");
22341
22448
  if (!existsSync31(accountJsonPath)) continue;
22342
22449
  let admins = [];
22343
22450
  try {
22344
- const config = JSON.parse(readFileSync35(accountJsonPath, "utf-8"));
22451
+ const config = JSON.parse(readFileSync36(accountJsonPath, "utf-8"));
22345
22452
  admins = config.admins ?? [];
22346
22453
  } catch (err) {
22347
22454
  result.errors.push({ source: accountJsonPath, detail: err instanceof Error ? err.message : String(err) });
@@ -22390,7 +22497,7 @@ function hashPin2(pin) {
22390
22497
  }
22391
22498
  function readUsersFile2() {
22392
22499
  if (!existsSync32(USERS_FILE)) return null;
22393
- const raw = readFileSync36(USERS_FILE, "utf-8").trim();
22500
+ const raw = readFileSync37(USERS_FILE, "utf-8").trim();
22394
22501
  if (!raw) return [];
22395
22502
  return JSON.parse(raw);
22396
22503
  }
@@ -22521,7 +22628,7 @@ app13.post("/claude-auth", async (c) => {
22521
22628
  ensureLogDir();
22522
22629
  appendFileSync4(logPath("claude-auth"), `==== attempt ${attemptId} ${(/* @__PURE__ */ new Date()).toISOString()} ====
22523
22630
  `);
22524
- const claudeAuthLogFd = openSync8(logPath("claude-auth"), "a");
22631
+ const claudeAuthLogFd = openSync9(logPath("claude-auth"), "a");
22525
22632
  const onClaudeOutput = (chunk) => writeSync(claudeAuthLogFd, chunk);
22526
22633
  if (process.platform === "darwin") {
22527
22634
  vncLog("claude-auth", { action: "start", transport: "native", platform: "darwin" });
@@ -22538,7 +22645,7 @@ app13.post("/claude-auth", async (c) => {
22538
22645
  claudeProc2.stdout?.on("data", onClaudeOutput);
22539
22646
  claudeProc2.stderr?.on("data", onClaudeOutput);
22540
22647
  claudeProc2.once("close", () => {
22541
- closeSync8(claudeAuthLogFd);
22648
+ closeSync9(claudeAuthLogFd);
22542
22649
  const writebackResult = bridgeKeychainToFile({
22543
22650
  platform: process.platform,
22544
22651
  before: darwinCredsBefore,
@@ -22551,7 +22658,7 @@ app13.post("/claude-auth", async (c) => {
22551
22658
  });
22552
22659
  persistKeychainService(
22553
22660
  writebackResult,
22554
- (service) => writeFileSync17(join45(dirname14(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
22661
+ (service) => writeFileSync17(join46(dirname14(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
22555
22662
  (line) => console.log(line)
22556
22663
  );
22557
22664
  if (pendingAuthLogin?.child === claudeProc2) pendingAuthLogin = null;
@@ -22576,7 +22683,7 @@ app13.post("/claude-auth", async (c) => {
22576
22683
  claudeProc.stdout?.on("data", onClaudeOutput);
22577
22684
  claudeProc.stderr?.on("data", onClaudeOutput);
22578
22685
  claudeProc.once("close", () => {
22579
- closeSync8(claudeAuthLogFd);
22686
+ closeSync9(claudeAuthLogFd);
22580
22687
  if (pendingAuthLogin?.child === claudeProc) pendingAuthLogin = null;
22581
22688
  });
22582
22689
  await waitForAuthPage(2e4);
@@ -22641,7 +22748,7 @@ app13.post("/set-pin", async (c) => {
22641
22748
  let installOwner = null;
22642
22749
  if (existsSync32(INSTALL_OWNER_FILE)) {
22643
22750
  try {
22644
- const raw = readFileSync36(INSTALL_OWNER_FILE, "utf-8").trim();
22751
+ const raw = readFileSync37(INSTALL_OWNER_FILE, "utf-8").trim();
22645
22752
  if (raw.length > 0) installOwner = raw;
22646
22753
  } catch (err) {
22647
22754
  console.error(`[set-pin] install-owner-read-failed path=${INSTALL_OWNER_FILE} error=${err instanceof Error ? err.message : String(err)}`);
@@ -22789,7 +22896,7 @@ app13.put("/set-pin", requireAdminSession, async (c) => {
22789
22896
  let installOwner = null;
22790
22897
  if (existsSync32(INSTALL_OWNER_FILE)) {
22791
22898
  try {
22792
- const raw = readFileSync36(INSTALL_OWNER_FILE, "utf-8").trim();
22899
+ const raw = readFileSync37(INSTALL_OWNER_FILE, "utf-8").trim();
22793
22900
  if (raw.length > 0) installOwner = raw;
22794
22901
  } catch (err) {
22795
22902
  console.error(`[set-pin] install-owner-read-failed path=${INSTALL_OWNER_FILE} error=${err instanceof Error ? err.message : String(err)}`);
@@ -23246,9 +23353,9 @@ app14.post("/probe", async (c) => {
23246
23353
  var field_default = app14;
23247
23354
 
23248
23355
  // server/routes/client-error.ts
23249
- import { appendFileSync as appendFileSync5, existsSync as existsSync33, renameSync as renameSync8, statSync as statSync21 } from "fs";
23250
- import { join as join46 } from "path";
23251
- var CLIENT_ERRORS_LOG = join46(LOG_DIR, "client-errors.log");
23356
+ import { appendFileSync as appendFileSync5, existsSync as existsSync33, renameSync as renameSync8, statSync as statSync22 } from "fs";
23357
+ import { join as join47 } from "path";
23358
+ var CLIENT_ERRORS_LOG = join47(LOG_DIR, "client-errors.log");
23252
23359
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
23253
23360
  var MAX_BODY_SIZE = 8 * 1024;
23254
23361
  var MAX_STACK_LEN = 2e3;
@@ -23306,7 +23413,7 @@ function stackHead(stack) {
23306
23413
  function rotateIfNeeded() {
23307
23414
  try {
23308
23415
  if (!existsSync33(CLIENT_ERRORS_LOG)) return;
23309
- const stats = statSync21(CLIENT_ERRORS_LOG);
23416
+ const stats = statSync22(CLIENT_ERRORS_LOG);
23310
23417
  if (stats.size < MAX_LOG_SIZE) return;
23311
23418
  renameSync8(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
23312
23419
  } catch (err) {
@@ -23662,17 +23769,17 @@ app17.get("/", requireAdminSession, async (c) => {
23662
23769
  var accounts_default = app17;
23663
23770
 
23664
23771
  // server/routes/admin/logs.ts
23665
- import { existsSync as existsSync35, readdirSync as readdirSync22, readFileSync as readFileSync37, statSync as statSync22 } from "fs";
23772
+ import { existsSync as existsSync35, readdirSync as readdirSync23, readFileSync as readFileSync38, statSync as statSync23 } from "fs";
23666
23773
  import { resolve as resolve26, basename as basename13 } from "path";
23667
23774
 
23668
23775
  // app/lib/logs-read-resolve.ts
23669
23776
  import { existsSync as existsSync34 } from "fs";
23670
- import { join as join47 } from "path";
23777
+ import { join as join48 } from "path";
23671
23778
  function resolveSessionLogPaths(filename, logDirs) {
23672
23779
  const tried = [filename];
23673
23780
  const hits = [];
23674
23781
  for (const dir of logDirs) {
23675
- const fullPath = join47(dir, filename);
23782
+ const fullPath = join48(dir, filename);
23676
23783
  if (existsSync34(fullPath)) {
23677
23784
  hits.push({ path: fullPath, dir });
23678
23785
  }
@@ -23698,8 +23805,8 @@ app18.get("/", async (c) => {
23698
23805
  const filePath = resolve26(dir, safe);
23699
23806
  searched.push(filePath);
23700
23807
  try {
23701
- const buffer = readFileSync37(filePath);
23702
- const onDiskBytes = statSync22(filePath).size;
23808
+ const buffer = readFileSync38(filePath);
23809
+ const onDiskBytes = statSync23(filePath).size;
23703
23810
  const headers = {
23704
23811
  "Content-Type": "text/plain; charset=utf-8",
23705
23812
  "Content-Length": String(buffer.byteLength)
@@ -23763,8 +23870,8 @@ app18.get("/", async (c) => {
23763
23870
  console.info(`[admin/logs] resolved cacheKey=${cacheKeySlice} sessionId=${sessionIdSlice} via=${primaryId === cacheKey ? "cacheKey" : primaryId === sessionKeyFromConv ? "reverse-lookup" : "sessionId-fallback"}`);
23764
23871
  try {
23765
23872
  const filename = basename13(hit.path);
23766
- const buffer = readFileSync37(hit.path);
23767
- const onDiskBytes = statSync22(hit.path).size;
23873
+ const buffer = readFileSync38(hit.path);
23874
+ const onDiskBytes = statSync23(hit.path).size;
23768
23875
  const headers = {
23769
23876
  "Content-Type": "text/plain; charset=utf-8",
23770
23877
  "Content-Length": String(buffer.byteLength)
@@ -23801,18 +23908,18 @@ app18.get("/", async (c) => {
23801
23908
  if (!existsSync35(dir)) continue;
23802
23909
  let files;
23803
23910
  try {
23804
- files = readdirSync22(dir).filter((f) => f.endsWith(".log"));
23911
+ files = readdirSync23(dir).filter((f) => f.endsWith(".log"));
23805
23912
  } catch (err) {
23806
23913
  const reason = err instanceof Error ? err.message : String(err);
23807
23914
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
23808
23915
  continue;
23809
23916
  }
23810
- files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync22(resolve26(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
23917
+ files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync23(resolve26(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
23811
23918
  seen.add(name);
23812
23919
  try {
23813
- const content = readFileSync37(resolve26(dir, name));
23814
- const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
23815
- logs[name] = tail.trim() || "(empty)";
23920
+ const content = readFileSync38(resolve26(dir, name));
23921
+ const tail2 = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
23922
+ logs[name] = tail2.trim() || "(empty)";
23816
23923
  } catch (err) {
23817
23924
  const reason = err instanceof Error ? err.message : String(err);
23818
23925
  console.debug(`[admin/logs] read-fail name=${name} reason=${reason}`);
@@ -23932,7 +24039,7 @@ var attachment_default = app20;
23932
24039
 
23933
24040
  // server/routes/admin/session-upload.ts
23934
24041
  import { readFile as readFile8 } from "fs/promises";
23935
- import { existsSync as existsSync37, statSync as statSync23 } from "fs";
24042
+ import { existsSync as existsSync37, statSync as statSync24 } from "fs";
23936
24043
  var app21 = new Hono();
23937
24044
  app21.get("/", requireAdminSession, async (c) => {
23938
24045
  const cacheKey = c.var.cacheKey;
@@ -23953,7 +24060,7 @@ app21.get("/", requireAdminSession, async (c) => {
23953
24060
  return c.json({ error: "Not found" }, 404);
23954
24061
  }
23955
24062
  const resolution = resolveClaudeUploadsPath(`${sessionId}/${file}`);
23956
- if (!resolution.ok || !existsSync37(resolution.absolute) || !statSync23(resolution.absolute).isFile()) {
24063
+ if (!resolution.ok || !existsSync37(resolution.absolute) || !statSync24(resolution.absolute).isFile()) {
23957
24064
  console.log(`[session-upload] op=miss session=${short2} file=${file} status=404 reason=absent`);
23958
24065
  return c.json({ error: "Not found" }, 404);
23959
24066
  }
@@ -23975,13 +24082,13 @@ var session_upload_default = app21;
23975
24082
 
23976
24083
  // server/routes/admin/agents.ts
23977
24084
  import { resolve as resolve28 } from "path";
23978
- import { readdirSync as readdirSync24, readFileSync as readFileSync39, existsSync as existsSync39, rmSync as rmSync5, renameSync as renameSync9, mkdirSync as mkdirSync10, writeFileSync as writeFileSync18, chmodSync } from "fs";
24085
+ import { readdirSync as readdirSync25, readFileSync as readFileSync40, existsSync as existsSync39, rmSync as rmSync5, renameSync as renameSync9, mkdirSync as mkdirSync10, writeFileSync as writeFileSync18, chmodSync } from "fs";
23979
24086
  import { execFileSync as execFileSync6 } from "child_process";
23980
24087
 
23981
24088
  // ../services/claude-session-manager/src/tool-surface.ts
23982
- import { readFileSync as readFileSync38, readdirSync as readdirSync23, statSync as statSync24, existsSync as existsSync38 } from "fs";
24089
+ import { readFileSync as readFileSync39, readdirSync as readdirSync24, statSync as statSync25, existsSync as existsSync38 } from "fs";
23983
24090
  import { createHash as createHash5 } from "crypto";
23984
- import { join as join48 } from "path";
24091
+ import { join as join49 } from "path";
23985
24092
 
23986
24093
  // ../services/claude-session-manager/src/canonical-tool-names.ts
23987
24094
  function canonicalToolName(plugin, tool) {
@@ -24234,15 +24341,15 @@ function loadToolSurface(pluginsRoots) {
24234
24341
  const riskByTool = /* @__PURE__ */ new Map();
24235
24342
  const manifestPaths = /* @__PURE__ */ new Map();
24236
24343
  const loadOne = (pluginsRoot, plugin) => {
24237
- const pluginDir = join48(pluginsRoot, plugin);
24344
+ const pluginDir = join49(pluginsRoot, plugin);
24238
24345
  try {
24239
- if (!statSync24(pluginDir).isDirectory()) return;
24346
+ if (!statSync25(pluginDir).isDirectory()) return;
24240
24347
  } catch {
24241
24348
  return;
24242
24349
  }
24243
- const manifestPath = join48(pluginDir, "PLUGIN.md");
24350
+ const manifestPath = join49(pluginDir, "PLUGIN.md");
24244
24351
  if (!existsSync38(manifestPath)) return;
24245
- const raw = readFileSync38(manifestPath, "utf-8");
24352
+ const raw = readFileSync39(manifestPath, "utf-8");
24246
24353
  const frontmatter = extractFrontmatter(raw, plugin);
24247
24354
  const tools = parseToolsBlock(frontmatter, plugin);
24248
24355
  if (tools.length === 0) return;
@@ -24261,7 +24368,7 @@ function loadToolSurface(pluginsRoots) {
24261
24368
  `${plugin}: mcpServers has entry but manifestPaths is missing \u2014 invariant violated, both maps must be written together`
24262
24369
  );
24263
24370
  }
24264
- const priorSha = createHash5("sha256").update(readFileSync38(priorPath)).digest("hex").slice(0, 8);
24371
+ const priorSha = createHash5("sha256").update(readFileSync39(priorPath)).digest("hex").slice(0, 8);
24265
24372
  const newSha = createHash5("sha256").update(raw).digest("hex").slice(0, 8);
24266
24373
  throw new ToolSurfaceError(
24267
24374
  "mcp-plugin-duplicate",
@@ -24284,15 +24391,15 @@ function loadToolSurface(pluginsRoots) {
24284
24391
  }
24285
24392
  };
24286
24393
  for (const root of roots) {
24287
- const entries2 = readdirSync23(root).sort();
24394
+ const entries2 = readdirSync24(root).sort();
24288
24395
  for (const plugin of entries2) {
24289
- const pluginDir = join48(root, plugin);
24396
+ const pluginDir = join49(root, plugin);
24290
24397
  loadOne(root, plugin);
24291
- const subRoot = join48(pluginDir, "plugins");
24398
+ const subRoot = join49(pluginDir, "plugins");
24292
24399
  let subEntries;
24293
24400
  try {
24294
- if (!statSync24(subRoot).isDirectory()) continue;
24295
- subEntries = readdirSync23(subRoot).sort();
24401
+ if (!statSync25(subRoot).isDirectory()) continue;
24402
+ subEntries = readdirSync24(subRoot).sort();
24296
24403
  } catch {
24297
24404
  continue;
24298
24405
  }
@@ -24424,7 +24531,7 @@ var SLUG_UNSAFE = (s) => s.includes("/") || s.includes("..") || s.includes("\\")
24424
24531
  function subdirs(dir) {
24425
24532
  if (!existsSync39(dir)) return [];
24426
24533
  try {
24427
- return readdirSync24(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
24534
+ return readdirSync25(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
24428
24535
  } catch {
24429
24536
  return [];
24430
24537
  }
@@ -24456,7 +24563,7 @@ function loadRiskSurface() {
24456
24563
  function readDisabledStoreStrict(accountDir) {
24457
24564
  const p = resolve28(accountDir, DISABLED_STORE);
24458
24565
  if (!existsSync39(p)) return /* @__PURE__ */ new Set();
24459
- const parsed = JSON.parse(readFileSync39(p, "utf-8"));
24566
+ const parsed = JSON.parse(readFileSync40(p, "utf-8"));
24460
24567
  if (!Array.isArray(parsed.disabled)) throw new Error("disabled is not an array");
24461
24568
  return new Set(parsed.disabled.filter((x) => typeof x === "string"));
24462
24569
  }
@@ -24476,7 +24583,7 @@ function authoredAgentFiles(accountDir) {
24476
24583
  const dir = resolve28(pluginsDir, plugin, "agents");
24477
24584
  if (!existsSync39(dir)) continue;
24478
24585
  try {
24479
- for (const entry3 of readdirSync24(dir)) {
24586
+ for (const entry3 of readdirSync25(dir)) {
24480
24587
  if (!entry3.endsWith(".md")) continue;
24481
24588
  const path = resolve28(dir, entry3);
24482
24589
  const paths = byName.get(entry3);
@@ -24497,7 +24604,7 @@ function shippedSourceDirs(accountDir) {
24497
24604
  ];
24498
24605
  }
24499
24606
  function readRowFields(path) {
24500
- const { fm } = splitFrontmatter(readFileSync39(path, "utf-8"));
24607
+ const { fm } = splitFrontmatter(readFileSync40(path, "utf-8"));
24501
24608
  return {
24502
24609
  name: fm.name ?? "",
24503
24610
  description: fm.description ?? "",
@@ -24530,9 +24637,9 @@ function compareToAuthored(candidatePath, authoredPaths, filename) {
24530
24637
  anyUnreadable = true;
24531
24638
  continue;
24532
24639
  }
24533
- const fields = divergentFields(candidate, authored);
24534
- if (fields.length === 0) return { verdict: "matched" };
24535
- firstDivergence ??= { authoredPath: path, fields };
24640
+ const fields2 = divergentFields(candidate, authored);
24641
+ if (fields2.length === 0) return { verdict: "matched" };
24642
+ firstDivergence ??= { authoredPath: path, fields: fields2 };
24536
24643
  }
24537
24644
  if (firstDivergence) return { verdict: "divergent", ...firstDivergence };
24538
24645
  if (anyUnreadable) return { verdict: "unreadable" };
@@ -24550,7 +24657,7 @@ function listShipped(accountDir, riskByTool, disabled, riskSurfaceFailed, author
24550
24657
  for (const dir of dirs) {
24551
24658
  if (!existsSync39(dir)) continue;
24552
24659
  try {
24553
- for (const entry3 of readdirSync24(dir)) if (entry3.endsWith(".md")) names.add(entry3);
24660
+ for (const entry3 of readdirSync25(dir)) if (entry3.endsWith(".md")) names.add(entry3);
24554
24661
  } catch (err) {
24555
24662
  console.error(`[admin/agents] op=list-shipped read-failed dir=${dir} error="${err}"`);
24556
24663
  }
@@ -24578,7 +24685,7 @@ function listShipped(accountDir, riskByTool, disabled, riskSurfaceFailed, author
24578
24685
  }
24579
24686
  }
24580
24687
  try {
24581
- const { fm } = splitFrontmatter(readFileSync39(resolve28(source, filename), "utf-8"));
24688
+ const { fm } = splitFrontmatter(readFileSync40(resolve28(source, filename), "utf-8"));
24582
24689
  if (!fm.name) {
24583
24690
  shippedSkipped++;
24584
24691
  console.error(`[admin/agents] op=list-shipped-skip file=${filename} reason=no-name`);
@@ -24640,14 +24747,14 @@ function listSpecialists(accountDir, riskByTool, riskSurfaceFailed) {
24640
24747
  if (!existsSync39(agentsDirP)) continue;
24641
24748
  let entries2;
24642
24749
  try {
24643
- entries2 = readdirSync24(agentsDirP, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
24750
+ entries2 = readdirSync25(agentsDirP, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
24644
24751
  } catch {
24645
24752
  continue;
24646
24753
  }
24647
24754
  for (const entry3 of entries2) {
24648
24755
  if (!entry3.isFile() || !entry3.name.endsWith(".md")) continue;
24649
24756
  try {
24650
- const { fm } = splitFrontmatter(readFileSync39(resolve28(agentsDirP, entry3.name), "utf-8"));
24757
+ const { fm } = splitFrontmatter(readFileSync40(resolve28(agentsDirP, entry3.name), "utf-8"));
24651
24758
  if (!fm.name) {
24652
24759
  specialistsSkipped++;
24653
24760
  console.error(`[admin/agents] op=list-specialist-skip plugin=${plugin} file=${entry3.name}`);
@@ -24709,14 +24816,14 @@ app22.get("/", requireAdminSession, (c) => {
24709
24816
  const agentsDir = resolve28(account.accountDir, "agents");
24710
24817
  if (existsSync39(agentsDir)) {
24711
24818
  try {
24712
- const entries2 = readdirSync24(agentsDir, { withFileTypes: true });
24819
+ const entries2 = readdirSync25(agentsDir, { withFileTypes: true });
24713
24820
  for (const entry3 of entries2.sort((a, b) => a.name.localeCompare(b.name))) {
24714
24821
  if (!entry3.isDirectory()) continue;
24715
24822
  if (entry3.name === "admin") continue;
24716
24823
  const configPath3 = resolve28(agentsDir, entry3.name, "config.json");
24717
24824
  if (!existsSync39(configPath3)) continue;
24718
24825
  try {
24719
- const config = JSON.parse(readFileSync39(configPath3, "utf-8"));
24826
+ const config = JSON.parse(readFileSync40(configPath3, "utf-8"));
24720
24827
  agents.push({
24721
24828
  slug: entry3.name,
24722
24829
  displayName: config.displayName ?? entry3.name,
@@ -24798,7 +24905,7 @@ app22.get("/:slug", requireAdminSession, (c) => {
24798
24905
  const dirs = shippedSourceDirs(account.accountDir);
24799
24906
  const source = dirs.find((d) => existsSync39(resolve28(d, `${slug}.md`)));
24800
24907
  if (!source) return c.json({ error: "Agent not found" }, 404);
24801
- const { fm, body } = splitFrontmatter(readFileSync39(resolve28(source, `${slug}.md`), "utf-8"));
24908
+ const { fm, body } = splitFrontmatter(readFileSync40(resolve28(source, `${slug}.md`), "utf-8"));
24802
24909
  const { riskByTool, failed: failed2 } = loadRiskSurface();
24803
24910
  const tools = parseToolsLine(fm.tools);
24804
24911
  const r = classify(tools, riskByTool, failed2 !== null);
@@ -24830,7 +24937,7 @@ app22.get("/:slug", requireAdminSession, (c) => {
24830
24937
  if (SLUG_UNSAFE(pluginParam)) return c.json({ error: "Invalid plugin" }, 400);
24831
24938
  const file = resolve28(account.accountDir, "plugins", pluginParam, "agents", `${slug}.md`);
24832
24939
  if (!existsSync39(file)) return c.json({ error: "Agent not found" }, 404);
24833
- const { fm, body } = splitFrontmatter(readFileSync39(file, "utf-8"));
24940
+ const { fm, body } = splitFrontmatter(readFileSync40(file, "utf-8"));
24834
24941
  const skills = subdirs(resolve28(account.accountDir, "plugins", pluginParam, "skills"));
24835
24942
  const { riskByTool, failed: failed2 } = loadRiskSurface();
24836
24943
  const tools = parseToolsLine(fm.tools);
@@ -24863,7 +24970,7 @@ app22.get("/:slug", requireAdminSession, (c) => {
24863
24970
  if (!existsSync39(configPath3)) return c.json({ error: "Agent not found" }, 404);
24864
24971
  let config;
24865
24972
  try {
24866
- config = JSON.parse(readFileSync39(configPath3, "utf-8"));
24973
+ config = JSON.parse(readFileSync40(configPath3, "utf-8"));
24867
24974
  } catch {
24868
24975
  console.error(`[admin/agents] op=detail slug=${slug} error="config.json parse failed"`);
24869
24976
  return c.json({ error: "Agent config unreadable" }, 500);
@@ -24874,7 +24981,7 @@ app22.get("/:slug", requireAdminSession, (c) => {
24874
24981
  const p = resolve28(agentDir, file);
24875
24982
  try {
24876
24983
  if (existsSync39(p)) {
24877
- docs[key2] = readFileSync39(p, "utf-8");
24984
+ docs[key2] = readFileSync40(p, "utf-8");
24878
24985
  present[key2] = true;
24879
24986
  } else {
24880
24987
  docs[key2] = "";
@@ -24936,9 +25043,9 @@ function reconcileAuthoredRoutingLine(accountDir, accountId, op, source) {
24936
25043
  const agentsMd = resolve28(accountDir, "agents", "admin", "AGENTS.md");
24937
25044
  if (!existsSync39(agentsMd) || !existsSync39(source)) return false;
24938
25045
  try {
24939
- const { fm } = splitFrontmatter(readFileSync39(source, "utf-8"));
25046
+ const { fm } = splitFrontmatter(readFileSync40(source, "utf-8"));
24940
25047
  if (!fm.name) return false;
24941
- const lines = readFileSync39(agentsMd, "utf-8").split("\n");
25048
+ const lines = readFileSync40(agentsMd, "utf-8").split("\n");
24942
25049
  const prefix = `- **specialists:${fm.name}**:`;
24943
25050
  const without = lines.filter((l) => !l.startsWith(prefix));
24944
25051
  const next = op === "disable" ? without : [...without, `${prefix} ${fm.description ?? ""}`.trimEnd()];
@@ -25516,21 +25623,21 @@ app23.post("/:id/resume", async (c) => {
25516
25623
  if (bridge.reason === "conversation-not-found") {
25517
25624
  return c.json({ error: "Conversation not found" }, 404);
25518
25625
  }
25519
- const tail = cacheKey.slice(0, 8);
25520
- console.error(`[session] middleware-reject status=401 code=session-not-registered reason="cookie-bridge-rejected:${bridge.reason}" path=${c.req.path} cacheKey=${tail}\u2026`);
25626
+ const tail2 = cacheKey.slice(0, 8);
25627
+ console.error(`[session] middleware-reject status=401 code=session-not-registered reason="cookie-bridge-rejected:${bridge.reason}" path=${c.req.path} cacheKey=${tail2}\u2026`);
25521
25628
  return c.json({ error: "Invalid or expired admin session", code: "session-not-registered" }, 401);
25522
25629
  }
25523
25630
  bridged = true;
25524
25631
  result = validateSession(cacheKey, "admin", signedSessionToken);
25525
25632
  if (!result.ok) {
25526
- const tail = cacheKey.slice(0, 8);
25527
- console.error(`[session] middleware-reject status=401 code=session-not-registered reason="post-bridge re-validate failed" path=${c.req.path} cacheKey=${tail}\u2026`);
25633
+ const tail2 = cacheKey.slice(0, 8);
25634
+ console.error(`[session] middleware-reject status=401 code=session-not-registered reason="post-bridge re-validate failed" path=${c.req.path} cacheKey=${tail2}\u2026`);
25528
25635
  return c.json({ error: "Invalid or expired admin session", code: "session-not-registered" }, 401);
25529
25636
  }
25530
25637
  } else {
25531
- const tail = cacheKey.slice(0, 8);
25638
+ const tail2 = cacheKey.slice(0, 8);
25532
25639
  const wireCode = result.reason === "agent-type-mismatch" ? "session-not-registered" : result.reason;
25533
- console.error(`[session] middleware-reject status=401 code=${wireCode} reason="invalid or expired admin session" path=${c.req.path} cacheKey=${tail}\u2026`);
25640
+ console.error(`[session] middleware-reject status=401 code=${wireCode} reason="invalid or expired admin session" path=${c.req.path} cacheKey=${tail2}\u2026`);
25534
25641
  return c.json({ error: "Invalid or expired admin session", code: wireCode }, 401);
25535
25642
  }
25536
25643
  }
@@ -25796,8 +25903,8 @@ app23.put("/:id/label", requireAdminSession, async (c) => {
25796
25903
  var sessions_default = app23;
25797
25904
 
25798
25905
  // app/lib/claude-agent/spawn-context.ts
25799
- import { existsSync as existsSync41, readFileSync as readFileSync40, readdirSync as readdirSync25, statSync as statSync25 } from "fs";
25800
- import { dirname as dirname15, resolve as resolve29, join as join49 } from "path";
25906
+ import { existsSync as existsSync41, readFileSync as readFileSync41, readdirSync as readdirSync26, statSync as statSync26 } from "fs";
25907
+ import { dirname as dirname15, resolve as resolve29, join as join50 } from "path";
25801
25908
  async function resolveOwnerProfileBlock(accountId, userId) {
25802
25909
  if (!userId) return { ok: false, reason: "missing-user-id" };
25803
25910
  try {
@@ -25838,14 +25945,14 @@ function frontmatterField(manifest, field2) {
25838
25945
  function extractPluginToolDescriptions(pluginDir) {
25839
25946
  const out = /* @__PURE__ */ new Map();
25840
25947
  const candidates = [
25841
- join49(pluginDir, "mcp/dist/index.js"),
25842
- join49(pluginDir, "mcp/src/index.ts")
25948
+ join50(pluginDir, "mcp/dist/index.js"),
25949
+ join50(pluginDir, "mcp/src/index.ts")
25843
25950
  ];
25844
25951
  let raw = null;
25845
25952
  for (const path of candidates) {
25846
25953
  if (!existsSync41(path)) continue;
25847
25954
  try {
25848
- raw = readFileSync40(path, "utf-8");
25955
+ raw = readFileSync41(path, "utf-8");
25849
25956
  break;
25850
25957
  } catch {
25851
25958
  }
@@ -25896,24 +26003,24 @@ function listPluginDirs(accountPluginsDir) {
25896
26003
  const out = /* @__PURE__ */ new Map();
25897
26004
  const platformPlugins = resolve29(PLATFORM_ROOT, "plugins");
25898
26005
  if (existsSync41(platformPlugins)) {
25899
- for (const name of readdirSync25(platformPlugins)) {
25900
- const dir = join49(platformPlugins, name);
26006
+ for (const name of readdirSync26(platformPlugins)) {
26007
+ const dir = join50(platformPlugins, name);
25901
26008
  try {
25902
- if (statSync25(dir).isDirectory()) out.set(name, dir);
26009
+ if (statSync26(dir).isDirectory()) out.set(name, dir);
25903
26010
  } catch {
25904
26011
  }
25905
26012
  }
25906
26013
  }
25907
26014
  const premiumRoot = resolve29(dirname15(PLATFORM_ROOT), "premium-plugins");
25908
26015
  if (existsSync41(premiumRoot)) {
25909
- for (const bundle of readdirSync25(premiumRoot)) {
25910
- const bundlePlugins = join49(premiumRoot, bundle, "plugins");
26016
+ for (const bundle of readdirSync26(premiumRoot)) {
26017
+ const bundlePlugins = join50(premiumRoot, bundle, "plugins");
25911
26018
  if (!existsSync41(bundlePlugins)) continue;
25912
26019
  try {
25913
- for (const name of readdirSync25(bundlePlugins)) {
25914
- const dir = join49(bundlePlugins, name);
26020
+ for (const name of readdirSync26(bundlePlugins)) {
26021
+ const dir = join50(bundlePlugins, name);
25915
26022
  try {
25916
- if (statSync25(dir).isDirectory()) out.set(name, dir);
26023
+ if (statSync26(dir).isDirectory()) out.set(name, dir);
25917
26024
  } catch {
25918
26025
  }
25919
26026
  }
@@ -25923,11 +26030,11 @@ function listPluginDirs(accountPluginsDir) {
25923
26030
  }
25924
26031
  if (accountPluginsDir && existsSync41(accountPluginsDir)) {
25925
26032
  try {
25926
- for (const name of readdirSync25(accountPluginsDir)) {
26033
+ for (const name of readdirSync26(accountPluginsDir)) {
25927
26034
  if (out.has(name)) continue;
25928
- const dir = join49(accountPluginsDir, name);
26035
+ const dir = join50(accountPluginsDir, name);
25929
26036
  try {
25930
- if (statSync25(dir).isDirectory()) out.set(name, dir);
26037
+ if (statSync26(dir).isDirectory()) out.set(name, dir);
25931
26038
  } catch {
25932
26039
  }
25933
26040
  }
@@ -25942,9 +26049,9 @@ function accountPluginsDirFor(accountId) {
25942
26049
  function listAccountPluginNames(accountPluginsDir) {
25943
26050
  if (!existsSync41(accountPluginsDir)) return [];
25944
26051
  try {
25945
- return readdirSync25(accountPluginsDir).filter((name) => {
26052
+ return readdirSync26(accountPluginsDir).filter((name) => {
25946
26053
  try {
25947
- return statSync25(join49(accountPluginsDir, name)).isDirectory();
26054
+ return statSync26(join50(accountPluginsDir, name)).isDirectory();
25948
26055
  } catch {
25949
26056
  return false;
25950
26057
  }
@@ -25957,7 +26064,7 @@ function readEnabledPlugins(accountId) {
25957
26064
  const accountFile = resolve29(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
25958
26065
  if (!existsSync41(accountFile)) return /* @__PURE__ */ new Set();
25959
26066
  try {
25960
- const parsed = JSON.parse(readFileSync40(accountFile, "utf-8"));
26067
+ const parsed = JSON.parse(readFileSync41(accountFile, "utf-8"));
25961
26068
  return new Set(
25962
26069
  Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : []
25963
26070
  );
@@ -25969,7 +26076,7 @@ function readFrontmatter(path) {
25969
26076
  if (!existsSync41(path)) return null;
25970
26077
  let raw;
25971
26078
  try {
25972
- raw = readFileSync40(path, "utf-8");
26079
+ raw = readFileSync41(path, "utf-8");
25973
26080
  } catch {
25974
26081
  return null;
25975
26082
  }
@@ -25987,7 +26094,7 @@ function computeActivePlugins(accountId) {
25987
26094
  for (const name of emitNames) {
25988
26095
  const dir = pluginDirs.get(name);
25989
26096
  if (!dir) continue;
25990
- const fm = readFrontmatter(join49(dir, "PLUGIN.md"));
26097
+ const fm = readFrontmatter(join50(dir, "PLUGIN.md"));
25991
26098
  if (!fm) continue;
25992
26099
  const description = frontmatterField(`---
25993
26100
  ${fm}
@@ -26004,7 +26111,7 @@ ${fm}
26004
26111
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
26005
26112
  );
26006
26113
  if (toolNames.length > 0 && descMap.size === 0) {
26007
- const hasSource = existsSync41(join49(dir, "mcp/dist/index.js")) || existsSync41(join49(dir, "mcp/src/index.ts"));
26114
+ const hasSource = existsSync41(join50(dir, "mcp/dist/index.js")) || existsSync41(join50(dir, "mcp/src/index.ts"));
26008
26115
  if (hasSource) {
26009
26116
  console.warn(
26010
26117
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -26014,7 +26121,7 @@ ${fm}
26014
26121
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
26015
26122
  const skills = [];
26016
26123
  for (const relPath of skillPaths) {
26017
- const skillPath = join49(dir, relPath);
26124
+ const skillPath = join50(dir, relPath);
26018
26125
  const skillFm = readFrontmatter(skillPath);
26019
26126
  if (!skillFm) continue;
26020
26127
  const skillName = frontmatterField(`---
@@ -26034,7 +26141,7 @@ function computeSpecialistDomains(accountId) {
26034
26141
  if (!existsSync41(specialistsDir)) return [];
26035
26142
  let entries2;
26036
26143
  try {
26037
- entries2 = readdirSync25(specialistsDir);
26144
+ entries2 = readdirSync26(specialistsDir);
26038
26145
  } catch {
26039
26146
  return [];
26040
26147
  }
@@ -26058,7 +26165,7 @@ function computeSpecialistDomains(accountId) {
26058
26165
  const out = [];
26059
26166
  for (const file of entries2.sort()) {
26060
26167
  if (!file.endsWith(".md")) continue;
26061
- const fm = readFrontmatter(join49(specialistsDir, file));
26168
+ const fm = readFrontmatter(join50(specialistsDir, file));
26062
26169
  if (!fm) continue;
26063
26170
  const wrapped = `---
26064
26171
  ${fm}
@@ -26080,7 +26187,7 @@ function computeDormantPlugins(accountId) {
26080
26187
  if (!existsSync41(accountFile)) return [];
26081
26188
  let enabled;
26082
26189
  try {
26083
- const raw = readFileSync40(accountFile, "utf-8");
26190
+ const raw = readFileSync41(accountFile, "utf-8");
26084
26191
  const parsed = JSON.parse(raw);
26085
26192
  enabled = new Set(
26086
26193
  Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : []
@@ -26095,7 +26202,7 @@ function computeDormantPlugins(accountId) {
26095
26202
  if (!existsSync41(pluginsDir)) return [];
26096
26203
  let entries2;
26097
26204
  try {
26098
- entries2 = readdirSync25(pluginsDir);
26205
+ entries2 = readdirSync26(pluginsDir);
26099
26206
  } catch {
26100
26207
  return [];
26101
26208
  }
@@ -26106,7 +26213,7 @@ function computeDormantPlugins(accountId) {
26106
26213
  if (!existsSync41(manifestPath)) continue;
26107
26214
  let manifest;
26108
26215
  try {
26109
- manifest = readFileSync40(manifestPath, "utf-8");
26216
+ manifest = readFileSync41(manifestPath, "utf-8");
26110
26217
  } catch {
26111
26218
  continue;
26112
26219
  }
@@ -26120,13 +26227,13 @@ function computeDormantPlugins(accountId) {
26120
26227
  }
26121
26228
 
26122
26229
  // server/routes/admin/claude-sessions.ts
26123
- import { existsSync as existsSync42, readFileSync as readFileSync41 } from "fs";
26230
+ import { existsSync as existsSync42, readFileSync as readFileSync42 } from "fs";
26124
26231
  import { resolve as resolve30 } from "path";
26125
26232
  function readTunnelState(brandConfigDir) {
26126
26233
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
26127
26234
  if (!existsSync42(statePath)) return null;
26128
26235
  try {
26129
- const parsed = JSON.parse(readFileSync41(statePath, "utf-8"));
26236
+ const parsed = JSON.parse(readFileSync42(statePath, "utf-8"));
26130
26237
  const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
26131
26238
  const tunnelName = typeof parsed.tunnelName === "string" ? parsed.tunnelName : null;
26132
26239
  const domain = typeof parsed.domain === "string" ? parsed.domain : null;
@@ -26140,7 +26247,7 @@ function resolveTunnelUrl() {
26140
26247
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve30(process.cwd(), "..");
26141
26248
  let brand;
26142
26249
  try {
26143
- brand = JSON.parse(readFileSync41(resolve30(platformRoot5, "config", "brand.json"), "utf-8"));
26250
+ brand = JSON.parse(readFileSync42(resolve30(platformRoot5, "config", "brand.json"), "utf-8"));
26144
26251
  } catch {
26145
26252
  return null;
26146
26253
  }
@@ -26341,7 +26448,7 @@ app25.post("/", async (c) => {
26341
26448
  var log_ingest_default = app25;
26342
26449
 
26343
26450
  // server/routes/admin/session-blocked.ts
26344
- import { join as join50 } from "path";
26451
+ import { join as join51 } from "path";
26345
26452
  var TAG44 = "[blocked-tool-notify]";
26346
26453
  function isLoopbackAddr4(addr) {
26347
26454
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
@@ -26388,7 +26495,7 @@ app26.post("/", async (c) => {
26388
26495
  if (!tool) return c.json({ error: "tool-required" }, 400);
26389
26496
  const text = blockedNotificationText({ sessionId, agentId, tool, blockedForMs });
26390
26497
  const projectDir = findSessionProjectDir(sessionId);
26391
- const meta = projectDir ? readSidecarMeta(join50(projectDir, `${sessionId}.meta.json`)) : { role: null, channel: null, senderId: null, accountId: null };
26498
+ const meta = projectDir ? readSidecarMeta(join51(projectDir, `${sessionId}.meta.json`)) : { role: null, channel: null, senderId: null, accountId: null };
26392
26499
  const account = validateAccountId2(meta.accountId ?? "");
26393
26500
  if (!account) {
26394
26501
  console.error(
@@ -26587,7 +26694,7 @@ import { createReadStream as createReadStream2, createWriteStream as createWrite
26587
26694
  import { readdir as readdir4, readFile as readFile10, stat as stat6, mkdir as mkdir2, unlink as unlink3, rename as rename3, rmdir } from "fs/promises";
26588
26695
  import { realpathSync as realpathSync7 } from "fs";
26589
26696
  import { randomUUID as randomUUID7 } from "crypto";
26590
- import { basename as basename15, dirname as dirname16, join as join52, relative as relative6, resolve as resolve32, sep as sep9 } from "path";
26697
+ import { basename as basename15, dirname as dirname16, join as join53, relative as relative6, resolve as resolve32, sep as sep9 } from "path";
26591
26698
  import { Readable as Readable2 } from "stream";
26592
26699
 
26593
26700
  // ../lib/graph-trash/src/index.ts
@@ -26905,7 +27012,7 @@ async function cascadeDeleteDocument(params) {
26905
27012
 
26906
27013
  // app/lib/file-index.ts
26907
27014
  import * as fsp from "fs/promises";
26908
- import { resolve as resolve31, relative as relative5, join as join51, basename as basename14, extname, sep as sep8 } from "path";
27015
+ import { resolve as resolve31, relative as relative5, join as join52, basename as basename14, extname, sep as sep8 } from "path";
26909
27016
  import { tmpdir as tmpdir3 } from "os";
26910
27017
  import { execFile } from "child_process";
26911
27018
  import { promisify } from "util";
@@ -26987,7 +27094,7 @@ async function extractPdf(absolute) {
26987
27094
  return stdout.trim();
26988
27095
  }
26989
27096
  async function ocrPdf(absolute) {
26990
- const outPdf = join51(tmpdir3(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
27097
+ const outPdf = join52(tmpdir3(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
26991
27098
  try {
26992
27099
  await execFileAsync(
26993
27100
  "ocrmypdf",
@@ -27049,7 +27156,7 @@ async function readDisplayName(absolute) {
27049
27156
  const stem = dot === -1 ? base : base.slice(0, dot);
27050
27157
  if (base === `${stem}.meta.json`) return null;
27051
27158
  try {
27052
- const raw = await fsp.readFile(join51(dir, `${stem}.meta.json`), "utf-8");
27159
+ const raw = await fsp.readFile(join52(dir, `${stem}.meta.json`), "utf-8");
27053
27160
  const meta = JSON.parse(raw);
27054
27161
  const dn = meta.displayName ?? meta.filename;
27055
27162
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -27070,7 +27177,7 @@ async function walkSubtree(root, dataRoot, out) {
27070
27177
  for (const entry3 of entries2) {
27071
27178
  if (entry3.isSymbolicLink()) continue;
27072
27179
  if (entry3.isDirectory() && entry3.name === ".uploads-tmp") continue;
27073
- const abs = join51(root, entry3.name);
27180
+ const abs = join52(root, entry3.name);
27074
27181
  if (entry3.isDirectory()) {
27075
27182
  const sub = await walkSubtree(abs, dataRoot, out);
27076
27183
  if (!sub.clean) clean = false;
@@ -27443,7 +27550,7 @@ var UPLOAD_TMP_DIR = ".uploads-tmp";
27443
27550
  var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
27444
27551
  async function readMeta2(absDir, baseName) {
27445
27552
  try {
27446
- const raw = await readFile10(join52(absDir, `${baseName}.meta.json`), "utf8");
27553
+ const raw = await readFile10(join53(absDir, `${baseName}.meta.json`), "utf8");
27447
27554
  const parsed = JSON.parse(raw);
27448
27555
  if (typeof parsed?.filename === "string") {
27449
27556
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -27498,7 +27605,7 @@ async function servableFilesIn(dirAbs, uuid) {
27498
27605
  }
27499
27606
  async function enrich(absolute, entry3, accountNames) {
27500
27607
  if (entry3.kind === "directory" && UUID_RE3.test(entry3.name)) {
27501
- const dirAbs = join52(absolute, entry3.name);
27608
+ const dirAbs = join53(absolute, entry3.name);
27502
27609
  const meta = await readMeta2(dirAbs, entry3.name);
27503
27610
  if (meta?.filename) {
27504
27611
  const servable = await servableFilesIn(dirAbs, entry3.name);
@@ -27507,7 +27614,7 @@ async function enrich(absolute, entry3, accountNames) {
27507
27614
  let size = null;
27508
27615
  let modifiedAt = entry3.modifiedAt;
27509
27616
  try {
27510
- const st = await stat6(join52(dirAbs, innerName));
27617
+ const st = await stat6(join53(dirAbs, innerName));
27511
27618
  size = st.size;
27512
27619
  modifiedAt = st.mtime.toISOString();
27513
27620
  } catch {
@@ -27719,7 +27826,7 @@ app28.get("/", requireAdminSession, async (c) => {
27719
27826
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
27720
27827
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
27721
27828
  try {
27722
- const entryPath = join52(absolute, name);
27829
+ const entryPath = join53(absolute, name);
27723
27830
  const s = await stat6(entryPath);
27724
27831
  entries2.push({
27725
27832
  name,
@@ -27748,7 +27855,7 @@ app28.get("/", requireAdminSession, async (c) => {
27748
27855
  const displayPath = buildDisplayPath(relPath, accountNames);
27749
27856
  if (groupReq || isAccountRoot(relPath)) {
27750
27857
  const acctId = relPath.split("/")[1] ?? accountId;
27751
- const schemaMd = await readFile10(join52(absolute, "SCHEMA.md"), "utf8").catch(() => null);
27858
+ const schemaMd = await readFile10(join53(absolute, "SCHEMA.md"), "utf8").catch(() => null);
27752
27859
  const groups = classifyAccountRoot(schemaMd, entries2.map((e) => e.name));
27753
27860
  console.error(
27754
27861
  `[data-schema] op=classify account=${acctId} status=${groups.parsed ? "ok" : "parse-failed"} reason=${groups.reason} entries=${entries2.length} home=${groups.home.join(",") || "none"} system=${groups.system.length} unknown=${groups.unknown.join(",") || "none"}`
@@ -27786,7 +27893,7 @@ app28.get("/", requireAdminSession, async (c) => {
27786
27893
  for (const name of homeDirs) {
27787
27894
  const base = byName.get(name);
27788
27895
  try {
27789
- const dirents = await readdir4(join52(absolute, name), { withFileTypes: true });
27896
+ const dirents = await readdir4(join53(absolute, name), { withFileTypes: true });
27790
27897
  const visible = dirents.filter((d) => !d.name.startsWith("."));
27791
27898
  visible.sort((a, b) => {
27792
27899
  const ad = a.isDirectory() ? 0 : 1;
@@ -27851,7 +27958,7 @@ app28.get("/download", requireAdminSession, async (c) => {
27851
27958
  console.error(`[data] op=scratchpad-no-session sessionId="${sessionId.slice(0, 8)}\u2026"`);
27852
27959
  return c.json({ error: "Not found" }, 404);
27853
27960
  }
27854
- const meta = readSidecarMeta(join52(projectDir, `${sessionId}.meta.json`));
27961
+ const meta = readSidecarMeta(join53(projectDir, `${sessionId}.meta.json`));
27855
27962
  if (!meta.accountId || meta.accountId !== accountId) {
27856
27963
  console.error(`[data] account-scope-blocked root="scratchpad" sessionId="${sessionId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
27857
27964
  return c.json({ error: "Not found" }, 404);
@@ -27945,7 +28052,7 @@ async function* walkRegularFiles(dirAbsolute) {
27945
28052
  const dirents = await readdir4(dirAbsolute, { withFileTypes: true });
27946
28053
  for (const d of dirents) {
27947
28054
  if (d.isSymbolicLink()) continue;
27948
- const child = join52(dirAbsolute, d.name);
28055
+ const child = join53(dirAbsolute, d.name);
27949
28056
  if (d.isDirectory()) {
27950
28057
  yield* walkRegularFiles(child);
27951
28058
  continue;
@@ -28051,7 +28158,7 @@ async function resolveUploadTarget(c, accountId, uid) {
28051
28158
  const base = resolveSharedOrOwnAccountWrite(rawDir, accountId, "POST /api/admin/files/upload");
28052
28159
  if (!base.ok) return { ok: false, status: base.status, error: base.error };
28053
28160
  const relDir = relpath ? dirname16(relpath) : ".";
28054
- const destRel = relDir === "." ? base.relative : join52(base.relative, relDir);
28161
+ const destRel = relDir === "." ? base.relative : join53(base.relative, relDir);
28055
28162
  if ((0, import_dist.isSharedPath)(destRel)) {
28056
28163
  const gate2 = gateSharedWrite(base.absolute, destRel, accountId, "POST /api/admin/files/upload");
28057
28164
  if (!gate2.ok) return { ok: false, status: gate2.status, error: gate2.error };
@@ -28437,7 +28544,7 @@ app28.delete("/", requireAdminSession, async (c) => {
28437
28544
  const dot = base.lastIndexOf(".");
28438
28545
  const stem = dot === -1 ? base : base.slice(0, dot);
28439
28546
  const containerDir = dirname16(absolute);
28440
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join52(containerDir, `${stem}.meta.json`) : null;
28547
+ const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join53(containerDir, `${stem}.meta.json`) : null;
28441
28548
  const isAttachmentContainer = UUID_RE3.test(stem) && basename15(containerDir) === stem;
28442
28549
  await unlink3(absolute);
28443
28550
  if (sidecarPath) {
@@ -28447,7 +28554,7 @@ app28.delete("/", requireAdminSession, async (c) => {
28447
28554
  }
28448
28555
  }
28449
28556
  if (isAttachmentContainer) {
28450
- await unlink3(join52(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
28557
+ await unlink3(join53(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
28451
28558
  });
28452
28559
  await rmdir(containerDir).catch(() => {
28453
28560
  });
@@ -29562,8 +29669,8 @@ function isHiddenByDefault(label) {
29562
29669
 
29563
29670
  // server/lib/top-level-labels.ts
29564
29671
  var import_dist14 = __toESM(require_dist9(), 1);
29565
- import { readdirSync as readdirSync26, readFileSync as readFileSync42 } from "fs";
29566
- import { join as join53, resolve as resolve33 } from "path";
29672
+ import { readdirSync as readdirSync27, readFileSync as readFileSync43 } from "fs";
29673
+ import { join as join54, resolve as resolve33 } from "path";
29567
29674
  var STATIC_TOP_LEVEL_LABELS = Object.freeze(
29568
29675
  /* @__PURE__ */ new Set([
29569
29676
  // Base-schema infra (schema-base.md has no top-level section).
@@ -29667,7 +29774,7 @@ function parseTopLevelLabels(content) {
29667
29774
  }
29668
29775
  function resolveReferencesDir() {
29669
29776
  if (process.env.MAXY_PLATFORM_ROOT) {
29670
- return join53(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
29777
+ return join54(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
29671
29778
  }
29672
29779
  return resolve33(import.meta.dirname, "../../../plugins/memory/references");
29673
29780
  }
@@ -29675,9 +29782,9 @@ function parseTableTopLevelLabels(referencesDir) {
29675
29782
  const labels = /* @__PURE__ */ new Set();
29676
29783
  const contributingFiles = [];
29677
29784
  try {
29678
- const fileNames = readdirSync26(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
29785
+ const fileNames = readdirSync27(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
29679
29786
  for (const fileName of fileNames) {
29680
- const content = readFileSync42(join53(referencesDir, fileName), "utf-8");
29787
+ const content = readFileSync43(join54(referencesDir, fileName), "utf-8");
29681
29788
  const parsed = parseTopLevelLabels(content);
29682
29789
  if (parsed.length > 0) contributingFiles.push(fileName);
29683
29790
  for (const label of parsed) labels.add(label);
@@ -31015,19 +31122,19 @@ function isWithin(target, root) {
31015
31122
  var sidebar_artefacts_default = app35;
31016
31123
 
31017
31124
  // server/channel-session-override.ts
31018
- import { readFileSync as readFileSync43, writeFileSync as writeFileSync19, renameSync as renameSync10 } from "fs";
31019
- import { join as join54 } from "path";
31125
+ import { readFileSync as readFileSync44, writeFileSync as writeFileSync19, renameSync as renameSync10 } from "fs";
31126
+ import { join as join55 } from "path";
31020
31127
  var FILE2 = "channel-session-override.json";
31021
31128
  var UUID3 = /^[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}$/;
31022
31129
  function channelOverridePath(accountDir) {
31023
- return join54(accountDir, FILE2);
31130
+ return join55(accountDir, FILE2);
31024
31131
  }
31025
31132
  function senderKey(channel, senderId) {
31026
31133
  return `${channel}:${senderId}`;
31027
31134
  }
31028
31135
  function readRaw2(accountDir) {
31029
31136
  try {
31030
- return JSON.parse(readFileSync43(channelOverridePath(accountDir), "utf8"));
31137
+ return JSON.parse(readFileSync44(channelOverridePath(accountDir), "utf8"));
31031
31138
  } catch {
31032
31139
  return null;
31033
31140
  }
@@ -31465,24 +31572,24 @@ var session_rc_spawn_default = app41;
31465
31572
  import { randomUUID as randomUUID9 } from "crypto";
31466
31573
 
31467
31574
  // server/wa-descriptor.ts
31468
- import { resolve as resolve35, join as join55 } from "path";
31575
+ import { resolve as resolve35, join as join56 } from "path";
31469
31576
  function waGatewayUrl() {
31470
31577
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
31471
31578
  }
31472
31579
  function waServerPath() {
31473
- return process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve35(process.env.MAXY_PLATFORM_ROOT ?? join55(__dirname, ".."), "services/whatsapp-channel/dist/server.js");
31580
+ return process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve35(process.env.MAXY_PLATFORM_ROOT ?? join56(__dirname, ".."), "services/whatsapp-channel/dist/server.js");
31474
31581
  }
31475
31582
  function waChannelDescriptor(senderId) {
31476
31583
  return { senderId, gatewayUrl: waGatewayUrl(), serverPath: waServerPath() };
31477
31584
  }
31478
31585
 
31479
31586
  // server/telegram-descriptor.ts
31480
- import { resolve as resolve36, join as join56 } from "path";
31587
+ import { resolve as resolve36, join as join57 } from "path";
31481
31588
  function telegramGatewayUrl() {
31482
31589
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
31483
31590
  }
31484
31591
  function telegramServerPath() {
31485
- return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve36(process.env.MAXY_PLATFORM_ROOT ?? join56(__dirname, ".."), "services/telegram-channel/dist/server.js");
31592
+ return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve36(process.env.MAXY_PLATFORM_ROOT ?? join57(__dirname, ".."), "services/telegram-channel/dist/server.js");
31486
31593
  }
31487
31594
  function telegramChannelDescriptor(senderId) {
31488
31595
  return { senderId, gatewayUrl: telegramGatewayUrl(), serverPath: telegramServerPath() };
@@ -31653,12 +31760,12 @@ function parseCpuStat(blob) {
31653
31760
  const line = blob.split("\n", 1)[0] ?? "";
31654
31761
  const parts = line.trim().split(/\s+/);
31655
31762
  if (parts[0] !== "cpu") throw new Error(`unexpected /proc/stat header: ${parts[0] ?? "(empty)"}`);
31656
- const fields = parts.slice(1).map((n) => Number.parseInt(n, 10));
31657
- if (fields.length < 4 || fields.some((n) => !Number.isFinite(n))) {
31763
+ const fields2 = parts.slice(1).map((n) => Number.parseInt(n, 10));
31764
+ if (fields2.length < 4 || fields2.some((n) => !Number.isFinite(n))) {
31658
31765
  throw new Error("malformed /proc/stat cpu line");
31659
31766
  }
31660
- const idle = fields[3] + (fields[4] ?? 0);
31661
- const total = fields.reduce((a, b) => a + b, 0);
31767
+ const idle = fields2[3] + (fields2[4] ?? 0);
31768
+ const total = fields2.reduce((a, b) => a + b, 0);
31662
31769
  return { idle, total };
31663
31770
  }
31664
31771
  function cpuPctFromSamples(a, b) {
@@ -31768,14 +31875,14 @@ app43.get("/", async (c) => {
31768
31875
  var system_stats_default = app43;
31769
31876
 
31770
31877
  // server/routes/admin/health.ts
31771
- import { existsSync as existsSync45, readFileSync as readFileSync44 } from "fs";
31772
- import { resolve as resolve37, join as join57 } from "path";
31878
+ import { existsSync as existsSync45, readFileSync as readFileSync45 } from "fs";
31879
+ import { resolve as resolve37, join as join58 } from "path";
31773
31880
  var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT ?? resolve37(process.cwd(), "..");
31774
31881
  var brandHostname = "maxy";
31775
- var brandJsonPath = join57(PLATFORM_ROOT4, "config", "brand.json");
31882
+ var brandJsonPath = join58(PLATFORM_ROOT4, "config", "brand.json");
31776
31883
  if (existsSync45(brandJsonPath)) {
31777
31884
  try {
31778
- const brand = JSON.parse(readFileSync44(brandJsonPath, "utf-8"));
31885
+ const brand = JSON.parse(readFileSync45(brandJsonPath, "utf-8"));
31779
31886
  if (brand.hostname) brandHostname = brand.hostname;
31780
31887
  } catch {
31781
31888
  }
@@ -31785,7 +31892,7 @@ var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
31785
31892
  var PROBE_TIMEOUT_MS = 1e3;
31786
31893
  function readVersion() {
31787
31894
  if (!existsSync45(VERSION_FILE)) return "unknown";
31788
- return readFileSync44(VERSION_FILE, "utf-8").trim() || "unknown";
31895
+ return readFileSync45(VERSION_FILE, "utf-8").trim() || "unknown";
31789
31896
  }
31790
31897
  async function probeConversationDb() {
31791
31898
  let session;
@@ -31840,7 +31947,7 @@ import { randomUUID as randomUUID10 } from "crypto";
31840
31947
 
31841
31948
  // ../lib/account-ingest-token/src/index.ts
31842
31949
  import { randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "crypto";
31843
- import { existsSync as existsSync46, readdirSync as readdirSync27, readFileSync as readFileSync45, writeFileSync as writeFileSync20 } from "fs";
31950
+ import { existsSync as existsSync46, readdirSync as readdirSync28, readFileSync as readFileSync46, writeFileSync as writeFileSync20 } from "fs";
31844
31951
  import { resolve as resolve38 } from "path";
31845
31952
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
31846
31953
  var INGEST_TOKEN_FIELD = "ingestToken";
@@ -31852,7 +31959,7 @@ function readConfig2(accountsDir, accountId) {
31852
31959
  const path = configPath2(accountsDir, accountId);
31853
31960
  if (!existsSync46(path)) return null;
31854
31961
  try {
31855
- const parsed = JSON.parse(readFileSync45(path, "utf-8"));
31962
+ const parsed = JSON.parse(readFileSync46(path, "utf-8"));
31856
31963
  return parsed !== null && typeof parsed === "object" ? parsed : null;
31857
31964
  } catch {
31858
31965
  return null;
@@ -31866,7 +31973,7 @@ function listAccountIdsOnDisk(accountsDir) {
31866
31973
  if (!existsSync46(accountsDir)) return [];
31867
31974
  let entries2;
31868
31975
  try {
31869
- entries2 = readdirSync27(accountsDir);
31976
+ entries2 = readdirSync28(accountsDir);
31870
31977
  } catch {
31871
31978
  return [];
31872
31979
  }
@@ -32393,9 +32500,9 @@ function renderWrite(write) {
32393
32500
  const val = String(v).slice(0, 200);
32394
32501
  kv.push(`${k}=${val}`);
32395
32502
  }
32396
- const tail = [parts.join(" "), kv.join("; ")].filter((s) => s.length > 0).join(" \u2014 ");
32397
- if (tail.length === 0) return null;
32398
- return `- ${label}: ${tail}`;
32503
+ const tail2 = [parts.join(" "), kv.join("; ")].filter((s) => s.length > 0).join(" \u2014 ");
32504
+ if (tail2.length === 0) return null;
32505
+ return `- ${label}: ${tail2}`;
32399
32506
  }
32400
32507
  function formatPreviousContext(writes) {
32401
32508
  if (writes.length === 0) return null;
@@ -32705,7 +32812,7 @@ var browser_default = app51;
32705
32812
  // server/routes/admin/calendar.ts
32706
32813
  import { existsSync as existsSync47 } from "fs";
32707
32814
  import { randomUUID as randomUUID11 } from "crypto";
32708
- import { join as join59 } from "path";
32815
+ import { join as join60 } from "path";
32709
32816
 
32710
32817
  // server/lib/calendar-ics.ts
32711
32818
  var CRLF = "\r\n";
@@ -32805,8 +32912,8 @@ function countVEvents(ics) {
32805
32912
  }
32806
32913
 
32807
32914
  // server/lib/calendar-availability.ts
32808
- import { readFileSync as readFileSync46 } from "fs";
32809
- import { join as join58 } from "path";
32915
+ import { readFileSync as readFileSync47 } from "fs";
32916
+ import { join as join59 } from "path";
32810
32917
  var AVAILABILITY_FILENAME = "calendar-availability.json";
32811
32918
  var REQUIRED_KEYS = [
32812
32919
  "timezone",
@@ -32815,10 +32922,10 @@ var REQUIRED_KEYS = [
32815
32922
  "weekly"
32816
32923
  ];
32817
32924
  function readAvailabilityConfig(accountDir) {
32818
- const path = join58(accountDir, AVAILABILITY_FILENAME);
32925
+ const path = join59(accountDir, AVAILABILITY_FILENAME);
32819
32926
  let raw;
32820
32927
  try {
32821
- raw = readFileSync46(path, "utf-8");
32928
+ raw = readFileSync47(path, "utf-8");
32822
32929
  } catch {
32823
32930
  throw new Error(`availability not configured: ${path} not found`);
32824
32931
  }
@@ -33204,16 +33311,16 @@ app52.patch("/meetings/:id", requireAdminSession, async (c) => {
33204
33311
  }
33205
33312
  const id = c.req.param("id");
33206
33313
  const body = await safeJson(c) ?? {};
33207
- const fields = EDITABLE_FIELDS.filter((f) => f in body);
33208
- if (fields.length === 0) {
33314
+ const fields2 = EDITABLE_FIELDS.filter((f) => f in body);
33315
+ if (fields2.length === 0) {
33209
33316
  return c.json({ error: "No editable field supplied (title, startsAt, endsAt, location, description, privateNote)" }, 400);
33210
33317
  }
33211
- const setClauses = fields.map(
33318
+ const setClauses = fields2.map(
33212
33319
  (f) => f === "startsAt" || f === "endsAt" ? `m.${f} = datetime($${f})` : `m.${f} = $${f}`
33213
33320
  );
33214
33321
  setClauses.push("m.updatedAt = datetime()");
33215
33322
  const params = { accountId, id };
33216
- for (const f of fields) params[f] = body[f];
33323
+ for (const f of fields2) params[f] = body[f];
33217
33324
  const session = getSession();
33218
33325
  try {
33219
33326
  const res = await session.run(
@@ -33224,12 +33331,12 @@ app52.patch("/meetings/:id", requireAdminSession, async (c) => {
33224
33331
  params
33225
33332
  );
33226
33333
  if (res.records.length === 0) {
33227
- console.warn(`[calendar-edit] account=${accountId.slice(0, 8)} uid=absent fields=${fields.join(",")} found=0`);
33334
+ console.warn(`[calendar-edit] account=${accountId.slice(0, 8)} uid=absent fields=${fields2.join(",")} found=0`);
33228
33335
  return c.json({ error: "Meeting not found for this account" }, 404);
33229
33336
  }
33230
33337
  const r = res.records[0];
33231
33338
  const uid = r.get("uid");
33232
- console.log(`[calendar-edit] account=${accountId.slice(0, 8)} uid=${uid ?? "absent"} fields=${fields.join(",")}`);
33339
+ console.log(`[calendar-edit] account=${accountId.slice(0, 8)} uid=${uid ?? "absent"} fields=${fields2.join(",")}`);
33233
33340
  return c.json({ meeting: mapMeeting(r) });
33234
33341
  } catch (err) {
33235
33342
  const message = err instanceof Error ? err.message : String(err);
@@ -33373,7 +33480,7 @@ app52.get("/booking-link", requireAdminSession, (c) => {
33373
33480
  }
33374
33481
  const id83 = account.accountId.slice(0, 8);
33375
33482
  try {
33376
- if (!existsSync47(join59(account.accountDir, AVAILABILITY_FILENAME))) {
33483
+ if (!existsSync47(join60(account.accountDir, AVAILABILITY_FILENAME))) {
33377
33484
  console.log(`[calendar] op=booking-link accountId=${id83} bookingDomain=none source=availability-config`);
33378
33485
  return c.json({ bookingDomain: null });
33379
33486
  }
@@ -33392,8 +33499,8 @@ app52.get("/booking-link", requireAdminSession, (c) => {
33392
33499
  var calendar_default = app52;
33393
33500
 
33394
33501
  // server/routes/admin/data-portal.ts
33395
- import { existsSync as existsSync48, readFileSync as readFileSync47 } from "fs";
33396
- import { join as join60 } from "path";
33502
+ import { existsSync as existsSync48, readFileSync as readFileSync48 } from "fs";
33503
+ import { join as join61 } from "path";
33397
33504
  var app53 = new Hono();
33398
33505
  var PORTAL_FILENAME = "data-portal.json";
33399
33506
  app53.get("/portal-link", requireAdminSession, (c) => {
@@ -33404,12 +33511,12 @@ app53.get("/portal-link", requireAdminSession, (c) => {
33404
33511
  }
33405
33512
  const id83 = account.accountId.slice(0, 8);
33406
33513
  try {
33407
- const path = join60(account.accountDir, PORTAL_FILENAME);
33514
+ const path = join61(account.accountDir, PORTAL_FILENAME);
33408
33515
  if (!existsSync48(path)) {
33409
33516
  console.log(`[data-portal] op=portal-link accountId=${id83} portalDomain=none source=data-portal-config`);
33410
33517
  return c.json({ portalDomain: null });
33411
33518
  }
33412
- const cfg = JSON.parse(readFileSync47(path, "utf-8"));
33519
+ const cfg = JSON.parse(readFileSync48(path, "utf-8"));
33413
33520
  const portalDomain = typeof cfg.portalDomain === "string" && cfg.portalDomain.trim() ? cfg.portalDomain.trim() : null;
33414
33521
  console.log(`[data-portal] op=portal-link accountId=${id83} portalDomain=${portalDomain ?? "none"} source=data-portal-config`);
33415
33522
  return c.json({ portalDomain });
@@ -33422,8 +33529,8 @@ app53.get("/portal-link", requireAdminSession, (c) => {
33422
33529
  var data_portal_default = app53;
33423
33530
 
33424
33531
  // server/routes/admin/dispatch-planner.ts
33425
- import { existsSync as existsSync49, readFileSync as readFileSync48 } from "fs";
33426
- import { join as join61 } from "path";
33532
+ import { existsSync as existsSync49, readFileSync as readFileSync49 } from "fs";
33533
+ import { join as join62 } from "path";
33427
33534
  var app54 = new Hono();
33428
33535
  var PORTAL_FILENAME2 = "data-portal.json";
33429
33536
  app54.get("/planner-link", requireAdminSession, (c) => {
@@ -33436,15 +33543,15 @@ app54.get("/planner-link", requireAdminSession, (c) => {
33436
33543
  }
33437
33544
  const id83 = account.accountId.slice(0, 8);
33438
33545
  try {
33439
- const portalPath = join61(account.accountDir, PORTAL_FILENAME2);
33440
- const dispatchConfigured = existsSync49(join61(account.accountDir, "dispatch", "config.json"));
33546
+ const portalPath = join62(account.accountDir, PORTAL_FILENAME2);
33547
+ const dispatchConfigured = existsSync49(join62(account.accountDir, "dispatch", "config.json"));
33441
33548
  if (!existsSync49(portalPath) || !dispatchConfigured) {
33442
33549
  console.log(
33443
33550
  `[dispatch-planner] op=planner-link accountId=${id83} plannerUrl=none portal=${existsSync49(portalPath)} dispatch=${dispatchConfigured}`
33444
33551
  );
33445
33552
  return c.json({ plannerUrl: null });
33446
33553
  }
33447
- const cfg = JSON.parse(readFileSync48(portalPath, "utf-8"));
33554
+ const cfg = JSON.parse(readFileSync49(portalPath, "utf-8"));
33448
33555
  const domain = typeof cfg.portalDomain === "string" && cfg.portalDomain.trim() ? cfg.portalDomain.trim() : null;
33449
33556
  const plannerUrl = domain ? `https://${domain}/planner` : null;
33450
33557
  console.log(
@@ -33462,11 +33569,11 @@ var dispatch_planner_default = app54;
33462
33569
  // server/routes/admin/routines.ts
33463
33570
  import cronParser from "cron-parser";
33464
33571
  import { int as int2 } from "neo4j-driver";
33465
- import { readFileSync as readFileSync50 } from "fs";
33572
+ import { readFileSync as readFileSync51 } from "fs";
33466
33573
  import { resolve as resolve40 } from "path";
33467
33574
 
33468
33575
  // ../lib/agent-dispatch-rule/src/index.ts
33469
- import { readFileSync as readFileSync49 } from "fs";
33576
+ import { readFileSync as readFileSync50 } from "fs";
33470
33577
  import { resolve as resolve39 } from "path";
33471
33578
  function normalizeE1642(value) {
33472
33579
  let candidate = value.trim().replace(/[\s\-().]/g, "");
@@ -33484,7 +33591,7 @@ function phonesMatch2(a, b) {
33484
33591
  function readChannelAdmins(accountDir, channel) {
33485
33592
  let config = {};
33486
33593
  try {
33487
- config = JSON.parse(readFileSync49(resolve39(accountDir, "account.json"), "utf-8"));
33594
+ config = JSON.parse(readFileSync50(resolve39(accountDir, "account.json"), "utf-8"));
33488
33595
  } catch {
33489
33596
  config = {};
33490
33597
  }
@@ -33591,23 +33698,39 @@ function listDispatchDestinations(input) {
33591
33698
  const byDestination = (a, b) => a.destination.localeCompare(b.destination);
33592
33699
  return [...managers.sort(byDestination), ...admins.sort(byDestination), ...telegram];
33593
33700
  }
33594
- function isDispatchable(fields) {
33595
- if (fields.agentChannel && fields.agentDestination && fields.agentPrompt) return true;
33596
- return Boolean(fields.actionPlugin && fields.actionTool);
33701
+ function isDispatchable(fields2) {
33702
+ if (fields2.agentChannel && fields2.agentDestination && fields2.agentPrompt) return true;
33703
+ return Boolean(fields2.actionPlugin && fields2.actionTool);
33597
33704
  }
33598
- function dispatchGapReason(fields) {
33599
- if (fields.agentChannel || fields.agentDestination || fields.agentPrompt) {
33705
+ function dispatchGapReason(fields2) {
33706
+ if (fields2.agentChannel || fields2.agentDestination || fields2.agentPrompt) {
33600
33707
  const missing = [];
33601
- if (!fields.agentChannel) missing.push("channel");
33602
- if (!fields.agentDestination) missing.push("destination");
33603
- if (!fields.agentPrompt) missing.push("prompt");
33708
+ if (!fields2.agentChannel) missing.push("channel");
33709
+ if (!fields2.agentDestination) missing.push("destination");
33710
+ if (!fields2.agentPrompt) missing.push("prompt");
33604
33711
  return `no-${missing.join("+")}`;
33605
33712
  }
33606
- if (fields.actionPlugin || fields.actionTool) {
33607
- return fields.actionTool ? "no-action-plugin" : "no-action-tool";
33713
+ if (fields2.actionPlugin || fields2.actionTool) {
33714
+ return fields2.actionTool ? "no-action-plugin" : "no-action-tool";
33608
33715
  }
33609
33716
  return "no-dispatch-configured";
33610
33717
  }
33718
+ function carrierVerdict(accountDir, botId, destination) {
33719
+ let config = {};
33720
+ try {
33721
+ config = JSON.parse(readFileSync50(resolve39(accountDir, "account.json"), "utf-8"));
33722
+ } catch {
33723
+ return { ok: false, reason: "absent" };
33724
+ }
33725
+ const bots = Array.isArray(config.telegram?.bots) ? config.telegram.bots : [];
33726
+ const entry3 = bots.find(
33727
+ (raw) => raw && typeof raw === "object" && raw.id === botId
33728
+ );
33729
+ if (!entry3) return { ok: false, reason: "absent" };
33730
+ if (entry3.role !== "admin") return { ok: false, reason: "not-admin" };
33731
+ const users = Array.isArray(entry3.adminUsers) ? entry3.adminUsers.filter((u) => typeof u === "number") : [];
33732
+ return users.includes(Number(destination)) ? { ok: true } : { ok: false, reason: "not-listed" };
33733
+ }
33611
33734
 
33612
33735
  // server/routes/admin/routines.ts
33613
33736
  var { parseExpression } = cronParser;
@@ -33652,7 +33775,7 @@ function gateWatermarkPath(eventId) {
33652
33775
  }
33653
33776
  function readGateLastCommitAt(eventId) {
33654
33777
  try {
33655
- const parsed = JSON.parse(readFileSync50(gateWatermarkPath(eventId), "utf-8"));
33778
+ const parsed = JSON.parse(readFileSync51(gateWatermarkPath(eventId), "utf-8"));
33656
33779
  return typeof parsed?.lastCommitAt === "string" ? parsed.lastCommitAt : null;
33657
33780
  } catch {
33658
33781
  return null;
@@ -33762,9 +33885,9 @@ function describeDispatchGap(reason) {
33762
33885
  destination: "a destination",
33763
33886
  prompt: "an instruction"
33764
33887
  };
33765
- const fields = reason.startsWith("no-") ? reason.slice(3).split("+") : [];
33766
- if (fields.length > 0 && fields.every((f) => f in words)) {
33767
- const list = fields.map((f) => words[f]);
33888
+ const fields2 = reason.startsWith("no-") ? reason.slice(3).split("+") : [];
33889
+ if (fields2.length > 0 && fields2.every((f) => f in words)) {
33890
+ const list = fields2.map((f) => words[f]);
33768
33891
  const joined = list.length === 1 ? list[0] : `${list.slice(0, -1).join(", ")} and ${list[list.length - 1]}`;
33769
33892
  return `This routine has no ${joined.replace(/^an? /, "")} set, so arming it would deliver nothing.`;
33770
33893
  }
@@ -34093,7 +34216,7 @@ app55.patch("/:eventId", requireAdminSession, async (c) => {
34093
34216
  const id83 = eventId.slice(0, 8);
34094
34217
  const setClauses = [];
34095
34218
  const params = { eventId, accountId };
34096
- const fields = [];
34219
+ const fields2 = [];
34097
34220
  let nextRunLog = "unchanged";
34098
34221
  let bindingLog = "";
34099
34222
  const hasChannel = "agentChannel" in body;
@@ -34177,7 +34300,7 @@ app55.patch("/:eventId", requireAdminSession, async (c) => {
34177
34300
  setClauses.push("e.agentChannel = $agentChannel", "e.agentDestination = $agentDestination");
34178
34301
  params.agentChannel = channel;
34179
34302
  params.agentDestination = destination;
34180
- fields.push("agentChannel", "agentDestination");
34303
+ fields2.push("agentChannel", "agentDestination");
34181
34304
  bindingLog = ` channel=${channel} destination=${destination.slice(-4)}`;
34182
34305
  }
34183
34306
  if (clearing) {
@@ -34190,13 +34313,13 @@ app55.patch("/:eventId", requireAdminSession, async (c) => {
34190
34313
  );
34191
34314
  }
34192
34315
  setClauses.push("e.agentChannel = null", "e.agentDestination = null");
34193
- fields.push("agentChannel", "agentDestination");
34316
+ fields2.push("agentChannel", "agentDestination");
34194
34317
  bindingLog = " channel=none destination=none";
34195
34318
  }
34196
34319
  if (typeof body.agentPrompt === "string") {
34197
34320
  setClauses.push("e.agentPrompt = $agentPrompt");
34198
34321
  params.agentPrompt = body.agentPrompt;
34199
- fields.push("agentPrompt");
34322
+ fields2.push("agentPrompt");
34200
34323
  setClauses.push("e.operatorEdited = $operatorEdited");
34201
34324
  params.operatorEdited = (/* @__PURE__ */ new Date()).toISOString();
34202
34325
  }
@@ -34213,7 +34336,7 @@ app55.patch("/:eventId", requireAdminSession, async (c) => {
34213
34336
  }
34214
34337
  setClauses.push("e.name = $name");
34215
34338
  params.name = nextName;
34216
- fields.push("name");
34339
+ fields2.push("name");
34217
34340
  setClauses.push("e.operatorEdited = $operatorEdited");
34218
34341
  params.operatorEdited = (/* @__PURE__ */ new Date()).toISOString();
34219
34342
  }
@@ -34227,7 +34350,7 @@ app55.patch("/:eventId", requireAdminSession, async (c) => {
34227
34350
  nextDescription = typeof raw === "string" && raw.trim().length > 0 ? raw : null;
34228
34351
  setClauses.push("e.description = $description");
34229
34352
  params.description = nextDescription;
34230
- fields.push("description");
34353
+ fields2.push("description");
34231
34354
  setClauses.push("e.operatorEdited = $operatorEdited");
34232
34355
  params.operatorEdited = (/* @__PURE__ */ new Date()).toISOString();
34233
34356
  }
@@ -34242,7 +34365,7 @@ app55.patch("/:eventId", requireAdminSession, async (c) => {
34242
34365
  params.embedding = embedding;
34243
34366
  } else {
34244
34367
  embedLog = " embed=failed";
34245
- console.error(`[admin:routines] op=patch id=${id83} fields=${fields.join("+")} embed=failed`);
34368
+ console.error(`[admin:routines] op=patch id=${id83} fields=${fields2.join("+")} embed=failed`);
34246
34369
  }
34247
34370
  }
34248
34371
  if (typeof body.recurrence === "string") {
@@ -34252,7 +34375,7 @@ app55.patch("/:eventId", requireAdminSession, async (c) => {
34252
34375
  setClauses.push("e.recurrence = $recurrence", "e.nextRun = $nextRun");
34253
34376
  params.recurrence = body.recurrence;
34254
34377
  params.nextRun = nextRun;
34255
- fields.push("recurrence");
34378
+ fields2.push("recurrence");
34256
34379
  nextRunLog = nextRun;
34257
34380
  } catch (err) {
34258
34381
  const reason = err instanceof Error ? err.message : String(err);
@@ -34278,7 +34401,7 @@ app55.patch("/:eventId", requireAdminSession, async (c) => {
34278
34401
  return c.json({ error: "Routine not found" }, 404);
34279
34402
  }
34280
34403
  const nameLog = nextName === null ? "" : ` name=len:${nextName.length} operatorEdited=stamped`;
34281
- console.log(`[admin:routines] op=patch id=${id83} fields=${fields.join("+")} outcome=ok nextRun=${nextRunLog} cron=${params.recurrence ?? "unchanged"}${bindingLog}${nameLog}${embedLog}`);
34404
+ console.log(`[admin:routines] op=patch id=${id83} fields=${fields2.join("+")} outcome=ok nextRun=${nextRunLog} cron=${params.recurrence ?? "unchanged"}${bindingLog}${nameLog}${embedLog}`);
34282
34405
  return c.json({ routine: mapRoutine(res.records[0]) });
34283
34406
  } catch (err) {
34284
34407
  const message = err instanceof Error ? err.message : String(err);
@@ -34529,7 +34652,7 @@ app55.delete("/:eventId", requireAdminSession, async (c) => {
34529
34652
  var routines_default = app55;
34530
34653
 
34531
34654
  // server/routes/admin/skills.ts
34532
- import { existsSync as existsSync50, readdirSync as readdirSync28, readFileSync as readFileSync51, rmSync as rmSync6 } from "fs";
34655
+ import { existsSync as existsSync50, readdirSync as readdirSync29, readFileSync as readFileSync52, rmSync as rmSync6 } from "fs";
34533
34656
  import { resolve as resolve41 } from "path";
34534
34657
  var app56 = new Hono();
34535
34658
  var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
@@ -34555,7 +34678,7 @@ function stripQuotes(s) {
34555
34678
  function subdirs2(dir) {
34556
34679
  if (!existsSync50(dir)) return [];
34557
34680
  try {
34558
- return readdirSync28(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
34681
+ return readdirSync29(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
34559
34682
  } catch {
34560
34683
  return [];
34561
34684
  }
@@ -34578,9 +34701,9 @@ app56.get("/", requireAdminSession, async (c) => {
34578
34701
  const skillMd = resolve41(skillsDir, skill, "SKILL.md");
34579
34702
  if (!existsSync50(skillMd)) continue;
34580
34703
  try {
34581
- const { frontmatter } = splitSkillMd(readFileSync51(skillMd, "utf-8"));
34704
+ const { frontmatter } = splitSkillMd(readFileSync52(skillMd, "utf-8"));
34582
34705
  const refsDir = resolve41(skillsDir, skill, "references");
34583
- const refCount = existsSync50(refsDir) ? readdirSync28(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
34706
+ const refCount = existsSync50(refsDir) ? readdirSync29(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
34584
34707
  skills.push({ plugin, skill, description: frontmatter.description, refCount });
34585
34708
  } catch (err) {
34586
34709
  console.error(`[admin:skills] op=list-skip plugin=${plugin} skill=${skill} reason="${err instanceof Error ? err.message : String(err)}"`);
@@ -34608,9 +34731,9 @@ app56.get("/:plugin/:skill", requireAdminSession, async (c) => {
34608
34731
  console.log(`[admin:skills] op=get plugin=${plugin} skill=${skill} found=${found}`);
34609
34732
  if (!found) return c.json({ error: "Skill not found" }, 404);
34610
34733
  try {
34611
- const { frontmatter, body } = splitSkillMd(readFileSync51(skillMd, "utf-8"));
34734
+ const { frontmatter, body } = splitSkillMd(readFileSync52(skillMd, "utf-8"));
34612
34735
  const refsDir = resolve41(skillDir, "references");
34613
- const references = existsSync50(refsDir) ? readdirSync28(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
34736
+ const references = existsSync50(refsDir) ? readdirSync29(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
34614
34737
  return c.json({ skill: { plugin, skill, frontmatter, body, references } });
34615
34738
  } catch (err) {
34616
34739
  const message = err instanceof Error ? err.message : String(err);
@@ -34654,7 +34777,7 @@ app56.delete("/:plugin/:skill", requireAdminSession, async (c) => {
34654
34777
  var skills_default = app56;
34655
34778
 
34656
34779
  // server/routes/admin/tasks-list.ts
34657
- import { basename as basename17, join as join62 } from "path";
34780
+ import { basename as basename17, join as join63 } from "path";
34658
34781
 
34659
34782
  // app/lib/time-entry-format.ts
34660
34783
  function secondsBetween(startIso, endIso) {
@@ -34830,7 +34953,7 @@ async function computeTaskList(accountId) {
34830
34953
  dangling = 0;
34831
34954
  } else if (cfg !== null) {
34832
34955
  try {
34833
- const walk = enumerateJsonlsWithSkips(join62(cfg, "projects"));
34956
+ const walk = enumerateJsonlsWithSkips(join63(cfg, "projects"));
34834
34957
  if (walk.skipped > 0) {
34835
34958
  console.error(
34836
34959
  `${TAG51} op=session-dangling-census-incomplete account=${accountId} skipped=${walk.skipped} detail="a slug the walk could not read contributes no session ids, so its links cannot be judged"`
@@ -35242,12 +35365,12 @@ app62.post("/", requireAdminSession, async (c) => {
35242
35365
  var task_delete_default = app62;
35243
35366
 
35244
35367
  // app/lib/admin-roster.ts
35245
- import { existsSync as existsSync51, readdirSync as readdirSync29, readFileSync as readFileSync52 } from "fs";
35368
+ import { existsSync as existsSync51, readdirSync as readdirSync30, readFileSync as readFileSync53 } from "fs";
35246
35369
  import { resolve as resolve42 } from "path";
35247
35370
  function readHouseAdminUserIds(accountsDir = ACCOUNTS_DIR) {
35248
35371
  let entries2;
35249
35372
  try {
35250
- entries2 = readdirSync29(accountsDir);
35373
+ entries2 = readdirSync30(accountsDir);
35251
35374
  } catch {
35252
35375
  return [];
35253
35376
  }
@@ -35255,7 +35378,7 @@ function readHouseAdminUserIds(accountsDir = ACCOUNTS_DIR) {
35255
35378
  const cfgPath = resolve42(accountsDir, entry3, "account.json");
35256
35379
  if (!existsSync51(cfgPath)) continue;
35257
35380
  try {
35258
- const cfg = JSON.parse(readFileSync52(cfgPath, "utf-8"));
35381
+ const cfg = JSON.parse(readFileSync53(cfgPath, "utf-8"));
35259
35382
  if (cfg.role !== "house") continue;
35260
35383
  if (!Array.isArray(cfg.admins)) return [];
35261
35384
  return cfg.admins.map(
@@ -35670,7 +35793,7 @@ app67.get("/", requireAdminSession, async (c) => {
35670
35793
  var dispatch_destinations_default = app67;
35671
35794
 
35672
35795
  // server/routes/admin/activity.ts
35673
- import { readdirSync as readdirSync30 } from "fs";
35796
+ import { readdirSync as readdirSync31 } from "fs";
35674
35797
  var app68 = new Hono();
35675
35798
  var TAG62 = "[activity]";
35676
35799
  function resolveHouseAccountId2(accounts) {
@@ -35686,7 +35809,7 @@ function requestToken() {
35686
35809
  var short = (id) => id ? id.slice(0, 8) : "unset";
35687
35810
  function countAccountDirsOnDisk() {
35688
35811
  try {
35689
- return readdirSync30(ACCOUNTS_DIR, { withFileTypes: true }).filter(
35812
+ return readdirSync31(ACCOUNTS_DIR, { withFileTypes: true }).filter(
35690
35813
  (e) => e.isDirectory() && !e.name.startsWith(".")
35691
35814
  ).length;
35692
35815
  } catch {
@@ -36097,7 +36220,7 @@ app72.route("/request-magic-link", request_magic_link_default);
36097
36220
  var access_default = app72;
36098
36221
 
36099
36222
  // server/routes/sites.ts
36100
- import { existsSync as existsSync52, readFileSync as readFileSync53, realpathSync as realpathSync8, statSync as statSync27 } from "fs";
36223
+ import { existsSync as existsSync52, readFileSync as readFileSync54, realpathSync as realpathSync8, statSync as statSync28 } from "fs";
36101
36224
  import { resolve as resolve45 } from "path";
36102
36225
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
36103
36226
  var MIME = {
@@ -36163,7 +36286,7 @@ app73.get("/:rel{.*}", (c) => {
36163
36286
  }
36164
36287
  let stat11;
36165
36288
  try {
36166
- stat11 = existsSync52(filePath) ? statSync27(filePath) : null;
36289
+ stat11 = existsSync52(filePath) ? statSync28(filePath) : null;
36167
36290
  } catch {
36168
36291
  stat11 = null;
36169
36292
  }
@@ -36201,7 +36324,7 @@ app73.get("/:rel{.*}", (c) => {
36201
36324
  }
36202
36325
  let body;
36203
36326
  try {
36204
- body = readFileSync53(realPath);
36327
+ body = readFileSync54(realPath);
36205
36328
  } catch (err) {
36206
36329
  const code = err?.code;
36207
36330
  if (code === "EISDIR") {
@@ -36237,7 +36360,7 @@ var sites_default = app73;
36237
36360
 
36238
36361
  // app/lib/visitor-token.ts
36239
36362
  import { createHmac as createHmac2, randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual3 } from "crypto";
36240
- import { mkdirSync as mkdirSync12, readFileSync as readFileSync54, writeFileSync as writeFileSync21 } from "fs";
36363
+ import { mkdirSync as mkdirSync12, readFileSync as readFileSync55, writeFileSync as writeFileSync21 } from "fs";
36241
36364
  import { dirname as dirname17 } from "path";
36242
36365
  var TOKEN_PREFIX = "v1.";
36243
36366
  var SECRET_BYTES = 32;
@@ -36246,7 +36369,7 @@ var cachedSecret = null;
36246
36369
  function getSecret() {
36247
36370
  if (cachedSecret) return cachedSecret;
36248
36371
  try {
36249
- const hex2 = readFileSync54(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
36372
+ const hex2 = readFileSync55(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
36250
36373
  if (hex2.length === SECRET_BYTES * 2) {
36251
36374
  cachedSecret = Buffer.from(hex2, "hex");
36252
36375
  return cachedSecret;
@@ -36260,7 +36383,7 @@ function getSecret() {
36260
36383
  console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
36261
36384
  } catch {
36262
36385
  }
36263
- const hex = readFileSync54(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
36386
+ const hex = readFileSync55(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
36264
36387
  cachedSecret = Buffer.from(hex, "hex");
36265
36388
  return cachedSecret;
36266
36389
  }
@@ -36313,8 +36436,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
36313
36436
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
36314
36437
 
36315
36438
  // app/lib/brand-config.ts
36316
- import { existsSync as existsSync53, readFileSync as readFileSync55 } from "fs";
36317
- import { join as join63 } from "path";
36439
+ import { existsSync as existsSync53, readFileSync as readFileSync56 } from "fs";
36440
+ import { join as join64 } from "path";
36318
36441
  var cached2 = null;
36319
36442
  var cachedAttempted = false;
36320
36443
  function readBrandConfig() {
@@ -36322,10 +36445,10 @@ function readBrandConfig() {
36322
36445
  cachedAttempted = true;
36323
36446
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
36324
36447
  if (!platformRoot5) return null;
36325
- const brandPath = join63(platformRoot5, "config", "brand.json");
36448
+ const brandPath = join64(platformRoot5, "config", "brand.json");
36326
36449
  if (!existsSync53(brandPath)) return null;
36327
36450
  try {
36328
- cached2 = JSON.parse(readFileSync55(brandPath, "utf-8"));
36451
+ cached2 = JSON.parse(readFileSync56(brandPath, "utf-8"));
36329
36452
  return cached2;
36330
36453
  } catch {
36331
36454
  return null;
@@ -37091,7 +37214,7 @@ var calendar_public_default = app78;
37091
37214
  // server/routes/portal-fetch.ts
37092
37215
  import { createReadStream as createReadStream3 } from "fs";
37093
37216
  import { stat as stat8, readFile as readFile12, realpath } from "fs/promises";
37094
- import { join as join64, resolve as resolve47, sep as sep11 } from "path";
37217
+ import { join as join65, resolve as resolve47, sep as sep11 } from "path";
37095
37218
  import { Readable as Readable3 } from "stream";
37096
37219
  var app79 = new Hono();
37097
37220
  var TAG65 = "[portal-fetch]";
@@ -37164,7 +37287,7 @@ function isValidAccountId2(value) {
37164
37287
  }
37165
37288
  async function readExposeFolders2(accountDir) {
37166
37289
  try {
37167
- const cfg = JSON.parse(await readFile12(join64(accountDir, "data-portal.json"), "utf8"));
37290
+ const cfg = JSON.parse(await readFile12(join65(accountDir, "data-portal.json"), "utf8"));
37168
37291
  return Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
37169
37292
  } catch {
37170
37293
  return [];
@@ -37173,7 +37296,7 @@ async function readExposeFolders2(accountDir) {
37173
37296
  async function resolveFetchTarget(accountDir, relPath, ownerId) {
37174
37297
  let schemaText = null;
37175
37298
  try {
37176
- schemaText = await readFile12(join64(accountDir, "SCHEMA.md"), "utf8");
37299
+ schemaText = await readFile12(join65(accountDir, "SCHEMA.md"), "utf8");
37177
37300
  } catch {
37178
37301
  schemaText = null;
37179
37302
  }
@@ -37343,8 +37466,8 @@ function startTimeEntryCensus(openSession, opts = {}) {
37343
37466
  }
37344
37467
 
37345
37468
  // app/lib/ledger-census.ts
37346
- import { readdirSync as readdirSync31, readFileSync as readFileSync56, statSync as statSync28 } from "fs";
37347
- import { join as join65 } from "path";
37469
+ import { readdirSync as readdirSync32, readFileSync as readFileSync57, statSync as statSync29 } from "fs";
37470
+ import { join as join66 } from "path";
37348
37471
 
37349
37472
  // ../lib/ledger-core/dist/reconcile.js
37350
37473
  var LEDGER_INDEX_NAMES = [
@@ -37392,16 +37515,16 @@ var DAY_MS = 864e5;
37392
37515
  function countWriteRejects24h(logDir, now) {
37393
37516
  let entries2;
37394
37517
  try {
37395
- entries2 = readdirSync31(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
37518
+ entries2 = readdirSync32(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
37396
37519
  } catch {
37397
37520
  return 0;
37398
37521
  }
37399
37522
  let total = 0;
37400
37523
  for (const name of entries2) {
37401
- const path = join65(logDir, name);
37524
+ const path = join66(logDir, name);
37402
37525
  try {
37403
- if (now - statSync28(path).mtimeMs > DAY_MS) continue;
37404
- for (const line of readFileSync56(path, "utf8").split("\n")) {
37526
+ if (now - statSync29(path).mtimeMs > DAY_MS) continue;
37527
+ for (const line of readFileSync57(path, "utf8").split("\n")) {
37405
37528
  if (line.includes("[graph-write] reject")) total += 1;
37406
37529
  }
37407
37530
  } catch {
@@ -37502,8 +37625,8 @@ function startLedgerCensus(openSession, opts = {}) {
37502
37625
  }
37503
37626
 
37504
37627
  // app/lib/dispatch-census.ts
37505
- import { readFileSync as readFileSync57 } from "fs";
37506
- import { join as join66 } from "path";
37628
+ import { readFileSync as readFileSync58 } from "fs";
37629
+ import { join as join67 } from "path";
37507
37630
 
37508
37631
  // ../lib/canonical-instant/src/index.ts
37509
37632
  var CANONICAL_INSTANT_PATTERN = "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z";
@@ -37541,7 +37664,7 @@ function percentile(sortedAsc, p) {
37541
37664
  function auditConfigFile(accountDir) {
37542
37665
  let cfg;
37543
37666
  try {
37544
- cfg = JSON.parse(readFileSync57(join66(accountDir, "dispatch", "config.json"), "utf-8"));
37667
+ cfg = JSON.parse(readFileSync58(join67(accountDir, "dispatch", "config.json"), "utf-8"));
37545
37668
  } catch {
37546
37669
  return null;
37547
37670
  }
@@ -37566,7 +37689,7 @@ function auditConfigFile(accountDir) {
37566
37689
  function terminalStatuses(accountDir) {
37567
37690
  try {
37568
37691
  const cfg = JSON.parse(
37569
- readFileSync57(join66(accountDir, "dispatch", "config.json"), "utf-8")
37692
+ readFileSync58(join67(accountDir, "dispatch", "config.json"), "utf-8")
37570
37693
  );
37571
37694
  return {
37572
37695
  job: (cfg.statuses?.job ?? []).filter((s) => s.terminal).map((s) => s.name),
@@ -37996,8 +38119,8 @@ function startGraphHealthTimer() {
37996
38119
  }
37997
38120
 
37998
38121
  // app/lib/shared-folder-census.ts
37999
- import { existsSync as existsSync55, statSync as statSync29, readdirSync as readdirSync32 } from "fs";
38000
- import { join as join67 } from "path";
38122
+ import { existsSync as existsSync55, statSync as statSync30, readdirSync as readdirSync33 } from "fs";
38123
+ import { join as join68 } from "path";
38001
38124
  var import_dist17 = __toESM(require_dist(), 1);
38002
38125
  var TAG69 = "[shared-census]";
38003
38126
  var WIRED_SURFACES = 3;
@@ -38005,12 +38128,12 @@ function countFiles(dir) {
38005
38128
  let n = 0;
38006
38129
  let entries2;
38007
38130
  try {
38008
- entries2 = readdirSync32(dir, { withFileTypes: true });
38131
+ entries2 = readdirSync33(dir, { withFileTypes: true });
38009
38132
  } catch {
38010
38133
  return 0;
38011
38134
  }
38012
38135
  for (const e of entries2) {
38013
- if (e.isDirectory()) n += countFiles(join67(dir, e.name));
38136
+ if (e.isDirectory()) n += countFiles(join68(dir, e.name));
38014
38137
  else if (e.isFile()) n++;
38015
38138
  }
38016
38139
  return n;
@@ -38021,7 +38144,7 @@ function runSharedFolderCensus(dataRoot = DATA_ROOT) {
38021
38144
  let isDir = false;
38022
38145
  if (exists) {
38023
38146
  try {
38024
- isDir = statSync29(root).isDirectory();
38147
+ isDir = statSync30(root).isDirectory();
38025
38148
  } catch {
38026
38149
  isDir = false;
38027
38150
  }
@@ -38059,9 +38182,9 @@ function startAccountsStateCensus() {
38059
38182
  }
38060
38183
 
38061
38184
  // app/lib/cred-refresh-census.ts
38062
- import { readdirSync as readdirSync33, readFileSync as readFileSync58 } from "fs";
38185
+ import { readdirSync as readdirSync34, readFileSync as readFileSync59 } from "fs";
38063
38186
  import { homedir as homedir4 } from "os";
38064
- import { join as join68 } from "path";
38187
+ import { join as join69 } from "path";
38065
38188
  var TAG71 = "[claude-auth]";
38066
38189
  function refreshTokenLength(raw) {
38067
38190
  let data;
@@ -38077,7 +38200,7 @@ function refreshTokenLength(raw) {
38077
38200
  function surveyBrandCredentials(home) {
38078
38201
  let entries2;
38079
38202
  try {
38080
- entries2 = readdirSync33(home);
38203
+ entries2 = readdirSync34(home);
38081
38204
  } catch {
38082
38205
  return [];
38083
38206
  }
@@ -38086,7 +38209,7 @@ function surveyBrandCredentials(home) {
38086
38209
  if (!entry3.startsWith(".")) continue;
38087
38210
  let raw;
38088
38211
  try {
38089
- raw = readFileSync58(join68(home, entry3, ".claude", ".credentials.json"), "utf-8");
38212
+ raw = readFileSync59(join69(home, entry3, ".claude", ".credentials.json"), "utf-8");
38090
38213
  } catch {
38091
38214
  continue;
38092
38215
  }
@@ -38348,7 +38471,7 @@ async function migrateUploads(opts = {}) {
38348
38471
  // app/lib/migrate-admin-webchat-sidecars.ts
38349
38472
  import { readdir as readdir7, readFile as readFile13, rename as rename5, writeFile as writeFile4, unlink as unlink4 } from "fs/promises";
38350
38473
  import { existsSync as existsSync56 } from "fs";
38351
- import { join as join69 } from "path";
38474
+ import { join as join70 } from "path";
38352
38475
  var ADMIN_ROLE2 = "admin";
38353
38476
  var WEBCHAT_CHANNEL2 = "webchat";
38354
38477
  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;
@@ -38393,7 +38516,7 @@ async function collectLiveSidecars(projectsRoot) {
38393
38516
  }
38394
38517
  for (const slug of slugs) {
38395
38518
  if (!slug.isDirectory()) continue;
38396
- const slugDir = join69(projectsRoot, slug.name);
38519
+ const slugDir = join70(projectsRoot, slug.name);
38397
38520
  let entries2;
38398
38521
  try {
38399
38522
  entries2 = await readdir7(slugDir, { withFileTypes: true });
@@ -38402,9 +38525,9 @@ async function collectLiveSidecars(projectsRoot) {
38402
38525
  }
38403
38526
  for (const entry3 of entries2) {
38404
38527
  if (entry3.isFile() && SESSION_META_RE.test(entry3.name)) {
38405
- out.push(join69(slugDir, entry3.name));
38528
+ out.push(join70(slugDir, entry3.name));
38406
38529
  } else if (entry3.isDirectory() && entry3.name === "subagents") {
38407
- const subDir = join69(slugDir, entry3.name);
38530
+ const subDir = join70(slugDir, entry3.name);
38408
38531
  let subs;
38409
38532
  try {
38410
38533
  subs = await readdir7(subDir, { withFileTypes: true });
@@ -38412,7 +38535,7 @@ async function collectLiveSidecars(projectsRoot) {
38412
38535
  continue;
38413
38536
  }
38414
38537
  for (const s of subs) {
38415
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join69(subDir, s.name));
38538
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join70(subDir, s.name));
38416
38539
  }
38417
38540
  }
38418
38541
  }
@@ -38424,7 +38547,7 @@ function shortId(path) {
38424
38547
  return base.slice(0, 8);
38425
38548
  }
38426
38549
  async function migrateAdminWebchatSidecars(opts = {}) {
38427
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join69(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
38550
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join70(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
38428
38551
  const usersFile = opts.usersFile ?? USERS_FILE;
38429
38552
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
38430
38553
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -38501,7 +38624,7 @@ async function migrateAdminWebchatSidecars(opts = {}) {
38501
38624
  // app/lib/migrate-sidecar-account-ids.ts
38502
38625
  import { readdir as readdir8, readFile as readFile14, rename as rename6, writeFile as writeFile5, unlink as unlink5 } from "fs/promises";
38503
38626
  import { existsSync as existsSync57 } from "fs";
38504
- import { join as join70 } from "path";
38627
+ import { join as join71 } from "path";
38505
38628
  var SESSION_META_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
38506
38629
  function projectSlugForCwd(cwd) {
38507
38630
  return cwd.replace(/\//g, "-");
@@ -38547,7 +38670,7 @@ async function collectSidecars(projectsRoot) {
38547
38670
  }
38548
38671
  for (const slug of slugs) {
38549
38672
  if (!slug.isDirectory()) continue;
38550
- const slugDir = join70(projectsRoot, slug.name);
38673
+ const slugDir = join71(projectsRoot, slug.name);
38551
38674
  let entries2;
38552
38675
  try {
38553
38676
  entries2 = await readdir8(slugDir, { withFileTypes: true });
@@ -38556,9 +38679,9 @@ async function collectSidecars(projectsRoot) {
38556
38679
  }
38557
38680
  for (const entry3 of entries2) {
38558
38681
  if (entry3.isFile() && SESSION_META_RE2.test(entry3.name)) {
38559
- out.push({ path: join70(slugDir, entry3.name), slug: slug.name });
38682
+ out.push({ path: join71(slugDir, entry3.name), slug: slug.name });
38560
38683
  } else if (entry3.isDirectory() && (entry3.name === "subagents" || entry3.name === "archive")) {
38561
- const subDir = join70(slugDir, entry3.name);
38684
+ const subDir = join71(slugDir, entry3.name);
38562
38685
  let subs;
38563
38686
  try {
38564
38687
  subs = await readdir8(subDir, { withFileTypes: true });
@@ -38567,7 +38690,7 @@ async function collectSidecars(projectsRoot) {
38567
38690
  }
38568
38691
  for (const s of subs) {
38569
38692
  if (s.isFile() && SESSION_META_RE2.test(s.name)) {
38570
- out.push({ path: join70(subDir, s.name), slug: slug.name });
38693
+ out.push({ path: join71(subDir, s.name), slug: slug.name });
38571
38694
  }
38572
38695
  }
38573
38696
  }
@@ -38576,7 +38699,7 @@ async function collectSidecars(projectsRoot) {
38576
38699
  return out;
38577
38700
  }
38578
38701
  async function migrateSidecarAccountIds(opts = {}) {
38579
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join70(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
38702
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join71(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
38580
38703
  const accounts = opts.accounts ?? listValidAccounts();
38581
38704
  const result = {
38582
38705
  scanned: 0,
@@ -40199,8 +40322,8 @@ function createWebchatChannelRoutes(deps) {
40199
40322
  }
40200
40323
 
40201
40324
  // app/lib/webchat/gateway/resolve-turn-answer.ts
40202
- import { existsSync as existsSync58, openSync as openSync9, readSync as readSync8, closeSync as closeSync9, readdirSync as readdirSync34 } from "fs";
40203
- import { join as join71 } from "path";
40325
+ import { existsSync as existsSync58, openSync as openSync10, readSync as readSync9, closeSync as closeSync10, readdirSync as readdirSync35 } from "fs";
40326
+ import { join as join72 } from "path";
40204
40327
 
40205
40328
  // app/lib/channel-delivery/outbound-guard.ts
40206
40329
  var INTERNAL_LEAK_PATTERNS = [
@@ -40242,13 +40365,13 @@ function resolveTurnAnswer(p) {
40242
40365
  if (!(length > 0)) return "";
40243
40366
  let text;
40244
40367
  try {
40245
- const fd = openSync9(path, "r");
40368
+ const fd = openSync10(path, "r");
40246
40369
  try {
40247
40370
  const buf = Buffer.alloc(length);
40248
- readSync8(fd, buf, 0, length, p.segmentStart);
40371
+ readSync9(fd, buf, 0, length, p.segmentStart);
40249
40372
  text = buf.toString("utf8");
40250
40373
  } finally {
40251
- closeSync9(fd);
40374
+ closeSync10(fd);
40252
40375
  }
40253
40376
  } catch {
40254
40377
  return "";
@@ -40264,12 +40387,12 @@ function findJsonl(projectsRoot, sessionId) {
40264
40387
  if (!existsSync58(projectsRoot)) return null;
40265
40388
  let slugs;
40266
40389
  try {
40267
- slugs = readdirSync34(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
40390
+ slugs = readdirSync35(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
40268
40391
  } catch {
40269
40392
  return null;
40270
40393
  }
40271
40394
  for (const slug of slugs) {
40272
- const live = join71(projectsRoot, slug, `${sessionId}.jsonl`);
40395
+ const live = join72(projectsRoot, slug, `${sessionId}.jsonl`);
40273
40396
  if (existsSync58(live)) return live;
40274
40397
  }
40275
40398
  return null;
@@ -41651,21 +41774,21 @@ function refusalNoticeText(reason) {
41651
41774
  }
41652
41775
  async function sendRefusalNotice(input) {
41653
41776
  if (notified.has(input.doorId)) return;
41654
- const fields = `channel=${input.channel} sender=${input.sender} reason=${input.reason}`;
41777
+ const fields2 = `channel=${input.channel} sender=${input.sender} reason=${input.reason}`;
41655
41778
  if (!input.send) {
41656
- console.error(`${TAG74} op=refusal-notice-failed ${fields} error=no-target`);
41779
+ console.error(`${TAG74} op=refusal-notice-failed ${fields2} error=no-target`);
41657
41780
  return;
41658
41781
  }
41659
41782
  try {
41660
41783
  await input.send(guardOutbound(input.sender, refusalNoticeText(input.reason)));
41661
41784
  } catch (e) {
41662
41785
  console.error(
41663
- `${TAG74} op=refusal-notice-failed ${fields} error=${e instanceof Error ? e.message : String(e)}`
41786
+ `${TAG74} op=refusal-notice-failed ${fields2} error=${e instanceof Error ? e.message : String(e)}`
41664
41787
  );
41665
41788
  return;
41666
41789
  }
41667
41790
  notified.add(input.doorId);
41668
- console.error(`${TAG74} op=refusal-notice ${fields} status=${input.status}`);
41791
+ console.error(`${TAG74} op=refusal-notice ${fields2} status=${input.status}`);
41669
41792
  }
41670
41793
  function clearRefusalNotice(doorId) {
41671
41794
  notified.delete(doorId);
@@ -42672,7 +42795,7 @@ var sessions3 = /* @__PURE__ */ new Map();
42672
42795
  function entry2(sessionId) {
42673
42796
  let e = sessions3.get(sessionId);
42674
42797
  if (!e) {
42675
- e = { armed: 0, suppressed: 0, delivered: 0, persisted: 0, sent: 0, crossChat: 0 };
42798
+ e = { armed: 0, suppressed: 0, delivered: 0 };
42676
42799
  sessions3.set(sessionId, e);
42677
42800
  }
42678
42801
  return e;
@@ -42687,59 +42810,23 @@ function noteCardDelivered(sessionId) {
42687
42810
  const e = sessions3.get(sessionId);
42688
42811
  if (e && e.armed > 0) e.delivered += 1;
42689
42812
  }
42690
- function noteCardPersisted(sessionId) {
42691
- entry2(sessionId).persisted += 1;
42692
- }
42693
- function noteCardSent(sessionId) {
42694
- entry2(sessionId).sent += 1;
42695
- }
42696
- function noteCardCrossChat(sessionId) {
42697
- entry2(sessionId).crossChat += 1;
42698
- }
42699
42813
  function cardCensusLines() {
42700
42814
  let armed3 = 0;
42701
42815
  let suppressed = 0;
42702
42816
  let delivered = 0;
42703
- let persisted = 0;
42704
- let sent = 0;
42705
- let crossChat = 0;
42706
42817
  for (const e of sessions3.values()) {
42707
42818
  armed3 += e.armed;
42708
42819
  suppressed += e.suppressed;
42709
42820
  delivered += e.delivered;
42710
- persisted += e.persisted;
42711
- sent += e.sent;
42712
- crossChat += e.crossChat;
42713
42821
  }
42714
42822
  const silent = Math.max(0, armed3 - suppressed - delivered);
42715
42823
  return [
42716
- `[telegram-card-suppression-census] sessions=${sessions3.size} armed=${armed3} suppressed=${suppressed} silent-turns=${silent} sent=${sent} persisted=${persisted} cross-chat=${crossChat}`
42824
+ `[telegram-card-suppression-census] sessions=${sessions3.size} armed=${armed3} suppressed=${suppressed} silent-turns=${silent}`
42717
42825
  ];
42718
42826
  }
42719
42827
 
42720
42828
  // app/lib/telegram/gateway/native-file-follower.ts
42721
42829
  var TELEGRAM_CARD_TOOL = "mcp__telegram__telegram-card";
42722
- var CARD_TOOL_NAMES = /* @__PURE__ */ new Set([
42723
- "mcp__telegram__telegram-card",
42724
- "mcp__plugin_telegram_telegram__telegram-card"
42725
- ]);
42726
- var CARD_RESULT_RE = /card-result: outcome=(sent|edited|unchanged|none) messageId=(\d+|none)(?: botId=(-?\d+) chatId=(-?\d+))?/;
42727
- function parseCardButtons(input) {
42728
- const rows = input?.buttons;
42729
- if (!Array.isArray(rows)) return [];
42730
- const out = [];
42731
- for (const row of rows) {
42732
- if (!Array.isArray(row)) continue;
42733
- for (const b of row) {
42734
- if (!b || typeof b !== "object") continue;
42735
- const text = b.text;
42736
- if (typeof text !== "string") continue;
42737
- const data = b.callbackData;
42738
- out.push({ text, data: typeof data === "string" ? data : null });
42739
- }
42740
- }
42741
- return out;
42742
- }
42743
42830
  var CHAT_ACTION_REFRESH_MS = 4e3;
42744
42831
  function startTelegramNativeFileFollower(input) {
42745
42832
  const entry3 = {
@@ -42760,9 +42847,7 @@ function startTelegramNativeFileFollower(input) {
42760
42847
  // The chat id the document is addressed to (set per spawn from the inbound).
42761
42848
  replyTarget: input.chatId
42762
42849
  };
42763
- const pendingCards = /* @__PURE__ */ new Map();
42764
42850
  const channelKey = input.senderId;
42765
- const numericSenderId = parseTelegramChannelKey(channelKey)?.senderId ?? input.chatId;
42766
42851
  let lastChatActionAt = Number.NEGATIVE_INFINITY;
42767
42852
  let turnOpen = false;
42768
42853
  let cardSentThisTurn = false;
@@ -42851,13 +42936,6 @@ function startTelegramNativeFileFollower(input) {
42851
42936
  // before it reaches the optional answerCallbackQuery, so there is no card
42852
42937
  // call that posts nothing and no bare acknowledgement to keep the text for.
42853
42938
  onToolUse: (tool) => {
42854
- if (CARD_TOOL_NAMES.has(tool.name) && tool.id) {
42855
- const text = tool.input?.text;
42856
- pendingCards.set(tool.id, {
42857
- text: typeof text === "string" ? text : "",
42858
- buttons: parseCardButtons(tool.input)
42859
- });
42860
- }
42861
42939
  if (tool.name !== TELEGRAM_CARD_TOOL) return;
42862
42940
  cardSentThisTurn = true;
42863
42941
  noteCardArmed(input.sessionId);
@@ -42865,75 +42943,6 @@ function startTelegramNativeFileFollower(input) {
42865
42943
  `[telegram-public] op=card-armed sessionId=${input.sessionId.slice(0, 8)} tool=${tool.name}`
42866
42944
  );
42867
42945
  },
42868
- // Task 2677 — the card's send outcome and message id arrive here, parsed out
42869
- // of the result text card.ts encoded them into. On a confirmed send write one
42870
- // outbound store row keyed by the card message id; on an edit patch that same
42871
- // row (Telegram reuses the id for an edit); unchanged/none write nothing.
42872
- onToolResult: ({ toolUseId, text }) => {
42873
- const pending = pendingCards.get(toolUseId);
42874
- if (!pending) return;
42875
- pendingCards.delete(toolUseId);
42876
- const m = CARD_RESULT_RE.exec(text);
42877
- if (!m) return;
42878
- const outcome = m[1];
42879
- const messageId = m[2];
42880
- if (outcome !== "sent" && outcome !== "edited" || messageId === "none") return;
42881
- noteCardSent(input.sessionId);
42882
- const destBot = m[3];
42883
- const destChat = m[4];
42884
- const follower = parseTelegramChannelKey(channelKey);
42885
- let destKey = channelKey;
42886
- let rowChat = input.chatId;
42887
- let rowSender = numericSenderId;
42888
- if (destBot === void 0 || destChat === void 0) {
42889
- console.error(
42890
- `[telegram-adaptor] op=card-destination-absent sessionId=${input.sessionId.slice(0, 8)} toolUseId=${toolUseId} follower=${channelKey}`
42891
- );
42892
- } else if (follower?.business === true && follower.botId === destBot && follower.senderId === destChat) {
42893
- rowChat = destChat;
42894
- rowSender = destChat;
42895
- } else {
42896
- destKey = `${destBot}:${destChat}`;
42897
- rowChat = destChat;
42898
- rowSender = destChat;
42899
- }
42900
- if (destKey !== channelKey) noteCardCrossChat(input.sessionId);
42901
- const at = (/* @__PURE__ */ new Date()).toISOString();
42902
- const rowId = `telegram:${input.accountId}:${destKey}:card:${messageId}`;
42903
- let created;
42904
- if (outcome === "sent") {
42905
- created = appendMessage2(input.accountId, {
42906
- messageId: rowId,
42907
- sessionId: input.sessionId,
42908
- dateSent: at,
42909
- body: pending.text,
42910
- fromMe: true,
42911
- senderId: rowSender,
42912
- senderName: null,
42913
- chatId: rowChat,
42914
- channelKey: destKey,
42915
- // Telegram row scope is not consumed for rendering or routing (only
42916
- // WhatsApp rows feed the operator-conversations scope counter); 'admin'
42917
- // matches the operator-surface intent of the card row.
42918
- scope: "admin",
42919
- origin: "agent",
42920
- ...pending.buttons.length > 0 ? { buttons: pending.buttons } : {},
42921
- createdAt: at
42922
- }).created;
42923
- } else {
42924
- created = appendUpdate(input.accountId, destKey, {
42925
- kind: "update",
42926
- targetMessageId: rowId,
42927
- body: pending.text,
42928
- ...pending.buttons.length > 0 ? { buttons: pending.buttons } : {},
42929
- createdAt: at
42930
- }).created;
42931
- }
42932
- if (created) noteCardPersisted(input.sessionId);
42933
- console.error(
42934
- `[telegram-adaptor] op=${created ? "card-persisted" : "card-persist-refused"} sessionId=${input.sessionId.slice(0, 8)} messageId=${messageId} outcome=${outcome} buttons=${pending.buttons.length} channelKey=${destKey} follower=${channelKey}`
42935
- );
42936
- },
42937
42946
  // Task 2521 — the answer reaches every bound door through the one fan-out.
42938
42947
  // Ungated by design: whatever woke the turn, the reader and the chats show
42939
42948
  // the same thing. Task 2666 adds the one exception above.
@@ -42973,15 +42982,15 @@ function startTelegramNativeFileFollower(input) {
42973
42982
  }
42974
42983
 
42975
42984
  // server/telegram-background-active.ts
42976
- import { join as join72, resolve as resolve52 } from "path";
42977
- import { readdirSync as readdirSync35, statSync as statSync30 } from "fs";
42985
+ import { join as join73, resolve as resolve52 } from "path";
42986
+ import { readdirSync as readdirSync36, statSync as statSync31 } from "fs";
42978
42987
  var SUBAGENT_STALE_WINDOW_MS = 6e4;
42979
42988
  var AGENT_JSONL_RE2 = /^agent-([0-9a-f]+)\.jsonl$/;
42980
42989
  function makeBackgroundActive(sessionId, deps = {}) {
42981
42990
  const findProjectDir = deps.findProjectDir ?? findSessionProjectDir;
42982
- const readDir = deps.readDir ?? ((d) => readdirSync35(d));
42991
+ const readDir = deps.readDir ?? ((d) => readdirSync36(d));
42983
42992
  const statFile = deps.statFile ?? ((p) => {
42984
- const st = statSync30(p);
42993
+ const st = statSync31(p);
42985
42994
  return { size: st.size, mtimeMs: st.mtimeMs };
42986
42995
  });
42987
42996
  const now = deps.now ?? (() => Date.now());
@@ -42992,7 +43001,7 @@ function makeBackgroundActive(sessionId, deps = {}) {
42992
43001
  if (subagentsDir === null) {
42993
43002
  const projectDir = findProjectDir(sessionId);
42994
43003
  if (projectDir === null) return false;
42995
- subagentsDir = resolve52(join72(projectDir, sessionId, "subagents"));
43004
+ subagentsDir = resolve52(join73(projectDir, sessionId, "subagents"));
42996
43005
  }
42997
43006
  let names;
42998
43007
  try {
@@ -43006,7 +43015,7 @@ function makeBackgroundActive(sessionId, deps = {}) {
43006
43015
  let size;
43007
43016
  let mtimeMs;
43008
43017
  try {
43009
- const st = statFile(join72(subagentsDir, name));
43018
+ const st = statFile(join73(subagentsDir, name));
43010
43019
  size = st.size;
43011
43020
  mtimeMs = st.mtimeMs;
43012
43021
  } catch {
@@ -43326,9 +43335,9 @@ function warnOnChannelAdminBindingDrift() {
43326
43335
  );
43327
43336
  }
43328
43337
  for (const d of drift) {
43329
- const tail = d.reason === "userid-not-admin" ? ` userId=${d.userId}` : "";
43338
+ const tail2 = d.reason === "userid-not-admin" ? ` userId=${d.userId}` : "";
43330
43339
  console.error(
43331
- `[admin-identity] binding-drift accountId=${acct.accountId} phone=${d.phone} reason=${d.reason}${tail}`
43340
+ `[admin-identity] binding-drift accountId=${acct.accountId} phone=${d.phone} reason=${d.reason}${tail2}`
43332
43341
  );
43333
43342
  }
43334
43343
  const managerDrift = findAccountManagerDrift(readAccountManagers(acct.accountDir), validAccountIds);
@@ -43372,8 +43381,8 @@ function runPublicAddressCollisionAudit(deps) {
43372
43381
  }
43373
43382
 
43374
43383
  // server/telegram-audit.ts
43375
- import { statSync as statSync31 } from "fs";
43376
- import { join as join73 } from "path";
43384
+ import { statSync as statSync32 } from "fs";
43385
+ import { join as join74 } from "path";
43377
43386
  function buildTelegramAuditLines(input) {
43378
43387
  const lines = [];
43379
43388
  const entries2 = input.accounts.flatMap(
@@ -43481,19 +43490,19 @@ function countTelegramSessionsForAccount(accountId) {
43481
43490
  function* walkTelegramSidecars() {
43482
43491
  const cfg = claudeConfigDir();
43483
43492
  if (!cfg) return;
43484
- const projectsRoot = join73(cfg, "projects");
43493
+ const projectsRoot = join74(cfg, "projects");
43485
43494
  for (const { path } of enumerateSessionSidecars(projectsRoot)) {
43486
43495
  const meta = readSidecarMeta(path);
43487
43496
  if (meta.channel !== "telegram" || !meta.accountId) continue;
43488
43497
  let spawnMs;
43489
43498
  try {
43490
- spawnMs = statSync31(path).mtimeMs;
43499
+ spawnMs = statSync32(path).mtimeMs;
43491
43500
  } catch {
43492
43501
  continue;
43493
43502
  }
43494
43503
  let turnMs;
43495
43504
  try {
43496
- turnMs = statSync31(path.replace(/\.meta\.json$/, ".jsonl")).mtimeMs;
43505
+ turnMs = statSync32(path.replace(/\.meta\.json$/, ".jsonl")).mtimeMs;
43497
43506
  } catch {
43498
43507
  turnMs = null;
43499
43508
  }
@@ -43693,8 +43702,8 @@ function businessConnectionCensusLine(c) {
43693
43702
  }
43694
43703
 
43695
43704
  // app/lib/telegram/business-window-census.ts
43696
- import { readdirSync as readdirSync36, existsSync as existsSync59 } from "fs";
43697
- import { join as join74 } from "path";
43705
+ import { readdirSync as readdirSync37, existsSync as existsSync59 } from "fs";
43706
+ import { join as join75 } from "path";
43698
43707
  var BUSINESS_WINDOW_CENSUS_TAG = "[telegram-audit]";
43699
43708
  var EXPIRING_SOON_S = 3600;
43700
43709
  function collectBusinessWindowCensus(input) {
@@ -43722,11 +43731,11 @@ function businessWindowCensusLine(c) {
43722
43731
  function readBusinessChatClocks(accountIds) {
43723
43732
  const out = [];
43724
43733
  for (const accountId of accountIds) {
43725
- const dir = join74(STORE_ROOT2(), accountId);
43734
+ const dir = join75(STORE_ROOT2(), accountId);
43726
43735
  if (!existsSync59(dir)) continue;
43727
43736
  let names;
43728
43737
  try {
43729
- names = readdirSync36(dir);
43738
+ names = readdirSync37(dir);
43730
43739
  } catch {
43731
43740
  continue;
43732
43741
  }
@@ -43784,15 +43793,15 @@ async function getTelegramBusinessConnection(botToken, connectionId, opts = {})
43784
43793
  }
43785
43794
 
43786
43795
  // server/telegram-migrate.ts
43787
- import { readFileSync as readFileSync59, writeFileSync as writeFileSync23, existsSync as existsSync60, renameSync as renameSync11, mkdirSync as mkdirSync14 } from "fs";
43788
- import { dirname as dirname19, join as join75 } from "path";
43796
+ import { readFileSync as readFileSync60, writeFileSync as writeFileSync23, existsSync as existsSync60, renameSync as renameSync11, mkdirSync as mkdirSync14 } from "fs";
43797
+ import { dirname as dirname19, join as join76 } from "path";
43789
43798
  function migrateTelegramTwoSlot(input) {
43790
43799
  const out = [];
43791
43800
  for (const account of input.accounts) {
43792
- const configPath3 = join75(account.accountDir, "account.json");
43801
+ const configPath3 = join76(account.accountDir, "account.json");
43793
43802
  let config;
43794
43803
  try {
43795
- config = JSON.parse(readFileSync59(configPath3, "utf-8"));
43804
+ config = JSON.parse(readFileSync60(configPath3, "utf-8"));
43796
43805
  } catch {
43797
43806
  console.error(`[telegram-audit] op=migrate-unreadable accountId=${account.accountId}`);
43798
43807
  continue;
@@ -43851,16 +43860,16 @@ function moveSecret(from, to) {
43851
43860
  }
43852
43861
 
43853
43862
  // server/telegram-unadopt.ts
43854
- import { readFileSync as readFileSync60, writeFileSync as writeFileSync24, renameSync as renameSync12 } from "fs";
43855
- import { join as join76 } from "path";
43863
+ import { readFileSync as readFileSync61, writeFileSync as writeFileSync24, renameSync as renameSync12 } from "fs";
43864
+ import { join as join77 } from "path";
43856
43865
  var FILE3 = "channel-session-override.json";
43857
43866
  function unadoptTelegramPointers(input) {
43858
43867
  return input.accounts.map(({ accountId, accountDir }) => {
43859
43868
  const out = { accountId, dropped: [], kept: 0, unknown: 0 };
43860
- const path = join76(accountDir, FILE3);
43869
+ const path = join77(accountDir, FILE3);
43861
43870
  const bySender = {};
43862
43871
  try {
43863
- const raw = JSON.parse(readFileSync60(path, "utf8"));
43872
+ const raw = JSON.parse(readFileSync61(path, "utf8"));
43864
43873
  if (!raw.bySender || typeof raw.bySender !== "object") return out;
43865
43874
  for (const [k, v] of Object.entries(raw.bySender)) if (typeof v === "string") bySender[k] = v;
43866
43875
  } catch {
@@ -43931,14 +43940,14 @@ function backfillMisfiledRecords(params) {
43931
43940
  }
43932
43941
 
43933
43942
  // server/lib/booking-site-accounts.ts
43934
- import { existsSync as existsSync61, readFileSync as readFileSync61 } from "fs";
43943
+ import { existsSync as existsSync61, readFileSync as readFileSync62 } from "fs";
43935
43944
  import { resolve as resolve53 } from "path";
43936
43945
  function listBookingSiteAccounts(accounts) {
43937
43946
  return accounts.filter((a) => {
43938
43947
  const availPath = resolve53(a.accountDir, "calendar-availability.json");
43939
43948
  if (!existsSync61(availPath)) return false;
43940
43949
  try {
43941
- const cfg = JSON.parse(readFileSync61(availPath, "utf-8"));
43950
+ const cfg = JSON.parse(readFileSync62(availPath, "utf-8"));
43942
43951
  return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
43943
43952
  } catch {
43944
43953
  return false;
@@ -43976,7 +43985,7 @@ function broadcastAdminShutdown(reason) {
43976
43985
 
43977
43986
  // ../lib/entitlement/src/index.ts
43978
43987
  import { createPublicKey, createHash as createHash7, verify as cryptoVerify } from "crypto";
43979
- import { existsSync as existsSync62, readFileSync as readFileSync62, statSync as statSync32 } from "fs";
43988
+ import { existsSync as existsSync62, readFileSync as readFileSync63, statSync as statSync33 } from "fs";
43980
43989
  import { resolve as resolve54 } from "path";
43981
43990
 
43982
43991
  // ../lib/entitlement/src/canonicalize.ts
@@ -44028,7 +44037,7 @@ function resolveEntitlement(brand, account) {
44028
44037
  if (!existsSync62(entitlementPath)) {
44029
44038
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
44030
44039
  }
44031
- const stat11 = statSync32(entitlementPath);
44040
+ const stat11 = statSync33(entitlementPath);
44032
44041
  const key2 = memoKey(stat11.mtimeMs, account);
44033
44042
  if (memo && memo.key === key2) {
44034
44043
  return memo.result;
@@ -44040,7 +44049,7 @@ function resolveEntitlement(brand, account) {
44040
44049
  function verifyAndResolve(brand, entitlementPath, account) {
44041
44050
  let pubkeyPem;
44042
44051
  try {
44043
- pubkeyPem = readFileSync62(pubkeyPath(brand), "utf-8");
44052
+ pubkeyPem = readFileSync63(pubkeyPath(brand), "utf-8");
44044
44053
  } catch (err) {
44045
44054
  return logResolved(anonymousFallback("pubkey-missing"), {
44046
44055
  reason: "pubkey-missing"
@@ -44054,7 +44063,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
44054
44063
  }
44055
44064
  let envelope;
44056
44065
  try {
44057
- envelope = JSON.parse(readFileSync62(entitlementPath, "utf-8"));
44066
+ envelope = JSON.parse(readFileSync63(entitlementPath, "utf-8"));
44058
44067
  } catch {
44059
44068
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
44060
44069
  }
@@ -44216,14 +44225,14 @@ function clientFrom(c) {
44216
44225
  }
44217
44226
  installMediaDownloadGuard();
44218
44227
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT || "";
44219
- var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join77(PLATFORM_ROOT6, "config", "brand.json") : "";
44228
+ var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join78(PLATFORM_ROOT6, "config", "brand.json") : "";
44220
44229
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
44221
44230
  if (BRAND_JSON_PATH && !existsSync63(BRAND_JSON_PATH)) {
44222
44231
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
44223
44232
  }
44224
44233
  if (BRAND_JSON_PATH && existsSync63(BRAND_JSON_PATH)) {
44225
44234
  try {
44226
- const parsed = JSON.parse(readFileSync63(BRAND_JSON_PATH, "utf-8"));
44235
+ const parsed = JSON.parse(readFileSync64(BRAND_JSON_PATH, "utf-8"));
44227
44236
  BRAND = { ...BRAND, ...parsed };
44228
44237
  } catch (err) {
44229
44238
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -44255,11 +44264,11 @@ var brandLoginOpts = {
44255
44264
  appleTouchIconPath: brandAppIcon512Path,
44256
44265
  themeColor: BRAND.defaultColors?.primary
44257
44266
  };
44258
- var ALIAS_DOMAINS_PATH = join77(homedir5(), BRAND.configDir, "alias-domains.json");
44267
+ var ALIAS_DOMAINS_PATH = join78(homedir5(), BRAND.configDir, "alias-domains.json");
44259
44268
  function loadAliasDomains() {
44260
44269
  try {
44261
44270
  if (!existsSync63(ALIAS_DOMAINS_PATH)) return null;
44262
- const parsed = JSON.parse(readFileSync63(ALIAS_DOMAINS_PATH, "utf-8"));
44271
+ const parsed = JSON.parse(readFileSync64(ALIAS_DOMAINS_PATH, "utf-8"));
44263
44272
  if (!Array.isArray(parsed)) {
44264
44273
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
44265
44274
  return null;
@@ -44401,7 +44410,7 @@ var waGateway = new WaGateway({
44401
44410
  // resolver and `fanTargetsFor` is a constructor dep, not a callable method.
44402
44411
  fanTargetsFor: whatsappFanTargets,
44403
44412
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
44404
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve55(process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
44413
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve55(process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
44405
44414
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
44406
44415
  // path-validation scope) is the sender's effective SESSION account, resolved
44407
44416
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -44416,7 +44425,7 @@ var waGateway = new WaGateway({
44416
44425
  caption,
44417
44426
  accountId,
44418
44427
  maxyAccountId,
44419
- platformRoot: resolve55(process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, ".."))
44428
+ platformRoot: resolve55(process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, ".."))
44420
44429
  });
44421
44430
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
44422
44431
  },
@@ -44591,7 +44600,7 @@ function runDuplicateSenderAudit() {
44591
44600
  try {
44592
44601
  const configDir = process.env.CLAUDE_CONFIG_DIR;
44593
44602
  if (!configDir) return;
44594
- const projectsRoot = join77(configDir, "projects");
44603
+ const projectsRoot = join78(configDir, "projects");
44595
44604
  const records5 = [];
44596
44605
  for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
44597
44606
  if (isSubagent || archived) continue;
@@ -44643,7 +44652,7 @@ var webchatGateway = new WebchatGateway({
44643
44652
  // rather than hanging the POST.
44644
44653
  publicProjectsRoot: () => {
44645
44654
  const cfg = claudeConfigDir();
44646
- return cfg ? join77(cfg, "projects") : "";
44655
+ return cfg ? join78(cfg, "projects") : "";
44647
44656
  },
44648
44657
  gatewayUrl: webchatGatewayUrl(),
44649
44658
  serverPath: webchatServerPath(),
@@ -44913,6 +44922,32 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
44913
44922
  if (hits.length === 0) return { kind: "none" };
44914
44923
  if (hits.length > 1) return { kind: "ambiguous", claimants: hits };
44915
44924
  return { kind: "one", ...hits[0] };
44925
+ },
44926
+ // Task 2776 — the carrier a routine NAMED, resolved against that account's own
44927
+ // bots and never install-wide. The verdict comes from `carrierVerdict`, the
44928
+ // same function `validateAgentDispatch` calls at write time, so a bot that
44929
+ // saved cannot be refused here for a reason the save would not have given.
44930
+ //
44931
+ // The token and allowlists are read off the entry this lookup just chose, for
44932
+ // the reason the resolver above states about its own: a second read of the
44933
+ // registry could disagree with the entry chosen.
44934
+ //
44935
+ // `absent` covers the two ways an entry can be missing — no such account, and
44936
+ // no such bot on it — because both mean the same thing to the operator: the id
44937
+ // this routine names is not a bot they can dispatch on.
44938
+ carrierFor: (accountId, botId, destination) => {
44939
+ const account = listValidAccounts().find((a) => a.accountId === accountId);
44940
+ if (!account) return { error: "absent" };
44941
+ const verdict = carrierVerdict(account.accountDir, botId, destination);
44942
+ if (!verdict.ok) return { error: verdict.reason };
44943
+ const entry3 = listBotEntries(account.config.telegram).find((e) => e.id === botId);
44944
+ if (!entry3) return { error: "absent" };
44945
+ return {
44946
+ accountId: account.accountId,
44947
+ botId,
44948
+ botToken: entry3.token,
44949
+ ...chatSendAllowlists(entry3)
44950
+ };
44916
44951
  }
44917
44952
  // Task 2078 — the same binding the live inbound resolves. Without it a
44918
44953
  // scheduled dispatch to a BOUND admin would derive the legacy per-chat id and
@@ -45317,7 +45352,7 @@ app80.get("/agent-assets/:slug/:filename", (c) => {
45317
45352
  const ext = "." + filename.split(".").pop()?.toLowerCase();
45318
45353
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
45319
45354
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
45320
- const body = readFileSync63(filePath);
45355
+ const body = readFileSync64(filePath);
45321
45356
  return c.body(body, 200, {
45322
45357
  "Content-Type": contentType,
45323
45358
  "Cache-Control": "public, max-age=3600"
@@ -45347,7 +45382,7 @@ app80.get("/generated/:filename", (c) => {
45347
45382
  const ext = "." + filename.split(".").pop()?.toLowerCase();
45348
45383
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
45349
45384
  console.log(`[generated] serve file=${filename} status=200`);
45350
- const body = readFileSync63(filePath);
45385
+ const body = readFileSync64(filePath);
45351
45386
  return c.body(body, 200, {
45352
45387
  "Content-Type": contentType,
45353
45388
  "Cache-Control": "public, max-age=86400"
@@ -45362,7 +45397,7 @@ var brandLogoPath = "/brand/maxy-monochrome.png";
45362
45397
  var brandIconPath = "/brand/maxy-monochrome.png";
45363
45398
  if (BRAND_JSON_PATH && existsSync63(BRAND_JSON_PATH)) {
45364
45399
  try {
45365
- const fullBrand = JSON.parse(readFileSync63(BRAND_JSON_PATH, "utf-8"));
45400
+ const fullBrand = JSON.parse(readFileSync64(BRAND_JSON_PATH, "utf-8"));
45366
45401
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
45367
45402
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
45368
45403
  } catch {
@@ -45393,7 +45428,7 @@ var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskabl
45393
45428
  );
45394
45429
  var SW_SOURCE = (() => {
45395
45430
  try {
45396
- return readFileSync63(resolve55(process.cwd(), "public", "sw.js"), "utf-8");
45431
+ return readFileSync64(resolve55(process.cwd(), "public", "sw.js"), "utf-8");
45397
45432
  } catch {
45398
45433
  return null;
45399
45434
  }
@@ -45401,9 +45436,9 @@ var SW_SOURCE = (() => {
45401
45436
  function readInstalledVersion() {
45402
45437
  try {
45403
45438
  if (!PLATFORM_ROOT6) return "unknown";
45404
- const versionFile = join77(PLATFORM_ROOT6, "config", `.${BRAND.hostname}-version`);
45439
+ const versionFile = join78(PLATFORM_ROOT6, "config", `.${BRAND.hostname}-version`);
45405
45440
  if (!existsSync63(versionFile)) return "unknown";
45406
- const content = readFileSync63(versionFile, "utf-8").trim();
45441
+ const content = readFileSync64(versionFile, "utf-8").trim();
45407
45442
  return content || "unknown";
45408
45443
  } catch {
45409
45444
  return "unknown";
@@ -45414,7 +45449,7 @@ var versionScript = `<script>window.__MAXY_VERSION__=${JSON.stringify(INSTALLED_
45414
45449
  function cachedHtml(file) {
45415
45450
  let html = htmlCache.get(file);
45416
45451
  if (!html) {
45417
- html = readFileSync63(resolve55(process.cwd(), "public", file), "utf-8");
45452
+ html = readFileSync64(resolve55(process.cwd(), "public", file), "utf-8");
45418
45453
  const productNameEsc = escapeHtml(BRAND.productName);
45419
45454
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
45420
45455
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -45431,14 +45466,14 @@ ${clientErrorReporterScript}
45431
45466
  return html;
45432
45467
  }
45433
45468
  function loadBrandingCache(agentSlug) {
45434
- const configDir = join77(homedir5(), BRAND.configDir);
45469
+ const configDir = join78(homedir5(), BRAND.configDir);
45435
45470
  try {
45436
45471
  const verdict = resolvePublicAddressFromDisk(agentSlug);
45437
45472
  const accountId = verdict.kind === "served" ? verdict.owner.accountId : getDefaultAccountId();
45438
45473
  if (!accountId) return null;
45439
- const cachePath = join77(configDir, "branding-cache", accountId, `${agentSlug}.json`);
45474
+ const cachePath = join78(configDir, "branding-cache", accountId, `${agentSlug}.json`);
45440
45475
  if (!existsSync63(cachePath)) return null;
45441
- return JSON.parse(readFileSync63(cachePath, "utf-8"));
45476
+ return JSON.parse(readFileSync64(cachePath, "utf-8"));
45442
45477
  } catch {
45443
45478
  return null;
45444
45479
  }
@@ -45533,7 +45568,7 @@ app80.use("/vnc-popout.html", logViewerFetch);
45533
45568
  app80.get("/vnc-popout.html", (c) => {
45534
45569
  let html = htmlCache.get("vnc-popout.html");
45535
45570
  if (!html) {
45536
- html = readFileSync63(resolve55(process.cwd(), "public", "vnc-popout.html"), "utf-8");
45571
+ html = readFileSync64(resolve55(process.cwd(), "public", "vnc-popout.html"), "utf-8");
45537
45572
  const name = escapeHtml(BRAND.productName);
45538
45573
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
45539
45574
  html = html.replace("</head>", ` ${brandScript}
@@ -45687,7 +45722,7 @@ var hostname = process.env.HOSTNAME ?? "127.0.0.1";
45687
45722
  var httpServer = serve({ fetch: app80.fetch, port, hostname });
45688
45723
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
45689
45724
  {
45690
- const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..");
45725
+ const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..");
45691
45726
  const reconcileScript = resolve55(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
45692
45727
  const runReconcile = (ctx) => {
45693
45728
  if (!existsSync63(reconcileScript)) return;
@@ -45710,7 +45745,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
45710
45745
  detached: true,
45711
45746
  run: runReconcile
45712
45747
  });
45713
- const reconcileStatePath = join77(MAXY_DIR, "booking-reconcile-state.json");
45748
+ const reconcileStatePath = join78(MAXY_DIR, "booking-reconcile-state.json");
45714
45749
  registerLoop({
45715
45750
  name: "calendar-reconcile-liveness",
45716
45751
  intervalMs: 6e5,
@@ -45728,7 +45763,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
45728
45763
  }
45729
45764
  {
45730
45765
  const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
45731
- const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..");
45766
+ const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..");
45732
45767
  const dreamSweepScript = resolve55(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
45733
45768
  registerLoop({
45734
45769
  name: "dream-cycle-sweep",
@@ -45752,7 +45787,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
45752
45787
  });
45753
45788
  }
45754
45789
  {
45755
- const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..");
45790
+ const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..");
45756
45791
  const outlookScript = resolve55(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
45757
45792
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
45758
45793
  const runOutlookComplete = (ctx) => {
@@ -45778,7 +45813,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
45778
45813
  });
45779
45814
  }
45780
45815
  {
45781
- const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..");
45816
+ const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..");
45782
45817
  const strandedAccountsDir = resolve55(auditRoot, "..", "data/accounts");
45783
45818
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
45784
45819
  const STRANDED_AGE_MS = 16 * 6e4;
@@ -45787,11 +45822,11 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
45787
45822
  try {
45788
45823
  if (!existsSync63(strandedAccountsDir)) return;
45789
45824
  const now = Date.now();
45790
- for (const name of readdirSync37(strandedAccountsDir)) {
45825
+ for (const name of readdirSync38(strandedAccountsDir)) {
45791
45826
  if (!STRANDED_UUID_RE.test(name)) continue;
45792
45827
  const pendingPath2 = resolve55(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
45793
45828
  if (!existsSync63(pendingPath2)) continue;
45794
- const ageMs2 = now - statSync33(pendingPath2).mtimeMs;
45829
+ const ageMs2 = now - statSync34(pendingPath2).mtimeMs;
45795
45830
  if (ageMs2 > STRANDED_AGE_MS) {
45796
45831
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
45797
45832
  }
@@ -45808,7 +45843,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
45808
45843
  });
45809
45844
  }
45810
45845
  {
45811
- const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..");
45846
+ const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..");
45812
45847
  const googleAccountsDir = resolve55(googleRoot, "..", "data/accounts");
45813
45848
  const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
45814
45849
  const runGooglePendingAuditSafe = () => {
@@ -45864,7 +45899,7 @@ registerLoop({
45864
45899
  }
45865
45900
  });
45866
45901
  {
45867
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..");
45902
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..");
45868
45903
  const STORAGE_AUDIT_INTERVAL_MS = 3e5;
45869
45904
  const runStorageAuditSafe = () => runStorageAudit(auditPlatformRoot).catch((err) => {
45870
45905
  console.error(`[storage-audit] error="${err.message}"`);
@@ -45931,7 +45966,7 @@ registerLoop({
45931
45966
  const lastByBot = newestTelegramSessionByBot();
45932
45967
  let secretFilesOnDisk = [];
45933
45968
  try {
45934
- secretFilesOnDisk = readdirSync37(telegramSecretsDir());
45969
+ secretFilesOnDisk = readdirSync38(telegramSecretsDir());
45935
45970
  } catch {
45936
45971
  }
45937
45972
  const lines = buildTelegramAuditLines({
@@ -45939,7 +45974,7 @@ registerLoop({
45939
45974
  secretFileExists: (botId) => existsSync63(secretPath(botId)),
45940
45975
  agentActive: isActiveAgentSlug,
45941
45976
  // Task 2619 — the card set a specialist binding is reconciled against.
45942
- specialistCards: (accountDir) => listSpecialistCardNames(join77(accountDir, "specialists", "agents")),
45977
+ specialistCards: (accountDir) => listSpecialistCardNames(join78(accountDir, "specialists", "agents")),
45943
45978
  // Task 2619 — the doors that can be sent to right now. The same accessor
45944
45979
  // the follower census reads (:1185), so "should have a reader" and "can be
45945
45980
  // sent to" stay one fact.
@@ -46025,6 +46060,14 @@ registerLoop({
46025
46060
  runTelegramMediaCensus();
46026
46061
  }
46027
46062
  });
46063
+ registerLoop({
46064
+ name: "telegram-card-row-census",
46065
+ intervalMs: STORAGE_AUDIT_INTERVAL_MS,
46066
+ firstRunDelayMs: 11e4,
46067
+ run: async () => {
46068
+ runTelegramCardRowCensus(process.env.LOG_DIR ?? LOG_DIR);
46069
+ }
46070
+ });
46028
46071
  registerLoop({
46029
46072
  name: "telegram-checkout-census",
46030
46073
  intervalMs: STORAGE_AUDIT_INTERVAL_MS,
@@ -46340,7 +46383,7 @@ registerLoop({
46340
46383
  });
46341
46384
  }
46342
46385
  {
46343
- const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..");
46386
+ const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..");
46344
46387
  const publishScript = resolve55(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
46345
46388
  const PUBLISH_INTERVAL_MS = 3e5;
46346
46389
  const bookingAccounts = () => {
@@ -46375,7 +46418,7 @@ registerLoop({
46375
46418
  let hasBookingSite = false;
46376
46419
  try {
46377
46420
  if (existsSync63(availPath)) {
46378
- const cfg = JSON.parse(readFileSync63(availPath, "utf-8"));
46421
+ const cfg = JSON.parse(readFileSync64(availPath, "utf-8"));
46379
46422
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
46380
46423
  }
46381
46424
  } catch {
@@ -46385,7 +46428,7 @@ registerLoop({
46385
46428
  let lastSuccessAt = null;
46386
46429
  if (existsSync63(statePath)) {
46387
46430
  try {
46388
- const rec = JSON.parse(readFileSync63(statePath, "utf-8"));
46431
+ const rec = JSON.parse(readFileSync64(statePath, "utf-8"));
46389
46432
  lastSuccessAt = rec.lastSuccessAt ?? null;
46390
46433
  } catch {
46391
46434
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
@@ -46420,7 +46463,7 @@ startDispatchCensus(() => getSession());
46420
46463
  startDispatchFieldCensus(() => getSession());
46421
46464
  startDispatchTgCensus(() => getSession());
46422
46465
  {
46423
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..");
46466
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..");
46424
46467
  const auditScript = resolve55(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
46425
46468
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
46426
46469
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
@@ -46551,7 +46594,7 @@ async function runAdminUserReconcileTick() {
46551
46594
  console.error("[adminuser-self-heal] skip reason=no-users-file");
46552
46595
  return;
46553
46596
  }
46554
- const usersRaw = readFileSync63(USERS_FILE, "utf-8").trim();
46597
+ const usersRaw = readFileSync64(USERS_FILE, "utf-8").trim();
46555
46598
  if (!usersRaw) {
46556
46599
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
46557
46600
  return;
@@ -46633,8 +46676,8 @@ var runIngestAuditTick = () => {
46633
46676
  },
46634
46677
  agentExists: (accountId, slug) => {
46635
46678
  if (!house) return false;
46636
- const dir = isHouseAccountKey(house.accountId, accountId) ? house.accountDir : join77(ACCOUNTS_DIR, accountId);
46637
- return existsSync63(join77(dir, "agents", slug, "config.json"));
46679
+ const dir = isHouseAccountKey(house.accountId, accountId) ? house.accountDir : join78(ACCOUNTS_DIR, accountId);
46680
+ return existsSync63(join78(dir, "agents", slug, "config.json"));
46638
46681
  }
46639
46682
  });
46640
46683
  } catch (err) {
@@ -46682,9 +46725,9 @@ registerLoop({
46682
46725
  runPublicAddressCollisionAudit({
46683
46726
  houseAccountId: () => resolveAccount()?.accountId ?? null,
46684
46727
  activeSlugs: () => listValidAccounts().map((a) => {
46685
- const agentsRoot = join77(a.accountDir, "agents");
46728
+ const agentsRoot = join78(a.accountDir, "agents");
46686
46729
  if (!existsSync63(agentsRoot)) return { accountId: a.accountId, slugs: [] };
46687
- const slugs = readdirSync37(agentsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((slug) => isActiveAgentSlug(a.accountDir, slug));
46730
+ const slugs = readdirSync38(agentsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((slug) => isActiveAgentSlug(a.accountDir, slug));
46688
46731
  return { accountId: a.accountId, slugs };
46689
46732
  })
46690
46733
  });
@@ -46698,7 +46741,7 @@ registerLoop({
46698
46741
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
46699
46742
  function countUsersRows() {
46700
46743
  if (!existsSync63(USERS_FILE)) return 0;
46701
- const raw = readFileSync63(USERS_FILE, "utf-8").trim();
46744
+ const raw = readFileSync64(USERS_FILE, "utf-8").trim();
46702
46745
  if (!raw) return 0;
46703
46746
  const users = JSON.parse(raw);
46704
46747
  return users.filter((u) => typeof u.userId === "string").length;
@@ -46801,7 +46844,7 @@ function sessionChannelResolver() {
46801
46844
  byId = /* @__PURE__ */ new Map();
46802
46845
  const cfg = claudeConfigDir();
46803
46846
  if (cfg) {
46804
- for (const { path } of enumerateSessionSidecars(join77(cfg, "projects"))) {
46847
+ for (const { path } of enumerateSessionSidecars(join78(cfg, "projects"))) {
46805
46848
  const channel = readSidecarMeta(path).channel;
46806
46849
  if (channel) byId.set(basename19(path).replace(/\.meta\.json$/, ""), channel);
46807
46850
  }
@@ -46876,7 +46919,7 @@ if (bootAccountConfig?.whatsapp) {
46876
46919
  }
46877
46920
  init({
46878
46921
  configDir: configDirForWhatsApp,
46879
- platformRoot: resolve55(process.env.MAXY_PLATFORM_ROOT ?? join77(__dirname, "..")),
46922
+ platformRoot: resolve55(process.env.MAXY_PLATFORM_ROOT ?? join78(__dirname, "..")),
46880
46923
  accountConfig: bootAccountConfig,
46881
46924
  // Task 2074 — enrich with the sub-account name and fan out to every open
46882
46925
  // admin SSE stream. Fire-and-forget: the manager's persist path must not